Angular ui-sref on dropdown not working - angularjs

I have an angular app with routing. I have a dropdown select defined as follows:
<select class="form-control" id="transactiontype" ng-model="tt">
<option><a ui-sref="cash">Cash</a></option>
<option><a ui-sref="cheque">Cheque</a></option>
<option><a ui-sref="debitcard">Debit</a></option>
<option><a ui-sref="creditcard">Credit</a></option>
</select>
When i select one of the dropdowns, somehow it is not loading the view i am referencing. Where am i going wrong? I also tried this:
<option ui-sref="creditcard">Credit</option>

I'm pretty sure it's because the a tags won't work inside the select - option tags.
As per this SO question: using href link inside option tag
Try writing a function that will redirect the page and trigger it based on the select change or maybe your model change, whatever it best for your program.
something like:
<select class="form-control" id="transactiontype" ng-model="tt" ng-change="locationChangeFunction()">
...
</select>
Your controller might look like:
angular.module('myApp')
.controller('myController', ['$scope', '$state', function ($scope, $state){
$scope.locationChangeFunction = function(){
$state.go($scope.tt);
}
}]);
EDIT
Use a combination of both solutions (credit to Hieu TB):
<select class="form-control" id="transactiontype" ng-model="tt" ng-options="opt.value as opt.label for opt in options" ng-change="locationChangeFunction()"></select>
ng-change will wait for the model change, which will change the DOM, which will trigger the change, now you're not running a resource consuming $watch function

consider using ng-options instead:
myApp.controller('MainController', ['$scope', '$state', function($scope, $state) {
$scope.options = [
{ label: 'Cash', value: 'cash' },
{ label: 'Cheque', value: 'cheque' },
{ label: 'Debit', value: 'debit' },
{ label: 'Credit', value: 'credit' }
];
$scope.$watch('tt', function(value) {
if(value) {
$state.go(value);
}
});
}]);
HTML:
<div ng-controller="MainController">
<select class="form-control" id="transactiontype" ng-model="tt" ng-options="opt.value as opt.label for opt in options">
</select>
</div>
EDIT: Agree with what #Likwid_T said, I think ng-change is the best choice to detect the change in select tag. I just forgot about it at that moment. So please refer to his answer too. Good day.

My solution ended up just using a generic href, but using the old ng-router declaration with a '#/' prefix. For example: instead of using...
<select class="form-control" id="transactiontype" ng-model="tt">
<option><a ui-sref="cash">Cash</a></option>
<option><a ui-sref="cheque">Cheque</a></option>
<option><a ui-sref="debitcard">Debit</a></option>
<option><a ui-sref="creditcard">Credit</a></option>
</select>
Try using href with '#/' prefix like so...
<select class="form-control" id="transactiontype" ng-model="tt">
<option>Cash</option>
<option>Cheque</option>
<option>Debit</option>
<option>Credit</option>
</select>

Related

Select default option with ng-options using a flat array

I'm generating <option>'s with ng-options using a flat array. The problem I'm having is selecting the default option element I already have defined. Seems to be a very simple task and there's tons and tons of similar questions using objects or array of objects, but everything I have found and tried for my situation does not work.
<div ng-app="MyApp">
<div ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt" data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.7.8/angular.min.js"></script>
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = '';
}]);
What I'm trying to do is select the "Choose Category" option by default. As plenty of others have already suggested in other questions, I have tried to use $scope.resultOpt = '' in my controller and even tried ng-init="resultOpt = ''", but does that not work at all. This works great for an array of objects, or objects but not with simple arrays. I also do not want to go outside of the AngularJS framework, I don't like mixing and matching vanilla and AngularJS code, things become messy.
I found an existing jsFiddle that is working for AngularJS 1.4.8, but at least for AngularJS 1.7.8, this is not working when used with a flat array. Not sure if it was functionality that was removed in later versions, or it's simply a bug.
Full example:
https://jsfiddle.net/v4uesg02/4/
How can I select the "Choose Category" option by default using a flat array without going outside of AngularJS framework?
How to select the hard-coded null option with ng-options and ng-model
To select the single hard-coded <option>, assign null to the model:
angular.module('MyApp', []).controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
̶$̶s̶c̶o̶p̶e̶.̶r̶e̶s̶u̶l̶t̶O̶p̶t̶ ̶=̶ ̶'̶'̶;̶
$scope.resultOpt = null;
}]);
From the Docs:
Optionally, a single hard-coded <option> element, with the value set to an empty string, can be nested into the <select> element. This element will then represent the null or "not selected" option.
For more information, see
AngularJS <select> Directive API Reference
The DEMO
angular.module('MyApp', [])
.controller('MyCtrl', ['$scope', function ($scope) {
$scope.testOpt = [
'ID',
'Name',
'Email',
'Address'
];
$scope.resultOpt = null;
}]);
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="MyApp" ng-controller="MyCtrl">
<select ng-options="opt as opt for opt in testOpt"
data-ng-model="resultOpt">
<option value="">Choose Category</option>
</select>
<br><br>
<button ng-click="resultOpt=null">Reset</button>
</body>
One thing i would like to add to #georgeawg's answer is to put disabled as an attribute to the option so that it is not reselect-able in the future
<option value="" disabled>Choose Category</option>

ng-model isn't updating when selecting an option

I have a form with with option list
<form class="column-form">
<select id="classSelection" ng-change="classOptionChange()" ng-model="selectedClass" maxHeight="120">
<option selected value="">{{classOptions}}</option>
</select>
</form>
Sample class options is here
[{"id":"classR","text":" Color - Red"},{"id":"classG","text":"Color - Green"}, {"id":"classY","text":"Color - Yellow"}]
My directive is simple as I'm just trying to print out the value of my selected option. However, it's always null.
(function() {
appModule.directive('classDefault', [ '$translate', '$timeout', '$window', classService, function($translate, $timeout, $window, $document, classService) {
return {
restrict : 'E',
scope : {
.......
}
link : function(scope, element) {
scope.classOptionChange() = function() {
console.log(scope.selectedClass);
Any suggestions?
UPDATE - Thanks for all the suggestions below. Apparently, we are using this widget that supposed to render the option lists and then bind to the select tag but it is currently broken.
You need to bind the array to the select tag. One option to do so is to use the NgOptions directive.
Here's an working example
angular.module("app",[]).controller("ctrl", function($scope){
$scope.items = [{"id":"classR","text":" Color - Red"},{"id":"classG","text":"Color - Green"}, {"id":"classY","text":"Color - Yellow"}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular.min.js"></script>
<div ng-app="app" ng-controller="ctrl">
<select ng-change="classOptionChange()"
ng-model="selectedClass"
maxHeight="120"
ng-options="item as item.text for item in items">
</select>
<h3>{{selectedClass}}</h3>
</div>
It seems like you are not properly rendering all options that have been passed down to your directive. Ideally you should loop over the classOptions collection using ng-repeat/ng-options directive and render the select tag filled option's. And then specify ng-value-"opt" on each of your option element. That will basically help you assign whole option object to selectedClass ng-model.
Template
<form class="column-form">
<select id="classSelection"
ng-change="classOptionChange()" ng-model="selectedClass"
maxHeight="120">
<option selected value="">Select option</option>
<option ng-value="opt" ng-repeat="opt in classOptions">{{opt.text}}</option>
</select>
</form>
Demo Plunker

Angular Select Tags

I am creating a select tag in angular. According to many sites I have read and some posts on here, it says when using the select tag to not use "ng-repeat" on the option tag but use "ng-options" on the select tag so that is how I set it up. My question is, I want a specific option tag selected by default, how do i set the selected attribute using this method?
<select class="form-control" ng-model="selected_group" ng-change="new_group($event)" ng-options="group as (group.group_name | decodeuri) for group in groups"></select>
Choosing a default is easy: set selected_group equal to a particular group in your controller.
The basic idea is that you have a collection and the selected option is to be stored in your ng-model. To designate a selection from the start, you need to put something in ng-model. That would have to be in your controller.
You could add an <option> tag:
<select class="form-control" ng-model="selected_group" ng-change="new_group(selected_group)" ng-options="group as (group.group_name | decodeuri) for group in groups">
<option value="">Please Select an Option</option>
</select>
Here I have created small working demo
<div ng-app="myApp" ng-controller="myCtrl">
<select class="form-control" ng-model="option.group" ng-options="group as (group.name | myfilter) for group in groups">
</select>
</div>
var app = angular.module('myApp', []);
app.filter('myfilter', function() {
return function(v) {
return v == 'test3' ? 'filtered test3' : v;
};
});
app.controller('myCtrl', function($scope) {
$scope.groups = [{id:1,name:'test1', phone:'1234567890'},
{id:2,name:'test2', phone:'1234567890'},
{id:3,name:'test3', phone:'1234567890'}
];
$scope.option={
group: $scope.groups[1]
}
});

angular 1.4.0 and selects: I don't understand the breaking change

Yesterday angular 1.4.0 was released.
The changelog states that there is a breaking change with "selects".
I used to use selects like this:
controller code:
// Default initial selection
$scope.filters = {
someFilter: false
};
view code:
<div class="form-group">
<label>Filter...</label>
<select class="form-control input-sm" ng-model="filters.someFilter">
<option value=""></option>
<option value="true">is true</option>
<option value="false">is false</option>
</select>
</div>
And the select would start with the option "is false" selected.
Now, with angular 1.4.0, that is not the case:
The selected option is "blank". I see two blanks in the rendered view (instead of one, as I did before)
How do I fix this?
As noted in the docs...
The value of a select directive used without ngOptions is always a string.
Essentially, you are trying to compare the string "false" with the boolean false.
One possible solution is to use ngOptions, eg
$scope.options = [
{ val: true, label: 'is true' },
{ val: false, label: 'is false' }
];
and in your template
<select ng-model="filters.someFilter"
ng-options="opt.val as opt.label for opt in options">
<option value=""></option>
</select>
Plunker
Alternatively, you could just use strings in your model, eg
$scope.filters = {
someFilter: "false"
};
Plunker

Reset select to default value with AngularJS

I have a following question for AngularJS. I have a
select with options created with ngOptions. I want to
set selected option back to default option. I tried to
delete model variable e.g:
if(angular.isDefined($scope.first)){
delete $scope.first;
}
But this not working. Here is my html.
<div ng-app="app">
<div ng-controller="testCtrl">
<select data-ng-model="first" data-ng-options="item.name for item in selectContent" required="required">
<option value="" style="display: none;">-- select --</option>
</select>
{{first.value}}
<hr/>
<input type="button" value="reset dropdown" data-ng-click="resetDropDown()"/>
</div>
</div>
And here is my JavaScript code:
angular.module('app', []).controller('testCtrl', function ($scope) {
$scope.selectContent = [
{
name: "first",
value: "1"
},
{
name: "second",
value: "2"
}
];
$scope.resetDropDown = function() {
if(angular.isDefined($scope.first)){
delete $scope.first;
}
}
});
Here is working jsfiddle:
http://jsfiddle.net/zono/rzJ2w/
How I can solve this problem?
Best regards.
Your reset-button is placed outside of the div containing your controller. This means that your reset-function does not exist in the context where you try to use it.
Change to:
<div ng-app="app">
<div ng-controller="testCtrl">
<select data-ng-model="first" data-ng-options="item.name for item in selectContent" required="required">
<option value="" style="display: none;">-- select --</option>
</select>
{{first.value}}
<hr/>
<input type="button" value="reset dropdown" data-ng-click="resetDropDown()"/>
</div>
</div>
It's always a good idea to use a debugger to make sure the code you're trying to fix is actually being executed.
$scope.resetDropDown = function() {
$scope.first = "";
}
Solution above works for Windows and Android, but did not work for iOS browsers. Probably events are happening in different order there.
So for my code I:
created ID for select element, so I could easily find it by
iQuery;
created delayed invocation of to statements to ensure the
reset is happenning at the very end;
and just in case was
resetting in two ways (but just first way was actually enough in iOS
too);
function resetDropDown () {
$timeout(function(){
$scope.first = '';
// jQuery way
$('select#idOfSelectElement option:first' ).prop( 'selected', true );
}, 200);
}

Resources