How to use a select option dropdown in an Angular Directive? - angularjs

Plunkr: http://plnkr.co/edit/pJRzKn2v1s865w5WZBkR?p=preview
I have 2 forms, a simple and advanced form.
Both have the same options (a lot of options)
Only a couple of differences in the opening select tag which contains
<select ng-show="showSimpleSelect"
ng-model="selected_tag"
ng-change="changeFormTag(formData)"
class="form-control manage-source-input-tag">
<!-- if advanced then -->
<select ng-show="showAdvanceSelect"
ng-model="formData.tag"
ng-change="changeTag(formData.tag)"
class="form-control manage-source-input-tag">
<option value="brand">Brand</option>
<option value="client">Client</option>
<option value="companies">Companies</option>
...
</select ng-show="showSimpleSelect">
</select ng-show="showAdvanceSelect">
In my Directives Controller, I'm using vars like this to show and hide the opening select tags:
vs.showSimpleForm = function() {
vs.showSimpleSelect = true,
vs.showAdvanceSelect = false,
However the HTML ends up looking like this, which breaks the design:
How would you go about refactoring this?

Angular overrides the select tag as a custom directive that expects an ng-options attribute instead of option tags. You can just hard-code your options into an array and put that as the ng-option
//controller
$scope.options = ["brand", "client", "companies"];
//html
<select ng-show="showAdvanceSelect"
ng-model="formData.tag"
ng-change="changeTag(formData.tag)"
ng-options="option for option in options"
class="form-control manage-source-input-tag">

Related

angular ng-model has not work in select tags

I am using ng-model on select tags, but those are a part of works. The code is
<select ng-model="uptpm.point" ng-if="uptpm.leval.length>0" class="form-control text-center nopaddingleft nopaddingright" ng-change="setPoint(uptpm)">
<option value="{{uptpml.value}}" ng-repeat="uptpml in uptpm.leval">{{uptpml.value}}</option>
</select>`
the view is
the datas struct.
Display effect
It's not recommended to use ngRepeat within select/option elements.
Take a look at https://docs.angularjs.org/api/ng/directive/ngOptions
Taken from angularjs docs:
The ngOptions attribute can be used to dynamically generate a list of elements for the element using the array or object obtained by evaluating the ngOptions comprehension expression.
I have wrote an example below:
Angular:
$scope.uptpm = [
{value: '0'},
{value: '4'}
];
$scope.point = 2;
HTML:
<select ng-model="point" ng-options="i.value as (i.value) for i in uptpm">
<option value="" selected>Please Select</option>
</select>
See this plunker for a working example:
http://plnkr.co/edit/Yl2ZynulIuk3ApG9jmTl

angularjs very simple yes/no boolean select directive not binding

I'm trying to write what must be the simplest angular directive which displays a Yes/No select list and is bound to a model containing a boolean value. Unfortunately the existing value is never preselected. My directive reads
return {
restrict: 'E',
replace: true,
template: '<select class="form-control"><option value="true">Yes</option><option value="false">No</option></select>',
scope: {
ngModel: '='
}
}
and I am calling the directive as
<yesno ng-model="brand.is_anchor"></yesno>
The select options display and the generated HTML reads as
<select class="form-control ng-isolate-scope ng-valid" ng-model="brand.is_anchor">
<option value="? boolean:false ?"></option>
<option value="true">Yes</option>
<option value="false">No</option>
</select>
The initial value of the bound model is "false" but it always displays an empty option and per the first option listed in the generated HTML.
Can anybody please advise?
You may not use <option> tags with angularjs.
Use the angular "ng-options" directive on the select element instead.
<select ng-options="..."></select>
See angular docs for it:
https://docs.angularjs.org/api/ng/directive/ngOptions
Your problems will be solved using this instead.
see we have to use <select ng-options="..."></select>
as per the angular js documentation or
we have to apply workaround for it by adding ng-selected directive of angular js so your code will be
<select class="form-control ng-isolate-scope ng-valid" ng- model="brand.is_anchor">
<option value="? boolean:false ?"></option>
<option value="true" ng-selected="brand.is_anchor == true">Yes</option>
<option value="false" >No</option>
</select>
This extra workaround we have to apply if we dont want to use
<select ng-options="..."></select>

Placeholder is not working in angularjs select2

Here is the code which i was tried. i tried to add placeholder with angularjs code and html code but it is not working in both the case. please help me or suggest me how to do in this case
<select ui-select2="select2Options"
style="width:100%"
ng-model="SelectedProcessandIngredients"
data-placeholder="Select or Add Process/Ingredient"
ng-options="c.name group by c.status for c in colors"
ng-change="selectedinnerLoop()" >
</select>
Angular js Code:
$scope.select2Options = {
placeholder : "Select or Add Process/Ingredient",
formatResult : processList,
formatSelection : processList,
escapeMarkup : function (m) {
return m;
}
};
Add an empty option tag inside your select tag and the placeholder will be shown.
Also, use ng-repeat instead of ng-options. Select2 is incompatible with ng-options.
<select ui-select2 ng-model="select2" data-placeholder="Pick a number">
<!-- empty option gets placeholder working -->
<option value=""></option>
<!-- ng-repeat to populate dynamic options -->
<option ng-repeat="number in range" value="{{number.value}}">{{number.text}}</option>
</select>

Angular UI / select2 multiple how to preselect values/options?

using angular-ui with select2 as follows:
<select ui-select2 ng-model="search.categories" multiple style="width:300px" data-placeholder="select category">
<option value="open" >open</option>
<option value="close" >close</option>
</select>
Where and how should I preselect options? By default selected option is only first.Somehow in controller?
For a simple <select> list it's easy:
MyController function($scope) {
$scope.search = {
categories: 'close'
};
}
For <input> it gets trickier because you may need to add a initSelection option

How to set the value attribute for select options?

Source JSON data is:
[
{"name":"Alabama","code":"AL"},
{"name":"Alaska","code":"AK"},
{"name":"American Samoa","code":"AS"},
...
]
I try
ng-options="i.code as i.name for i in regions"
but am getting:
<option value="?" selected="selected"></option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
while I am expecting to get:
<option value="AL">Alabama</option>
<option value="AK">Alaska</option>
<option value="AS">American Samoa</option>
So, how to get value attributes and get rid of "?" item?
By the way, if I set the $scope.regions to a static JSON instead of AJAX request's result, the empty item disappears.
What you first tried should work, but the HTML is not what we would expect. I added an option to handle the initial "no item selected" case:
<select ng-options="region.code as region.name for region in regions" ng-model="region">
<option style="display:none" value="">select a region</option>
</select>
<br>selected: {{region}}
The above generates this HTML:
<select ng-options="..." ng-model="region" class="...">
<option style="display:none" value class>select a region</option>
<option value="0">Alabama</option>
<option value="1">Alaska</option>
<option value="2">American Samoa</option>
</select>
Fiddle
Even though Angular uses numeric integers for the value, the model (i.e., $scope.region) will be set to AL, AK, or AS, as desired. (The numeric value is used by Angular to lookup the correct array entry when an option is selected from the list.)
This may be confusing when first learning how Angular implements its "select" directive.
You can't really do this unless you build them yourself in an ng-repeat.
<select ng-model="foo">
<option ng-repeat="item in items" value="{{item.code}}">{{item.name}}</option>
</select>
BUT... it's probably not worth it. It's better to leave it function as designed and let Angular handle the inner workings. Angular uses the index this way so you can actually use an entire object as a value. So you can use a drop down binding to select a whole value rather than just a string, which is pretty awesome:
<select ng-model="foo" ng-options="item as item.name for item in items"></select>
{{foo | json}}
If you use the track by option, the value attribute is correctly written, e.g.:
<div ng-init="a = [{label: 'one', value: 15}, {label: 'two', value: 20}]">
<select ng-model="foo" ng-options="x for x in a track by x.value"/>
</div>
produces:
<select>
<option value="" selected="selected"></option>
<option value="15">one</option>
<option value="20">two</option>
</select>
If the model specified for the drop down does not exist then angular will generate an empty options element. So you will have to explicitly specify the model on the select like this:
<select ng-model="regions[index]" ng-options="....">
Refer to the following as it has been answered before:
Why does AngularJS include an empty option in select? and this fiddle
Update: Try this instead:
<select ng-model="regions[index].code" ng-options="i.code as i.name for i in regions">
</select>
or
<select ng-model="regions[2]" ng-options="r.name for r in regions">
</select>
Note that there is no empty options element in the select.
You could modify you model to look like this:
$scope.options = {
"AL" : "Alabama",
"AK" : "Alaska",
"AS" : "American Samoa"
};
Then use
<select ng-options="k as v for (k,v) in options"></select>
It appears it's not possible to actually use the "value" of a select in any meaningful way as a normal HTML form element and also hook it up to Angular in the approved way with ng-options. As a compromise, I ended up having to put a hidden input alongside my select and have it track the same model as my select, like this (all very much simplified from real production code for brevity):
HTML:
<select ng-model="profile" ng-options="o.id as o.name for o in profiles" name="something_i_dont_care_about">
</select>
<input name="profile_id" type="text" style="margin-left:-10000px;" ng-model="profile"/>
Javascript:
App.controller('ConnectCtrl',function ConnectCtrl($scope) {
$scope.profiles = [{id:'xyz', name:'a profile'},{id:'abc', name:'another profile'}];
$scope.profile = -1;
}
Then, in my server-side code I just looked for params[:profile_id] (this happened to be a Rails app, but the same principle applies anywhere). Because the hidden input tracks the same model as the select, they stay in sync automagically (no additional javascript necessary). This is the cool part of Angular. It almost makes up for what it does to the value attribute as a side effect.
Interestingly, I found this technique only worked with input tags that were not hidden (which is why I had to use the margin-left:-10000px; trick to move the input off the page). These two variations did not work:
<input name="profile_id" type="text" style="display:none;" ng-model="profile"/>
and
<input name="profile_id" type="hidden" ng-model="profile"/>
I feel like that must mean I'm missing something. It seems too weird for it to be a problem with Angular.
you can use
state.name for state in states track by state.code
Where states in the JSON array, state is the variable name for each object in the array.
Hope this helps
Try it as below:
var scope = $(this).scope();
alert(JSON.stringify(scope.model.options[$('#selOptions').val()].value));

Resources