I seem to have trouble setting a default value for a select dropdown with AngularJS. I have read similiar topics on StackOverflow, but none of the proposed solutions worked for me, so I decided to finally ask you guys :)
Bascically I want to implement an entry editing functionality in my app. So, the user clicks on the edit button, a modal pops up with a form with values filled from the object that was passed to the modal controller. I mean all of the values, but the "category" which I want to be presented as a dropdown select.
I think it's going to be easier to show in code, so I prepared this fiddle:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.dataReceived = {
category: "FOOD"
}
$scope.availableCategories = {
FOOD: "Food and drinks",
FREE_TIME: "Free time",
HOUSING: "Housing costs"
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="form-group">
<label for="select-category">Select category:</label>
<select class="form-control" id="select-category" ng-model="dataReceived.category" required>
<option ng-repeat="(key,value) in availableCategories" ng-value="key">
{{value}}
</option>
</select>
</div>
</div>
I tried different ways of fixing it, but none have worked so far so please help! All I want to do is for the dropdown to say "Food and drinks" by default if passed object's category is "FOOD".
Cheers!
I think you should try to use ng-options with key value pairs instead.
Like this:
var myApp = angular.module('myApp', []);
function MyCtrl($scope) {
$scope.dataReceived = {
category: "FOOD"
}
$scope.availableCategories = {
FOOD: "Food and drinks",
FREE_TIME: "Free time",
HOUSING: "Housing costs"
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div class="form-group">
<label for="select-category">Select category:</label>
<select class="form-control" id="select-category" ng-model="dataReceived.category" ng-options="key as value for (key , value) in availableCategories " required>
</select>
</div>
</div>
Hope it helps.
Related
I'm using UI-Bootstrap so I can use them both Angular and bootstrap. I want to access the value from a select tag that the "controllerCountries" controller have and use that value as a parameter to the fill the select "selectedServices". I want to do that because the logic of the program will be that when I choose a country of a list of countries in a select tag, use that value to fill the another select tag.
My HTML is here:
<div style="margin-top: 15px" class="col-md-6">
<div id="form-pais"class="form-group">
<label class=" control-label">Country:</label>
<div class="selectContainer">
<select ng-controller="controllerCountries" class="form-control" id="abvCountry" name="abvCountry" ng-model="countrySelected">
<option value="gt">Guatemala</option>
<option value="sl">El Salvador</option>
<option value="hn">Honduras</option>
</select>
</div>
</div>
</div>
<div style="margin-top: 15px" class="col-md-6">
<div class="form-group">
<label class=" control-label">Services:</label>
<div ng-controller="controllerServices" class="selectContainer">
<select class="form-control" id="selectServices"ng-model="servicios" ng-options="y for (x, y) in serviciosgt" text="">
</select>
</div>
My JS file looks like that:
//Heres the list of services in the objects. I use this to fill the second select.
app.controller('controllerServices', function($scope)
{
$scope.serviciosgt =
{
consMiami : "Consolidación Miami",
contCompletosGT: "Contenedores Completos",
cargMartConsolidadGT : "Carga Maritima Consolidada",
cargAereaRegularGT: "Carga Áerea Regular"
};
$scope.serviciosSL =
{
contCompletosSl : "Contenedores Completos",
cargMartConsolidadSl: "Carga Marítima Consolidada",
cargAereaRegularSl: "Carga Áerea Regular"
};
$scope.serviciosHN =
{
contCompletosHN : "Contenedores Completos",
cargMartConsolidadHN: "Carga Marítima Consolidada",
cargAereaRegularHN: "Carga Áerea Regular"
};
});
//Heres the controller to fill.
app.controller('controllerCountries', function($scope)
{
$scope.countrySelected ='';
$scope.$watch('countrySelected', function () {
if($scope.countrySelected=="gt")
{
console.log("Select GT");
}
else if($scope.countrySelected=="sl")
{
console.log("Select SL");
}
else if($scope.countrySelected=="hn")
{
console.log("Select HN");
}
});
});
Right now I can access the value of the first "controllerCountries" and log that value on the console, but thats it. And, as you can see, I fill the select with the first object, but I wan them to be dinamic. Can anyone help me please. And if you look that my code is wrong, youre welcome to fix it.
Greetings and thanks.
HTML view
First of all, you don't need that $watch, you can use ng-change to fire a callback when the select value (ng-model) is changed. you can write your if statements there.
Second, don't use ng-controller on a select, you have ng-options to dynamically place nested <option> elements inside the <select>.
Lastly, if you want to fill select number 2 using a value you've selected from select number 1, just reference the correct data when the ngChange callback is fired
$scope.onCountryChange = function (country) {
if(country=="gt")
{
console.log("Select GT");
$scope.serviciosgt = { ... };
}
else if(country=="sl")
{
console.log("Select SL");
$scope.serviciosgt = { ... };
}
else if(country=="hn")
{
console.log("Select HN");
$scope.serviciosgt = { ... };
}
};
your select could look something like this
<select class="form-control"
name="abvCountry"
ng-change="onCountryChange(countrySelected)"
ng-options="country for country in countries" ng-model="countrySelected">
</select>
While
$scope.countries = ["gt", "sl", "hn"];
I have a <select> in my application, which is supplied data from an ng-repeat but each option in the select has data of it's own. Simply enough, here is the JSON payload I am working with:
{
"0":{
"name":"Mover",
"scalar":[
{
"name":"Size",
"unit":"m"
},
{
"name":"Speed",
"unit":"m/s"
}
]
},
"1":{
"name":"Stationary",
"scalar":[
{
"name":"Size",
"unit":"m"
}
]
},
"2":{
"name":"Vibrator",
"scalar": [
{
"name":"Frequency",
"unit":"hz"
}
]
}
}
I need the outer 3 names in the select, but I'd like the 'scalar' values to show up as checkboxes next to the select. It's obviously got to be dynamic, so i was curious if there was a way to do this based off of the ng-repeat of the select. Another reason why I am asking is because due to formatting, I'd like to place the checkboxes outside of the ng-repeat (clearly since that's in a select) so not too sure how the checkboxes would access the repeat value. Below is the html snippet:
<div id="type-selection"
class="row ng-hide"
ng-show="rcw.page ==='Type Selection'">
<div class="col-md-6">
<div class="form-group">
<label for="rule-type">Type</label>
<select id="rule-type"
class="form-control"
ng-model="rcw.selectedRuleType">
<option ng-repeat="type in rcw.QueryTypes">{{type.name}}</option>
</select>
</div>
</div>
<div class="col-md-2" ng-repeat="ideally scalar in type from above^">
<label>
<input type="checkbox"
class="faChkSqr"
ng-model="ideally this would be dynamically tied to scalar.name </input>
<span></span>
<b>{{ideally this would be scalar.name}}</b>
</label>
</div>
</div>
Just not too sure if this is possible, or if I need to handle what's selected then from there in the javascript decide what needs to be displayed? Thanks in advance!
You are storing the selection in a variable: rcw.selectedRuleType
<select id="rule-type" class="form-control" ng-model="rcw.selectedRuleType">
<option ng-repeat="type in rcw.QueryTypes">{{type.name}}</option>
</select>
I guess you just have to loop over this object with your ng-repeat:
<div class="col-md-2" ng-repeat="scalar in rcw.selectedRuleType">
{{scalar.name}}
</div>
As a side note, I suggest you to use ng-options in your select:
<select ng-model="rcw.selectedRuleType"
ng-options="type as type.name in rcw.QueryTypes">
</select>
Try like this.
<li ng-repeat="n in items">{{n.name}}{{n.scalar}}
<select ng-model="selectme" ng-options="options.name for options in n.scalar">
<option value="">-- choose color --</option>
</select>{{selectme}}
</li>
We can create checkboxes based on the selection,But not sure how we can dynamically bind model based on scaler.name.
We need to set the value of option as scaler of selected option.Then we should listen to change event on select field & extract the scalar value from the selected value.
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.QueryTypes = [{
"name":"Mover",
"scalar":[
{
"name":"Size",
"unit":"m"
},
{
"name":"Speed",
"unit":"m/s"
}
]
},
{
"name":"Stationary",
"scalar":[
{
"name":"Size",
"unit":"m"
}
]
},
{
"name":"Vibrator",
"scalar": [
{
"name":"Frequency",
"unit":"hz"
}
]
}
];
$scope.getScalarTypes=function(){
$scope.scalarTypes=JSON.parse($scope.selectedRuleType);
}
});
<!DOCTYPE html>
<html>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div id="type-selection">
<div class="col-md-6">
<div class="form-group">
<label for="rule-type">Type</label>
<select id="rule-type"
class="form-control"
ng-model="selectedRuleType" ng-change="getScalarTypes()">
<option ng-repeat="type in QueryTypes" value="{{type.scalar}}">{{type.name}}</option>
</select>
</div>
</div>
<div class="col-md-2" ng-repeat="scalar in scalarTypes">
<label>
<input type="checkbox"
class="faChkSqr"</input>
<span></span>
<b>{{scalar.name}}</b>
</label>
</div>
</div>
</div>
</body>
</html>
I am new to angular and I'm confused over this thing. I'm trying to populate a select box based on object inside an array. I want selectbox by using ng-repeat for that array... but initially i need to show only one selectbox after clicking add() next selectbox has to come. for ref:[initially one selectbox has to come]
HTML
<div class="col-lg-12" id="variant1" style="margin-top:10px" ng-repeat="variant in variants">
<div class="col-lg-4" style="text-align:right;padding-top:2px;padding-right: 20px" >
<label for="variant1name">Variant Name</label>
</div>
<div class="col-lg-6" >
<div >
<select class="form-control" ng-model="filterFormInputs.apps" ng-options="app.Application for app in variants" >
<option value="" disabled selected>Select an Application</option>
</select>
<label ng-repeat="checkbox in filterFormInputs.apps.details">
<input class="ecomtexttype1" type="checkbox" ng-model="checkbox.checked"> {{checkbox.name}}
</label>
</div>
</div>
</div>
Controller:
$scope.variants =
[
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]},
{"Application": "Color", "details":[{"name":"red"},{"name":"blue"},{"name":"black"}]}
]
I think that you can just have your add() function update the array... if things are configured correctly the new row should render due to the binding on the array.
As mentioned in comments you did not provide enough source code, so here is the assumed pseudo-code:
in html you might have
<button ng-click="$scope.add()">Add</button>
so in the controller
$scope.variants = [
// array of whatever you are displaying
{"foo":"bar1"},
{"foo":"bar2"}
];
$scope.add = function() {
variants.push({"foo":"bar_new"});
}
Have you considered using a Directive for this? That may work better, depending on your situation. Look into this: https://docs.angularjs.org/guide/directive
This problem has been frustrating me for the last couple days now so, here I am. I'll try to be as clear as possible.
I have an object to retrieve from the database. This object is used to create dropdown menus. It has two properties on it: A section property, which contains one string. The other property is called value, which contains all the possible options that the user can select in the dropdown. I use two nested ng-repeats in my HTML to create the dropdowns.
I am trying to send out to the database a formData object that has 2 properties in it: the name of the dropdown menu, and the value that the user selected. Appending the value selected from the dropdown menu is easy thanks to two way data binding that I set on the select element. However, I CANNOT figure out how to grab the value from the label element inside my controller so that I can attach it to my formData object. As far as I know, ng-model does not work on a label element. Here is the HTML, which hopefully will make it a bit more clear:
<form class="form-horizontal" ng-controller="PreferenceCtrl">
<div ng-repeat="(name, section) in configs">
<label ng-bind="name"></label>
<select class="form-control" ng-model="formData.settings[$index].value">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
</option>
</select>
</div>
<div class="col-md-12" ng-include="gametemp"></div>
<div class="row">
<div class="hr-line-dashed"></div>
<div class="text-center col-md-12 padding-15">
<button class="btn btn-primary btn-lg" ng-click="saveSetting()" formnovalidate translate>
<i class='fa fa-circle-o-notch fa-spin' ng-if="showBusy"></i> Save
</button>
</div>
</div>
</form>
Because the <select> class can have an ng-model attached to it, I can easily capture that value in my controller. I cannot do the same with the label. If anyone can help me out I will forever be your best friend. Thank you!
In answer to your question title "Is there a way to create a two-way binding on a label element", no, that isn't possible.
But if I understand correctly what you're trying to do, it sounds like you want to save data to the database based on information contained in both the <label> and it's associated <select>. If that's true, then I'd recommend using an ng-change function in your <select> like this:
<select class="form-control" ng-model="formData.settings[$index].value" ng-click="dropdownItemClicked(name, formData.settings[$index].value)">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
</option>
</select>
In your controller, create a function to handle this ng-click event:
$scope.dropdownItemClicked = function(name, value) {
console.log(name, value);
// save name/value to database
}
The key is to pass in the exact data you want to save to the database into your dropdownItemClicked() function.
Could you just put the value inside the label?
<label ng-bind="name">{{formData.settings[$index].value}}</label>
There is no way to read from the label. It is the one way binding after all, right. I would do something like this.
var app = angular.module('MyApp', []);
app.controller("MyCtrl", function($scope){
$scope.formData = {
settings:[]
};
$scope.configs = {
'Label1': [{ value: 11 }, { value: 12 }],
'Label2': [{ value: 21 }, { value: 22 }]
};
$scope.change = function(name, idx) {
$scope.formData.settings[idx].name = name;
};
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-cloak="" ng-app="MyApp">
<form class="form-horizontal" ng-controller="MyCtrl">
<div ng-repeat="(name, section) in configs">
<label ng-bind="name"></label>
<select class="form-control" ng-model="formData.settings[$index].value" ng-change="change(name, $index)">
<option value="" disabled="disabled">---Please Select Option---</option>
<option ng-repeat="item in section" value="{{item.value}}" ng-bind="item.value">
{{item.name}}
</option>
</select>
</div>
<div class="col-md-12" ng-include="gametemp"></div>
<div class="row">
<div class="hr-line-dashed"></div>
<div class="text-center col-md-12 padding-15">
<button class="btn btn-primary btn-lg" ng-click="saveSetting()" formnovalidate translate>
<i class='fa fa-circle-o-notch fa-spin' ng-if="showBusy"></i> Save
</button>
</div>
</div>
<div>
{{formData.settings}}
</div>
</form>
</div>
I have a dropdown with a backing JSON like this:
$scope.tradestyles = [
{"id":"1","source":"Source One","name":"Name One"},
{"id":"2","source":"Source Two","name":"Name Two"}
]
This is the dropdown, using select2, the model is the ID of the selected tradestyle:
<select id="tradestyle" ui-select2 ng-model="currentTradestyle" >
<option ng-repeat="tradestyle in tradestyles" value="{{tradestyle.id}}">
{{tradestyle.name}}
</option>
</select>
Next to it, I want to place a text field where the selected tradestyle's name is shown and
can be edited.
<input type="text" ng-model="currentTradestyle" />
How do I change the model of the latter to point to the selected tradestyle's name rather than the ID? In other words, how do I traverse the scope object to point to the sibling name value of the selected ID value?
If i have understood your question correctly, you need to use ng-options for binding to a object rather than a field. So it becomes
<select id="tradestyle" ui-select2 ng-model="currentTradestyle" ng-options="style.name for style in tradestyles">
</select>
<input type="text" ng-model="currentTradestyle.id" />
<input type="text" ng-model="currentTradestyle.name" />
See my fiddle here
http://jsfiddle.net/cmyworld/UsfF6/
<div ng-app="myApp">
<div ng-controller='Ctrl'>
<select id="tradestyle" ng-model="currentTradestyle" update-model="tradestyles">
<option ng-repeat="style in tradestyles" value="{{style.id}}">{{style.name}}</option>
</select>
<input type="text" ng-model="currentTradestyle.name" />
</div>
</div>
JavaScript:
var app = angular.module('myApp', []);
app.controller('Ctrl', ['$scope', '$rootScope', function ($scope, $rootScope) {
$scope.tradestyles = [{
"id": "1",
"source": "Source One",
"name": "Name One"
}, {
"id": "2",
"source": "Source Two",
"name": "Name Two"
}];
}]);
app.directive('updateModel', function() {
return {
require: '?ngModel',
restrict: 'A',
link: function(scope, element, attrs, modelCtrl) {
function parser(value) {
if(value) {
return _.findWhere(scope[attrs.updateModel], {id: value});
}
}
modelCtrl.$parsers.push(parser);
},
}
});
This might satisfy the issues you raised in your comment. It uses tradestyle.id rather than $index in the <option>s which means the selected item works in cases where a filter is applied to the collection. The additional of a $parser ensures the tradestyle.id actually becomes the selected tradestyle item before being applied to the currentTradestyle model property.
Theres a dependency on Underscore but you can remove that with a more long hand alternative to the findWhere() method.
http://jsfiddle.net/asperry1/Zfecq/6/
I believe what you are looking for is something like this:
<div ng-app="myApp">
<div ng-controller='Ctrl'>
<select id="tradestyle" ui-select2 ng-model="currentTsIndex">
<option ng-repeat="tradestyle in tradestyles" value="{{$index}}">{{tradestyle.name}}</option>
</select>
<input type="text" ng-model="tradestyles[currentTsIndex].name" />
</div>
</div>
Working fiddle: