EventListener showing wrong target - javascript

I have the following JS code
var existingMenus = document.getElementsByClassName('multiSelectMenu');
for (var i = 0; i < existingMenus.length; i++) {
var existingMenu = existingMenus[i];
var existingMenuHTML = [];
var targetChildren = existingMenu.parentElement.nextElementSibling.children;
console.log(targetChildren)
// Here I'm adding +1 to the ID as it appears starting at zero with a styled checkbox does not work correctly
for (var x = 0; x < targetChildren.length; x++) {
if (targetChildren[x].selected) {
existingMenuHTML += '<li><input class="dropdown-input" type="checkbox" id="' + (x + 1) + '" data-label="' + targetChildren[x].textContent + '" checked="true"/><label class="multiLabel" for="' + (x +
1) + '"><span></span> ' + targetChildren[x].textContent + ' </label></li>';
} else {
existingMenuHTML += '<li><input class="dropdown-input" type="checkbox" id="' + (x + 1) + '" data-label="' + targetChildren[x].textContent + '"/><label class="multiLabel" for="' + (x + 1) +
'"><span></span> ' + targetChildren[x].textContent + ' </label></li>';
}
}
existingMenu.innerHTML += existingMenuHTML;
console.log(existingMenuHTML)
var inputs = existingMenu.children;
console.log(inputs);
for (var w = 0; w < inputs.length; w++) {
var input = inputs[w].children[0];
console.log(input);
input.addEventListener('click', function() {
console.log('--------------')
console.log(event)
var targetElement = event.target || event.srcElement;
console.log(targetElement);
var elementParent = targetElement.parentElement.parentElement.parentElement;
console.log(elementParent)
if (!elementParent.classList.contains('open')) {
elementParent.className += ' open';
}
var multiList = elementParent.nextSibling.querySelector('[value="' + targetElement.dataset.label + '"]');
console.log(multiList)
// Subtracting one to account for the plus one I added above
var inputId = targetElement.id - 1;
if (targetElement.checked == true) {
multiList.selected = "selcted";
} else {
multiList.selected = "";
}
console.log('--------------')
});
}
}
The code works correctly on the first instance of the multiPick but all others on page trigger the first multiSelectMenu items even though I was clicking on the 3rd multiSelectMenu on page.
Here is a screen shot of the console,
Here is a code pen, https://jsfiddle.net/6s3rc8d7/ When you click the 'label' and not the checkbox it has the same issue I am seeing.

The reason behind getting the different event.target in your fiddle is due to the below code snippet in your html.
<input class="dropdown-input" type="checkbox" id="1" data-label="English only">
<label class="multiLabel" for="1"><span></span> English only </label>
you can see that in the label element, you have the for attribute which contains the id of the input element. The functionality of for attribute is that the value of this identifies which form element a label is bound to. When you click on the label it will simulate the click event of the bounded element. This is why when you click the label , in your script the event.target is the input the label is bonded with.
More on for attribute you can read here. https://developer.mozilla.org/en-US/docs/Web/HTML/Element/label

I was able to rework the code and added the EventListener to the label instead of the checkbox.

Related

css linear gradient inside of option tag of a Dropdownmenu

I would like to have a dropdown menu with the Colorbar inside of the option to select them.
This is my Code so far
http://jsfiddle.net/xpvt214o/895130/
html:
<div id="legendtest" style="width:50%;margin-left:50px">
<div id="legendGradient"><span style="opacity:0;">.</span></div></div>
<div style="display: inline">
<form action="#">
<label>Farbskala: <span id="Colormenuspan">test lala</span>
<br/>
<select id="Colormenu"></select>
</label>
</form>
</div>
js:
var first = [
'rgb(43,131,186)',
'rgb(131,193,171)',
'rgb(215,239,178)',
'rgb(252,169,94)',
'rgb(215,25,28)'
];
var second =
["rgb(255,247,251)",
"rgb(236,231,242)",
"rgb(208,209,230)",
"rgb(166,189,219)",
"rgb(116,169,207)",
"rgb(54,144,192)",
"rgb(5,112,176)",
"rgb(4,90,141)",
"rgb(2,56,88)"];
AllColorRampsName = [ "first","second"]
DrawLegend = function(gradient) {
var gradientCss = '(left';
for (var i = 0; i < gradient.length; ++i) {
gradientCss += ', ' + gradient[i];
}
gradientCss += ')';
$('#legendGradient').css('background', '-webkit-linear-gradient' + gradientCss);
$('#legendGradient').css('background', '-moz-linear-gradient' + gradientCss);
$('#legendGradient').css('background', '-o-linear-gradient' + gradientCss);
$('#legendGradient').css('background', 'linear-gradient' + gradientCss);
}
function CreateFarbskaladropdown(AllColorRampsName){
$.each(AllColorRampsName, function(j, item) {
$("#Colormenu").append('<option data-' + item + '-ival="' + j + '" value="' + item + '"> <div id="dm' + item + '">.</div></option>');
var gradientCss = '(left';
for (var i = 0; i < eval(item).length; ++i) {
gradientCss += ', ' + eval(item)[i];
}
gradientCss += ')';
$('#dm' + item).css('background', '-webkit-linear-gradient' + gradientCss);
$('#dm' + item).css('background', '-moz-linear-gradient' + gradientCss);
$('#dm' + item).css('background', '-o-linear-gradient' + gradientCss);
$('#dm' + item).css('background', 'linear-gradient' + gradientCss);
});
}
DrawLegend(first)
DrawLegend(second)
CreateFarbskaladropdown(AllColorRampsName)
I am trying to put the same div i create to show the legend colorbar in the html to show up inside of the dropdownmenu so i can choose which of the colorbars to use.
Is it even possible to create a div inside of a dropdown menu option?
It seems that option tag permitted content is just "Text, possibly with escaped characters (like é)" (from MDN read more here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/option), so you can't put element nor style it.
What you can do is making div that will act like select, nice example can be found here: https://www.w3schools.com/howto/howto_custom_select.asp
Good luck!

Changing the CSS style for multiple check boxes not working

I have an application using firebase which looks like this:
The tick boxes to the right hand side of each 'Book', when clicked, sends the value of the firebase object into a string as shown below:
When clicking these tick boxes, I would like the style of the box and content to change so they turn blue. I have added this piece of code into the on click event:
function select(data, book, key) {
//What I added
document.getElementById('selectBook').style.color="blue";
document.getElementById('selectBook').style.borderColor="blue";
//
var selectBookRef = book;
document.getElementById('alltext').value += selectBookRef + ',';
}
However, this only turns the first box blue. No matter which check box I click, the first one just changes to blue and the rest stay grey.
Here is the JS code which creates the checkbox icons and the JS to highlight the selected check boxes.
function refreshUI(list) {
var lis = '';
var lis2 = '';
var lis3 = '';
//This generates the 3 columns on the application page
for (var i = 0; i < 10 && i < list.length; i++) {
lis += '<li style="width: 150px" data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
};
for (var i = 10; i < 20 && i < list.length; i++) {
lis2 += '<li style="width: 150px" data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
};
for (var i = 20; i < 30 && i < list.length; i++) {
lis3 += '<li style="width: 150px" data-key="' + list[i].key + '">' + list[i].book + genLinks(list[i].key, list[i].book) +'</li>';
};
document.getElementById('bookList').innerHTML = lis;
document.getElementById('bookList2').innerHTML = lis2;
document.getElementById('bookList3').innerHTML = lis3;
};
//This creates the 3 icons of delete, clear and select.
function genLinks(key, bkName) {
var links = '';
links += '<i id="deleteBook" class="material-icons">delete</i> ';
links += '<i id="removeBook" class="material-icons">clear</i> ';
links += '<i id="selectBook" onclick="functionSelected()" class="material-icons">check</i>';
return links;
};
function del(key, bkName) {
var deleteBookRef = buildEndPoint(key);
deleteBookRef.remove();
}
//This is the function to select and insert the data into the string as well as highlight each checkbox
function select(data, book, key) {
document.getElementById('selectBook').style.color="blue";
document.getElementById('selectBook').style.borderColor="blue";
var selectBookRef = book;
document.getElementById('alltext').value += selectBookRef + ',';
}
function buildEndPoint (key) {
return new Firebase('https://project04-167712.firebaseio.com/books/' + key);
}
bookList.on("value", function(snapshot) {
var data = snapshot.val();
var list = [];
for (var key in data) {
if (data.hasOwnProperty(key)) {
book = data[key].book ? data[key].book : '';
if (book.trim().length > 0) {
list.push({
book: book,
key: key
})
}
}
}
refreshUI(list);
});
If anybody can help it will be much appreciated.
Thanks,
G
The only thing I can see is that you are using the same id tags for multiple different objects on the same page. If you use it at more than one place, use a class! You should never have more than one of the same id because you will be facing a lot of repeating problems..

Get Checked count in dynamic check boxes JavaScript

I'm using following code to design my screen dynamically according to the DB data.
function RefillUI(data) {
var html = "";
$.each(data,
function (i, item) {
$('#patientName').html(item.PatientName);
html += "<div class='col-md-3'> <div class='card'><div class='card_header'><h5>" +
item.DrugName +
"</h5></div><div class='card_body'>" +
"<div class='col-md-12'></div><ul class='col-md-6'><li class='bold'>Ref #</li><li class='bold'>" +
item.ReferenceNo +
"</li>" +
"</ul><ul class='col-md-6'><li class='center'>Refills</li><li class='fill'>1</li></ul>" +
"<table class='table table-bordered table-inverse'><tbody><tr><th>Prescriber</th><td>" +
item.PatientName +
"</td>" +
"</tr><tr><th>Last filled</th><td>Nov 14 2014</td></tr><tr><th>Next fill</th><td>Oct 16 2016</td></tr>" +
"<tr><th>Qty</th><td>" +
item.LastRefillQty +
"</td></tr><tr><th>Last Filled Dispensory</th><td>" +
item.LastRefillDispensory +
"</td></tr></tbody></table><form action='' class='cta center bold'>" +
"<label><input name='refill' type='checkbox' value='refill'>Refill</label></form></div></div></div>";
});
$('#refillcards').html(html);
}
Now I want to check how many check boxes are checked when click a button. How can I do this?
I know only answer in pure Javascript:
First, put this declaration at the top:
checkboxes = []; // No `var', it's global
This will initialize the stuff
function
init (n)
{
// n is the number of check boxes
checkboxes[0] = document.getElementById ('some-id');
checkboxes[1] = document.getElementById ('other-id');
// ...
checkboxes[n - 1] = document.getElementById ('different-id');
}
To check selection for a particular check box, do:
function
checkSelect (n)
{
if (n >= checkboxes.length)
{
throw "Index out of bounds: " + n;
}
return checkboxes[n].value;
}
Then, count all of then
function
count ()
{
var ret = 0;
for (var n = 0; n < checkboxes.length; n++)
{
if (checkSelect (n))
{
ret = ret + 1;
}
}
return ret;
}
var n = $( "input:checked" ).length;
you can replace input with a better selector if you want.

Get text and id from an li element on click with pure JS

I've been stuck with this for several days and I can't solve it.
I've done it with jQuery with no problem, but I need it in pure JS.
This is how my list is generated.
function get_friends(items){
if(items != undefined){
if (items.length != 0){
var html_friends_list = "";
for(var count = 0; count < items.length; count++){
if(items[count].subscription == "both"){
var display_name = Strophe.getNodeFromJid(items[count].jid);
html_friends_list = html_friends_list + "<li style='font-size:19px' id='open_chat-" + items[count].jid + "'>" + "<a href='chat-js/index.html'>" + display_name + "<span class='block-list-label' id='" + items[count].jid + "_unread_messages" + "'>0</span><span class='block-list-label' id='" + items[count].jid + "_change_status" + "'></span></a></li>";
}
}
document.getElementById("friends-list").innerHTML = html_friends_list;
As a said I want to save the value of the text and the id of any li element clicked.
Regards
you haven't specified whether this is for a specific list or just any li on your page. The below will log the id and innerHTML components of any li on the page. Perhaps you may need to update the querySelector for your particular use case.
var list = document.querySelectorAll('li');
Array.prototype.slice.call(list).forEach(function(listItem){
listItem.addEventListener('click', function(e){
console.log(this.id);
console.log(this.innerHTML);
});
});
Here's a JSFiddle which I think demonstrates what you are trying to achieve.
Jsfiddle
Combination of james' answer and working example.
function get_friends(items) {
if (items != undefined) {
if (items.length != 0) {
var html_friends_list = "<ul>";
for (var count = 0; count < items.length; count++) {
if (items[count].subscription == "both") {
html_friends_list = html_friends_list + "<li id='open_chat-" + items[count].jid + "'>"+ items[count].display_name +"</li>";
}
}
html_friends_list = html_friends_list + '</ul>'
document.getElementById("friends-list").innerHTML = html_friends_list;
}
}
}
Note: you should trigger prototype after your dom element created.

What's easiest way to get value of a checkbox

what is the easiest way to get the value of a checkbox?
I create my checkboxes dynamically
function buildList() {
var output;
output = "<form><fieldset data-role='controlgroup' data-iconpos='right' id='fieldset_item'>";
if (codeCounter != 0 && codeCounter > 0 && codeCounter != null) {
for (var i = 0; i < codeCounter; i++) {
output += "<input type='checkbox' name='checkbox_" + i
+ "' id='checkbox_" + i + "'><label for='checkbox_" + i
+ "'>" + localStorage.getItem(i) + "</label>";
}
}
output += "</fieldset></form>";
$(output).appendTo("#fieldSet");
$('#fieldSet').trigger("create");
}
So how can i get the value of the each checkbox?
Having no value in the checkboxes you're generating, kind of made me feel you want the text inside the label tags, in case I was right:
var id = 'checkbox_1';
var checkboxLabel = $('label[for="' + id + '"]').html();
$('input[type=checkbox]:checked').val()

Categories

Resources