Angularjs: radio button checked - javascript

I'm trying to build a color configurator in AngularJS using radio buttons and everything seems to be working, the data binds, etc... but I'm not able to set the default color radio button checked. As I see in the docs if the ng-model is the same as the radio value the input should be auto-checked but I don't know if this only work for strings and not for objects.
This is the HTML:
<div ng-app ng-controller="ThingControl">
<ul >
<li ng-repeat="color in colors">
<input type="radio" ng-model="thing.color" value="{{color}}" />{{ color.name }}
</li>
</ul>
Preview: {{ thing }}
</div>
And this is the JS:
function ThingControl($scope){
$scope.colors = [
{ name: "White", hex: "#ffffff"},
{ name: "Black", hex: "#000000"}
]
$scope.thing = {
color: $scope.colors[1]
}
}
You can see the previous example in this fiddle:
http://jsfiddle.net/xWWwT/1/
Thanks very much in advance!

Selection is matched by the string defined in Value, so you can either do
value="{{color.name}}"
$scope.thing = {
color: $scope.colors[1].name
}
or
value="{{color}}"
$scope.thing = {
color: JSON.stringify($scope.colors[1])
}
As #bertez mentioned, use ng-value is the best solution.
ng-value="color"

Have you already tried ng-change directive? You can use a expression to set it checked, try this.
<div ng-app ng-controller="ThingControl">
<ul >
<li ng-repeat="color in colors">
<input type="radio" ng-model="thing.color" value="{{color}}" ng-checked="$index == 0" />{{ color.name }}
</li>
</ul>
Preview: {{ thing }}
</div>

Related

Run functions with checkbox interactions

I am trying to create checkboxes that will add an object to an array when checked, but will remove that object when unchecked. I am not sure if this is the correct way, but will show what I have below. Using Angular 2 by the way.
Original Code:
<div>
<ul>
<a *ngFor="let perkResult of perkList.results" (click)="onAddPerk(perkResult)">
<li>{{ perkResult.perk }}</li>
</a>
</ul>
</div>
<div *ngFor="let perk of company.perks;>
{{ perk.perk }}
<a (click)="onDeletePerk(i)"></a>
</div>
Functions:
onAddPerk(perkResult) {
// Adds a new perk to the array
this.company.perks.push({perk: (perkResult.perk)});
}
onDeletePerk(i: number) {
// Delete the perk in the selected index
this.company.perks.splice(i, 1);
}
And I want to do something like this:
<div *ngFor="let benefitResult of benefitList.results" >
<a (click)="onAddBenefit(benefitResult)">
<input type="checkbox" />
//Basically if checked then run add function, if not checked then run delete function
</a> {{ benefitResult.benefit }}
</div>
EDIT:
Got to this point, but cannot reference my other scope for the delete.
<ul *ngIf="benefitList">
<div *ngFor="let benefitResult of benefitList.results; let i = index" >
<input type="checkbox" (change)="updateBenefits($event, benefitResult, i)" >
<li>
{{ benefitResult.benefit }}
</li>
</div>
</ul>
//Original delete
<div *ngFor="let benefit of company.benefits; trackBy: customTrackBy; let i = index">
{{benefit.benefit}}
<a (click)="onDeleteBenefit(i)"></a>
</div>
//function
updateBenefits(event, benefitResult, i) {
if(event.srcElement.checked) {
this.company.benefits.push({benefit: (benefitResult.benefit)});
} else {
this.company.benefits.splice(i, 1);
}
}
You could listen to the change event on the checkboxes. Then pass the event along with the object and index to a method that will look at the status of the checkbox element.
In the component:
optionsList = {
results: [{
perk: 'free coffee',
checked: false
}, {
perk: 'car',
checked: false
}, {
perk: 'pastry',
checked: false
}, {
perk: 'free post-it notes',
checked: false
}]
};
updatePerks(event, perkResult) {
perkResult.checked = event.srcElement.checked;
}
In your HTML template:
<ul>
<li *ngFor="let listItem of optionsList.results">
<label><input type="checkbox" (change)="updatePerks($event, listItem)">
{{ listItem.perk }}</label>
</li>
</ul>
Note: I don't know your data structure, so make the necessary adjustment or post a data sample if you need more help.

How can we achieve product filter page using angularjs with multi selection of checkboxes?

I have created a tabular page in which i need to filter the table with filters using a left side facets boxes of different category but with multi-selection options and i need to use Angularjs for this requirement.
I need to check/uncheck using the clear filter selection .
Any helping library can help to achieve the same or we need to do some logic around the checkboxes to achieve this.
My checkbox code looks like this:
<div class="col-sm-2" style="padding-top: 10px; padding-bottom: 20px;">
<div class="facetBx sltBx" ng-show="tabFilters.length > 0">
<p class="facetBxTitle"><i class="fa fa-filter"></i> Filter Selection
<a class="clrSlt" ng-click="clearAllFilters();">Clear</a>
</p>
<div class="facetBxChld" id="uRslctn">
<ul>
<li ng-repeat="item in tabFilters">
<div class="crop">
<strong title="{{item}}">{{item}}</strong>
</div>
<i class="fa fa-remove rmvThs" style="font-size: 14px;color:#000;float: right;" ng-click="checkItem(item, item,false);"></i>
</li>
</ul>
</div>
</div>
<div class="facetBx" ng-repeat="item in filters">
<p class="facetBxTitle bomtype">{{item.label}}</p>
<div class="facetBxChld" id="bomFacet">
<ul class="multiselect" style="max-height: 140px;overflow-y: auto;">
<li ng-repeat="(k,v) in item.values">
<input type="checkbox" ng-model='isSelected' ng-click='checkItem(item.name, k, isSelected)'>
<span> {{k}} ({{v}})</span>
</li>
<li ng-show="value.length == 0">
No Data Available.
</li>
</ul>
</div>
</div>
</div>
Below website are the reference of the code which i am trying to build:
www.jabong.com
The UI(HTML) is done but i am facing the trouble in the maintaining the checking and un-checking of the checkboxes which are not clearing off.
I believe i need to code something in the ng-model of checkbox to achieve it but i am not able to be successfull so need help on the same.
Sample Plunkur for the same:
enter link description here
Thanks in advance.
Basically you need to keep track of ng-model of checkboxes with some property in your $scope. I did this by modifying your $scope.filters and adding selected property inside it, like below.
var filters = [{
label: 'Brand',
name: 'brand',
values: {
Blackberrys: 503,
Arrow: 175,
ParkAvenue: 358
}
}, {
label: 'Color',
name: 'color',
values: {
Black: 100,
Green: 200,
Red: 300
}
}]
function loadFilters() {
$scope.filters = filters.map(function(filter) {
var filter = angular.copy(filter);
for (var key in filter.values) {
filter.values[key] = {
selected: false,
count: filter.values[key]
}
}
return filter;
})
}
loadFilters();
Then you can call loadFilters() any time you want to clear all filters. Please see POC attached below.
https://plnkr.co/edit/SADPoUpftnJkg1rMuSB9?p=preview
You should try 'ng-change' on checkboxes to trigger a method which changes the values according to checked and unchecked checkboxes.
For Ex.
<input type="checkbox" ng-model='isSelected' ng-click='checkItem(key, k, isSelected)' ng-change="yourMethodHere()">
in JS:
$scope.yourMethodHere = function() {
if (isSelected) {
// filter the values here
} else {
// non filtered values
}
}
By doing this you do not need to even maintain the values of exiting checked/unchecked checkbox.

How to change an angular2 html dynamically?

Im trying to find a way to change some html lines of a component dynamically.
<li *ngFor="p in persons" [attr.id]="p.id">
<span> {{ p.name }} </span>
<a (click)="getAge(p.id)">Get Age<a/>
</li>
If the user clicks on the Get Age link i would like to replace the content inside of the corresponding li tag to something like:
<span> {{ p.OtherProperty }} </span>
<a (click)="OtherMethod(p)">Call OtherMethod<a/>
I found that ComponentFactoryResolver to create dynamic components, but i found it too overwhelming for just 2 lines of html. And i tried to change it by hand using jquery but it does not work to create the event bindings:
getAge(id) {
//some work
//remove the corresponding <li> content
$('#' + id).append('<a (click)="getAnotherValue(p.name)">GetAnotherValue<a/>');
$('#' + id).append('<span> {{ p.age}} </span>'); //this obviously doesnt work. But thats the ideia.
}
So how can i replace some html tags with angular attributes dynamically?
You could access the person's Object property dynamically like this:
object[property]; // Where property is a string
// If property equals 'name', the above sentence would equal this:
object.name; // or `object['name'];`
So, following your example, you could do this:
export class App {
persons = [
{
id: 1,
name: 'John',
age: 25
},
{
id: 2,
name: 'Mike',
age: 30
}
];
selectedProperty = 'name';
constructor() {
}
getProperty(prop) {
this.selectedProperty = prop;
}
}
And in your template you could:
<div>
<li *ngFor="let p of persons" [attr.id]="p.id">
<span> {{ p[selectedProperty] }} </span>
<br>
</li>
<button (click)="getProperty('age')">Get Age</button>
<button (click)="getProperty('name')">Get Name</button>
</div>
If I understood well, this should do the trick. You can't use ngIf because if you have 60 properties or persons then will be somewhat caothic.
Check the Plunker
Use ngIf to activate the code as shown:
<li *ngFor="p in persons" [attr.id]="p.id">
<div *ngIf=!p?.touched>
<span> {{ p.name }} </span>
<a (click)="getAge(p)">Get Age<a/>
</div>
<div *ngIf=p?.touched>
<span> {{ p.age}} </span>
<a (click)="getAnotherValue(p.name)">GetAnotherValue<a/>
</div>
</li>
isGetAgeClicked=false;
getAge(person) {
//some work
//remove the corresponding <li> content
person.touched=true
}

How to ng-style one element it's $index created by ng-repeat?

I have 2 directives: wa-hotspots & wa-tooltips.
On ng-mouseover of wa-hotspots it takes that $index of wa-hotspot and sets the visibility and position of wa-tooltip via ng-class:on and ng-style="tooltipCoords" by matching indexes.
Note: Since wa-hotspots & wa-tooltips share the same collection page.hotspots and therefore they share teh same index via ng-repeat
Problem:
When you hover over wa-hotspots it sets the ng-style position to ALL of the elements in wa-tooltips. I only want it ot set the proper matching index. Since the visiblity is controlled by ng-class, This doesn't really matter but it seems like it's extra overhead that could be avoid.
Therefore:
Question:
How can I make sure that my ng-style isn't styling all the wa-tooltips on hover of wa-hotspots? But rather, style only the tooltip that matches the proper shared index?
<ul id="wa-page-{{page.pageindex}}" class="wa-page-inner" ng-mouseleave="pageLeave()">
<li wa-hotspots
<map name="wa-page-hotspot-{{page.pageindex}}">
<area ng-repeat="hotspot in page.hotspots"
class="page-hotspot"
shape="{{hotspot.areashape}}"
coords="{{hotspot.coordinatetag_scaled}}"
ng-mouseover="showTooltip($index, hotspot.coordinatetag_scaled)"
ng-mouseout="hideTooltip()">
</map>
</li>
<li class="tooltip-wrapper">
<ul class="tooltip">
<li wa-tooltips
ng-repeat="hotspot in page.hotspots"
ng-class="{on: hovered.index == $index}"
ng-mouseover="hovered.active == true"
ng-mouseout="hovered.active == false"
ng-style="tooltipCoords" hotspot="hotspot">
</li>
</ul>
</li>
</ul>
tooltip:
You need to make it per item like in your case - hotspot.tooltipCoords then set that variable by index.
you can do the check inside the expression function.
Heres a fiddle
<div ng-controller="MyCtrl">
<div ng-repeat="item in items" ng-style="isChecked($index)">
name: {{item.name}}, {{item.title}}
<input type="checkbox" ng-model="item.checked" />
</div>
</div>
...
$scope.isChecked = function($index){
var color = $scope.items[$index].checked ? 'red' : 'blue';
return {color:color};
}
Instead of
ng-mouseover="hovered.active == true"
ng-mouseout="hovered.active == false"
use
ng-mouseover="hotspot.class== 'active'"
ng-mouseout="hotspot.class== ''"
and after that you can use hotspot.class in ng-class ie:
ng-class="hotspot.class"
Please see demo below:
var app = angular.module('app', []);
app.controller('homeCtrl', function($scope) {
$scope.items = [{
id: 1
}, {
id: 2
}, {
id: 3
}, {
id: 4
}]
});
.red {
background-color: yellow;
}
p {
background-color: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="homeCtrl">
<p ng-repeat="i in items" ng-mouseover="i.class='red'" ng-class="i.class" ng-mouseout="i.class = ''">{{i.id}}</p>
</div>
</div>
Use the below one
<div class="col-md-4 col-xs-12 col-lg-4" ng-repeat="obj in items">
<button type="button" class="btn btn-sm pull-right" ng-class="obj.class" ng-click="obj.class='test'" >
Write a new class "test". Instead of click you can use the same in ngmouseover

Binding OBJECT ARRAY to OPTIONS VALUES of a SELECT in AngularJs

I have a hash of objects, and the ID of this hash is binding to a RADIO BUTTON. When the user select this radio, I need to populate a select tag with options based on attribute of this model.
Its hard to explain, so I created a Codepen to show what I want:
http://codepen.io/rizidoro/pen/BeJjf
Thanks in advance!
Here's a codepen demo binding dynamically to a single SELECT element, with a working ng-model binding on selection change:
HTML:
<div ng-controller="TestCtrl">
<ul>
<li ng-repeat="attr in data">
<input type="radio" name='data-attr' value='{{attr.id}}' ng-model="selected.id" />{{attr.name}}
</li>
</ul>
<select ng-model="selected.value" ng-options="item.name for item in selectedAttr.values "></select>
</div>
JS:
function TestCtrl($scope) {
$scope.selected = {};
$scope.data = [
{"id":"113000",
"name":"Size",
"values":
[{"id":"92029","name":"Size A"},
{"id":"92030","name":"Size B"}]
},
{"id":"113002",
"name":"Color",
"values":
[{"id":"94029","name":"Blue"},
{"id":"94030","name":"Black"}]
}
];
$scope.$watch('selected.id', function(id){
delete $scope.selected.value;
angular.forEach($scope.data, function(attr){
if(attr.id === id){
$scope.selectedAttr = attr;
}
});
});
}
I have created a fiddle, that may solve ur problem. http://jsfiddle.net/qY2Zz/.
Seperated the data to a service.
animateAppModule.service('data', function(){...})
Assigned a model to the select box.
ng-model="$scope.selectedOption"
http://jsfiddle.net/wagedomain/afuz5/
I rewrote your HTML a little - not using ul / li tags where a div or span would suffice. Makes it easier.
Basically, inside the ng-repeat, you can do this:
<div ng-repeat="attr in data">
<input type='radio' name='data-attr' value='{{attr.id}}' />{{attr.name}}
<select ng-model="selected" ng-options="item.name for item in attr.values "></select>
</div>
It's the ng-options that makes this work. I also added a $scope.selected variable to model bind to but I'm not doing anything with it in the fiddle. Use as you need.

Categories

Resources