handlebar select box populate - javascript

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));

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.

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>

Angularjs and automatically generated SELECT tags

I have a bit of a problem, I have an API that provides me with products, and each product has multiple options, like so :
[
{
"name": "Product 1",
"options": [
{
"name": "Product 1 all options",
"price": 2000
}, {
"name": "Product 1 no option",
"price": 1400
}
]
}, {
"name": "Product 2",
"options": [
{
"name": "Product 2 all options",
"price": 3000
}, {
"name": "Product 2 no option",
"price": 1900
}
]
}];
Now I present it as so :
<tbody>
<tr ng-repeat="product in products">
<td>{{ product.name }}</td>
<td>
<select class="form-control">
<option
ng-repeat="option in product.options"
data-price="{{ option.price }}">{{ option.name }}</option>
</select>
</td>
<td>HERE I WANT TO DISPLAY THE SELECTED option.price +/- VAT</td>
</tr>
</tbody>
Now as you may notice, the <select> tag itself is inside a ng-repeat, so it can be infinitely repeated, depending on the number of products I have; I can't bind the select to any ng-model because I may accidentally bind many <select>'s to the same model.
Now for each <select>, I have to display the price +/- a VAT in the third <td>, that corresponds to the selected option. Is there any way of doing that with angularjs? I don't want to go plain JS/jQuery.
You can use the product variable as the model for the select. When the value changes it will also be updated outside the select as well.
An example would be:
app.controller('MainCtrl', function($scope) {
$scope.products = ['a', 'b', 'c', 'd'];
});
<body ng-controller="MainCtrl">
<div ng-repeat="product in products">
<input ng-model="product">
<div>{{product}}</div>
</div>
</body>
You can find a working plnkr here.
A working example using your data. It's making a new field in your product called selectedPrice just to store the selected option.
app.controller('MainCtrl', function($scope) {
$scope.products = [{
"name": "Product 1",
"options": [{
"name": "Product 1 all options",
"price": 2000
}, {
"name": "Product 1 no option",
"price": 1400
}]
}, {
"name": "Product 2",
"options": [{
"name": "Product 2 all options",
"price": 3000
}, {
"name": "Product 2 no option",
"price": 1900
}]
}];
});
<table>
<tbody>
<tr ng-repeat="product in products">
<td>{{ product.name }}</td>
<td>
<select class="form-control" ng-model="product.selectedPrice">
<option ng-repeat="option in product.options" value="{{ option.price }}">{{ option.name }}</option>
</select>
</td>
<td>{{product.selectedPrice}}</td>
</tr>
</tbody>
</table>
A working example of that can be found here.
Alternative to #toskv you can also avoid option tag altogether.
<tr ng-repeat="product in products">
<td>{{ product.name }}</td>
<td>
<select class="form-control" ng-model="product.selectedPrice" ng-options="option.price as option.name for option in product.options track by option.name">
</select>
</td>
<td>{{product.selectedPrice}}</td>
</tr>
see this

Angular ng-model not working inside ng-repeat

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>

Categories

Resources