I have a problem with ng-options. I can't get rid of the blank option in my ng-options with multi select.
I tried this solutions but this works for single select. Is there any solution for multi select.
HTML
<select ng-model="feed.config" ng-options="item.name for item in configs" multiple>
<!-- <option value="" ng-if="false"></option> works only for single select -->
</select>
JS
$scope.feed = {};
$scope.configs = [{'name': null,'value': 'config1'},
{'name': 'Config 2', 'value': 'config2'},
{'name': 'Config 3','value': 'config3'}
];
Fiddle
A pure CSS solution is to use :empty pseudo-class to hide the empty options:
select option:empty {
display:none;
}
:empty MDN reference:
The :empty CSS pseudo-class represents any element that has no children. Children can be either element nodes or text (including whitespace). Comments or processing instructions do not affect whether an element is considered empty or not.
You can filter configs which exclude null data and then use it to bind ngOption
$scope.getConfigs = function () {
return $scope.configs.filter(function (x) {
return x.name != null;
})
}
HTML
<select ng-model="feed.config" ng-options="item.name for item in getConfigs()" multiple>
</select>
var MyApp = angular.module('MyApp1', [])
MyApp.controller('MyController', function($scope) {
$scope.feed = {};
$scope.configs = [{
'name': null,
'value': 'config1'
}, {
'name': 'Config 2',
'value': 'config2'
}, {
'name': 'Config 3',
'value': 'config3'
}];
$scope.getConfigs = function() {
return $scope.configs.filter(function(x) {
return x.name != null;
})
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp1">
<div ng-controller="MyController">
<select ng-model="feed.config" ng-options="item.name for item in getConfigs()" multiple>
</select>
<br> {{feed.config}}
</div>
</div>
You can also create a filter
var MyApp = angular.module('MyApp1', []);
MyApp.filter('notNull', [function() {
return function(object) {
var array = object.filter(function(x) {
return x.name != null;
})
return array;
};
}])
MyApp.controller('MyController', function($scope) {
$scope.feed = {};
$scope.configs = [{
'name': null,
'value': 'config1'
}, {
'name': 'Config 2',
'value': 'config2'
}, {
'name': 'Config 3',
'value': 'config3'
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="MyApp1">
<div ng-controller="MyController">
<select ng-model="feed.config" ng-options="item.name for item in configs | notNull " multiple>
</select>
<br> {{feed.config}}
</div>
</div>
check this it will work
<select id="feed" ng-model="feed.config" >
<option ng-repeat="config in configs " value="{{config.name}} || Null" ng-bind="config.name"></option>
</select>
add css
select option:empty {
display:none;
}
or without css
check this fiddle http://jsfiddle.net/ADukg/16750/
Related
I can't figure out how to set default selections into Extras fields.
Selection options are the same for both Main and Extras, but defaults should be set like following: [0] goes into Main and from [1] till the end of the list into Extras. Any advice on how to achieve that?
Structure is something like this:
<div>Main selection</div>
<input type="text" ng-model="mainInput" />
<select data-ng-options="option.id as option.title for option in items" ng-model="mainSelection" ng-init="mainSelection = mainSelection"></select>
<div>Extras</div>
<div ng-repeat="i in extraSelections">
<input type="text" ng-model="extraInput" />
<select data-ng-options="option.id as option.title for option in items" ng-model="extraSelection"></select>
</div>
$scope.extraSelections = [];
$scope.items = [{
'id': 1,
'title': 'Main/Extra'
},
{
'id': 2,
'title': 'Extra/Main1'
},
{
'id': 3,
'title': 'Extra/Main2'
},
{
'id': 4,
'title': 'Extra/Main3'
}
];
function getExtraSelections() {
if ($scope.items) {
for (var i = 1; i < $scope.items.length; i++) {
var rowObj = {
input: null,
title: null
};
$scope.extraSelections.push(rowObj);
}
}
}
function setDefaultSelections() {
$scope.mainSelection = $scope.items[0].id;
}
Plunker:
https://plnkr.co/edit/Yw94hLx3ntyOFL7AFmkx?p=preview
Edit:
I've tried to use ng-init or ng-selected with passing model and index like this:
$scope.getDefExtra = function(model, index){
model = $scope.items[index+1].id;
return model;
}
The function gets and sets correct values, but there are no changes in view.
Got it working.
The answer was simple:
<select data-ng-options="option.id as option.title for option in items" ng-model="extraSelection" ng-init="extraSelection = setExtraDefault(extraSelection,$index)"></select>
$scope.setExtraDefault = function(model, index){
model = $scope.items[index+1].id;
return model;
}
Please change this
$scope.mainSelection = $scope.items[0];
to
$scope.mainSelection = $scope.items[0].id;
and setDefaultSelections() called after $scope.items initialization.
I'd like to use ng-options for my select using AngularJS but it seems not working as I'd like...
Below you can see javascript code, which contain from creating array
and also view, where ng-options are using.
var vm = this;
vm.selectedUser;
vm.userDatas = [
{ id: 1, name: "Ruslan", surname: "Poltayev" },
{ id: 2, name: "Handor", surname: "Ten" }
];
<div id="page-content-wrapper"
data-ng-controller="TableShowCtrl as t">
<select data-ng-model="t.selectedUser"
data-ng-options="item.name for item in t.userDatas track by item.id">
</select>
</div>
I have this results
enter image description here
You need to declare the elements to display the different options. To display options using the name property you can use this:
<select ng-model="selected.user">
<option ng-repeat="item in t.userDatas">{{ item.name }}</option>
</select>
<!-- display selected user -->
{{ t.selected.user | json }}
Check this.
<body ng-app="Sample">
<h1>Sample Angular controller</h1>
<div ng-controller="Ctrl">
<div id="page-content-wrapper" >
<select ng-model="t.selectedUser" ng-options="item.name for item in usrDatas ">
</select>
</div>
</div>
</body>
Script:
// Code goes here
var app = angular.module("Sample",[]);
app.controller("Ctrl", function($scope){
var vm = this;
vm.selectedUser;
$scope.userDatas = [ { id: 1, name: "Ruslan", surname: "Poltayev" },
{ id: 2, name: "Galym", surname: "Kariev" }];
})
Working Demo at Plnkr
I am trying to create a list of editable inputs from a list of items. I want the user to be able to edit any of the items, but if they change there mind they can click a button and reset it back to the way it was.
So far I have everything working except the reset.
my html
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text" ng-click="copy(item)"/>
<button ng-click="reset(item)">
x
</button>
</div>
{{list}}<br>
{{selected_item_backup}}
</div>
my controller
function TestController($scope) {
$scope.selected_item_backup = {};
$scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ];
$scope.reset = function (item) {
// i know this wont work for many reasons, it is just an example of what I would like to do
item = $scope.selected_item_backup;
};
$scope.copy = function (item) {
angular.copy(item, $scope.selected_item_backup);
};
}
and here is a fiddle
http://jsfiddle.net/ryanmc/1ab24o4t/1/
Keep in mind that this is a simplified version of my real code. My objects will have many editable fields each. Also they are not indexed, and so the index cannot be relied on. I just want to be able to assign the original item on top of the new and have it replaced.
This is work solution jsfiddle
function TestController($scope) {
$scope.list = [{
value: 'value 1'
}, {
value: 'value 2'
}, {
value: 'value 3'
}];
var orgiinalList = [];
angular.forEach($scope.list, function(item) {
orgiinalList.push(angular.copy(item));
});
$scope.reset = function(index) {
$scope.list[index] = angular.copy(orgiinalList[index]);
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text" />
<button ng-click="reset($index)">
x
</button>
</div>
{{list}}
<br>
</div>
Changing your reset function so that it looks like this:
$scope.reset = function(index) {
$scope.list[index].value = "value "+ (index+1);
};
will make it so that your 'reset' buttons restore what would be those original values...
Angular controller:
function TestController($scope) {
$scope.selected_item_backup = {};
$scope.list = [{
value: 'value 1'
}, {
value: 'value 2'
}, {
value: 'value 3'
}];
$scope.reset = function(index) {
$scope.list[index].value = "value " + (index+1);
};
$scope.copy = function(item) {
angular.copy(item, $scope.selected_item_backup);
};
}
HTML:
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text" ng-click="copy(item)" />
<button ng-click="reset($index)">
x
</button>
</div>
</div>
The values of your array are directly modeled by those inputs - therefore as a user types changes into those inputs they are directly manipulating the $scope.list array so you cant really use it as a reference... Hope that makes sense.
You can't use global functions as controllers in newer versions of angular but you can register your controllers in your application:
<div ng-app ng-controller="TestController">
<div ng-repeat="item in list">
<label>Input {{$index+1}}:</label>
<input ng-model="item.value" type="text" ng-click="copy($index,item)"/>
<button ng-click="reset($index,item)">
x
</button>
</div>
{{list}}<br>
{{selected_item_backup}}
function TestController($scope) {
$scope.selected_item_backup = [];
$scope.list = [ { value: 'value 1' }, { value: 'value 2' }, { value: 'value 3' } ];
$scope.reset = function (index) {
$scope.list[index].value = $scope.selected_item_backup[index];
};
$scope.copy = function (index,item) {
// backup the old value
$scope.selected_item_backup[index] = item.value;
};
}
Problem Question -
I have a two drop down in my view. And second drop down rely on the first one. But somehow second one does not get updated
// my firstdrop down
<select ng-controller="myController"
ng-options="customer.name for customer in customerDetailData" ng-model="customer"
ng-change="updateCost(customer)">
<option value="">Please select customer</option>
</select>
// my second drop down
<select ng-controller="myController"
ng-options="cc.name for cc in customerCostData">
<option value="">Please select cost</option>
</select>
// my controller
(function() {
var myController = function($scope,Service){
$scope.customerDetailData;
Service.cust()
.success(function(data){
console.log(data)
$scope.customerDetailData = data;
})
.error(function(status,error){
})
$scope.customerCostData;
$scope.updateCost=function(customer){
Service.cost(customer.id)
.success(function(cost){
$scope.customerCostData= cost
})
.error(function(status,data){
console.log(status);
console.log(data);
})
}
};
myController .$inject = ['$scope','Service'];
angular.module('app').controller('myController ',myController );
}());
Is anything i am missing ? the data is coming through fine in the console. Please guide me
There are 2 things to do here:
The first and main issue is that you are attaching ng-controller to each select individually. This means it is actually creating 2 separate controllers, one for each select, and so they are given different scopes. You need to apply the ng-controller attribute to a parent element, such as the form.
The second issue is that angular will not automatically update an element just because the scope variable is used in ng-options. You therefore need to give it a ng-model so that Angular watches it correctly.
Here is an example of the code with two separate controller instances. Note the 2 alerts:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
<form ng-app="myApp">
<select ng-controller="myController"
ng-options="customer.name for customer in customerDetailData" ng-model="customer"
ng-change="updateCost(customer)">
<option value="">Please select customer</option>
</select>
<select ng-controller="myController"
ng-options="cc.name for cc in customerCostData" ng-model="customercustomerCostData">
<option value="">Please select cost</option>
</select>
</form>
<script type="text/javascript">
(function () {
var myApp = angular.module('myApp', []);
var myController = function ($scope) {
alert('myController created');
$scope.customerDetailData = [{ id: 1, name: "bob" }, { id: 2, name: "fred" }];
$scope.updateCost = function (customer) {
$scope.customerCostData = [{ name: customer.id.toString() }, { name: 'x' }];
}
};
myController.$inject = ['$scope'];
myApp.controller('myController', myController);
}());
</script>
Here it is with the single ng-controller applied to the form and ng-model="customerCostData" on the second select, so it now works:
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.4/angular.min.js"></script>
<form ng-app="myApp" ng-controller="myController">
<select
ng-options="customer.name for customer in customerDetailData" ng-model="customer"
ng-change="updateCost(customer)">
<option value="">Please select customer</option>
</select>
<select
ng-options="cc.name for cc in customerCostData" ng-model="customercustomerCostData">
<option value="">Please select cost</option>
</select>
</form>
<script type="text/javascript">
(function () {
var myApp = angular.module('myApp', []);
var myController = function ($scope) {
alert('myController created');
$scope.customerDetailData = [{ id: 1, name: "bob" }, { id: 2, name: "fred" }];
$scope.updateCost = function (customer) {
// would be an ajax call
$scope.customerCostData = [{ name: customer.id.toString() }, { name: 'x' }];
}
};
myController.$inject = ['$scope'];
myApp.controller('myController', myController);
}());
</script>
is the cost data the result of an Ajax request? if so, you may need to force a force a $digest cycle to let the UI know the model has been changed. You can achieve this by wrapping the assignment of cost in a $timeout, or $apply.
$timeout(function () {
$scope.customerCostData = cost;
});
or
$scope.$apply(function () {
$scope.customerCostData = cost;
});
I am using Angularjs and I have a dropdown box that lists several items. If the item the user needs is not in the list I need to allow the user to enter the data. Is this possible? How would I do it?
Try this out
Working Demo
html
<div ng-app="myapp">
<fieldset ng-controller="FirstCtrl">
<select ng-options="p.name for p in people" ng-model="selectedPerson"></select>
<br>
Name:<input type="text" ng-model="name"/>
<button ng-click="add(name)">Add</button>
</fieldset>
</div>
script
var myapp = angular.module('myapp', []);
myapp.controller('FirstCtrl', function ($scope) {
$scope.people = [{
name: 'John'
}, {
name: 'Rocky'
}, {
name: 'John'
}, {
name: 'Ben'
}];
$scope.add = function(value)
{
var obj= {};
obj.name = value;
$scope.people.push(obj);
$scope.name = '';
}
});
You seem to want something like a tagging widget. Maybe looking at angular-tags you can accomplish what you want