Using ng-selected with a <select> - angularjs

I'm trying to send some piece of information to my loadSecondary function, but I don't know how to access any information about my array or the object I'm selecting.
I've tried sending $index,p,$parent.$index,$parent.p, and all of them come out as undefined.
What information about my selected object or it's position in the array can I send to my function?
<select ng-model="secondPres" ng-options="p.name for p in presentations">
<option value="" ng-selected="loadSecondary(???)">-- Choose a presentation to merge with --</option>
</select>

Rather than use ng-selected, I would put a watch on the $scope.secondPres in your controller, then run loadSecondary on it:
$scope.$watch('secondPres', function(s) {
if(typeof s !== 'undefined') {
$scope.loadSecondary(s);
}
});

Since I couldn't send anything with ng-selected, I sent nothing.
I ended up just accessing $scope.secondPres, from the inside the function

Related

How to access variables in ng-repeat scope in AngularJS?

I am populating html drop down list from database with angularjs and I want to access selected value and pass it further to another function to get some more data from database but I cannot access values that is select tag populated with ng-repeat.
<select name="boja" ng-model="boja" class="form-control" ng-click="loadState(data.model)">
<option value="">Odaberi boju</option>
<option ng-repeat="boja in boje" value="{{boja.boja}}">{{boja.boja}}</option> </select>
$scope.loadState = function(model){
$http({
method:"POST",
url:"ubaciBoje.php",
data:{'model':model}
}).success(function(data){
$scope.boje = data;
});
};
Now when I want to access $scope.boja in another function it says it is undefined. But I am able to access $scope.boje which gives me an array of values. My question is how do i get access to value selected by user and pass it to another function?
When you do this:
<option ng-repeat="boja in boje" value="{{boja.boja}}">{{boja.boja}}</option> </select>
boja will exist here in the view template, and only here. IF you want to use in component code you have to directly pass it from a view as a paramenter eg
<option ng-repeat="boja in boje" value="{{boja.boja}}">{{someComponentMethod(boja.boja)}}</option>
and since boje isa scope (here component) field, you can access it whenever you want.
Here ng-click in select statement is not a good choice. angularjs has a very good directive for selecting and generating select html template.
<select ng-options="boja as boja.boja for boja in boje" ng-model="selectedBoja" ng-change="loadState(selectedBoja)"></select>
Here selectedBoja is you selected item when user change item drom select.

ng-model not working with ng-repeat

I'm trying to figure out why the ng-model is not working with the ng-repeat.
There is my code:
$scope.availableCountries = [];
APIUtility.getCountries().then(function(data){
$scope.availableCountries = data;
$scope.filters.country = "AZ";
});
<select id="eventprice" class="searchpage_select" ng-model="filters.country">
<option value="all">show all</option>
<option ng-repeat="countries in availableCountries" value="{{countries.country_iso}}" ng-class="{'element_selected' : filters.country == countries.country_iso}">{{countries.name}}</option>
</select>
where:
availableCountries is an object from an API call (well formed, trust me)
$scope.filters is an object containing a lot of filters (including country)
The problem is that if i change the ng-model before or after the API call, the select statement is not updated, i think that if i update the scope before angular has the time to execute his ng-repeat, ng-model stop working and will not update the field.
i added the ng-class to prove that filters.country has the right value (ng-class statement returns true when needed and add the class in the right place, so filters.country contains the right value).
I don't know if i was clear enough. Thanks all for your time!
Use ng-options instead of an ng-repeat on an option field.
<select id="eventprice"
class="searchpage_select"
ng-model="filters.country"
ng-options="country.country_iso as country.name for country in availableCountries">
<option value="all">show all</option>
</select>
Problem is in
$scope.filters.country = "AZ";
Try this updated jsfiddle
http://jsfiddle.net/HB7LU/15021/

AngularJS select tag not populating with object data when in ng-repeat

I have an issue with angularjs's select directive.
Here is my code:
<ul class="thumbnails">
<li class="span4" ng-repeat="product in productsDTO">
<div class="thumbnail">
...
...
...
<div class="span4" ng-repeat="varCat in product.varietyCategoriesAndOptions">
{{varCat.varietyCategoryName}}
<br />
<br /><br />
<select ng-model="varCat.varietyCategoryOption" ng-options="varietyCategoryOptionTransfer.varietyCategoryOptionId as varietyCategoryOptionTransfer.varietyCategoryOptionValue for varietyCategoryOptionTransfer in varCat.varietyCategoryOptions">
<option value="">Select color</option>
</select>
</div>
...
...
</div>
</li>
</ul>
I have a $http call that returns json which gets added to the local scope.
function getProductsByCategoryIdServiceCall(CategoryService, categoryId){
CategoryService.getProductsByCategoryId(categoryId).success(function(data){
$scope.productsDTO = data;
}).error(function(data){
$scope.productsDTO = null;
});
}
So basically I have a set of json objects returned from a webservice call, I set the local $scope to have those json objects, and the first iteration tag for productsDTO iterates over the newly populated objects.
Each product has a seperate object that shows what special categories this product has, and the options for those category(s).
I am trying to have the select tag be bound (ng-model) to the varCat Object. This is the one currently being iterated over, and the same object that also contains the array of options for the category that I am trying to set for the select tag directive.
I added a special field on the varietycategory object called varietycategoryoption specifically to hold the current state of that particular select category. I'm doing it this way because there could be many many of these category select's per page, and it is unknown how many, so I can't just hard code it into the page.
It doesnt seem to be working. Does anyone have any advice?
All of the json is a lot of data, but here is the part of the json return inside product that has all of the values associated with the select box:
"varietyCategoriesAndOptions":{"1":{"varietyCategoryId":111,"varietyCategoryName":"color","varietyCategoryOptions":{"202":{"varietyCategoryOptionId":202,"varietyCategoryOptionValue":"red"},"203":{"varietyCategoryOptionId":203,"varietyCategoryOptionValue":"blue"}},"varietyCategoryOption":null}}
**UPDATE*******************
user Chandermali said I was treating my data like it was
in array format, when it is in object format. Chandermali said to use this format
(key, value) in product.varietyCategoriesAndOptions
I tried this in my select
<select ng-model="varCat.varietyCategoryOption" ng-options="(varietyCategoryOptionTransfer.varietyCategoryOptionId, varietyCategoryOptionTransfer.varietyCategoryOptionValue) in varCat.varietyCategoryOptions">
<option value="">Select color</option>
</select>
And got this error:
Error: [ngOptions:iexp] Expected expression in form of '_select_ (as _label_)?
for (_key_,)?_value_ in _collection_' but got
'varietyCategoryOptionTransfer.varietyCategoryOptionId,
varietyCategoryOptionTransfer.varietyCategoryOptionValue in
varCat.varietyCategoryOptions'.
This change in the select tag was enough for it to work for me.
<select ng-model="varCat.varietyCategoryOption" ng-options="value.varietyCategoryOptionId as value.varietyCategoryOptionValue for (key,value) in varCat.varietyCategoryOptions">
<option value="">Select color</option>
</select>
I just had the wrong formatting on the select directive to access my object graph.
The select box is now being populated with the data.
Thank you very much for you patience.
Seeing your json neither your varietyCategoriesAndOptions or varietyCategoryOptions are array. These are object maps. You need to use the syntax for object map like
(key, value) in expression – where key and value can be any user
defined identifiers, and expression is the scope expression giving the
collection to enumerate.
For example: (key, value) in product.varietyCategoriesAndOptions

How to get option value of select element

I am trying to get the option value of a select element using Protractor. However, I'm not able to find the option element.
HTML
<select ng-options="opions.c as options.n for option in options" ng-model="model">
<option value="0">Option 1</option>
<option value="1">Option 2</option>
</select>
Spec-file
describe('testing select option', function() {
it('', function() {
ptor = protractor.getInstance();
//This will not get the option required
ptor.findElement(protractor.By.binding('model'));
});
});
I cannot seem to find a way to grab the option value as I haven't found a function that I can use that doesn't give and exception or error message.
Does anyone know how to resolve this issue?
I have had some problems getting dropdowns working well, and have spent some time today working it out (and therefore I'm sharing it here in case someone else finds it useful).
On earlier versions of Protractor there was a by.selectedOption, which effectively does the same thing as by.select, but returns only the selected item. So, to get the text of the selected option above, you could have:
expect(element(by.selectedOption('model')).getText()).toEqual('Option 1');
I wrote a blog post if you want more detail, it also covers a helper function for selecting the option in the dropdown: http://technpol.wordpress.com/2013/12/01/protractor-and-dropdowns-validation/
Recent versions of protractor have removed this function, replacing it with:
expect(element(by.id('my_id')).element(by.css('option:checked')).getText();
Which is more flexible, as it can be applied to any of the finders, whereas selectedOption only worked with a model finder.
ok again I have now been able to figure out how to grab the option element with protractor.
the example code below shows how to accomplish this.
ptor.findElement(protractor.By.css('select option:nth-child(value of the option you require IE: the number)')).click();
Try using xPath:
ptor.findElement(protractor.By.xpath('//select/option[1]'));
You can use the same technique to choose an option by value:
protractor.By.xpath('//select/option[text()="Option 2"]'));
I've needed to do this for setting up forms where inputs are visible based on selected dropdowns, e.g.:
makeFord = protractor.By.xpath('//select[#id="make"]/option[text()="Ford"]'));
modelMustang = protractor.By.xpath('//select[#id="model"]/option[text()="Mustang"]'));
makeFord.click();
modelMustang.click();
Here is how you can get the value of an option in a select:
HTML
<select ng-options="opions.c as options.n for option in options" ng-model="model">
<option value="Africa">Option 1</option>
<option value="Switzerland">Option 2</option>
</select>
.spec file
describe("Country <select>", function() {
it("should have 'Africa' as the value of the first option", function() {
browser.get('index.html');
let all_options = element.all(
by.options("opions.c as options.n for option in options") //use whatever string is assigned to the ng-options attribute in the html
);
let first_option = all_options.get(0); //or all_options.first()
let second_option = all_options.get(1); //or all_options.last()
expect(
first_option.getAttribute('value')
).toEqual("Africa");
});
});
To get the value of a selected option (which can be an option programmatically selected with protractor by calling click() on an option):
expect(
element(
by.model('model') //'model' is the string assigned to the select's ng-model attribute
).element(
by.css('option:checked')
).getAttribute('value')
).toEqual('Swizerland');
This will help.
//check whether the selected value is equal to the expected value.
expect(element(by.model("model")).getAttribute('value')).toEqual("0");
//catch the selected value
element(by.model("model")).getAttribute('value').then(function (value) {
console.log('selected value', value);
});
In order to enumerate the option tags you can try to use the .all method and you should access it by the parent first.
element(by.model('model')).all(by.tagName('option')).then(function(arr) {
expect(arr.length).toEqual(2);
});
Have a look at the API reference for inspiration
http://www.protractortest.org/#/api?view=ElementArrayFinder.prototype.all
Edit: also follow the style guide which discourages usage of XPath
http://www.protractortest.org/#/style-guide

How can I detect when a USER changes the value in a select drop down using AngularJS?

I have the following:
<select data-ng-model="selectedTestAccount" data-ng-options="item.Id as item.Name for item in testAccounts">
<option value="">Select Account</option>
</select>
It was suggested to me that I could watch for the value of this select to change with the following:
$scope.$watch('testAccounts', function(){
/* get updated values and update other select "model" on success*/
alert("hello");
});
But this does not seem to work. For one thing it gives an alert as soon as the select appears on the screen and before the user has selected anything. Also am I correct in saying that I should be watching for a change in selectedTestAccount? Finally one more question. How can I show the value of selectedTestAccount in an alert box?
As said, you can get it as the first argument, no need to get it from scope. Use
$scope.$watch('selectedTestAccount', function(newValue){
alert(newValue);
});
Beware that you always get a undefined as the first change for a $watch.
What about putting an "ng-change" to your select?
In your example it would be something like this:
<select data-ng-model="selectedTestAccount" ng-change="updateSelectedAccount(selectedTestAccount)" data-ng-options="item.Id as item.Name for item in testAccounts"></select>
And then in your controller
$scope.updateSelectedAccount = function (selectedTestAccount) {
console.log(selectedTestAccount);
}
P.S. Sorry, just noticed how old this question is :) Hope this might help somebody in the future.

Resources