How to temporarily block selectable elements - javascript

I am working on a popup menu on my webpage. The menu contains various selectable items, and I would like to only allow selection of certain items after a top-selection has been made. Now I could hide all items lower-down, but that would make the popup look weird. I'd rather show them, but dimmed. My idea was to enclose the follow-up selections in a div, and have that div act as a blocker. Now the question is how to do it - I tried setting the z-index of the selBlocker div higher than the rest, also to give it absolute positioning, but didn't get anywhere yet. I am using a javascript library to handle the selections in general.
<div id="SelPopup" >
<div id="topSelect"></div>
<div id="selBlocker">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
</div>

I would append a class to the items you dont want to select, and add the not() selector to your jQuery.
For example:
$("div:not('.selected').....
Instead of
$("div").....
Ofcourse you can add an opacity to the class .selected, to make it a little bit less visible.

You can try below:
Instead of using id for selection blocked element use class="selectBlocked" and for menu div use class="selectMenu"
<div id="SelPopup" >
<div id="topSelect" class="selectMenu"></div>
<div id="selBlocker1" class="selectMenu selectBlocked">
<div id="selectable2"></div>
<div id="selectable3"></div>
</div>
<div id="selBlocker4" class="selectMenu selectBlocked">
<div id="selectable5"></div>
<div id="selectable6"></div>
</div>
</div>
Now right jQuery for handling selection of menu and do nothing if selected menu is with class="selectBlocked"
$('.selectMenu').click(function(){
if($(this).hasClass("selectBlocked"))
return false;
// do your stuff if above condition fails
});

Thank you all for the suggestions, I actually found what I was looking for:
$("#selBlocker").css("pointer-events", "none");
This will nicely disable all interaction, and with
$("#selBlocker").css("pointer-events", "all");
I can restore it. Can add the change in opacity easily alongside it.

Related

each loop should only run once when button is clicked

I want to hide a div when a button is clicked and then show the next div with the same class. I have tried using this code, but when I do this, the next div that I want shown also fades out.
$('.arrow:last-of-type').on('click', function(){
$( ".collaboration" ).each(function( index ) {
if($('.collaboration').css('display') == 'block'){
$(this).fadeOut()
$(this).next().fadeIn()
}
})
})
Is there a way to stop the each() from running when it is executed once and then run again when the click action happens?
Here's the HTML:
<div id="collaborations">
<p class="arrow"><</p>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<div class="collaboration">
<img src="./img/test.png" />
<p>Text</p>
<button>Visit</button>
</div>
<p class="arrow">></p>
</div>
</div>
Thanks
Solution
You could solve this by not iterating through the .collaborations at all.
The key thing is that you need to keep track of which one is currently being shown.
If you know that, then what your click handler can do is show the next one and hide the current one.
I would suggest doing that with a class .active on the same div as .collaboration. You can then select the next div by $('.active').next().addClass('.active'), and deselect by $('.active').removeClass('.active').
You might need to store a reference to your first element before you select the next one 👍
Example
Here's a quick example of how this might work: https://codepen.io/juancaicedo/pen/LYGgPWa
I moved around the html to group all the collaborations into a div by themselves.
Other approaches
You'll find that you have to think through some other behaviors with the solution above. For example, in my example, there is a moment when two items are on the screen, causing their container div to grow and later shrink.
For these reasons, I don't like handling presentation from within javascript (i.e. using jquery's fadeIn/fadeOut).
If you can find a way to instead using only css, I think that's preferable. Here's an example using css transitions
https://codepen.io/juancaicedo/pen/ZEQqzrR
The each method of jQuery can be stopped whenever you want by returning false inside of the callback, so you can probably fix your code by doing this:
$('.arrow:last-of-type').on('click', function(){
$( ".collaboration" ).each(function( index ) {
if($('.collaboration').css('display') == 'block'){
$(this).fadeOut()
$(this).next().fadeIn()
return false;
}
});
});

How can I select all the divs inside a section tag using javascript?

I'm making a turn-based game in javascript. I want to move the player from div to div. I have put all those divs in a section and then into an array using queryselectorall. Now my problem is that I also have another divs who I want to use and I can't select them separately. Can anyone tell me how to select only some divs? I have seen something like section>div to differentiate them, but that doesn't work for me.
I have tried replacing div with span on rollDice, zar1, and zar2, but by doing that some CSS breaks.
~
<div class="rollDice">Roll the dice</div>
<div class="zar1">
<img src="poze/dice-5.png" alt="Dice" class="dice" id="dice-1" style="width:150px">
</div>
<div class="zar2">
<img src="poze/dice-5.png" alt="Dice" class="dice2" id="dice-2" style="width:150px">
</div>
<section class="mutari">
<div class="nr1 mutabil"><h1>1</h1></div>
<div class="nr2 mutabil"><h1>2</h1></div>
<div class="nr3 mutabil"><h1>3</h1></div>
</section>
~
I want to select the div only from the section. And after that I want to select the first 3 divs.
What you are looking for is:
document.querySelectorAll('section > div:nth-child(-n+3)')
section (a type selector) finds your <section>. If you had more section elements, you could use section.mutari to be more precise (using a class selector).
> div selects all the <div> tags that are direct children of that section. > is a child combinator.
:nth-child(-n+3), a pseudo-class, restricts this to only select the first three elements, not all of them. It is not needed in your example, as you only have three divs; but if you had more, this would give you only the first three.
With document.body.childNodes
Just replace document.body with your HTML Element.
You can filter after that through the list you get an select all divs.
If you want to get all divs you can also use following:
var dh = document.body.getElementsByTagName('div');
Get all div nodes:
Use document.body.getElementsByTagName('div')
Or
Get filtered div nodes:
Take array from document.body.childNodes.
filter by using for loop and if condition.
Condition Example: use like node[i].nodeName and node[i].id

jQuery code is hiding all content inside my div

I have the following code:
jQuery(document).ready(function($) {
$("ul.accordion-section-content li[id*='layers-builder'] button.add-new-widget").click(function() {
$("#available-widgets-list div:not([id*='layers-widget'])").css('display','none');
});
});
The idea is, when i click a button that contains the class "layers-builder", all divs in "available-widgets-list" that DO NOT contain the class "layers-widget" are hidden.
The problem I'm facing is that using this code also hides all the divs inside "layers-widget" (as not all of them have "layers-widget" in the id.
for example, here is a mockup markup:
<div id="some-id">
...
</div>
<div id="this-layers-widget-89">
<div id="hello"></div>
<div id="yes"></div>
</div>
In the above example, the first div "some-id" would be hidden, along with all the child divs inside "this-layers-widget-89"
How can I make it so that all the content within the div containing "layers-widget" still shows?
The ">" operator specifies that the div must be a direct child of #available-widgets-list:
$("#available-widgets-list > div:not([id*='layers-widget'])").css('display','none');
You should add a class instead of relying on finding parts of some-id but this will work also work: $('[id*="some-id"]');
You should also be using jquery's built in hide()method instead of css('display', 'none'). They do literally the exact same thing but using the built in methods is more readable.

understanding jQuery parent, children and sibling

I am struggling to figure out where I am going with the current show and hide function I am trying to incorporate on my site. I have a drop down menu show and hide function similar to the one currently implemented at Hippodrome Mobile Casino. Which is identical to my HTML. My div class I am noticing with my Jquery when i click the next button .regNext it hides all three .regGroupContent divs. However i want to add and remove the active class which i current have as display:none on my site.
$('.regGroupContent').removeClass('active');
$('.regGroupContent').eq(0).addClass('active');
$('.regNext').click(function () {
var $this = $(this);
$('.regGroupContent').hide().removeClass('active');
$this.parent().children($('.regGroupContent')).show().addClass('active');
});
Html
<div class="vengeForm">
<div class="regGroupContent">
<div class ="fieldset">
<ul class="fieldset">
<li class="editor-next">
</li>
</ul>
</div>
</div>
</div>
This line has a bit of a syntax issue:
$this.parent().children($('.regGroupContent')).show().addClass('active');
In the children selector, you don't need a jQuery object, rather just the class name. Also, your .parent() selector is only going one level up, you need to get to the top of the element tree. Try changing it to:
$this.parents('.vengeForm').children('.regGroupContent').show().addClass('active');

Get value of text inside span

I am working with Flexigrid plugin with JQuery. Ok so I have a div with two span elements, they would contain the text/display text for the buttons that flexigrid provides. The problem is, there is no mechanism to add ids to those buttons, except for adding different text.
<div class="tdiv2>
<div class="fbutton">
<div>
<span class="view" style="padding-left: 20px;">Add</span>
</div>
</div>
<div class="fbutton">
<div>
<span class="view" style="padding-left: 20px;">Delete</span>
</div>
</div>
</div>
This is how the buttons are arranged. So onclick of that button, I get the text inside the span, as Add and Delete. Now I want to add a class tag to that span, to differentiate between the active button and the other one.
So I came up with the idea, that if I could get span-text that matches to the text being returned, I could add the class to that span.
But when I do
alert($('.tDiv2 span').html());
I am only getting the text of the first span and not the second one. Could somebody help me with getting the html of both spans and not just the first one.
Try this >
$('.tDiv2 span').each(function(index, el) { alert($(el).html()); });
You need each.
$('.tDiv2 span')each(function(node){ alert(node.html()); });
However, I would like to point out that this approach is likely to cause accessibility problems for screen reader users. If you absolutely must re-invent buttons for some reason, then use ARIA attributes so that your blind visitors have some hope of getting it to work right.
jQuery automatically selects the first element in a series if you try to get a property like html or text from it. to get the second (or any number) try:
alert($('.tDiv2 span').eq(1).html()); //returns 2nd element's html content
You can substitute any 0 based index in for 1.

Categories

Resources