I want to check if this element has a matching data attribute value to all other elements, but the loop doesn't always work.
Stripped down code below.
HTML
<div class="list">
<div class="target" data-post-id="1"></div>
<div class="target" data-post-id="2"></div>
<div class="target" data-post-id="1"></div>
<div class="target" data-post-id="1"></div>
</div>
JS (event is tied to the target class):
if ($(this).data("post-id") == $(this).closest('.list').find('.target').data("post-id")) {
// do stuff
}
Clearly, I don't know how to loop through it properly. What's the solution?
You could probably use a one-liner:
if ($(this).closest('.list').find('.target[data-post-id=' + $(this).data("post-id") + ']').not(this).length > 0) {
// there was at least one other element in the list with the same data-post-id as the clicked element
}
I have an answer in pure javascript. Try this,
var divs = document.getElementsByClassName('list')[0].children;
function divClick(element) {
Array.from(divs).forEach(div => {
if(element != div) {
if (element.dataset.postId == div.dataset.postId) {
console.log("equal");
} else {
console.log("not equal");
}
}
});
}
<div class="list">
<div class="target" onclick="divClick(this)" data-post-id="1">One</div>
<div class="target" onclick="divClick(this)" data-post-id="2">Two</div>
<div class="target" onclick="divClick(this)" data-post-id="1">Three</div>
<div class="target" onclick="divClick(this)" data-post-id="1">Four</div>
</div>
.siblings() in jquery will be helpful in this case,
$(document).ready(function(){
$('.target').click(function(){
$.each($(this).siblings(), (div, element) => {
if($(element).data("post-id") == $(this).data("post-id")) {
console.log("Equal");
} else {
console.log("Not Equal");
}
})
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list">
<div class="target" data-post-id="1">One</div>
<div class="target" data-post-id="2">Two</div>
<div class="target" data-post-id="1">Three</div>
<div class="target" data-post-id="1">Four</div>
</div>
Do you need something like this?
var arr1 = [];
var arr2 = [];
$(".target").each(function(){
arr1.push($(this).data("post-id"));
});
$(".target").each(function(index){
var newArray = arr1.slice();
newArray.splice(index, 1); // remove index value from an array, so this index != match its own
console.log(newArray);
if ($.inArray($(this).data("post-id"), newArray ) !== -1){
$(this).text("Has A Match!");
}else{
$(this).text("No Match!");
}
});
Jsfiddle Here : https://jsfiddle.net/synz/votuqyp0/1/
This should work for you:
HTML
<div class="list">
<div class="not-a-sibling">
<div class="target" data-post-id="1"></div>
</div>
<div class="target" data-post-id="2"></div>
<div class="not-a-target">I'M NOT A TARGET, LEAVE ME ALONE!</div>
<div class="target" data-post-id="1"></div>
<div class="target" data-post-id="1"></div>
<div class="target" data-post-id="3"></div>
<div class="target" data-post-id="3"></div>
</div>
Assuming you're basing this on click event – obviously, change this to hover or whatever's relevant.
JS (More verbose example)
$(document).on('click', '.target', function() {
var clickedTarget = $(this);
var clickedTargetPostId = clickedTarget.data('post-id');
var elementsToCompare = clickedTarget.parents('.list').find('.target').not(this);
elementsToCompare.each(function() {
var elementToComparePostId = $(this).data('post-id');
if (elementToComparePostId === clickedTargetPostId) {
alert('Found a match!');
}
});
});
Test it out here:
https://jsfiddle.net/5wv40vq9/4/
JS (Less verbose)
$(document).on('click', '.target', function() {
var _this = this;
$(_this).parents('.list').find('.target').not(this).each(function() {
if ($(this).data('post-id') === $(_this).data('post-id')) {
alert('Found a match!');
}
});
});
https://jsfiddle.net/5wv40vq9/5/
Related
I would like the .box elements to show/hide based on the words the user searches for, so for example if a user types in 'Title2 Title1' because those words exists inside box one and two they will remain visible with the renaming .box elements hiding. All the text within the .box elements needs to be searchable not just that in the .title element.
Below is how far I've got. It's almost there but it's not quite working as hoped.
Any help would be great.
Many thanks.
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
<script>
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')')) {
$(this).show();
} else {
$(this).hide();
}
});
});
} else {
$(".box").show();
}
});
</script>
You need to use a different search method. :contains does not work as you expect. Consider the following example.
$(function() {
function filter(e) {
var term = $(e.target).val();
if (term.length < 3) {
$(".box").show();
return;
}
$(".box").each(function(i, el) {
if ($(".content", el).text().indexOf(term) >= 0) {
$(el).show();
} else {
$(el).hide();
}
});
}
$("#search").keyup(filter);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">Box title one content</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">Box title two content</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">Box title three content</div>
</div>
So for example if on is entered, no filtering is performed. If one is entered, the script will look inside the content class of each box and if one is found in the text, it will be shown otherwise, it is hidden. If the User clears their search out, all items are shown.
Hide all box before iterate, then only show when match any words:
$("#search").on("input", function () {
var search = $(this).val();
if (search !== "") {
var searchArray = search.split(" ");
// Hide all .box
$(".box").each(function () {
$(this).hide();
})
searchArray.forEach(function(searchWord) {
$(".box").each(function () {
if($(this).is(':contains('+ searchWord +')') ) {
$(this).show();
}
});
});
} else {
$(".box").show();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input placeholder="Search" id="search" type="text" />
<div class="box">
<div class="title">Box Title1</div>
<div class="content">
Box title one content
</div>
</div>
<div class="box">
<div class="title">Box Title2</div>
<div class="content">
Box title two content
</div>
</div>
<div class="box">
<div class="title">Box Title3</div>
<div class="content">
Box title three content
</div>
</div>
Loop through all .boxs and using regex pattern matching, check either the title or content matches the search query. Show all matched boxes and hide all others
I have also fiddled it here
$("#search").on("input", function () {
var searchables=$('.box');
console.log(searchables)
var query=$(this).val();
searchables.each(function(i,item){
var title=$(item).find('.title').text();
var content=$(item).find('.content').text();
var rgx=new RegExp(query,'gi');
if(rgx.test(title) || rgx.test(content))
{
$(item).show();
}
else
{
$(item).hide();
}
})
})
This question already has answers here:
How can I assign a unique ID to all div's that have a specific class using JQuery
(4 answers)
Closed 3 years ago.
I was wondering if there's simple JS/JQuery to change the div ids inside the container from 'one' to unique ids (like 'one_1', 'one_2', 'one_3')
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
Desired Output
<div id="container">
<div id="one_1">ONE</div>
<div id="one_2">ONE</div>
<div id="one_3">ONE</div>
</div>
I've gotten so far as to extract the three divs, but now need to replace the text:
document.getElementById("container").querySelectorAll("#one")
You could just loop over the container's children and update their IDs:
var children = document.getElementById('container').children;
for (var i = 0; i < children.length; i++) {
var child = children[i];
child.id = child.id + "_" + (i + 1);
}
You may use the version of .attr() which takes a function as its second parameter:
jQuery(($) => {
$('#container > div').attr('id', (index, id) => `${id}_${index + 1}`);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
Or, if you can't use ES6+ Javascript:
jQuery(function ($) {
$('#container > div').attr('id', function (index, id) {
return id + '_' + (index + 1);
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
jQuery solution:
$("#container div").each(function( index ) {
this.id = this.id+"_"+(index+1);
});
Single line (thanks to Andreas's comment)
$("#container div").attr("id", (index, oldId) => oldId + "_" + (index + 1))
$(".changer").on("click",function(){
var i = 1;
$("#container").children().each(function(){
var id = this.id;
$(this).attr("id",(id + "_" + i));
i++;
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
<div id="one">ONE</div>
<div id="one">ONE</div>
<div id="one">ONE</div>
</div>
<button class="changer">
Change IDs
</button>
i need to change class of current element, in loop but with different timing.
in this case it happen just once :/
any suggestions thx ??
<div class="wrapper">
<div class="wrapper-item wrapper-item--0 current" data-time="2500">
<div class="item"></div>
</div>
<div class="wrapper-item wrapper-item--1" data-time="5000">
<div class="item"></div>
</div>
<div class="wrapper-item wrapper-item--0" data-time="7000">
<div class="item"></div>
</div>
<div class="wrapper-item wrapper-item--0" data-time="9000">
<div class="item"></div>
</div>
</div>
function myFunction() {
var current = $('.wrapper').children(".current")
var timeOfVisible = $('.wrapper').children(".current").data("time");
setInterval(function() {
current.removeClass("current").next().addClass("current");
if ((current.next()) > $('.wrapper').children().length) {
alert(current)
}
}, timeOfVisible);
}
myFunction()
First of all, you will need setTimeout instead of Interval, because you will run one delay per element. Second - you need to call your function recursively for this to repeat in a loop.
Here is working js for you:
function changeClass() {
var current = $('.wrapper .wrapper-item.current');
if(current.length > 0) {
var timeOfVisible = current.data("time");
setTimeout(function(){
current.removeClass('current');
if (current.next().length > 0)
current.next().addClass('current');
else
$('.wrapper .wrapper-item').first().addClass('current');
changeClass();
}, timeOfVisible);
}
};
changeClass();
Codepen example here.
Also, if you don't want infinite loop, use this instead:
function changeClass() {
var current = $('.wrapper .wrapper-item.current');
if(current.length > 0) {
var timeOfVisible = current.data("time");
setTimeout(function(){
current.removeClass('current');
if (current.next().length > 0) {
current.next().addClass('current');
changeClass();
}
}, timeOfVisible);
}
};
changeClass();
If you want to chain the function then you need to add the main function loop to the callback of the setInterval.
simply done this is:
function myFunction() {
var current = $('.wrapper').children(".current")
var timeOfVisible = $('.wrapper').children(".current").data("time");
setInterval(function() {
current.removeClass("current").next().addClass("current");
if ((current.next()) > $('.wrapper').children().length) {
alert(current)
}
myFunction();
}, timeOfVisible);
}
All I have done is moved the function call myFunction() to inside the callback.
You can solve by calling the function TWO times insted of just one.. & call it recursively i.e. within itself
You can check the console....
here is a working snippet
$(document).ready(function(){
function myFunction() {
var current = $('.wrapper').children(".current");
var timeOfVisible = $('.wrapper').children(".current").data("time");
setInterval(function() {
current.removeClass("current").next().addClass("current");
console.log($(current))
if ((current.next()) > $('.wrapper').children().length) {
alert(current)
}
myFunction()
}, timeOfVisible);
}
myFunction();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div class="wrapper-item wrapper-item--0 current" data-time="2500">
<div class="item">0</div>
</div>
<div class="wrapper-item wrapper-item--1" data-time="5000">
<div class="item">1</div>
</div>
<div class="wrapper-item wrapper-item--0" data-time="7000">
<div class="item">2</div>
</div>
<div class="wrapper-item wrapper-item--0" data-time="9000">
<div class="item">3</div>
</div>
</div>
My situation is the following: I have several classes with names obj1, obj2, ob3 and an output object. When one of obj# is clicked, i want a corresponding text to be added in output object. Here is my code:
<div class="obj obj1">Object 1</div>
<div class="obj obj2">Object 2</div>
<div class="obj obj3">Object 3</div>
<div class="output"></div>
And JavaScript:
function whichObject($obj) {
for (i = 0; i < 3; i++) {
switch($obj.hasClass("obj" + (i+1).toString())) {
case "obj1":
$(".output").text("Object 1");
break;
case "obj2":
$(".output").text("Object 2");
break;
case "obj3":
$(".output").text("Object 3");
break;
}
}
$(".obj").on("click", function () {
whichObject($(this));
});
I need the loop because the number of obj# objects may increase over time and I cannot predict a certain amount of obj# objects.
I'm surely missing something or the whole approach is wrong.
$('.obj').on('click', function(e){
$('.output').text(e.target.innerHTML);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="obj obj1">Object 1</div>
<div class="obj obj2">Object 2</div>
<div class="obj obj3">Object 3</div>
<div class="output"></div>
So, if somebody is interested I solved it this way:
function whichObject(obj) {
var $obj = $(obj);
if ($obj.attr("id") === "obj1") {
$(".output").text("Object 1");
} else if ($obj.attr("id") === "obj2") {
$(".output").text("Object 2");
} else if ($obj.attr("id") === "obj3") {
$(".output").text("Object 3");
}
}
$(".obj").on("click", function () {
whichObject(this);
});
while adding the following IDs to my HTML:
<div class="obj" id="obj1">Object 1</div>
<div class="obj" id="obj2">Object 2</div>
<div class="obj" id="obj3">Object 3</div>
<div class="output"></div>
So I make this little kind of game. There are 7 switches that trigger other buttons on click to toggleClass 'on' which is defined in jQuery.
The Goal is to get all buttons to the state 'on'.
The problem is, you can easily right-click, choose Inspect Element, add the class 'on' and win the game.
So I need to make the classes for these switches random. E.g. 'on-214124712', 'on-307153821369' or 'on-6471649031264'. But they have to share the same prefix which is 'on-'.
How can I generate them differently with every click? And how can I still toggleClass and check hasClass them using regex?
HTML:
<h2>You clicked <span id="output">0</span> times</h2>
<div class="switches">
<div id="switch1" class="switch"></div>
<div id="switch2" class="switch on"></div>
<div id="switch3" class="switch on"></div>
<div id="switch4" class="switch"></div>
<div id="switch5" class="switch on"></div>
<div id="switch6" class="switch on"></div>
<div id="switch7" class="switch"></div>
</div>
Javascript:
var count = 0;
$('.switch').click(function () {
$('#output').html(function (i, val) {
return val * 1 + 1
});
});
$("#switch1").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch5').toggleClass("on");
$('#switch6').toggleClass("on");
count++;
});
$("#switch2").bind("click", function () {
$(this).toggleClass("on");
$('#switch1').toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch7').toggleClass("on");
count++;
});
$("#switch3").bind("click", function () {
$(this).toggleClass("on");
$('#switch2').toggleClass("on");
$('#switch5').toggleClass("on");
count++;
});
$("#switch4").bind("click", function () {
$(this).toggleClass("on");
//$('#switch1').toggleClass("on");
$('#switch2').toggleClass("on");
$('#switch5').toggleClass("on");
count++;
});
$("#switch5").bind("click", function () {
$(this).toggleClass("on");
$('#switch1').toggleClass("on");
$('#switch4').toggleClass("on");
count++;
});
$("#switch6").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch5').toggleClass("on");
$('#switch7').toggleClass("on");
count++;
});
$("#switch7").bind("click", function () {
$(this).toggleClass("on");
$('#switch3').toggleClass("on");
$('#switch4').toggleClass("on");
count++;
});
$('.switches').click(function () {
if ($("#switch1").hasClass("on") && $("#switch2").hasClass("on") && $("#switch3").hasClass("on") && $("#switch4").hasClass("on") && $("#switch5").hasClass("on") && $("#switch6").hasClass("on") && $("#switch7").hasClass("on")) {
alert('Success!');
}
});
Thanks!
UPDATE
You can use this selector that checks if the element has a class that contains the desired string (check the updated demo):
$('.switch[class*=on-]').addClass('red');
Each div that has a class that contains on will get red
$('.switch[class*=on-]').addClass('red');
.red { color:red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="switches">
<div id="switch1" class="switch">test</div>
<div id="switch2" class="switch on-9876597856978">test</div>
<div id="switch3" class="switch on-jhg675">test</div>
<div id="switch4" class="switch">test</div>
<div id="switch5" class="switch on-876uyg">test</div>
<div id="switch6" class="switch on-kjhg76gt9">test</div>
<div id="switch7" class="switch">test</div>
</div>