Using jQuery to dynamically create checkboxes based on multiple attributes from div - javascript

I would like for jQuery to dyanmically create a list of checkboxes based on the class/data present in divs. Essentially these checkboxes will filter through the products so that clicking a checkbox will show the products containing that tag in their div while avoiding any duplicate checkboxes.
Sample:
<div class="Shoes" data-size="Small" data-color="Black">
<h3>Nike</h3>
</div>
<div class="Belts" data-size="Medium" data-color="Black">
<h3>Belt</h3>
</div>
<div class="Shirt" data-size="Large" data-color="Blue">
<h3>Polo</h3>
</div>
<div class="Socks" data-size="Small" data-color="White">
<h3>Generic Socks</h3>
</div>
Expected output
Class Type
Shoes
Belts
Shirt
Socks
Size
Small
Medium
Large
Color
Black
White
Blue
Each checkbox needs to be able to hide/show the item.
JsFIDDLE
The code I have so far is from searching around/previous answers, however it is only creating 1 checkbox type which is for "class" and not creating multiple ones.

Try
jQuery(function ($) {
function createCheckboxes($els, attr) {
var props = {};
$els.each(function () {
props[$(this).attr(attr)] = true;
});
return $.map(props, function (val, key) {
var $chk = $('<input />', {
type: 'checkbox',
value: key
})
return $('<label />', {
text: key
}).append($chk)
})
}
$('span').append(createCheckboxes($('div'), 'class'))
$('span').append(createCheckboxes($('div'), 'data-size'))
$('span').append(createCheckboxes($('div'), 'data-color'))
});
Demo: Fiddle

Try this http://jsfiddle.net/LzmTA/1/
HTML
<div class="Shoes" data-size="Small" data-color="Black">
<h3>Nike</h3>
</div>
<div class="Belts" data-size="Medium" data-color="Black">
<h3>Belt</h3>
</div>
<div class="Shirt" data-size="Large" data-color="Blue">
<h3>Polo</h3>
</div>
<div class="Socks" data-size="Small" data-color="White">
<h3>Generic Socks</h3>
</div>
Javascript
$(document).ready(function(){
var goods = {};
var divs = $('div');
for(var i = 0; i < divs.length; i++){
var attributes = divs[i].attributes;
var item = {};
for(var j = 0; j < attributes.length; j++){
var attrName = attributes[j].name;
if(!goods[attrName]){
goods[attrName] = {};
}
goods[attrName][attributes[j].value] = 1;
}
}
printAttributes(goods);
console.log(goods);
});
function printAttributes(goods){
for(var group in goods){
var groupTitle = $('<h3>').text(group);
$('span').append(groupTitle);
for(var item in goods[group]){
console.log(item);
var sp = $('<label>').text(item);
var chk = $('<input>').attr('type', 'checkbox').attr('value', item).attr('attr', group);
chk.bind('change', function(){
filterGoods();
});
$('span').append(chk).append(sp);
}
}
}
function filterGoods(){
var separator = '|';
var chks = $('input[type=checkbox]:checked');
var filter = [];
//get filter
for(var i = 0; i < chks.length; i++){
var item = $(chks[i]).attr('attr') + separator + $(chks[i]).val();
filter.push(item);
}
//do filter
var hasAttr = false;
var divs = $('div');
for(var i = 0; i < divs.length; i++){
hasAttr = false;
for(var j = 0; j < filter.length; j++){
var filterParts = filter[j].split(separator);
if($(divs[i]).attr(filterParts[0]) == filterParts[1]){
hasAttr = true;
continue;
}
}
hasAttr ? $(divs[i]).show() : $(divs[i]).hide();
}
console.log(filter);
}

Related

Getting Random Nulls on .querySelector() in for Loop

<div id="agg-filter-buttons">
<button class="btn filter-btn" onclick="filterSelection(event)"><span data-
value="freespins">Free Spins <div class="num-brands"></div> </span></button>
<button class="btn filter-btn" onclick="filterSelection(event)"> <span data-value="bigbonus">Big Bonus <div class="num-brands"></div> </span></button> </div>
enter code here
</div>
<div class="brand-row the-table-row all row-1 filterDiv bigbonus newPlay show">
Row 1
</div>
<div class="brand-row the-table-row all row-2 filterDiv freespins newPlay show">
Row 2
</div>
filterSelection();
function filterSelection(e) {
var x, i, c;
x = document.getElementsByClassName("filterDiv");
var allBtns = document.getElementsByClassName("filter-btn")
for(i = 0; i<allBtns.length; i++){
let rowsAffected = allBtns[i].querySelector('.num-brands');
rowsAffected.innerText = '';
}
c = "all";
if(e && e.target.dataset){
c = e.target.dataset.value ? e.target.dataset.value : "all";
}
const numBrands = [];
for (i = 0; i < x.length; i++) {
x[i].classList.remove('show');
void x[i].offsetWidth;
if (x[i].classList.contains(c)) {
x[i].classList.add('show');
numBrands.push(i);
}
}
if(e && e.target){
e.srcElement.children[0].innerText = ` (${numBrands.length})`;
}
}
// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("agg-filter-buttons");
var btns = btnContainer.getElementsByClassName("filter-btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function($this) {
var current = document.querySelectorAll(".active-btn");
current[0].className = current[0].className.replace(" active-btn", "");
this.className += " active-btn";
});
}
var filter = document.getElementById('agg-filter-buttons');
filter.addEventListener('click', function(){
document.getElementsByClassName('section--btable')[0].classList.add('flash');
});
filterSelection();
function filterSelection(e) {
var x, i, c;
x = document.getElementsByClassName("filterDiv");
var allBtns = document.getElementsByClassName("filter-btn")
for (i = 0; i < allBtns.length; i++) {
let rowsAffected = allBtns[i].querySelector('.num-brands');
rowsAffected.innerText = '';
}
c = "all";
if (e && e.target.dataset) {
c = e.target.dataset.value ? e.target.dataset.value : "all";
}
const numBrands = [];
for (i = 0; i < x.length; i++) {
x[i].classList.remove('show');
void x[i].offsetWidth;
if (x[i].classList.contains(c)) {
x[i].classList.add('show');
numBrands.push(i);
}
}
if (e && e.target) {
e.srcElement.children[0].innerText = ` (${numBrands.length})`;
}
}
// Add active class to the current control button (highlight it)
var btnContainer = document.getElementById("agg-filter-buttons");
var btns = btnContainer.getElementsByClassName("filter-btn");
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function($this) {
var current = document.querySelectorAll(".active-btn");
current[0].className = current[0].className.replace(" active-btn", "");
this.className += " active-btn";
});
}
var filter = document.getElementById('agg-filter-buttons');
filter.addEventListener('click', function() {
document.getElementsByClassName('section--btable')[0].classList.add('flash');
});
<div id="agg-filter-buttons">
<button class="btn filter-btn" onclick="filterSelection(event)"><span data-
value="freespins">Free Spins <div class="num-brands"></div> </span></button>
<button class="btn filter-btn" onclick="filterSelection(event)"> <span data-value="bigbonus">Big Bonus <div class="num-brands"></div> </span></button> </div>
enter code here
</div>
>
<div class="brand-row the-table-row all row-1 filterDiv bigbonus newPlay show">
Row 1
</div>
<div class="brand-row the-table-row all row-2 filterDiv freespins newPlay show">
Row 2
</div>
So I have a table with rows. These are filtered with the filter buttons. When you click a filter button it shows only the rows with the same name in its class. This works and populates the button with how many rows are affected.
However this breaks occasionally and I have no idea why.
the Variable rowsAffected works until it becomes null for some unknown reason.
My guess is that the dom eventually doesnt load fast enough for the querySelector to be able to read it. But im not sure.. Any advice very welcome!
I have also added a fiddle
https://jsfiddle.net/8z56sxby/
Since you only care about the first .active-btn (because there is at most one), you can just use querySelector.
Make sure there is a current before you do anything with its classes.
Use element.classList.add and element.classList.remove to add or remove classes.
for (var i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
var current = document.querySelector(".active-btn");
if (current) current.classList.remove("active-btn");
this.classList.add("active-btn");
});
}
Thankyou
The answer to this question was that clicks on my button were sometimes clicking child elements which were not setup to handle the click.
A silly mistake - that someone may find useful in the future.

Nested Question Toggle using Radio Buttons

I have a relatively straightforward nested question setup using radio buttons and JavaScript/jQuery which shows/hides extra information based on the button that you click (Yes to show, No to hide):
Here is the HTML:
<div class="form-nest panel-question d-flex justify-content-start">
<span class="icon icon-primary icon-medium icon-roundel icon-vehicle align-self-start mr-2 mr-md-4"></span>
<div class="question-wrapper">
<h2 class="heading-epsilon">Are you interested in RAC Breakdown Cover for complete peace of mind?</h2>
<!-- Yes/no Open-->
<div class="form-row form-inline">
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button" type="radio" name="buttonRadio3" id="buttonRadio5"><label for="buttonRadio5">Yes</label></div>
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button" type="radio" name="buttonRadio3" id="buttonRadio6"><label for="buttonRadio6">No</label></div>
</div>
<!-- Yes/no closed -->
</div><!--question-wrapper-->
</div><!-- Form Nest Close-->
<!--Nested container open -->
<div class="nested-container">
<div id="buttonRadio5-nest" class="nested-content">
<ul class="list list-icons">
<li class="list-item list-icon list-icon-tick">Pays out regardless of whether the accident was fault or non-fault</li>
<li class="list-item list-icon list-icon-tick">Covers named drivers and passengers</li>
<li class="list-item list-icon list-icon-tick">Covers the policy holder when driving other vehicles if they don't own the vehicle</li>
</ul>
View more product information
<p><strong>+ £40.00</strong> per year</p>
<div class="form-row form-inline">
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button" type="checkbox" name="buttonCheckbox1" id="buttonCheckbox1"><label for="buttonCheckbox1">Add</label></div>
</div>
</div>
</div><!-- Nested container closed -->
And the JS/jQuery:
function nestedPanelHide(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container");
nestCont.children().hide();
}
function nestedPanelShow(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container"),
eleNestId = eleId + "-nest",
nestFields = nestCont.children(eleNestId);
nestedPanelHide(ele);
nestFields.show();
}
$(document).ready(function(){
$(".nested-content").hide();
// Find each form with nest class
$(".form-nest").each(function( index ) {
// Find nest conts
var nest = $(this),
nestCont = nest.next(".nested-container");
// For each nest cont
for (var i = 0; i < nestCont.length; i++) {
// Find nest opts in cont
var nestOpt = nestCont[i].children;
// For each nest opt add click event
for (var j = 0; j < nestOpt.length; j++) {
// Get cont id, trim to form ele id
var id = nestOpt[j].id,
str = id.substr(0, id.lastIndexOf("-")),
eleId = "#" + str;
// Add class to ele to remove from later look up
$(eleId).parent().addClass("nest-btn");
// Add show event listener to ele
$(eleId).on("click", function() {
var id = $(this).attr("id");
nestedPanelShow(id);
});
}
}
// Find nest opts
var nestOpts = nest.children();
// For each nest opt
for (var k = 0; k < nestOpts.length; k++) {
// Get this opt
var opt = $(nestOpts[k]);
// If opt does not have class nest-btn
if (!opt.hasClass("nest-btn")) {
// Add hide event listener to opt
$(opt.children()).on("click", function() {
var id = $(this).attr("id");
nestedPanelHide(id);
});
}
}
});
});
function nestedPanelHide(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container");
nestCont.children().hide();
}
function nestedPanelShow(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container"),
eleNestId = eleId + "-nest",
nestFields = nestCont.children(eleNestId);
nestedPanelHide(ele);
nestFields.show();
}
$(document).ready(function(){
$(".nested-content").hide();
// Find each form with nest class
$(".form-nest").each(function( index ) {
// Find nest conts
var nest = $(this),
nestCont = nest.next(".nested-container");
// For each nest cont
for (var i = 0; i < nestCont.length; i++) {
// Find nest opts in cont
var nestOpt = nestCont[i].children;
// For each nest opt add click event
for (var j = 0; j < nestOpt.length; j++) {
// Get cont id, trim to form ele id
var id = nestOpt[j].id,
str = id.substr(0, id.lastIndexOf("-")),
eleId = "#" + str;
// Add class to ele to remove from later look up
$(eleId).parent().addClass("nest-btn");
// Add show event listener to ele
$(eleId).on("click", function() {
var id = $(this).attr("id");
nestedPanelShow(id);
});
}
}
// Find nest opts
var nestOpts = nest.children();
// For each nest opt
for (var k = 0; k < nestOpts.length; k++) {
// Get this opt
var opt = $(nestOpts[k]);
// If opt does not have class nest-btn
if (!opt.hasClass("nest-btn")) {
// Add hide event listener to opt
$(opt.children()).on("click", function() {
var id = $(this).attr("id");
nestedPanelHide(id);
});
}
}
});
});
(function($) {
$('.label-yes').click(function() {
$(this).closest('.nested-content').addClass('open');
});
$('.label-no').click(function() {
$(this).closest('.nested-content').removeClass('open');
});
})(jQuery);
I can get the extra information to display when you click on "yes" but I can't get it to hide again when you click "no". I've tried going over line-by-line to see if I can identify where my error might be. I feel like it's something simple, but I fear I may have gone a little code blind from staring at it too much.
I have a JSfiddle here which shows you the basis of what I'm trying to achieve - I've stripped out the styling as it might give away who this is for (it's client work), but the basic functionality is there:
https://jsfiddle.net/3y4b25uk/
Any help or guidance that can be given would be greatly appreciated as I'm at the end of my tether trying to get it working and it's so nearly there.
Thank you.
Your code has a few issues - there are no elements with the classes label-yes and label-no, there is no class open, the selectors in the click() events for label-yes and label-no do not select the div with the class nested-content as this is not selectable with closest. The div with the class nested-conent is displayed upon click of "yes" not because of the click() event that is attached to label-yes, but because of a click() event you have earlier in your code in the $(".form-nest").each() function:
$(eleId).on("click", function() {
var id = $(this).attr("id");
nestedPanelShow(id);
});
To get the click() functions for label-yes and label-no working, I've added these classes to the input elements, added the class open, set the nested-content element to display:none via CSS and adjusted the selector in the click() events from
$(this).closest('.nested-content')
to
$(this).closest(".form-nest").next(".nested-container").find(".nested-content")
Working example:
function nestedPanelHide(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container");
nestCont.children().hide();
}
function nestedPanelShow(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container"),
eleNestId = eleId + "-nest",
nestFields = nestCont.children(eleNestId);
nestedPanelHide(ele);
nestFields.show();
}
$(document).ready(function() {
$(".nested-content").hide();
// Find each form with nest class
$(".form-nest").each(function(index) {
// Find nest conts
var nest = $(this),
nestCont = nest.next(".nested-container");
// For each nest cont
for (var i = 0; i < nestCont.length; i++) {
// Find nest opts in cont
var nestOpt = nestCont[i].children;
// For each nest opt add click event
for (var j = 0; j < nestOpt.length; j++) {
// Get cont id, trim to form ele id
var id = nestOpt[j].id,
str = id.substr(0, id.lastIndexOf("-")),
eleId = "#" + str;
// Add class to ele to remove from later look up
$(eleId).parent().addClass("nest-btn");
// Add show event listener to ele
$(eleId).on("click", function() {
var id = $(this).attr("id");
nestedPanelShow(id);
});
}
}
// Find nest opts
var nestOpts = nest.children();
// For each nest opt
for (var k = 0; k < nestOpts.length; k++) {
// Get this opt
var opt = $(nestOpts[k]);
// If opt does not have class nest-btn
if (!opt.hasClass("nest-btn")) {
// Add hide event listener to opt
$(opt.children()).on("click", function() {
var id = $(this).attr("id");
nestedPanelHide(id);
});
}
}
});
});
function nestedPanelHide(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container");
nestCont.children().hide();
}
function nestedPanelShow(ele) {
var eleId = "#" + ele,
nestWrap = $(eleId).closest(".form-nest"),
nestCont = nestWrap.next(".nested-container"),
eleNestId = eleId + "-nest",
nestFields = nestCont.children(eleNestId);
nestedPanelHide(ele);
nestFields.show();
}
$(document).ready(function() {
$(".nested-content").hide();
// Find each form with nest class
$(".form-nest").each(function(index) {
// Find nest conts
var nest = $(this),
nestCont = nest.next(".nested-container");
// For each nest cont
for (var i = 0; i < nestCont.length; i++) {
// Find nest opts in cont
var nestOpt = nestCont[i].children;
// For each nest opt add click event
for (var j = 0; j < nestOpt.length; j++) {
// Get cont id, trim to form ele id
var id = nestOpt[j].id,
str = id.substr(0, id.lastIndexOf("-")),
eleId = "#" + str;
// Add class to ele to remove from later look up
$(eleId).parent().addClass("nest-btn");
// Add show event listener to ele
$(eleId).on("click", function() {
var id = $(this).attr("id");
nestedPanelShow(id);
});
}
}
// Find nest opts
var nestOpts = nest.children();
// For each nest opt
for (var k = 0; k < nestOpts.length; k++) {
// Get this opt
var opt = $(nestOpts[k]);
// If opt does not have class nest-btn
if (!opt.hasClass("nest-btn")) {
// Add hide event listener to opt
$(opt.children()).on("click", function() {
var id = $(this).attr("id");
nestedPanelHide(id);
});
}
}
});
});
(function($) {
$('.label-yes').click(function() {
$(this).closest(".form-nest").next(".nested-container").find(".nested-content").addClass("open");
});
$('.label-no').click(function() {
$(this).closest(".form-nest").next(".nested-container").find(".nested-content").removeClass("open");
});
})(jQuery);
.sandbox{
.panel-question{
display: flex;
flex-direction: row;
}
.form-row.form-inline {
width: 100%;
}
}
.nested-content {
display:none;
}
.open {
display:block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<section class="sandbox">
<div class="container">
<div class="row">
<div class="col">
<div class="panel">
<div class="panel-content">
<div class="form-nest panel-question d-flex justify-content-start">
<span class="icon icon-primary icon-medium icon-roundel icon-vehicle align-self-start mr-2 mr-md-4"></span>
<div class="question-wrapper">
<h2 class="heading-epsilon">Are you interested in RAC Breakdown Cover for complete peace of mind?</h2>
<!-- Yes/no Open-->
<div class="form-row form-inline">
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button label-yes" type="radio" name="buttonRadio3" id="buttonRadio5"><label for="buttonRadio5">Yes</label></div>
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button label-no" type="radio" name="buttonRadio3" id="buttonRadio6"><label for="buttonRadio6">No</label></div>
</div>
<!-- Yes/no closed -->
</div>
<!--question-wrapper-->
</div><!-- Form Nest Close-->
<!--Nested container open -->
<div class="nested-container">
<div id="buttonRadio5-nest" class="nested-content">
<ul class="list list-icons">
<li class="list-item list-icon list-icon-tick">Pays out regardless of whether the accident was fault or non-fault</li>
<li class="list-item list-icon list-icon-tick">Covers named drivers and passengers</li>
<li class="list-item list-icon list-icon-tick">Covers the policy holder when driving other vehicles if they don't own the vehicle</li>
</ul>
View more product information
<p><strong>+ £40.00</strong> per year</p>
<div class="form-row form-inline">
<div class="form-check form-check-inline"><input class="form-check-input form-check-input-button" type="checkbox" name="buttonCheckbox1" id="buttonCheckbox1"><label for="buttonCheckbox1">Add</label></div>
</div>
</div>
</div><!-- Nested container closed -->
</div>
</div>
</div>
</div>
</div>
</section>
Note that the <div> with the class nested-content now gets displayed because of 2 reasons: once because of the working click() event handler on label-yes, and in addition because of the previous click() event that calls the function nestedPanelShow(). I'm not sure if you want to remove this click() event or rework your code so you're also attaching a click() event to the input for "No" and can omit the additional click() events you attach to label-yes and label-no. I've added a console message to this event handler in this Fiddle.

What to do when looping repeats in 2 different areas

The code gets the values of the input and sends it to the textarea, but when you add more than one title the values are repeated in the result of the titles, for example, the DESCRIPTIONS of title 1 are the same as in title 2, why does this happen? and how to make it work without changing the purpose?
Run the code in codepen.io or jsfiddle.net
This is what happens:
This is what should happen:
function result() {
var inp2 = document.getElementsByName("inp2");
var titu = document.getElementsByName("titu");
var res = document.getElementById("result");
res.value = "";
if (titu[0]) {
for (var k = 0; k < titu.length; k++) {
if (titu[k].value.trim() != '') {
res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
for (var j = 0; j < inp2.length; j++) {
if (inp2[j].value.trim() != '') {
res.value += `<li>${inp2[j].value.trim()}</li>\n`;
}
}
}
}
}else {
console.log("test")
res.value += `<ul>\n`;
for (var l = 0; l < inp2.length; l++) {
if (inp2[l].value.trim() != '') {
res.value += `<li>${inp2[l].value.trim()}</li>\n`;
}
}
}
};
// -----------------------------------------
if (document.getElementById("add2")) {
let cont2 = 1;
document.getElementById("add2").onclick = function clone2() {
let container2 = document.getElementById("output2");
let tempLinha2 = document.querySelector('#template2');
let clone2 = document.importNode(tempLinha2.content, true);
const label2 = clone2.querySelector("label");
label2.htmlFor = cont2;
clone2.querySelector("input").className = cont2;
container2.appendChild(clone2);
cont2++;
};
document.getElementById("del2").onclick = function del2() {
document.querySelector('#output2 #linha2:last-child').remove();
};
}
// ---------------------------------------
if (document.getElementById("addtit")) {
let cont3 = 1;
document.getElementById("addtit").onclick = function clone3() {
let container3 = document.getElementById("output2");
let tempLinha3 = document.querySelector('#template3');
let clone3 = document.importNode(tempLinha3.content, true);
const label3 = clone3.querySelector("label");
label3.htmlFor = cont3;
clone3.querySelector("input").className = cont3;
container3.appendChild(clone3);
cont3++;
document.getElementById('add2').id = 'add3';
document.getElementById('del2').id = 'del3';
};
document.getElementById("deltit").onclick = function deltit() {
document.querySelector('#output2 #alg:last-child').remove();
document.getElementById('add3').id = 'add2';
document.getElementById('del3').id = 'del2';
};
}
// -----------------------------------------
if (document.getElementById("add3")) {
let cont4 = 1;
document.getElementById("add3").onclick = function clone4() {
let container4 = document.getElementById("output3");
let tempLinha4 = document.querySelector('#template2');
let clone4 = document.importNode(tempLinha4.content, true);
const label4 = clone4.querySelector("label");
label4.htmlFor = cont4;
clone4.querySelector("input").className = cont4;
container4.appendChild(clone4);
cont4++;
};
document.getElementById("del3").onclick = function del4() {
document.querySelector('#output3 #linha2:last-child').remove();
};
}
<div class="container">
<button id="addtit">+ TITLE</button>
<button id="deltit">- TITLE</button>
<button id="add2">+ DESCRIPTION</button>
<button id="del2">- DESCRIPTION</button>
<div id="output2"></div>
<div class='botoes'>
<button onclick="result()" id='done'>DONE</button>
</div>
<div class="header"><span class="title">RESULT</span>
</div>
<div class="linha"><textarea id="result"></textarea>
</div>
</div>
<!-- template 2 -->
<template id="template2">
<div class="linha" id="linha2"><div class="coluna1"><label for="0">DESCRIPTION:</label></div><div class="coluna2"><input name="inp2" class="0" type="text"/></div>
</div>
</template>
<!-- template 3 -->
<template id="template3">
<div id="alg">
<div class="linha"><div class="coluna1"><label for="0">TITLE:</label></div><div class="coluna2"><input name="titu" class="0" type="text"/></div>
</div>
<div class="linha" id="linha3"><div class="coluna1"><label for="0">DESCRIPTION:</label></div><div class="coluna2"><input name="inp2" class="0" type="text"/></div>
</div>
<div id="output3"></div>
</div>
</template>
Ok. it's because this part of code in function result:
if (titu[0]) {
for (var k = 0; k < titu.length; k++) {
if (titu[k].value.trim() != '') {
res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
for (var j = 0; j < inp2.length; j++) {
if (inp2[j].value.trim() != '') {
res.value += `<li>${inp2[j].value.trim()}</li>\n`;
}
}
}
}
}
your titles have the same names : 'titu' , and your descriptions have same names : 'inp2', and you have two nested loops, for each title, loop on description, and it results as you see.
it's better to change your code and make different names and ids
by the way. if you persist to do not change your code, you should use one loop for both of them, like this code
if (titu[0]) {
for (var k = 0; k < titu.length; k++) {
if (titu[k].value.trim() != '') {
res.value += `<div>
<span>${titu[k].value.trim()}</span>
</div>
<ul>\n`;
if (inp2[k].value.trim() != '') {
res.value += `<li>${inp2[k].value.trim()}</li>\n`;
}
}
}
}
UPDATE
for the case of more description for each title, you have to change the code of onClick methods of Title+ and Description+, the added title and all of its description must have same parent, and after doing that, it's possible to solve the problem like this . (assuming the parent that I already have said has class name 'parent')
function result() {
var parents = document.querySelectorAll(".parent")
parents.forEach(function(parent){
var title = parent.querySelector("titu");
var descriptions = parent.querySelectorAll("inp2");
var res = document.getElementById("result");
if (title.value.trim() != '') {
res.value += `<div>
<span>${title.value.trim()}</span>
</div>
<ul>\n`;
}
descriptions.forEach(function(inp2){
if (inp2.value.trim() != '') {
res.value += `<li>${inp2.value.trim()}</li>\n`;
}
});
});
}
notice that this code could work after modifying Title+ and Description+ events and add same parent with class name parent to title and descriptions inputs

Morris Bar-chart(Error: <rect> attribute width: A negative value is not valid. ("-0.2634408602150538") in the first click im getting like this

> In the first click my chart is not displaying(but data is present),
after changing the date it is loading n displaying, from past 3 days
I'm trying to fix this issue but couldn't.
<div class="box box-success barchart">
<div ng-show="dataFound" class="box-body chart-responsive">
<div class="y-axis"><text ng-show="isBarShowing" id="y-axis" class="axis">Inverter Capacity kWh →</text></div>
<div class="chart" id="bar-chart">
</div>
</div>
<div id="x-axis" ng-show="isBarShowing"><text class="axis">Inverters →</text></div>
</div>
js file
function generateMultipleBarValues() {
var data = $scope.data;
var timeKeys = [];
var tempMap = [];
barData = [];
for (var i = 0; i < data.length; i++) {
var datum = data[i];
var timeKey = datum.TimeofReading.split(' ')[0];
if (timeKeys.indexOf(timeKey) == -1) {
timeKeys.push(timeKey);
}
}
for (var i = 0; i < timeKeys.length; i++) {
for (var j = 0; j < data.length; j++) {
var time = data[j].TimeofReading.split(' ')[0];
if (timeKeys[i] == time) {
if (typeof tempMap[time] == 'undefined') {
tempMap[time] = { date: time };
tempMap[time]['Inv ' + data[j].InverterId] = data[j].Readingby;
} else {
tempMap[time]['Inv ' + data[j].InverterId] = data[j].Readingby;
}
}
}
barData.push(tempMap[timeKeys[i]]);
}
if (barData.length == 0) {
$('#bar-chart').hide();
$scope.isBarShowing = false;
$scope.viewDisabled = true;
$scope.dataFound = false;
return;
} else {
$('#bar-chart').show();
timeKeys = [];
tempMap = [];
console.log(JSON.stringify(barData));
generateBarChart(barData);
barData = [];
$scope.dataFound = true;
$scope.isBarShowing = true;
$scope.viewDisabled = false;
$scope.dataFound = true;
}
}
// generate barchart
function generateBarChart(barData) {
var keyNames = Object.keys(barData[0]);
var keys = [];
for (var i = 1; i < keyNames.length; i++) {
keys.push('Inv ' + i);
for (var j = 0; j < barData.length; j++) {
barData[j][keys[i - 1]] = barData[j][keyNames[i]];
delete barData[j][keyNames[i]];
}
}
console.log(JSON.stringify(keys));
console.log(JSON.stringify(barData));
$('#bar-chart').empty();
bar = new Morris.Bar({
element: 'bar-chart',
data: barData,
xkey: 'date',
ykeys: keys,
labels: keys,
});
keys = [];
}
here each time when I'm changing the select range in facing the of
negative value, initially the width is less(when we are loading the
chart first time) but in the second time, it is loading correctly.
please some on help me to fix this issue... were my chart can be
display in all the time
Please put width for your div element. like width:auto or width:600px.
<div class="box box-success barchart">
<div ng-show="dataFound" class="box-body chart-responsive" style="width:auto; height:350px">
<div class="y-axis"><text ng-show="isBarShowing" id="y-axis" class="axis">Inverter Capacity kWh →</text></div>
<div class="chart" id="bar-chart">
</div>
</div>
<div id="x-axis" ng-show="isBarShowing"><text class="axis">Inverters →</text></div>
</div>

how to display checked values in checkbox using angular array?

I've already accomplished selecting htc in home page and coming to another page. Now I want to display whether the selected store value and severdata match (in this case I need to show true). During the on submit event, I want to pass all selected values. I have tried the code below, but its not working for me.
$scope.Selctedstores =window.localStorage.getItem("selectedservices");
console.log($scope.Selctedstores);
//console i am getting htc
var serverData = ["Nokia", "Htc", "Samsung"];
$scope.items = [];
for (var i = 0; i < serverData.length; i++)
{
var modal = {
name: serverData[i],
selected: false
};
$scope.items.push(modal);
}
$scope.check = function()
{
var checkedItems = [];
for (var i = 0; i < $scope.items.length; i++) {
if ($scope.items[i].selected) {
checkedItems.push($scope.items[i].name);
}
}
console.log(checkedItems);
}
html
<div ng-controller="Test1Controller">
<div ng-repeat="item in items">
<input type="checkbox" ng-model="item.selected" /> {{item.name}}
</div>
<input type="button" name="submit" value="submit" ng-click="check()" />
</div>
Before pushing to items array check whether the item is present already in the selected store. If so, then assign selected as true. Hope this helps. Let me know if you have any problem
check updated fiddle
function TodoCtrl($scope) {
var serverData = ["Nokia", "Htc", "Samsung"];
var selectedStore = ["Htc"]
$scope.items = [];
for (var i = 0; i < serverData.length; i++)
{
var modal = {
name: serverData[i],
selected: false
};
if (selectedStore.indexOf(serverData[i]) >= 0) {
modal.selected = true;
}
$scope.items.push(modal);
}
$scope.check = function()
{
var checkedItems = [];
for (var i = 0; i < $scope.items.length; i++) {
if ($scope.items[i].selected) {
checkedItems.push($scope.items[i].name);
}
}
console.log(checkedItems);
}
}
Try
for(var i=0;i<serverData.length;i++)
{
var modal = {
name:serverData[i],
selected:($scope.Selctedstores !== null && $scope.Selctedstores.indexOf(serverData[i]) > -1) ? true : false
};

Categories