Jquery comparing elements - javascript

I have an array on javascript and i insert the elements on it like this:
var parentRow = $(button).parent().parent();
list.push({ parent: parentRow, detailRow: newRow });
On the click of another button i do the following:
var parentRow = $(button).parent().parent();
var detailRow = null;
for (var i in list) {
if ($(list[i].parent) == $(parentRow)) {
detailRow = list[i].detailRow;
}
}
The point is: The if comparing to two elements should return TRUE, because they are the same DOM element....the same i added before, but it return FALSE.
I would like to know how i compare this two elements to get TRUE there.

Try:
if (parentRow.has(list[i])) {

They are not the same objects, because they don't refer to the same jQuery instance.
Simple solution: Don't use jQuery and do it with normal DOM methods.
jQuery solution: Use .is()

You need to compare the native elements, not the jQuery-wrapped elements. jQuery's DOM methods returns not the elements themselves but a jQuery object.
if (list[i].parent[0] === parentRow[0]) {

Related

How to get the this DOM Object from the $(this) jQuery Object?

I have a function to which a jQuery object is passed as an argument. See below code.
$('selector').click(function() {
// $(this) is the jquery object for the DOM on which I clicked.
test($(this));
});
function test(jqobj) {
// Here from jqobj, I want to get back the native javascript object (I mean the this)
}
The jqobj param is an array of DOM elements so you can use
jqobj[0]
but test the size of the array if it is not empty like
jqobj.length > 0
So we can covert each other
//From jQuery object to Dom:
var domobject = jqueryObject.get();
//From Dom to jQuery object
var jqueryObject = jQuery(domobject);
Example:
//From Dom to jQuery object
var overlayContent = document.createElement("div");
var __this=this; //declare out side your function.
function test(){
__this; //use __this in your function.
}
if you are sure that there will only be one element then
function test(jqobj) {
var el = jqobj[0]
}
rather passing object as a parameter you can also send element id or class to function.Then you can use getElementById method inside function to refer the element.
If you are not passing multiple element use like this:
function test(jqobj) {
var obj;
if(jqobj[0]!=null)
{
obj = jqobj[0];
}
}

Find element from jQuery matching objects

I have a click event listener as below:
$(".clickable").click(function (e) {
var results= $(e.currentTarget).closest('div.set').find('.clickable');
// returns
//[<label for=​"thumbnail" class=​"clickable">​1 Malaysia​</label>​,
//<div class=​"thumbnail clickable">​…​</div>​]
var label = $(results).find('label'); // returns [] (empty list)
}
My problem is, how can I select the label element from the results list ? Thanks !
Try to use .filter() instead of .find(),
var label = results.filter('label');
.find() will search for descendants, but here we are in need to filter out the required element from the collection, so use .filter(selector) here.
And also you could have simply used as satpal said like,
var results= $(e.currentTarget).closest('div.set').find('label.clickable');

Remove multiple elements with same name using removeChild?

I have an element with multiple elements inside. All of the elements inside have the same name. Is there any way to remove them using one function?
(refer to this question for example Remove multiple children from parent?
Here's a solution that removes the first level children with the specified name for the parent with the specified id. If you want to go deeper, you can recursively call it on the child elements you get inside (you'll have to add a parent parameter as well).
function removeChildren (params){
var parentId = params.parentId;
var childName = params.childName;
var childNodes = document.getElementById(parentId).childNodes;
for(var i=childNodes.length-1;i >= 0;i--){
var childNode = childNodes[i];
if(childNode.name == 'foo'){
childNode.parentNode.removeChild(childNode);
}
}
}
And to call it:
removeChildren({parentId:'div1',childName:'foo'});
And a fiddle for testing:
Notes: You can only access the name element dependably in JavaScript when it supported on your element (e.g. NOT on DIVs!). See here for why.
UPDATE:
Here's a solution using className based on our conversation:
function removeChildren (params){
var parentId = params.parentId;
var childName = params.childName;
var childNodesToRemove = document.getElementById(parentId).getElementsByClassName('foo');
for(var i=childNodesToRemove.length-1;i >= 0;i--){
var childNode = childNodesToRemove[i];
childNode.parentNode.removeChild(childNode);
}
}
2021 Answer:
Perhaps there are lots of way to do it, such as Element.replaceChildren().
I would like to show you an effective solution with only one redraw & reflow supporting all ES6+ browsers.
function removeChildren(cssSelector, parentNode){
var elements = parentNode.querySelectorAll(cssSelector);
let fragment = document.createDocumentFragment();
fragment.textContent=' ';
fragment.firstChild.replaceWith(...elements);
}
Usage: removeChildren('.foo',document.body);: remove all elements with className foo in <body>
ok this should be easy. First get the parent element:
var theParent = document.getElementById("notSoHappyFather");
then get an array of the nodes that you want to remove:
var theChildren = theParent.getElementsByName("unluckyChild");
Lastly, remove them with a loop:
for (var i = 0; i < theChildren.length; i++)
{
theParent.removeChild(theChildren[i]);
}
A sample of your HTML would get you a more complete answer, but one can fairly easy call DOM functions to get the list of children and just remove them. In jQuery, remove all children would be something like this:
$("#target > *").remove();
or
$("#target").html("");
And, you can see a demo here: http://jsfiddle.net/jfriend00/ZBYCh/
Or, not using jQuery you could also do:
document.getElementById("target").innerHTML = "";
If you're trying to only remove a subset of the children (and leave others intact), then you need to be more specific how one would determine which children to leave and which to remove. In jQuery, you could use a .find() select or a filter() selector to narrow the list of children to just the children you wanted to target for removal.

JQuery on dynamically creating element and attaching data does not return value when calling data() again using selector?

I create a div element dynamically and associate data() to it. When accessing it again via selector it does not return the data. As result of below snippet I see first alert with data '1' and another with 'null' value. Can someone please help.
var dc = 0;
$("#attachData").click(function () {
dc++;
var newDiv = jQuery('#oldid').clone();
newDiv.attr('id', 'dt'+dc);
jQuery.data(newDiv, "dd", '1')
alert(jQuery.data(newDiv, "dd"));
var divFromSelector = $('#dt'+dc);
alert(jQuery.data(divFromSelector, "dd"));
});
Sorry, I did not add it in the snippet but its attached to the tree:
newDiv.attr('id', 'dt'+dc).
appendTo('#workspace-container');
Also when I try to access it using selector the element is returned correctly - but no data found.
Try:
var dc = 0;
$("#attachData").click(function () {
dc++;
var newDiv = jQuery('#oldid').clone();
newDiv.attr('id', 'dt'+dc).appendTo('#workspace-container');
jQuery.data(newDiv[0], "dd", '1')
alert(jQuery.data(newDiv[0], "dd"));
var divFromSelector = $('#dt'+dc);
alert(jQuery.data(divFromSelector[0], "dd"));
});
From the docs it seems that the JQuery.data method expects a DOM element, not a JQuery object. Appending [0] to a JQuery object gives the DOM element it is wrapping.
It'd probably be better if you used newDiv.data(...) and divFromSelector.data(...).
Demo here.
It looks like you haven't attached the new node in the DOM your accessing. http://api.jquery.com/clone/

Looping over elements in jQuery

I want to loop over the elements of an HTML form, and store the values of the <input> fields in an object. The following code doesn't work, though:
function config() {
$("#frmMain").children().map(function() {
var child = $("this");
if (child.is(":checkbox"))
this[child.attr("name")] = child.attr("checked");
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
return null;
});
Neither does the following (inspired by jobscry's answer):
function config() {
$("#frmMain").children().each(function() {
var child = $("this");
alert(child.length);
if (child.is(":checkbox")) {
this[child.attr("name")] = child.attr("checked");
}
if (child.is(":radio, checked"))
this[child.attr("name")] = child.val();
if (child.is(":text"))
this[child.attr("name")] = child.val();
});
}
The alert always shows that child.length == 0. Manually selecting the elements works:
>>> $("#frmMain").children()
Object length=42
>>> $("#frmMain").children().filter(":checkbox")
Object length=3
Any hints on how to do the loop correctly?
don't think you need quotations on this:
var child = $("this");
try:
var child = $(this);
jQuery has an excellent function for looping through a set of elements: .each()
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Depending on what you need each child for (if you're looking to post it somewhere via AJAX) you can just do...
$("#formID").serialize()
It creates a string for you with all of the values automatically.
As for looping through objects, you can also do this.
$.each($("input, select, textarea"), function(i,v) {
var theTag = v.tagName;
var theElement = $(v);
var theValue = theElement.val();
});
I have used the following before:
var my_form = $('#form-id');
var data = {};
$('input:not([type=checkbox]), input[type=checkbox]:selected, select, textarea', my_form).each(
function() {
var name = $(this).attr('name');
var val = $(this).val();
if (!data.hasOwnProperty(name)) {
data[name] = new Array;
}
data[name].push(val);
}
);
This is just written from memory, so might contain mistakes, but this should make an object called data that contains the values for all your inputs.
Note that you have to deal with checkboxes in a special way, to avoid getting the values of unchecked checkboxes. The same is probably true of radio inputs.
Also note using arrays for storing the values, as for one input name, you might have values from several inputs (checkboxes in particular).
if you want to use the each function, it should look like this:
$('#formId').children().each(
function(){
//access to form element via $(this)
}
);
Just switch out the closing curly bracket for a close paren. Thanks for pointing it out, jobscry, you saved me some time.
for me all these didn't work. What worked for me was something really simple:
$("#formID input[type=text]").each(function() {
alert($(this).val());
});
This is the simplest way to loop through a form accessing only the form elements. Inside the each function you can check and build whatever you want. When building objects note that you will want to declare it outside of the each function.
EDIT
JSFIDDLE
The below will work
$('form[name=formName]').find('input, textarea, select').each(function() {
alert($(this).attr('name'));
});

Categories