I have a simple select dropdown menu.
<select onchange="showDiv(this)">
<option value="1">Container 01</option>
<option value="2">Container 01 + 02</option>
<option value="3">Container 01 + 02 + 03</option>
</select>
I have three container. If I click in the select area on "container 01 + 02", container 1 and 2 should appear. If I click on "container 01", only container 01 appears.
<div id="container_01></div>
<div id="container_02></div>
<div id="container_03></div>
I have found a way to do this using Jquery:
function showDiv(select){
if(select.value==1){
document.getElementById('container_01').style.display = "block";
}
else if (select.value==2){
document.getElementById('container_01').style.display = "block";
document.getElementById('container_02').style.display = "block";
}
else if(select.value==3){
document.getElementById('container_01').style.display = "block";
document.getElementById('container_02').style.display = "block";
document.getElementById('container_03').style.display = "block";
}
This works fine for me!
Now my Problem:
To make the select fields more attractive, I'm using a pretty nice script, to pep up the selection. Here an example:
https://tympanus.net/Development/SelectInspiration/index3.html
The thing is, the script converts the select dropdown menu to a list element:
<ul>
<li class="" data-value="1"> <span>1</span> </li>
<li class="cs-selected" data-value="2"> <span>2</span> </li>
<li class="" data-value="3"> <span>3</span> </li>
</ul>
Is it possible, to rebuilt the effect, I have created for the select menu?
Get the data-value from li.cs-selected and display:
<div id="container_01></div>
<div id="container_02></div>
Im not pretty good at Javascript. Maybe someone can help me out, to solve this problem? Thank you!
Your aim is to get the class of List element selected, for that use this:
var elementSelected = document.getElementByClassName('your_class_name');
Upon storing a reference in elementSelected apply an event listener as:
elementSelected.onClick = function(){ //Code goes here }
OR you could use addEventListener method to do the same:
elementSelected.addEventListener("click", function(e) {
alert('something');
}, false);
Once the element is clicked you can get its value by using
var elementValue = elementSelected.value
Then you can transfer that value into the "select-option" drop down menu you've created.
I am not sure if you have or can use jQuery but you can use this script to get that values without needing select.
// I would add a classname or an id to differentiate from other ul tags.
$('ul.myMenuSelect').on('click', 'li', function(){
var value = $(this).data('value');
$(this).addClass('cs-selected').siblings().removeClass('cs-selected');
$('#container_' + value).show().siblings().hide();
})
$("li.cs-selected").attr("data-value")
Related
With the help of SO member the.marolie I learned how to implement a JS filter/selector [the 'demo JS filter']. I have this working perfectly on a test page: it shows/hides divs according to "data-types" assigned to them in the body html. However, the selection is made by sliding down a <select> dropdown list and letting go at the preferred option. That's not quite what I want.
I want to utilise my existing nav-bar dropdown ['my dropdown'] as the filter/selector. I especially want to retain the existing interactivity of my dropdown, whereby one click/tap reveals the whole of the dropdown content block, and one click outside the content block closes it.
I want the elements within my dropdown to represent various show/hide <div> 'options' for the html page, and enable the user to choose from these via an additional click/tap (essentially what the demo JS filter does, but at the instigation of a click/tap). Once revealed via a nav-bar click/tap, the whole dropdown content block has to stay on-screen -as it currently does- for this to be practically possible.
After making my dropdown identifiable via id="media-selector-demo" and name="filter" I was hoping that I could assign the demo JS filter's <option> elements to the <a> elements in it, and the whole thing would function like the <select> dropdown of the demo JS filter. I had a vague idea that using <a> elements might obviate the need for another onClick in the JS. I've tried various combinations of <a> and <option> elements, but nothing has worked yet.
Do I need another onClick to invoke the JS filter via my dropdown? or
Can I invoke the JS filter via 'active' <a> status?
I'm struggling by trial and error.
Here are what I think are the relevant sections of code pertaining to all discussed above:
My dropdown is based on the following code.
JS in the page head:
/* When the user clicks on the button,
toggle between hiding and showing the dropdown content */
function myDropdownJS() {
document.getElementsByClassName("navbarDROPDOWN-JS")[0].classList.toggle("show");
}
// Close the dropdown if the user clicks outside of it
window.onclick = function(e) {
if (!e.target.matches('.dropbtn')) {
var myDropdown = document.getElementsByClassName("navbarDROPDOWN-JS")[0];
if (myDropdown.classList.contains('show')) {
myDropdown.classList.remove('show');
}
}
}
My dropdown html in nav bar (most of the css is just design styling):
<span class="dropdown" onclick="myFunction()">
<a class="dropbtn navbarDROP-ICON" style="opacity:0.5; padding-top:0px;">menu</a>
<a class="dropbtn navbarDROP-TXT" style="opacity:0.5">menu </a>
<a class="dropbtn navbarDROP-TXT">Career Works by Date </a>
<div class="dropdown-content navbarDROPDOWN-JS" >
<a class="tag-bgd-INSTLLN" href="#">Installations (all media)</a>
<a class="tag-bgd-MOVIMG" href="#">Works with moving image (inc. vid/film releases)</a>
<a class="tag-bgd-SNDMUS" href="#">...with sound and music (inc. sound/music releases)</a>
<a class="tag-bgd-PHOTO" href="#">...with photographs</a>
<a class="tag-bgd-DRAW" href="#">...with drawing (inc. 2D works)</a>
<a class="tag-bgd-TXT" href="#">...with text</a>
<a class="tag-bgd-PERF" href="#">...with performative action</a>
<a class="tag-bgd-COLPUB" href="#">Collaborative and public works</a>
<a class="tag-bgd-OBJDEV" href="#">>Objects, garments, devices</a>
<a class="tag-bgd-EDPUB" href="#">Editions, publications</a>
<a class="tag-bgd-CAREER" href="#">Career Works by Date</a>
</div>
Above: the <a href> elements were going to contain URLs for alternatively styled pages. There is no need for these if I can enable the user to selectively show/hide parts of just this one page, via this dropdown.
The demo JS filter is based on the following code (via SO user the.marolie).
JS at page end:
var select = document.getElementById('media-selector-demo');
var filter;
select.addEventListener("change", function() {
filter = select.value;
var elements = document.querySelectorAll('.wk-date_ITEM');
elements.forEach((el) => {
var type = el.dataset.type.split(', ');
if (type.includes(filter)) {
el.classList.remove('hide-by-media');
} else {
el.classList.add('hide-by-media');
}
})
});
Demo JS filter CSS:
.hide-by-media {
display: none;
}
Demo JS filter html in page body:
<select id="media-selector-demo" name="filter">
<option value="INSTLLN"> Installations (all media)</option>
<option value="MOVIMG"> Works with moving image (inc. vid/film releases)</option>
<option value="SNDMUS" >...with sound and music (inc. sound/music releases)</option>
</select>
Example div in page body (there are 80-100 of these):
<!-- ++++++++++ START FULL-WIDTH LIST ENTRY '2017 STATE OF DREAD' ++++++++++ -->
<div id="state-of-dread" class="w3-container wk-date_ITEM" data-type="INSTLLN, SNDMUS">
<div class="w3-container wk-date_TXT-IMG">
<div class="wk-date_GRID">
<div class= "h3 wk-date_DATE"> 2017 </div>
<div class="wk-date_TTL"><h1>State of Dread</h1></div>
<div class="h2 wk-date_KIND-1" >Installation</div>
<div class="p wk-date_KIND-2" ><span class="sound">Sound</span>, for x2 interconnected rooms.<br>AB, CD, EF, Solo exhibition (as trio), Ohrenhoch sound gallery, Berlin.</div>
<div class="wk-date_IMG">
<div class="w3-container w3-right wk-date_IMG-BOX-LSCP">
<img src="../../imgs/INSTALLATION-EVENT/2017_dread_thmb.jpg"
alt="'xx' by Andrew Stones, installation view, xx"></div>
</div>
</div>
</div>
</div>
<!-- ++++++++++ END FULL-WIDTH LIST ENTRY '2017 STATE OF DREAD' ++++++++++ -->
Demo JS filter: JS at end of page:
<script type="text/javascript">
var select = document.getElementById('media-selector-demo');
var filter;
select.addEventListener("change", function() {
filter = select.value;
var elements = document.querySelectorAll('.wk-date_ITEM');
elements.forEach((el) => {
var type = el.dataset.type.split(', ');
if (type.includes(filter)) {
el.classList.remove('hide-by-media');
} else {
el.classList.add('hide-by-media');
}
})
});
</script>
What you would need to do is change the event listener from select, change to drop down element, click. you would also need to add the values of the options from the select as data-value attributes on the drop down elements.
1 - add a data-value attribute to the elements to represent what to hide
<a class="tag-bgd-INSTLLN" href="#" data-value="INSTLLN">
2 - target the drop down elements you want to attach the event listener to.
const dropDownElements = document.querySelectorAll('.dropdown-content a')
3 - attach event listeners to the selected targets (PS. the e in the function stands for event, click event listener produces an event object)
dropDownElements.forEach((dropDownElement) => {
dropDownElement.addEventListener('click',(e)=>{
const filter = e.target.dataset.value;
})
})
4 - the rest is just adding the rest of the filter used in the demo js filter
dropDownElements.forEach((dropDownElement) => {
dropDownElement.addEventListener("click", (e) => {
const filter = e.target.dataset.value
var elements = document.querySelectorAll(".wk-date_ITEM")
elements.forEach((el) => {
var type = el.dataset.type.split(", ")
if (type.includes(filter)) {
el.classList.remove("hide-by-media")
} else {
el.classList.add("hide-by-media")
}
})
})
})
Been doing well so far with MDC Web Components, but I've been hung up here for far too long. (Not strong in JS.)
mdc-select used to be non-native, then used native HTML select, and now once again it's non-native. For a while MDC Web supported a hidden input so that you could pass values to the server.
There's hardly any documentation - mostly just stuck users like me opening issues on GitHub:
Closed: MDC Select - no longer form input compatible #2221
Closed: [MDC Select] Example in README does send values to the web server #5295
Open: [MDCSelect] Add hidden input element to support HTML forms #5428
I need to set/update the value of a hidden input on MDCSelect change for multiple select boxes on the same page... I can get it to do it for ONE select box, but not multiple.
Here is the select box HTML:
<div class="mdc-select mdc-select--outlined region-select">
<div class="mdc-select__anchor demo-width-class">
<i class="mdc-select__dropdown-icon"></i>
<div id="demo-selected-text" class="mdc-select__selected-text" tabindex="0" aria-disabled="false" aria-expanded="false"></div>
<div class="mdc-notched-outline">
<div class="mdc-notched-outline__leading"></div>
<div class="mdc-notched-outline__notch" style="">
<label id="outlined-label" class="mdc-floating-label" style="">Region</label>
</div>
<div class="mdc-notched-outline__trailing"></div>
</div>
</div>
<div class="mdc-select__menu mdc-menu mdc-menu-surface demo-width-class">
<ul class="mdc-list">
<li data-value="" disabled="" aria-selected="false" role="option" class="mdc-list-item" tabindex="0"></li>
<li data-value="north" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">North</li>
<li data-value="east" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">East</li>
<li data-value="south" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">South</li>
<li data-value="west" aria-selected="false" role="option" class="mdc-list-item" tabindex="-1">West</li>
</ul>
</div>
<!-- THIS IS THE HIDDEN INPUT THANK YOU -->
<input type="hidden" id="name2" name="input_name2" value="" class="my_mdc-select__value" />
</div>
I've tried targeting the hidden input with id, name, and even class. I think I need some sort of integrated function, forEach, or loop - tried adding JS beneath each select with no avail. I've worked the examples (seen below) from other users and no success. JavaScript isn't my thing, I know what it supposed to be happening but don't know the function or loop syntax etc to make this work.
I need to make sure each set/update targets the correct hidden input associated with that particular select box.
Here is my JS that works for ONE select box but not multiple:
// Select Menu
import {MDCSelect} from '#material/select';
const selectElements = [].slice.call(document.querySelectorAll('.mdc-select'));
selectElements.forEach((selectEl) => {
const select = new MDCSelect(selectEl);
select.listen('MDCSelect:change', (el) => {
const elText = el.target.querySelector(`[data-value="${select.value}"]`).innerText;
console.log(`Selected option at index ${select.selectedIndex} with value "${select.value}" with a label of ${elText}`);
// this works but only saves one
document.querySelector('input.my_mdc-select__value').value = select.value;
});
});
Here is some code that others used that I haven't been able to modify/apply (taken from links above):
From nikolov-tmw:
document.querySelectorAll( '[data-mdc-auto-init="MDCSelect"]' ).forEach( function( sel ) {
sel.My_MDCSelect__Value = sel.querySelector('input.my_mdc-select__value');
if ( null !== sel.My_MDCSelect__Value ) {
sel.addEventListener( 'MDCSelect:change', function( a ) {
if ( sel.MDCSelect ) {
sel.My_MDCSelect__Value.value = sel.MDCSelect.value;
}
} );
}
} );
From daniel-dm:
<div class="mdc-select">
...
</div>
<input id="pet-select" type="hidden" name="pets">
<script>
const input = document.querySelector('#pet-select');
const select = document.querySelector('.mdc-select');
select.addEventListener('MDCSelect:change', e => {
input.value = e.detail.value;
});
</script>
Please help! This particular issue has been open since January (people struggling long before) with no clear solution to help non-JS developers implement MDCSelect boxes. Thanks in advance!
The problem is here:
document.querySelector('input.my_mdc-select__value').value = select.value;
Document.querySelector will find the first matching element in the whole document, so in your loop you're always accessing the same input element.
Instead, you should run querySelector method on the parent element of each hidden input, which in your loop will look like:
selectEl.querySelector('input.my_mdc-select__value').value = select.value;
I have been trying to get an active border when selecting a list item. I cannot get the item to show the CSS background-color. how can I get this to work... then a second question I would have is how would I show an alert of which color selected when clicking the button?
here is the javascript that I am trying to incorporate.
$(".swatches li").click(function() {
$(this).addClass('activeColor');
$(this).removeClass('activeColor');
});
here is my html
<div class="dropdown-container">
<ul class="swatches" id="swatches">
<li class="cell">
NONE
<div class="colorBox"></div>
<!--END COLOR BOX-->
</li>
<!--END LI-->
</ul>
<!--END SWATCHES-->
</div>
<!--END DROPDOWN CONTAINER-->
<div class="buttonForColor">
<button>
Change Color
</button>
</div><!--END BUTTON FOR COLOR-->
css
.activeColor {
background-color: red;
}
here is my jsfiddle
https://jsfiddle.net/kotten03/02abL9cu/
Any help would be appreciated!
You are adding the class & then immediately removing it. Remove $(this).removeClass('activeColor'); from the click function to stop this. If you want to clear the previous items with that class, you could use:
$(".swatches li").click(function() {
$(".swatches li").removeClass('activeColor');
$(this).addClass('activeColor');
});
To alert the colour, one option would be:
$(".buttonForColor button").click(function() {
alert($($.find('.activeColor')[0]).text());
});
jsFiddle
First, you are trying to set a click listener on an array rather than individual elements. Second, you are adding a class and immediately removing it as well.
Try the below code which solves both the issues.
var elements = $(".swatches li");
for (var i = 0, n = elements.length; i < n; ++i) {
var e = elements[i];
$(e).click(function() {
$(this).addClass('activeColor');
});
}
Could someone kindly advise me how I go about expanding my code?
What I want to do is:
When the plots_container is clicked, this prompts up a modal with a list of charts in it
When the user clicks on a chart (eg: line plot in the modal), the content in the span stating hello hello changes to <span>line plot</span>
I would like to do something exactly like this
At the moment I have just managed to prompt up the modal when plots_container is clicked.
I would be very grateful if someone could take a look at what I've tried in the below files and provide suggestions or feedback.
index.html
<span class="modal_content">
<select class="hide seriesDetails" title="Type of Chart for this Series" id="ChartType" name="ChartType"><option selected="selected" value="17">Pie</option></select>
<div class="seriesDetails" id="plots_container">
<span>hello</span>
</div>
<div id="plotList">
<ul>
<li class="business">
<div class="image_text_content">
<div class="image_container"><img src="Content/images/plot-thumbs/1-scatter-plot.jpg" alt="scatter-plot"></div>
<div class="plot_title">scatter plot</div>
</div>
<div class="image_text_content">
<div class="image_container"><img src="Content/images/plot-thumbs/2-line-plot.jpg" alt="scatter-plot"></div>
<div class="plot_title">line plot</div>
</div>
</li>
</ul>
</div>
</span>
application.js
// modal to display types of plots
$(document).ready(function() {
$('#plots_container').click(function() {
$('#plotList').fadeToggle();
})
$(document).mouseup(function (e) {
var container = $("#plotList");
if (!container.is(e.target) // if the target of the click isn't the container...
&& container.has(e.target).length === 0) // ... nor a descendant of the container
{
container.fadeOut();
}
});
});
A quick JSFiddle: https://jsfiddle.net/hxnm7q2L/1/ to show how you can use an
.addEventListener("change", function(e) {
to trigger showing the value changing of a selected value in a modal.
If I correctly understood what you want, you could try something like this:
$('.plot_title').click(function(event){
$('#plots_container > span').html(event.target.innerText);
})
Though it would work only with html-structure that you've provided, since it has very specific css-selectors.
I have a simple menu bar for displaying a couple different menus. When I click the first one the image comes up, but when I click the 2nd I need the 1st one to disappear and the 2nd appear in its place.
What happens right now is I click "Main Menu" and it opens, but then I need to click it again to close it.
<div class='rmm' data-menu-style = "graphite" data-menu-title = "Menu">
<ul>
<li>Main Menu Show</li>
<li>Gluten Friendly</li>
<li>Kids Menu</li>
</ul>
</div>
<div id="main_menu" style="display:none;"><a href="http://xxxxxx"></div>
<div id="gluten_friendly" style="display:none;"><a href="http://xxxxx"></div>
<div id="kids_menu" style="display:none;"><a href="http://xxxxx"></div>
=====Javascript
<script type="text/javascript">
function hideshow(temp){
var menu = document.getElementById(temp);
if (menu.style.display=="block")
menu.style.display="none"
else
menu.style.display="block"
return false;
}
</script>
I've updated the code from Sid, which works a little better than what I had, but when I click "Main Menu" it opens and I still need to click it again to close, but also when I click "Kids Menu" that one opens right below the "Main Menu".
I know I'm getting close, haha, ughh.
This is part of my Company Website so I don't really want to post the link in public, but if someone can help me please shoot me an email and I will send you the live link so you can see what I'm dealing with. It would be greatly appreciated and I'll gladly make note of the help here on the forum.
seansugden#britishbeer.com
The following may not be the best solution but works OK for me.
HTML
<div class='rmm' data-menu-style = "graphite" data-menu-title = "Menu" >
<ul>
<li>Main Menu Show</li>
<li>Gluten Friendly</li>
<li>Kids Menu</li>
<li>Desserts</li>
</ul>
</div>
<div id="main_menu"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="gluten_friendly"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="kids_menu"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
<div id="desserts"><a href="http://xxxxxxx"><img src="http://xxxxxx" height="650" width="650"></div>
JavaScript
function hideshow(temp){
var menu = temp.id;
if (menu == "main_menu") {
document.getElementById('main_menu').style.display="block";
}
else
{
document.getElementById('main_menu').style.display="none";
}
if (menu == "gluten_friendly") {
document.getElementById('gluten_friendly').style.display="block";
}
else
{
document.getElementById('gluten_friendly').style.display="none";
}
if (menu == "kids_menu") {
document.getElementById('kids_menu').style.display="block";
}
else
{
document.getElementById('kids_menu').style.display="none";
}
if (menu == "desserts") {
document.getElementById('desserts').style.display="block";
}
else
{
document.getElementById('desserts').style.display="none";
}
}
Demo
Try using underscores _ or dashes - instead of spaces for the id attributes. As Brett said in his comment, the ones with spaces are invalid.
As for hiding them all, you can give the divs a common class
<div class="image" id="main-menu"> ... </div>
and use document.getElementsByClassName('class-name') to retrieve an array to loop over and hide (before showing the selected one).
var divs = document.getElementsByClassName('image');
for(var i in divs){
div.style.display = 'none';
}
I do something similar on my website. You need to give them all a class and do the following when one is clicked:
$('#desserts').click(function(){
$('.menus').hide();
$('#desserts').show();
});
When you click desserts, first all menus are closed, then desserts is opened. I don't completely understand what you want to show and hide but I'm sure you'll be able to adapt it.