Hide element if it has an attribute value within an array - javascript

What I'm trying to achieve is hiding specific divs if it's specified attribute matches a value within an array.
The information being used will be dynamic and the divs that need to hide may change. Therefore it has to be extensible.
What I have so far is grabbing the attributes and putting them into an array. Then I'm matching what was put into that array against another array that specifies what divs will need to hide. If a divs attribute matches hide that div otherwise let the div render.
Right now I'm getting an all or none on hiding the divs.
Here is the code
var matching = ['2', '3'];
var mids = [];
$('.merch-tile').each(function(i, e) {
mids.push($(e).attr('m_mid'));
});
//alert(mids);
for (var c1 = 0; c1 < mids.length; c1++) {
//alert('running');
var nm_arg = matching[c1];
//alert('still running');
if ($.inArray(nm_arg, mids) === -1)
$('.merch-tile').hide();
alert('something matches');
}
$(document.body).append(mids);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="merch-tile" m_mid="1">Tile 1</div>
<div class="merch-tile" m_mid="2">Tile 2</div>
<div class="merch-tile" m_mid="3">Tile 3</div>

You can
var matching = ['2', '3'];
$('.merch-tile').filter(function (i, e) {
return matching.indexOf($(this).attr('m_mid')) > -1
}).hide();
var matching = ['2', '3'];
$('.merch-tile').filter(function (i, e) {
return matching.indexOf($(this).attr('m_mid')) > -1
}).hide();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="merch-tile" m_mid="1">Tile 1</div>
<div class="merch-tile" m_mid="2">Tile 2</div>
<div class="merch-tile" m_mid="3">Tile 3</div>

There's no need for the mids array. Just loop over the DOM elements, testing if the attribute is in the array.
I also don't understand $(document.body).append(mids) at the end -- mids is not HTML, it's an array.
I've also replaced your custom attribute with data-mid. data-XXX attributes are reserved for the programmer to use as extensions.
If you want to hide the DIVs that are in the array, you should test != -1, not == -1.
var matching = ['2', '3'];
var something_matches = false;
$('.merch-tile').each(function() {
if ($.inArray($(this).attr('data-mid'), matching) != -1) {
$(this).hide();
something_matches = true;
}
});
if (something_matches) {
alert('something matches');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div class="merch-tile" data-mid="1">Tile 1</div>
<div class="merch-tile" data-mid="2">Tile 2</div>
<div class="merch-tile" data-mid="3">Tile 3</div>
Beware of using .data('mid') instead of .attr('data-mid'). .data() returns the value as an integer, because an attribute value that's valid JSON is parsed as JSON, but matching contains strings.

Look at your code :
if ($.inArray(nm_arg, mids) === -1)
$('.merch-tile').hide(); // Look at here,you hide all, because of your have class name
alert('something matches');

Related

Find parent which contains specific CSS property

I need to find the closest parent that contains the following css property:
background-image: url(*here goes a link to a valid image*);
Finding it could probably be done via selecting all elements, filtering them in an array, then using the first/last element of the array, but I'd like to know if there's a faster way to select the closest parent that fulfills the requirement I mentioned before, like this:
<parent1 style="background-image:url(http://google.com/images/photo.png);">
<parent2 style="background-image:url('http://google.com/images/photo.png');">
<mydiv></mydiv>
</parent2>
</parent1>
I want the parent2 selected;
Keep in mind that I do not know the background url.
You can extend the jQuery selector to allow for this. And with your specific rules.
Something like this:
$.extend($.expr[':'], {
backgroundValid: function(a) {
//change the url for what you want
return $(a).css('background-image') === "url(http://stacksnippets.net/validurl)";
}
});
var test = $('.foo').closest('div:backgroundValid');
console.log(test) //prints bar
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="background-image:url('validurl');">
<div class="bar" style="background-image:url('validurl');">
<div class="foo"></div>
</div>
</div>
There is no need to filter all parents, just make it recursive like this jsfiddle
html
<div id="parent1" style="background-image:url(validurl);">
<div id="parent2" style="background-image:url(validurl);">
<div id="start"></div>
</div>
</div>
javascript
$(function() {
var cssKey = "background-image";
var element = $('#start');
var found = false;
while (!found) {
element = element.parent();
found = element.css(cssKey) == 'none' ? false : true;
if (element.is($('html'))) break;
}
if (found) {
console.log(element.attr('id'));
} else {
console.log('Not found');
}
});
Probably this can help you,
select the element
pick up all its parent
filter its parent by what you want!
var firstParent, URL_TO_MATCH = "url(HELLO WORLD)";
$('#foo').parents().filter(function() {
var isValid = $(this).css('background-image') == URL_TO_MATCH;
if(!firstParent && isValid) {
firstParent = $(this);
}
return isValid;
});

Remove subsequent duplicate elements by class

Via javascript or jquery, I am in need of removing duplicate elements in sets so that one remains. They're all the same, so it doesn't matter which are removed so long as one remains. The page appears as follows:
<div class="column-hr"></div>
<div class="column-hr"></div>
<div class="column-dude"></div>
<div class="column-hr"></div>
<div class="column-hr"></div>
<div class="column-dude"></div>
<div class="column-hr"></div>
One <div class="column-hr"></div> before every <div class="column-dude"></div> needs to stay, but every subsequent hr column before every dude column needs to go.
I tried the following, hoping it would be this simple. Didn't work.
$( "div.column-hr" ).each(function( index ) {
if ($(this).next('div.column.hr')) {
$(this).remove();
}
});
You can achieve this with sibling selector +. Very easy and also the fastest solution, since the browser's CSS engine will be used to select elements:
$(".column-hr + .column-hr").remove();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="column-hr">hr</div>
<div class="column-hr">hr</div>
<div class="column-dude">dude</div>
<div class="column-hr">hr</div>
<div class="column-hr">hr</div>
<div class="column-dude">dude</div>
<div class="column-hr">hr</div>
How it works: CSS selector .column-hr + .column-hr selects .column-hr elements that have immediate previous sibling .column-hr. As the result this expression will select all adjacent .column-hr elements except the very first one, because the first one doesn't have another .column-hr right before it.
You can try this:
$( ".column-hr" ).each(function() {
console.log($(this).html());
console.log($(this).next().attr('class'));
if ($(this).next().attr('class') == 'column-hr') {
$(this).remove();
}
});
https://jsfiddle.net/aodnw5ns/
var classesToRemove = ['column-hr', 'column-dude'];
var $elements;
for (var i = 0, l = classesToRemove.length; i < l; i++) {
// Find elements
$elements = $('.' + classesToRemove[i]);
var elementsLength = $elements.length;
// If there is more than one element
if (elementsLength > 1) {
// get all elements except the first
$elements = $elements.slice(1, elementsLength);
// remove them
$elements.remove();
}
}
// prevent memory leaks
$elements = null;
JSFiddle

swap 2 div's index using pure javascript

I have a parent div and it has 9 same div's am trying to swap two div's index. Following is my code:
HTML:
<div id="cont" class="container">
<div class="no">1</div>
<div class="no">2</div>
<div class="no">3</div>
<div class="blank"></div>
<div class="no">4</div>
<div class="no">5</div>
<div class="no">6</div>
<div class="no">7</div>
<div class="no">8</div>
</div>
now I want to swap say 5th and 6th indexed elements. I have no clue how to do that in JavaScript. I know there is function called .index() but how to do that in pure JS.
Here's one implementation: http://jsfiddle.net/x8hWj/2/
function swap(idx1, idx2) {
var container = document.getElementById('cont');
// ditch text nodes and the like
var children = Array.prototype.filter.call(
container.childNodes,
function(node) {
return node.nodeType === 1;
}
);
// get references to the relevant children
var el1 = children[idx1];
var el2 = children[idx2];
var el2next = children[idx2 + 1];
// put the second element before the first
container.insertBefore(el2, el1);
// now put the first element where the second used to be
if (el2next) container.insertBefore(el1, el2next);
else container.appendChild(el1);
}
This starts by getting a list of all element child nodes, then uses insertBefore to rearrange them.

problems getting element position in array

UPDATED WITH THE CORRECT FIDDLE LINK
I have the following example: http://jsfiddle.net/gespinha/kRUym/52/
Every time you click an element of the array it logs to the console its position in the array and the position of the next element. What I'm trying to do is that when I click on the last element I want it to identify that the next element is actually the first (looping the array).
But when when I click on the last element it doesn't set the arrayPos variable (the number of the position in the array: articles) to zero (the first position in the array, it just continues to number 6, even though I have stated in the if argument that if it is bigger than the length of the array it should become zero.
Why is this happening?
Any suggestions?
HTML
<div class="item">index 0</div>
<div class="item">index 1</div>
<div class="item">index 2</div>
<div class="item">index 3</div>
<div class="item">index 4</div>
<div class="item">index 5</div>
JQUERY
var articles = [];
$('.item').each(function(){
var obj = $(this);
articles.push(obj);
});
for (var i = 0; i < articles.length; i++) {
$(articles[i]).data("index", i)
}
$('.item').on("click", function() {
var id = $(this).data("index");
console.log('NOW: '+id);
if(id < articles.length){
id++
} else {
id = 0;
}
console.log('NEXT: '+id);
});
How can I make this work?
I believe it's a 1 off issue...try
if (id < articles.length - 1)
You can simply use the jQuery index():
$('.item').click(function(){
alert( $(this).index() );
});
This will alert the index starting from 0.
This requires the items to be in a seperate div, the index is the index relative to the parent.
LIVE DEMO
$(function(){
var articles = [];
$('article').each(function(){
articles.push( this );
});
$(articles).click(function(){
console.log( $(this).index() );
});
});
Note that this way you'll just collect the indexable articles (every children will always be index 0). You can push the JS this element into a collection of elements and than on click reference their original index value by wrapping the JS elements into a jQuery Object Elements collection $(articles).

Calculate the number of html element with js

I have multiple div elements with same id='mydiv'.I want to calculate these divs and Iam using the code
document.getElementById('mydiv').length
But it is not working
What you should do is use class instead of ID's. ID is for one element only, class is for multiple.
http://jsfiddle.net/d7AHV/
It won't work as getElementById will always return an element with the specified ID and null if the specified ID doesn't exist
From ECMA
getElementById(elementId) This method returns a Element. The elementId
parameter is of type DOMString.
What you can do is to assign each div with class
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>
<div class="mydiv"></div>​​​​​​​​​
And iterate over:
var divs = document.getElementsByTagName('div');
var count = 0;
for(var i = 0; i < divs.length; i++) {
if(divs[i].className == 'mydiv') count++;
}
alert(count);
If your clients support document.getElementsByClassName(), it's even more concise:
alert(document.getElementsByClassName('mydiv').length)
You've been told about multiple elements with the same ID, but in rare cases it might be unavoidable (e.g. an XML document over which you have no control). The only adverse behaviour is that selecting by ID will usually only return the first one (but that's not guaranteed).
You can count elements with the same id by looping over all the elements in the document and counting the ones with a matching id, e.g.
function countSameIds(id) {
var allNodes = document.getElementsByTagName('*');
for (var i=allNodes.length, count=0; i; ) {
if (allNodes[--i].id == id) {
++count;
}
}
return count;
}

Categories