Reference to input field added dynamically to the page - javascript
In one of the jsp pages of my project, I have this jquery code, which fill a table with dynamic data from server (the json strings):
$('document').ready(function(){
var obj_data = jQuery.parseJSON( '{"Data":[{"data":"2014-04-10","string":"10/MAR"},{"data":"2014-04-11","string":"11/MAR"},{"data":"2014-04-12","string":"12/MAR"},{"data":"2014-04-13","string":"13/MAR"},{"data":"2014-04-14","string":"14/MAR"},{"data":"2014-04-15","string":"15/MAR"},{"data":"2014-04-16","string":"16/MAR"},{"data":"2014-04-17","string":"17/MAR"},{"data":"2014-04-18","string":"18/MAR"},{"data":"2014-04-19","string":"19/MAR"}]}' );
var obj_hora = jQuery.parseJSON( '{"Hora":[{"hora":"04:30:00","string":"4:30-4:30"},{"hora":"05:00:00","string":"5:0-5:0"},{"hora":"05:30:00","string":"5:30-5:30"},{"hora":"06:00:00","string":"6:0-6:0"},{"hora":"06:30:00","string":"6:30-6:30"},{"hora":"07:00:00","string":"7:0-7:0"},{"hora":"07:30:00","string":"7:30-7:30"},{"hora":"08:00:00","string":"8:0-8:0"},{"hora":"08:30:00","string":"8:30-8:30"},{"hora":"09:00:00","string":"9:0-9:0"},{"hora":"09:30:00","string":"9:30-9:30"},{"hora":"10:00:00","string":"10:0-10:0"}]}' );
var obj_horario = jQuery.parseJSON( '{"Horario":[{"horario":"2014-04-11 06:00:00","data":"2014-04-11","string_data":"11/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-11 06:30:00","data":"2014-04-11","string_data":"11/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-11 07:00:00","data":"2014-04-11","string_data":"11/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-12 06:00:00","data":"2014-04-12","string_data":"12/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-12 06:30:00","data":"2014-04-12","string_data":"12/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-12 07:00:00","data":"2014-04-12","string_data":"12/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-13 06:00:00","data":"2014-04-13","string_data":"13/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-13 06:30:00","data":"2014-04-13","string_data":"13/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-13 07:00:00","data":"2014-04-13","string_data":"13/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-14 06:00:00","data":"2014-04-14","string_data":"14/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-14 06:30:00","data":"2014-04-14","string_data":"14/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-14 07:00:00","data":"2014-04-14","string_data":"14/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-15 06:00:00","data":"2014-04-15","string_data":"15/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-15 06:30:00","data":"2014-04-15","string_data":"15/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-15 07:00:00","data":"2014-04-15","string_data":"15/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-16 06:00:00","data":"2014-04-16","string_data":"16/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-16 06:30:00","data":"2014-04-16","string_data":"16/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-16 07:00:00","data":"2014-04-16","string_data":"16/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-17 06:00:00","data":"2014-04-17","string_data":"17/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-17 06:30:00","data":"2014-04-17","string_data":"17/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-17 07:00:00","data":"2014-04-17","string_data":"17/MAR","hora":"07:00:00","string_hora":"7:0-7:0"},{"horario":"2014-04-18 06:00:00","data":"2014-04-18","string_data":"18/MAR","hora":"06:00:00","string_hora":"6:0-6:0"},{"horario":"2014-04-18 06:30:00","data":"2014-04-18","string_data":"18/MAR","hora":"06:30:00","string_hora":"6:30-6:30"},{"horario":"2014-04-18 07:00:00","data":"2014-04-18","string_data":"18/MAR","hora":"07:00:00","string_hora":"7:0-7:0"}]}' );
var newRow1 = $('<tr>');
for(var item in obj_hora.Hora) {
newCol1 = "<td></td>";
for(var item2 in obj_data.Data) {
newCol1 += '<td>' + obj_data.Data[item2].string + '</td>';
}
}
newRow1.append(newCol1);
$("table.horarios").append(newRow1);
var counter = 1;
var newRow2 = "";
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
for(var item2 in obj_data.Data) {
newCol2 += '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
newRow2.append(newCol2);
$("table.horarios").append(newRow2);
}
});
My problem is with this line:
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
that line should make the checkbox with similar values of date and time checked, but when I run the application and open this page, nothing is checked, despite I have data in the variable 'obj_horario', as you can see in the code above.
Someone can see what i am doing wrong here?
UPDATE
I change the code highlight above to this:
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data) {
console.info('counter='+counter);
console.info('Hora = ' + obj_hora.Hora[item].hora + '| Horario.hora = ' + obj_horario.Horario[index].hora);
console.info('Data = ' + obj_data.Data[item2].data + '| Horario.data = ' + obj_horario.Horario[index].data);
var checkbox = $('input[name='+counter+']');
$(checkbox).attr("checked", "true");
}
}
to include the console.info() function; now, i can see in the browser console that the itens which should be checked are being selected correctly by the if sentence, but i guess this snippet of the code:
var checkbox = $('input[name='+counter+']');
$(checkbox).attr("checked", "true");
aren't working properly. My guess it's because it is referring a dynamically created object - I have a similar problem before, and solve including the dynamic object inside a static one, and binding an event to this static element, but now I can't figure out how to do the same, since I'm triggering any event, just are adding the element to the page.
Anyone can point me a direction for solving this?
In this part:
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
for(var item2 in obj_data.Data) {
newCol2 += '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
newRow2.append(newCol2);
$("table.horarios").append(newRow2);
}
you are not appending newCol2 to the DOM (with .append()) until the end of the for loop. As a result, within the for loop, where your $('input [name='+counter+']') gets executed, there is not (yet) such an element within the DOM.
Possible solutions:
(1st solution) Add this for loop after your .append() (so after the code snippet you pasted):
for(var item in obj_hora.Hora) {
for(var item2 in obj_data.Data) {
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
}
(2nd solution) Replace your original code with something like this:
for(var item in obj_hora.Hora) {
newRow2 = $('<tr>');
newCol2 = '<td>' + obj_hora.Hora[item].string + '</td>';
newRow2.append(newCol2);
for(var item2 in obj_data.Data) {
newCol2 = '<td>' + '<input type="checkbox" class="horario" data-key_data="'+obj_data.Data[item2].data+'" data-key_hora="'+obj_hora.Hora[item].hora+'" name="'+counter+'">' + '</td>';
newRow2.append(newCol2);
for(var index in obj_horario.Horario) {
if(obj_hora.Hora[item].hora == obj_horario.Horario[index].hora && obj_data.Data[item2].data == obj_horario.Horario[index].data)
$('input[name='+counter+']').attr("checked", "true");
}
counter++;
}
$("table.horarios").append(newRow2);
}
Related
Dynamic Menu Bar with Child Relation In MVC Ajax Call
Hi i am student working on a Project in MVC i am Creating Dynamic Menu bar i retrieve Main Menu successfully but all child menus are shown in Contact Us Dropdown menu --------------------------- ID ParentID MenuName --------------------------- 1 NULL Home 2 Null Contact Us 3 2 Address 4 2 Place 5 1 Index //html <div id="menu"> <ul> </ul> </div> //jquery code function LoadMenubarSuccess(response) { if (response != undefined && response != null && response.length > 0) { var IncidentData = "<ul>"; $.each(response, function (index, Obj) { if (Obj.ParentMenuID == null || Obj.ParentMenuID == 0) { IncidentData += "<li>" + "<a href='" + Obj.Url + "'>" + Obj.MenuName + "</a>" } if (Obj.ParentMenuID == !null || Obj.ParentMenuID > 0) { IncidentData += "<ul>"+"<li>" + "<a href='" + Obj.Url + "'>" + Obj.MenuName + "</a>" +"</li>"+ "</ul>" } }); IncidentData +="</li>"+"</ul>"; $("#menu").html(IncidentData.replace(/null/g, ' - ')); } }
The Loop is wrong. You will have to first, sort your data to your needs. In this case, it's probably best to loop through the items and attach the ones with parentID to the main item. After that, start another loop which will create the actual menu. // Sort could work like this var menuList = []; $.each(response, function(index, object) { if(object.ParentID != null && object.ParentID != undefined) menuList[object.ID].Children.push(object); else menuList[object.ID] = { Menu = object, Children = [] }; }); This way the data will be sorted to your needs (I did not test run this code). After that, you can just do whatever you need with it. For example: $incidentData = "<ul>"; $.each(menuList, function(index, parent) { $incidentData = $incidentData + "<a href='" + parent.Url + "'>" + parent.MenuName + "</a>"; if(parent.Children.length > 0) { $.each(parent.Children, function (childIndex, child) { $incidentData = $incidentData + "<a href='" + child.Url + "'>" + child.MenuName + "</a>"; }); } }); $incidentData = $incidentData + "</ul>"; Something like this should work. You can see, we are sorting the data kinda like a tree. Item has multiple parents and each parent can have multiple children. This way, we don't have to do anything fancy. Perhaps you can change your source to do this for you? Code is not tested. Adjust to your needs.
How to add a class to an element based on something saved in Local Storage with JQuery?
Basically, I'm making a TODO list, the functions are save and delete records, which are already implemented and mark as important and mark as done, which are the functions that I'm having trouble with. This is the method that I use to retrieve the items saved in Local Storage as an array. function get_todos() { var todos = new Array; var todos_str = localStorage.getItem('todo'); if (todos_str !== null) { todos = JSON.parse(todos_str); } return todos; } This is the method that I use to save records in Local Storage function add() { var task = "00"+document.getElementById('task').value; var todos = get_todos(); todos.push(task); localStorage.setItem('todo', JSON.stringify(todos)); show(); return false; } As you can see, I add the records with two 00 at the beginning, the first number is 0 when that item of the TODO list is "undone", and 1 when it is marked as done, the second number is 0 when that item if the TODO list is "not important", and 1 when it is marked as important, for changing those numbers on the local storage, I do this:- //if the second digit is 0 then the task is not important function markAsImportant(){ var id = parseInt(this.getAttribute('id')); var todos = get_todos(); var task = todos[id].replaceAt(1, "1"); console.log(task); todos.splice(id, 0, task); todos.splice(id+1, 1); localStorage.setItem('todo', JSON.stringify(todos)); show(); return false; } That method is already well implemented and working as it should. Now, knowing what item of the TODO is important and which one is not, I simply want to add a class to the items which second character is a one, and that is what I try to do here:- function show() { var todos = get_todos(); var html = '<div class="list">'; for(var i=0; i<todos.length; i++) { //HERE HERE HERE HERE HERE if (todos[i].charAt(1) == '1') { console.log("important"); $('.item').addClass('important'); } else{ console.log("not important"); } html += '<div class="item"> <input type="checkbox" class="check" id="' + i + '"> ' +' <div class="title">' + todos[i].substring(2) + '</div> <div class="tools"> <span class="tag" id="' + i + '"> <img class="important-img" src="resources/important.png"> </span> <span class="delete remove " id="' + i + '"> <img src="resources/thrash.png"> </span> </div></div>'; }; html += '</div>'; document.getElementById('todos').innerHTML = html; var deleteButtons = document.getElementsByClassName('remove'); for (var i=0; i < deleteButtons.length; i++) { deleteButtons[i].addEventListener('click', remove); }; var doneButtons = document.getElementsByClassName('check'); for (var i=0; i < doneButtons.length; i++) { doneButtons[i].addEventListener('click', markAsDone); }; var importantButtons = document.getElementsByClassName('tag'); for (var i=0; i < importantButtons.length; i++) { importantButtons[i].addEventListener('click', markAsImportant); }; var listItems = document.getElementsByClassName('item'); for (var i=0; i < listItems.length; i++) { console.log(listItems[i]); $(listItems[i]).attr('id', i); }; } But it simply won't add anything at all to the .item tags, how can I make it actually add the class important to the items that I want ?
You are not adding the html to DOM so $(".item") won't work. This should work: for (var i = 0; i < todos.length; i++) { html += '<div class="item'; if (todos[i].charAt(1) == '1') { console.log("important"); html += ' important'; // The space must be there, so change just the "important" bit, but don't remove the space } else { console.log("not important"); } html += '"><input type="checkbox" class="check" id="' + i + '"> ' + ' <div class="title">' + todos[i].substring(2) + '</div> <div class="tools"> <span class="tag" id="' + i + '"> <img class="important-img" src="resources/important.png"> </span> <span class="delete remove " id="' + i + '"> <img src="resources/thrash.png"> </span> </div></div>'; } Paste this instead your for loop and post the result in comments under this answer.
Change data property using checkbox from false to true using jQuery
I have created list of items in a table. I want to calculate the price of checked items, but can't figure out how to update the data property when a checkbox is checked/unchecked. I have included the code for generating the list and updating the price calculation. $.each(shopList, function (i, elem) { var item = elem.item; var link = elem.link; var user = elem.user; var price = elem.price; var priority = elem.priority; $(".listItems").append( '<tr class="items" data-priority="' + priority + '">' + '<td><input type="checkbox" class="priority"' + ((priority) ? 'checked' : '') + ' /></td>' + '<td>' + '' + item + '' + '</td>' + '<td>' + user + '</td>' + '<td class="price">' + price + '</td>' + '<td><button class="btn btn-default deleteItem">Del </button></td>' + '</tr>' ); }); And the code to update the price: function updatePriority(){ sumPriority = 0; $('tr.items[data-priority=true] .price').each(function () { var total = $(this).text(); if (!isNaN(total) || total.length != 0) { sumPriority += parseFloat(total); }; }); $('.totalPriority').html(sumPriority.toFixed(2)); }; When the page renders it has checked and unchecked items and everything works that way at first, but not when a change is made. How can I update the data-property true/false in the DOM?
Do not use data-property but just use the Checkbox :checked status Instead of looping over the [data-priority=true] checkboxes you can loop over the checked checkboxes instead, and use parent().find('.price') to find the correct price labels. function updatePriority(){ sumPriority = 0; $('.priority:checked').each(function () { var priceElement = $(this).parent().parent().find('.price'); var total = priceElement.text(); if (!isNaN(total) || total.length != 0) { sumPriority += parseFloat(total); }; }); $('.totalPriority').html(sumPriority.toFixed(2)); }; How can I update the data-property true/false in the DOM? If you really want to keep your code as it is and only update the data-priority attribute when you change a checkbox you can implement change listeners on the checkboxes and change the parents attribute: $('tr.items .price').change(function() { if ($(this).is(":checked")) { $(this).parent().parent().attr("data-priority",true); }else{ $(this).parent().parent().attr("data-priority",false); } });
You can try this : function updatePriority(){ sumPriority = 0; $('.listItems tr td .priority').each(function () { if ($(this).is(":checked")) { var price=$(this).parent().find('.price').text(); var total = price; if (!isNaN(total) || total.length != 0) { sumPriority += parseFloat(total); }; } }); $('.totalPriority').html(sumPriority.toFixed(2)); };
display my dropdown box in a specific area
Ok here's what I am doing. Based on some dropdown value I am craeting another dropdown value. Is it possible to display that dropdown in some specific area as I wish based on my existing code. if (SelectedIndex == 2 || SelectedIndex == 5 || SelectedIndex == 7) { $("#DomContainer").remove(); var MainContainer = document.createElement("Div"); MainContainer.id = "DomContainer"; $("body").append(MainContainer); var Options = new Array(); for(var i=1;i<=28;i++){ Options.push(i); } AddDropDown(Options); } function AddDropDown(Options) { var selectHTML = "<label>Day:</label> "; selectHTML += "<select>"; for (i = 0; i < Options.length; i = i + 1) { selectHTML += "<option value='" + Options[i] + "'>" + Options[i] + "</option>"; } selectHTML += "</select>"; document.getElementById("DomContainer").innerHTML = selectHTML; } For example <div id="new_drop">//Display the drop down here </div>
Simply add a second parameter to AddDropDown for passing the ID of the container to which you want to insert your dropdown list: function AddDropDown(Options, containerId) { ... document.getElementById(containerId).innerHTML = selectHTML; Then call it like this: AddDropDown(Options, "new_drop"); (if I understand you correctly)
No need to remove and append elements from the DOM, just replace the existing element contents ... here's a simplified version. // if "SelectedIndex" is one of the values in the array provided if ($.inArray(SelectedIndex, [2,5,7])) { $("#DomContainer").html("<label>Day:</label> "+inject_dropdown(28)); } // Creates and returns a new drop-down based on the "length" provided function inject_dropdown(length){ var selectHTML = "<select>"; for( i=1; i<=length; i++ ){ selectHTML += "<option value='" + i + "'>" + i + "</option>" } selectHTML += "</select>" return selectHTML; } Replace the $('#DomContainer') selector with whatever selector identifies the place you want the new drop-down to appear.
How to rewrite this Javascript code using Jquery?
function SelectDistrict(argument) { var sel=document.getElementById("city"); sel.style.display = ''; sel.options.length = 0; sel.options.add(new Option('Please select a location','')); var i=1; var tempInt=parseInt(argument); if (tempInt%10000==0) { var place1=document.getElementById('place1'); place1.innerHTML =county[tempInt]; } sel.options.add(new Option('all',tempInt)); $('#inputcity').hide(); while (i<=52) { tempInt+=100; if (county[tempInt]==undefined) { break; } else { op_cir = new Option(county[tempInt], tempInt); sel.options.add(op_cir); } i++; } }
You could do something like this: function SelectDistrict(argument) { var sel = $('#city'); // Store the jQuery object to save time sel.hide().empty().append('<option>Please select a location.</option'); var i = 1; var tempInt = argument; if (tempInt % 10000 == 0) { $('#place1').html(county[tempInt]); } sel.append('<option value="'+tempInt+'">all</option>'); $('#inputcity').hide(); var optionsValue = ''; // Appending strings to each other is faster than modifying the DOM tempInt += 100; while ((i <= 52) && (county[tempInt] != undefined)) // Just put the condition here instead of breaking the loop { optionsValue += "<option value='" + tempInt + "'>" + county[tempInt] + "</option>"; tempInt += 100; i++; } sel.append(optionsValue); } I hope that works for you!
you have to replace every document.getElementById() by $("#elementid") like $("#city"); and place1.innerHTML =county[tempInt]; by $("#place1").text(county[tempInt]);
You can change the while loop to: $.each(county, function(i, itm) { optionsValue += "<option value='" + i + "'>" + itm + "</option>"; })