How to toggle ng class by clicking a checkbox button? - javascript

Through webservice i used ngrepeat to show the check box.
It contains 10 check box. Check box was produced in div tag not used html input tag.
In Html,
<div ng-repeat="showproduct in showproducts.ProductList.products" class="col-md-3 mobile-two">
<div id="1" class="mSelected">{{showproduct.productName}}
</div>
In controller,
$http({
method : 'POST',
url : '///',
headers : {'Content-Type': 'application/x-www-form-urlencoded'},
data:$.param({
userId:$localStorage.loginUserDet.LoginStatus.user.userId,
sessionId:$localStorage.loginUserDet.LoginStatus.sessionId,
authToken:$localStorage.loginUserDet.LoginStatus.user.authToken
})
})
.success(function(data)
{
alert("success");
$scope.showproducts= data;
console.log($scope.showproducts);
});
JSon, to view the check box list
{
"ProductList": {
"code": 0,
"products": [
{
"productId": 1,
"productName": "Credit Card",
"productStatus": 1
},
{
"productId": 2,
"productName": "Net Banking",
"productStatus": 1
},
{
"productId": 3,
"productName": "Saving Account",
"productStatus": 1
},
{
"productId": 4,
"productName": "Loan",
"productStatus": 1
},
{
"productId": 5,
"productName": "Insurance",
"productStatus": 1
},
{
"productId": 6,
"productName": "Certificate Of Deposit",
"productStatus": 1
},
{
"productId": 7,
"productName": "Prepaid Card",
"productStatus": 1
},
{
"productId": 8,
"productName": "Investment",
"productStatus": 1
},
{
"productId": 9,
"productName": "All Products",
"productStatus": 1
},
{
"productId": 10,
"productName": "Demo",
"productStatus": 1
},
{
"productId": 11,
"productName": "Remittance",
"productStatus": 1
}
],
"uploadStatus": 1
}
}
I need to toggle the ngclass when i click the check obx.
Can anyone please help on this.

So, you want to div behave like toggle, on click you the selectTog() will be called and adds ClassName because of $scope.mSlected varibale will become true in the same way it removes the class
<div id="1" ng-class="(mSelected ? 'ClassName': '')" ng-click="selectTog()">{{showproduct.productName}}</div>
now in controller
$scope.mSelected = false; // setting it false by default
$scope.selectTog = function(){
$scope.mSelected = !$scope.mSelected;
}
What if there is ng-repeat?
remove ng-class from <div> and add class in the function.
<div ng-repeat="x in [1,2,3,4]"
<div id="x" ng-click="selectTog($event)">{{x}}</div>
</div>
now in controller
$scope.selectTog = function(){
$event.target.addClass("ClassName");
}

Do like this:
<div id="1" ng-class="'mSelected': data" ng-click="toggle()">{{showproduct.productName}}</div>
controller:
$scope.data = true;
$scope.toggle = function() {
$scope.data = !$scope.data;
}
When ever you click the div it will toggle the class.
All the best.

In your html:
<div id="1" class="mSelected" ng-click="myFunc($event)">{{showproduct.productName}}
</div>
In your controller:
$scope.myFunc = function(event) {
$(event.target).toggleClass("your_css_class");
}

ng-class evaluates an expression like ng-class="productSaleTrue ? onSale : notOnSale"
<div ng-class="mSelected" ng-click="mSelected = !mSelected">
{{showproduct.productName}}
</div>
This would evaluate to true and add the css class onSale to the element with that ng-class, if the expression would evaluate to false, the other css class notOnSale would be added to the element, in your case the checkbox.
There is a lot of documentation and codepen examples that you can take from! Have a nice day! A link, just for the sake of knowledge: https://appendto.com/2016/03/ng-class-use-cases-action/
A practical example taken from treehouse:
<div ng-controller="mainCtrl" class="list">
<div class="item" ng-class="{'editing-item': editing, 'edited': todo.edited}" ng-repeat="todo in todos">
<input ng-model="todo.completed" type="checkbox"/>
<label ng-hide="editing" ng-click="helloWorld()">
{{todo.name}}</label>
<input ng-change="todo.edited = true" ng-blur="editing = false;" ng-show="editing" ng-model="todo.name" class="editing-label" type="text"/>
<div class="actions">
Edit
Save
delete
</div>
</div>
{{todos}}
</div>

Related

How to load different part of data from JSON file for each page using AngularJS?

I'm trying to create a shopping website using angularJs. My website has several html pages like women.html, men.html,...
I has 1 JSON file for the whole website. I want each website has different products, I did it but it only works on the main page (the page which showing all the products). When I click on a specific product, it doesn't show anything thing.
For more clearly, here is my code:
JSON file:
{
"Men": [
{
"name": "Adidas",
"price": 20,
"id": "adidas1",
"image": "pic4.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Nike",
"price": 37,
"id": "nike1",
"image": "pic2.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Converse",
"price": 25,
"id": "converse1",
"image": "pic3.png",
"description": "abcđsfadfdfsgsg"
}
],
"Women": [
{
"name": "Adidas2",
"price": 20,
"id": "adidas2",
"image": "pic6.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Nike2",
"price": 37,
"id": "nike2",
"image": "pic7.png",
"description": "abcđsfadfdfsgsg"
},
{
"name": "Converse2",
"price": 25,
"id": "converse2",
"image": "pic5.png",
"description": "abcđsfadfdfsgsg"
}
]
}
Men.html:
<div ng-repeat="item in items.Men" style="float:left;">
<div><a href="#/item/{{item.name}}"><img src="/image/{{item.image}}" />
</a>
</div>
</div>
Women.html:
<div ng-repeat="item in items.Women" style="float:left;">
<div>
<a href="#/item/{{item.name}}"><img src="/image/{{item.image}}" />
</a>
</div>
</div>
App.js:
app.controller('ItemCtrl',
['$scope', '$routeParams', 'cartService',
function ($scope, $routeParams, cartService) {
$scope.item = {};
angular.forEach($scope.items, function (item) {
if (item.name == $routeParams.itemName) {
$scope.item.itemName = item.name;
$scope.item.itemPrice = item.price;
$scope.item.itemId = item.id;
$scope.item.itemImage = item.image;
$scope.item.itemDescription = item.description;
}
});
$scope.addProduct = function (item) {
cartService.addToCart(item, $scope.numberOfProducts);
};
}
]);
Product details page:
<div style="float:left; margin:0px 50px 300px 50px;">
<img src="/image/{{item.itemImage}}" style="margin- bottom:50px;margin-
left:200px;">
<p style="margin-right:0px;margin-top:50px;margin-left:50px;">Description:
{{item.itemDescription}}</p>
</div>
The code is really long so I only show its parts which I think making my code doesn't work.
Hopefully, there would be some help. Thanks in advance!
Check whether 'ItemCtrl' controller is binded to both men.html and women.html, if both the html files are not views.
Make two controllers and use $http method to call each page.Then using scope,reference data that you want and render in each page

Angular 1.5 nested ng-repeat relation json

I just spent a couple hours to find solution for this issue, but couldn't find any similar problems.
The result should be that materials are linked with colors. I want to display materials and colors and ID of colors in value of ng-option.
View:
<div class="row clearfix">
<div class="col-md-8">
<md-input-container class="md-block">
<label>material</label>
<md-select name="material" ng-model="secondStep.material">
<md-optgroup label="material">
<md-option ng-value="materialsObjs.id" ng-repeat="materialsObjs in materialsObj track by $index">{{materialsObjs.name}}</md-option>
</md-optgroup>
</md-select>
</md-input-container>
</div>
</div>
<div class="row clearfix">
<div class="col-md-8">
<md-input-container class="md-block">
<label>colors</label>
<md-select name="colors" ng-model="secondStep.colors">
<md-optgroup label="colors">
<md-option ng-value="{{key}}" ng-repeat="(key , value) in colorsObj">{{value}}</md-option>
</md-optgroup>
</md-select>
</md-input-container>
</div>
</div>
JSON:
{
"status": "ok",
"printer_id": 113,
"materials": [{
"id": 1,
"name": "drewno",
"color": [{
"1": "green"
}]
}, {
"id": 2,
"name": "pla",
"color": [{
"3": "yellow"
}]
}]
}
Controller:
if(respondeObj.status == 'ok') {
$scope.materialsObj = respondeObj.materials;
$scope.colorsObj = [];
angular.forEach(respondeObj.materials, function(value , key) {
var putish = value.color[0];
this.push(putish);
}, $scope.colorsObj);
}
I just cant get separated color value for list and color ID to pass as selector value.
Current results is in the image: Image
Here is a working solution based on my comment.
EDIT - I forgot about the ng-optons attribute that allows you to use an object as the selected value for an option. By changing your first select to use ng-options, all you need to add is the keysFilter and use the code for the second dropdown in my HTML section to get the key/value from material.color
HTML
<select ng-model="currentMaterial"
ng-options="material as material.name for material in materialsObj"></select>
<select ng-if="currentMaterial">
<option ng-repeat="color in currentMaterial.color" value="{{id}}" ng-init="id = (color | keysFilter)">{{color[id]}}</option>
</select>
AngularJS Controller
var app = angular.module("myApp", [])
.filter("keysFilter", function () {
return (function (item){
if (!item) {
return [];
}
var keys = Object.keys(item);
return keys[0];
});
})
.controller("myCtrl", function ($scope){
$scope.currentMaterial = {};
$scope.materialsObj = [
{
"id": 1,
"name": "drewno",
"color": [
{
"1": "green"
},
{
"2": "yellow"
}
]
},
{
"id": 2,
"name": "pla",
"color": [
{
"3": "yellow"
},
{
"4": "purple"
},
{
"5": "brown"
}
]
}
];
});
If I understood correctly your problem is because after you construct $scope.colorsObj array you will have objects in it:
$scope.colorsObj = [
{"1": "green"},
{"3": "yellow"}
];
and then you would need to have another ng-repeat to achieve what you want, like:
<div ng-repeat="obj in colorsObj">
<div ng-repeat="(key, value) in obj">
{{key}} : {{value}}
</div>
</div>
Let me know if it helped. Thanks!

Fetching information from nested JSON based on unique fields using AngularJS

I have a json as following.
{
"id":14,
"discussion":8,
"parent":0,
"userid":2,
"subject":"communication skill discussion 2",
"message":"<p>hi all to communication discussion 2 </p>",
"children":[
24,
16,
15
]
},
{
"id":15,
"discussion":8,
"parent":14,
"userid":2,
"subject":"Re: communication skill discussion 2",
"message":"<p>hiiiiiiiiii</p>",
"children":[
25,
23
],
},
{
"id":23,
"discussion":8,
"parent":15,
"userid":2,
"created":1461562317,
"modified":1461562317,
"mailed":0,
"subject":"Re: communication skill discussion 2",
"message":"<p>helloooo</p>",
"children":[
],
}
I want first fetch the details whose Ids matches with the elments in children array
such as for id:14 there are 3 children 24,16,15.Then the control should go directly to id:15 and fetch details of id:15.Again id has children eg. consider id:23 which has no children and will directly print the message.
Please guide me how will I achieve this using ng-repeat of angular ?
Refer to the demo.
Please find the code below:
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
{{key + 1}}) --
<span ng-if="value.children.length > 0">
{{value.children}}
</span>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
</div>
</div>
JS:
var app = angular.module('app', []);
app.controller('test', function($scope) {
$scope.data = [{
"id": 14,
"discussion": 8,
"parent": 0,
"userid": 2,
"subject": "communication skill discussion 2",
"message": "<p>hi all to communication discussion 2 </p>",
"children": [
24,
16,
15
]
}, {
"id": 15,
"discussion": 8,
"parent": 14,
"userid": 2,
"subject": "Re: communication skill discussion 2",
"message": "<p>hiiiiiiiiii</p>",
"children": [
25,
23
],
}, {
"id": 23,
"discussion": 8,
"parent": 15,
"userid": 2,
"created": 1461562317,
"modified": 1461562317,
"mailed": 0,
"subject": "Re: communication skill discussion 2",
"message": "<p>helloooo</p>",
"children": [
],
}];
});
UPDATE: As per the request
Demo
HTML:
<div ng-app="app" ng-controller="test">
<div ng-repeat="(key,value) in data">
[{{key + 1}}] --
<div ng-if="value.children.length > 0">
<div ng-repeat="item in value.children">
<span>{{item}}</span> <span class="green" ng-bind-html="getMessage(item)"></span>
</div>
</div>
<span ng-if="!(value.children.length > 0)">
No children found!!
</span>
<br />
</div>
</div>
JS:
$scope.getMessage = function(itemId) {
var flag = true;
var msg;
angular.forEach($scope.data, function(value, key) {
if (flag && value.id == itemId) {
flag = false;
msg = value.message;
}
});
return $sce.trustAsHtml(msg);
}
CSS:
.green {
color: green;
}
Use ng-repeat to display the records.
<ul ng:controller="Cntl">
<li ng:repeat="item in data">
{{item.subject}}: Parent
<ul>
<li ng:repeat="child in item.children">{{child}} : Children
</li>
</ul>
</li>
This is one of the way to display in html. Based on your page design ng-repeat will change.
You can use lodash or underscore _.where:
<div ng:controller="Cntl">
<div ng:repeat="item in data">
{{item.subject}}<br/>
Children
<div ng:repeat="child in item.children">{{_.where(data, {id:child});}}
</div>
</div>
First you need to restructure your json into a tree structure. May be you want to have a look at this post. Then you have to recursively add templates

Angular ng-show select option child options

So if I have a selection like:
<div class="form-group">
<label for="beneSelect">Select your benefit</label>
<select class="form-control" id="beneSelect" >
<option ng-repeat="descr in claim.claimBenes"
data-ng-model="claimInfo.providerName">{{ descr.descr }}</option>
</select>
</div>
And below that, if the 'descr' has a sibling property that has data, to ng-show an selection option, how or what is the best way to do this?
So for instance, if the JSON data I am pulling has 9 different properties and in the initial select I am showing like:
"id": "%2fooTA9gmtHE8IJ13CdcAww%3d%3d",
"planTypeId": 1,
"benefitTypeId": 11,
"benefCode": "LHCFSA",
"descr": "Limited Health Care FSA (1/1/2015 - 12/31/2015)",
"askSecIns": false,
"askResidual": false,
"hasFunds": true,
"startDate": "2015-01-01T00:00:00",
"endDate": "2015-12-31T00:00:00",
"expenseTypes": [
{
"id": 56,
"descr": "General Dental Care"
},
{
"id": 52,
"descr": "General Vision Care"
},
{
"id": 57,
"descr": "Orthodontia"
},
{
"id": 58,
"descr": "Preventive Care"
}
],
If the expenseTypes "HAS" data, then another select would show, otherwise, just the one select would show. Actually, I would show a new <div> with HTML in it with another <select>.
Not sure the best way to tackle this in Angular. Suggestions with examples please?
Thanks much.
Can use the length of the expenseTypes array as a boolean
ng-if="claim.expenseTypes.length"
I guess You are looking for this....
maybe it will help you with some ideas....
(function() {
'use strict';
function InputController() {
var secondary = {
A: [1, 2, 3],
B: [3, 4, 5]
},
vm = this;
vm.primary = ['A', 'B'];
vm.selectedPrimary = vm.primary[0];
vm.onPrimaryChange = function() {
vm.secondary = secondary[vm.selectedPrimary];
};
}
angular.module('inputs', [])
.controller('InputCtrl', InputController);
}());
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.12/angular.min.js"></script>
<div class="container" ng-app="inputs" ng-controller="InputCtrl as ctrl">
<div class="row">
<div class="col-xs-6">
<h3>Primary</h3>
<select class="form-control" ng-model="ctrl.selectedPrimary" ng-options="item for item in ctrl.primary" ng-change="ctrl.onPrimaryChange()"></select>
</div>
<div class="col-xs-6">
<h3>Secondary</h3>
<select class="form-control" ng-model="ctrl.selectedSecondary" ng-options="item for item in ctrl.secondary"></select>
</div>
</div>
</div>

Dynamic index in ng-repeat value

I have a simple ng-repeat iterating through an array of objects.
The ng-repeat contains a ng-model input element for which I need to use a dynamic value as the array index. Probably very unclear explanation so here is the code :
<div ng-repeat="property in current_data.object_subtype.object_property_type" ng-init="set_input_state()" class="input-group ng-scope disabled">
<span class="input-group-addon">{{property.name}}</span>
<input type="text" placeholder="{{property.name}}" ng-model="current_data.properties[getIndexFromId(current_data.properties, property.object_property_type_id)].value" class="form-control" disabled="disabled">
The problem is that the input stays empty. I've tested some combinations and found this to work :
getIndexFromId(current_data.properties, property.object_property_type_id) == 0
current_data.properties[0].value gives the expected output
So somehow getIndexFromId(current_data.properties, property.object_property_type_id)is not well accepted by Angular or I made a stupid mistake somewhere ...
Does anyone know what's wrong with this?
Thanks!
[edit]
Here is a sample of the data behind all this :
{
"id": 1,
"name": "Robert Smith",
"object_subtype_id": 1,
"object_subtype": {
"id": 1,
"description": "Manager",
"object_property_type": [
{
"id": 1,
"description": "Phone number"
},
{
"id": 2,
"description": "Hair color"
},
{
"id": 3,
"description": "Nickname"
}
]
},
"properties": [
{
"id": 1,
"value": "819-583-4855",
"object_property_type_id": 1
},
{
"id": 2,
"value": "Mauves",
"object_property_type_id": 2
},
{
"id": 3,
"value": "Bob",
"object_property_type_id": 3
}
]
}
From what I've seen of Angular, the content of the attributes are not executed as javascript. It's a custom parsed and executed mini-language that doesn't support complex indexing.
With that said, its probably for the best. Any sufficiently complex logic should be handled by the controller or a service.
function MyController($scope) {
$scope.set_current_data_value = function (current_data, property) {
var index = $scope.getIndexFromId(current_data.properties, property.object_property_type_id);
current_data.properties[index].value = $scope.property_name;
}
}
Then your html would look something like:
<input type="text" placeholder="{{property.name}}" ng-model="property_name" ng-change="set_current_data_value(current_data, property)" class="form-control" disabled="disabled">
You may also be able to use ng-submit if you don't need to update your model in real time.

Categories

Resources