dynamic explanation div on dropdown menu change - javascript

Hi guys I am quite new in javascript,
I am using a chart.js chart that update itself based on a dropdown button.
I would like to update as well another div called explanation that give comment on the chart.
gogo is a an object that list explantation id. log.console(gogo) may output [15, 16] or [15, 16, 17, 18].
I would need for each explanation id create a new div within the explanation div
I tried :
$(".pick-chart").change(function(e) {
e.preventDefault();
var val = $(this).val();
if (val != 0) {
info_process.data.datasets[1].data = info_array[val];
info_process.update();
stringval = JSON.stringify(val)
gogo = opposed_model[val]
for(var x = 0; x < gogo.length; x++){
$("#explanation").append("<b>gogo[x]</b>");
}
document.getElementById('explanation').innerHTML = gogo;
} else {
info_process.data.datasets[1].data = [];
document.getElementById('explanation').innerHTML = "";
}
info_process.update();
});
HTML:
<div class="col">
<div class="card box-shad">
<h5 class="card-header text-center bg-dark text-white">Action</h5>
<div class="card-body">
Text - Test
<div id="explanation">
</div>
</div>
</div>
</div>
I do not manage to make it work, any idea ?

Couple of issues you have:
Instead of $("#explanation").append("<b>gogo[x]</b>"); do $("#explanation").append("<b>"+gogo[x]+"</b>");. Note the way string concatenation is happening.
Remove document.getElementById('explanation').innerHTML = gogo; this will overwrite the html of #explanation.

Related

How do I use For Loop in JavaScript to show the list?

I am a beginner in JavaScript and I can't figure out the following problem: I am trying to create a simple JavaScript Movie List. I have 10 lists on the Movie List. I tried to show all of the lists with for loop, but it doesn't work.
Here's the code:
function renderModal() {
for (let i = 0; i < listMovies.length; i++) {
let movieData = listMovies[i];
document.getElementById("poster").src = movieData.img;
document.getElementById("title").innerHTML = movieData.name;
document.getElementById("genre").innerHTML = movieData.genre;
document.getElementById("rating-num").innerHTML = "Rating: "+ movieData.rating + "/10";
document.getElementById("movie-desc").innerHTML = movieData.desc;
document.getElementById("imdb-page").href = movieData.link;
return movieData;
}
}
What do I have to do?
Help me to fix it!.
You can use template tag for list and render it into target element.I am showing an example.
Movie list
<div id="movieList"></div>
template for list
<template id="movieListTemplate">
<div class="movie">
<img src="" class="poster" alt="">
<div class="title"></div>
<div class="genre"></div>
<div class="rating-num"></div>
<div class="movie-desc"></div>
<div class="imdb-page"></div>
</div>
</template>
Javascript code:
if (listMovies.length > 0) {
const movileListTemplate = document.getElementById('movieListTemplate')
const movieRenederElement = document.getElementById('movieList')
for(const movie of listMovies) {
const movieEl = document.importNode(movileListTemplate.content, true)
movieEl.querySelector('.poster').src = movie.img
movieEl.querySelector('.title').textContent = movie.name
//use all queryselector like above
}
}
Your return movieData; will stop the loop dead. Not that running it more than once will change anything since you change the same elements over and over. IDs must be unique.
Here is a useful way to render an array
document.getElementById("container").innerHTML = listMovies.map(movieData => `<img src="${movieData.img}" />
<h3>${movieData.name}</h3>
<p>${movieData.genre}</p>
<p>Rating: ${movieData.rating}/10</p>
<p>${movieData.desc}
IMDB
</p>`).join("<hr/>");
With return movieData, the for loop will ends in advance.You should put it outside the for loop.

Save , Send and Retrieve data in Angularjs

I am trying to make a news object and in that section in which there are separate sub-section so it will look like this. user can add and remove subsection.
and when I press the save button it should send the data as following json structure seperating each subsection by ||.
{"news": {
"section1": ["ABCDE||FGHI||JKLM"],
"section2": ["NOPQ"],
"section3": ["RSTU"]
}
}
and when use save the data it should get saved and when the user open that page again it should be as last saved.
This is what I have tried so far.
I have tried to make a div and then wrap test area in it in ng-repeat but it seems like it should be it a table.
// For adding the subsection
$scope.section1 = [];
$scope.addsection1=function(){
$scope.section1.push({});
}
// For removing the subsection
$scope.removesection1 = function(id){
var indexToRemove;
for(i = 0; i < $scope.section1.length; i++){
if($scope.section1[i].id === id){
indexToRemove = i;
}
$scope.section1.splice(indexToRemove, 1);
}
}
<div class="section-div flex-column">
<div class="flex-row">
<h4 style="flex-grow: 2;">New Updates</h4>
<button class="add-btn" ng-click="addsection1()">+Add field</button>
</div>
<textarea ng-repeat="section in section1"
style="margin: 7px;border: 1px solid #00000047;border-radius: 4px;"
name="" id="">
</textarea>
</div>
Please help me I m a beginner in the angularjs. Thanks in advance.
send the data as following json structure seperating each subsection by ||
One approach is to use array.join:
var arr = ["ABCDE", "FGHI", "JKLM"];
var obj = { news: { section1: [arr.join("||")] } };
console.log(obj);
Conversely, to receive, use string.split:
var obj = { news: { section1: ["ABCDE||FGHI||JKLM"] } };
var arr = obj.news.section1[0].split("||");
console.log(arr);

Create a HTML list based on value of a data attribute of div tags?

I have a PHP function that generates hierarchical view of some blog posts according to their category, child category, grand child category and so on. It generates a string containing div tags with its data attributes. I want to convert those divs to html <ul><li> based on their value of attribute aria-level.
Actual output from php method
<div role="heading" aria-level="1">Test 1</div>
<div role="heading" aria-level="2">Test 1.1</div>
<div role="heading" aria-level="3">Test 1.1.1</div>
<div role="heading" aria-level="3">Test 1.1.2</div>
<div role="heading" aria-level="1">Test 2</div>
<div role="heading" aria-level="3">Test 2.1.1</div>
<div role="heading" aria-level="2">Test 2.2</div>
Desired Output using php/js/jquery/ any framework
Test 1Test 1.1Test 1.1.1Test 1.1.2Test 2Test 2.1.1Test 2.2
What I have achieved so far ?
function buildRec(nodes, elm, lv) {
var node;
// filter
do {
node = nodes.shift();
} while(node && !(/^h[123456]$/i.test(node.tagName)));
// process the next node
if(node) {
var ul, li, cnt;
var curLv = parseInt(node.tagName.substring(1));
if(curLv == lv) { // same level append an il
cnt = 0;
} else if(curLv < lv) { // walk up then append il
cnt = 0;
do {
elm = elm.parentNode.parentNode;
cnt--;
} while(cnt > (curLv - lv));
} else if(curLv > lv) { // create children then append il
cnt = 0;
do {
li = elm.lastChild;
if(li == null)
li = elm.appendChild(document.createElement("li"));
elm = li.appendChild(document.createElement("ul"));
cnt++;
} while(cnt < (curLv - lv));
}
li = elm.appendChild(document.createElement("li"));
// replace the next line with archor tags or whatever you want
li.innerHTML = node.innerHTML;
// recursive call
buildRec(nodes, elm, lv + cnt);
}
}
// example usage
var all = document.getElementById("content").getElementsByTagName("*");
var nodes = [];
for(var i = all.length; i--; nodes.unshift(all[i]));
var result = document.createElement("ul");
buildRec(nodes, result, 1);
document.getElementById("outp").appendChild(result);
<div id="outp">
</div>
<div id="content">
<h1>Test 1</h1>
<h2>Test 1.1</h2>
<h3>Test 1.1.1</h3>
<h3>Test 1.1.2</h3>
<h1>Test 2</h1>
<h3>Test 2.1.1</h3>
<h2>Test 2.2</h2>
<p></p>
</div>
Problem to be resolved ?
As you can see above it is using Heading tags to sort. But unfortunately my category hierarchy are not limited to only 6th level. It may grow. So I want a JS/Jquery/any framework to convert some tags to ul/li structure based on their attribute value. If any changes from Backend side is needed I can change those attributes/tags to any from PHP side. If it can be done from PHP side easily then some example code snippets is also welcome. Consider the above div tags as a single string input. :)

javascript - Show data in loop with html tags

I have an array of objects. Each object contain few parameters. What I am trying to do is to run over the array and get from each cell the data and present it on a tabel/grid.
Example code
function addButton(){
var phoneNumber = document.getElementById("phoneNumber").value;
var email = document.getElementById("email").value;
var typeNotification = document.getElementById("typeNotification").value;
var valueNumber = document.getElementById("valueNumber").value;
var delayLimit = document.getElementById("delayLimit").value;
var timeStart = document.getElementById("timeStart").value;
var timeEnd = document.getElementById("timeEnd").value;
var notify = {
typeNotification : typeNotification,
email : email,
delayLimit : delayLimit,
timeStart : timeStart,
timeEnd : timeEnd,
valueNumber : valueNumber,
phoneNumber : phoneNumber
};
var notificationList = [];
notificationList.push(notify);
console.log(notificationList);
var notificationListLength = notificationList.length;
for(var i = 0;i < notificationListLength;i++){
<div class="container">
<div class="row">
<div class="col">
1 of 2
</div>
<div class="col">
2 of 2
</div>
</div>
<div class="row">
<div class="col">
1 of 3
</div>
<div class="col">
2 of 3
</div>
<div class="col">
3 of 3
</div>
</div>
</div>
}
}
Inside the loop it gives me error with the Tags.
As you can see, when the user press the AddButton it gets all the data and restore it in object, then I add the object into Array, and then I run on the array and get from each cell of the array the data and I want to show it in Grid.
Like I said it gives me error inside the loop with the tags.
Any idea how can I solve it?
You need to build up the output of html/tags you want, then add that to a targeted element on the page, like so:
<div id="target"></div>
<button onclick="addButton()">Add</button>
<script>
const
target = document.querySelector('#target'),
notificationList = [{
typeNotification: 'typeNotification',
email: 'email',
delayLimit: 'delayLimit',
timeStart: 'timeStart',
timeEnd: 'timeEnd',
valueNumber: 'valueNumber',
phoneNumber: 'phoneNumber'
}];
let output = '';
function addButton() {
notificationList.forEach(item => {
output = `
<div class="container">
<div class="row">
<div class="col">
${item.email} - 1 of 2
</div>
<div class="col">
${item.typeNotification} - 2 of 2
</div>
</div>
<div class="row">
<div class="col">
${item.timeStart} - 1 of 3
</div>
<div class="col">
${item.timeEnd} - 2 of 3
</div>
<div class="col">
${item.delayLimit} - 3 of 3
</div>
</div>
</div>
`;
target.innerHTML += output
});
}
</script>
As you can see, you can adjust the output before you add it to the target.
I have made all the properties in notificationList strings to save time, but in your example, they would be made up of other elements on the page.
Here is a working example: https://jsfiddle.net/14o8n30u/6/
--EDIT--
Here is the same thing, but this time a table gets updated, using javascript builtin table functions:
<button onclick="addButton()">Add</button>
<table></table>
<script>
const
targetTable = document.querySelector('table'),
headerRow = targetTable.createTHead().insertRow(),
tableBody = targetTable.createTBody(),
notificationList = [];
headerRow.insertCell().textContent = 'Notification Type';
headerRow.insertCell().textContent = 'Email';
headerRow.insertCell().textContent = 'Delay Limit';
function addButton() {
while (tableBody.firstChild) {
tableBody.removeChild(tableBody.firstChild);
}
notificationList.push({
typeNotification: `Type${Math.floor(Math.random() * Math.floor(10))}`,
email: `Name${Math.floor(Math.random() * Math.floor(1000))}#test.com`,
delayLimit: `${Math.floor(Math.random() * Math.floor(100))} seconds`,
});
notificationList.forEach(item => {
const newRow = tableBody.insertRow(0);
newRow.insertCell().textContent = item.typeNotification;
newRow.insertCell().textContent = item.email;
newRow.insertCell().textContent = item.delayLimit;
});
}
</script>
On mine, I used random data for illustration purposes, but in yours the data will be built from elements on the page.
Note that you have to keep the notificationList outside the addButton, or it gets reset to an empty array each time the button is clicked.
When the page loads, the table head and body are populated.
Then when the addButton is clicked, the table body is emptied, then a new notification is added to the notificationList.
Then, inside the forEach, which loops over the notifications, all the notifications get their own row added at the top of the table (i.e. the entire table body is repopulated each time addButton is clicked).
You may not need to populate your own table header, but if you do, you can see how in this example.
Here it is working (I couldn't get it to work on jsfiddle for some reason): https://codepen.io/leonsegal/pen/oyKBQb
Hope that helps
var notificationListLength = notificationList.length;
var html_data = '';
for(var i = 0;i < notificationListLength;i++)
{
html_data += '<div class="container">
<div class="row">
<div class="col">
1 of 2
</div>
<div class="col">
2 of 2
</div>
</div>
<div class="row">
<div class="col">
1 of 3
</div>
<div class="col">
2 of 3
</div>
<div class="col">
3 of 3
</div>
</div>
</div>';
}
/* Make a div(id="html_div") when you need display data */
document.getElementById("html_div").innerHTML = html_data ;

JavaScript reselect class personally in ListView

I am creating ListView using my template:
HTML:
<div id="ItemTemplate" data-win-control="WinJS.Binding.Template">
<div class="ItemTemplate">
<div class="back"></div>
<div data-win-bind="innerText:Info.shortName" class="shortName"></div>
<div data-win-bind="innerText:value Converters.BeginValue" class="value"></div>
<div data-win-bind="innerText:value Converters.EndValue" class="valueEnd"></div>
<div data-win-bind="innerText:Info.longName"></div>
<img data-win-bind="src:Info.flag" class="flag" />
<div data-win-bind="innerText:change Converters.BeginChange" class="change"></div>
<div data-win-bind="innerText:change Converters.EndValue" class="changeEnd"></div>
<div data-win-bind="innerText:changePercent Converters.BeginChangePercent" class="changePercent"></div>
<div data-win-bind="innerText:changePercent Converters.EndValue" class="changePercentEnd"></div>
</div>
</div>
The issue is when I meet the very long name I need to adjust font-size.
So I do (for each element in list):
JavaScript:
template = document.getElementById('ItemTemplate');
// Adjust font - size
var name = item.data.Info.longName;
// Split by words
var parts = name.split(' ');
// Count words
var count = parts.filter(function(value) {
return value !== undefined;
}).length;
var longNameDiv = $(template).children("div").children("div").eq(4);
if (count > 2) {
// Display very long names correctly
$(longNameDiv).removeClass();
$(longNameDiv).addClass("veryLongName");
}
var rootDiv = document.createElement('div');
template.winControl.render(item.data, rootDiv);
return rootDiv;
CSS:
.veryLongName {
font-size: 10pt;
}
But it doesn't effect selectivly. Moreover seems like it is check conditions for the first time and then just apply the same setting for remaining items. But it needs to change font-size to smaller only in case if the name is too long. So what am I doing wrong? Thanks.
Try by using following code instead, but u must include jquery for it.
jsfiddle : http://jsfiddle.net/vH6G8/
You can do this using jquery's filter
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 5);
}).addClass('more_than5');
$(".ItemTemplate > div").filter(function(){
return ($(this).text().length > 10);
}).removeClass('more_than5').addClass('more_than10');
DEMO

Categories