jQuery Advanced Selector for Multiple Elements - javascript

I am trying to add hidden class on two elements.
$("#grid").closest(".ui-jqgrid").addClass("hidden");
$("#grid").closest(".ui-jqgrid").prev("h3").addClass("hidden");
For the following markup,
<div class="col-sm-12">
<h3>Heading 1</h3>
<div class="ui-jqgrid hidden" id="" dir="rtl" style="width: 1035px;">
<div class="jqgrid-overlay ui-overlay" id=""></div>
<div class="loading row" id="" style="display: none;"></div>
<div class="ui-jqgrid-view" role="grid" id="">
<div class="ui-jqgrid-titlebar ui-jqgrid-caption-rtl" style="display: none;">
<a role="link" class="ui-jqgrid-titlebar-close HeaderButton " title="" style="left: 0px;">
<span class="ui-jqgrid-headlink glyphicon glyphicon-circle-arrow-up"></span></a>
<span class="ui-jqgrid-title"></span>
</div>
<div class="ui-jqgrid-bdiv">
<div style="position: relative;">
<div></div>
<table id="grid" class="ui-jqgrid-btable">
</table>
</div>
</div>
</div>
</div>
</div>
Can I do this in one line without finding the closest(".ui-jqgrid") twice? I don't want to add more classes to markup and also I don't want to use a JS variable here. Can anybody with strong selectors suggest a solution?

Just chain the methods. jQuery returns the manipulated object every time you call a method, so you can just call the next method on the returned object.
This is known as chaining
$("#grid").closest(".ui-jqgrid").addClass("hidden").prev("h3").addClass("hidden");
Explanation
$("#grid") // returns #grid
.closest(".ui-jqgrid") // returns .ui-jqgrid
.addClass("hidden") // returns .ui-jqgrid
.prev("h3") // returns the previous h3 element of .ui-jqgrid
.addClass("hidden"); // returns the h3
UPDATE (Chained and no need for new class)
// Select the closest '.ui-jqgrid', find its parent and hide it's direct children ('h3' and '.ui-jqgrid' div)
$('#grid').closest('.ui-jqgrid').parent().children().addClass('hidden');

You can do this:
$("#grid").closest('.col-sm-12').find(".ui-jqgrid, h3").addClass("hidden");
As you have the id of the grid #grid the traverse up at the wrapper element of all then use .find() method which can take multiple comma separated selectors then add the class on the found elements.
As per your comment you can change to this:
$("#grid").closest('[class^="col-sm"]')

Related

Javascript: Add margin-top to an object, object with other objects is inside object A, multiple objects A on page

I have an object (div) which has four elements (with classes) inside.
What I am trying to do: When height of the element A is lower than 40px then add to element B 20px margin-top.
However there are many objects on the page.
<div class="list">
<div class="block">
<div class="list-name" style="height: 20px">element A</div>
<div class="div1">another div here</div>
<div class="div2">another div here</div>
<div class="product-image-container">element B</div>
</div>
<div class="block">
<div class="list-name" style="height: 50px">element A</div>
<div class="div1">another div here</div>
<div class="div2">another div here</div>
<div class="product-image-container">element B</div>
</div>
(...)
</div>
So far I tried this. Nevertheless it works only if there are only two elements in the div.
$(document).ready(function(){
$('.list-name').each(function(index, obj){
console.log($(obj).height())
if($(obj).height() < 40)
{
$(obj).next('.product-image-container').css('margin-top', 20)
}
});
});
Any help is much appreciated.
Rob
next() only works for the very next element.
Use siblings() instead which includes all elements on same level
$(obj).siblings('.product-image-container').css('margin-top', 20)
Or another commonly used pattern is to look up to a common ancestor and find() within that parent
$(obj).closest('.block').find('.product-image-container').css('margin-top', 20)

$('parent > child > childOfChild > ...').css('background-color','red)

HTML
<div class="galao">
<div class="informacoesGalao invisible">
<div class="tabelaInformacoes infoGalao" style="float:right; text-align:right">
<p class="nomeGalao">Produto A</p>
<p class="invisible volumeTotalGalao">1000</p>
<p class="invisible volumeAtualGalao">800</p>
</div>
</div>
<div class="desenhoGalao">
<div class="bordasGalao">
<div class="conteudoGalao"></div>
</div>
</div>
</div>
CSS
.conteudoGalao { background-color: blue }
I'm trying to select the <div class="galao"> and change the background color of the child <div class="conteudoGalao">.
When the user clicks into the <div class="galao"> this div turns into <div id="selectedGalao" class="galao">.
I've already tried $('#selectedGalao > conteudoGalao').css('background-color','red') but it doesn't even return a error or anything. Any idea of how I can make this work? Is there a specific jquery for this kind of "grandson div"?
The '>' css selector is for direct children. Since conteudoGalao is a grandchild it will not work. Simply use $('#selectedGalao .conteudoGalao').css('background-color','red') instead unless that's not specific enough, in which case I'll need more info as to why. IF that's how your markup will always work, and you do want to be extremely explicit in your selector, $('#selectedGalao > .desenhoGalao > .bordasGalao > .conteudoGalao').css('background-color','red'). Lastly, as CalvT said, you are also missing a period in front of 'conteudoGalao' to label it as a class.
You have an error in your jQuery. Try the following:
$('#selectedGalao .conteudoGalao').css('background-color','red')
You weren't specifying that conteudoGalao was a class, so do this by adding the . As the . was missing, jQuery was looking for an element called conteudoGalao
The > is for direct children, and conteudoGalao is not.

Changing map address with jquery

I currently have this code, when user clicks on the div, the map on the changes the position with the updated addresss:
<div class="row">
<div class="col-sm-12 col-lg-6">
<div class="dir">
<h3 class="title">Shopping abasto</h3>
<p>tel: 4676-4565</p>
<p>Avenida Marota</p>
<div id="map" data-maps="Av. Aconquija 600, Paseo Heller, Yerba Buena, Tucuman"><span class="glyphicon glyphicon-map-marker" id="dir"></span></div>
</div>
<div class="dir">
<h3 class="title">Shopping abasto</h3>
<p>tel: 4676-4565</p>
<p>Avenida Marota</p>
<div id="map" data-maps="Juncal 1213, Buenos Aires, Argentina"><span class="glyphicon glyphicon-map-marker"></span></div>
</div>
<div class="dir">
<h3 class="title">Shopping abasto</h3>
<p>tel: 4676-4565</p>
<p>Avenida Marota</p>
<div id="map" data-maps="Paseo Pilar, Del Viso, Buenos Aires Province"><span class="glyphicon glyphicon-map-marker"></span></div>
</div>
</div>
<div class="col-sm-12 col-lg-6">
<div class="map">
<iframe width="100%" height="368" frameborder="0" style="border:0" src="https://www.google.com/maps/embed/v1/place?q=Buenos%20Aires%2C%20Argentina&key=AIzaSyCDg1Dfoxg3cKcOsucYZQnTjpmPjbUqe2M"></iframe>
</div>
<div class="col-separador-s"></div>
<div class="">
<img src="http://placehold.it/727x502">
</div>
</div>
</div>
I want the map to update the position when clicking on any of the divs with the id 'map'.
The problem is that it only works with the first div, here is my script so far:
jQuery(function(){
jQuery('#map').on('click', function() {
var maps = jQuery(this).data('maps');
jQuery('.map iframe').attr('src','https://www.google.com/maps/embed/v1/place?q=' + maps + '&key=AIzaSyCDg1Dfoxg3cKcOsucYZQnTjpmPjbUqe2M');
});
});
Jquery's selector by id returns one single element, that's why it's working only for your first element.
You need to use classes instead of id's.
Replace with
<div class="map" ... >
And match by class
jQuery('.map')
Element id's must be unique in the DOM for targeting to work as expected. There will not be errors thrown with the rendering of elements with the same ID, however it goes against standard practice, and introduces issues such as you're experiencing here.
Please refer to this article for a more in-depth differentiation between ID and CLASS.
So, to resolve the issue you're experiencing, you should make the following adjustments:
Change map id div's from <div id="map"> to <div class="map">
Change map class jQuery selector from jQuery('#map') to jQuery('.map')
Change the iframe wrapping div to <div id="map-wrapper">
Change jQuery selector for the iframe to jQuery('#map-wrapper iframe')

Dragula drop in multiple divs

I implemented drag 'n' drop on my application using Dragula, but I need to set it so I can drop my elements to more than one div.
I tried to use a class to achieve it, but it just activates the first one of my divs.
THe HTML:
<div role="presentation" class="table table-striped">
<div class="files" id="upload-file"></div>
</div>
<div class="col-md-4">
<div class="drag-container">Test 1</div>
<div class="drag-container">Test 2</div>
<div class="drag-container">Test 3</div>
</div>
The JS calling Dragula:
dragula([document.querySelector('#upload-file'), document.querySelector('.drag-container')]);
How can I drop te items to more than one div?
You can define an array containers:
var containers = $('.drag-container').toArray();
containers.concat($('#upload-file').toArray());
And then, pass the var 'containers' to dragula initializer:
dragula(containers, {
isContainer: function (el) {
return el.classList.contains('drag-container');
}
});
For those without jQuery or $ you can use:
dragula([].slice.call(document.querySelectorAll("drag-container")));
This converts the NodeList to an array and passes it to dragula.
querySelector only returns a single element, you would need to use querySelectorAll in order to get a list of elements. Not sure how dragula would handle getting a two element array, with the second element being an array. You may want to generate the array first, add the '#upload-file' to that array, and then pass the array. Or you could generate the array after initializing, and cycle through the array, adding the elements dynamically using something like "drake.containers.push(container);". I got this construct directly from the github site https://github.com/bevacqua/dragula
HTML:
<div className="wrapper">
<div className="container col-md-4" id="A">
<div className="panel panel-white">
</div>
<div className="panel panel-white">
</div>
</div>
<div className="container col-md-4" id="B">
<div className="panel panel-white">
</div>
<div className="panel panel-white">
</div>
</div>
</div>
JS:
dragula([document.querySelector('#A'), document.querySelector('#B')]);
You can drag each item in one column to the other. You can add more columns with the class name of container.
If you want to specify a custom class name, you should define option like this :
Option:
let options = {
isContainer: (el) => {
return el.classList.contains('drag-container'); // The immediate elements in this container will be draggable
}

Change list-group-item from hidden to visible with JS

I have a list which contains of several items that are hidden.
In my JS i want a function that changes the items of this list so it becomes visible. I want each item to become visible if a certain event has happened. The event is working fine and can be considered as shakeCount= 6, to test it properly.
Here is my list:
<div class="container">
<div class="list-group">
<div id="s1">Shake1</div>
<div id="s2">Shake2</div>
<div id="s3">Shake3</div>
</div>
</div>
What i tried so far and didn't work:
function nR(){
if (shakeCount>5)
document.getElementbyId("s1").style.visibility ="visible";
}
Thanks in advance!
Have you tried using Toggle? I would recommend it but you may need to remove the "hidden" class from your elements and add in the style="display: none;" attribute to each in order to default them to hidden.
<div class="container">
<div class="list-group">
<div id="s1">Shake1</div>
<div id="s2">Shake2</div>
<div id="s3">Shake3</div>
</div>
</div>
function nR(){
if (shakeCount>5)
document.getElementbyId("s1").toggle();
}
First, you're using getElementbyId -- it should be getElementById (missing capital 'B').
Second, you've made the #shake links visibility:hidden, but you are targeting the wrapping div when you run your js.
var shakeCount = 6;
if (shakeCount>5)
document.getElementById("s1").style.visibility ="visible";
.hidden {visibility: hidden;}
<div class="container">
<div class="list-group">
<div id="s1" class="list-group-item hidden"><a href="#shake1" >Shake1</a></div>
<div id="s2" class="list-group-item hidden"><a href="#shake2" >Shake2</a></div>
<div id="s3" class="list-group-item hidden"><a href="#shake3" >Shake3</a></div>
</div>
</div>
The above code hides the wrapping div elements instead of the links so that they are shown when the js runs.

Categories

Resources