Find element from jQuery matching objects - javascript

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');

Related

How to run script two times

I have two the same forms on the same page and script that works only for the first form.
I'm a beginner and this is a challenge for me; I tried add the `for (var i = 0; i < input.length; i++) but it doesn't work out. I will be grateful for any help.
var el = document.querySelector(".js-tac");
input = document.querySelector('.js-tel')
input.addEventListener('input', evt => {
const value = input.value
if (!value) {
el.classList.remove("is-visible");
return
}
const trimmed = value.trim()
if (trimmed) {
el.classList.add("is-visible");
} else {
el.classList.remove("is-visible");
}
})
document.querySelector return the first matched element. So you need document.querySelectorAll which will give a collection. Then iterate that collection like this
document.querySelectorAll('.js-tel').forEach((input)=>{
// not using arrow function since using this to target the element
input.addEventListener('input', function(evt){
const value = this.value
// rest of the code
})
})
The problem is that you are only getting one input element. (querySelector returns the first matching element, not all matching elements). You likely want to use querySelectorAll to get a NodeList (which will contain all matching nodes). You can iterate over those.
Based on how you seem to be using it, I'd recommend making sure your js-tac and js-tel are wrapped in some common parent, and use querySelectorAll to find those. Then, you can use querySelector to find the js-tel and js-tac.
var nodes = document.querySelectorAll('.js-parent')
//If you don't export forEach to be available, you can also just do a standard
//for loop here instead.
nodes.forEach((parent) => {
var el = parent.querySelector(".js-tac");
input = parent.querySelector('.js-tel')
...
})

Find selector in array

I have to find and display a selector from HTML presented in array, this works for me using Jquery:
var a = '';
var b = Array.prototype.map.call($('p', a),
function(e) { return e.outerHTML; });
console.log(b)
However I don't want to use Jquery, Id rather use plain Javascript so I tried:
a.querySelectorAll('p')
Not working. Why is that and what else can I try?
You're using querySelectorAll as if it is available in the String.prototype object because the variable a is an empty string.
Try document.querySelectorAll('p');
I think what you want is this:
var b = Array.prototype.map.call(document.querySelectorAll("p"),
function(e) { return e.outerHTML; });
console.log(b);
This way your calling the query selector on the document rater than on an empty string(where the function won't exist).
Try this:
document.getElementsByTagName("p")
Which will return an array of all <p> tags

jQuery selector: match array attribute's n-th value

I have an attribute for a set of HTML5 objects that is an array. Something like
<button attr=[1,0,0,0,1,1]>test</button>
<button attr=[1,1,0,0,1,1]>test</button>
...
How do I formulate a jQuery selector to match only elements whose n-th value of attr is 1? Something like $("attr[1]=1") that would only select the second button from this example (this syntax does not work, but I wrote it just to give an idea of what I need).
In my case I am not dealing with buttons but with other types of objects, I just wanted so simplify the context of the question.
You can use a custom filter to select only the matched elements.
<button data-attr="[1,0,0,0,1,1]">button 1</button>
<button data-attr="[1,1,0,0,1,1]">button 2</button>
Note that attr is not a valid html attribute for button. I'd suggest you use the data-attr instead. You can use .data('attr') to get the data back.
var selected = $('button').filter(function (idx) {
var attr = $(this).data('attr');
return attr && attr[1] == 1;
});
alert(selected.html());
jsFiddle Demo
You can write your own selector like this (i called it "array", you can use a better name here):
jQuery.expr[':'].array = function (elem, index, match) {
var params = match[3].replace(/^\s+|\s+$/g, '').split(/\s*,\s*/),
attribute = params[0],
arrayindex = parseInt(params[1]),
matchvalue = params[2],
value = JSON.parse($(elem)[attribute](attribute));
return value[arrayindex] == matchvalue;
};
Then, use it like any other selector where the first parameter is the name of the attribute, the second parameter is the index in your array and the third parameter is the expected value:
$('button:array(attr,1,1)');
Fiddle: http://jsfiddle.net/pascalockert/uDnK8/2/

Jquery comparing elements

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]) {

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.

Categories