I have an array of numbers which I need to target on pages like this:
sku = [1243,3453,6453, ..... ]
These values are inside a div on a page like this:
<div id="product_1243">
<div class="block">
test
</div>
</div>
<div id="product_3453">
<div class="block">
test
</div>
</div>
<div id="product_6453">
<div class="block">
test
</div>
</div>
I have created a function to check if a number from the array exists in this div:
sku.forEach(function (element) {
if ($("div[id*='product_item_code_" + element +"']").length) {
alert("this exists" + element);
}
});
This works, but I want to ask two questions:
1) How to use insertAfter below to insert some HTML after each <div class="block">. It should only get inserted if the statement is true of course.
$("<p>test!</p>").insertAfter(....);
2) if this is best for performance because my array is actually much much bigger with over 1000 values to check for in the forEach.
Thanks
Use append or appendTo if block is the only child of product_***
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$("<p>test!</p>").appendTo( $el );
}
or
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$el.append( "<p>test!</p>" )
}
In case block is not the only child
var $el = $("div[id*='product_item_code_" + element +"']");
if ( $el.length) {
alert("this exists" + element);
$("<p>test!</p>").insertAfter( $el.find( ".block" ) );
}
How about this? Store products instead of querying it each time as it affects performance.
const products = $('div[id^=product_item_code]')
products.each((index, element) => {
if(sku.includes(element.id.split('_')[1]))
$('.block', element).after('<p>test!</p>')
})
Related
I have a tree of div elements with the same class but different id as we can see below:
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
I have to check which class exists in each of these divs and show on the console. For this I created the following code:
$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).has('.successResults')){
console.log('The results is success');
}
if($(this).has('.warningResults')){
console.log('The results is warning');
}
if($(this).has('.dangerResults')){
console.log('The results is danger');
}
});
I expected to get the following results like this:
I'm on div: result_0 The results is success
I'm on div: result_1 The results is warning
I'm on div: result_2 The results is danger
But I'm getting the following results:
I'm on div: result_0 The results is success The results is warning The
results is danger
I'm on div: result_1 The results is success The results is warning The
results is danger
I'm on div: result_2 The results is success The results is warning The
results is danger
How I can solve this problem?
One efficiency solution is to use .children method, because you have to check if span children of each div has one certain class.
children method gets the children of each element in the set of matched elements, optionally filtered by a selector.
$( ".resultsAnalitics" ).each(function( ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).children('.successResults').length){
console.log('The results is success');
}
if($(this).children('.warningResults').length){
console.log('The results is warning');
}
if($(this).children('.dangerResults').length){
console.log('The results is danger');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
You were close.
The problem is that the .has() method will still return a jQuery object even if an element isn't selected. As the relevant jQuery documentation states, the .has() method will "reduce the set of matched elements to those that have a descendant that matches the selector or DOM element".
This means that your conditional statements were always true, which is why the message was logged regardless of whether any elements were found.
To check if any elements are returned from the jQuery object, check the .length property of the jQuery object in your conditional statements. In doing so, the value will be 0 when an element isn't found.
Your updated code would be:
$(".resultsAnalitics").each(function(index) {
console.log("I'm on div: " + this.id);
if ($(this).has('.successResults').length) {
console.log('The results is success');
}
if ($(this).has('.warningResults').length) {
console.log('The results is warning');
}
if ($(this).has('.dangerResults').length) {
console.log('The results is danger');
}
});
You could go the other way and target each of the classes specifically and then find the id of the parent container. Notethat I added another success div at the bottom to demonstrate that all success divs give the parent ID and then the warning and then the danger.
$(".successResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is success');
});
$(".warningResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is warning');
});
$(".dangerResults" ).each(function(){
var parent = $(this).parent().attr('id');
console.log("I'm on div: " + parent + ' - The results is danger');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
<div class="resultsAnalitics" id="result_3">
<span class="successResults">Success</span>
</div>
You could use .find() (checking length of search result) and use loop to make it more elegant and elastic for further changes.
http://codepen.io/themeler/pen/mRgKLP
$( ".resultsAnalitics" ).each(function( index ) {
var $this = $(this),
current = $this.attr('id'),
states = [
{
name: '.successResults',
msg: 'The results is success'
},
{
name: '.warningResults',
msg: 'The results is warning'
},
{
name: '.dangerResults',
msg: 'The results is danger'
}
];
for (var i = 0; i < states.length; i++) {
if ($this.find(states[i].name).length) console.log("I'm on div: " + current, states[i].msg)
}
});
// Grabs all classes that end with Results within resultsAnalitics
var results = $(".resultsAnalitics span[class$='Results']");
// loop through each, grabbing parent id and innerHTML
results.each(function(idx, node) {
console.log("I'm on div:", node.parentNode.id, "- Result are:", node.innerHTML);
})
You can always use jQuery "find" method to check out for specific elements in a particular element.It returns jQuery object. Using this object we can further check for number of elements by using 'length'.
<div class="resultsAnalitics" id="result_0">
<span class="successResults">Success</span>
</div>
<div class="resultsAnalitics" id="result_1">
<span class="warningResults">Warning</span>
</div>
<div class="resultsAnalitics" id="result_2">
<span class="dangerResults">Danger</span>
</div>
<script>
$( ".resultsAnalitics" ).each(function( index ) {
var current = $(this).attr('id');
console.log("I'm on div: " + current);
if($(this).find('.successResults').length){
console.log('The results is success');
}
if($(this).find('.warningResults').length){
console.log('The results is warning');
}
if($(this).find('.dangerResults').length){
console.log('The results is danger');
}
});
</script>
I'm trying to create a function where I click a button and I get content from a <div>. After, I need to divide the content. I mean, if this div has 10 children, I need to save 5 children in my var code1 and the other 5 in var code2. My problem is I'm not able to use html() function. My code looks like:
$(".pluscontrol").click(function(){
var id = $(this).attr("id");
var items=$(this).closest("table").parent().next().children('#'+id).children().length;
var middle = items / 2;
var code1="";
$(this).closest("table").parent().next().children('#'+id).html(
function(index,currentcontent){
if (index < middle )
code1 = code1 + currentcontent;
});
if ( $(".modal-body .row .sdiv").attr("id") == 1 )
$(".modal-body .row #1.sdiv").html(code1);
if ( $(".modal-body .row .sdiv").attr("id") == 2 )
$(".modal-body .row #2.sdiv").html("...");
});
As you can see, at first, I get the children lenght but I get all items.
I've checked this reference but it not helps too much
the var items is the number of items
Giving an argument to .html() makes it change the HTML of the selected elements. If you want to get the HTML, just call .html() with no argument.
To get the HTML of all the elements in a collection, use .map() to iterate, then combine them with .join().
var allChildren = $(".parent").children();
var middle = Math.floor(allChildren.length/2);
var code1 = allChildren.slice(0, middle).map(function(index, element) {
return element.innerHTML + " " + index;
}).get().join(' ');
var code2 = allChildren.slice(middle).map(function(index, element) {
return element.innerHTML + " " + (index + middle);
}).get().join(' ');
$("#out1").html(code1);
$("#out2").html(code2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="parent">
<div class="child">Test1</div>
<div class="child">Test2</div>
<div class="child">Test3</div>
<div class="child">Test4</div>
<div class="child">Test5</div>
<div class="child">Test6</div>
<div class="child">Test7</div>
<div class="child">Test8</div>
<div class="child">Test9</div>
<div class="child">Test10</div>
</div>
First group:
<div id="out1"></div>
Second group:
<div id="out2"></div>
You can use querySelectorAll which gives u a collection of child element. It also has a length function which you can call. If you want you can chain a foreach method to it. I have broken it down for clarity.
var children = document.querySelectorAll('.parent > div');
var midPoint = Math.round(children.length / 2);
var firstHalf = Array.prototype.slice.call(children,0,midPoint);
var secondHalf = Array.prototype.slice.call(children,midPoint);
firstHalf.forEach(function(elm){
console.log(elm.innerHTML);
});
<div class="parent">
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
<div class="child"><p>Test1</p></div>
</div>
<div id="table1"></div>
<div id="table2"></div>
<div id="table3"></div>
<div id="table4"></div>
<div id="table5"></div>
...
How to select all elements with "table" and an ID > 4.
Something like this might help you:
var test = /table(\d+)/;
$("[id^='table']").filter(function () {
return parseInt(test.exec(this.id)[1], 10) > 4;
});
It will match all elements starting with 'table' and then filter out those ending with values smaller than or equal to 4.
You can go over each element that the id starts with table [id^='table'] and check if the rest (the number) is bigger than 4
Example here http://jsfiddle.net/fLg00oxq/2/
$("[id^='table']").each(function(){
var id = $(this).attr('id').substr(5); // remove table and leave just the number
if(id > 4 ){
// Your code here
}
});
Edit, Updated
Try
v1 (for numerically ordered id's , i.e.g., table1 -> table2)
$("[id=table4] ~ [id*=table]")
v2 (unordered id's)
$("[id*=table]").not(function() {
// return elements that _don't_ match the selector ,
// `id` cast as `Number` <= 4
return this.id.match(/\d+/)[0] <= 4
})
See
Attribute Equals Selector [name="value"]
Next Siblings Selector (“prev ~ siblings”)
Attribute Contains Selector [name*="value"]
.not()
$("[id*=table]").not(function() {
// return elements that _don't_ match the selector ,
// `id` cast as `Number` <= 4
return this.id.match(/\d+/)[0] <= 4
})
.each(function() {
this.innerText = this.id
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="table10"></div>
<div id="table2"></div>
<div id="table9"></div>
<span></span>
<div id="table6"></div>
<div id="table5"></div>
<div id="table1"></div>
<div id="table7"></div>
<div id="table8"></div>
<div></div><br />
<div id="table3"></div>
<div id="table4"></div>
If your div they ordered will in example:
Edit your HTML :
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
<div class="table"></div>
Scripts
$(document).ready(function() {
$('.table:gt(2)').each(function() {
// Apply your functions for each div ....
});
}
This will do it:
$("div[id^=table]").slice(4);
Basically it selects all the div elements with id starting with "table". After that it removes four first matches and returns all the remaining jQuery objects.
So this has an assumption that there is <div id="table1"> ... <div id="table2"> ... <div id="table[n+1]">.
demo
var $tables = $('[id^=table]').filter(function(){
return +this.id.replace(/\D+/,'') > 4;
});
$tables.hide(); // Use example
the above will get the number out of the selector ID and compare if greater than 4. $tables will now result in a collection of elements returned by the jQuery's filter() method.
.replace(/\D+/,'') will remove all non-numeric (D+) Characters; the unary + will convert the String result to Number and > 4 does the desired.
For a micro-Plugin extension you can go for:
// Retrieve elements from mixed ID str+number
// Returns a collection of elements with ID number greather than the num argument
$.fn.idNumGreaterThan = function(num){
return this.filter(function() {
return +this.id.replace(/\D+/,'') > num;
});
};
$('[id^=table]').idNumGreaterThan(4).hide();
// Also with class selectors (element must have a mixed alphaNumeric ID)
$('.element').idNumGreaterThan(4).hide();
You can try with this code, however i think that there are better ways to do it:
for (var i = 4; i <= 100; i++) {
$('#table'+i)...
};
You Could try the contain selector like so $('div[id~=table]')
Reference http://api.jquery.com/attribute-contains-word-selector/
I'm trying to do a filter that will show or hide <div> regarding the data-type they have in their tags.
Here is my Javascript :
var course_difficulty_level_filter= function(el,level)
{
this.el = el;
this.el.closest('#courses_content').find("div").hide();
if(level != "00"){
this.el.closest('#courses_content').find('div[data-difficulty="'+level+'"]').show();
console.log("show difficulty_level : "+ level);
} else {
this.el.closest('#courses_content').find("div").show();
console.log("show difficulty_level : all");
};
}
$('#course_filter_level1').click(function(){
$(this).click(course_difficulty_level_filter($(this),"1"));
});
And here is my HTML :
<div id="coursefilter">
<div id="coursefilter_content" class="hide">
<div id="coursefilter_content_text">
<div id="course_filter_level_text"><p class="course_filter">Level: </p></div>
</div>
<div id="coursefilter_content_icons">
<div id="course_filter_level">
<div id="course_filter_level1" class="opacityquarter">
<div id="level1_rectangle1"></div>
<div id="level1_rectangle2"></div>
<div id="level1_rectangle3"></div>
<div id="level1_rectangle4"></div>
</div>
</div>
</div>
</div>
</div>
<!--Courses - Course Overviews-->
<div id="courses">
<div id="courses_content" class="hide">
<div class="course_overview_content_even" data-difficulty="1" data-lang="en"></div>
</div>
</div>
I successfully get the console.log => show difficulty_level : 1, so my script is "working", but I think it can't navigate trough the DOM, but I don't find why.
Are you simply looking for:
$('div[data-difficulty="'+level+'"]').show();
$('div[data-difficulty="'+level+'"]').hide();
jQuery has rich support for querying HTML attibutes: http://api.jquery.com/category/selectors/attribute-selectors/
I think this code is the problem:
this.el.closest('#courses_content')
The closest function works back up the parents to find the selector, but #courses_content is not a parent of #course_filter_level1 (the value passed in as el).
Try changing those references to just be:
$('#courses_content')
There should be no need to find this element relative to the passed in element as I hope there is only one div with the id courses_content as ID's are supposed to be unique within the document.
The whole function can be changed to this:
// removed el, so it must be removed from the calling function
var course_difficulty_level_filter= function(level)
{
var coursesContent = $('#courses_content');
coursesContent.find("div").hide();
if(level != "00"){
coursesContent.find('div[data-difficulty="'+level+'"]').show();
console.log("show difficulty_level : "+ level);
} else {
coursesContent.find("div").show();
console.log("show difficulty_level : all");
};
}
I got following markup twice on the page with different id for each .option div and it might be duplicate few more times
<div class="optionsHolder"></div>
<div class="option selected">Select</div>
<div id="option238" class="option">Option1</div>
<div id="option239" class="option">Option2</div>
<div id="option261" class="option">Option3</div>
I am trying to grab all options and place them inside optionsHolder , this works but only for the last optionHolder on the page , this is js
var optionscont = $$('.optionsHolder');
var findoptions = $$('.option');
optionscont.each(function (element){
element.adopt(findoptions);
});
any help would be appreciated. thank you!
This i think does what you want JSFiddle
function GetHolder( option )
{
var holder = option.getPrevious( ".optionsHolder" )
if( holder )
{
holder.adopt( option );
}
}
var findoptions = $$('.option');
Array.each( findoptions, function( item) { GetHolder( item ) } );