I am trying to make a custom select just like this, but without jquery (I just dont want to import a whole new library for one single thing). I made it until this, but I dont know how I can make the selection with regular JS. How can I select something from the list?
If you just want to show the selected item in the dropdown,
You need to wrap the text to be displayed inside a <span> as follows
<div class="label"><span>Select Element</span><b class="button">▾</b>
</div>
Then you can change it's innterHTML to display the selected item using the following js:
var dd = document.querySelector('.label span');
var options = document.querySelectorAll('div.hidden ul li');
for (var i = 0; i < options.length; i++) {
options[i].onclick = select;
}
function show() {
var selectbox = document.getElementById("options");
if (selectbox.className == "hidden") {
selectbox.setAttribute("class", "visible");
} else {
selectbox.setAttribute("class", "hidden");
}
}
function select() {
dd.innerHTML = this.innerHTML;
}
Demo
Listen to clicks on your div#options. Demo
function choose(ev, el) {
var options = el, target = ev.target,
value = ev.target.innerHTML;
options.setAttribute('class', 'hidden');
options.parentElement.querySelector('.label').innerHTML = value;
}
<div id="options" class="hidden" onclick='choose (event, this);'>
Side notes. I don't recommend to use inline handlers. Use addEventListener instead.
You need to define an onclick handler of your li elements. Either in HTML, or in JS by looping through children of div container with li elements http://jsfiddle.net/rWU5t/2/
If you want fancy item highlights on mouse hover, you also need to define onmouseover and onmouseout handlers.
Related
I have two buttons defined with their IDs : but-toggle, but-close for show hide a panel :
<button id="but-toggle">Panel</button>
<div id="main-panel" style="display:none">
<button id="but-close">X</button>
<!-- some panel data -->
</div>
Now i have a JS function which toggle the panel (show/hide) assigned to but-toggle as following :
(function(){document.getElementById("but-toggle").addEventListener("click",function(){
var pan = document.getElementById("main-panel");
if(pan.style.display==="inline-block")
{pan.style.display="none"}
else
{pan.style.display="inline-block"}
});})();
My question is how to use the same function for both buttons without writing two func, one for each.
I want a solution for elements based on their ids, since the classes are differents and can't use getElementByClass for this
Thanks
You can use document.querySelector to get a list of elements from a list of IDs:
function toggleFn() {
const pan = document.getElementById("main-panel");
if(pan.style.display === "inline-block") {
pan.style.display = "none";
} else {
pan.style.display = "inline-block";
}
}
document.querySelector("#Id1, #Id2")
.forEach(elem => elem.addEventListener(toggleFn);
You can use the below to get all buttons
var btns=document.getElementsByTagName('button');
for (let i = 0; i < btns.length; i++) {
btns[i].addEventListener("click", function() {
//code
});
}
(OR)
if you use input tag with type button
document.querySelectorAll("input[type=button]");
(OR)
Based on multiple IDs
document.querySelectorAll('#id1, #id2, #id3');
then you can add eventListener
I have a problem with pure JS list. I want the div with content (below each li) to display once the particular li is clicked. No idea how to make it work. I'm either ablo to show one "content" block or all of the at once (by adding the once that are commented now. Any help appreciated.
const channelList = document.getElementById("station-list");
channelList.addEventListener("click", function (e) {
const target = e.target;
if (target.matches("li")) {
content.classList.toggle("show");
//content2.classList.toggle("show");
//content3.classList.toggle("show");
//content4.classList.toggle("show");
//content5.classList.toggle("show");
//content6.classList.toggle("show");
}
})
https://jsbin.com/valojoruhe/1/edit?html,js,output
Try something like this:
Fiddle example: https://jsfiddle.net/eugensunic/9ebxvt1u/
your div's must be inside a li, otherwise you'll have invalid html
do not use multiple id's content, content1, content2 ... it's useless, rather define a class.
after you've clicked on the li element find the div element (filter it out) and then apply the desired styling to it.
you'll need to adjust the layout for your div to be below the paragraph, for now it's on the right side but toggles appropriately.
JS
const getAllLiElements = document.querySelectorAll('li');
for (let i = 0; i < getAllLiElements.length; i++) {
let element = getAllLiElements[i];
element.addEventListener('click', () => {
const dummyText = Array.from(element.children).filter(htmlNode => htmlNode.tagName === 'DIV')[0]
dummyText.classList.toggle('show')
})
}
This is the thing I have:
A normal select with a few options...
And the thing is, I do need to click in some other div and when I click on that one, I want the select list to show up as they were clicked normally and then allow the user to choose from the select options
I have some code already
<div onclick="set_select()"></div>
<select class='form-control' id='opts'>
<option selected disabled></option>
<option>Contacto</option>
<option>Entrevista</option>
<option>Prensa</option>
<option>Conferencias</option>
</select>
<script type="text/javascript">
function set_select(){
var select = document.getElementById('opts');
return select.active = true;
}
</script>
Not possible with plain html/javascript.
You need some plugin to replace your standard select field with divs and then use your function to trigger that divs. One is selectmenu: https://jqueryui.com/selectmenu/#product-selection
There is a lot more of them available: https://www.google.pl/search?q=js+select+replacement&gws_rd=cr&ei=wN5ZV8SjMIGLsgGP_IboDQ
This is "sort" of possible but not trivial and you will need to possibly do some management of the effect as I do here in the "change" event for the select. Not perfect but perhaps this can give you a start.
Note you MIGHT just want to use the "focus" on the select or, set the visible size as I do here, set the select size on the change to 0 with event.target.size = 0; and so forth.
Revised the markup a bit to allow the click handler:
<div id="clicker">clicker</div>
<select class='form-control' id='opts'>
<option selected disabled></option>
<option>Contacto</option>
<option>Entrevista</option>
<option>Prensa</option>
<option>Conferencias</option>
</select>
Here is the script, as I said, not perfect but you can decide how you handle the change/click events.
window.onload = function() {
var id = "clicker";
var div = document.getElementById(id);
var select = document.getElementById("opts");
div.onclick = function(event) {
console.log('clicker div');
select.size = select.options.length;
select.focus();
};
select.onclick = function(event) {
console.log('opt clicked');
};
select.onchange = function(event) {
console.log('opt change');
var index = event.target.selectedIndex;
console.log(index);
event.target.size = index + 2;
};
}
Here is a fiddle you can use to get you started: https://jsfiddle.net/MarkSchultheiss/mL0b7ubr/
Note that if you wish to use the "default" size for the select you can detect that like so:
if (event.target.type == "select-one") {
event.target.size = 1;
} else {
event.target.size = 4;
}
Here is a fiddle with that change and a bit cleaner on the event attachment: https://jsfiddle.net/MarkSchultheiss/mL0b7ubr/1/
I'm having some trouble creating a JavaScript function using an select element and id link. The function should depend on the selected option/value of the select dropdon.
What I want to do, is call an event function when the select dropdown is clicked, then apply a class to the appropriate id.
The html is this:
<select class="select-trigger" >
<option value="value1">Value1</option>
<option value="Value2">Value2</option>
<option value="Value3">Value3</option>
</select>
And the elements to get a class added:
<div id="value1"></div>
<div id="value2"></div>
<div id="value3"></div>
And my function so far (almost working):
var trigger = document.querySelectorAll('.trigger');
for (var i =0; i < trigger.length; i++) {
var btn = trigger[i];
btn.addEventListener('click', function () {
var id = this.options[this.selectedIndex].value;
document.querySelector('#' + id).classList.toggle('active');
}, false);
}
I think the trouble I'm having is that I'm calling the function using click event listener. I guess I would need to use an onchange function instead?
Also I only want a single div to have an "active" class at any given time. At the moment, the function is adding the class but not removing it when another is selected.
Here's a fiddle http://jsfiddle.net/2Rcjt/1/
Note - I don't want to put any inline onclick JS in my markup.
You can save the last selected option (div) into some property of the select. Then each time user change the option, just toggle class on the last selected option to make it inactive. Code:
var trigger = document.querySelectorAll('.trigger');
for(var i = 0; i < trigger.length; i++){
trigger[i].onchange = function(){
if(this.lastOption) this.lastOption.classList.toggle('active');
this.lastOption = document.getElementById(this.value);
this.lastOption.classList.toggle('active');
};
trigger[i].onchange();
}
Demo.
I have a page with a content accordion with 8 items. I also have an h4 tag on the page outside of the accordion. I want to hide which ever content accordion item matches the text inside the h4 tag.
The text inside the h4 tag and the content accordion items might change so I need to use variables (I think).
Here is what I have so far:
var category = $('.leftColumnNav h4').html();
var topic = $('.contentAccordionItemTitle p').html();
if(topic === category){
$(".contentAccordionItemTitle").css("display", "none");
} else {
$(".contentAccordionItemTitle").css("display", "block");
}
What I have sort of works. It successfully hides the .contentAccordionItemTitle. Unfortunately it obviously hides all of them. I just want to hide the one that matches the h4 tag.
If it's needed I can probably create a JSFiddle example.
var category = $('.leftColumnNav h4').text();
$(".contentAccordionItemTitle").each(function() {
if ($(this).text() === category) { $(this).hide() }
})
var topic = $('.contentAccordionItemTitle p').html();
That line means you're getting all the p-tags. If you want to continue down this solution, you could use the jQuery each function -> http://api.jquery.com/each/
$(".contentAccordionItemTitle").css("display", "none");
} else {
$(".contentAccordionItemTitle").css("display", "block");
The $(".contentAccordionItemTitle") also gets all elements with this class.
You should use a loop, like jQuery each:
var category = jQuery('.leftColumnNav h4').html();
jQuery('.contentAccordionItemTitle p').each(function() {
if(jQuery(this).html() === category) {
jQuery(this).parent('.contentAccordionItemTitle').css('display', 'none');
} else {
jQuery(this).parent('.contentAccordionItemTitle').css('display', 'block');
}
This is assuming there is only one element that matches jQuery('.leftColumnNav h4')