I have a JSON file which contains data like the following:
{"posts": [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
]}
I need to filter title by range with two text boxes: from and to.
Why not do this?
var json = JSON.parse('{"posts": [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
]}');
var filteredJson = json.posts.filter(function (row) {
if(row.title matches your criteria) {
return true
} else {
return false;
}
});
Yes, its an ES5 method but that can be shimmed quite nicely
I use Linq JS on my current project and it works really well for filtering data.
http://jslinq.codeplex.com/
var posts = [
{ "title":"1", "url":"n1.png" },
{ "title":"2", "url":"n2.png" },
{ "title":"3", "url":"n3.png" },
{ "title":"4", "url":"n4.png" },
{ "title":"5", "url":"n5.png" },
{ "title":"6", "url":"n6.png" },
{ "title":"7", "url":"n7.png" },
{ "title":"8", "url":"n8.png" },
{ "title":"9", "url":"n9.png" },
{ "title":"10", "url":"n10.png" }
];
var filteredPost = JSLINQ(posts)
.Where(function(item){ return item.title >= "textBox1Value" && item.title <= "textBox2Value"; });
There is another solution to this: using jLinq.js (documentation), which has even more features. In this case, you can get the solution by using the following code:
var selectedPosts = jLinq.from(posts)
.betweenEquals("title",4,8)
.select();
try this
var q = new RegExp(req.query.q,'i');
posts = posts.filter(function(item){
if(item.title.match(q) || item.url.match(q)){
return item;
}
});
Read the json into an object/arr the parseJson function of jquery(http://api.jquery.com/jQuery.parseJSON/) and the try to splice the array using the splice function() Just make a copy of the object and splice that one.
Well i have this JSON array full of projects, each of project belong to a product:
[
{
"id": 1,
"parentProduct": {
"id": 12,
"productName": "Test 123"
},
"phase": "Phase 4",
"productNumber": "111223",
"projectName": "Test JPEG Apple",
"supplier1": "de",
},
{
"id": 2,
"parentProduct": {
"id": 12,
"productName": "Test from me"
},
"phase": "222",
"productNumber": "11122",
"projectName": "Test PNG",
"supplier1": "222"
}
]
I wanted to get only those with specific parent id, and i did it as below:
filterByProductId(projects, productId) : any[] {
var filteredArray = new Array;
for(var k in projects) {
if(projects[k].parentProduct.id == productId) {
filteredArray.push(projects[k]);
}
}
return filteredArray;
}
json data array of objects filter
<html>
<head>
<script type="text/javascript">
/*
var ss = JOSN.stringify(obj,function(key,value){ //serialization
if(key=='a'){
return undefined;
}else{
return value;
}
});
*/
var jsonStr = [
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Bang Bang",
"outline": "A chance encounter with a mysterious charmer leads to a bank employee's wild adventure.",
"rating": 5.6,
"director": "Siddharth Anand",
"id": 250
},
{
"name": "Indian",
"outline": "After his daughter's tragic death, a freedom fighter steps up his war against corruption.",
"rating": 8.4,
"director": "Shankar",
"id": 251
},
{
"name": "Dilwale Dulhania Le Jayenge",
"outline": "Raj and Simran meet on a trip to Europe. After some initial misadventures, they fall in love. The battle begins to win over two traditional families.",
"rating": 8.4,
"director": "Aditya Chopra",
"id": 253
}
];
var jsonobj = jsonStr;
function filterMovieDirectorData(movie,director){
if(movie!='' && (director!='' && director!='Director')){
var data = jsonobj.filter(function(item){
return (item["name"].toLowerCase().indexOf(movie.toLowerCase())!=-1 && item["director"].toLowerCase().indexOf(director.toLowerCase())!=-1)
});
}else if(movie!='' && director=='Director'){
var data = jsonobj.filter(function(item){
return item["name"].toLowerCase().indexOf(movie.toLowerCase())!=-1
});
}else if(movie=='' && (director!='' && director!='Director')){
var data = jsonobj.filter(function(item){
return item["director"].toLowerCase().indexOf(director.toLowerCase())!=-1
});
}
return data;
}
function getFilterDirectorJson(){
var inputStr = document.getElementById("movie").value;
var e = document.getElementById("director");
var directorStr = e.options[e.selectedIndex].text;
if( (inputStr=='' || inputStr=='Enter movie name') && (directorStr=='' || directorStr=='Director') ){
alert("Please enter movie name or select director.");
document.getElementById("filter_data_div").innerHTML="";
document.getElementById("movie").focus();
return false;
}
var filterObjs = filterMovieDirectorData(inputStr,directorStr);
var text="";
for(var i=0; i<filterObjs.length; i++){
text+='<div id="filter_data"><div><h3>'+filterObjs[0].name+'</h3></div>';
text+='<div>Director : '+filterObjs[0].director+'</div></div><div class="clear"></div>';
}
if(filterObjs.length===0){document.getElementById("filter_data_div").innerHTML='<div id="filter_data"><div><h3>No movies found.</h3></div></div>';}else
document.getElementById("filter_data_div").innerHTML=text;
}
window.onload=function(){
getDirectors();
}
function getDirectors(){
for(var i=0; i<jsonobj.length; i++){
//console.log(jsonobj[i].director);
var option = document.createElement("option");
option.text = jsonobj[i].director;
option.value = i;
var daySelect = document.getElementById('director');
daySelect.appendChild(option);
}
}
</script>
<style>
#director{
line-height: 3px;
padding: 20px;
font-size: 21px;
color: #acacac;
}
#go{
background: #FFC000;
padding: 11px 14px 16px 11px;
font-size: 36px;
line-height: 3;
color: #fff;
margin: 0px;
text-align: center;
}
#movie{
width: 213px;
font-size: 21px;
margin-left: 12px;
padding: 20px;
color:#ACACAC;
}
#main_div{
background: #EEEEEE;
width: 554px;
min-height:120px;
}
#filter_data{
width: 335px;
background: #D8D8D8;
padding: 1px 0px 20px 13px;
margin: 20px 0px 0px 12px;
border: 1px solid #000;
}
a{text-decoration:none;}
.clear{clear: both;}
</style>
</head>
<body>
<div id="main_div">
<div style="display:block;">
<input type="text" id="movie" placeholder="Enter movie name">
<select id="director" ><option value="">Director</option></select>
Go
</div>
<div id="filter_data_div"></div>
</div>
</body>
</html>
First once you have all the json data, you need to traverse them. For that,
**$.each(data, function (i, data) {
if (data.title >= "textBox1Value" && item.title <= "textBox2Value")
//then the data;
});**
List item
Related
I have nested checkboxes with a tree hierarchy level. It contains also both indeterminate and checked status for each level. Basically, I need to store each checked / indeterminate value of the checkbox in an array with the correct level. Unfortunately, I'm not able to include indeterminate values with the current solution. Is there any way we can search for two elements (input:checked,input:indeterminate) at the same time?
function toggleCheckboxArea(onlyHide = false) {
var checkboxes = document.getElementById("SelectOptions");
var displayValue = checkboxes.style.display;
if (displayValue != "block") {
if (onlyHide == false) {
checkboxes.style.display = "block";
}
} else {
checkboxes.style.display = "none";
}
}
let data = {
"Tall Things": {
"label": "Tall Things",
"children": {
"Buildings": {
"label": "Buildings",
},
"Two sandwiches": {
"label": "Two sandwiches",
},
"Giants": {
"label": "Giants",
"children": {
"Andre": {
"label": "Andre",
},
"Paul Bunyan": {
"label": "Paul Bunyan",
}
}
}
}
},
"Tall' Things 2": {
"label": "Tall' Things 2",
"children": {
"Buildings 2": {
"label": "Buildings 2",
},
"Two sandwiches 2": {
"label": "Two sandwiches 2",
},
"Giants 2": {
"label": "Giants 2",
"children": {
"Andre 2": {
"label": "Andre 2",
},
"Paul Bunyan 2": {
"label": "Paul Bunyan 2",
}
}
}
}
}
}
let nodeLevel = 1;
function addItem(parentUL, branch, parentName) {
for (var key in branch) {
var item = branch[key].children;
let name = '';
if (parentName) {
name = parentName }
$item = $('<li>', {
id: key,
});
$item.append($('<input>', {
type: "checkbox",
id: 'smb',
name: key,
value: key,
"data-parent": name,
}));
$item.append($('<label>', {
for: key,
text: key
}));
parentUL.append($item);
nodeLevel++;
if (branch[key].children) {
var $ul = $('<ul>', {
class: 'ul-child',
style: 'display: none'
}).appendTo($item);
addItem($ul, item, branch[key].label);
} else {
nodeLevel = 1;
}
}
}
// On default load
$(document).ready(function(){
addItem($('#sb'), data);
$('input[type="checkbox"]').prop("checked", "true");
$('label').click(function(){
$(this).closest('li').children('ul').slideToggle();
});
$('input[type="checkbox"]').change(function(e) {
var checked = $(this).prop("checked"),
container = $(this).parent(),
siblings = container.siblings();
container.find('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
function checkSiblings(el) {
var parent = el.parent().parent(),
all = true;
el.siblings().each(function() {
let returnValue = all = ($(this).children('input[type="checkbox"]').prop("checked") === checked);
return returnValue;
});
if (all && checked) {
parent.children('input[type="checkbox"]').prop({
indeterminate: false,
checked: checked
});
checkSiblings(parent);
} else if (all && !checked) {
parent.children('input[type="checkbox"]').prop("checked", checked);
parent.children('input[type="checkbox"]').prop("indeterminate", (parent.find('input[type="checkbox"]:checked').length > 0));
checkSiblings(parent);
} else {
el.parents("li").children('input[type="checkbox"]').prop({
indeterminate: true,
checked: false
});
}
}
checkSiblings(container);
});
});
$(".save").click(function() {
var sbl1 = $('#sb li input:checked').not('#sb li ul li input:checked').not('#sb li ul li ul li input:checked').map(
function(x){
return $(this).val().replace(/(["'])/g, "\\$1");
}).get().join('\',\'');
console.log(sbl1)
});
.no-bullets {
list-style: none;
padding: 0;
margin: 0;
}
.ul-child {
list-style: none;
margin: 0 0 0 5px;
}
.selectBox {
position: relative;
}
.overSelect {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
}
#SelectOptions {
display: none;
border: 0.5px #7c7c7c solid;
background-color: #ffffff;
max-height: 300px;
overflow-y: scroll;
text-align: left;
}
#SelectOptions label:hover {
background-color: #1e90ff;
}
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="./style.css">
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap#5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
</head>
<body>
<div class="form-group col-sm-8">
<div class="selectBox" onclick="toggleCheckboxArea()">
<select class="form-select">
<option></option>
</select>
<div class="overSelect"></div>
</div>
<div id="SelectOptions">
<ul class="no-bullets">
<li id="All">
<input type="checkbox" name="selectAll" id="selectAll">
<label>All</label>
<ul class="ul-child" style="display:none;" id="sb">
</ul>
</li>
</ul>
</div>
</div>
<button class="save">Save</button>
<p id="demo"></p>
<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="./script.js"></script>
</body>
Hey all I am using KendoListBox and needing to loop through it and remove the selected [checked] items once I un-check the full category.
let apiData = {
"object_list": [{
"Name": "facebook",
"Description": null,
"Id": "eb8cb0c8c32d1201bff30cf54S4f30889abb23f92b1f7",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Social Networks"
}, {
"Name": "twitter",
"Description": null,
"Id": "732fe66cce4365bc5074384f09b34e787f3f3efe8b55",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Social Networks"
}, {
"Name": "Google",
"Description": null,
"Id": "8b11d6f7b74bf71a7ddbc62dcfead27087e0f3e047e",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Search Engines"
}]
};
$("#treeview").kendoTreeView({
checkboxes: {
checkChildren: true
},
check: onCheck,
dataSource: {
data: apiData,
schema: {
model: {
children: 'items'
},
parse: (data) => {
// The new data array to be used by treeview
let newData = [];
data.object_list.forEach(item => {
// Look for an already created parent for that categoty
let parent = newData.find(parentItem => parentItem.text === item.Cat);
// If not found...
if (!parent) {
// ... create a new one...
parent = {
id: 2,
text: item.Cat,
expanded: true,
items: [],
spriteCssClass: "folder"
};
// ... and add it to the final data array.
newData.push(parent);
}
// Add the new item to the parent
parent.items.push({
id: 3,
text: item.Name,
spriteCssClass: "image"
});
});
// Return the root object with its new child items
return [{
id: 1,
text: 'Categories',
expanded: true,
spriteCssClass: "rootfolder",
items: newData
}];
}
}
}
});
$("#Sources").kendoListBox();
function onCheck(e) {
let checkedNodes = [],
checkedNode = e.node.innerText,
intx = 0,
listBox = $("#Sources").data("kendoListBox");
//console.log(e.node.innerText);
if (e.node.ariaChecked == "false") {
console.log("Its just now been selected *REMOVED*");
var node = listBox.dataSource.get("twitter");
//let listBoxItem = listBox.dataItems().find(item => item.text === e.node.innerText);
let listBoxItem = listBox.dataItems().find(item => "twitter" === "twitter");
console.log("listbox item: ", listBoxItem);
var text = e.node.innerText;
var textSpliced = text.split("\n").slice(1);
if (textSpliced.length >= 1) {
$.each(textSpliced, function(tS) {
console.log("splice: ", textSpliced[tS]);
listBox.dataSource.remove(textSpliced[tS]);
});
} else {
/*
$("#Sources option").each(function(i){
alert($(this).text() + " : " + $(this).val());*/
//if (listBoxItem) {
//console.log("list: ", listBoxItem);
//listBox.dataSource.remove(listBoxItem);
//}
//}
// });
}
} else {
console.log("Its just now been selected *ADDED*");
listBox = $("#Sources").data("kendoListBox");
var text = e.node.innerText;
var textSpliced = text.split("\n").slice(1);
if (textSpliced.length >= 1) {
$.each(textSpliced, function(tS) {
console.log(textSpliced[tS]);
listBox.add({
text: textSpliced[tS],
value: textSpliced[tS]
});
});
} else {
listBox.add({
text: checkedNode,
value: checkedNode
});
}
}
}
#treeview .k-sprite {
background-image: url("../content/web/treeview/coloricons-sprite.png");
}
.rootfolder {
background-position: 0 0;
}
.folder {
background-position: 0 -16px;
}
.pdf {
background-position: 0 -32px;
}
.html {
background-position: 0 -48px;
}
.image {
background-position: 0 -64px;
}
#filterText {
width: 100%;
box-sizing: border-box;
padding: 6px;
border-radius: 3px;
border: 1px solid #d9d9d9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.common.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.rtl.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.mobile.all.min.css">
<script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/angular.min.js"></script>
<script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/jszip.min.js"></script>
<script type="text/javascript" src="http://cdn.kendostatic.com/2021.1.330/js/kendo.all.min.js"></script>
<div id="treeview"></div>
<select id="Sources"></select>
I can do this
listBox.dataItems().find(item => item.text === e.node.innerText)
And be able to delete any 1 checked item. But if its more than 1 I am unable to figure out what I am missing.
So I tried doing this:
var text = e.node.innerText;
var textSpliced = text.split("\n").slice(1);
if (textSpliced.length >= 1) {
$.each(textSpliced, function(tS) {
console.log("splice: ", textSpliced[tS]);
listBox.dataSource.remove(textSpliced[tS]);
});
} else {}
But of course that did not produce any results - did not delete the items in the kendoListBox.
Try this new approach:
let apiData = {
"object_list": [{
"Name": "facebook",
"Description": null,
"Id": "eb8cb0c8c32d1201bff30cf54S4f30889abb23f92b1f7",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Social Networks"
}, {
"Name": "twitter",
"Description": null,
"Id": "732fe66cce4365bc5074384f09b34e787f3f3efe8b55",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Social Networks"
}, {
"Name": "Google",
"Description": null,
"Id": "8b11d6f7b74bf71a7ddbc62dcfead27087e0f3e047e",
"DocumentType": null,
"ProviderId": 2,
"Cat": "Search Engines"
}]
};
$("#treeview").kendoTreeView({
checkboxes: {
checkChildren: true
},
check: onCheck,
dataSource: {
data: apiData,
schema: {
model: {
children: 'items'
},
parse: (data) => {
// The new data array to be used by treeview
let newData = [];
data.object_list.forEach(item => {
// Look for an already created parent for that categoty
let parent = newData.find(parentItem => parentItem.text === item.Cat);
// If not found...
if (!parent) {
// ... create a new one...
parent = {
id: 2,
text: item.Cat,
expanded: true,
items: [],
spriteCssClass: "folder"
};
// ... and add it to the final data array.
newData.push(parent);
}
// Add the new item to the parent
parent.items.push({
id: 3,
text: item.Name,
spriteCssClass: "image"
});
});
// Return the root object with its new child items
return [{
id: 1,
text: 'Categories',
expanded: true,
spriteCssClass: "rootfolder",
items: newData
}];
}
}
}
});
$("#Sources").kendoListBox();
function onCheck(e) {
let listBox = $("#Sources").data("kendoListBox"),
treeView = $("#treeview").data("kendoTreeView"),
selection = [],
getSelection = (items) => {
items.forEach(item => {
if (item.hasChildren) getSelection(item.items);
else if (item.checked) selection.push(item);
});
};
listBox.remove(listBox.items());
getSelection(treeView.dataSource.data());
if (selection.length) {
selection.forEach(item => {
listBox.add({
text: item.text,
value: item.value
});
});
}
}
#treeview .k-sprite {
background-image: url("../content/web/treeview/coloricons-sprite.png");
}
.rootfolder {
background-position: 0 0;
}
.folder {
background-position: 0 -16px;
}
.pdf {
background-position: 0 -32px;
}
.html {
background-position: 0 -48px;
}
.image {
background-position: 0 -64px;
}
#filterText {
width: 100%;
box-sizing: border-box;
padding: 6px;
border-radius: 3px;
border: 1px solid #d9d9d9;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.common.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.rtl.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.default.min.css">
<link rel="stylesheet" type="text/css" href="https://kendo.cdn.telerik.com/2021.1.330/styles/kendo.mobile.all.min.css">
<script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/angular.min.js"></script>
<script type="text/javascript" src="https://kendo.cdn.telerik.com/2021.1.330/js/jszip.min.js"></script>
<script type="text/javascript" src="http://cdn.kendostatic.com/2021.1.330/js/kendo.all.min.js"></script>
<div id="treeview"></div>
<select id="Sources"></select>
I have this code in JS. Please tell me how i can increment a piece of this code so that articles are automatically inserted into HTML.
It is necessary that the data index [0] is incremented for example data [0], data [1], data [2] and beyond. title, author, content vary depending on the index number.Thanks!
document.querySelector(".title").textContent = data[1]["title"];
document.querySelector(".author").textContent = data[1]["author"]["username"];
document.querySelector(".content").textContent = data[1]["content"];
fetch("https://any-site/articles")
.then(function(resp) {
return resp.json();
})
.then(function(data) {
console.log(data);
document.querySelector(".title").textContent = data[1]["title"];
document.querySelector(".author").textContent = data[1]["author"]["username"];
document.querySelector(".content").textContent = data[1]["content"];
})
.catch(function() {
//catch any errors
});
// ---------- JSON on SITE ----------
[
{
"id": 1,
"title": "Some title",
"content": "Some content",
"author": {
"id": 1,
"username": "Leo",
},
},
{
"id": 2,
"title": "Some title2",
"content": "Some content2",
"author": {
"id": 2,
"username": "Vernon",
},
},
{
"id": 3,
"title": "Some title3",
"content": "Some content3",
"author": {
"id": 2,
"username": "Vernon",
},
},
]
<body>
<h1>News</h1>
<h2 class="title"></h2>
<h5 class="author"></h5>
<p class="content"></p>
</body>
<script src="data.js"></script>
The easiest method I've found is to map over the data and produce some HTML using a template literal, and then insert that into the document body with insertAdjacentHTML.
const data = [{"id":1,"title":"Some title","content":"Some content","author":{"id":1,"username":"Leo"}},{"id":2,"title":"Some title2","content":"Some content2","author":{"id":2,"username":"Vernon"}},{"id":3,"title":"Some title3","content":"Some content3","author":{"id":2,"username":"Vernon"}}];
function getHTML(data) {
// Iterate over the array of objects
return data.map((block) => {
// Destructure the title, author username, and content
// from the object
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment
const { title, author: { username }, content } = block;
// For each object return those variables
// in a template literal
return `
<div class="block">
<p class="title">${title}</p>
<p class="author">${username}</p>
<p class="content">${content}</p>
</div>
`;
// `map` returns an array of information so make
// you join it up into one string of data
}).join('');
}
// Call the `getHTML` function with the data and insert
// it on the element you want
document.body.insertAdjacentHTML('beforeend', getHTML(data));
.block {
border: 1px solid #454545;
margin: 0.5em 0 0.5em 0;
padding: 0.5em;
}
.title { text-decoration: underline; }
.author { color: blue; }
<body>
<h1>News</h1>
</body>
Our club needs to type members in an input field and have the parent li background color change based on the name lookup in a supporting json file. I would prefer a jquery solution, but javascript is OK!
All is included in the link https://jsfiddle.net/24n2on57/7/
HTML:
<ul id="sortable">
<li id="L01"><input type="text" id="I01"></li>
<li id="L02"><input type="text" id="I02"></li>
<li id="L03"><input type="text" id="I03"></li>
<li id="L04"><input type="text" id="I04"></li>
</ul>
JS:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
<script>
var standing = [{
"code": "A",
"background": "#AEF3D4"
},
{
"code": "B",
"background": "#6DDCEA"
},
{
"code": "C",
"background": "#9CC7CC"
},
{
"code": "D",
"background": "#B37F77"
}
];
</script>
<script>
var members = [{
"Class": "A",
"Name": "Bob"
},
{
"Class": "C",
"Name": "James"
},
{
"Class": "D",
"Name": "Thomas"
},
{
"Class": "B",
"Name": "Anthony"
}
]
</script>
<script>
// Lookup background color
function getBackground(name) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name === name) {
return standing[i].background;
$(this).css('background-color', standing[i].background);
}
}
return;
};
$("#I01").on("blur", function() {
$("#L01").val(getBackground($(this).val()));
})
$("#I02").on("blur", function() {
$("#L02").val(getBackground($(this).val()));
})
$("#I03").on("blur", function() {
$("#L03").val(getBackground($(this).val()));
})
$("#I04").on("blur", function() {
$("#L04").val(getBackground($(this).val()));
})
</script>
You have to set css instead of val. Also, you had multiple unnecessary style tags in your jsfiddle. I removed them and added the working code here.
For the first list element I added styling using javascript and for the others I used jQuery in-order to show you how to do it in both ways.
var standing = [{
"code": "A",
"background": "#AEF3D4"
},
{
"code": "B",
"background": "#6DDCEA"
},
{
"code": "C",
"background": "#9CC7CC"
},
{
"code": "D",
"background": "#B37F77"
}
];
var members = [{
"Class": "A",
"Name": "Bob"
},
{
"Class": "C",
"Name": "James"
},
{
"Class": "D",
"Name": "Thomas"
},
{
"Class": "B",
"Name": "Anthony"
}
]
$(this).css('background-color', 'red');
function getBackground(name) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name === name) {
return standing[i].background;
//$(this).css('background-color', standing[i].background); // Don't put any code after 'return' statement
}
}
return;
}
$("#I01").on("blur", function() {
document.getElementById("L01").style.backgroundColor = getBackground($(this).val());
});
$("#I02").on("blur", function() {
$("#L02").css({"background-color":getBackground($(this).val())});
});
$("#I03").on("blur", function() {
$("#L03").css({"background-color":getBackground($(this).val())});
});
$("#I04").on("blur", function() {
$("#L04").css({"background-color":getBackground($(this).val())});
});
#myDiv,
#intro {
display: table;
width: 30rem;
margin: 2rem auto
}
li {
background: lightgreen;
margin: 1rem;
height: 3rem;
line-height: 3rem;
list-style-type: none;
}
input {
background: #fff;
height: 2rem;
line-height: 2rem;
font-size: 1.5rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="grid-container" style="margin-top:4rem">
<div id="intro">
The color of the list items (default background = "lightgreen") is to be based on the lookup members.Name and return of the standing.background. Valid names are "Bob", "James", "Thomas", and "Anthony". User types in a name, presses tab (onblur) and the
list item background changes to standing.background.
</div>
<div id="myDiv" class="grid-item">
<ul id="sortable">
<li id="L01"><input type="text" id="I01"></li>
<li id="L02"><input type="text" id="I02"></li>
<li id="L03"><input type="text" id="I03"></li>
<li id="L04"><input type="text" id="I04"></li>
</ul> </div>
</div>
Here is the solution for your problem.
var standing = [{
"code": "A",
"background": "#AEF3D4"
},
{
"code": "B",
"background": "#6DDCEA"
},
{
"code": "C",
"background": "#9CC7CC"
},
{
"code": "D",
"background": "#B37F77"
}
];
var members = [{
"Class": "A",
"Name": "Bob"
},
{
"Class": "C",
"Name": "James"
},
{
"Class": "D",
"Name": "Thomas"
},
{
"Class": "B",
"Name": "Anthony"
}
]
$(this).css('background-color', 'red');
function getBackground(name) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name === name) {
return standing[i].background;
$(this).css('background-color', standing[i].background);
}
}
return;
};
$('input').on('input', function() {
var input = $(this).val();
$(this).parent().css('background-color', searchMembers(input));
});
function searchMembers(name){
var className = '';
for (var i=0; i < members.length; i++) {
if (members[i].Name === name) {
return searchStanding(members[i].Class);
}
}
}
function searchStanding(className){
for (var i=0; i < standing.length; i++) {
if (standing[i].code === className) {
return standing[i].background;
}
}
}
#myDiv,
#intro {
display: table;
width: 30rem;
margin: 2rem auto
}
li {
background: lightgreen;
margin: 1rem;
height: 3rem;
line-height: 3rem;
list-style-type: none;
}
input {
background: #fff;
height: 2rem;
line-height: 2rem;
font-size: 1.5rem;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Change BG color of list item based on json lookup</title>
</head>
<body>
<div class="container">
<div class="grid-container" style="margin-top:4rem">
<div id="intro">
The color of the list items (default background = "lightgreen") is to be based on the lookup members.Name and return of the standing.background. Valid names are "Bob", "James", "Thomas", and "Anthony". User types in a name, presses tab (onblur) and the
list item background changes to standing.background.
</div>
<div id="myDiv" class="grid-item">
<ul id="sortable">
<li id="L01"><input type="text" id="I01"></li>
<li id="L02"><input type="text" id="I02"></li>
<li id="L03"><input type="text" id="I03"></li>
<li id="L04"><input type="text" id="I04"></li>
</ul </div>
</div>
</body>
</html>
I just changed the JQuery part. All You need is changing the li back ground color depending on name.
var standing = [{
"code": "A",
"background": "#AEF3D4"
},
{
"code": "B",
"background": "#6DDCEA"
},
{
"code": "C",
"background": "#9CC7CC"
},
{
"code": "D",
"background": "#B37F77"
}
];
var members = [{
"Class": "A",
"Name": "Bob"
},
{
"Class": "C",
"Name": "James"
},
{
"Class": "D",
"Name": "Thomas"
},
{
"Class": "B",
"Name": "Anthony"
}
]
function getBackground(name,selector) {
var i = null;
for (i = 0; members.length > i; i++) {
if (members[i].Name == name) {
for (k = 0; standing.length > k; k++) {
if (members[i].Class == standing[k].code) {
$(selector).parent().css('background-color', standing[k].background);
}
}
}
}
return;
};
$("#I01").on("blur", function() {
getBackground($(this).val(),this);
})
$("#I02").on("blur", function() {
getBackground($(this).val(),this);
})
$("#I03").on("blur", function() {
getBackground($(this).val(),this);
})
$("#I04").on("blur", function() {
getBackground($(this).val(),this);
})
Also check the fiddle https://jsfiddle.net/24n2on57/39/
I'm new to web development and I'm trying to learn how to turn JSON content into HTML structures. In this project I am trying to create a menu for a restaurant that can be edited by a JSON file. The project is code-named "pike" to answer any questions about my variable naming.
What I am trying to do right now is have one JSON Array that holds an unknown amount of legend symbols (controlled by a user) and to turn that into html. The final product should look something like this:
GF - GlutenFree, GFO - GlutenFree option, Veg - Vegitarian, V - Vegan
Where there could be any amount of legend symbols the user wants.
To start I have created a JSON array which assigns some html syntax to variables:
var syntax = {
"spanOpen": "<span>",
"spanClose": "</span>",
"hr": "<hr>",
"pike": {
"menu": {
"legendOpen": "<p class='legend'>",
"legendClose": "</p>",
"legendIndicatorOpen": "<span class='legend-indicator'>",
"legendIndicatorClose": "</span>"
}
}
};
I have also created an array for user input that will be displayed in the menu:
var menuUserInput = {
"legend": [
{
"symbol": "GF",
"description": "GlutenFree"
}, {
"symbol": "GFO",
"description": "GlutenFree option"
}, {
"symbol": "Veg",
"description": "Vegitarian"
}, {
"symbol": "V",
"description": "Vegan"
}
]
};
Then I created a variable to put the previous two together:
var menuResponsive = {
"legend": syntax.pike.menu.legendOpen + new Array(menuUserInput.legend.length + 1).join(syntax.spanOpen + menuUserInput.legend[0].symbol + syntax.spanClose + " - " + menuUserInput.legend[0].description + ", ") + syntax.pike.menu.legendClose,
};
The problem is that this produces the following:
GF - GlutenFree, GF - GlutenFree, GF - GlutenFree, GF - GlutenFree,
And I have no clue how to get it to display correctly since I do not know how many legend items the user will want.
I have searched around a lot but unfortunately my knowledge in this realm is still very new. Thank you so much for anyone who takes the time to read this and help a noob out.
You need to loop over your menuUserInput.legend array items this way:
var syntax = {
"spanOpen": "<span>",
"spanClose": "</span>",
"hr": "<hr>",
"pike": {
"menu": {
"legendOpen": "<p class='legend'>",
"legendClose": "</p>",
"legendIndicatorOpen": "<span class='legend-indicator'>",
"legendIndicatorClose": "</span>",
"legendIndicatorSpacer": " - "
}
}
};
var menuUserInput = {
"legend": [{
"symbol": "GF",
"description": "GlutenFree",
}, {
"symbol": "GFO",
"description": "GlutenFree option"
}, {
"symbol": "Veg",
"description": "Vegitarian"
}, {
"symbol": "V",
"description": "Vegan"
}]
};
function createMenu(name) {
var toReturn = '';
if( typeof menuUserInput[name]!='undefined' ) {
for(ind in menuUserInput[name]) {
toReturn += syntax.pike.menu.legendOpen + syntax.pike.menu.legendIndicatorOpen + menuUserInput[name][ind].symbol + syntax.pike.menu.legendIndicatorClose + syntax.pike.menu.legendIndicatorSpacer + menuUserInput[name][ind].description + syntax.pike.menu.legendClose + '\n';
};
};
return toReturn;
};
var menuResponsive = createMenu('legend');
console.log( menuResponsive );
document.getElementById('result').innerHTML = menuResponsive;
<div id="result"></div>
Also on Fiddle.
Maybe you should read more about the JSON structure.
I would rather "abstract" a little more the syntax object to avoid specifying opening and closing tags. Instead I would indicate what the type should be.
/*
var syntax = {
"spanOpen": "<span>",
"spanClose": "</span>",
"hr": "<hr>",
"pike": {
"menu": {
"legendOpen": "<p class='legend'>",
"legendClose": "</p>",
"legendIndicatorOpen": "<span class='legend-indicator'>",
"legendIndicatorClose": "</span>"
}
}
};
*/
var syntax2 = {
groupItem:{
type:'span',
class:'pikeMenu'
},
divider:{
type:'hr'
},
pike: {
menu: {
legendItem:{
type:'p',
class:'legend'
},
"legendIndicator":{
type:'span',
class:'legend-indicator'
}
}
}
};
var menuUserInput = {
"legend": [
{
"symbol": "GF",
"description": "GlutenFree"
}, {
"symbol": "GFO",
"description": "GlutenFree option"
}, {
"symbol": "Veg",
"description": "Vegitarian"
}, {
"symbol": "V",
"description": "Vegan"
}
]
};
window.onload = function () {
var body = document.getElementsByTagName('body')[0];
/*
var menuResponsive = {
"legend": syntax.pike.menu.legendOpen +
new Array(menuUserInput.legend.length + 1).join(syntax.spanOpen + menuUserInput.legend[0].symbol + syntax.spanClose + " - " + menuUserInput.legend[0].description + ", ") + syntax.pike.menu.legendClose
};
*/
//crete the container
var groupContainer = document.createElement(syntax2.groupItem.type);
groupContainer.textContent = "menu container";
groupContainer.className = syntax2.groupItem.class;
body.appendChild(groupContainer);
var dividerItem = document.createElement(syntax2.divider.type);
groupContainer.appendChild(dividerItem);
for(var key in menuUserInput.legend){
if(menuUserInput.legend.hasOwnProperty(key)){
var legendItem = menuUserInput.legend[key];
console.log(legendItem);
var legendElement = document.createElement(syntax2.pike.menu.legendItem.type);
legendElement.className = syntax2.pike.menu.legendItem.class;
legendElement.textContent = legendItem.description;
var legendIndicatorElement = document.createElement(syntax2.pike.menu.legendIndicator.type);
legendIndicatorElement.className = syntax2.pike.menu.legendIndicator.class;
legendIndicatorElement.textContent = legendItem.symbol;
legendElement.appendChild(legendIndicatorElement);
groupContainer.appendChild(legendElement);
}
}
}
.pikeMenu{
font-family: sans-serif;
display: inline-block;
border: 1px solid lightgrey;
border-radius: 10px;
padding: 10px;
}
.pikeMenu .legend{
border-bottom: 1px solid gray;
cursor: pointer;
}
.pikeMenu .legend:hover{
background-color: azure;
}
.pikeMenu .legend .legend-indicator{
float: left;
color: lightblue;
}
.legend-indicator::after{
display: inline-block;
content: "-";
margin-left: 4px;
margin-right: 4px;
}