Home > OS >  AngularJS, using ng-show breaks select2's layout
AngularJS, using ng-show breaks select2's layout

Time:04-11

I'm creating a dynamic page that loads a lot of filters from the server. I want to show those filters only when all server side calls are done. For that, I'm using a simple true/false variable (ng-show="filtersDone", 11th row).

<div >
    <div >
        <div >
            <div >
                <span><strong> Planning - Details </strong></span>
                <div ></div>
            </div>
            <div >
                <div >
                    <div >
                        <div  ng-show="filtersDone">
                            <div >
                                <label for="searchFilters.year" >Year</label>
                                <select  ng-model="searchFilters.year" ng-options="y as y for y in yearsList"></select>
                            </div>

                            <div >
                                <label for="searchFilters.dealer" >Dealers</label>
                                <select  ng-model="searchFilters.dealer" ng-options="dealer.ID as dealer.Name for dealer in dealers"><option></option></select>
                            </div>

                            <div >
                                <label for="searchFilters.planningStatus" >Planning Status</label>
                                <select  ng-model="searchFilters.planningStatus">
                                    <option></option>
                                    <option value="1">Started</option>
                                    <option value="2">Compiled</option>
                                    <option value="3">Archived</option>
                                </select>
                            </div>

                            <div >
                                <label for="searchFilters.buildingType" >Building Type</label>
                                <select  ng-model="searchFilters.buildingType" id="select2_buildingType" name="searchFilters.buildingType"
                                        multiple="multiple" ng-options="item.ID as item.Name for item in buildingTypes">
                                </select>
                            </div>

                            <div >
                                <label for="searchFilters.buildingCategory" >Building Category</label>
                                <select  ng-model="searchFilters.buildingCategory" id="select2_buildingCategory" name="searchFilters.buildingCategory" 
                                        multiple="multiple" ng-options="item.ID as item.Category for item in buildingCategories">
                                </select>
                            </div>

                            <div >
                                <div >
                                    <label  style="width: 100%">&nbsp;</label>
                                    <button type="button"  ng-click="search()">Search</button>
                                    <button type="button"  ng-click="clean()">Clean</button>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

And here's the part of the controller for filters. $scope.filtersDone is setted to false at the beginning of the function, then i call all the server side functions to get all select values and then, when evertything is done, i set $scope.filtersDone to true (28th row).
I thought the problem could be that i was initializing select2 select before the $scope.filtersDone = true; but it doesn't change if I do it before or after.

$scope.init = function () {
  $scope.filtersDone = false;

  apiCustomService.defaultYear.get(function (res) {
    $scope.currentYear = res.value;

    $scope.yearsList = [];
    const currentYear = new Date().getFullYear();
    for (i = 0; i < 15; i  ) {
      $scope.yearsList.push(currentYear - i);
    }

    apiCustomService.dealersGet.get(function(dealers) {
      $scope.dealers = dealers;
      apiCustomService.operaType.get(function(buildingTypes) {
        $scope.buildingTypes = buildingTypes;
        apiCustomService.operaCategory.get(function(buildingCategories) {
          $scope.buildingCategories = buildingCategories;
          apiCustomService.inspectionTypes.get(function(inspectionTypes) {
            $scope.inspectionTypes = inspectionTypes;
            apiCustomService.getListOfValues.get(function(listOfValues) {
              $scope.listOfValues = listOfValues;
              apiCustomService.getAllBuildingCodes.get(function(buildingCodes) {
                $scope.buildingCodes = buildingCodes.codes;

                $scope.searchFilters = {year: $scope.currentYear};

                $scope.filtersDone = true;

                jQuery('#select2_buildingType').select2({
                  multiple: true,
                  placeholder: " ",
                  allowClear: true,
                  language: 'it'
                });

                jQuery('#select2_buildingCategory').select2({
                  multiple: true,
                  placeholder: " ",
                  allowClear: true,
                  language: 'it'
                });
              });
            });
          });
        });
      });
    });
  });
}

$scope.init();

If i don't use ng-show="filtersDone", this is the (correct) situation:

enter image description here

But if i use it, this is the situation (layout breaks down only for select2 components):

enter image description here

Any suggestion?

CodePudding user response:

When ng-show is set to false, the element is not available in the page to be manipulated, because angular hides it using CSS: "display: none !important"

So instead of ng-show, you can use a class or style directive to hide the element via the usage of either CSS visibility or opacity rules.

This ensures that the element is being rendered in the page even though it is not visible.

basically replace this:

<div  ng-show="filtersDone">

with this:

<div  ng-style="{'opacity': filtersDone ? '1' : '0' }">
  • Related