joaoneto / angular-bootstrap-select

DEPRECATED DON'T USE - Directive to wrap bootstrap-select
105 stars 81 forks source link

Directive is duplicating the dropdown boxes in a ng-table column #49

Open felipegr opened 9 years ago

felipegr commented 9 years ago

Hi,

I'm having an issue when trying to use a selectpicker inside a column of a ng-table, the dropdown is being duplicated and I can't find the reason.

Just as an example, I created the following table:

<div class="table-responsive" style="width: 1300px;">
      <table ng-table="batchUserCtrl.tableParams" class="table table-bordered table-hover">
        <tr ng-repeat="classification in $data" class="vert-align">
          <td data-title="'ID'" sortable="'object.object_id'" class="vert-align col-sm-1">
              <a href="">{{classification.object.object_id}}</a>
          </td>
          <td data-title="'Texto'" sortable="'object.text'" class="vert-align col-sm-2">
            {{ classification.object.text }}
          </td>
          <td data-title="'Sentimento'" class="vert-align col-sm-1" ng-if="batchUserCtrl.controlColumnsVisibility(1)">
            <select title="Selecionar" ng-model="batchUserCtrl.bla" selectpicker data-live-search="true" id="teste">
              <option>1</option>
              <option>2</option>
            </select>
          </td>
          <td data-title="'Tema'" class="vert-align col-sm-1" ng-if="batchUserCtrl.controlColumnsVisibility(2)">
            {{ batchUserCtrl.getValue(classification.category_values, 2).val }}
          </td>
          <td data-title="'Manifestação'" class="vert-align col-sm-1" ng-if="batchUserCtrl.controlColumnsVisibility(4)">
            manif
          </td>
          <td data-title="'Complemento 1'" class="vert-align col-sm-1" ng-if="batchUserCtrl.controlColumnsVisibility(5)">
            {{ batchUserCtrl.getValue(classification.category_values, 5).val }}
          </td>
          <td data-title="'Outros'" class="vert-align col-sm-1">
              {{classification.others}}
          </td>
          <td data-title="'Lixo'" class="vert-align col-sm-1">
              {{classification.garbagePretty}}
          </td>
        </tr>
      </table> 
  </div>

In the third column I created only one selectpicker with fixed options, but when the page is rendered there are 2 dropdowns, instead of one:

image

And only the upper one works, which means that the user can select an option, the other one shows the options and even let the user choose one of them, but doesn't change the selected option text. If I put the same <select> tag outside the table it works ok.

Here's the HTML code of the selectpickers after the page is fully rendered:

<td data-title="'Sentimento'" class="vert-align col-sm-1 ng-scope" ng-if="batchUserCtrl.controlColumnsVisibility(1)" data-title-text="Sentimento">

            <!--{{ batchUserCtrl.getValue(classification.category_values, 1).val }}-->
            <select title="Selecionar" ng-model="batchUserCtrl.bla" selectpicker="" data-live-search="true" id="teste" class="bs-select-hidden ng-untouched ng-valid ng-dirty ng-valid-parse"><option class="bs-title-option" value="">Selecionar</option>
             <!--2-->
              <option value="1">1</option>
              <option value="2">2</option>
            </select>
            <div class="btn-group bootstrap-select ng-pristine ng-untouched ng-valid ng-dirty ng-valid-parse">
                <button type="button" class="btn dropdown-toggle btn-default" data-toggle="dropdown" data-id="teste" title="2" aria-expanded="false">
                     <span class="filter-option pull-left">2</span>&nbsp;<span class="caret">
                     </span>
                </button>
              <div class="dropdown-menu open" style="max-height: 141px; overflow: hidden; min-height: 42px;">
                <div class="bs-searchbox"><input type="text" class="form-control" autocomplete="off">
                </div>
                <ul class="dropdown-menu inner" role="menu" style="max-height: 87px; overflow-y: auto; min-height: 0px;">
                     <li data-original-index="1" class="">
                           <a tabindex="0" class="" style="" data-tokens="null">
                               <span class="text">1</span>
                               <span class="glyphicon glyphicon-ok check-mark"></span>
                           </a>
                    </li>
                    <li data-original-index="2" class="selected active">
                          <a tabindex="0" class="" style="" data-tokens="null">
                              <span class="text">2</span>
                              <span class="glyphicon glyphicon-ok check-mark"></span>
                          </a>
                    </li>
                </ul>
            </div>
         </div>
         <div class="btn-group bootstrap-select">
             <button type="button" class="btn dropdown-toggle btn-default" data-toggle="dropdown" data-id="teste" title="Selecionar" aria-expanded="false">
                  <span class="filter-option pull-left">Selecionar</span>&nbsp;<span class="caret"></span>
             </button>
             <div class="dropdown-menu open">
                  <div class="bs-searchbox">
                       <input type="text" class="form-control" autocomplete="off">
                  </div>
                  <ul class="dropdown-menu inner" role="menu">
                      <li data-original-index="1" class="active">
                           <a tabindex="0" class="" style="" data-tokens="null">
                                 <span class="text">1</span>
                                 <span class="glyphicon glyphicon-ok check-mark"></span>
                            </a>
                      </li>
                      <li data-original-index="2">
                          <a tabindex="0" class="" style="" data-tokens="null">
                              <span class="text">2</span>
                              <span class="glyphicon glyphicon-ok check-mark"></span>
                          </a>
                      </li>
                  </ul>
           </div>
        </div>
   </td>

Can someone please help?

Thanks!

hmonadjem commented 9 years ago

having the same effect ... in my case its even not in an table :/

felipegr commented 9 years ago

@hmonadjem If it helps you, I managed to add some code to the directive that "corrects" this behavior. I don't believe it's a proper correction, but anyway, it works. I saw there was a difference between the two dropdowns created, the one which worked had the classes ".btn-group.bootstrap-select.ng-pristine.ng-untouched.ng-valid" in it and the duplicate hadn't, so what I did was to remove the wrong one.

Here's the code, I hope it is useful for you:

// Added $timeout
angular.module('angular-bootstrap-select', [])
  .directive('selectpicker', ['$parse', '$timeout', function ($parse, $timeout) {
    return {
      restrict: 'A',
      require: '?ngModel',
      priority: 10,
      compile: function (tElement, tAttrs, transclude) {
        tElement.selectpicker($parse(tAttrs.selectpicker)());
        tElement.selectpicker('refresh');
        return function (scope, element, attrs, ngModel) {
          if (!ngModel) return;

          scope.$watch(attrs.ngModel, function (newVal, oldVal) {
            scope.$evalAsync(function () {
              if (!attrs.ngOptions || /track by/.test(attrs.ngOptions)) element.val(newVal);
                element.selectpicker('refresh');
            });
          });

          ngModel.$render = function () {
            scope.$evalAsync(function () {
              element.selectpicker('refresh');
            });
          }

          // New code, removes the divs that don't have all the necessary classes
          $timeout(function () {
            if ($( 'div' ).find('.btn-group.bootstrap-select.ng-pristine.ng-untouched.ng-valid').length > 0 ) {
              $('.bootstrap-select:not(.ng-pristine.ng-untouched.ng-valid)').remove();
            }
          });
        };
      }

    };
  }]);
hmonadjem commented 9 years ago

Hi, thank you, i figured out that it happens when the selectpicker is in an ng-if ...

Am Montag, 21. September 2015 schrieb felipegr :

@hmonadjem https://github.com/hmonadjem If it helps you, I managed to add some code to the directive that "corrects" this behavior. I don't believe it's a proper correction, but anyway, it works. I saw there was a difference between the two dropdowns created, the one which worked had the classes ".btn-group.bootstrap-select.ng-pristine.ng-untouched.ng-valid" in it and the duplicate hadn't, so what I did was to remove the wrong one.

Here's the code, I hope it is useful for you:

// Added $timeout angular.module('angular-bootstrap-select', []) .directive('selectpicker', ['$parse', '$timeout', function ($parse, $timeout) { return { restrict: 'A', require: '?ngModel', priority: 10, compile: function (tElement, tAttrs, transclude) { tElement.selectpicker($parse(tAttrs.selectpicker)()); tElement.selectpicker('refresh'); return function (scope, element, attrs, ngModel) { if (!ngModel) return;

      scope.$watch(attrs.ngModel, function (newVal, oldVal) {
        scope.$evalAsync(function () {
          if (!attrs.ngOptions || /track by/.test(attrs.ngOptions)) element.val(newVal);
            element.selectpicker('refresh');
        });
      });

      ngModel.$render = function () {
        scope.$evalAsync(function () {
          element.selectpicker('refresh');
        });
      }

      // New code, removes the divs that don't have all the necessary classes
      $timeout(function () {
        if ($( 'div' ).find('.btn-group.bootstrap-select.ng-pristine.ng-untouched.ng-valid').length > 0 ) {
          $('.bootstrap-select:not(.ng-pristine.ng-untouched.ng-valid)').remove();
        }
      });
    };
  }

};

}]);

— Reply to this email directly or view it on GitHub https://github.com/joaoneto/angular-bootstrap-select/issues/49#issuecomment-141954884 .

von mobil gesendet

fthiemonge commented 9 years ago

We are having the same issue, but only with the minified js.

zdolin commented 9 years ago

+1

StefanOrzu commented 8 years ago

@hmonadjem is right. It happened to me when the select was nested inside an ng-if or ng-switch-when. I worked around it by placing the conditional directly on the select. It's not a nice solution, but at least it got the job done. A real fix is still necessary for this bug.

KevinHoward commented 8 years ago

https://github.com/joaoneto/angular-bootstrap-select/pull/57 <-- Here is the real fix. Thanks @xixao!

ghost commented 8 years ago

hey any one know how to give select filter in ng-table column i saw the doc but i cant understand any one have complete code