Search code examples
htmlangularjsangularjs-ng-repeat

Display label displayed in options as the title of select


How to show option.Brand.Name as the title of the select field without using java script and changing the ng-model?

<select ng-model="detail.BrandId" title="" class="form-control" disabled>
    <option ng-repeat="option in mainCtrl.products" ng-selected="option.Id === detail.ProductId" ng-value="option.BrandId">{{option.Brand.Name}}</option>
</select>

Solution

  • AngularJS and select-options

    Try using ng-options AngularJS ngOptions directive within select element itself. Then you don't need to add each option element yourself using ng-repeat.

    Clarification

    The title-attribute belongs to the select-element and will show if you hover over the select. You would like the title to reveal the current selected option? Did I understand you correctly?

    How to show option.Brand.Name as the title of the select field

    Curious, where this detail.ProductId comes from? Is the brand preselected by product-id (see your code)?

    ng-selected="option.Id === detail.ProductId"

    Solution space

    Your requirements/restrictions are:

    • without using JavaScript (maybe because you can't change the sources)
    • without changing the ng-model (because you need there only the BrandId for some database-reasons)

    So since the title of the select-element has no access to the options inside, the only way to set it is depending on the current selection, i.e. your detail.BrandId. So the title can only set dynamically (depending on the current selection) by using standard-angularJS means, as:

    Expected behavior

    The only scope-variable changed by selecting is specified within select's ng-model as detail.BrandId. This will be set when user selects an option to its property BrandId. When user selects between options they will be visible with ther BrandName as label. After selection this BrandName (label of the option) should be shown as title of the entire select element.

    So we need to get from detail.BrandId (selected ng-model) to related options BrandName (as this should show as title).

    Possible Solution

    Only way is to use standard angular expressions/filters/array-indexing to get the whole option by the selected detail.BrandId (ng-model)

    Then we can lookup the option.BrandName by this equation after selected detail.BrandId === option.BrandId

    var app = angular.module('app', []);
    
    app.controller('mainCtrl', function($scope){
      $scope.products = [
        {Id: 0, name: 'Watson', brandId: 1, brandName:"IBM"},
        {Id: 1, name: 'DB2', brandId: 1, brandName:"IBM"},
        {Id: 2, name: 'Windows', brandId: 2, brandName: "Microsoft"},
        {Id: 3, name: 'Office', brandId: 2, brandName: "Microsoft"}
      ];
      $scope.detail = { ProductId: 3, BrandId: null };
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.5/angular.min.js"></script>
    
    <!DOCTYPE html>
    <html>
      <body data-ng-app="app" data-ng-controller="mainCtrl">
          <table border="1">
            <tr>
    	  <th>Product Id</th><th>Product Name</th><th>Choose Brand</th><th>Brand Id</th>
            </tr>
            <tr>
              <td>{{detail.ProductId}}</td>
              <td>{{ (products | filter: {Id: detail.ProductId})[0].name }}</td>
              <td>
                <select class="form-control"
                 ng-model="detail.BrandId" 
                 ng-init="detail.BrandId = (products | filter: {Id: detail.ProductId})[0].brandId"
                 ng-options="o.brandId as ('['+ o.Id +'] '+ o.name +' : '+ o.brandName  +' ('+ o.brandId +')') for o in products"
                 title="{{ (products | filter: {brandId: detail.BrandId})[0].brandName}}"
                >
                  <!-- default option when not preset by detail.ProductId-->
                  <option value="">-- please choose brand --</option>
                </select>
            </td>
            <td>{{detail.BrandId}}</td>
          </tr>
        </table>
    
        <hr/>
          <p>Product is predefined. So the brand is pre-selected by product. BUT: after brand is selected, the product-details do NOT change!</p>
        Selected <strong>detail</strong>:
          <pre ng-model="selected">{{detail | json}}</pre>
       </body>
    </html>

    See also

    For using ng-options, see also plunkr example.