I would like to filter <div> children from this list item to not get selected, only the entire <li>.
The HTML structure would be like:
<ul id="selectable">
<li>
<div id="1"></div>
<div id="2"></div>
</li>
<li>
<div id="1"></div>
<div id="2"></div>
</li>
...
</ul>
The jQuery would be:
var foo = $('#selectable').selectable({
filter: " > div"
});
But it's not working, happens that... if I don't put any filtering, I would be selecing the <div>s inside it, specially the <div> with the id=2 which is out the container gets selected, and it's awful! Here’s a screenshot so you can understand what I'm saying:
See the "About" text being selected too? How can I fix this?
Try this,
var foo = $('#selectable').selectable({
filter: " li " // li in place of div
});
I needed to filter by "li" in the selectable.
Related
Expected behavior: When I click on the .parent class, an item detail modal will be shown but the modal won't be shown if I click on the .dropdown or any of it's option.
<div class="parent click-for-item-detail">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img class="click-for-item-detail" src="image.jpg></div>
<div class="info">
Item title
<div class="click-for-item-detail"> item subtitle</div>
</div>
</div>
So far:
$(".click-for-item-detail").on("click",function(e){
// show the modal if the target itself has been clicked
if(e.target === this) {
$('#itemDetailModal').modal('toggle');
}
});
I have added click-for-item-detail class in every element that should trigger the item detail modal. Is there a better way to achieve this?
It is true what Phong is saying and that works. However, imagine now you had many child elements in your parent all matching that selector. With something like below, you would add an event listener to each of those elements.
$(".info, .item-image").on("click", function(){
console.log("Trigger");
});
While with your first approach you were already very close to only have one listener, no matter how many child elements are in the parent.
Consider following example:
<ul class='parent'>
<li>No</li>
<li>Click</li>
<li>Event</li>
</ul>
$(".parent").on("click",function(e) {
if(!e.target.classList.contains('parent')) {
return console.log('no event')
}
console.log('fire event')
});
This is called event delegation, and you pretty much do this already. Here I am checking if the element, I am clicking on, is indeed of class parent, only then I fire my event.
You can of course do all sorts of checks, for example only the <li> elements.
$(".parent").on("click", (e) => e.target.tagName == 'LI' && console.log('fire event'))
Here check out this example https://codepen.io/bluebrown/pen/xxGVgYd?editors=1111
I would recommend doing a web search for event delegation and event bubbling.
You can specify some selectors to be able to trigger.
Read the following post to have a better understanding.
Event listener for multiple elements - jQuery
$(".info, .item-image").on("click", function(){
console.log("Trigger");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent click-for-item-detail">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img class="click-for-item-detail" src="image.jpg"></div>
<div class="info">
Item title
<div class="click-for-item-detail"> item subtitle</div>
</div>
</div>
You can use :not() selector to filter out the element you do not to be clicked:
$('.parent > :not(.dropdown)').click(function(e){
alert('modal');
//show modal
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="parent">
<div class="dropdown">
Options
<ul class="dropdown-menu">
<li>option-1</li>
<li>option-2</li>
</ul>
</div>
<div class="item-image"><img src="image.jpg"></div>
<div class="info">
Item title
<div> item subtitle</div>
</div>
</div>
I want to move some span elements to closest div. I found the solution to my problem but it does not work for me. I have some Html code:
<ul>
<li>
<a><span>Some info</span></a>
</li>
<div class="cl1">...</div>
<li>
<a><span>Some info 2</span><a>
</li>
<div class="cl1">
...
</div>
...
</ul>
and to move <span> like this:
$('span').each(function () {
$(this).parent().parent().closest('.cl1').append(this);
})
but nothing happened. Any help would certainly be appreciated
you can't put a div in a ul, only li's.
your html has to be valid (a's, ul need to be closed)
Closest searches anscetors, not siblings.
since your markup is not valid as is, i'm not sure if you want the divs in the list or not. This example removes them from the lis, which breaks the list into two lists.
$('button').click(function() {
$('span').each(function() {
var $div = $(this).closest('ul').siblings('.cl1');
$(this).clone().appendTo($div);
$(this).remove();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
<a><span>Some info</span></a>
</li>
</ul>
<div class="cl1">...</div>
<ul>
<li>
<a><span>Some info 2</span></a>
</li>
</ul>
<div class="cl1">...</div>
<button>Do Stuff</button>
I have a menu list that refer to different projects.
Each list item shares its "ID" with a project showcased in a gallery.
<div class="menu">
<ul>
<li id="id1">project 1</li>
</ul>
</div>
<div class="gallery">
<div class="proc id="id1">project 1</div>
</div>
I'd like a jQuery function that :
When a list item from the menu is clicked, gets the project with the same id to do something.
I really don't know where to start from and I'm stuck at that :
<script>
$( "li#id1").click(function() {
$( ".project#id1" ).show();
});
</script>
Many thanks
As the comments said the IDs must be unique and you have missing quote.
You can use data attributes to handle your logic or combination of ids and data attributes.
Try something like this:
HTML
<div class="menu">
<ul>
<li data-project-id="first-project-id">project 1</li>
...
</ul>
</div>
<div class="gallery">
<div class="proc" data-project-id="first-project-id">project 1</div>
</div>
JavaScript
$('.menu li').click(function(){
var targetId = $(this).attr('data-project-id');
$('.proc[data-project-id="' + targetId + '"]').show();
});
The click event is attached to every li item in the element with class .menu.
On click event we extract the data-project-id attribute from the clicked element, find the project elemenet from gallery and show it.
JSFiddle Demo
you can use normal id also (as selector)
HTML
<div class="menu">
<ul>
<li id="first-project-id">project 1</li>
...
</ul>
</div>
<div class="gallery">
<div class="proc" id="first-project-id">project 1</div>
</div>
jQuery
$('.menu li').click(function(){
var targetId = $(this).attr('id');
$('.proc[id="' + targetId + '"]').toggle();
});
In the follow content I need to remove the mark-up tags <div class="sub"> and </div> but not it's content with jquery. This is to adapt the menu to a responsive layout.
<nav id="top">
<ul>
<li class="ti" id="snw"> <a class="mm" href="/snowdepth/">Weather</a>
<div class="sub">
<ul>
<li><h2>Snowline</h2></li>
<li>Nordliche Ostalpen</li>
</ul>
</div>
</li>
<li class="ti" id="blg"> <a class="mm" href="/live/">Weblog</a></li>
</ul>
</nav>
Try unwrap():
$('.sub').find('ul').unwrap();
Essentially, you are looking for all the child elements of .sub, and unwrapping them or removing their parent.
Here's the demo: http://jsfiddle.net/yEseX/
You can do it this way.
Live Demo
$('.sub').parent().html($('.sub').html());
Supposing you may have more than one div with class sub, I'd suggest this :
var container = $('#top');
container.html(
container.html().split('<div class="sub">').join('').split('</div>').join('')
);
Try this,
var content = $(".sub").html(); // stored ".sub" div content
$(".sub").remove(); // remove ".sub" div
$("#top #snw").after(content); // insert content where you want
Try this:
var list = $('#snw');
var html = list.html();
list.html(html.replace('<div class="sub">','').replace('</div>',''));
Demo here
I think #Abhilash's answer is the neatest so far, but I would modify the selector slightly:
$('.sub').contents().unwrap();
This removes all of the .sub elements, leaving their contents in place.
JsFiddle: http://jsfiddle.net/yEseX/2/
I've got this html below.
I need all div's inside div#ProductImagesContainer to be hidden at startup, all but div#productImageA.
When you click a.productImageB, the corresponding div#productImageB inside div#ProductImagesContainer should be shown and it's siblings should hide.
I need to use Prototype for this project, but I'm not a javascript genious. Would know what to do with jQuery but can't do it with Prototype.
<ul>
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
My JavaScript is a bit rusty, but I believe you want the following:
Hide everything:
$$('#ProductImagesContainer div').invoke('hide');
Show the one you want:
$('ProductImageA').show();
Edit: documentation on prototype's api can be found here
Here is the jsfiddle to achieve what you are looking for in prototype:
Given HTML:
<ul>
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
Prototype JavaScript:
//declare global variables to access within functions and etc...
var myLi = $$('li'); //get all the li a links
var myDiv = $('ProductImagesContainer').children; //get all the children of div#ProductImagesContainer
hideAllBut(null); //first hide all the divs
//function to hideAllBut the child div element of #ProductImagesContainer w/ the following classname as id
function hideAllBut(el) {
var toShow = el;
for (var index = 0; index < myDiv.length; index++) {
if (myDiv[index].identify() == toShow)
myDiv[index].show();
else
myDiv[index].hide();
};
}
//oops through each li
myLi.each(function(myLiEl) {
//attached on click event for each of the hyperlinks and use the hyperlink's class name to call hideAllBut(theclassname)
Event.observe(myLiEl, 'click', function() {
hideAllBut(myLiEl.firstDescendant().className); //gets the className of first decendant based on your example
});
});
First we declare two global variables to hold all the li's a links and children of div#ProductImagesContainer. Then we create a function called hideAllBut(el); where it hides all but the child div element of #ProductImagesContainer w/ the classname as id. A parameter, which is the classname of link that is associated w/ the div element's id name that we need to hide. Then we proceed to oop through each li and add an onclick event so whenever the li is clicked it'll call hideAllBut(); and pass its classname as the param.
Based on kjy112's detailed answer, here is a shorter version.
HTML:
<ul id="ProductImagesLinks">
<li>
A
</li>
<li>
B
</li>
<li>
C
</li>
<li>
D
</li>
</ul>
<div id="ProductImagesContainer">
<div id="productImageA">maybe flash video</div>
<div id="productImageB">imageB</div>
<div id="productImageC">imageC</div>
<div id="productImageD">imageD</div>
</div>
Javascript:
$('ProductImagesLinks').on('click', 'a', function(event, element){
var target = $(element.readAttribute('data-target'));
if (target) {
target.show();
$$('#ProductImagesContainer > div[id!='+target.identify()+']').invoke('hide');
}
});
$('ProductImagesContainer').down().siblings().invoke('hide');
The advantage here is it adapts if the list changes by utilising event bubbling.