Angular ng-model not working inside ng-repeat - javascript

Trying to bind Json data into ng-model inside ng-repeat it gives error.
html :
<div ng-controller="Ctrl">
<div>
<table>
<th>
<td>add</td>
<td>edit</td>
<td>delete</td>
</th>
<tr ng-repeat="category in categories">
<td>
<input id="add{{category.id}}" ng-model="add{{category.id}}" type="checkbox">{{category.name}}</td>
<td>
<input id="edit{{category.id}}" ng-model="edit{{category.id}}" type="checkbox">{{category.name}}</td>
<td>
<input id="del{{category.id}}" ng-model="del{{category.id}}" type="checkbox">{{category.name}}</td>
</tr>
</table>
</div>
</div>
Js :
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.selection = {
ids: {"50d5ad": true}
};
$scope.categories = [
{"name": "Sport", "id": "50d5ad" } ,
{"name": "General", "id": "687ffr" },
{"name": "Activities", "id": "678ffb" },
{"name": "Regards", "id": "678fff" },
{"name": "Thanks", "id": "678fer" },
{"name": "Goes", "id": "678fgf" },
{"name": "Oppertnities", "id": "674ffr" },
{"name": "Convince", "id": "654ffr" },
{"name": "Mopols", "id": "623ffr" }
];
}
Fiddle

You cannot write {{}} within ng-model like ng-model="del{{category.id}}". Use an array/object hash instead.
For example: ng-model="del[category.id]"

As Shay already mentioned you cannot use {{}} within ng-model this way. Here you have an example how you could implement it:
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.selection_add = {};
$scope.selection_edit = {};
$scope.selection_delete ={};
$scope.categories = [
{"name": "Sport", "id": "50d5ad" } ,
{"name": "General", "id": "687ffr" },
{"name": "Activities", "id": "678ffb" },
{"name": "Regards", "id": "678fff" },
{"name": "Thanks", "id": "678fer" },
{"name": "Goes", "id": "678fgf" },
{"name": "Oppertnities", "id": "674ffr" },
{"name": "Convince", "id": "654ffr" },
{"name": "Mopols", "id": "623ffr" }
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Ctrl">
<div>
<table>
<tr>
<th>add</th>
<th>edit</th>
<th>delete</th>
</tr>
<tr ng-repeat="category in categories">
<td><input id="{{category.id + '_add'}}" ng-model="selection_add[category.id]" type="checkbox">{{category.name}}</td>
<td><input id="{{category.id + '_edit'}}" ng-model="selection_edit[category.id]" type="checkbox">{{category.name}}</td>
<td><input id="{{category.id + '_delete'}}" ng-model="selection_delete[category.id]" type="checkbox">{{category.name}}</td>
</tr>
</table>
<h1>Add</h1>
{{selection_add}}
<h1>Edit</h1>
{{selection_edit}}
<h1>Delete</h1>
{{selection_delete}}
</div>
</div>
</div>
If you want to store the information inside the original array you could implement it this way:
var app = angular.module('app', []);
function Ctrl($scope) {
$scope.categories = [
{"name": "Sport", "id": "50d5ad" } ,
{"name": "General", "id": "687ffr" },
{"name": "Activities", "id": "678ffb" },
{"name": "Regards", "id": "678fff" },
{"name": "Thanks", "id": "678fer" },
{"name": "Goes", "id": "678fgf" },
{"name": "Oppertnities", "id": "674ffr" },
{"name": "Convince", "id": "654ffr" },
{"name": "Mopols", "id": "623ffr" }
];
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Ctrl">
<div>
<table>
<tr>
<th>add</th>
<th>edit</th>
<th>delete</th>
</tr>
<tr ng-repeat="category in categories">
<td><input id="{{category.id + '_add'}}" ng-model="category.add" type="checkbox">{{category.name}}</td>
<td><input id="{{category.id + '_edit'}}" ng-model="category.edit" type="checkbox">{{category.name}}</td>
<td><input id="{{category.id + '_delete'}}" ng-model="category.delete" type="checkbox">{{category.name}}</td>
</tr>
</table>
{{categories}}
</div>
</div>
</div>

Instead of add{{category.id}} use add[category.id] and so on, define add, edit and del as scope variables in controller.
<tr ng-repeat="category in categories">
<td><input id="add[category.id]" ng-model="add[category.id]" type="checkbox">{{category.name}}</td>
<td><input id="edit[category.id]" ng-model="edit[category.id]" type="checkbox">{{category.name}}</td>
<td><input id="del[category.id]" ng-model="del[category.id]" type="checkbox">{{category.name}}</td>
</tr>

Related

how can i fetch data json from api to Web app page html

I want to fetch all Jason data into a table
How can i do that?
i write code javascript to get json data from my api, but i can't fetch all data like "category" "name" "value" to table in page html !!
api json :
[
{ "allinfo":[
{
"category": "category1",
"info": [{
"name": "Tech1",
"value": "1575"
},
{
"name": "tech2",
"value": "a-25"
}
]
},
{
"category": "category2",
"info": [{
"name": "Announced",
"value": "2022"
},
{
"name": "Status",
"value": "Coming soon"
}
]
},
{
"category": "category3",
"info": [{
"name": "with",
"value": "163.3 cm"
},
{
"name": "Weight",
"value": "500 g"
}
]
}]
}]
code javascript :
$.getJSON('https://myapi', function(data) {
console.log(data);
$.each(data, function(index, value) {
console.log(value);
var category = value.allinfo.category;
var name = value.allinfo.info.name;
var value = value.allinfo.info.value;
$('.output').append('<div class="cont"><h3>' + category + '</h3><table><tbody><tr><td>'+ name +'</td><td>' + value + '</td></tr></tbody></table></div>');});});
html :
<div class="output"></div>
output html:
<div class="cont">
<h3>undefined</h3>
<table>
<tbody>
<tr>
<td>undefined</td>
<td>undefined</td>
</tr>
<tr>
<td>undefined</td>
<td>undefined</td>
</tr>
</tbody>
</table>
</div>
i want to be like this :
<div class="cont">
<h3>category1</h3>
<table>
<tbody>
<tr>
<td>Tech1</td>
<td>1575</td>
</tr>
<tr>
<td>tech2</td>
<td>a-25</td>
</tr>
</tbody>
</table>
</div>
<div class="cont">
<h3>category2</h3>
<table>
<tbody>
<tr>
<td>Announced</td>
<td>2022</td>
</tr>
<tr>
<td>Status</td>
<td>Coming soon</td>
</tr>
</tbody>
</table>
</div>
<div class="cont">
<h3>category3</h3>
<table>
<tbody>
<tr>
<td>with</td>
<td>163.3 cm</td>
</tr>
<tr>
<td>Weight</td>
<td>500 g</td>
</tr>
</tbody>
</table>
</div>
How can i do that?
I appreciate your help
Here is a short way of doing the whole thing in one expression:
const da=[{ "allinfo":[
{"category": "category1",
"info":[{"name":"Tech1","value":"1575"},
{"name":"tech2","value": "a-25"}]},
{"category": "category2",
"info":[{"name": "Announced","value": "2022"},
{"name": "Status","value": "Coming soon"}]},
{"category": "category3",
"info":[{"name": "with","value": "163.3 cm"},
{"name": "Weight","value": "500 g"}]}
]}];
document.querySelector("div.cont").innerHTML=da[0].allinfo.map(cat=>
`<h1>${cat.category}</h1>
<table><tbody>${cat.info.map(r=>
`<tr><td>${r.name}</td><td>${r.value}</td></tr>`).join("")}
</tbody></table>`).join("\n")
td {border:1px solid grey; width:100px}
table{border-collapse:collapse}
<div class="cont"></div>
There are two (nested) .map()s looping over
da[0].categories for all tables using cat for each category and
cat.info for all records r in one category
The output of each map() is .join()-ed and the resulting string is assigned to the first encountered div.cont's .innerHTML.
You can access your Obj properties like this:
To get category:
var cat = value[0].allinfo[1].category
console.log(cat) //category2
To get info:
var name = value[0].allinfo[1].info[0].name
console.log(name) //announced
Pay attention: to your variable names, it appears that you name all variables as "name"!

How to generate nested Json object from inputs?

I need to generate following Json Object daynamically from inputs
{
"name":"USA",
"parents": [
{
"state":"California",
"id":"12",
"child":[
{
"city":"Los Angeles",
"id":"1"
},
{
"city":"San Francisco",
"id":"2"
}
]
},
{
"state":"Texas",
"id":"33",
"child":[
{
"city":"Dallas",
"id":"3"
},
{
"city":"Houston",
"id":"4"
}
]
}
]
}
from this Table of inputs
<table id="tTypeTable" class="table table-bordered" hidden="hidden" >
<tr>
<th><a class="btn btn-primary" onclick="add_tTypeParentField();"></th>
</tr>
<!-- ko foreach: {data: tTypeParentFields, as: 'tParentField'} -->
<tr>
<td>
<table class="table table-hover" >
<tr>
<th> State </th>
<th> </th>
</tr>
<tr title="tParentRow" >
<td>
<input id="state" data-bind="value: tParentField[0]"
onblur="createJSON()"/>
</td>
<td>
<input id="value" data-bind="value: tParentField[0]"
onblur="createJSON()"/>
</td>
</tr>
</table>
<table id="tChild" class="table table-hover" >
<tr>
<th> City </th>
<th> </th>
<th> <a id="childAdd" onclick="addChild(this);"></th>
</tr>
<tbody>
<tr title="tChildRow" id="tChildRow">
<td>
<input id="cityName" onblur="createJSON()"/>
</td>
<td>
<input id="cityValue" " onblur="createJSON()"/>
</td>
<td>
<a id="removeChild" onclick="deleteChild(this)" ></a>
</td>
</tr>
</tbody>
</table>
<td> <a data-bind="click: removeTTypeParentField" ></a></td>
</td>
</tr>
<!-- /ko -->
</table>
<div class="col-md-11 ">
<textarea class="form-control" id="requestData" ></textarea>
</div>
there is no problem with adding new row of inputs. I have used Knockouts for addding Parent table and used jQuery for adding child table. it's working well.
The problem is that generating Json child Object (cities).
I have tried to get value of inputs and generate Json Object in textare like this
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script th:inline="javascript">
function createJSON() {
var jsonObj = [];
$(document).ready(function() {
var valueTypeTChild = [];
var valueTypeTParent = [];
$("tr[id=tParentRow]").each(function() {
$(this).find('tr[id=tChildRow]').each(function () {
child = {
city: $(this).find('#cityName').val(),
id: $(this).find('#cityValue').val()
};
valueTypeTChild.push(child);
});
parent = {
city:$(this).find('#state').val(),
id:$(this).find('#value').val(),
child: valueTypeTChild
};
valueTypeTParent.push(parent);
);
inputItem = {
"name":"Country",
parents: valueTypeTParent
};
jsonObj.push(inputItem);
});
$('#requestData').val(JSON.stringify(jsonObj));
console.log(JSON.stringify(jsonObj));
</script>
But I'm getting this
{
"name": "USA",
"parents": [
{
"state": "California",
"id": "12",
"child": [
{
"city": "Los Angeles",
"id": "1"
},
{
"city": "San Francisco",
"id": "2"
},
{
"city": "Dallas",
"id": "3"
},
{
"city": "Houston",
"id": "4"
}
]
},
{
"state": "Texas",
"id": "33",
"child": [
{
"city": "Los Angeles",
"id": "1"
},
{
"city": "San Francisco",
"id": "2"
},
{
"city": "Dallas",
"id": "3"
},
{
"city": "Houston",
"id": "4"
}
]
}
]
}
You are giving every state the same city array without clearing it.
Move var valueTypeTChild = []; inside the $("tr[id=tParentRow]").each(function() { loop.

Angular customer directive with filter and sort

I need to sort the json object with one of the userType thru ng-repeat. Now i was able to retrieve and display the data, and ISSUE is that I need to sort and display two different table the below list; One is for MARRIED and another for SINGLE.
How can i sort married/single when i use ng-repeat, and need to show in TWO tables. Any suggestions/help will be appreciated....
.controller('userInfo', ['$scope', 'userService', function ($scope, userService) {
userService.getuserList().then(function (users) {
users = {
"personalInfo": {
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Married",
"percentage": "50"
},"personalInfo": {
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Single",
"percentage": "50"
},
"personalInfo": {
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Married",
"percentage": "50"
}}
$scope.users = users;
});
}])
.directive('userDetails', function () {
return {
restrict: 'E',
scope: {
users: '='
},
controller: function ($scope) {
$scope.showEdit = function () {
$scope.isEdit = true;
}
},
template: `<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Relation</th>
<th>Percentage</th>
<th></th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="user in users">
<td>{{user.personalInfo.firstName}} {{user.personalInfo.lastName}}</td>
<td>{{user.userRelations.relationshipType}}</td>
<td><span ng-if="!isEdit">{{user.personalInfo.percent}}</span><input type="text"
ng-if="isEdit" ng-model="user.personalInfo.percent" class="form-control"></td>
<td><a ng-click="showEdit()" href="#">Update</a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="2">Total Percentage</td>
<td>100%</td>
<td><a ng-if="!isEdit" ng-click="showEdit()" href="#">Update</a><a ng-if="isEdit" ng-click="showEdit()" href="#">Save Percentage</a></td>
</tr>
</tfoot>
</table>
</div>`
};
})
<div class="container">
<div class="row">
<div class="col-md-9">
<h1>Update User Information</h1>
<div data-ng-controller="user">
<div data-ng-controller="userInfo">
<user-details user="users"></user-details>
</div>
</div>
</div>
</div>
</div>
users in your answer is not a valid object as it has "personalInfo" as key multiple times. You should instead create an array of objects like :
users = [{
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Married",
"percentage": "50"
},{
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Single",
"percentage": "50"
},{
"firstName": "Richardoo",
"lastName": "Gil",
"maritalStatus": "Married",
"percentage": "50"
}];
For creating two tables, for married and single,
HTML
<div class="row">
<div class="col-md-9">
<h1>Update User Information</h1>
<div data-ng-controller="user">
<div data-ng-controller="userInfo">
<user-details user="users" userfilter="single"></user-details>
<user-details user="users" userfilter="married"></user-details>
</div>
</div>
</div>
</div>
Change in userDetails directive template function
<tbody>
<tr data-ng-repeat="user in users | filter:{maritalStatus:$attrs.userfilter}">
<td>{{user.personalInfo.firstName}} {{user.personalInfo.lastName}}</td>
<td>{{user.userRelations.relationshipType}}</td>
<td><span ng-if="!isEdit">{{user.personalInfo.percent}}</span><input type="text"
ng-if="isEdit" ng-model="user.personalInfo.percent" class="form-control"></td>
<td><a ng-click="showEdit()" href="#">Update</a></td>
</tr>
</tbody>
<tr data-ng-repeat="user in users | filter:{maritalStatus:userfilter}"></tr>
$scope.sortType = 'x.user'

handlebar select box populate

my HTML code,
I want each user role is selected next to the select box of each user name,
inside the each loop of role i cant able to access the role of parent user node,
is it possible to compare the role id of user node with roles node roleid and when its equal, the option will be selected
<table>
<tr>
<p>peter is employee</p>
<p>john is admin</p>
<p>michel is manager</p>
</tr>
{{#user}}
<tr>
<td>
<input type="text" value="{{name}}">
</td>
<td>
<select>
{{#each ../roles}}
<option value="{{roleid}}">{{value}}</option>
{{/each}}
</select>
</td>
</tr>
{{/user}}
This is may Json
var data = {
"user": [
{ "name": "peter", "role": 1 },
{ "name": "john", "role": 2 },
{ "name": "michel", "role": 3 }
],
"roles": [
{ "roleid": 1, "value":"manager"},
{ "roleid": 2, "value":"employee"},
{ "roleid": 3, "value":"admin"}
]
};
fiddle url https://jsfiddle.net/Manu_S/egbwbfav/2/
thanks
You can access the parent node values and compare in your select box.
Please follow the Jsfiddle working that
https://jsfiddle.net/gsubbarao/nz0bc0pq/
<script id="t" type="text/x-handlebars">
<table>
<tr>
<p>peter is employee</p>
<p>john is admin</p>
<p>michel is manager</p>
</tr>
<tr>
<td> </td><td></td><td></td>
</tr>
{{#user}}
<tr>
<td>
<input type="text" value="{{name}}">
</td>
<td>
<select>
{{#each ../roles}}
<option value="{{roleid}}"
{{#ifCond ../role roleid}}
selected
{{/ifCond}}
>
{{value}}
</option>
{{/each}}
</select>
</td>
</tr>
{{/user}}
</script>
var data = {
"user": [
{ "name": "peter", "role": 2 },
{ "name": "john", "role": 3 },
{ "name": "michel", "role": 1 }
],
"roles": [
{ "roleid": 1, "value":"manager"},
{ "roleid": 2, "value":"employee"},
{ "roleid": 3, "value":"admin"}
]
};
Handlebars.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
var t = Handlebars.compile($('#t').html());
$('body').append(t(data));

Binding object to checkbox value in Vuejs

So normal checkboxes in vuejs allows you to bind a model to it.
When this model has the values from checkboxes pre filled, those particular checkboxes appear checked.
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="selectedUsers" v-bind:value="{ id: user.id }">
</td>
<td>
<input type="checkbox" v-model="selectedUsers" value="{{ user.id }}">
</td>
</tr>
However you don't get the same behaviour when you bind the checkbox value to an object.
Following is the snippet:
new Vue({
el: '#app',
data: {
users: [{
"id": "1",
"name": "Shad Jast",
"email": "pfeffer.matt#yahoo.com"
}, {
"id": "2",
"name": "Duane Metz",
"email": "mohammad.ferry#yahoo.com"
}, {
"id": "3",
"name": "Myah Kris",
"email": "evolkman#hotmail.com"
}, {
"id": "4",
"name": "Dr. Kamron Wunsch",
"email": "lenora95#leannon.com"
}, {
"id": "5",
"name": "Brendon Rogahn",
"email": "verlie.buckridge#yahoo.com"
}],
selectedUsers: [{
"id": "1"
}, "1"]
}
})
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th></th>
<th></th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="selectedUsers" v-bind:value="{ id: user.id }">
</td>
<td>
<input type="checkbox" v-model="selectedUsers" value="{{ user.id }}">
</td>
</tr>
</table>
</div>
<span>Selected Ids: {{ selectedUsers | json }}</span>
</div>
I have done it the following way, please suggest better ways, if any:
new Vue({
el: '#app',
data: {
users: [{
"id": "1",
"name": "Shad Jast",
"email": "pfeffer.matt#yahoo.com"
}, {
"id": "2",
"name": "Duane Metz",
"email": "mohammad.ferry#yahoo.com"
}, {
"id": "3",
"name": "Myah Kris",
"email": "evolkman#hotmail.com"
}, {
"id": "4",
"name": "Dr. Kamron Wunsch",
"email": "lenora95#leannon.com"
}, {
"id": "5",
"name": "Brendon Rogahn",
"email": "verlie.buckridge#yahoo.com"
}],
previousUsers: [{
"id": "2"
}, {
"id": "5"
}, "1", "5"],
updatedUsers: []
},
methods: {
check: function(user_id) {
var checked = false;
for (i = 0; i < this.previousUsers.length; i++) {
if (this.previousUsers[i].id == user_id) {
this.previousUsers.splice(i, 1)
return true
}
return false;
}
}
}
})
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<div id="app">
<h4>User</h4>
<div>
<table>
<tr>
<th>Name</th>
<th></th>
<th></th>
</tr>
<tr v-for="user in users">
<td>{{ user.name }}</td>
<td>
<input type="checkbox" v-model="updatedUsers" v-bind:value="{ id: user.id }" checked="{{check(user.id)}}">
</td>
<td>
<input type="checkbox" v-model="updatedUsers" value="{{ user.id }}">
</td>
</tr>
</table>
</div>
<span>Selected Ids: {{ updatedUsers | json }}</span>
</div>

Categories

Resources