how to set only required properties to angular select object using ng-option? - angularjs

I have object array which contains objects along with many properties. I am binding it to the select tag using angular ng-options
Demolink
Once user selects the value in the combobox, controller property is updated(here it is $scope.selectedIem={"selected":""}). But this selected propriety contains all the property list name.
eg:
{"description":"Bank",
"shortDescription":"dd",
"value":"xx",
"enable":null,
"name":"jhon"
},
But I want only
{
"shortDescription":"dd",
"value":"xx",
},
Kindly, help me how can pass only required properties to "select object" by using ng-options

You can do this by using ng-change, when your are selecting an object you just need to call a function using ng-change and in that function you need to deleted the unwanted attributes of the selectedItem in ng-model
Here is the working plunker
http://embed.plnkr.co/IX1HFV9o3rOb0c8AcjmP/preview
Hope this helps!!!

Related

AngularJS: why does my dropdown have an initial blank entry?

I am fetching some JSON frm a server and using it to populate a combobox.
A JSON entry looks like this
"campaign_id": "2",
"customer_id": "1",
"title": "Purple monkey dishwasher",
"description": "perfectly cromulent",
"start_time": "19/09/2015 09:42:06",
"end_time": "19/10/2015 09:42:06"
And I declare my drop down thus-wise
<select name="SelectCampaignForConnections"
ng-model="connectionsCampaignDropDown"
ng-options="campaign.title for campaign in campaigns"
ng-change="ShowConnectionsForCampaign(connectionsCampaignDropDown)">
I initialize the model of the select ...
$http.get(url)
.success(function(data, status, headers, config)
{
if ($scope.connections.length > 0)
$scope.connectionsCampaignDropDown = $scope.connections[0];
When the dropdown shows, it contains the title element of each JSON entry, BUT, it has an initial blank entry.
What am I doing wrongsomely?
[Update] #sheilak gave a good anser :
In order for the dropdown to defaulted to a non-blank value, the value
of the variable passed to ng-model must equal one of the options
passed to ng-options.
In your case where ng-options is populated by values of
campaign.title, it looks like the value passed to ng-model i.e.
connectionsCampaignDropDown should be populated with
$scope.connections[0].title rather than the whole object
$scope.connections[0].
$scope.connectionsCampaignDropDown = $scope.connections[0].title;
However, I would prefer to pass around an complete object, rather than just a field of it.
Can this be done?
(if not, then I will have to pass only the title to the ng-change function ShowConnectionsForCampaign() and it will then have to loop over the data to find a match, which seems inefficient)
<select name="SelectCampaignForConnections"
ng-init="justGiveItAName=getInitialSelection()"
ng-model="justGiveItAName"
ng-options="campaign.title for campaign in campaigns"
ng-change="ShowConnectionsForCampaign(justGiveItAName)">
where getInitialSelection() is a function on your scope that could take a param if you need it to, but I would probably go with something like this in the case you outline above:
function getInitialSelection() {return connections[0]};
or set it directly in the ng-init:
ng-init="$scope.connections[0]"
(you might have to fiddle with the above code - I haven't tested it).
btw - 'justGiveItAName' is then an object available elsewhere.
I have now tested it; see these Fiddles for working examples:
Setting directly in ng-init: http://jsfiddle.net/lukkea/nuo2c3Lk/
Using a function on the $scope: http://jsfiddle.net/lukkea/o6strxjf/
Passing the object instead of properties (as the OP requested): http://jsfiddle.net/lukkea/fsx8s67j/2/
Passing the objects in and object back: http://jsfiddle.net/lukkea/ww9yqsrm/3/
In order for the dropdown to defaulted to a non-blank value, the value of the variable passed to ng-model must equal one of the options passed to ng-options.
In your case where ng-options is populated by values of campaign.title, it looks like the value passed to ng-model i.e. connectionsCampaignDropDown should be populated with $scope.connections[0].title rather than the whole object $scope.connections[0].
$scope.connectionsCampaignDropDown = $scope.connections[0].title;
This should be possible, you just have to make sure that the initial value you set is the exact same object (not just another object with the same values)
You should be able to use campaign as campaign.title for campaign in campaigns in ng-options.
Then it stores the selected campaign object in the model (not just the value of campaign.title) and the label shown in the dropdown will still be campaign.title.
<select name="SelectCampaignForConnections"
ng-model="connectionsCampaignDropDown"
ng-options="campaign as campaign.title for campaign in campaigns"
ng-change="ShowConnectionsForCampaign(connectionsCampaignDropDown)">
The expression used here is: select as label for value in array.
select - the value stored in ng-model
label - the text displayed in the dropdown
The different expression options are listed in the official documentation.

AngularJS, Select and binding to value

I have a scenario that I thought it is logical, but seems angular doesn't support it.
So, I have in the scope/controller a list of user types as array of objects like this:
$scope.userTypes = [{text : "Buyer", value : "1"},
{text : "Vendor", value : "2"},
{text : "Buyer / Vendor", value : "9"}];
$scope.user = new User(globalSelectedUserType);
Where the User is defined like this:
function User(userType) {
this.userType = userType;
this.isAdminUser = false;
this.isActive = true;
this.roleDisabled = true;
};
And I want to have a select element with the list of options coming from the userTypes binding the values to the "value" property and text to the "text" property , and bind the select value to only the "value" property of the array object, allowing the user to set the value from the code.
so when I create the user from the code using this
$scope.user = new User("9");
it should initialize the select with the "Buyer / Vendor" selected.
Reading the documentation of the select element in angular and ng-options, seems it is impossible to do.
I tried this
<select name="usertypedata" id="UsersTypeData" ng-model="user.userType"
ng-disabled="user.roleDisabled" ng-options="usertype.value as usertype.text for usertype in userTypes track by usertype.value">
</select>
and when we select the option, I want only the "value" property to be populated by the ng-model
I have two answers for this.
First answer is what PSL suggested in his comments before.
The second answer is
instead of binding ng-options to an array, I bind it to an object and it worked fine
to elaborate more, it might be that I am not doing fully angular solution from start to end.
I am using angular to populate / and control the behavior of the html page / form.
But later, I am doing normal html/form submit that will submit all the data inside the form.
and usual form/submit, will use the select/option value to submit that value, and not ng-model
but ng-model was important for me to select the option programmatically.

NG Options select based on object name

I have a ng-options, using an array of objects with the objects name property as the label.
When I first load the module, the ng-module contains an object with is foreign to the array but shares the same properties. How to I get the ng-options to recognise this and select the correct option?
So :
var options = [{name:'test'},{name:'test2'}];
they go into the ng-options like so
ng-options="options.name for option in options "
and the model is set in the controller like so
$scope.modelVar = {name:'test'};

AngularJS drop down (ng- options) not binding - string to object (initial selection)

I am having a problem binding data retrieved from the server to a drop down list. The main issue I think is the fact that the comparison is done on differing object types.
For example:
1. The object returned from the server contains a currency code string. we want this to be bound to an item in the dropdown list
"baseCurrencyCode":"GBP"
The view model returns the list of currencies.. These are returned as a list of currency objects with different properties
{"currencies":[{"id":1,"rateId":0,"abbreviation":"AFN","description":"Afghani","rate":0.0,"rateDescription":null,"languageCode":"en-gb","isDefault":true,"fullDescription":"AFN - Afghani - ","shortDescription":"AFN - Afghani"}}
etc.
Currently, I have got this working by writing a function to go through every property for every item in the list, find the correct property we wish to compare to - do the comparison and then return the initial selection.
When calling my save method I then need to manually bind the currency abbreviation to the object I wish to return to the server.
Surely there must be a better way to do this?
Some of my code for reference..
<select ng-model="selectedCurrency" ng-options="currency.shortDescription for currency in viewModel.currencies"></select>
// Call to my custom method..List, PropertyName, value to compare
$scope.selectedCurrency = InitialiseDropdown($scope.viewModel.currencies, "abbreviation", $scope.updatedObject.baseCurrencyCode);
// Code executed when saving - to bind the currency to the updated object
$scope.updatedObject.baseCurrencyCode = $scope.selectedCurrency.abbreviation;
Any help is appreciated!
EDIT
Sorry if I wasn't clear enough.. To summarise..
The main problem here is binding to the drop down and initial selection.
The object we are updating contains a parameter (string) of the currency abbreviation.
The list we select from is a list of currency objects. As these are two differing object types I have been unable to plug in angulars 2 way binding and have written some code to do this on initial retrieval and when saving.
The cleanest way to fix this would be to return a currency object in our retrieval instead of a simple string of the abbreviation, but this is not an option.
Is there a better way of enabling 2 way binding on different object types ?
Thanks again
It is not exactly clear what the problem is, but you can save yourself some work by binding the <select> to the currently selected currency object (so you don't have to look it up later).
select + ngOptions allow you to bind to one value while displaying another, with the following syntax:
<select ng-model="selectedCurrency"
ng-options="currency as currency.shortDescription
for currency in viewModel.currencies">
</select>
In the above example, $scope.selectedCurrency will be bound to the whole currency object, but currency.shortDescription will be displayed in the dropdown.
See, also, this short demo.
UPDATE:
In case you don't need to bind to the whole currency object, but just bind updatedObject's baseCurrencyCode property to the abbreviation of the selected (in dropdown) currency, you can do it like this:
<!-- In the VIEW -->
<select ng-model="updatedObject.baseCurrencyCode"
ng-options="c.abbreviation as c.shortDescription
for c in currencies">
</select>
// In the CONTROLLER
$scope.currencies = [...];
$scope.updatedObject = {
...
baseCurrencyCode: <baseCurrencyCodeFromServer>
};
See, also, that short demo.
I have had the same problem, ng-model and ng-option being from 2 different sources. My ng-model is bound to a value in a json object representing a chosen filename and my ng-option is a list of possible values taken from a csv file.
In the controller I am reading a directory via a Nodejs route, and creating a json array of filenames like this
var allCsvFiles = [{"name":"file1.csv"},{"name","file2.csv},etc..]
The current csv file, i.e. the selected one is stored in another json array
[{"date":"01-06-2017","csvfile":"file1.csv","colour":"red"},{...}, etc].
I was using the following code for the dropdown:
<select type="text" ng-model="file.csvfile"
ng-options="opt.name for opt in allCsvFiles track by opt.name"></select>
Which caused the current selection to be blank and if I selected an item from the dropdown it put [object],[object] as the current selection. If I stepped through the code I found that it seemed to be selecting {"name","file1.csv"} as the option and couldn't display it, this seemed odd as my ng-options selection looks like it should just return the value of "name" not the array entry. I tried many different ways to make this work but eventually I found that if I made the list of possible selections a plain javascript array:
var allCsvFiles = ["file1.csv","file2.csv", "file3,csv]
and changed the select to:
<select type="text" ng-model="file.csvfile" ng-options="opt for opt in allCsvFiles"></select>
then the dropdown selection worked as expected.
I may have missed some other obvious solution here, but as the array of json objects is one dimensional anyway it doesn't seem to be an issue.
It looks like the OPs question has been answered, I just thought I'd add this as it solved it for me.

AngularJS inconsistent databinding

I'm learning AngularJS and I have a question regarding the databinding for select elements. The databinding for textboxes works without any kind of event handling code. Once the ng-model attribute is set textbox updates when the model property changes and vice versa. There is no need for ng-change attribute.
However, for select elements we need to write functions that will be called via ng-change atribute.
Why does angularjs handle databinding without an ng-change attribute for textboxes but requires functions that will be called via ng-change attribute for select elements?
UPDATE:
Added the fiddle in the comments section. The example is from AngularJS in Action book. Click on one of the stories, change the textbox value and the model is updated. Change the selection in dropdown model is not updated.
UPDATE:
Added a new fiddle in the comments.
Thanks.
I've created a fiddle that works here - The issue is really just the dummy data here. In the original fiddle, the object created in the statuses array for {name:'Back Log'} and {name:'To Do'} are not the same (not ===) as the {name:'Back Log'} and {name:'To Do'} objects created in the dummy story objects.
To make the example work, I pass the indexed statuses into the getStories function. However I think this is really just a case of demo-induced confusion. (I've been looking at the MEAP for Angular in Action as well, and I think it could be simplified a bit like this one, that uses simple string statuses that will pass the === test
var getStories = function(statusesIndex) {
var tempArray = [
{title:'Story 00',
description:'Description pending.',
status: statusesIndex['To Do']
},
{title:'Story 01',
description:'Description pending.',
status: statusesIndex['Back Log']
}
];
return tempArray;
}
I think your confusion might be a result of the select documentation still being incorrect. (See my Disqus comment.) ng-model can and should be used with select. ng-change is optional and it just gives you a hook should you want to do something each time the selected option changes.
Normally you should use ng-options with select.
If i understood your question correctly then I think your guessing is wrong because for select boxes, you do not have to invoke ng-change event in order to fetch the selected option.
<select ng-model='select'>
<option>....</option>
<option value='one'>One</option>
<option value='Two'>Two</option>
</select>
// Your selected option will print below... without invoking ng-change
<div>You selected: {{select}}</div>
Demo: http://jsfiddle.net/jenxu/1/

Resources