0

I cannot figure out why data binding is not working on a select tag, as the docs specifies.

This is my select element:

<select id="start-type" ng-model="startType">
  <option value="day-of-week">Day of the week</option>
  <option value="month">Month</option>
  <option value="month-day">Day and month</option>
  <option value="year">Year</option>
  <option value="year-month">Month and year</option>
  <option value="local-time" selected>Time</option>
  <option value="local-date">Date</option>
  <option value="local-date-time">Date and time</option>
</select>
<label for="start-type">Start type</label>

The issue is that whenever an item is selected the $scope.startType model is never changed. It's always blank.

I have tried defining $scope.startType in my controller but I don't see why that would change anything because it should work as it already is. And of course, it didn't help.

I have gone through several working examples, but I can't see what I am missing here.

Edit: I figured out what's happening. The CSS framework I am using didn't have Angular in mind at all. It is rendering a custom view for a select using its own divs and layout, while hiding the actual select element. But they didn't even hook the select action into the hidden select, so the angular directives or data binding are never being triggered... Any clue on how I could put it all together?

2
  • "so the angular directives or data binding are never being triggered... Any clue on how I could put it all together?" - this needs to be asked as a separate question
    – jusopi
    Commented Jul 14, 2016 at 18:12
  • @jusopi yeah I know, I found out about the actual issue after creating this question.
    – dabadaba
    Commented Jul 14, 2016 at 18:38

3 Answers 3

3

In order to bind to a pre selected value on the select's ng-model, you need to use ng-options instead.

<select id="start-type" 
        ng-model="startType" 
        ng-options="type.value as type.label for type in startTypes">

Where startTypes is defined on your controller:

$scope.startTypes = [{value:'day-of-week', label:'Day of Week'}, ...]

edit

Per @John S's comment below, you might want to add a default/blank option when the $scope.startType == undefined so that the UI renders correctly.

<option ng-selected="true" value="">select a market vertical</option>

source = Why does AngularJS include an empty option in select?

8
  • In my experience this directive will not behave properly unless you have just one option tag that looks like <option value=""></option>. Other than this this answer is the right way to do it.
    – John S
    Commented Jul 14, 2016 at 16:47
  • agreed, and I wish the angular team would've done a better job at handling such cases. I did answer a related issue here - stackoverflow.com/questions/12654631/…
    – jusopi
    Commented Jul 14, 2016 at 16:49
  • it is actually in the AngularJS docs but they dont make a big deal of it. I missed it several times. Generally what happens is you will get the wrong index selected on the model. Super confusing.
    – John S
    Commented Jul 14, 2016 at 16:52
  • isn't there a way to make it work with fixed values in the html? The css framework I am using doesn't render the options properly if used in this fashion. It only does the other way.
    – dabadaba
    Commented Jul 14, 2016 at 16:54
  • @dabadaba it may be a value/reference type issue. Try changing $scope.startTypes to $scope.something.startTypes
    – John S
    Commented Jul 14, 2016 at 16:56
1

I would use ng-model, and ng-change. Ng-change would be evaluated whenever the selected value is changed.

1

I can see it working. Check out the snippet below

  • Make sure you have the controller and the app declared correctly
  • Also use try using ng-options and have the values come from the controller like in this example.

angular.module('demo', []).controller('DemoController', function($scope) {
  $scope.logModelValue = function() {
    console.log($scope.startType);
  };
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<body ng-app="demo">
  <div ng-controller="DemoController">
    <label for="start-type">Start type</label>
    <select id="start-type" ng-model="startType" ng-change="logModelValue()">
      <option value="day-of-week">Day of the week</option>
      <option value="month">Month</option>
      <option value="month-day">Day and month</option>
      <option value="year">Year</option>
      <option value="year-month">Month and year</option>
      <option value="local-time" selected>Time</option>
      <option value="local-date">Date</option>
      <option value="local-date-time">Date and time</option>
    </select>
    <span>{{startType}}</span>
    <button ng-click="logModelValue()">Console log model value</button>
  </div>
</body>

EDIT
Looks like the trouble is with getting materializecss and angular working together. You could either write your own angular wrappers over materializecss or use this library angular-materialize

7
  • I have tried setting up ng-change on the select tag and ng-click on any of the options to trigger a dummy method that logs something and none work.
    – dabadaba
    Commented Jul 14, 2016 at 16:46
  • Updated the snippet. I have added ng-change as well. It works. Can you try as in the snippet above?
    – Srijith
    Commented Jul 14, 2016 at 16:50
  • Yeah I tried something like that and as I said nothing is logged. The ng-change directive isn't being triggered.
    – dabadaba
    Commented Jul 14, 2016 at 16:56
  • Can you post your entire code here? Not sure how I can help without seeing the whole thing!
    – Srijith
    Commented Jul 14, 2016 at 16:57
  • I copied the select block directly from my project. What else would you need?
    – dabadaba
    Commented Jul 14, 2016 at 16:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.