Working with select binding in angularjs - javascript

I'm running my head against the wall here trying to bind a pre-defined select box's selected attribute depending on a property on an object.
What I have is a collection of objects: Items and an Item object has the StatusCode property which is either 0, 1 or 2.
On my markup I have the following:
<div ng-repeat="fb in feedbackItems | orderBy: 'Id'">
<select>
<option value="0">Some text</option>
<option value="1">Some other text</option>
<option value="2">Text 3</option>
</select>
</div>
What I need is to check if the StatusCode of my fb object is either 0, 1 or 2 and then set the selected="selected" attribute on the right option.
When the client chooses another option, the fb object should be updated aswell.
My controller looks like this:
app.controller('feedbackController', function($scope, feedbackService, $filter) {
// Fields
var takeCount = 20;
var currentNodeId = $('.current-id').text();
// Constructor for this controller
init();
function init() {
feedbackService.getFeedbackPaged(currentNodeId, 1, takeCount).then(function(response) {
$scope.feedbackItems = response.data.Items;
$scope.CurrentPage = response.data.CurrentPage + 1;
$scope.TotalPages = response.data.TotalPages;
$scope.TotalFeedbackItems = response.data.TotalItems;
$scope.FeedbackCount = response.data.Items.length;
});
}
});
Is there any way of doing this? :-)
Thanks in advance!

Make sure to put the model on the there. Not sure what your model looks like but based on how I read your question:
<div ng-repeat="fb in feedbackItems | orderBy: 'Id'">
<select data-ng-model="fb.StatusCode"> <!-- here -->
<option value="0">Some text</option>
<option value="1">Some other text</option>
<option value="2">Text 3</option>
</select>
or if feedback items is actually your option list (like jbird said)
<div >
<select data-ng-model="Item.StatusCode" ng-options="fb.id as fb.text for fb in feedbackItems"></select>
</div>

Related

Clear value from select element when filtering in Angular

I have a basic select element with options that dropdown hooked up to a small set of data which is being filtered using the dropdown. Initially on page load the select element has a value of undefined (according to the console), however after selecting any option it takes on the value of that option.
How can I go back to undefined? Basically I want to be able to select an option in the list that will go back to displaying all of the data. Below is my app on JSBin:
App
add a custom filter function
$scope.filterByGenre = function(item){
if (!$scope.selectedGenre || $scope.selectedGenre == 'All'){
return true;
}
return item.genre && item.genre.indexOf($scope.selectedGenre) != -1;
}
change your <select> to this:
<select ng-model="selectedGenre"
ng-options="choice as choice for (idx, choice) in genres"
name="genre"
class="genre-dropdown">
</select>
change <tr ng-repeat="... filters to this:
<tr ng-repeat="movie in movies | filter:searchBar | filter:filterByGenre | orderBy:sortType:sortReverse">
Online Demo - http://jsbin.com/riyafupexu/1/edit?html,js,output
I'm confused, you are using ng-options but you also provided the static options.
For a quick fix in this case you can remove that ng-options and uncomment that All and remove it's value.
Like:
<select ng-model="selectedGenre"
ng-change="handleSelect()"
name="genre"
class="genre-dropdown">
<option selected="selected" value="">All</option>
<option value="Action">Action</option>
<option value="Adventure">Adventure</option>
<option value="Animation">Animation</option>
<option value="Biography">Biography</option>
<option value="Comedy">Comedy</option>
<option value="Crime">Crime</option>
<option value="Drama">Drama</option>
<option value="Fantasy">Fantasy</option>
<option value="History">History</option>
<option value="Horror">Horror</option>
<option value="Romance">Romance</option>
<option value="Sci-Fi">Sci-Fi</option>
<option value="Western">Western</option>
</select>
You can do it this way:
$scope.selectedGenre = "";//set the model to blank.
$scope.genres = 'All,Action,Adventure,Animation,Biography,Comedy,Crime,Drama,Fantasy,History,Horror,Romance,Sci-Fi,Western';
//create an array after splitting the commas
$scope.genresAry = $scope.genres.split(',');
$scope.genresAry.push("");//push blank into the array.
In HTML use genresAry.
<select ng-model="selectedGenre"
ng-options="choice as choice for (idx, choice) in genresAry"
ng-change="handleSelect()"
name="genre"
class="genre-dropdown">
working code here

Why is my selected value not updated when copied from a controller?

I have a <select> that is controlled using both ng-model and ng-options:
<select ng-model="user.option"
ng-options="value.label for (key, value) in data.options">
<option value="">Select value</option>
</select>
The options are grouped in an object:
$scope.data.options = {
one: { label: 'one' },
two: { label: 'two' }
};
At some point, I want to change the selected option from the controller. This works:
$scope.user.option = $scope.data.options['two'];
However, in my context, I maintain a variable master, and use it to set $scope.user:
$scope.master.option = $scope.data.options['two'];
$scope.user = angular.copy ($scope.master);
This does not work: my <select> still shows Select value. But other elements properly reflect the change.
What am I doing wrong?
I created a fiddle there.
//Add track by in ng-options ..check below code
<div ng-app="my-app">
<div ng-controller="MyCtrl">
<select ng-model="user.option"
ng-options="value.label for (key, value) in data.options track by value.label">
<option value="">Select value</option>
</select>
<p>Selected: {{user.option.label}}
</div>
</div>

How to add selected attribute to ng-repeated dropdown form?

I have a form that builds out multiple widgets based on some JSON data. In part of that form is a select dropdown, and some items have different options selected by default.
ie:
object 1 {
tag: "products"
}
The select dropdown in the ng-repeat widget
<select class="btn-success form-control">
<option value="companies">companies</option>
<option value="news">news</option>
<option value="people">people</option>
<option value="products">products</option>
</select>
^ Here if this was object 1, I'd need the products option to gain the selected attribute.
What I've tried so far, that hasn't worked, but so you can see my thinking:
HTML
ng-repeat="stuff in stuffs"...
<select class="btn-success form-control">
<option value="companies">companies</option>
<option ng-if="widget.selectedTag(stuff.tag)" value="news">news</option>
<option value="people">people</option>
<option value="products">products</option>
</select>
Controller
this.selectedTag= function(s) {
console.log(s);
if (s = 'news'){
return 'selected';
}
}
How would you go about this?
Found answer here: Initializing select with AngularJS and ng-repeat
<option ng-selected="{{operator.value == filterCondition.operator}}"
ng-repeat="operator in operators"
value="{{operator.value}}">
So in my case:
<option value="products"
ng-selected="{{stuff.tag == 'products'}}">products</option>

Cant get Select Box to update dynamically with angular.js

I am currently learning angularJS and so far so good, but I'm having a problem that I cant seem to figure out.
I have 2 select boxes, one with top level categories in it, and a second one for sub-categories which is supposed to dynamically update when a change is made to the first select.
The first select box is populating fine, but despite the values being set for the second binding array by the event function I developed, the view never updates the second select box with the new values. I'm not sure what I'm doing wrong, and have tried a bunch of things but with no luck.
Here is what I've got:
var themebucketApp = angular.module('themebucketApp',[]);
//category list controller
themebucketApp.controller('CategoriesOptions',function($scope) {
$scope.thememap = {"wordpress":[{"category":"Activism"},{"category":"Art"},{"category":"Blog \/ Magazine"},{"category":"BuddyPress"},{"category":"Business"},{"category":"Cart66"},{"category":"Charity"},{"category":"Children"},{"category":"Churches"},{"category":"Computer"},{"category":"Corporate"},{"category":"Creative"},{"category":"eCommerce"},{"category":"Entertainment"},{"category":"Environmental"},{"category":"Events"},{"category":"Experimental"},{"category":"Fashion"},{"category":"Film & TV"},{"category":"Food"},{"category":"Government"},{"category":"Health & Beauty"},{"category":"Hosting"},{"category":"Jigoshop"},{"category":"Marketing"},{"category":"Miscellaneous"},{"category":"Mobile"},{"category":"Music and Bands"},{"category":"News \/ Editorial"},{"category":"Nightlife"},{"category":"Nonprofit"},{"category":"Personal"},{"category":"Photography"},{"category":"Political"},{"category":"Portfolio"},{"category":"Restaurants & Cafes"},{"category":"Retail"},{"category":"Shopping"},{"category":"Software"},{"category":"Technology"},{"category":"Travel"},{"category":"Wedding"},{"category":"WooCommerce"},{"category":"WordPress"},{"category":"WP e-Commerce"}],"magento":[{"category":"Entertainment"},{"category":"Fashion"},{"category":"Health & Beauty"},{"category":"Magento"},{"category":"Miscellaneous"},{"category":"Shopping"},{"category":"Technology"}],"designs":[{"category":"404 Pages"},{"category":"Activism"},{"category":"Admin Templates"},{"category":"Art"},{"category":"Business"},{"category":"Charity"},{"category":"Children"},{"category":"Churches"},{"category":"Computer"},{"category":"Corporate"},{"category":"Creative"},{"category":"Electronics"},{"category":"Entertainment"},{"category":"Environmental"},{"category":"Events"},{"category":"Experimental"},{"category":"Fashion"},{"category":"Film & TV"},{"category":"Food"},{"category":"Government"},{"category":"Health & Beauty"},{"category":"Hosting"},{"category":"Marketing"},{"category":"Miscellaneous"},{"category":"Mobile"},{"category":"Music and Bands"},{"category":"Nightlife"},{"category":"Nonprofit"},{"category":"Personal"},{"category":"Photo Gallery"},{"category":"Photography"},{"category":"Political"},{"category":"Portfolio"},{"category":"Restaurants & Cafes"},{"category":"Resume \/ CV"},{"category":"Retail"},{"category":"Shopping"},{"category":"Site Templates"},{"category":"Social Media Home"},{"category":"Software"},{"category":"Specialty Pages"},{"category":"Technology"},{"category":"Travel"},{"category":"Under Construction"},{"category":"Virtual Business Card"},{"category":"Wedding"}],"opencart":[{"category":"Entertainment"},{"category":"Fashion"},{"category":"Miscellaneous"},{"category":"OpenCart"},{"category":"Shopping"},{"category":"Technology"}]};
$scope.categories = [{'name' : 'WordPress', 'value' : 'wordpress'},{'name' : 'Magento', 'value' : 'magento'},{'name' : 'OpenCart', 'value' : 'opencart'},{'name' : 'Designs', 'value' : 'designs'}];
$scope.subcategories = [];
$scope.loadSubcategories = function(){
$scope.subcategories = $scope.thememap[$('#theme-type').val()];
};
});
...
<div class="navbar-text pull-right" style="margin-top:10px;">
<select id="theme-type" name="themetype" ng-controller="CategoriesOptions" ng-click="loadSubcategories();">
<option value="">Theme Type</option>
<option ng-repeat='category in categories' value="{{category.value}}">{{category.name}}</option>
</select>
<select id="theme-cat" name="themecat" ng-controller='CategoriesOptions'>
<option value="All">All</option>
<option ng-repeat='subcategory in subcategories' value='{{subcategory.category}}'>{{subcategory.category}}</option>
</select>
</div>
Can anyone show me what I'm doing wrong or what I'm missing?
There are several issues:
One: ng-controller="CategoriesOptions" should be declared only once and not one per control Like this:
<div class="navbar-text pull-right" style="margin-top:10px;" ng-controller="CategoriesOptions">
<select id="theme-type" name="themetype" ng-click="loadSubcategories();">
<option value="">Theme Type</option>
<option ng-repeat='category in categories' value="{{category.value}}">{{category.name}}</option>
</select>
<select id="theme-cat" name="themecat" >
<option value="All">All</option>
<option ng-repeat='subcategory in subcategories' value='{{subcategory.category}}'>{{subcategory.category}}</option>
</select>
Two for selects it better to use ng-options and ng-model:
http://docs.angularjs.org/api/ng.directive:select
About:
ng-model="{string}"
It is what associates the selected value of the control with your model.
About:
[ng-options="{comprehension_expression}"]
it works something like this:
<select ng-model="mySelectedValue" ng-options="c.name for c in categories"></select>

Show Hide select options based on previous selection dropdown

Thanks for reading my question... ;-)
I'm building a Wordpress site that uses Custom Posts and Custom Fields to show a vehicle inventory. I would like the visitor to be able to filter the posts by Taxonomies...
The plugin I use for drilling the available Taxonomies (Query Multiple Taxonomies) outputs all options it can find for that particular Taxonomy into a dropdown list.
To prevent the dropdown list (i.e. Model) to become too long, I would like to show only those options that are based on the previous selection.
So when the visitor selects Vehicle = Cars, the dropdown for Manufacturer should only show the car manufacturers.
When the visitor selects a manufacturer, i.e. Ford, the next dropdown for selecting a model should only show the models available for the previous selected manufacturer, in this case Ford...
The labels and level-0 values don't change but when I add or change a manufacturer or model, the level-1 and/or level-2 changes.
Not that important but, if possible, it would also be nice to strip everything not needed to show up in the "filtered" dropdown. In case of the Manufacturer dropdown, level-0 and all the spaces are not needed.
In case of the Model dropdown, level-0, level1 and all the spaces are not needed after selection.
Here's a sample how the HTML-code, generated by the plugin, looks like:
<label for="qmt-vehicle">Vehicle:</label>
<select id="qmt-vehicle" name="vehicle">
<option></option>
<option class="level-0" value="cars" >Cars</option>
<option class="level-0" value="motorcycles" >Motorcycles</option>
</select>
<label for="qmt-manufacturer">Manufacturer:</label>
<select id="qmt-manufacturer" name="manufacturer">
<option></option>
<option class="level-0" value="cars" >Cars</option>
<option class="level-1" value="ford" > Ford</option>
<option class="level-1" value="chevrolet" > Chevrolet</option>
<option class="level-0" value="motorcycles" >Motorcycles</option>
<option class="level-1" value="honda" > Honda</option>
<option class="level-1" value="yamaha" > Yamaha</option>
</select>
<label for="qmt-model">Model:</label>
<select id="qmt-model" name="model">
<option></option>
<option class="level-0" value="cars" >Cars</option>
<option class="level-1" value="ford" > Ford</option>
<option class="level-2" value="model-1-ford" > Model 1</option>
<option class="level-2" value="model-2-ford" > Model 2</option>
<option class="level-2" value="model-3-ford" > Model 3</option>
<option class="level-1" value="chevrolet" > Chevrolet</option>
<option class="level-2" value="model-1-chevrolet" > Model 1</option>
<option class="level-2" value="model-2-chevrolet" > Model 2</option>
<option class="level-2" value="model-3-chevrolet" > Model 3</option>
<option class="level-0" value="motoren" >Motorcycles</option>
<option class="level-1" value="honda" > Honda</option>
<option class="level-2" value="model-1-honda" > Model 1</option>
<option class="level-2" value="model-2-honda" > Model 2</option>
<option class="level-2" value="model-3-honda" > Model 3</option>
<option class="level-1" value="yamaha" > Yamaha</option>
<option class="level-2" value="model-1-yamaha" > Model 1</option>
<option class="level-2" value="model-2-yamaha" > Model 2</option>
<option class="level-2" value="model-3-yamaha" > Model 3</option>
</select>
I can do some simple things with Javascript but this is not simple to me, sorry... ;-)
Can someone please help me to figure out how to do this in Javascript/JQuery?
Cross browser would be great!
* EDIT *
The HTML code shows the code send to the browser. Because I cannot modify the plugin that much, I'd like to "manipulate" this code to make it work the way I want to... ;-)
The only fixed things are: Labels for the dropdowns and the Values for all the Class="level-0" elements.
So "Cars" and "Motorcycles" will always stay and never change. BUT from there everything is flexible to change. I.e. when there are no Posts for Chevy's to display, Chevy will not be in the generated HTML. So the plugin only shows dropdown options for the items that are realy there and can be found.
So when there's no Ford available at all, Ford will not be in the dropdown...
I rather not make a predefined list of Manufacurers and their Models.
subscribe to your select elements' onchange events: http://www.w3schools.com/jsref/event_onchange.asp. In the event handler, read the currently selected value and repopulate the other elements accordingly.
I would suggest you hold the data in javascript so you only need to show the necessary options for each model without having to hide some..
I put this on jsfiddle but the site keeps breaking.
The code below was tested and works though.
Ok Works now:
<script type="text/javascript">
var vehicles = {"Cars": {
"Ford" : [ "Fiesta", "Focus", "Fusion"],
"Chevy": [ "Malibu", "Corvette", "Tahoe"],
},
"Motorcycles": {
"Honda": ["model 1", "model 2", "model 3"],
"Yamaha": ["model 1", "model 2", "model 3", "model 4"]
}
};
$(document).ready(function() {
var $vehiclesList = $("#qmt-vehicle");
var $manufList = $("#qmt-manufacturer");
var $modelList = $("#qmt-model");
var selectedType = null
var selectedManuf = null;
$.each(vehicles, function(key, vehicle) {
$vehiclesList.append($("<option/>", {value:key,text:key}));
});
$vehiclesList.bind("change", function() {
selectedType = $(this).val();
if (selectedType && vehicles[selectedType]) {
var manufacturers = vehicles[selectedType];
$("#qmt-manufacturer option").not(":first").remove();
$("#qmt-model option").not(":first").remove();
$.each(manufacturers, function(key, manufacturer) {
$manufList.append($("<option/>", { value: key, text: key}));
});
}
});
$manufList.bind("change", function() {
var selectedManuf = $(this).val();
$("#qmt-model option").not(":first").remove();
if (selectedManuf && vehicles[selectedType] && vehicles[selectedType][selectedManuf]) {
var models = vehicles[selectedType][selectedManuf];
$.each(models, function(key, model) {
$modelList.append($("<option/>", { value: model, text: model}));
});
}
});
});
</script>
Then in your page you'd have
<label for="qmt-vehicle">Vehicle:</label>
<select id="qmt-vehicle" name="vehicle">
<option></option>
</select>
<label for="qmt-manufacturer">Manufacturer:</label>
<select id="qmt-manufacturer" name="manufacturer">
<option></option>
</select>
<label for="qmt-model">Model:</label>
<select id="qmt-model" name="model">
<option></option>
</select>

Categories