jQuery XOR selector - javascript

From a set of divs I want to select all the divs that contain a specific attribute and then select all the divs that do not contain any of the attributes.
Example:
<div data-attr="1"></div>
<div data-attr="2"></div>
<div data-attr="3"></div>
<div data-attr="4"></div>
<div data-attr="5"></div>
var attrList = [3,4];
// I want to process every div containing attr 3 and 4
attrList.forEach(function(item){
var div = $("[data-attr='"+item+"']");
div.operation_here()
});
// but I also want to process the remaining divs that do not contain neither attr 3 and 4
/* HELP ME HERE - this would select divs with attr 1, 2 and 5 */
How to achieve this?

Make it steps by steps. First, select all div:
var $div = $('div[data-attr]');
Then, select those you need:
var $valid_div = $div.filter(function(){
return attrList.indexOf($(this).data('attr')) > -1;
});
Now you can do your operation on matching div with your variable:
$valid_div.operation_here();
To select remaining div, you can use .not():
var $invalid_div = $div.not($valid_div);
$invalid_div.operation_here();

var $divs = $('div').filter(function() {
// returns all divs with data-attr not equal 1 or 2 or 5
return [1, 2, 5].indexOf(this.data('attr')) == -1;
});
HTML:
<div data-attr="2">not matched</div>
<div data-attr="5">not matched</div>
<div data-attr="6">matched</div>

Given a list of elements, you can use jQuery.not to exclude those elements from another selector
$(function(){
// I want to process every div containing attr 3 and 4
var divs = $('div[data-attr="3"], div[data-attr="4"]');
console.log(divs); // logs 2
var notDivs = $('div[data-attr]').not(divs);
console.log(notDivs); // logs the other 3
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div data-attr="1"></div>
<div data-attr="2"></div>
<div data-attr="3"></div>
<div data-attr="4"></div>
<div data-attr="5"></div>

Related

jQuery: select elements with slice

in a page i've got different divs elements with the same class
<div id="masterdiv">
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div class="a"></div>
<div>
with a setTimeout i want to take three elements for time do some action with them.
i tried with the slice function:
var elements = $("#masterdiv").find('.a');
var t = setInterval(function () {
var currentElements = elements.slice(points.f, points.l);
/* where points.f = 0 and points.l = 3 */
/* do something with currentElements then increment points.f and points.l +1 */
}, xinterval );
But there's a problem, at a certain time my code will reach a .slice(8,10) / .slice(9,11) and a in a selection of 11 divs.
So in these cases (point.l > elements.length()) i want select the first divs instead of the exceeded ones:
In the case of .slice(8,10) i want to select instead of the
inexistent div '10' the div 0 with the 8,9 divs .
In the case of .slice(9,11) i want to select instead of the
inexistent divs '10','11' the div 0,1 with the 9 div.
How can i accomplish this? Can i do it with slice or should i use another function?
Thanks in advance for all the help.
An alternative, would be to use the pop() and push() array functions like this:
var $elements = $("#masterdiv").find('.a');
// Convert to native Array
var elements = Array.prototype.slice.apply($elements);
var t = setInterval(function () {
elements.slice(points.f,points.l).forEach(function(el){
// do something on the element...
$(el).addClass('debug');
});
elements.push(elements.shift()); // Re-arrange elements array for loop
}, xinterval );
Here's the codepen demo: http://codepen.io/kostasx/pen/mRVzqQ?editors=0010
you can increment your variable like this,
var elements = $("#masterdiv").find('.a');
/* where points.f = 0 and points.l = 3 */
var t = setInterval(function () {
var currentElements;
if(points.l > elements.length && points.f<=elements.length){
tempArr1 = elements.slice(points.f);
tempVar = points.l % elements.length;
tempArr2 = elements.slice(0,tempVar);
currentElements = [...tempArr1,...tempArr2];
}
else{
currentElements = elements.slice(points.f, points.l);
}
/* do something with currentElements then increment points.f and points.l +1 */
}, xinterval );
I have not covered edge cases,please find yourself ;)

How to get index, position number of element with certain class with jQuery

I have this markup
<div class="parent">
<div class="one"></div>
<div class="two"></div>
<div class="one"></div>
<div class="two"></div>
</div>
My question is: how to get "index" number of element with class two. I'm not asking of regular index number of element in parent div. I need to know that when i'm clicking at first element with class one that next two element have 0 index or it's first element in this list with class two, and so on.
I've tried with index() method and eq() and always i have the real index number of this element in parent div. I hope this is clear, thx for help.
You need to find the elements index in collection of element with sameclass:
$('.parent > div').click(function(){
var index;
if($(this).is('.one'))
index = $('.parent > .one').index(this);
else
index = $('.parent > .two').index(this);
});
This should be the faster way to get the index you are looking for.
Instead of retrieving all matches, it just counts the number of elements of the same class among previous leafs in your DOM.
Also, it allows having multiple <div class="parent"> and still work
$('.parent div').click(function() {
// Retrieve clicked element class (one, two)
var elClass = $(this).attr('class');
// Retrieve all previous elements that have the same class
// and count them
var prevElmts = $(this).prevAll('.' + elClass),
numPrevElements = prevElmts.length;
console.log(numPrevElements);
})
Using jquery you can find index of element which have same class name or tag name
$(".class_name").on("event_name", function() {
var index=($(this).index());
console.log('index : ',index);
});
This may work for you.
var p = $('.parent'),
current = p.filter('.two'),
index = p.index(current);

Finding text length within a divs children

So i have an array of divs. each div contains three span elements. Each span element can contain any number of digits.
This is what i have so far:
var arrayOfDivs = $(".avgMaxClass");
$.each(arrayOfDivs, function (index, value) {
});
what i want to do is calculate the total length of all the text within all the spans within the div im iterating through. I can't figure it how to do that.
EDIT:
To be clear i don't want the total text length of all the divs. I want the text length of the current div that im iterating through
$(".avgMaxClass span").text().length;
JSFiddle demo
Edit:
As you stated in your comment that you want to know the length for each DIV, here is another way using jQuery.each():
var avgMaxClass = $('.avgMaxClass');
$.each(avgMaxClass, function(i,item) {
// Output span text length for each item
console.log($("span", item).text().length);
});
JSFiddle demo
Just iterate over the div and find its length.
$(".avgMaxClass").each(function(){
var thisDivsLength = $(this).find('span').text().length;
alert("Current div's length: " + thisDivsLength);
});
$.each is for non-jQuery objects. Use $.fn.each instead.
DEMO
You can use a selector to get the divs and spans at the same time, or to split the logic and show both parts individually, you can use two selectors and loop over the results of each.
var total = 0;
$(".avgMaxClass").each(function(index, value) {
$(value).find("span").each(function(cindex, child) {
total += $(child).text().length;
});
});
$("#result").text("Total length: " + total);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="avgMaxClass">
<span>1</span>
<span>12</span>
<span>123</span>
</div>
<div class="avgMaxClass">
<span>1234</span>
<pre>12345</pre>
<span>12345</span>
</div>
<div class="avgMaxClass">
<span>123456</span>
<span>1234567</span>
<span>12345678</span>
</div>
<div id="result"></div>

How to find element of div from another div

I have the elements in the div as mentioned below:
<div id="container">
<div id="first_div">
<div id="comment-1" class="comment">Child 1 of first div</div>
<div id="comment-2" class="comment">Child 2 of first div</div>
<div id="comment-3" class="comment">Child 3 of first div</div>
<div id="comment-4" class="comment">Child 4 of first div</div>
</div>
<div id="second_div">
<div id="comment-5" class="comment">Child 1 of second div</div>
<div id="comment-6" class="comment">Child 2 of second div</div>
<div id="comment-7" class="comment">Child 3 of second div</div>
<div id="comment-8" class="comment">Child 4 of second div</div>
</div>
<div id="third_div">
<div id="comment-9" class="comment">Child 1 of third div</div>
<div id="comment-10" class="comment">Child 2 of third div</div>
<div id="comment-11" class="comment">Child 3 of third div</div>
<div id="comment-12" class="comment">Child 4 of third div</div>
</div>
I need to retrieve the next element from comment id comment-4.
$('#comment-4').next().attr('id') gives me result as undefined.I need the target div to be comment id - comment-5.How to retrieve the next element of div from another div using jquery?
Try this :
$(function(){
$('.comment').click(function(index){
var id;
if ( $(this).is(':last-child') )
id = $(this).parent().next().children(':first').attr('id');
else
id = $(this).next().attr('id');
alert(id);
});
});
Demo
Demo : http://jsfiddle.net/abdennour/PU54r/
function nextOf(id,cyclic){
var ids= $('div[id^=comment-]').toArray().map(function(e){return $(e).attr('id')}).sort();
var idx=ids.indexOf("comment-"+id);
if(idx!==-1){
if(ids.length> idx+1){
return $('div#'+ids[idx]);
}
else{
// it is the last div: if it is cyclic ,you may return the first
if(cyclic){
return $('div#'+ids[0]);
}
}
}else{
// no div with this id
}
}
Then :
var target=nextOf(4)
if(target){
target.html()
//--> Child 1 of second div
}
I think you can use $('.comment') to pick up all of your wanted, and save them in some variable such as var arrResult = $('.comment');.
So far, you can choose what you wanted use the arrResult variable.
Because your inner-most divs have different parents, I would first get all the divs you care about:
var comments = $('.comment');
Next, if we can assume your id's are all numbered sequentially, get the number in the id (assuming this references the element):
var index = parseInt($(this).attr('id').substr(8));
Now, the next div in the comment list is at that position in the comments:
var nextDiv = comments[index];
Just for good measure, I'd first make sure index is set:
var nextDiv;
if (index < comments.length) {
nextDiv = comments[index];
}
You could use an index in your case :
JS:
for (var index = 0; index <= 12; ++index) {
$("#comment-" + index).attr("id");
}
You can define a statement which checks the target id is the last child, than you can return a function according to value.
jsFiddle Demo
var target = 'comment-4';
$('.comment').each(function(i) {
if ( $(this).attr('id') == target ) {
if ( $(this).is(':last-child') ) {
$(this).parent().next().children().first().addClass('red');
}else{
$(this).next().addClass('red');
}
}
});
Here is one way - http://jsfiddle.net/jayblanchard/WLeSr/
$('a').click(function() {
var highlight = $('.highlight');
var currentIndex = $('.comment').index(highlight); // get the index of the currently highlighted item
$('.comment').removeClass('highlight');
var nextIndex = currentIndex + 1;
$('.comment').eq(nextIndex).addClass('highlight');
});
It is showing undefined because comment-4 and comment-5 are childrens of different parent elements. Means comment-4 is children of first_div and second_div parent of comment-5.
You can get the comment-5 using below code.
$('#comment-4').parent().next().children().attr('id');
Assuming jQuery-wrapped element is collected in $comment, there's one way to solve it:
function getNextComment($comment) {
var $nextComment = $comment.next();
if ($nextComment.length) {
return $nextComment;
}
var $nextParent = $comment.parent().next();
if ($nextParent.length) {
return $nextParent.children().first();
}
return null;
}
Demo. Click on one comment - and see the next one's highlighted. )
The base algorithm's very simple here. First, we attempt to retrieve the next sibling of the given element. If there's one, it's returned immediately. If not (and it's the case with #comment-4 in your question - it's the last element in its hierarchy), we go up the DOM chain for its parent (#first-div, in this case), and look for its next sibling (#second-div). If it exists, then its very first child element is returned. If it doesn't, null is returned (we can actually return an empty jQuery object - $(), but that depends on use cases.
Just one instruction : )
$('<div id="mock" />').append($('.comment').clone()).find('#comment-4').next().attr('id')//---> comment-5
Based on divs have the same Css class .comment
DEMO
Why not this will be undefined: $('#comment-4').next().attr('id') because there is no next element. as you mentioned that you want to target the #comment-5 in the next div's child then you can do this:
function giveId(el) {
var sel = el.id ? '#'+el.id : '.'+el.className;
var id = $(sel).next('div').length ? $(sel).next('div').attr('id') : $(sel).parent('div').next('div').find('> div:first').attr('id');
return id || "Either no next elem exist or next elem doesnot have any id/class.";
}
$(function () {
$('div').click(function (e) {
e.stopPropagation();
alert(giveId(this));
});
});
Updated Demo in action
Try this: JSFiddle (The easiest solution!)
$(document).ready(function(){
var currDiv = $("#comment-4"); // Try with different valies: "#comment-x"
currDivId = currDiv.prop('id');
lastDivId = currDiv.parent('div').find('.comment').last().prop('id');
if(currDivId == lastDivId){
var nextComment = currDiv.parent('div').next('div').find('.comment').prop('id');
}else{
var nextComment = currDiv.parent('div').find('.comment').next().prop('id');
}
alert(nextComment);
});

jQuery/JavaScript - Counting child elements in multiple parent elements

I'm creating a directory of apps, each of which has it's own comments which are hidden until the user opens them. I'd like to show the number of comments that each app currently contains but I can only get it display the total number of comments on the page (See JSFiddle: http://jsfiddle.net/9M4nw/2/ for a basic example). Ideally it should display 2 in the top box and 4 in the bottom box. I thought I might need to use an array or something along those lines?
Here is my code:
HTML
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
jQuery
$(".parent").each(function(index){
var numChilds = $(".child").length;
$(".parent").append(numChilds);
});
You have to select the current HTML element (with class parent). Then, you will use it in selecting the length of elements with class .child and the html for .counter.
Using $(this) you can select the current HTML element from each() function.
Corrected code:
$(".parent").each(function(){
var numChilds = $(".child", $(this)).length;
$(".counter", $(this)).html(numChilds);
});
JSFIDDLE
The problem is you need to limit the scope of the element look up to the desired parent element
$(".parent").each(function(index){
var numChilds = $(".child", this).length;
$(".counter", this).html(numChilds);
});
Another version
$(".parent").each(function(index){
var $this = $(this);
var numChilds = $this.find(".child").length;
$this.find(".counter").html(numChilds);
});
Demo: Fiddle
This would require some extra work to show the number of childs in a more elegan way, but it should be enough to understand the idea
$(".parent").each(function(index){
var $this = $(this);
var numChilds = $this.find(".child").length;
$this.append("<span>" + numChilds + "</span>");
});
This code will help you to get number of children separately for each parent div :-
$(document).ready(function () {
$(".parent").each(function (i) {
$(this).children().length;
});
});
Try this hope this may help you.Vote

Categories

Resources