How to remove elements from jquery object - javascript

I have a specific problem. I want to grab some element, traverse through it and remove or edit unwanted elements before posting that element data over JSON.
My function looks like this.
$("#submit_btn").off("click").on("click", function(e) {
e.preventDefault();
pdfhtml = $("#Calculation").html();
var inputs = $("input[type=number]", pdfhtml);
$.each(inputs, function(k, v) {
$(this).remove();
//$(this, pdfhtml).remove(); //also not working
})
var data = {};
data["data"] = pdfhtml;
alert(pdfhtml);
getdataJSON("","POST", "html", data, true);
});
The problem I have is that nothing happens, elements are still present after i submit this data. What am I doing wrong? I need this in order to generate pdf with mpdf6 (PHP).

You are creating a temp jQuery object and is removing inputs form that but the original string pdfhtml is not modified
$("#submit_btn").off("click").on("click", function (e) {
e.preventDefault();
//create a temp dom structure with the target html as its content
var $temp = $('<div />', {
html: $("#Calculation").html()
});
//modify the temp dom structure
$temp.find("input[type=number]").remove();
var data = {};
//get the update html content from the temp object
data["data"] = $temp.html();
alert(pdfhtml);
getdataJSON("", "POST", "html", data, true);
});

jQuery won't do string modification like that. All inputs will be is an in-memory representation of <input> tags, changes to these will not save back to the pdfhtml string.
What you should do instead is clone the #Calculation div, then perform your actions:
$("#submit_btn").off("click").on("click", function(e) {
e.preventDefault();
var pdfhtml = $("#Calculation").clone(); // Clone this
var inputs = pdfhtml.find("input[type=number]");
$.each(inputs, function(k, v) {
$(this).remove();
});
var data = {};
data["data"] = pdfhtml.html(); // Read the HTML here...
alert(pdfhtml);
getdataJSON("","POST", "html", data, true);
});

Related

Populate Bootstrap modal form fields from JSON

I've got a Bootstrap modal that displays a large form (30+ inputs).
I wrote the following code to populate the first few fields from JSON.
$('#seg-detail-modal').on('shown.bs.modal', function (e) {
var modal = $(this);
$.get( "includes/segdata.json", function( data ) {
$('#seg-detail-modal').find("input[name='segCode']").val(data.segCode);
$('#seg-detail-modal').find("input[name='orgName']").val(data.orgName);
$('#seg-detail-modal').find("input[name='referenceId']").val(data.referenceId);
});
});
Is there a more efficient way of populating a large form than what I'm doing here?
You could just iterate through the object properties and match selector to property in that loop.
Something like:
$('#seg-detail-modal').on('shown.bs.modal', function(e) {
var $inputs = $(this).find(':input');
$.getJSON("includes/segdata.json", function(data) {
$.each(data, function(key, val) {
$inputs.filter('[name="' + key + '"]').val(val);
});
});
});
If a property exists that doesn't have a match the selector will just fail quietly

How to properly use appendChild

$(document).ready(function() {
$("a:last").on("click", function(event) {
event.preventDefault();
var url = $("a:last").attr("href");
var page = url.slice(-2).trim();
var newDiv = document.createElement("div");
$(newDiv).addClass("content");
$(newDiv).addClass(page);
$(newDiv).load(url);
document.getElementById("main").appendChild($(newDiv));
});
});
I want to create a new div and load some content into it, then append it to the "main" div, but I get a TypeError:
Argument 1 of Node.appendChild does not implement interface Node.
I already have a div with id="main", why can't I append my new div to it?
Basically appendChild() expects a node object as its parameter, but here you are passing a jquery object. You can fix it by passing a node object,
document.getElementById("main").appendChild(newDiv);
And since you are using jquery, you can use its own append() function,
$(document).ready(function() {
$("a:last").on("click", function(event) {
event.preventDefault();
var url = $("a:last").attr("href");
var page = url.slice(-2).trim();
var newDiv = $("<div>");
newDiv.addClass("content");
newDiv.addClass(page);
newDiv.load(url);
$("#main").append(newDiv);
});
});
The issue is because you're mixing up jQuery and plain old JS. The error itself is because you're proving a jQuery object to appendChild() when it's expecting a DOMElement. As you're using jQuery anyway you may as well use that to create your elements. Try this:
$("a:last").on("click", function(e) {
e.preventDefault();
var url = $("a:last").attr("href");
var page = url.slice(-2).trim();
$('<div />').addClass('content ' + page).appendTo('#main').load(url);
});
$(newDiv) is a jquery object, not the node. You need to pass the node in. This will work
$(document).ready(function() {
$("a:last").on("click", function(event) {
event.preventDefault();
var url = $("a:last").attr("href");
var page = url.slice(-2).trim();
var newDiv = document.createElement("div");
$(newDiv).addClass("content");
$(newDiv).addClass(page);
$(newDiv).load(url);
document.getElementById("main").appendChild(newDiv);
});
});

How to add click event listener to each elements?

I use query to build a mobile app. First of all I use $.getJSON to retrieve data from json file:
$.getJSON('js/sura.json', function(data){
$.each(data, function(key, value){
//alert(key+' '+value['id']);
buildList(value['id'], value['name'], value['number']);
});
});
There are more than 100 rows from json file.
After that, I need to put every lists to an elements name <ul id="list></ul>. Should I make new Javascript function then write the code:
function buildList(id, name, number){
var name_elm = '<h3>'+name+'</h3>';
var noq_elm = '<span>'+number+'</span>';
var $list_elm = '<li>'+name_elm+''+noq_elm+'</li>';
$('#list').append($list_elm);
}
After I use .append(...). I would like to add click listener to every lists (each list has unique id).
How should I write query to add listener to each <li></li>?
You can use event delegation:
var $list_elm = '<li class="noqele">'+name_elm+''+noq_elm+'</li>';
$('#list').append($list_elm);
}
And Code for click event:
$(document).on('click','.noqele',function(){
//click event code...
});
This can be done more efficiently like this
$.getJSON('js/sura.json', function (data) {
var container = $();
$.each(data, function (key, value) {
var h3 = $('<h3 />', {text : value.name}),
span = $('<span />', {text : value.number}),
li = $('<li />', {
id: value.id,
on: {
click: click_function
}
});
container = container.add(li.append(h3, span));
});
$('#list').append(container);
});
function click_function() {
// do stuff on click
}

Generate input handler via jQuery for xmlhttprequest json data in a table

I'm struggling with dynamic generation of buttons over a JSON array.
Stripped-down code is this (aim is to build a table based on the data, nothing fancy yet, I'm not yet proficient at this):
$.ajax({
/* type, content, etc. removed */
success: function (data, textStatus, XmlHttpRequest) {
var target = $('myContainerDiv');
var result = data.d.results;
var $table = $('<table />');
for(var i=0;i < results.length; i++) {
var $row = $('<tr />');
var $cell = $('<td />');
var $button = $('<input />').attr({ type: 'button', value: 'Edit', name: 'btn' + i });
$button.click(function () {
// **
// In a .NET environment, this would become a closure
// I suspect this is the offending bit of code
//
alert(results[i].name);
};
$cell.append($button);
$row.append($cell);
$table.append($row);
}
$target.append($table);
},
/* error etc. removed*/
});
I basically want a column filled with buttons, each one would popup the value of a field from the array I get from my $.ajax call.
Buttons actually show up, but they do not react to clicking, and I see no runtime error in the F12 tools console. This is probably due to the fact that this script is part of the configuration page for a Microsoft Dynamics CRM 2011 Solution, but other than that, I'm sure the AJAX call goes on OK (I tried making it print out data, and I can see it).
UPDATE
Referencing i inside the click handler was the offending line indeed: changed the code like this made things work as I was expecting:
var $button = $('<input />').attr({ type: 'button', value: 'Edit', name: 'btn' + results[i].name });
$button.click(function () {
// 'i' value is NOT what I thought it was !
alert(this.name.substring(3,this.name.length));
// I found out in the meanwhile that 'this' references the event source
};
First you have several syntax errors in your code and it may not be running at all:
if the ID of your div container is myContainerDiv, to get the target you need to do $('#myContainerDiv')
you create a result varialbe, but you use a results variable
you're not closing the parentesis in the $button.click
you're adding everything to $target but is defined as target
Now the actual problem may be, as you say, the closure, remember that you close over variables not values, so when you execute the button click handler, i has a value of results.length, so you are out of bounds by that time.
You could try to store the results objects elsewhere, extract the Id of the object your looking for from the button (you're naming then 'btn'+i) and then access the name property that way.
I noticed you didn't close the .click() bracket.
Try...
$button.click(function () {
alert(results[i].name);
});
You can try this ...
$.ajax({
/* type, content, etc. removed */
success: function (data, textStatus, XmlHttpRequest) {
var $target = $('#myContainerDiv'),
results = data.d.results,
$table = $target.append('<table />').children('table:last-child'), $trSet = $([]);
for(var i=0; i < results.length; i++) {
$trSet = $trSet.add(
$([
'<tr><td>',
$('<input type="button" value="edit" name="btn'+i+'" rel="'+results[i].name+'" />').wrap('<div />').html(),
'</td></tr>'
].join(''))
);
}
// Using Event delegation ... Only one handler is attached to the DOM.
$table.append($trSet).click(function(e){
var $t = $(e.target);
if( $t.is('input[type="button"]') ){
alert($t.attr('rel'));
}
// choose to return false whether to prevent event bubbling up the DOM or not
// return false;
});
},
/* error etc. removed*/
});

jQuery updating elements added on the fly?

My code is not working, i think because elements are added on the fly:
var tooltip = $('<div/>').insertAfter('.trigger').addClass('tooltip');
var tname = $('<span/>').addClass('tname').text('(...)');
tooltip.html(tname.html()):
// Ajax call
success: function() {
tname.html('success'); // not working
$('.tooltip').find('.tname').html('success'); // not working
$('.tname').html('success'); // not working
}
This won't work because you are not inserting the tname element into the DOM. See this fix below:
var tooltip = $('<div/>').insertAfter('.trigger').addClass('tooltip');
var tname = $('<span/>').addClass('tname').text('(...)');
tooltip.html("");
tooltip.append(tname);
// Ajax call
success: function() {
tname.html('success'); // should work
$('.tooltip').find('.tname').html('success'); // should work
$('.tname').html('success'); // should work
}
You're not inserting the span into the DOM.
// append to some element
var tname = $('<span/>').addClass('tname').text('(...)').appendTo(tooltip);
Only then you can use selectors to find the element and do something with it.

Categories

Resources