Set default selection of Dropdown using Backbone - backbone.js

My question is quiet similar to set-dropdown-selected-value-with-backbone, with minor difference that I don't want to manipulate the DOM thru jQuery.
For this what I have done is:-
Assuming my DropDown is of type UserType
var userType = backbone.Model.extend({
idAttribute: "TypeId",
defaults: {
TypeId: null,
TypeName: null,
Selected: false
}
});
Here, I have created an extra attribute as Selected, which I am using as below in my Handlebar template.
<select id="userType" name="UserTypeId" class="input-medium form-control">
{{#each MasterUserType}}
<option id="{{TypeId}}" selected="{{Selected}}">{{TypeName}}</option>
{{/each}}
</select>
Okay, now when I get my Data thru api- say(example)
[
{
"TypeId":1,
"TypeName":"Admin"
},
{
"TypeId":2,
"TypeName":"User"
},
{
"TypeId":3,
"TypeName":"Super Admin"
}
]
Now, I manipulate my variable MasterUserType to become something like below:-
[
{
"TypeId":1,
"TypeName":"Admin",
"Selected":""
},
{
"TypeId":2,
"TypeName":"User",
"Selected":"selected"
},
{
"TypeId":3,
"TypeName":"Super Admin",
"Selected":""
}
]
So my HTML which renders is :-
<div class="controls">
<select id="userType" name="TypeId" class="input-medium form-control">
<option id="" selected="">Admin</option>
<option id="" selected="selected">User</option>
<option id="" selected="">Super Admin</option>
</select>
</div>
But still it reflects the first Item....
Can anyone tell me what is wrong? Or any other alternative?
Lastly, can we achieve this requirement from some other better way?
I have tried replacing "selected with true" but it doesn't work.

Try updating your template as below:
<select id="userType" name="UserTypeId" class="input-medium form-control">
{{#each MasterUserType}}
{{#if Selected}}
<option id="{{TypeId}}" selected="{{Selected}}">{{TypeName}}</option>
{{else}}
<option id="{{TypeId}}">{{TypeName}}</option>
{{/if}}
{{/each}}
</select>

Related

AngularJs ng-options repeat into repeat

Have code:
<tr data-ng-repeat="item in data.items">
<td>{{item.Id}}</td>
<td>
<div>
{{ data.items[$index].selectedBusinessType.id }}
{{ data.items[$index].businessTypes[$index].id }}
<select ng-options="businessType.name for businessType
in item.businessTypes track by businessType.id"
data-ng-model="item.businessTypes.id == item.selectedBusinessType.id">
</select>
</div>
</td>
</tr>
In div models result is ok, but dropdown still didn't work
DropDown without value screen
Scope data from back
Can i get some solution what i doing wrong?
You will probably need filter. Try something like: (plunker: https://next.plnkr.co/edit/DiInzWMC2k8WZzuH)
<select class="form-control" ng-model="$scope.data.items[0].selectedBusinessType.id" ng-options="businessType.name for businessType in item.businessTypes | filter:doFilter(item.selectedBusinessType)">
</select>
And in controller:
$scope.doFilter = function(id) {
console.log("selectedId:" + Object.values(id))
return function(value, index, array) {
console.log(value.id)
if(value.id == Object.values(id))
return true;
}
};
Relate to the answer in https://stackoverflow.com/a/39635805/4952634
On angularJs version 1.5 work option like this:
Plunk - Use angularJs 1.5x
<select class="form-control" ng-model="data.items[$index].selectedBusinessType.id"
ng-disabled="item.CanChangeBusinessType"
ng-change="changeBusinessType(item, selectedBusinessType.id)">
<option ng-repeat="businessType in item.businessTypes" ng-value="businessType.id">
{{businessType.id}}
</option>
</select>
But this don't work on version 1.4+.
Plunk - Use angularJs 1.4x
<div>
<select class="form-control" ng-model="data.items[$index].selectedBusinessType.id"
ng-disabled="item.CanChangeBusinessType"
ng-change="changeBusinessType(item, selectedBusinessType.id)">
<option ng-repeat="businessType in item.businessTypes" ng-value="businessType.id">
{{businessType.id}}
</option>
</select>
</div>
Second worked option - use ng-option:
Ng-Option using
<select class="form-control" ng-model="item.selectedBusinessType"
ng-options="option.id as option.name for option in data.businessTypes"
ng-disabled="item.CanChangeBusinessType"
ng-change="changeBusinessType(item, item.selectedBusinessType, '{{item.selectedBusinessType}}')">
<option value="">-- Не указан --</option>
</select>

How to display selected name in <p> from a Select dropdown and send selected id to controller in AngularJS?

I have the following select input in my html which is populated using ng-options. I want to show the selected NAME down below in whereas I want to send the selected ID back to the controller. I get the required id from ng-model="user.category". How can I show the selected name? I also show the names in options.
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.retailerBranchId}}</p>
<select ng-model="user.category" ng-options="category for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}">Select a Category</option>
</select>
<p>Available On : {{user.category.id}}</p>
If you make retailerBranchId a method you can do it with something like lodash' _.find() (or even native find). You have user.category updating according to your selection, which you say has the id in it, which you can use:
function retailerBranchId() {
return _.get(_.find(this.categories, { id: user.category }), 'name', '');
}
This also fails gracefully; if it can't find any name, or any item that matches the id, it'll return an empty string.
Edit: You would call it in a similar fashion like so:
<p>Available on: {{ user.retailerBranchId() }}</p>
Although really, it's better to use it like this:
<p data-ng-bind="'Available on: ' + user.retailerBranchId()"></p>
Can you try like a below method,
Controller to get selected Category Name:
$scope.getSelectedCategoryDetail=function(selectedCat){
angular.forEach($scope.categories, function(cat){
if(selectedCat===cat.id){
$scope.user.name=cat.name;
}
});
};
Template to have ng-change event:
<select ng-model="user.category" ng-options="category.id as category.name for category in categories" class="form-control" class="select" required>
<option value="{{category.name}}" ng-change="getSelectedCategoryDetail(user.category)">Select a Category</option>
</select>
<p>Category Id : {{user.category}}</p>
<p>Category Name : {{user.name}}</p>

AngularJS: dynamic custom directive with multiple templates

I'm a Java developer working on a side-project. I've decided to use AngularJS to consume my RESTful webservice.
My JSON structure is following:
[
{
"generatorName": "name1",
"constructorParams": [
{
"type": "Boolean",
"value": "true",
},
{
"type": "Integer",
"value": "2",
}
]
},
{
"generatorName": "name2",
"constructorParams": [
{
"type": "Integer",
"value": "10",
},
{
"type": "Integer",
"value": "10",
}
]
}
]
My goal is to display a specific (for ex. number, text etc.) input field based on the "type" of constructor param and initialise it with a "value". So, if the first generator was selected, I'd like to have something like this:
<html>
<select>
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<input type="number" value="2">
<html>
I've read some threads and decided to use custom directive inside my loop:
<p ng-repeat="param in selectedGenerator.constructorParams">
<constructor-param param="{{param}}"></constructor-param>
</p>
Here's my custom directive:
app.directive("constructorParam", function() {
return {
scope : {
param : '#'
},
templateUrl : '/html_templates/constructor_param_template.html'
};
});
And here's template:
<div ng-switch="{{param.type}}">
<div ng-switch-when="Integer">
<input type="number" ng-attr-name="{{param.type}}" min="0" ng-attr-value="{{param.value}}">
</div>
<div ng-switch-when="Boolean">
<select ng-if="{{param.value}}" ng-attr-name="{{param.type}}">
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<select ng-if="!{{param.value}}" ng-attr-name="{{param.type}}">
<option value="true">Yes</option>
<option selected="selected" value="false">No</option>
</select>
</div>
<div ng-switch-when="String">
<input type="text" ng-attr-name="{{param.type}}" ng-attr-value="{{param.value}}">
</div>
<div ng-switch-when="Double">
<input type="number" ng-attr-name="{{param.type}}" step="0.01" min="0" ng-attr-value="{{param.value}}">
</div>
</div>
These don't work. I can see in the Chrome developer's tools that the directive is run, but it doesn't provide any visible output. My questions are:
1) Do I pass the param object correctly in the custom directive element?
2) I'm not sure about the scope of the directive - I've also tried param : '=param' - it doesn't work either...
3) How should I read the passed object's properties in the template? I've tried: value="{{param.type}}", value={{param.type}} and ng-attr-value="{{param.value}}". None works, but there could be completely different cause to that...
4) Can I use prefix "ng-attr-" for all such element's HTML attributes as name and value?
5) My template's code is exactly what I've pasted - do I need to make it a valid HTML structure with head, body etc.? Do I have to attach <script> with AngularJS? I've done that, but once again, no change.
6) The usage scenario for the whole story is to choose a concrete generator from a drop-down list and display it's constructor params in the specified way. So it has to regenerate HTML with a generator's change. I assume that it's done in the ng-repeat loop but please confirm that.
Thank you very, very much for your input! :)
When you do param : '#' that's a "text binding". That's useful in case you want to tell Angular to not interpret what you're binding to your attribute as a property on the scope but rather as a string directly.
So if you'd do
<my-custom-directive param="hello"></my-custom-directive>
Then in your directive, param would be equal to the the string "hello". While if you bind to param using two-way binding param : '=', then Angular would look for the hello property on the scope instead of taking it as a string literal.
In your case, when you do param="{{param}}" Angular is first unpacking "param" by looking at the scope, into a string literal, then it creates the binding. So even though this might have worked if param was a string, in your case it's an Object, so I don't think it will play well. So I would just do a direct binding to it (see my final code below).
In your directive template, you're also using a few Angular directive which expect a scope binding, so I would try to bind without the curly brackets. See my example code below.
app.directive("constructorParam", function() {
return {
scope: {
param: '='
},
templateUrl: '/html_templates/constructor_param_template.html'
};
});
<!-- container -->
<p ng-repeat="param in selectedGenerator.constructorParams">
<constructor-param param="{{param}}"></constructor-param>
</p>
<!-- TEMPLATE -->
<div ng-switch="param.type">
<div ng-switch-when="Integer">
<input type="number" ng-attr-name="param.type" min="0" ng-attr-value="param.value">
</div>
<div ng-switch-when="Boolean">
<select ng-if="param.value" ng-attr-name="param.type">
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<select ng-if="!param.value" ng-attr-name="param.type">
<option value="true">Yes</option>
<option selected="selected" value="false">No</option>
</select>
</div>
<div ng-switch-when="String">
<input type="text" ng-attr-name="param.type" ng-attr-value="param.value">
</div>
<div ng-switch-when="Double">
<input type="number" ng-attr-name="param.type" step="0.01" min="0" ng-attr-value="param.value">
</div>
</div>
If it still doesn't work, let me know so I can try it in a CodePen.
1) No, you need to remove the curly brackets when passing the values to directive
<constructor-param param="param"></constructor-param>
2,3) in directive use = instead of #. Because # take string value of the parameter and = take the parameter value
scope: {
param: '='
},
4) if you need to bind data then use ng-model instead of ng-attr
5) You don't need to add html or body tag inside constructor_param_template.html template.
6) ng-repeat does that. once the array get updated it will dynamically update the DOM
Demo
First of all, thank you both guys for your help! Unfortunately, I can't mark any of the given answer as correct, because I have to mixed them in order to get what I was looking for.
I wouldn't elaborate here, let me just share with you the final code:
<!-- container -->
<p ng-repeat="param in selectedGenerator.constructorParams">
<constructor-param param="param"></constructor-param>
</p>
<!-- template -->
<div ng-switch="param.type">
<div ng-switch-when="Integer">
<input type="number" name={{param.type}} min="0" value={{param.value}}>
</div>
<div ng-switch-when="Boolean">
<select ng-if="param.value" name={{param.type}}>
<option selected="selected" value="true">Yes</option>
<option value="false">No</option>
</select>
<select ng-if="!param.value" name={{param.type}}>
<option value="true">Yes</option>
<option selected="selected" value="false">No</option>
</select>
</div>
<div ng-switch-when="String">
<input type="text" name={{param.type}} value={{param.value}}>
</div>
<div ng-switch-when="Double">
<input type="number" name={{param.type}} step="0.01" min="0" value={{param.value}}>
</div>
</div>
And here's the directive, you both get it right:
app.directive("constructorParam", function() {
return {
scope: {
param: '='
},
templateUrl: '/html_templates/constructor_param_template.html'
};
});
Once again - thank you very much, I wouldn't solve this problem so quickly without your help!

how to render the options inside angular select box

How do i render the values inside dropdown(selectbox options).
I need to show 'header' and 'footer' names inside selectbox.
$scope.sections = [
{
"header":{
"background-color":"#fff",
"color":"#fff"
},
"footer":{
"background-color":"#fff",
"color":"#fff"
}
}
];
I tried in the following way but not working,
<select name="section" class="form-control" ng-model ="section">
<option ng:repeat="options[0] in sections">
{{options[0]}}
</option>
</select>
You need to iterate over keys instead of values.
<option ng-repeat="(option, val) in sections[0]">
{{option}}
</option>
Or with ng-options
ng-options="option for (option, val) in sections[0]"
see the plunker
http://plnkr.co/edit/FQEooL5wNh8Xl8GprT99?p=preview

Using both <select>'s value AND text for ng-model

I currently have this:
<div>
<label for="market-type">Market Type</label>
<select id="market-type" type="text" ng-model="tradingFee.market_type">
<option value="stock">Stock Market</option>
<option value="otc">OTC Market</option>
</select>
</div>
which assigns the selected option's value to tradingFee.market_type. What I wish is to be able to do this plus assign the selected option's text to tradingFee.market_type_human_friendly_text, for example. Only being able to do one of the assignments is not enough. Is this possible somehow?
You could do this, but not with this syntax. use ng-options so that the ng-model holds both value and display name.
In your controller set array of objects:
$scope.marketType = [{id:"stock", displayName:"Stock Market"}, {id:"otc", displayName:"OTC Market"}];
and
<select id="market-type" type="text"
ng-model="tradingFee.market_type"
ng-options="mt.displayName for mt in marketType track by mt.id">
<option value="">--Select--</option>
</select>
Now the ng-model will have both id as well as value. i.e example:
tradingFee.market_type will be {id:"otc", displayName:"Stock Market"} if you select that specific item from the dropdown. With this you do not have to worry about maintaining 2 separate properties for displayName and id.
angular.module('app', [])
.run(function($rootScope) {
$rootScope.marketType = [{
id: "stock",
displayName: "Stock Market"
}, {
id: "otc",
displayName: "OTC Market"
}];
$rootScope.tradingFee = {
market_type: {
id: 'stock'
}
};
});
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app">
<select id="market-type" type="text" ng-model="tradingFee.market_type" ng-options="mt.displayName for mt in marketType track by mt.id">
<option value="">--Select--</option>
</select>
{{ tradingFee.market_type }}
</div>
You could just use ng-change on your select to fire a custom event handler that sets the secondary value.
<select id="market-type" type="text" ng-model="tradingFee.market_type"
ng-change="updateSecondary()">
<option value="stock">Stock Market</option>
<option value="otc">OTC Market</option>
</select>

Resources