Check each div for id based upon values within an array - javascript

I'm creating a set of tabs based upon an existing set of categories with the below JS. I need to extend this to target specific id's within the DIV id based upon values from a JS array.
$("#categories div[id^=category]:not(:first)", this).hide();
var cats = $('#categories div[id^=category]');
cats.each(function () {
var anch = $(this).find('h3 a').eq(1).clone();
anch[0].rel = this.id;
$('<li/>').append(anch).appendTo('#tabs');
});
The html:
<div id="category_1">
<h3 class="maintitle">
<a class="toggle">..</a>
Cat 1 Title
</h3>
<div>
...
</div>
</div>
<div id="category_2">
<h3 class="maintitle">
<a class="toggle">..</a>
Cat 2 Title
</h3>
<div>
...
</div>
</div>
I've got a JS array ready by adding:
var catsList = '{$cats}'; // comma separated list of numbers generated in PHP - returns 1,4,8 currently.
var catsArray = catsList.split(',');
How would I convert the below, to check for each item within catsArray ?
var cats = $('#categories div[id^=category]');
Something like
var cats = $('#categories div[id^=category_'+catsArray+']');
but obviously checking each item within the array and not the entire array as that's doing.

You could use that as IDs have to be unique on context page:
var cats = $('#category_'+catsArray.join(',#category_'));
DEMO

you probably want the each function
$.each(catsArray,function(index, item) {
var cats = $('#categories div[id^=category_'+item+']');
});
Depending on how you using this a for loop will do it also:
for (var i = 0; i < catsArray.length; i++) {
var catIndex = catsArray[i];
var cats = $('#categories div[id^=category_'+catIndex +']');
}

Related

Find the index of an element in an array created by toArray in JS/JQuery

I have a bunch of spans of class = "change" and each has a unique id. I created an array of those spans using:
var changesArray = $('.change').toArray()
I want to be able to get the index of the span in the array when I click on it. I tried:
$('.change').click(function(){
var thisChange = $(this).attr('id');
var thisChangeIndex = $.inArray(thisChange,changesArray);
});
But all I get is -1 for every .change I click on.
I'm a bit of a newbie with this type of code. Help?
The toArray method says
Retrieve all the elements contained in the jQuery set, as an array.
You are looking for a particular id in the array - that will never work.
If you want the index of the item you can use .index()
$('.change').click(function(){
var thisChangeIndex = $('.change').index(this);
console.log(thisChangeIndex);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<span class="change">change1</span>
<span class="change">change2</span>
<span class="change">change3</span>
<span class="change">change4</span>
</div>
<div>
<span class="change">change5</span>
<span class="change">change6</span>
<span class="change">change7</span>
<span class="change">change8</span>
</div>
You should keep a plain array of the unique ID's only:
var changesArrayIds = $('.change').toArray().map(function(x) { return x.id; });
Then this line should work fine:
var thisChangeIndex = $.inArray(thisChange, changesArrayIds);
If you insist on using .toArray that works http://codepen.io/8odoros/pen/JKWxqz
var changesArray = $('.change').toArray();
$('.change').click(function(){
var thisChange = $(this).attr('id');
var thisChangeIndex = -1;
$.each( changesArray, function( i, val ) {
if( thisChange==val.id) thisChangeIndex= i;
});
console.log(thisChangeIndex);
});
When you call toArray, you get an array of all the DOM nodes, not the jquery objects. You can search on this instead of $(this):
var changesArray = $('.change').click(function(){
var thisChangeIndex = $.inArray(this,changesArray);
}).toArray();

How to iterate through all div and get specific property?

what I'm trying to do is iterate over a collection of div, contained in a parent container. My structure is the following:
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>
My goal is take the field data-id of each div and create an array collection. Previously I used the select where do I get each value of available option, like this:
var available_services = $('#selected-service').find('option', this).map(function ()
{
return this.value;
}).get();
But now I'm using a div collection instead of the select. How I can iterate through all available div?
This should return all data-id values in a list:
var available_services = $('#main').find('div').map(function (item)
{
return item.attr('data-id');
});
I didn't test this, but I think should do the job. (maybe you need to tweak a little bit)
I believe this will do it:
var available_services = [];
$('#main div').each(function(){
available_services.push($(this).data( "id" ));
})
This is the easy way to go:
$(document).ready(function() {
var myCollection = [];
$('#main div').each(function(){
var dataDiv = $(this).attr('data-id');
myCollection.push(dataDiv)
})
});
Try this:
(function(){
var main = $("#main");
var divs = $(main).find("div");
var arrId = divs.map(function(index, div){
return $(div).attr("data-id");
});
console.log(arrId);
})()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='main'>
<div data-id='2'>
</div>
<div data-id='3'>
</div>
</div>

How to remove element from array

I have little problem with my code. I push the value of an input in an empty array, and i display the value in a html list with a remove button.
But when i remove the value in html, the array still holds the value. I used arr.splice(0, 1) but it doesn't remove the specific value. Example:
My html list looks like:
v1
v2
v3
My array after the list is filled:
array = [v1, v2, v3]
When i remove v2 in html my array doesn't changes. I'm new to JavaScript.
My code in JSBin or JSFiddle.
im sorry my english is not very nice
https://jsfiddle.net/15mdjdpa/
var taches = [];
var saisie;
var ecran;
var liste;
var organiz;
var j= 0;
function run(){
saisie= document.getElementById('champ').value;
taches.push(saisie);
ecran = document.getElementById('afficheur');
var liste = document.getElementById('listes');
console.log("taches :", taches);
var li = document.createElement('li');
li.setAttribute("id", "lisupr");
var btn = document.createElement('Button');
btn.textContent="X";
btn.addEventListener("click",function supr (){
liste.removeChild(li);
taches.splice(0,1);
console.log("tableau taches: "+ taches);
} );
li.innerText= saisie + " "+" ";
console.log("saisie "+saisie);
li.appendChild(btn);
liste.appendChild(li);
}
<input type ="text" id="champ" onfocus="javascript:this.value=''" class="form-control ">
<button type="button" onclick ="run()" class="btn btn-primary" >send</button>
<div id="afficheur"><h4> list : </h4>
<ul id="listes"> </ul>
</div>
If you want to remove v2 from array, do like this.
var index = array.indexOf(v2);
if(index != -1) array.splice(index,1);
I'd rewrite this code using jQuery. I'd remove all the ids - you can make the edits relative to the button being clicked. Which would let you have more than one of these on a page, among other things.
HTML:
<div class="module">
<input class="item" />
<button type="button" class="btn btn-primary js-add">add</button>
<ul class="list"></ul>
</div>
Here's the script:
var list = [],
addToList = function(target,item){
list.push(item);
target
.append(
$('<li>')
.html(item)
.append(
$('<button>')
.addClass('js-delete m-l')
.html('X')
)
)
}
$('.js-add').click( function(){
var parent = $(this).parent(),
item = parent.find('input.item');
addToList(parent.find('ul.list'),item.val());
item.val('');
})
$('.module').on( 'click', '.js-delete', function(){
var parent = $(this).parent(),
index = $('li').index( parent );
list.splice(index,1);
parent.remove();
console.log(list);
})
Actually, if you want to make it so you can add multiple lists, you actually need to nest the 'list' array in an object or array, and have something reference it, probably inside the module div.
Your issue is what Angular does automatically - without all the management. It binds the html content to the json array so all you need to do is change the array value, or delete it. The HTML would immediately reflect the change.
Here's a jsfiddle:
https://jsfiddle.net/mckinleymedia/yducyt83/

Javascript Pushing Objects to Array

I'm unable to push objects to an array and i can't figure out why. At the moment, the result (records) repeats the last instance of the each loop.
JSFiddle
HTML
<div data-provider="prv1"></div>
<div data-rating="rtn1"></div>
<div data-price="prc1"></div>
<div data-provider="prv2"></div>
<div data-rating="rtn2"></div>
<div data-price="prc2"></div>
<div data-provider="prv3"></div>
<div data-rating="rtn3"></div>
<div data-price="prc3"></div>
<div data-provider="prv4"></div>
<div data-rating="rtn4"></div>
<div data-price="prc4"></div>
Javascript (w/ jQuery)
(function(){
var sort = $(".sort select");
var provider = $("[data-provider]");
var rating = $("[data-rating]");
var price = $("[data-price]");
var records = [];
var record = {};
$(provider).each(function(index, value){
record.provider = $(provider).eq(index).data("provider");
record.rating = $(rating).eq(index).data("rating");
record.price = $(price).eq(index).data("price");
records[index] = record;
});
})();
In your loop you set each index to be equal to record. Since the scope of record is the anonymous function, it will be the same object for each index.
What you want is for the scope to be the function provided to .each
Like this fiddle
$(provider).each(function(index, value){
var record = {};
...
});

Count sibling elements that all have same unknown class name

I need help working with a large list of sibling elements with different class names.
Getting the amount of elements with the same class name and putting them in an array
Finding first element in that class group (this can be number or name).
Statement that runs a function: if element = first element of group do console.log("first element");
Here's an example of the first 3 classes but this will go from groupA to Groupz
<div class = 'slider'>
<div class = 'item1 groupA'> <!-- Start Group A -->
<img src='xyz' />
</div>
<div class = 'item1 groupA'>
<img src='xyz' />
</div>
<div class = 'item1 groupA'>
<img src='xyz' />
</div>
<div class = 'item1 groupA'>
<img src='xyz' />
</div>
<div class = 'item1 groupB'> <!-- Start Group B -->
<img src='xyz' />
</div>
<div class = 'item1 groupB'>
<img src='xyz' />
</div>
<div class = 'item1 groupB'>
<img src='xyz' />
</div>
<div class = 'item1 groupC'> <!-- Start Group C -->
<img src='xyz' />
</div>
<div class = 'item1 groupC'>
<img src='xyz' />
</div> <!-- All the way to group Z -->
</div>
Edit: Your requirement is very specific. Below is just a sample to just loop thru all childrens and store the count and first element in the matching count. Let me
$(function () {
$.fn.benton = function () {
//just the immediate childrens
var $chds = $(this).children();
var lc = {
firstEl: {},
classCount: {}
};
$.each ($chds, function (idx, el) {
if (el.className) {
var tokens = el.className.split(' ');
for (var i = 0; i < tokens.length; i++) {
if (lc.classCount.hasOwnProperty(tokens[i])) {
lc.classCount[tokens[i]] += 1;
} else {
lc.classCount[tokens[i]] = 1;
lc.firstEl[tokens[i]] = $(el);
}
}
}
});
return lc;
};
var stats = $('.slider').benton();
console.log(stats.classCount['groupA']);
stats.firstEl['item1'].css({border: '1px solid red', width: 100, height: 10});
});
DEMO: http://jsfiddle.net/LhwQ4/1/
I think what you need is to use context of slider to get the child elements.. see below,
var $slider = $('.slider')
Now using the $slider context,
$('.groupA', $slider)
//Returns Array of jQuery object with elements has class `groupA`
$('.groupA:first', $slider)
//Returns first element in collection of element with class `groupA`
To get all elements with the same class name, you would only have to use a simple jQuery selector. The returned value is an array containing all matching elements.
var groupA = $(".groupA");
To get the number of items you need only access the length parameter of the array.
var groupALength = groupA.length;
If you want to extract only the first element of any matched elements, you can use jQuery's :first selector.
var firstElement = $(".groupA:first");
var groups = {};
$(".slider").children().each(function(i, el) {
var classes = el.className.split(/\s+/);
for (var i=0; i<classes.length; i++)
if (classes[i] in groups)
groups[classes[i]].push(el);
else
groups[classes[i]] = [el];
});
Now, you can access all elements of a group via groups["groupA"] etc (jQuery collection: $(groups["groupB"])) and the first one via groups["groupC"][0]. The amount of elements in a group is just the length of the array.
Notice that this puts all elements in the group "item1" - I don't know what you need that class for.
Ok, so this solution is quite sensitive. I'm making a few assumptions about your HTML.
In your example you gave each item a class of item1. I am assuming that this is just an issue of copying and pasting the element. Each "item" should have the same class so that you can retrieve all the items with one selector. For my example, I'm assuming a class of item.
There should be only this item class plus an additional "group" class. Any other class given to the item will render this solution invalid.
// fetch ALL items
var allItems = $(".item");
// initialize groups array
var groups = {};
$.each(allItems,function(index,elem){
var item = $(this);
var itemClass = item.attr('class');
// remove the "item" class and any leftover whitespace
itemClass = $.trim(itemClass.replace('item','')); // should now be groupA/groupB...
// add item to array at the index of the group
if (groups[itemClass] == undefined){
groups[itemClass] = [];
}
groups[itemClass].push(item);
});
You should now be left with an array of arrays containing all the items. To see this in action, you can check out this jsFiddle.

Categories