Iam trying to do multiple select with JavaScript. but can't working.how can i fix this?
Iam done it in following way
var expanded = false;
function showCheckboxes() {
var checkboxes = document.getElementById("checkboxes");
if (!expanded) {
checkboxes.style.display = "block";
expanded = true;
} else {
checkboxes.style.display = "none";
expanded = false;
}
}
.multiselect {
width: 200px;
}
.selectBox {
position: relative;
}
.selectBox select {
width: 100%;
font-weight: bold;
}
.overSelect {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
}
#checkboxes {
display: none;
border: 1px #dadada solid;
}
#checkboxes label {
display: block;
}
#checkboxes label:hover {
background-color: #1e90ff;
}
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>check box1</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one"><input type="checkbox" id="one" />First checkbox</label>
</div>
</div>
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>check box2</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one"><input type="checkbox" id="one" />First checkbox</label>
</div>
</div>
<div class="multiselect">
<div class="selectBox" onclick="showCheckboxes()">
<select>
<option>check box3</option>
</select>
<div class="overSelect"></div>
</div>
<div id="checkboxes">
<label for="one"><input type="checkbox" id="one" />First checkbox</label>
</div>
</div>
you cannot have same id for multiple elements .it's invalid . however when you call getElementById() 1st element is taken .that's why in your example only 1st element expand and collapse .
here is example .
in this example i pass a parameter to showCheckboxes methods.so we can select correct checkboxes .also we have to store state of 3 elements individually.
https://jsfiddle.net/93894gbs/5/
js
var expanded = [false, false, false];
var checkboxes;
function showCheckboxes(i) {
checkboxes = checkboxes || document.getElementsByClassName("checkboxes");
if (!expanded[i]) {
checkboxes[i].style.display = "block";
expanded[i] = true;
} else {
checkboxes[i].style.display = "none";
expanded[i] = false;
}
}
Also you can pass "event" attribute while calling the handler like :
div class="selectBox" onclick="showCheckboxes(event)"
and change javascript like :
var expanded = false;
function showCheckboxes(ev) {
console.log("ev", ev);
var checkboxes = ev.currentTarget.parentElement.lastElementChild;
if (!expanded) {
checkboxes.style.display = "block";
expanded = true;
} else {
checkboxes.style.display = "none";
expanded = false;
}
}
Related
I have a page that contain different section these section appear when the user click on li an active class is added to the section and then this section appear
each section contain a box with checkboxes and a link to another page when i click on this link i should store the value of the checkboxes for the section active only to print them later
all the code work fine but my problem is that i only can have the checkbox value for the first section that contain active class by defaul
how can i solve that please?
/*Put active class on li click for section*/
let tabs = document.querySelectorAll(".nav li");
let tabsArray = Array.from(tabs);
let section = document.querySelectorAll(".section");
let sectionArray = Array.from(section);
tabsArray.forEach((ele) => {
ele.addEventListener("click", function (e) {
tabsArray.forEach((ele) => {
ele.classList.remove("active");
});
e.currentTarget.classList.add("active");
sectionArray.forEach((sec) => {
sec.classList.remove("active");
});
document.querySelector('#' + e.currentTarget.dataset.cont).classList.add("active");
});
});
/*put the check box value in localstorage to print them later*/
let printBtn = document.querySelector(".active .btn-print");
let terms = document.querySelectorAll(".active input[type='checkbox']");
let termsValChecked = [];
let termsValUnChecked = [];
printBtn.addEventListener("click", function (e) {
localStorage.removeItem("termschecked");
localStorage.removeItem("termsunchecked");
for (let i = 0; i < terms.length; i++) {
if (terms[i].checked == true) {
termsValChecked.push(terms[i].value);
} else {
termsValUnChecked.push(terms[i].value);
}
}
window.localStorage.setItem("termschecked", JSON.stringify(termsValChecked));
window.localStorage.setItem("termsunchecked", JSON.stringify(termsValUnChecked));
});
.box {
display: flex;
align-items: center;
}
section {
display: none;
}
section.active {
display: block;
}
.nav {
list-style:none;
display: flex;
align-items: center;
}
.nav li {
padding: 20px;
background-color: #ccc;
margin-left: 2px;
cursor: pointer;
}
<ul class="nav">
<li data-cont="r1">1</li>
<li data-cont="r2">2</li>
<li data-cont="r3">3</li>
</ul>
<section class="section section-one active" id="r1">
<h3>Section 1</h3>
<div class="box">
<input type="checkbox" value="test1">
<p>test1</p>
</div>
<div class="box">
<input type="checkbox" value="test2">
<p>test2</p>
</div>
<div class="print">
Print
</div>
</section>
<section class="section section-two" id="r2">
<h3>Section 2</h3>
<div class="box">
<input type="checkbox" value="test3">
<p>test3</p>
</div>
<div class="box">
<input type="checkbox" value="test4">
<p>test4</p>
</div>
<div class="print">
Print
</div>
</section>
<section class="section section-three" id="r3">
<h3>Section 3</h3>
<div class="box">
<input type="checkbox" value="test5">
<p>test5</p>
</div>
<div class="box">
<input type="checkbox" value="test6">
<p>test6</p>
</div>
<div class="print">
Print
</div>
</section>
querySelectorAll returns a static NodeList, i.e. the list will reflect the state at invocation and won't update if the page later changes.
The following line runs when you initialize your page:
let terms = document.querySelectorAll(".active input[type='checkbox']");
And that's why you always capture the first section in local storage.
You need to move this line inside your click handler so that you enumerate the checkboxes inside the .active section at that time.
Remove the Attribute ".change" from your selector on line 23
simply change
let terms = document.querySelectorAll(".active input[type='checkbox']");
to
let terms = document.querySelectorAll("input[type='checkbox']");
I have a div and when a checkbox is clicked I want to disable all the elements inside the div, including disabling the onClick of one of the elements. Here is the codepen: https://codepen.io/anon/pen/JVwMOq
HTML:
<input type="checkbox" onChange="checkMe(this)">
<div id="test">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe()">
</span>
</div>
JS:
function checkMe(element){
if($(element).prop('checked') === true){
$('#test').prop('disabled', true).off("click");
}
else{
$('#test').prop('disabled', false).on("click");
}
}
Any advice? Thanks!
You can use this, disabled with CSS.
you can't add disabled on div, it's working with input, etc..
$('#clickCheckbox').change(function() {
if($(this).is(":checked")) {
$('#test').addClass('disable-button');
}else{
$('#test').removeClass('disable-button')
}
$('#clickCheckbox').val($(this).is(':checked'));
});
.disable-button {
pointer-events: none;
cursor: not-allowed;
text-decoration: none;
color: white;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="checkbox" id="clickCheckbox">
<div id="test">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe()">
</span>
</div>
I have a working solution below.
I have added in an additional input field to check it works on multiple items.
I created an checking function to see if your item is checked.
const isChecked = (element) => document.getElementById(element.id).checked ? true : false
Then updated the likeMe function to pass in the current id and returned null if the checkbox is checked.
function likeMe(element) {
if (isChecked(element)) {
return null
} else {
console.log('Calling likeMe()');
}
}
Then I updated your checkMe function to pass in the current element and the targetdiv so this would be more reusable across other parts of your code.
function checkMe(element, targetDiv) {
const targetDivInput = `#${targetDiv} input`
const targetDivClassName = `.${targetDiv}`
if (isChecked(element)) {
$(targetDivInput).prop('disabled', true);
$(targetDivClassName).toggleClass('disabled')
} else {
$(targetDivInput).prop('disabled', false);
$(targetDivClassName).toggleClass('disabled')
}
}
Then made some small changes to the markup to pass in the ids into your functions
<div id="test">
<input type="text">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe('test')">
</span>
</div>
and added a disabled state to your css so the user wouldn't see the cursor.
#like{
cursor: pointer;
}
.disabled #like {
cursor: inherit;
}
This is the final result.
#like{
cursor: pointer;
}
.disabled #like {
cursor: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script>
const isChecked = (element) => document.getElementById(element.id).checked ? true : false
function likeMe(element) {
if (isChecked(element)) {
return null
} else {
console.log('Calling likeMe()');
}
}
function checkMe(element, targetDiv) {
const targetDivInput = `#${targetDiv} input`
const targetDivClassName = `.${targetDiv}`
if (isChecked(element)) {
$(targetDivInput).prop('disabled', true);
$(targetDivClassName).toggleClass('disabled')
} else {
$(targetDivInput).prop('disabled', false);
$(targetDivClassName).toggleClass('disabled')
}
}
</script>
<input id="textCheck" type="checkbox" onChange="checkMe(this,'test')">
<div id="test">
<input type="text">
<input type="text">
<span class="test">
<img id="like" src="https://cdn4.iconfinder.com/data/icons/game-interface-outline/100/objects-15-512.png" height="40px" onclick="likeMe('test')">
</span>
</div>
I'm looking for a simple, non-jquery method of toggling between two divs. Specifically, clicking button A will show div A content (and hide div B content), and clicking button B will show div B content (and hide div A content. I want div A content to appear by default when the page loads.
The code I have isn't hiding the appropriate divs from the onclick
I've looked around, but every solution seems overly complex or seems to involve jquery - which I would really prefer not to use, because I have to work with an old jquery library on a site where I shouldn't be updating that stuff.
<button class="button" onclick="content_A(); Hide_Content_B;">Content A</button>
<button class="button" onclick="content_B(); Hide_Content_A;">Content B</button>
<script>
function Content_A() {
var x = document.getElementById("A");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
<script>
function Hide_Content_B() {
var x = document.getElementById("B");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "none";
}
}
</script>
<script>
function Content_B() {
var x = document.getElementById("B");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
</script>
<script>
function Hide_Content_A() {
var x = document.getElementById("A");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "none";
}
}
</script>
<div id="A"> stuff</div>
<div id="B"> other stuff </div>
Create one function showContent that takes the id of the element you want
to toggle as parameter and just toggles a CSS class, i.e visible on the element with that id.
Use CSS classes to initially hide the "toggleable" elements. You can set the visible class directly on the element you want shown on page load.
Here's an example:
function showContent(id) {
document.getElementById(id).classList.toggle('visible')
}
/*
All elements with class "toggleable"
should be hidden.
*/
.toggleable {
display: none;
}
/*
All elements that have both
class "toggleable" and "visible"
should be visible.
*/
.toggleable.visible {
display: block;
}
<button onclick="showContent('a');" >Show Content A</button>
<button onclick="showContent('b');" >Show Content B</button>
<div class="toggleable visible" id="a">
Hello Content A!
</div>
<div class="toggleable" id="b">
Hello Content B!
</div>
About your code:
You have to call the function using parenthesis like Hide_Content_A() and Hide_Content_B(); which are misssing in onclick of the <button>
The functions Content_B and Content_B start with uppercase C.
The fix your own code, just run Hide_Content_B(); at the end to hide the second one.
Note that you can also use a single <script> block.
function Content_A() {
var x = document.getElementById("A");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function Hide_Content_B() {
var x = document.getElementById("B");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "none";
}
}
function Content_B() {
var x = document.getElementById("B");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
}
function Hide_Content_A() {
var x = document.getElementById("A");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "none";
}
}
Hide_Content_B();
<button class="button" onclick="Content_A(); Hide_Content_B();">Content
A
</button>
<button class="button" onclick="Content_B(); Hide_Content_A();">Content
B
</button>
<div id="A"> stuff</div>
<div id="B"> other stuff</div>
If you dont want to use jQuery, you should consider not using javascript at all.
You can do the same with pure css. Also the styling of button tags some times brakes in other devices, so I suggest to use tag or just a span
Here is a pure CSS solution:
input {
display:none;
}
input[name="toggle"] + .toggleContent{
max-height: 0;
overflow: hidden;
transition: max-height .4s;
}
input[name="toggle"]:checked + .toggleContent{
max-height: 100px;
}
<label for="A">A Button</label>
<input type="radio" name="toggle" value="1" id="A" checked="checked">
<div class="toggleContent">This is content for A</div>
<label for="B">B Button</label>
<input type="radio" name="toggle" value="2" id="B">
<div class="toggleContent">This is content for B</div>
Here's a simple solution that requires jQuery 1.7 or above, since you mentioned that you're working with an old jQuery library!
$(document).on('click', '.map-point-sm', function() {
var show = $(this).data('show');
$(show).removeClass("hide").siblings().addClass("hide");
});
.hide {
display: none;
}
.map-container {
text-align: center;
}
button{
width: 5%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<div class="map-container">
<div class="inner-basic division-map div-toggle" data-target=".division-details" id="divisiondetail">
<button class="map-point-sm" data-show=".a">
<div class="content">
<div class="centered-y">
<p>A</p>
</div>
</div>
</button>
<button class="map-point-sm" data-show=".b">
<div class="content">
<div class="centered-y">
<p>B</p>
</div>
</div>
</button>
</div>
</div>
<div class="map-container">
<div class="inner-basic division-details">
<div class="initialmsg">
<p>A Content here</p>
</div>
<div class="a hide">
<p>A Content here</p>
</div>
<div class="b hide">
<p>B Content here</p>
</div>
</div>
</div>
There are some great answers here, but I think I'll probably go with The fourth bird's because it's the simplest. Thanks everybody!
If you are interested in a non-JS solution, you can use sibling input elements to perform a button toggle effect. Simply match the for attributes with the id attributes.
form {
display: flex;
flex-wrap: wrap;
}
input {
display: none;
}
input:checked + label {
background-color: #eee;
}
label {
cursor: pointer;
padding: 12px;
display: inline-block;
}
.container {
display: none;
background-color: #eee;
order: 1;
padding: 12px;
width: 100%;
}
input:checked + label + .container {
display: block;
}
<form>
<input id="a" type="radio" name="container" checked="checked">
<label for="a">button a</label>
<div class="container">content a</div>
<input id="b" type="radio" name="container">
<label for="b">button b</label>
<div class="container">content b</div>
</form>
I am trying to create a dropdown with multi-select check box manually using jQuery.
I don't want to use any built in libraries other than jQuery. I tried implementing the functionality but the issue is, when I select the check boxes, the data will be popped up in input field, if I click for the second time, I can see that checkboxes are unchecked and data is not appending to previous one.
Please tell me where i went wrong in the code.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Untitled Document</title>
<style>
.multiselect {
width: 200px;
}
.selectBox {
position: relative;
}
.selectBox select {
width: 100%;
font-weight: bold;
}
.overSelect {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
}
#presentationTable {
display: none;
border: 1px #dadada solid;
}
#presentationTable label {
display: block;
}
#presentationTable label:hover {
background-color: #1e90ff;
}
</style>
</head>
<body>
<form>
<div class="multiselect">
<div class="selectBox" onClick="showCheckboxes()">
<input type="text" id="presentatioonTableimputValue"><img src="http://siged.sep.gob.mx/analytics/res/s_blafp/uicomponents/obips.CommonIconSets/dropdownfilled_en_choicelistmulti.png" />
<div class="overSelect"></div>
</div>
<div id="presentationTable"> </div>
</div>
</form>
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script>
var expanded = false;
function showCheckboxes()
{
var abc = '<label><input type="checkbox" id="one" value="1"/>First1 checkbox</label> <label><input type="checkbox" id="two" value="two"/>Second checkbox </label> <label><input type="checkbox" id="three" value="three"/>Third checkbox</label>';
$('#presentationTable').html(abc);
if (!expanded) {
$('#presentationTable').show();
expanded = true;
} else {
$('#presentationTable').hide();
expanded = false;
}
}
function updateTextArea()
{
var allVals = [];
$('#presentationTable :checked').each(function () {
allVals.push($(this).val());
});
$('#presentatioonTableimputValue').val(allVals);
}
$(document).click(function(event){
var $trigger = $(".multiselect");
if($trigger !== event.target && !$trigger.has(event.target).length){
$("#presentationTable").slideUp("fast");
updateTextArea();
}
});
</script>
</body>
</html>
Try this:
JS
var expanded = false;
populateCheckbox();
function populateCheckbox(){
var abc = '<label><input type="checkbox" id="one" value="1"/>First1 checkbox</label> <label><input type="checkbox" id="two" value="two"/>Second checkbox </label> <label><input type="checkbox" id="three" value="three"/>Third checkbox</label>';
$('#presentationTable').html(abc);
}
function showCheckboxes()
{
if (!expanded) {
$('#presentationTable').show();
expanded = true;
} else {
$('#presentationTable').hide();
expanded = false;
}
}
function updateTextArea()
{
var allVals = [];
$('#presentationTable :checked').each(function () {
allVals.push($(this).val());
});
$('#presentatioonTableimputValue').val(allVals);
}
$("#presentationTable label input").click(function(){
updateTextArea();
});
$(document).click(function(event){
var $trigger = $(".multiselect");
if($trigger !== event.target && !$trigger.has(event.target).length){
$("#presentationTable").slideUp("fast");
// updateTextArea();
}
});
Each time when you click on the input field, it is creating new checkboxes, That was the issue.
hope it will solve your problem.
I want this list to behave as an accordion. I have to do this in pure javascript without using jQuery or other external libraries. I am not allowed to adjust the HTML code shown below.
<ul class="accordion">
<li>Apple
<ul>
<li>abc</li>
<li>xyz</li>
<li>pqr</li>
</ul>
</li>
<li>Apple1</li>
<li>Apple2</li>
<li>Apple3</li>
<li>Apple4</li>
</ul>
I have javascript code below provided by #Ruud, which is showing accordion menu but it does not have animation effect. I want animation effect with only one item activated at a time
window.getTopUL = function() {
var uls = document.getElementsByTagName('UL');
for (var i = 0; i < uls.length; i++) {
if (uls[i].className == 'accordion') return uls[i];
}
return null;
};
window.getChild = function(li, tag) {
return li.getElementsByTagName(tag)[0];
};
window.toggleDisplay = function(s) {
s.display = s.display == 'none' ? 'block' : 'none';
};
window.setEventHandlers = function(topUL) {
if (topUL) {
var lis = document.getElementsByTagName('LI');
for (var i = 0; i < lis.length; i++) {
var ul = getChild(lis[i], 'UL');
if (ul) {
ul.style.display = 'none';
getChild(lis[i], 'A').onclick = function() {
toggleDisplay(getChild(this.parentNode, 'UL').style);
return false;
}
}
}
}
};
setEventHandlers(getTopUL());
window.getTopUL = function() {
var uls = document.getElementsByTagName('UL');
for (var i = 0; i < uls.length; i++) {
if (uls[i].className == 'accordion') return uls[i];
}
return null;
};
window.getChild = function(li, tag) {
return li.getElementsByTagName(tag)[0];
};
window.toggleDisplay = function(s) {
s.display = s.display == 'none' ? 'block' : 'none';
};
window.setEventHandlers = function(topUL) {
if (topUL) {
var lis = document.getElementsByTagName('LI');
for (var i = 0; i < lis.length; i++) {
var ul = getChild(lis[i], 'UL');
if (ul) {
ul.style.display = 'none';
getChild(lis[i], 'A').onclick = function() {
toggleDisplay(getChild(this.parentNode, 'UL').style);
return false;
}
}
}
}
};
setEventHandlers(getTopUL());
<ul class="accordion">
<li>Apple
<ul>
<li>abc
</li>
<li>xyz
</li>
<li>pqr
</li>
</ul>
</li>
<li>Apple1
</li>
<li>Apple2
</li>
<li>Apple3
</li>
<li>Apple4
</li>
</ul>
You can do it with simple html and css also
/* Clean up the lists styles */
ul.accordion {
list-style: none;
margin: 0;
padding: 0;
}
/* Hide the radio buttons */
/* These are what allow us to toggle content panes */
ul.accordion label + input[type='radio'] {
display: none;
}
/* Give each content pane some styles */
ul.accordion li {
background-color: #CCCCCC;
border-bottom: 1px solid #DDDDDD;
}
/* Make the main tab look more clickable */
ul.accordion label {
background-color: #666666;
color: #FFFFFF;
display: block;
padding: 10px;
}
ul.accordion label:hover {
cursor: pointer;
}
/* Set up the div that will show and hide */
ul.accordion div.content {
overflow: hidden;
padding: 0 10px;
display: none;
}
/* Show the content boxes when the radio buttons are checked */
ul.accordion label + input[type='radio']:checked + div.content {
display: block;
}
<ul class='accordion'>
<li>
<label for='cp-1'>Content pane 1</label>
<input type='radio' name='a' id='cp-1' checked='checked'>
<div class='content'>
<p>content to be displayed</p>
</div>
</li>
<li>
<label for='cp-2'>Content pane 2</label>
<input type='radio' name='a' id='cp-2'>
<div class='content'>
<p>content to be displayed</p>
</div>
</li>
<li>
<label for='cp-3'>Content pane 3</label>
<input type='radio' name='a' id='cp-3'>
<div class='content'>
<p>content to be displayed</p>
</div>
</li>
<li>
<label for='cp-4'>Content pane 4</label>
<input type='radio' name='a' id='cp-4'>
<div class='content'>
<p>content to be displayed</p>
</div>
</li>
<li>
<label for='cp-5'>Content pane 5</label>
<input type='radio' name='a' id='cp-5'>
<div class='content'>
<p>content to be displayed</p>
</div>
</li>
</ul>