I have a grid of cards, right now clicking one of the cards adds an overlay to all of them.
I need:
1.- If user clicks one cards, and only that card gets the overlay.
2.- No more than 3 cards at a time can have an overlay. User would have to click one of the already clicked cards to diselect it, in order to select another one.
Codepen:
https://codepen.io/ogonzales/pen/yLJGzYr
JS Code:
$('.imageDiv').click(function(){
$('img').toggleClass("tricky_image");
$(".text").toggleClass("display-inline");
});
Expected result:
Try this instead. Make use of this so that the relevant scope is preserved.
$('.imageDiv').click(function(){
$(this).find('img').toggleClass("tricky_image");
/*$(".text").css("display", "inline");*/
$(this).find(".text").toggleClass("display-inline");
});
You could equally (maybe) use the .children() method (as opposed to .find()) but I didn't know exactly how your dom structure was inside each "imageDiv".
Your specified click function search for every 'img' element and every node with a .text class.
What you actually want, is to get the child img element and .text of the clicked .imageDiv
By limiting the queried scope with $(this).find(...) we only search for child elements of the clicked .imageDiv.
With some additional logic your second requirement can be also fulfilled ->
$('.imageDiv').click(function(){
const trickyCount = $(".tricky_image").length;
const img = $(this).find('img');
const text = $(this).find(".text");
if(trickyCount < 3 || img.hasClass("tricky_image")){
img.toggleClass("tricky_image");
text.toggleClass("display-inline");
}
});
Related
Above I have three banner elements that I want to mark as unread if they are clicked. I structured each banner so that they have a span element within a nested div as shown with the image below (the red dot comes from the span element):
My javascript for this function is the following code:
I am trying to add a class ".read-dot" to the ".dot" span element that will hide it. I would like to add this class to the ".dot" span element that is inside the div that the user would click on. Any help would be appreciated.
I tried accessing the this.$(".dot) to access the dot element of the current object that triggered the event, but I now see this syntax is incorrect. I am new to jQuery which is why I tried this; I also could not find the page most relevant to my question on the API doc.
First, you have to remove click accessibility for the child.
$('div.banner > *').css('pointer-events', 'none');
And then, you can use the jquery selector for the .unread class to remove the class and replace .dot with .read-dot
$('.unread').click((e) => {
let clickedElm = e.target;
clickedElm.classList.remove('unread');
clickedElm.querySelector('span').classList.remove('dot');
clickedElm.querySelector('span').classList.add('read-dot');
})
I am working with jira and there are two buttons with the same id and class. Both are submit button, one at top and one below and when i use the below jquery only the first one is captured while clicking. Intention is to make comments testfield mandatory.
Only the top one is working..
<script>
AJS.toInit(function () {
AJS.$("#next").click(function(e){
var comment=AJS.$("#jira #page #content .aui-page-panel .aui-page-panel-inner .aui-page-panel-content #bulkedit .form-body .aui .comment-input #comment").val();
if(comment==""){
AJS.$(".bulk-affects").append("<br/><div id='resErrror' style='color:red;margin-left:30px'>Comment is mandatory</div>");
return false;
}
});
});
</script>
Please help me out with to capture both the next button to work for this script
ID's should be unique, so you should only use a particular ID once on a page. Actually when you try to call the element using id code only calls the first element. Classes may be used repeatedly
querySelectorAll will find all ID's
const allButtons = document.querySelectorAll('#next');
for (let button of allButtons) {
$(button).click((e) => {
// Do your magic here
})
}
Remember: A webpage element has certain inalienable rights; having a unique ID is one of them. Prevent html element identity theft by ensuring that every element on your webpage that needs an ID has a unique one.
But Classes can be repeated.
So, say, I have 5 html elements that are hidden via class that has a display:none property.
Then there's a button which removes that class on one of these elements with every click (5 clicks results into all 5 elements being visible).
And then all of these 5 elements have "their own button" that adds back this class with display:none when clicked.
Now, I want some other element to get invisible when all of these elements are invisible as well. And then, when at least one of them is visible (doesn't have display:none), I want this other element to be visible as well.
To complete the task, I was trying to use the MutationObserver.
let my_observer = new MutationObserver(function(mutations) {...}
elements_nodelist.forEach((my_element) => {
observer.observe(my_element, {attributes: true, attributeFilter: ["class"]});
})
But unfortunatelly, it reacts to just any class changes, it doesn't only watch the visibility state, or only this particular class changes. yes, I can get a mutation.oldValue information and get to the element.classList, but I can't figure out the way to use it to solve all this.
You can check if all your hidden elements have the hidden class:
const myHiddenElements = [...document.querySelectorAll('.my-hidden-element')];
const isAnyVisible = myHiddenElements.filter( elm => elm.classList.contains('hidden-class') ).length < myHiddenElements.length;
if( isAnyVisible ) {
// Do what you want
}
in my website, I want to append a div below to a class, I have a lot of same class. The website is selling T-shirt, each item has the .color class. Each time, when I refresh the page, it only append to one item, when I go to the second item, the div won't append. #myshop is loading from other site, so that's why I need to use append to add the message. The reason I use setTimeout because #myshop is be load after the page load, so I have to delay it. You can check it out on my url, www.sayhitoworld.com, click any item, you will see the message below the color, go back, and click another item, the message won't append any more. Appreciate your time.
jQuery('#myshop').one('click', function(){
setTimeout(append_color, 1000);
});
function append_color(){
jQuery('.color').append("<div id='append_color' >Note: If the T-shirt had the same color as the character's hair or body, you won't see the shape, still cool though.</div>");
}
Are the items on the same page? If so this div will only append to the first item because of the div has an ID. ID's need to be unique so only one div called append_color can exist per page. Why not append a class called append_color and see if that works for you.
function append_color(){
$('.color').each(function(){
$(this).append("<div class='append_color' >Note: If the T-shirt had the same color as the character's hair or body, you won't see the shape, still cool though.</div>");
});
}
try:
$('.color').each(function(i, obj) {
$(obj).append(<your_template>);
});
Try switching to the on method, instead of one (if possible), that is why the function only fires once. From the docs:
.one( events [, data ], handler ):
Attach a handler to an event for the elements. The handler is executed
at most once per element per event type.
Try something like this instead:
jQuery(document).on('click', '#myshop', function(){
setTimeout(append_color, 1000);
});
function append_color(){
jQuery('.color').append("<div id='append_color' >Note: If the T-shirt had the same color as the character's hair or body, you won't see the shape, still cool though.</div>");
}
Thank you in advance for looking at this.
My webapp allows a user to select choices from four different drop-down menus. When the user makes a selection, the program successfully performs the following click() function which creates a new span element within a div element:
var activeFilterNames = [];
$('.filter').click(function()
{
if (!this.classList.contains('disabled'))
{
//above checks to see if link has already been clicked
//and is therefore disabled. If not, go ahead.
activeFilterNames.push(this.textContent);
//above adds name of selected link to array
i = activeFilterNames.length;
var newFilter = document.createElement('span');
newFilter.id = activeFilterNames[i-1];
newFilter.className = this.className+" activated";
//above adds a new class to identify the filter as 'activated'
//above retains existing classname to identify
//which of the four filters it came from
newFilter.innerHTML = activeFilterNames[i-1];
//above creates display text to be rendered in browser
document.getElementById('active_filters').appendChild(newFilter);
//above is the div in which span will be appended to other spans.
$("#active_filters > span").removeClass('filter');
//above removes .filter class so that this newly created span does
//not respond to the .filter click() function.
$(this).addClass('disabled');
//above adds 'disabled' class to the originally
//clicked link, causing it to skip this block of code
}
}
);
Everything appears to work fine up to this point (though I may be missing something). Essentially I am creating span elements that come out looking like this in html:
<span id="id_name" class="menu_name activated">Rendered Name</span>
And since the above span does not have the filter class, I then try to create a new function in javascript (just as a test) to make the element responsive:
$('.activated').click(function()
{
alert('hi');
}
);
But no luck. I've tried to re-render the dynamically created elements by nesting div or a inside the span, modifying the code as needed, but still nothing. I would like to keep the span because it's the only way I've found to wrap these dynamically generated elements to a second line within the div (#active_filters) where they are being created.
Can anyone see what I'm doing wrong given that I want to make the activated click() function responsive within each newly created span element?
Your binding will not work if you attempt to bind to DOM elements contained in $('.activated') before creating them. What this usually means is that you need that event listener to bind after creating. If you're dynamically creating DOM elements, you need to do something like this:
var activeFilterNames = [];
$('.filter').click(function()
{
if (!this.classList.contains('disabled'))
{
activeFilterNames.push(this.textContent);
i = activeFilterNames.length;
var newFilter = document.createElement('span');
newFilter.id = activeFilterNames[i-1];
newFilter.className = this.className+" activated";
newFilter.innerHTML = activeFilterNames[i-1];
document.getElementById('active_filters').appendChild(newFilter);
$('.activated').unbind('click');
$('.activated').click(function()
{
alert('hi');
}
);
$("#active_filters > span").removeClass('filter');
$(this).addClass('disabled');
}
}
);
Notice, before binding we unbind. This makes sure that if you do this multiple times, you aren't binding 2, 3, 4 times to the same DOM element.
You need to attach click event on dynamically created elements. In jQuery this can be done using on method if you will pass your selector as second argument and attach click to some parent element, body for example:
$( 'body' ).on( 'click', '.activated', function()
{
alert('hi');
}
);