How to use a variable in html code using backtick in JavaScript? - javascript

I have a variable there is define few value with using JavaScript backtick. How can I use another variable with backtick?
var liElem = '';
$('button').click(function(){
var newData = 'This is new data'
liElem = `<ul>
<li class=" ' + newData + ' ">Good news</li>
<li class="icon-text-dark-yellow">Fair</li>
<li class="icon-text-dark-red">Poor</li>
<li class="icon-text-light-gray">N/A</li>
</ul>`;
console.log(liElem);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>click</button>
Why newData variable is not readable inside? JavaScript backtick? There is any way to do this?
Answer will be appreciated!

It is called template literals, as the documentation states:
Template literals are string literals allowing embedded expressions. You can use multi-line strings and string interpolation features with them. They were called "template strings" in prior editions of the ES2015 specification.
What you want to do is called expression interpolation what you can achieve with ${variableName}.
You need to use as the following:
const newData = 'This is new data';
const liElem = `<ul>
<li class="${newData}">Good news</li>
<li class="icon-text-dark-yellow">Fair</li>
<li class="icon-text-dark-red">Poor</li>
<li class="icon-text-light-gray">N/A</li>
</ul>`;
console.log(liElem);
I hope that helps!

Use placeholder ${<your var name>}
var liElem = '';
$('button').click(function(){
var newData = 'This is new data'
liElem = `<ul>
<li class=${newData}>Good news</li>
<li class="icon-text-dark-yellow">Fair</li>
<li class="icon-text-dark-red">Poor</li>
<li class="icon-text-light-gray">N/A</li>
</ul>`;
console.log(liElem);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button>click</button>

This is not different from any regular string if you start a string with " you have to end it with ". So if you start it with ` then you need to end it with `.
So if you want to use + newData + then you have to write:
var newData = 'This is new data'
liElem = `<ul>
<li class=" ` + newData + ` ">Good news</li>
<li class="icon-text-dark-yellow">Fair</li>
<li class="icon-text-dark-red">Poor</li>
<li class="icon-text-light-gray">N/A</li>
</ul>`;
console.log(liElem);
Or as you already use tempalte string literals can use embedded expressions <li class="${newData}">

Related

javascript, nested navbar from json

My aim is to replicate this structure automatically from a json file.
<ul class="sidebar-menu">
<li class="treeview">
Mammals
<ul class="treeview-menu">
<li>Goat</li>
<li> Sheep
<ul class="treeview-menu">
<li>Bone</li>
<li>Bone
<ul class="treeview-menu">
<li>Variant 1</li>
<li> Variant 2</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
JSON
[
{"datasetID":"5fd4124900827","higherClassification":"Eukarya","kingdom":"Animalia","phylum":"Chordata","class":"Mammalia","order":"Artiodactyla","family":"Bovidae","genus":"Capra","subgenus":"None","vernacularName":"goat","commonName":"None","elementName":"Calcaneus","commonElementName":"None"},
{"datasetID":"5fd4058e5c8d2","higherClassification":"Eukarya","kingdom":"Animalia","phylum":"Chordata","class":"Mammalia","order":"Artiodactyla","family":"Bovidae","genus":"Capra","subgenus":"None","vernacularName":"goat","commonName":"goat","elementName":"Femur","commonElementName":"None"}
]
The relevant parts are:
"datasetID":"5fd4124900827"
"class":"Mammalia",
"order":"Artiodactyla",
"family":"Bovidae",
"genus":"Capra",
"subgenus":"None",
"vernacularName":"goat",
"elementName":"Calcaneus"},
So the class is on the top level of the hierarchy, it could be mammal, bird, fish...
Taking class: Mammalia as an example, under this is order under that family under that genus
then if there is a subgenus that is on the next level also.
Under that is the vernacularName then elementName.
Each record has a unique id datasetID there may be multiple "elementName": "Calcaneus" for a goat, these need an integer added (i.e. Calcaneus 1, then Calcaneus 2, then Calcaneus 3 etc.
>Mammalia
>order
>family
>genus
>subgenus (if exists)
>vernacularName
>elementName (if more than one append 1,2,3...)
So, my mega question, how to do this in javascript?
My attempt so far:
Php gets the json, yes this could be done in javascript.
<?php
$data = json_decode(file_get_contents("bonify" . $version . "/app/json/data.json"), True);
?>
Javascript picks up the json:
<script type="text/javascript">
const version = "<?php echo $version; ?>";
$.getJSON('bonify'+ version +'/app/json/data2.json', function(json) {
console.log(json); // this will show the info it in firebug console
obj = json
This lists all the json data:
function printValues(obj) {
for(var k in obj) {
if(obj[k] instanceof Object) {
printValues(obj[k]);
} else {
document.write(obj[k] + "<br>");
};
}
};
closing code:
});
</script>
I'm not convinced document.write is the best way to do this.
I have this code for my search and it seems like I should adapt that but with out the filter capability.
$('#txt-search').keyup(function(){
var searchField = $(this).val();
if(searchField === '') {
$('#filter-records').html('');
return;
}
var regex = new RegExp(searchField, "i");
var output = '<div class="col-12 p-0"><hr />';
var count = 1;
$.each(data, function(key, val){
if ((val.datasetID.search(regex) != -1) || (val.ownerInstitutionCode.search(regex) != -1)|| (val.vernacularName.search(regex) != -1)|| (val.elementName.search(regex) != -1)) {
output += '<ul class="sidebar-menu">';
output += '<li><i class="fas fa-bone" data-fa-transform="rotate-45"></i> <span>' + val.vernacularName + ': ' + val.elementName + '</span></li>';
output += '</ul>';
if(count%2 == 0){
output += '</div>'
}
count++;
}
});
$('#filter-records').html(output);
});
});
});
I'm assuming several nested foreach loops is the way to go? I've put the whole aim for clarity. I am trying to learn and I have a learning disability so please be patient with me, thanks for your help. I've tried to included as much info as possible to avoid having my question closed as too broad.
You have a repeated pattern. If we assume that you have built a hierarchical data structure, then we can use a function using template literals, like:
function buildChildren(children) {
var tvms = [];
for (let child of children) {
tvms.push(myTreeViewMenu(child));
}
return tvms;
}
function myTreeViewMenu(treeViewMenu) {
tvms = buildChildren(treeViewMenu.children);
return `
<ul class="treeview-menu">
<li>${treeViewMenu.name} ${tvms.join("")}</li>
</ul>
`;
}
function myTree(tree) {
tvms = buildChildren(tree.children);
return `
<ul class="sidebar-menu">
<li class="treeview">
${tree.name}
${tvms.join("")}
</li>
</ul>
`;
}
(NOT TESTED)
This logic can be a starting point for you, basically you nest your pattern into itself. You need to make sure that from your raw JSON you build an object tree whose nodes have a string called name and an array for the subtree called children. Also, make sure there are no cycles in the tree.

Get index of an element from a NodeList

I have a simple list:
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
And need to get index of a specific item disregarding hidden items.
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
I try to convert NodeList in Array:
var list_items = Array.from(items);
But don't known how to run something like that: list_items.indexOf('item-3')
https://codepen.io/marcelo-villela-gusm-o/pen/RwNEVVB?editors=1010
You can make a function to find the id you need in a list you want, passing two parameters, that way you can use this function dynamically.
Based on id, inside the function just need to use .findIndex() that returns the index or -1 if not found.
See here:
var list = document.getElementById('list');
var items = list.querySelectorAll('li:not([style*="display: none"])');
var list_items = Array.from(items);
function getIndexById(idToSearch, list){
//ES6 arrow function syntax
return list.findIndex(elem => elem.id == idToSearch)
//normal syntax
//return list.findIndex(function(elem) {return elem.id == idToSearch})
}
console.log("found at index: ", getIndexById("item-3", list_items))
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" style="display: none">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Not exactly related to the question, but if possible, I would suggest you to change your HTML to remove that inline style of display: none and change it to a class, (e.g: class='hidden'), it would be better for your .querySelector when using :not, for example: li:not(.hidden), since any space in your inline style can break your selector. ("display:none" != "display: none", spot the space)
Maybe like this:
var item = list_items.find(function(item) {
return item.id === "item-3";
});
I would recommend using :not(.hidden) instead of "grepping" for a match on the style tag. Then, simply find the index after casting the NodeList to an array.
For the Vue.js inclined, see this fiddle: https://jsfiddle.net/634ojdq0/
let items = [...document.querySelectorAll('#list li:not(.hidden)')]
let index = items.findIndex(item => item.id == 'item-4')
console.log('item-4 index in visible list is', index)
.hidden {
display: none;
}
<ul id="list">
<li id="item-1">1</li>
<li id="item-2" class="hidden">2</li>
<li id="item-3">3</li>
<li id="item-4">4</li>
<li id="item-5">5</li>
</ul>
Maybe you can use map. First you can create an object with id and value. Then use map function to create array of this object. Then you can access it with foreach, when id = 'item-3'.

Get data-attribute value and HTML in array

I have the following tag in my html and I need to select the data-id value and the inner html value into an array.
How can I achieve this in either Jquery or Javascript
<li class="dual-listbox__item" data-id="1">Politieacademie</li>
<li class="dual-listbox__item" data-id="3">IBM</li>
<li class="dual-listbox__item dual-listbox__item--selected" data-id="5">Energias de Portugal</li>
You can use .map() along with .get() to convert it to basic array
var arr = $('li.dual-listbox__item').map(function() {
return {
id: $(this).data('id'),
text: $(this).html()
};
}).get();
console.log(arr)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li class="dual-listbox__item" data-id="1">Politieacademie</li>
<li class="dual-listbox__item" data-id="3">IBM</li>
<li class="dual-listbox__item dual-listbox__item--selected" data-id="5">Energias de Portugal</li>
</ul>
Select the elements, loop them using map and you got your array. Below will return an array of objects holding the data you want
const res = Array.from(document.querySelectorAll('.dual-listbox__item')).map(e => ({
dataId: e.dataset.id,
innerHTML: e.innerHTML
}));
console.log(res);
<li class="dual-listbox__item" data-id="1">Politieacademie</li>
<li class="dual-listbox__item" data-id="3">IBM</li>
<li class="dual-listbox__item dual-listbox__item--selected" data-id="5">Energias de Portugal</li>
You can use $('.dual-listbox__item').each() to achieve this:
var dataId = [];
var nHTML = [];
$('.dual-listbox__item').each(function(){
dataId.push($(this).data('id'));
nHTML.push($(this).text());
});
console.log(dataId);
console.log(nHTML);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="dual-listbox__item" data-id="1">Politieacademie</li>
<li class="dual-listbox__item" data-id="3">IBM</li>
<li class="dual-listbox__item dual-listbox__item--selected" data-id="5">Energias de Portugal</li>

How do I add an HTML element into a div using jQuery while passing variables as content?

Say I have a list like so:
<ul id="my-list">
<li class="list-item" data-role="collapsible">List Item</li>
<li class="list-item" data-role="collapsible">List Item</li>
<li class="list-item" data-role="collapsible">List Item</li>
</ul>
I want to be able to add another li element with the class list-item and maybe the data-role collapsible at the end of the list. But, I want to pass the contents of a variable to the inside of the new li tag. Say the variable is var myVariable = "Contents of Variable"; Is there a way to do this using jQuery and/or JavaScript?
You could clone one of the existing tags:
$('#my-list li').first().clone().text(myVariable).appendTo('#my-list');
And with plain JavaScript:
var list = document.getElementById('my-list');
var elem = list.firstChild.cloneNode();
elem.textContent = myVariable;
list.appendChild(elem);
Try this:
var myVariable = "Contents of Variable";
$("#my-list").append("<li class='list-item' data-role='collapsible'>" + myVariable + "</li>");
Are you trying to do this FIDDLE ?
var myVariable = "Contents of Variable";
x(myVariable);
function x(obj) {
$('#my-list').append('<li class="list-item" data-role="collapsible">' + obj + '</li>');
}
Also
function create(content){
$('<li />', {
class: 'list-item',
'data-role': 'collapsible'
}).html(content).appendTo('#my-list')
}
create('my content')
Demo: Fiddle
You can use
$('#my-list').append('<li class="list-item" data-role="collapsible">' + myVariable + '</li>');

get all values of ul into variable

I have <ul> like this:
<ul class="options" id="selt_count">
<li value="1">One</li>
<li value="2">Two</li>
<li value="5">Five</li>
<li value="12">Other</li>
</ul>
What I want is to get all values of <li> into variable in the following format (1,2,5,12) in jquery.
Thanks
How about:
var values = $('#selt_count li').map(function() {
return this.value
});
values; // [1, 2, 5, 12]
To get a string representation you can do:
var s = '(' + values.get().join(',') + ')'; // "(1,2,5,12)"
FYI the value attribute was deprecated a while ago.
References:
jQuery.map

Categories

Resources