4

I have a dropdown (Select, option), and the options get populated dynamically using ng-repeat. I want to call a function within $scope on change of the option. Here is the HTML

<div class="type-style" ng-show="accountCount > 3">
     <select class="account-filter">
          <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option>
     </select>
</div>

I know we can use ng-change, but ng-change needs ng-model and I don't think ng-model is needed in my case. Can anyone help?

As you can notice in the code, I am doing and ng-repeat on option tag. So will I get that 'account' which I have used in ng-repeat, in the select tag? So that I can use it in ng-model?

Also, each account is a string that has 3 values separated by a '|'. When I call a function on ng-change, I want to pass the 2nd value with it.

For eg: Each account has Name | number | number2. Now in ng-repeat I am just showing name, as you can see I have done a split in ng-bind. So if I use ng-model in select tag, I will just get name. But I want number to be passed as parameter in the function.

1
  • If you want to use value of your current selected option of dropdown in function then ng-model will help you. use ng-change along with ng-model. Commented Apr 11, 2016 at 5:34

4 Answers 4

7

There is no problem in adding a ng-model because that will help you to use its value. For example:

<select class="account-filter" ng-change="customerSelected()" ng-model="selectedCustomer">
      <option ng-repeat="account in getCustomerName() track by $index"
          ng-class="(account | limitTo: 18)"
          ng-bind="account.split('|')[0]"
          value="{{account}}"></option>
</select>

Now you can read the selected customer's value in your controller by simply $scope.selectedCustomer.

Update

After updating the question with more description, you have two option:

Option 1 (recommended)

You can write like this (although, you can achieve much of it in the HTML itself but it is cleaner to do in the controller):

$scope.customerSelected = function() {
     var selectedCustomer = $scope.selectedCustomer;
     if (!selectedCustomer) {
          alert("Please select a customer");
          return;
     }

     var secondId = selectedCustomer.split('|')[2];
     // You can directly put your main logic here but since you want to
     // call a separate method with passing the id
     $scope.doSomethingWithCustomer(secondId);
};

$scope.doSomethingWithCustomer = function(id) {
    // Your main logic here after selecting the customer
};

and modify your HTML as I described above:

<select class="account-filter" ng-change="customerSelected()" ng-model="selectedCustomer">
      <option ng-repeat="account in getCustomerName() track by $index"
          ng-class="(account | limitTo: 18)"
          ng-bind="account.split('|')[0]"
          value="{{account}}"></option>
</select>

Option 2 (less cleaner)

$scope.doSomethingWithCustomer = function(id) {
    // Your main logic here after selecting the 2nd customer
};

and modify your HTML as:

<select class="account-filter" ng-model="selectedCustomer"
    ng-change="doSomethingWithCustomer(selectedCustomer.split('|')[2])">
      <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]" value="{{account}}"></option>
</select>

Option 3

If you want to achieve it without the ng-model and without jQuery then you can use a directive:

See a working example below.

var a = angular.module("sa", [])

a.controller("foobar", function($scope) {
  $scope.getCustomerName = function() {
    return ['Foo', 'Bar'];
  };

  $scope.customerSelected = function() {
    console.log("I'm changed");
    alert("I'm changed");
  };
});

a.directive("changeMe", function() {
  return {
    scope: {
      changeMe: '&'
    },
    link: function($scope, element, attr) {
      element.on("change", function() {
           $scope.changeMe();
      })
    }
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="sa" ng-controller="foobar">
  <select class="account-filter" change-me="customerSelected()">
    <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option>
  </select>
</div>

Sign up to request clarification or add additional context in comments.

5 Comments

I am adding some more information to my question. Do let me know if that makes sense.
<select class="account-filter" ng-model="selectedCustomer" ng-change="customerSelected(selectedCustomer.split('|')[0])"> <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option> </select> In this code, the problem is that in ng-model itself I will get the already split value. Because I am already doing a split in ng-bind within the option tag.
I may be talking rubbish, but I thought that ng-model will just give you the selected value text. So if the dropdown value itself is name, which was split from name|Number|Number2, in ng-model also will I not get just name? i want Number.
Modified the answer. Just need to add value="{{account}}" into the option tag.
Bingo!! You hit the right spot. Thanks man. I just posted another question. Similar to this, but I think if I use that instead of this, it could be a good solution. Can you check?
2

Just add a ng-change in select, ng-model is required for ng-change

<select class="account-filter" ng-change="fnName()" ng-model="account">
     <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option>
</select>

3 Comments

1 more thing. Do you notice the split in ng-bind? I am binding the 0th value of the split. Now on selection of any value, I want to send the 1st value of the split with the function. Any ideas?
I have added a few more details on the question. I think that will change the answer. Can you have a look please?
pass the account variable to that funtion, split the value in inside the function
0
<div class="type-style" ng-show="accountCount > 3">
     <select class="account-filter" id="detect_change">
          <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option>
     </select>
</div>
<script>
$('#detect_change').change(function() {
//change detect function
}
</script>

1 Comment

I don't want to use jquery for this man :) I want to do it the angular way.
0

You can use ng-change event

<script>
            
            var myapp=angular.module("my_app",[]);
            
            myapp.controller("my_ctrl",function($scope){
                
                
                $scope.your_function=function(s){
                
                alert(s);
            }
            
    });
            
</script>
<div ng-app="my_app" ng-controller="my_ctrl">

<div class="type-style" ng-show="accountCount > 3" >
     <select class="account-filter" ng-model="selected_model" ng-change="your_function({{selected_model}});">
          <option ng-repeat="account in getCustomerName() track by $index" ng-class="(account | limitTo: 18)" ng-bind="account.split('|')[0]"></option>
     </select>
</div>

</div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.