.nextAll function will not work when used inside a click function - javascript

Im trying to use the .nextAll option in jquery inside a checkbox listed inside modal window.. so the when the user clicks on a link and the modal window opens up, through the function .on("click") , thats when the chexkbox appears and Ive wrote a code inside the click function which alters check prop of the checkbox.
$('input[name="Company"],input[name="Country"]').live("click",function(){
if ($(this).is(':checked')){
alert("s");
$(this).nextAll('input[name="'+this.name+'Sub"]').prop('checked',true);
} else {
alert("n");
$(this).nextAll('input[name="'+this.name+'Sub"]').prop('checked',false);
}
});
<input type="checkbox" class="entityCheckboxHeader1" id="entityCheckboxHeader" name="Company">Company
<input class="modalEntityCompany" id="entity1" type="checkbox" name="CompanySub">Microsoft
<input class="modalEntityCompany" id="entity2" type="checkbox" name="CompanySub">Apple
<br />
<input type="checkbox" class="entityCheckboxHeader2" id="entityCheckboxHeader" name="Country">Country
<input class="modalEntity" id="entity3" type="checkbox" name="CountrySub">USA
<input class="modalEntity" id="entity4" type="checkbox" name="CountrySub">UK
The program works fine independly when tried in a jsfiddle or inside a new html that we create, bt it will not wrk when it is used inside a click function that I created. what could be causing the conflict?
Note:Im using .live() function for checkbox as it wont even get in to the .nextAll part when .on() is used
DYNAMIC CREATION PART
function generateTreeHTML(input) {
var html = '';
var entityNumber = 1;
var color = 663399;
html = "<ul id='tree' class='treeview-black' >";
for ( var m = 0; m < input.length; m++) {
html+="<li>";
currentEntity = input[m];
currentEntityType = currentEntity.entity;
html += "<span style='font-size:12px; font-family:Helvetica; font-weight:bold;' id='entityHeader' class='entityHeader"
+ getEntityHeader()
+ "'><input name='" + currentEntityType +"' type='checkbox' id='entityCheckboxHeader' class=\""
+ 'entityCheckboxHeader'
+ getEntityCheckboxHeader()
+ "\" />"
+ currentEntityType
+ "</span><div style='width:15px; height:10px; background-color:#"
+ colorArray[entityNumber]
+ "; float:right; margin-right:50px; margin-top:5px;'></div>";
html+="<ul>";
for ( var n = 0; n < currentEntity[currentEntityType].length; n++) {
html += "<li>";
var entityName = currentEntity[currentEntityType][n].entity;
var entityName1 = entityName.split('.').join("");
entityName1 = entityName1.split('_').join("");
entityName1 = entityName1.replace(/ /g, "");
html += "<span><input type='checkbox' key=\"" + entityName
+ "\" mapKey=\"" + currentEntityType
+ "\" categoryNumber=\"" + entityNumber
+ "\" class='modalEntity' id=\"" + 'entity' + getEntityID()
+ "\" name='" + currentEntityType + "Sub'>" + entityName + "</span>";
html += "</li>";
}
html+="</ul></li>";
entityNumber = entityNumber + 1;
html += "<div style='width:200px; border-bottom:1px solid #cccccc; height:1px;'></div>";
}
html += "</ul>";
return html;
}

The .nextAll() method only finds the next sibling elements (as stated very clearly in the doco). The structure that you are creating dynamically seems to put the related checkboxes each in their own spans inside different li elements - i.e., they are not siblings of each other or of the header checkboxes that your click handler belongs to. You can't expect the traversal methods you were using to find the elements to work for different html structures any more than driving directions from my office to my house would work to get to your house.
Try this instead:
$('input[name="Company"],input[name="Country"]').live("click",function(){
if ($(this).is(':checked')){
alert("s");
$('input[name="'+this.name+'Sub"]').prop('checked',true);
} else {
alert("n");
$('input[name="'+this.name+'Sub"]').prop('checked',false);
}
});
Which can be greatly simplified to:
$('input[name="Company"],input[name="Country"]').live("click",function(){
$('input[name="'+this.name+'Sub"]').prop('checked',this.checked);
});
Or if you're concerned that there might be other checkboxes of the same name elsewhere in your document you could look just within the same li element that the clicked header box belongs to:
$(this).closest('li')
.find('input[name="'+this.name+'Sub"]').prop('checked',this.checked);

Give a class say checkinput to checkbox input[name="Company"] and input[name="Country"]"
$('body').delegate(".checkinput","click",function(){
if ($(this).is(':checked')){
alert("s");
$(this).nextAll('input[name="'+$(this).attr('name')+'Sub"]').prop('checked',true);
} else {
alert("n");
$(this).nextAll('input[name="'+$(this).attr('name')+'Sub"]').prop('checked',false);
}
});

Related

How to reinitialize a script in an HTML document?

I have a document that uses the jscolor.com library, for the user to be able to select and store a color. I'm also using a JQuery function to add rows to the screen, so the user can create and define a number of colors. The problem is, when the new row is added, the Javascript isn't re-initialized for the added elements.
Here is the code in question:
<script type="text/javascript">
$(document).ready(function(){
var i=1;
$("#add_row").click(function(){
$('#addr'+i).html("<div id='addr" + i + "'>" +
"<div class='col-xs-4'>" +
"<input type='text' name='config_color[" + i + "][css]' id='input-color[" + i + "][css]' class='form-control' />" +
"</div>" +
"<div class='col-xs-2'>" +
"<input type='text' name='config_color[" + i + "][value]' id='input-color[" + i + "][value]' class='form-control jscolor' />" +
"</div>" +
"<div class='col-xs-2'>" +
"<input type='text' name='config_color[" + i + "][default]' id='input-color[" + i + "][default]' class='form-control' />" +
"</div>" +
"<div class='col-xs-4'>" +
"<input type='text' name='config_color[" + i + "][notes]' id='input-color[" + i + "][notes]' class='form-control' />" +
"</div>" +
"</div>");
$('#tab_logic').append('<div id="addr'+(i+1)+'"></div>');
i++;
});
$("#delete_row").click(function(){
if(i>1){
$("#addr"+(i-1)).html('');
i--;
}
});
}).trigger('change');
</script>
I've made an simplified example of what I'm talking about on JSFiddle - you can see in the first row, if you click in the color cell, it gives you a pop up color palette.
If you add additional rows, the popup picker doesn't work.
However, all of the data stores in the database properly, so i have an instance where some elements added by Javascript work properly and others don't?
(Also full disclosure, I asked on Reddit first - this is therefore a cross-post.
In their examples, jscolor has one called "Instantiating new Color Pickers" which shows you how to do it.
You're adding the new row as a string, which I wouldn't recommend, because if you created each input separately using jQuery it would be easier to call jscolor() on only one element, but this works too.
Just add the following to your click handler:
// Get all the inputs first
var allInputs = $('.jscolor');
// From there, get the newest one
var newestInput = allInputs[allInputs.length - 1];
// And call jscolor() on it!
new jscolor(newestInput);
Here's an updated fiddle
Generally Abe Fehr answer helped me too, but i had slightly other problem. My elements already had default values from database so
new jscolor(newestInput);
initialized them but with default FFFFF
So in my case twig (html) looks like this:
<button class="jscolor {value:'{{ category.color }}'} btn btn-sm disabled color-picker" data-color="{{ category.color }}"></button>
And then I reinitialize all the colors like this:
let all_pickers = $('.color-picker');
if ($(all_pickers).length !== 0) {
$(all_pickers).each((index, element) => {
let color = $(element).attr('data-color');
new jscolor(element, {'value': color});
});
}

jQuery getJSON and get value from button

I'm download data from JSON file and display button with value:
function iterateOverPrzepisy(best) {
$('#listaPrzepisow').html('');
$.getJSON('przepisy.json', function(data) {
for (var x in przepisyDost) {
$('#listaPrzepisow').append(" <div data-role=\"collapsible\"><h2>" + przepisyDost[x].nazwa + "</h2>" +
"<ul data-role=\"listview\" data-theme=\"d\" data-divider-theme=\"d\">" +
"<li>" +
"<h3>Składniki: " + przepisyDost[x].skladniki + "</h3>" +
"<p class='ui-li-desc' style='white-space: pre-wrap; text-align: justify;'>" + przepisyDost[x].tresc + "</p>" +
"<button id='ulubioneBtn' value='" + przepisyDost[x].id + "'>Ulubione</button></li>" +
"</ul>" +
"</div>");
j++;
}
})
}
When I click to button #ulubioneBtn I would like to get value from this button. So I add done to getJSON
}).done(function(data){
$('button#ulubioneBtn').click(function (event) {
console.log("Ulubione: ");
event.preventDefault();
var id = $("button#ulubioneBtn").val();
console.log("Value: " + id);
//dodajemy do ulubionych
localStorage.setItem("ulubione"+id, id);
});
});
But it's not working. When I click on button Ulubione I always get in console log value = 0
The problem seems to be that you add multiple buttons with the same id. An id of a html element should be unique.
przepisyDost does not appear to be defined at
for (var x in przepisyDost) {
? Try
for (var x in data.przepisyDost) {
Duplicate id's are appended to document at
"<button id='ulubioneBtn' value='" + przepisyDost[x].id
+ "'>Ulubione</button></li>" +
within for loop. Try substituting class for id when appending html string to document
"<button class='ulubioneBtn' value='" + data.przepisyDost[x].id
+ "'>Ulubione</button></li>" +
You could use event delegation to attach click event to .ulubioneBtn elements, outside of .done()
$("#listaPrzepisow").on("click", ".ulubioneBtn", function() {
// do stuff
})
I have created a dummy JSON and executed the same JS with a single change.
In onclick handler instead of getting button I am using $(event.target).
And it is working fine.
Please find the fiddle https://jsfiddle.net/85sctcn9/
$('button#ulubioneBtn').click(function (event) {
console.log("Ulubione: ");
event.preventDefault();
var id = $(event.target).val();
console.log("Value: " + id);
//dodajemy do ulubionych
localStorage.setItem("ulubione"+id, id);
});
Seems like first object doesn't have any id value.
Please check JSON response returned from server.
Hope this helps you in solving.

My button isn't working

I have some html in my JS and everything but the button works. The input button appears but when I click it, nothing happens.
function updateFavourite(video) {
document.getElementById("favourite").onclick = function () {
blacklist[video["id"]] = true;
myfavourite.push(video);
var html =
"<input onclick='remove(video);' value='Remove' type='button'></input>" +
"<li class=\"saved\">" +
"<img class= \"img-rounded\" src=\"{0}\"/>" +
"<p><b title=\"{2}\"><a class=\"extendedLink\" href=\"javascript:watchFavouriteVideo(\{1}\)\"><span></span>{2}</a></b><br>" +
"by {3}<br>" +
"{4} | {5} views</p>" +
"</li>";
$("#myfavourite").prepend(html.format(video["thumbnail"],
video["id"],
video["title"],
video["uploader"],
video["length"],
video["views"]));
setVideoF(video);
}
}
Method to call:
function remove (video) {
alert('Favourites removed');
}
It looses its access to video variable, remove the onclick attribute and use jQuery to bind its event, and also use JavaScript Closure to keep the video variable safe:
function updateFavourite(video) {
var clickFunc = (function (video) {
return function () {
blacklist[video["id"]] = true;
myfavourite.push(video);
var html =
"<input class='removeButton' value='Remove' type='button' />" +
"<li class=\"saved\">" +
"<img class= \"img-rounded\" src=\"{0}\"/>" +
"<p><b title=\"{2}\"><a class=\"extendedLink\" href=\"javascript:watchFavouriteVideo(\{1}\)\"><span></span>{2}</a></b><br>" +
"by {3}<br>" +
"{4} | {5} views</p>" +
"</li>";
$("#myfavourite").prepend(html.format(video["thumbnail"],
video["id"],
video["title"],
video["uploader"],
video["length"],
video["views"]));
$("#myfavourite .removeButton").click(function () {
remove(video);
});
};
})(video);
document.getElementById("favourite").onclick = clickFunc;
}
Your code is generating a dynamic html so click event is not registering properly. A little html updated required. Use the "removeVideo"class to your button and use the jquery to
register the click event for dynamic element.
$('body').on('click','.removeVideo', function(){
$(this).val("Clicked");
});
Insted of $('body') you can use the closest(but not dynamic element) parent.

How do I execute an event using jQuery through an html object(button) created through Javascript?

I'm just new here. So here's where I'm stuck:
I created an html table using javascript. I have a button,which when clicked, will create set of tables with exactly the same structure but the objects(eg. button, text) inside those tables have different ID's. Now when I try to execute a click function using jQuery with a button on one of the produced tables, it won't work. How do I go around here? Thanks in advance!
Here's a sample function which creates the html table(with unique ID's) in javascript:
function CreateTables() {
var html = ' ';
var valPrompt = prompt("How many tables would you like to add?");
parseInt(valPrompt);
for (i = 1; i <= valPrompt; i++) {
html += "<table>" + "<tr>" + "<td>" + "Text goes here" + "</td>" + "<td>" + "<input type='text' id='txtTEXT" + i + "'/>" + "</td>" + "<td>" + < input type = 'button'
id = 'btnALERT" + i + "' / > +"</td>" + "</tr>" + "</table>"
}
document.getElementById('HtmlPlaceHolder').innerHTML = html;
}​
So, if we review the code, Sets of table with buttons(btnALERT) with unique ID's will be created if the function CreateTables is executed. In order to select the objects, I suppose I'll be using jQuery. So for example, if I bind a handler in btnALERT1(produced by CreateTables) say a click function in order to alert a simple "Hello", how will I do this? My code for this doesn't seem to work:
$(document).ready(function() {
$('#btnALERT1').click(function() {
alert("Hello");
});
});​
Use .live() (for older jquery versions - < v1.7):
$('#btnALERT1').live('click', function()
{
alert("Hello");
});
Or:
$(document).delegate('#btnALERT1', 'click', function()
{
alert("Hello");
});
Use .on() (for new jquery versions - >= 1.7):
$(document).on('click', '#btnALERT1', function()
{
alert("Hello");
});
I think you may want to use the method .on():
$(document).ready(function() {
$('#btnALERT1').on('click', function() {
alert("Hello");
});
});
For more information, check the online doc: http://api.jquery.com/on/
I would use a delegate on HtmlPlaceHolder to check for click events like so:
$("#HtmlPlaceHolder").on("click", "input[type=button]", function() {
alert($(this).attr("id"));
});
Also, I would change the button id scheme to btnALERT_1, so you can extract the ID number with a .split("_") method.
You have to attach the event handlers after you create the tables, not when the document is ready (the document should be ready anyways since the user is interacting with it).
You can do this with jQuery, sure, but have a look at the native methods - jQuery might be too bloated depending on what you will do and you will learn something about the DOM.
I've added some code below which lets you add a callback and shows some things you can get back easily. It is not exactly what you asked for, but a great start to finding your way in the DOM.
function CreateTables() {
var html = ' ';
var valPrompt = prompt("How many tables would you like to add?");
parseInt(valPrompt);
for (i = 1; i <= valPrompt; i++) {
html += "<table>" + "<tr>" + "<td>" + "Text goes here" + "</td>" + "<td>" + "<input type='text' id='txtTEXT" + i + "'/>" + "</td>" + "<td>" + < input type = 'button'
id = 'btnALERT" + i + "' / > +"</td>" + "</tr>" + "</table>"
}
var placeholder = document.getElementById('HtmlPlaceHolder').innerHTML = html;
placeholder.innerHTML = html;
placeholder.addEventListener('click', function (e) {
console.log(this, e);
}
}​

How to fetch the id of dynamically generated textboxes?

How is it possible to get the id of the dynamically generated textboxes using jquery?. I need to fire the TextChanged event for the corresponging textbox. There is no method reference for the textboxes in the code behind.How can i refer to any method in the codebehind on firing the event. Somebody please help. I dont know jquery much. The entire script im using is as as follows:
<script type="text/javascript">
$(init);
function init()
{
$('#test').droppable(// Div Control
{
drop: handleDropEvent
});
$('a').each(function(idx, item) {
$(item).draggable({ cursor: 'move', helper: 'clone' })
});
}
$(function() {
$("#draggable").draggable(); //Nothing to do with this div
});
function handleDropEvent(event, ui)
{
var draggable = ui.draggable;
document.getElementById('test').innerHTML += addColumn(draggable.attr('text')) + '<br>';
}
function addColumn(column)
{
var iHtml;
// This code will generate a checkbox and a textbox. I need to fire the event of thus generated textboxes.
iHtml = '<div id="dv' + column + '" width="100px;" height="20px;" padding: "0.5em;"> ' + '<span title="ToolTipText">' + '<input type="checkbox" id="cb' + column + '" value="' + column + '" /> <label for="cb' + column + '">' + column + '</label></span><input type="text" runat="server" id="aln' + column + '"> </div>';
return iHtml;
}
</script>
There's two ways: keep the generated element, or generate an ID when you generate your new element.
a) keep the generated element
This requires that you don't use innerHTML, but create the element (with document.createElement, or with jQuery's $), and then you can use the element directly (no need to call it by ID any more). For instance, with jQuery:
var container = $('#container');
var myDiv = $('<div id="myDiv"/>');
var myCheck = $('<input type="checkbox"/>');
myDiv.append(myCheck);
container.append(myDiv);
b) generate the ID
container.innerHTML = '<div id="myDiv"><input type="checkbox" id="myCheck"/></div>';
// and after this you can get them by ID:
var myCheck = $('#myCheck');
I would just add a class to the textbox in your iHtml then use .live() event
replace your iHtml with this
iHtml = '<div id="dv' + column + '" width="100px;" height="20px;" padding: "0.5em;"> ' + '<span title="ToolTipText">' + '<input type="checkbox" id="cb' + column + '" value="' + column + '" /> <label for="cb' + column + '">' + column + '</label></span><input class="myclass" type="text" runat="server" id="aln' + column + '"> </div>';
then add the live event
$('.myclass').live('change', function() {
alert(' Live handler called.');
});
here is a WORKING DEMO

Categories