Drop down menu items behavior - javascript

Hi I'm working on a MVC application that has a drop down menu in it, and the items
in this drop down are fetched from the DB via a foreach.
foreach (Category item in Model.CategoriesV){
<input type="submit" class="dropdown-item" id="Show"
value="#item.CategoriesName" name="CategName" />
}
I get 3 results from this for each (Mobiles-Consoles-Tablets),
I have another div that contains an image gallery.
I used this code to hide this gallery once I click on an item in the drop down menu.
Here's the image galley(I put it in a Partial View)
<div id="ImageGalleryDiv">
#Html.Partial("_ImageGallery", Model)
</div>
And here's the script that I used to hide the gallery once I click on drop down items list.
<script>
$(document).ready(function () {
$('#Show').click(function () {
$('#ImageGalleryDiv').hide("100");
});
});
Everything is working fine when I click on Mobiles (the first item in the drop down),the others items aren't working.
Any help would be appreciated.

id should be unique. That is it's purpose. Uniquely identifying an element. You are not allowed to use duplicate id's on a page. It can result in unwanted behavior like you are experiencing now. Basically, jQuery gets the first element that it finds with the id and then ignores all the other. Also in plain javaScript we not not have a getElementsById method but getElementById.
Read more about it here -> Why are duplicate ids not allowed in HTML
So you can use a class instead.
Also, class and id should be lowercase and dash separated string-string ( if the consist of multiple words ) , not camelCase.
See example below
const categories = ['Mobiles', 'Consoles', 'Tablets']
categories.forEach(categ => {
const input = `<input type="submit" class="dropdown-item show" id="show-${categ}" value=${categ} name=${categ} />`
$('#categories').append(input);
});
$('.show').click(function() {
$('#image-gallery-div').hide("100");
});
#image-gallery-div {
height: 100px;
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="categories">
</div>
<div id="image-gallery-div">
</div>

Related

How to print the content of a div that changes based on a foreach statement?

I have an ArrayList named conversations_client, I want to be able to get the value of conversation[6] for each div.
Each one the the media div represent a conversation.
Here is a part of my code :
<c:forEach var="conversation" items="${conversations_client}" >
<div class="media">
<div class="media-left">
<input class="checkbox" type="checkbox" name="selected-conv">
</div>
<div class="media-body">
<h4 class="media-heading">${conversation[0]}</h4>
<span class="hidden">${conversation[6]}</span>
......
I had first tried to use this code :
<script type="text/javascript">
$('.media').click(function(){
var text = $(this).text();
alert(text);
});
</script>
But it would print not only conversation[6] but others as well since they're all inside the div with class media.
Then I tried this :
<script type="text/javascript">
$('.media').click(function(){
var text = $('.hidden').text();
alert(text);
});
</script>
But it would print the same id for all divs, which is the id of the first one.
How can I do that? and would it be better to wrap those media divs with tags to be able to use a specific action for each one of them? because I am displaying all conversations, then once the user will click on one them I'll have to recover its id to be able to display the messages of that specific conversation and it isn't advisable to write Java code inside of jsp.
Thank you :)
Use find from current element.
$('.media').click(function()
{
var text = $(this).find('#hidden').text();
alert(text);
});
UPDATE:
You are using loop to repeat the markup. It's not good to use ID hidden multiple times as per W3C standards. ID should be unique and should be used once in the page.
Use class instead of id for multiple usages. In this case class="hidden"
Better change <span id="hidden">${conversation[6]}</span> to <span class="hidden">${conversation[6]}</span>
Also change JS to find .hidden
$('.media').click(function()
{
var text = $(this).find('.hidden').text();
alert(text);
});

JS pop-up for different items on page

I'm trying to make a pop-up for each item in my app to select quantity.
So it preloads several items on page, and I need to make it show pop-up when clicked on any of them.
I found this solution and tried it:
<div class="items">
<div class="menu_item_btn" href = "javascript:void(0)" onclick = "itemquantity()">
<%= item.name %>
</div>
<div id="light" class="itemshowcontent">
<p>Some content</p>
Close
</div>
<div id="fade" class="blackoverlay"></div>
</div>
where js:
<script>
function itemquantity() {
document.getElementById('light').style.display='block';
document.getElementById('fade').style.display='block'
}
function closeitemquantity() {
document.getElementById('light').style.display='none';
document.getElementById('fade').style.display='none'
}
</script>
It works, however when I select quantity, it always selects it only for the first item that comes.
If click on second item (or any other), the pop-up is still for the first one.
I believe this is because I use getElementById, as ID is used for only one object.
I tried changing to getElementsByClassName, but then it doesn't work at all. So, my question is how to make it work?
Should I stick to using classes? Or somehow use ID, within classes?
I apologise if it's simple question, I'm not really familiar with JS.
Any advice appreciated.
EDIT:
Here are some images for what I'm doing. This is page with listed objects:
These are the objects preloaded from DB shown in a list. When you click on any of them, this pop-up comes up:
to select quantity.
I'm developing in elixir and phoenix framework.
Give id to each item and move light and fade out from id and to class. Then, find light and fade by item id when click function is executed. See the following example.
function getParent(itemChild) { // Get parent.
var item = itemChild.parentElement;
return item;
}
function itemquantity(itemChild) {
var item = getParent(itemChild); // Get parent and it is the item.
item.querySelector('.light').style.display='block'; // Find .light element as of item.
item.querySelector('.fade').style.display='block'; // Find .fade element as of item.
}
function closeitemquantity(itemChild) {
var item = getParent(getParent(itemChild)); // You have to get parent twice and that is the item.
item.querySelector('.light').style.display='none'; // Find .light element as of item.
item.querySelector('.fade').style.display='none'; // Find .fade element as of item.
}
<div class="items" id="apple">
<div class="menu_item_btn" href = "javascript:void(0)" onclick = "itemquantity(this)">
Apple
</div>
<div class="light itemshowcontent">
<p>Red Apple</p>
Close
</div>
<div class="fade blackoverlay"></div>
</div>
<div class="items" id="banana">
<div class="menu_item_btn" href = "javascript:void(0)" onclick = "itemquantity(this)">
Banana
</div>
<div class="light itemshowcontent">
<p>Yello Banana</p>
Close
</div>
<div class="fade blackoverlay"></div>
</div>

Hiding other ids when read more of a particular id is clicked

I have various read more buttons under each staff details in my about.html which will direct to their particular sections in another page. i have about.html where i have displayed the staff images, excerpt description and a read more button. Full description of each staff can be red from the bio.html where i have entered the complete description.
When read more button of say id #bio1 is clicked it will be linked to http://www.mysite/bio.html#bio2 . i want all the other ids to be hide in this case(#bio2, #bio2, #bio3 and so on)
HTML CODE
<li>
<div class="item">
<div class="img_block wrapped_img">
<img src="img/pictures/team1.jpg" alt="Tom" />
</div>
<div class="carousel_title">
<h6>Dave</h6>
<div class="op">Chair Person</div>
</div>
<div class="carousel_desc">
<div class="exc">Saul Yarmak has the distinguished honor or repeating his role as Chairman of BXI.</div>
<div class="read_more">
Read More
</div>
</div>
</li>
When you click on #bio1 hide all elements with particular class and show only #bio1:
<span id='bio1' class='a'></span>
...
<span id='bio8798' class='a'></span>
$(document).on('click', '.a', function(){
$('.a').hide();
$(this).show();
})
Add a class to the links and use jquery not() as shown here: jsfiddle
$('.myLink').click( function() {
$('.myLink').not(this).css('visibility','hidden');
});
This will make all elements of class myLink invisible - except the one that has been clicked (this) . If you want to remove from the layout then you would use hide() rather than css('visibility','hidden')
give you bio elements a class name "bio". then do the following to hide them all:
$(".bio").hide();
after that show your selected bio:
$("#bio6").show();
see http://api.jquery.com/hide/ and http://api.jquery.com/show/
If on click of button (#bio1), redirects to another page then I don't think there is a use for hiding other buttons.
Since page is already redirected to another page/section.
Update:
Now you can do this using Attribute Starts With Selector,
var bioVar = $("div[id^='bio']");
bioVar.on("click", function() {
bioVar.not(this).css("display", "none");
});

jQuery Masonry remove function example

I have implemented jQuery masonry to our site and it works great. Our site is dynamic and users must be able to add/remove masonry box's. The site has an add example but no remove example. Our db is queried returning x number of items. Looping through they are loaded and displayed. Here's a code sample: (we are use F3 framework and the F3:repeat is it's looping mechanism.).
<div id="container" class="transitions-enabled clearfix" style="clear:both;">
<F3:repeat group="{{#productItems}}" value="{{#item}}">
<div id="{{#item.itemId}}">
<div class="box">
<div class="view"> <!-- for css -->
<a onclick='quickRemove("{{#item.itemId}}")>
<img src="{{#item.pic}}" />
</a>
</div>
<p>
{{#item.title}}
</p>
</div>
</div>
</F3:repeat>
</div>
In the javascript code the item id number is unique and is passed into the function. It's also the div id# to distinguish each box. I've tried various combinations and methods but can't seem to get this to work.
function quickRemove(item){
var obj = $('#'+item+'').html(); // item is the product id# but also the div id#
$('#container').masonry('remove',obj);
$('#container').masonry('reloadItems');
$('#container').masonry('reload');
}
Has anyone out there successfully removed an item and how did you do it?
Thx.
Currently you appear to be passing a string full of html to the masonry remove method. Pass it the actual jQuery wrapped element by not including .html()
function quickRemove(item){
var obj = $('#'+item+''); // item is the product id# but also the div id#
$('#container').masonry('remove',obj);
$('#container').masonry('reloadItems');
$('#container').masonry('reload');
}

Href: Target ID in Current DIV

I have a list of <li> items being generated from a CMS/DB. Each <li> has a <div> in it which contains a link to a lightbox (a hidden <div>). The link targets the id of the hidden <div> (#inline-content-print) so the javascript plugin triggers and pulls up the lightbox.
The problem I'm running into is that all of the <li>s on the page generate with the same hidden div id (I can change this to classes). So no matter which <li> href is clicked, it always pulls up the lightbox for the first <li> on the page (the first instance of the id). I need a way for the href to say "open #inline-content-print" from THIS div (the one the link being clicked lives in)".
<li>
<div class="store-buttons-bg hide-print-buttons-{tag_Hide-Print-Buttons}">
PRINT
<div style="display: none;" id="inline-content-print">
CONTENT OF LIGHTBOX
</div>
<!-- end inline-content-print -->
</div>
</li>
Any advice would be greatly appreciated.
What server side language are you using? Is it producing these list items in a loop? Is there an index on that loop? If so, this would work for you.
[Server language version of a for loop with an index variable named "i"]
<li>
<div class="store-buttons-bg hide-print-buttons-{tag_Hide-Print-Buttons}">
PRINT
<div style="display: none;" id="inline-content-print_[server language output of "i"]">
CONTENT OF LIGHTBOX
</div>
<!-- end inline-content-print -->
</div>
</li>
[server language version of an end to the for loop]
Assuming you want to do this with jQuery/Javascript, you could use something like this:
$(document).ready(function()
{
$('li a.store-button').click(function(e)
{
var lightboxElement = $(e.currentTarget).find('div');
lightboxElement.show(); // or whatever function you need to display
return false;
});
});
Which is a little script that:
Waits for the page to load.
Finds your list elements (by li object type and the class on the links)
Intercepts click events.
Finds the div element nested in the link that was clicked.
Displays (or runs another function) on the target lightbox element.

Categories

Resources