Add glyphicon icon to a 'saved' selected item using ng-options - angularjs

What if we have this scenario ....
A dropdown with 3 elements. Upon selecting an item and clicking the save button, the ng-model from the dropdown menu is binded with an html tag so that the ng-model now has a glyphicon icon appended before the item name.
I have tried a basic implementation, however I was not able to complete it.
The Model
var app = angular.module('myApp', ['ngSanitize'])
app.controller('myController', function($scope){
$scope.name = 'Dylan'
$scope.saved = false
$scope.data = [{
'name' : 'Item 1',
'color': 'red'
},
{
'name' : 'Item 2',
'color': 'blue'
},
{
'name' : 'Item 3',
'color': 'green'
}]
$scope.saveItem = function(item) {
// var index = $scope.data.indexOf(item);
// $scope.data[index].name = "✓" + item.name
// console.log(index)
$scope.binder = " ✓ " + item.name;
}
})
The View
<body ng-app="myApp">
<div ng-controller="myController">
<span class="glyphicon glyphicon-star" aria-hidden="true"></span> {{name}}
<div class="row">
<div class="col-sm-2" >
<select class="form-control selectPicker glyphicon"
ng-model="selectedItem"
ng-options = "item as item.name for item in data">
</select>
</div>
</div>
<br>
<button type="button"
class="btn btn-danger"
ng-disabled="!selectedItem"
ng-click="saveItem(selectedItem)">
Save
</button>
<div ng-bind-html="binder"></div>
</body>
Preview of result
What I want is this ....
The current ng-model 'Item 1' is to be replaced/updated exactly like the binder (With the tick included).
Furthermore, I tried to do the same thing using ng-repeat, however this is not an option for me as I need to use the object properties throughout the whole application. With ng-repeat, from my understanding, it seems that the selected value is a string rather than an object.
Thanks in advance for any help or suggestions :)

A) If you mean you want to add the Glyphicon to the select then this isn't simple and I can point you here
B) If you want to add the simple UTF-8 symbol then this is shown below.
The most efficient thing to do would be to add a new value to your data object to hold the icon/symbol you require so you can use this as and when required.
So in your save item function you are saving the icon/symbol value away from your name.
$scope.saveItem = function(item) {
var index = $scope.data.indexOf(item);
$scope.data[index].symbol= "✓";
};
Then you can display your output however you wish such as shown below.
<div ng-bind-html="selectedItem.symbol + ' ' + selectedItem.name"></div>
Your data afterwards will look like.
$scope.data = [{
'name' : 'Item 1',
'color': 'red',
'symbol': '✓'
}];
To render the symbol in your select options you will need to use a custom filter as shown below.
app.filter('renderSymbol', function(){
return function(val){
var symbol = document.createElement('div');
symbol.innerHTML = val;
return symbol.childNodes[0].nodeValue;
};
});
The filter will take the value of each option and put them in a div which will render the symbol for you.
The filter is used in your ng-options as shown:
ng-options="item as (item.symbol + ' ' + item.name | renderSymbol) for item in data"
Output:
Here is a working example: Plunker

Related

Check if state of dropdown has changed

I am using ng-options to display drop-down with options. Suppose I have three options in it for example option1, option2, option3.By default option1 is selected, now if a user selects option2, then $pristine becomes False and again if he selects option1 then from angularjs's prospective $pristine should be false but according to user he has not changed the option.So I was looking for a way to detect this change
Here is the Js fiddle demo
HTML
<div ng-app="myApp">
<div ng-controller="ctrl">
<form name="myForm">
{{myForm.$pristine}}
<select ng-model='list' ng-options='item.name for item in data'>
</select>
</form>
</div>
</div>
JS code
var app = angular.module('myApp', []);
app.controller('ctrl', function($scope) {
$scope.data = [{
id: 1,
name: 'test'
}, {
id: 2,
name: 'test1'
}];
$scope.list = $scope.data[0];
$scope.$watch('list', function(o, n) {
if ($scope.list == $scope.data[0])
$scope.myForm.$pristine = true;
})
});
You have add watch on your list model then this can be achieved
That is exactly what ng-change is for.
Usage would be like this (added $index to show you another option):
HTML
<div ng-app="myApp">
<div ng-controller="listController">
<form name="myForm">
<select ng-model="currOption"
ng-options='item.name for item in data'
ng-change="optionChanged(currOption, $index)">
</select>
</form>
</div>
</div>
Controller
angular.module('myApp')
.controller('listController', function($scope) {
$scope.data = [{
id: 1,
name: 'option1'
}, {
id: 2,
name: 'option2'
}, {
id: 3,
name: 'option3'
}];
$scope.optionChanged(option, index) {
// option = the selection the user just made.
// index = the index of the selection in your data. I.E. $scope.data[index]
};
});

Data Binding ionic checkbox in controller not working

Is my firts time working with ionic and angular. I have a checkbox list populate from controller, when I click on check the view show my change but if I want view this change on controller show me the old value. I need add/substract the values
html
<div class="item-text-wrap">
<ion-list>
<ion-checkbox ng-repeat="item in listTypeProduct"
ng-model="item.checked"
ng-checked="item.checked"
ng-change="add(listTypeProduct)" >{{ item.text }}
</ion-checkbox>
</ion-list>
</div>
<div class="item">
<pre ng-bind="listTypeProduct | json"></pre>
</div>
the print on page is working!
This is my controller
app.controller('CotCtrl', function($scope, $ionicSideMenuDelegate,$rootScope) {
$scope.listTypeProduct = [
{ text: "a1", checked: false , value:4500 },
{ text: "a2", checked: false , value:2000 },
{ text: "a3", checked: false , value:1200 }
];
$scope.add = function(list){
console.log(JSON.stringify(list));
};
But on my controller when I iterate the array give me the old information.
Method "add" I want iterate the list with update values for example
angular.forEach(list, function(val, key) {
if( checked && (value) )
$scope.total += total+val.value;
});
To add all checked values.
Quoting AngularJS documentation here
Note that this directive "ngChecked" should not be used together with ngModel, as this can lead to unexpected behaviour.
This said, use only ng-model to bind your checkbox to the model in the controller.

How to conditionally disable an object within an array in Angular

I have several select elements on the same page. Each select dropdown contains the same items. I would like to disable an item within the dropdown if it has already been selected in another select element. In other words, I don't want an item to be selected more than once across all of the select elements.
Any thoughts on how to accomplish this?
When I use the following code, nothing is disabled in the dropdown.
Code for controller:
var editProject = this;
editProject.addMore = function() {
editProject.project.fruit.push({});
};
editProject.fruitids = [
{code: 'GOODS', fruit: '1. Apple'},
{code: 'GOODS', fruit: '2. Orange'},
{code: 'GOODS', fruit: '3. Peach'},
];
HTML:
<div ng-repeat="item in editProject.project.fruits">
<select ng-model="editProject.project.fruits[$index]"
ng-options="fruitid.class group by fruitid.code disable when (editProject.project.fruits.indexOf((fruitid)) !== -1)
for fruitid in editProject.fruitids track by fruitid.class">
<option value="">--Select Class--</option>
</select>
</div>
<button ng-click="editProject.addMore()" class="btn btn-default btn-xs" role="button">Add More Classes
</button>
You need to use a function as the expression for the disable parameter in the ng-options directive.
Please see working example1
HTML
<div data-ng-repeat="item in items">
<select data-ng-options="fruitId.fruit disable when isDisabled(fruitId) for fruitId in fruitIds" data-ng-model="items[$index]"></select>
</div>
JS
$scope.isDisabled = function(fruitid) {
return ($scope.items.indexOf((fruitid)) !== -1);
};
This will disable the option in all the select's including the the select where the option was selected. The option will now not be selected any more as it is disabled.
You need to exclude the current fruitId so it is still enabled in the selected select
Please see example2 where the current fruitId is excluded and the selected option is disabled in the other selects
We make sure that the index found is not the index of the current item.
HTML
<div data-ng-repeat="item in items">
<select data-ng-options="fruitId.fruit disable when isDisabled(fruitId, item) for fruitId in fruitIds" data-ng-model="items[$index]"></select>
</div>
JS
$scope.isDisabled = function(fruitid, item) {
return ($scope.items.indexOf((fruitid)) !== -1 && $scope.items.indexOf((fruitid)) != $scope.items.indexOf(item));
};
This code can help to you?
index.html:
<html ng-app>
<head>
<title>Demo</title>
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/controllers/app.js"></script>
<link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="css/bootstrap-responsive.min.css">
</head>
<body>
<div class="container" ng-controller="AppCtrl">
<select ng-model="selectedOption" ng-change="change(selectedOption)">
<option ng-repeat="var in myObj.myArr" value={{var.id}}
ng-disabled="var.selectable">
{{var.fruit}}
</option>
</select>
</div>
</div>
</div>
</body>
</html>
app.js:
function AppCtrl ($scope) {
$scope.myObj = {
"myArr":[
{id:0, code: 'GOODS', fruit: '1. Apple', selectable:false},
{id:1, code: 'GOODS', fruit: '2. Orange', selectable:false},
{id:2, code: 'GOODS', fruit: '3. Peach', selectable:false}
]};
$scope.selectedOption = {};
$scope.change = function(id){
var name = $scope.myObj.myArr[id].selectable = true;
};
};
You can:
1- Create an angularjs directive that encapsulate every select/dropdown and assign a unique id to each of them.
2- Bind the array of elements to all directives
3- When the user selects an item you set an item's property (assignedTo) with the unique id of the directive as the value (and clean the property for all other items with this id as value)
4- The select disables elements based on the value of the property (assignedTo !== uniqueId)
View template:
<my-select-directive unique-select-id="1" items="theItems"><my-select-directive>
<my-select-directive unique-select-id="2" items="theItems"><my-select-directive>
<my-select-directive unique-select-id="3" items="theItems"><my-select-directive>
Directive template:
<select ng-model="selectedItem" ng-change="change()">
<option ng-repeat="item in myItems" value={{item.id}}
ng-disabled="item.assignedTo && item.assignedTo !== uniqueSelectId">
{{item.fruit}}
</option>
</select>
Directive code:
//here you can implement logic to remember previous selection, now it doesn't
scope.selectedItem= null;
scope.change = function(){
//needed to sync
//remove the mark of the previous selected item for this dropdown if any
myItems.forEach(function(item) {if (item.assignedTo === scope.uniqueSelectId) item.assignedTo = null;});
//now mark the item as selected in this dropdown
selectedItem.assignedTo = scope.uniqueSelectId;
}
This is not working code, it's only to guide you

Ionic , angular , Show or disable a component within controller

I have the following code. The following code displays 5 tag item.
What I wanted to do is when user click on any of the tag item, it will be hidden or blank-out. But when I clicked on any of it, all the tag item got blanked out instead of the item I selected. Can anyone give me some idea ?
<div data-ng-repeat="x in mylist">
<a class="button" ng-click="hideme();" style="{{visibility}}">{{x}}</a>
</div>
.controller('MyCtrl', function($scope, $stateParams, chats) {
$scope.hideme = function(index, value) {
$scope.visibility = "background-color: #000000 !important;";
}
});
Firstly, you might want to change your object structure a bit. Remeber always have a dot (.) in your model value.
Try this.
<div ng-app ng-controller="myCtrl">
<div ng-repeat="x in myList">
{{x.value}}
</div>
</div>
function myCtrl($scope){
$scope.myList = [{
value: "a"
}, {
value: "b"
}, {
value: "c"
}];
$scope.hide = function(obj){
obj.hide = true;
}
}
JSFiddle

AngularJS Accordion Expand All Collapse All

I am trying to get the accordions to toggle correctly through the directive ng-click. If I have Item one open how do I get it to expand all the accordions? Item two and Item three will continue to expand and collapse but Item one stays stagnant.
Plunker
alternately you can adjust your buttons so that they just loop through the children.
html:
<div ng-controller="AccordionDemo">
<div >
<div class="stuff_in_the_middle" >
<div ng-repeat="m in results" ng-click="m.open = !m.open" style="margin-bottom:20px">
<div heading="{{m.label}}" is-open="m.open" style="background-color:#d2d2d2; cursor:pointer" >
{{m.label}}
</div>
<div ng-show="m.open" style="padding:10px">
contents
</div>
</div>
<span class="btn btn-default" ng-click="toggle(false)">Collapse All</span>
<span class="btn btn-default" ng-click="toggle(true)">Expand All</span>
</div>
<hr />
</div>
</div>
JS:
var module = angular.module('plunker', []);
module.controller('AccordionDemo', ['$scope',
function ($scope) {
$scope.results = [
{label: 'Item 1', open: false},
{label: 'Item 2', open: false},
{label: 'Item 3', open: false}
];
$scope.toggle = function(state) {
$scope.results.forEach(function(e) {
e.open = state;
});
}
}
]);
see it working here: http://plnkr.co/edit/T6iv7mSoat9SQBwSIFJP
You have a problem with scopes. Simple rule is to never set variable value from ng-click or similar directives if you gonna use this variable outside - in parent.
It is caused by ng-repeat, which creates scope and if you will try to define new variable within it(you are doing it, because you have used name plunker, instead of opened), it will be defined only to current item in repeat.
You can use setter function to set it to right scope. So, here we go: http://plnkr.co/edit/h3MtKywiOaIQhpnAzWLT?p=preview

Resources