Angular 1/ ng-if one-time binding only in a condition - javascript

In my template i have :
<div ng-if="$ctrl.show()">
<input class="form-control" type="text">
</div>
In my component
show() {
if (angular.isDefined(this.parking.parkingType)) {
return this.parking.parkingType.labelKey === 'parking_type.air'
}
}
I want angular to process the function only when clicking on a select input (ui-select) by the attribute on-select="$ctrl.show()" :
<ui-select ng-model="$ctrl.parking.parkingType"
on-select="$ctrl.show()">
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
<ui-select-choices repeat="item in $ctrl.parkingType | filter: { label: $select.search }">
<span ng-bind-html="item.label"></span>
</ui-select-choices>
</ui-select>
This case may be similar to a sample case of: launching the function only when clicking on an ng-click

change your ng-show to a variable and keep on-select="$ctrl.show()" as is
In your view:
<div ng-if="$ctrl.shouldShow">
<input class="form-control" type="text">
</div>
In your component:
$ctrl.show = function() {
if (angular.isDefined(this.parking.parkingType)) {
$ctrl.shouldShow = (this.parking.parkingType.labelKey === 'parking_type.air')
}
}
It's a good practice not to have a function in ng-if, ng-show, and ng-hide because it's a performance hit

Related

$watch changes ui-select in individual object iterated via ng-repeat

I am working with <ui-select> and came across a problem I apparently do not understand how to tackle. There is a bunch of related topics on it here on SO, however, none of them covered my specific problem, which is I think quite simple for people who have worked with this directive before.
I have a big object with item objects inside, like this one:
let items = [{id: 1, name: 'name'}, {id: 2, name: 'name2'}];
I am iterating over object to make it visible in front. The option will be displayed in
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
The label will be selected in controller based on the "watched" value. My question here is what should I set in ng-model to watch the changes on the level of individual items and update it?
I tried to use track by index, ng-change instead of watch and a bunch of other approaches which brought no results.
Template:
<div ng-repeat="item in vm.items">
<div class="form-group field">
<label>Items:</label>
<ui-select ng-model="item.id"
ng-keyup="vm.newItems({ keyword: $select.search })"
search-enabled="false">
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
<ui-select-choices repeat="item.id as item in vm.shortlistsList">
<pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
</ui-select-choices>
</ui-select>
</div>
In controller:
function $onChanges() {
$scope.$watch('item.id', function (newValue, oldValue) {
console.log(item.id);
});
}
QUESTION: How can I watch each individual item, what/how should I pass to ng-model? At the moment I see no way of doing it as my half day of attempts is gone in vain.
Following a long and painful day of experiments, I found a workable solution:
Template:
<div ng-repeat="item in vm.items track by $index">
<div class="form-group field">
<label>Items:</label>
<ui-select ng-model="item[$index]"
ng-keyup="vm.newItems({ keyword: $select.search })"
search-enabled="false">
<ui-select-match allow-clear="true">
<span>{{ $select.selected.label }}</span>
</ui-select-match>
<ui-select-choices repeat="item.id as item in vm.shortlistsList">
<pre>Name: {{ item.label }}</pre><pre>Id: {{ item.id }} </pre>
</ui-select-choices>
</ui-select>
</div>
Controller:
for (let i = 0; i < vm.items.length; i++) {
$scope.$watch('vm.items[' + i + ']', function (newValue, oldValue) {
if (newValue && oldValue !== null) {
return newValue.label = newValue.name;
}
}, true);
}

Angular js pass value from select menu to controller using ng-change

I wanted to pass everytime i select an item from a ui-select to the controller I did try to use ng-update and ng change but it does not seem to work. Any idea? why code is below. Thank you. I just want to trigger a function once i select an item from the ui select.
controller
$scope.update = function () {
alert("triggered")
}
view
<ui-select ng-change="update()" multiple="multiple" tagging="tagging" tagging-label="(custom 'new' label)" ng-model="main.record.skills" theme="bootstrap" sortable="true" style="width: 300px;" title="">
<ui-select-match class="ui-select-match" placeholder="Select skills">{$ $select.selected.name $}{$ $item.name | limitTo:70 $} {$ $item.name.length > 70 ? "..." : "" $}</ui-select-match >
<ui-select-choices ng-change="main.update()" refresh="main.read_skills($select.search)" repeat="skill in main.skills | filter:$select.search track by $index">
<div ng-bind-html="skill.name | highlight: $select.search"></div>
{$ name $}
</ui-select-choices>
</ui-select>
Add on-select="onSelected($item)" to your ui-select and in controller:
$scope.onSelected = function (selectedItem) {
//do selectedItem.PropertyName like
//selectedItem.Name or selectedItem.Key
//whatever property your list has.
}

How to set the required field for md-autocomplete dynamically

trying to use md-autocomplete inside a custom directory.
I wanted the field to be required based on two conditions. One which is initialized(cond1) and one that changes(cond2)
I've tried to do it like this:
required="{{ cond1 && !cond2 }}"
But for some reason the md-autocomplete always becomes required, even if cond1 is initially undefined or false. It also doesn't respond to changes done to the value of cond2.
The validator also doesn't check if the selected-item has been set. It just checks if there is text in the field.
ng-required doesn't seem do anything.
Any ideas how i can make this work?
EDIT:
Here is my directive's .html
<div ng-form="dummyForm">
<md-autocomplete
md-input-name="{{ctrl.fieldName}}"
md-selected-item="ctrl.dummyItem"
md-selected-item-change="ctrl.setSelectedItem()"
md-search-text="ctrl.searchText"
md-items="item in ctrl.querySearch(ctrl.searchText)"
md-item-text="item.display || item"
md-min-length="0"
placeholder="{{ ctrl.placeholder }}"
ng-disabled="ctrl.selectAll || ctrl.isDisabled"
required="{{ ctrl.isRequired && !ctrl.selectAll }}">
<md-item-template>
<span>{{ item.display || item }}</span>
</md-item-template>
<md-not-found>
No results.
</md-not-found>
</md-autocomplete>
</div>
<div class="label-wrapper">
<label
class="checkbox-label"
ng-if="ctrl.selectAll !== null">
<input
type="checkbox"
ng-model="ctrl.selectAll"
ng-change="ctrl.checkSelectAll()">
{{ ctrl.checkboxName ? ctrl.checkboxName : 'Select all' }}
</label>
</div>
It is basically just a custom input field that lets the user either select a value from the list OR click the checkbox to "select all" items. When the checkbox is selected, i don't want the md-autocomplete field to be required anymore.
It does work fine with ng-required as you can see in this demo plnkr.
View
<form name="myForm">
<md-autocomplete
md-autoselect=true
placeholder="What is your favorite place?"
md-item-text="item.display"
md-items="item in ctrl.items"
md-menu-class="autocomplete-custom-template"
md-min-length="2"
md-delay="ctrl.throttle"
md-search-text="ctrl.searchText"
md-search-text-change="ctrl.searchTextChange(ctrl.searchText)"
md-select-on-match=true
md-match-case-insensitive=true
md-selected-item-change="ctrl.selectedItemChange(item)"
ng-required="ctrl.cond1 && !ctrl.cond2"
md-selected-item="ctrl.selectedItem">
{{ myForm.$error }}
<div>
<md-button type="submit">Submit</md-button>
</div>
</form>
AngularJS controller
myApp.controller('MyCtrl', function ($scope) {
var vm = this;
this.cond1 = true;
this.cond2 = false;
});

How to show drop down Angularjs-ui-select onclick on hyperlink tags?

I want to bind ui-select to <a></a> tag, so when we click on this tag, it show ui-select.
Please see the following demo Plunker DEMO
In demo, select-ui are shown separately, but I want to show it only when I click on following drop-downs (person, country), when I click on person It show the following ui-select. Similarly When I click on country it should show the ui-select for country.
It should be attach with the drop-down,
<ui-select ng-model="country.selected" theme="selectize" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select or search a country in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="country in countries | filter: $select.search">
<span ng-bind-html="country.name | highlight: $select.search"></span>
<small ng-bind-html="country.code | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>
I modified the my pluncker DEMO as suggested by Naga Sandeep, but after selection of country, I am not able to select again person.
All you need to do is
1) toggle a property on scope
2) ng-show that property on ui-select.
Click for countries
<ui-select ng-model="country.selected" theme="selectize" ng-disabled="disabled" style="width: 300px;" ng-show="showCountry">
In your js file toggle the property
$scope.showCountry = false;
$scope.toggleCountry = function()
{
$scope.showCountry = !$scope.showCountry;
}
i updated the plunker example : http://plnkr.co/edit/e64JGEakaKRVBgNwgpDg?p=preview
into controller, add isActive() function:
//that function checks if the ui-select is active
$scope.isActive = function(type){
return $scope.selectedType == type;
};
into HTML:
Just wrap your ui-select into <div></div> and check if they are active, like this :
<div ng-show="isActive('person')">
<h3>Select2 theme</h3>
<p>Selected: {{person.selected}}</p>
<ui-select ng-model="person.selected" theme="select2" ng-disabled="disabled" style="min-width: 300px;">
<ui-select-match placeholder="Select a person in the list or search his name/age...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="person in people | propsFilter: {name: $select.search, age: $select.search}">
<div ng-bind-html="person.name | highlight: $select.search"></div>
<small>
email: {{person.email}}
age: <span ng-bind-html="''+person.age | highlight: $select.search"></span>
</small>
</ui-select-choices>
</ui-select>
</div>
<div ng-show="isActive('country')">
<h3>Selectize theme</h3>
<p>Selected: {{country.selected}}</p>
<ui-select ng-model="country.selected" theme="selectize" ng-disabled="disabled" style="width: 300px;">
<ui-select-match placeholder="Select or search a country in the list...">{{$select.selected.name}}</ui-select-match>
<ui-select-choices repeat="country in countries | filter: $select.search">
<span ng-bind-html="country.name | highlight: $select.search"></span>
<small ng-bind-html="country.code | highlight: $select.search"></small>
</ui-select-choices>
</ui-select>
</div>
Hope helps , good luck.

ng-model value not available outside of ng-repeat

I have an object like this:
"styleArr":[
{
"text":"General Text","default_value":"#d11e1e","scopval":"general"
},
{
"text":"Accent Color","default_value":"#2ec72e","scopval":"Accent"
},
{
"text":"Button/Link Hover","default_value":"#2ec72e","scopval":"Button_link"
}]
In my template :
<div ng-repeat="style in styleArr">
<span> {{ style.text }} </span>
<input colorpicker type="text" ng-model="style.scopval"/>
</div>
I want to make ng-model value dynamically.So that I can change the color of text/background color outside from this ng-repeat.
When I try to use ng-model value outside of this ng-repeat it not seems to work for me.
<div class="myclass" ng-style="{'background-color' : general}">This is my first div..</div>

Categories