Edit to answer: OK, so it seems this problem has come up before. The key seems to be in the return false; statement in the js prepareList function. I commented it out and now the code works fine. For more information and a more complete answer, here is the previous version of the question.
EDIT: Here's a jsfiddle that reproduces the error.
I'm trying to make a form using the expandable list code found here, and my checkboxes and radio buttons are either unresponsive or glitchy. They both know they're being pressed, they change to the depressed image when I click on them, but they don't update their value. For radio buttons, I can click one and it works, but then the others in that group become unresponsive. I have a dummy php page to just print out the results of the form, but it doesn't appear to be receiving any data. NOTE: This is my first website project, there may be something completely obvious that I'm just missing.
Here's a sample of the HTML:
<div id="listContainer">
<div class="listControl">
<a id="expandList">Expand All</a>
<a id="collapseList">Collapse All</a>
</div>
<form id="ColForm" action="Table.php" method="post"> <!--Organized list of collumns and filter options-->
<ul id="expList">
<li>Section heading
<ul>
<li><input type="checkbox" name="ColSelect" value="Name" form="ColForm"> <!--If checked, collumn will be included in final table--> Name
<ul>
<li>
<input type="text" name="Name" form="ColForm"><br> <!--filter parameter input-->
</li>
</ul>
</li>
<li><input type="checkbox" name="ColSelect" value="RA,Dec" form="ColForm">Another collumn
<ul>
<li>
<input type="radio" name="PoSearch" value="Range" form="ColForm">Radio button to select form type for this section<br>
<i>I have an option here
<input type="radio" name="Degs" value="Dec" form="ColForm">Option 1
<input type="radio" name="Degs" value="Hex" form="ColForm">Option 2</i><br>
Text input 1<br>
<input type="text" name="RA" form="ColForm">deg<br>
Text input 2<br>
<input type="text" name="Dec" form="ColForm">deg<br>
<input type="radio" name="PoSearch" value="Area" form="ColForm">Second form option<br>
<i>Text input A</i><br>
<input type="text" name="Area" form="ColForm"><br>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<input type="submit" value="submit" form="ColForm">
</form>
</div>
And here's the javascript for the list function:
/**************************************************************/
/* Prepares the cv to be dynamically expandable/collapsible */
/**************************************************************/
function prepareList() {
$('#expList').find('li:has(ul)')
.click( function(event) {
if (this == event.target) {
$(this).toggleClass('expanded');
$(this).children('ul').toggle('medium');
}
return false;
})
.addClass('collapsed')
.children('ul').hide();
//Create the button functionality
$('#expandList')
.unbind('click')
.click( function() {
$('.collapsed').addClass('expanded');
$('.collapsed').children().show('medium');
})
$('#collapseList')
.unbind('click')
.click( function() {
$('.collapsed').removeClass('expanded');
$('.collapsed').children().hide('medium');
})
};
$(document).ready( function() {
prepareList()
});
And the relevant CSS:
#listContainer{
margin-top:15px;
}
#expList ul, li {
list-style: none;
margin:0;
padding:0;
cursor: pointer;
}
#expList p {
margin:0;
display:block;
}
#expList p:hover {
background-color:#121212;
}
#expList li {
line-height:140%;
text-indent:0px;
background-position: 1px 8px;
padding-left: 20px;
background-repeat: no-repeat;
}
/* Collapsed state for list element */
#expList .collapsed {
background-image: url(../img/collapsed.png);
}
/* Expanded state for list element
/* NOTE: This class must be located UNDER the collapsed one */
#expList .expanded {
background-image: url(../img/expanded.png);
}
#expList {
clear: both;
}
The issue here is with event.preventDefault() in your code. It's keeping the checkboxes / radio buttons from performing their default behavior. Removing that entry will allow the input tags to function normally. But they will no longer trigger the expand and collapse functionality you're looking for.
You'll need to modify your JS to also listen for the click on the checkboxes. Here are some similar situations that may help you:
making on-click events work with checkboxes
clicking on a div to check / uncheck a checkbox
Related
Ive been thinking about this for days... seems simple but I can't wrap my head around it!
We want to make a simple booking form, where people chose a day and then see two columns of available time slots. I already generate a lost of these.
Now I need to display this in buttons, so they can be pressed and only 1 is selected. So if they choose 2pm Wednesday, and then another, the first goes back to the standard color...
This value needs to be loaded in a hidden field to pass on to the next page.
Having searched it seems like the colors are best done in jquery and the hidden field can be populated easily with vanilla js, that part I have working... Help, how add the color change?
ps this is on a bootstrap 3.4 template, not that that should matter but maybe
<input type="button" id = "booktime" onclick="change(this)" class="btn btn-default" value=" & thishour & ">
function change(bookingtime) {
document.getElementById("myInput").value= bookingtime.value;
}
var links = $('#booktime');
links.click(function() {
links.css('background-color', 'white');
$(this).css('background-color', 'purple');
});
Consider the following HTML and jQuery example.
$(function() {
$(".booking label").click(function() {
var $self = $(this).parent();
$("input", $self).trigger("click");
$(".checked").removeClass("checked");
$self.addClass("checked");
});
$("form").submit(function(e) {
e.preventDefault();
var formData = new FormData(this);
for (var pair of formData.entries()) {
console.log(pair[0] + ', ' + pair[1]);
}
});
});
.booking ul {
list-style: none;
padding: 0;
width: 100px;
}
.booking li {
border: 1px outset rgb(224, 224, 224);
border-radius: 6px;
background: #eee;
padding: 7px;
text-align: center;
margin-bottom: 3px;
font-family: Arial, sans-serif;
}
.booking li.checked {
background: #aaf;
}
.booking li:hover {
background: #ccc;
}
.booking li input {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form>
<div class="booking">
<ul>
<li>
<input type="radio" id="time-0000" name="time" value="12:00">
<label for="time-0000">12:00 AM</label>
</li>
<li>
<input type="radio" id="time-0100" name="time" value="01:00">
<label for="time-0100">1:00 AM</label>
</li>
<li>
<input type="radio" id="time-0200" name="time" value="02:00">
<label for="time-0200">2:00 AM</label>
</li>
<li>
<input type="radio" id="time-0300" name="time" value="03:00">
<label for="time-0300">3:00 AM</label>
</li>
<li>
<input type="radio" id="time-0400" name="time" value="04:00">
<label for="time-0400">4:00 AM</label>
</li>
</ul>
</div>
<button type="submit">Save</button>
</form>
Most of the User Interface is all CSS. You can make it a bit mo9re custom and include a better look and feel with additional JavaScript. The default function of the Radio Button will help.
Radio buttons are normally presented in radio groups (a collection of radio buttons describing a set of related options). Only one radio button in a group can be selected at the same time.
This will help each button retain a State, either Checked or Unchecked. only one can be checked at a time, so we can simple clear the Styling from any other and apply it to the one clicked upon.
So i have made a custom selector like
<div class="search">
<input class="custom-selector" type="text" autocomplete="off" >
<ul class="custom-options hidden">
<li>New York</li>
<li>Moscow</li>
<li>Baku</li>
</ul>
</div>
and whenever i focus on the input the class hidden(only has display:none;) gets removed, and on blur(unfocus) it gets added back
$('.custom-selector').focus(function() {
$(".custom-options").removeClass("hidden");
}).blur(function() {
$(".custom-options").addClass("hidden");
})
On the next step i needed a function to onclick get the li value and copy it to the input ,but whenever i click on the li ,the input gets unfocused and the onclick function cant work on a display none,one solution i found was opacity 0 instead of display none for hidden class,is there more optimal and correct way to fix this issue?
Edit: You can add a timeout maybe?
$('.custom-selector').focus(function() {
$(".custom-options").removeClass("hidden");
}).blur(function() {
setTimeout(function () { $(".custom-options").addClass("hidden") }, 350);
})
$('.custom-options > li').click(function(e) {
$('.custom-selector').val($(this).text());
});
.hidden {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search">
<input class="custom-selector" type="text" autocomplete="off">
<ul class="custom-options hidden">
<li>New York</li>
<li>Moscow</li>
<li>Baku</li>
</ul>
</div>
You could use a combination of focusable elements and the :focus-within pseudo-class to not lose focus.
$('.custom-options a').click(function (ev) {
const selected = ev.target.textContent;
$('.custom-selector').val(selected);
ev.target.blur();
});
.custom-options {
display: none;
}
.search:focus-within .custom-options {
display: block;
}
.custom-options a {
text-decoration: none;
color: inherit;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="search">
<input class="custom-selector" type="text" autocomplete="off">
<ul class="custom-options">
<li>
New York
</li>
<li>
Moscow
</li>
<li>
Baku
</li>
</ul>
</div>
I have two custom styled radio buttons that look like below [just an example]
li {
width: 100px;
border: 1px solid black;
display: inline-block;
}
<ul>
<li>
<input type="radio" name="radio-test" id="radio1">
<div>
<label for="radio1">Radio One</label>
</div>
</li>
<li>
<input type="radio" name="radio-test" id="radio2">
<div>
<label for="radio2">Radio Two</label>
</div>
</li>
</ul>
Once this has been made to look prettier, I would ideally want that clicking anywhere inside the box enclosing a radio button should trigger activation of that choice.
My team mates have used custom styles and images to show selection and hence I do not want to modify CSS.
I was trying to think of a way to implement mentioned functionality with Javascript.
Attack a click event-handler on the li and trigger a click on the underlying input but that causes an infinite recursion of event triggers.
This raised 2 questions in my mind:
Is there a way to stop the the click recursion? I tried preventDefault and stopPropagation on the JS triggered click but
they do not seem to accomplish what I want.
Can we user JavaScript(or jQuery if needed) to differentiate between a real mouse click and a JS triggered click event?
You were on the right track. You just need to stop the propagation from the input back up to the list item:
$('li').click(function() {
$(this).find('input').click()
})
$('input').click(function(e) {
e.stopPropagation();
})
li {
width: 100px;
border: 1px solid black;
display: inline-block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li>
<input type="radio" name="radio-test" id="radio1">
<div>
<label for="radio1">Radio One</label>
</div>
</li>
<li>
<input type="radio" name="radio-test" id="radio2">
<div>
<label for="radio2">Radio Two</label>
</div>
</li>
</ul>
I need to count :checked checkboxes on popover content on bootstrap 3.
The problem is when I change checkboxes and close popover it doesn't saved. I tried to reinstall/destroy popovers and change dynamically content option, but no results.
I also tried to create empty array and count checked checkboxes by hands, push every new check to array, but no result again and it is very hard way.
js:
$(function () {
$('.item').popover({
placement: 'bottom',
html: true,
content: function () {
return $(this).find('.filters').html();
}
});
$('#count').click(function() {
var filter = $('.item input[type=checkbox]:checked').map(function () {
return this.value;
}).get();
$('#res').text(filter);
});
});
html:
<div class="item">
click for popover
<div class="filters">
<ul class="list-unstyled">
<li>
<input type="checkbox" value="1" checked="checked" id="filter1">
<label for="filter1">Filter 1</label>
</li>
<li>
<input type="checkbox" value="2" checked="checked" id="filter2">
<label for="filter2">Filter 2</label>
</li>
<li>
<input type="checkbox" value="3" id="filter3">
<label for="filter2">Filter 3</label>
</li>
</ul>
</div>
</div>
<br>
count
<div id="res"></div>
css:
.filters {
display: none;
}
.popover-content {
width: 100px;
}
update: http://jsfiddle.net/sirjay/0vetvfpz/
When you create the popover, you duplicate the content of your .filters div, meaning that you have it twice. One that's hidden because it's in the .filters div that's hidden because of
.filters {
display: none;
}
and one that's visible in your popover.
When you're counting, you're actually counting the checked boxes that are invisible and not those in the popover. The popover gets created outside of the .item div and thus does not match the .item input[type=checkbox]:checked selector. Changing it to .popover input[type=checkbox]:checked would maybe do what you want.
Update
I've done a bit of research and found out that this usecase was not thougth about by the creators. So doing it is really tricky. But I've managed to find a solution for you:
$(function () {
$('.item').popover({
placement: 'bottom',
html: true,
content: function () {
return $(this).find('.filters').html();
}
});
//Magic
$(".item").on("shown.bs.popover",function(){
$(".popover-content input").on("change",function(){
if(this.checked){
this.setAttribute("checked","checked");
}else{
this.removeAttribute("checked");
}
$(".filters").html($(".popover-content").html());
});
});
$('#count').click(function() {
var filter = $('.item input[type=checkbox]:checked').map(function () {
return this.value;
}).get();
$('#res').text(filter);
});
});
I'm trying to achieve the effect of the li tag changing background colors when the user focuses on the input (effect can be seen at the bottom of the page here. From seeing similar questions it seems like it can't be done in pure CSS, so I was wondering how to do it in jquery (I have no knowledge). Here is my HTML:
<form class="contact-form" action="" method="post" name="contact-form">
<ul>
<li>
<input type="text" name="name" placeholder="NAME" class="test"/>
</li>
<li>
<input type="email" name="email" placeholder="EMAIL" />
</li>
<li>
<textarea name="message" name="message" placeholder="MESSAGE"></textarea>
</li>
<li>
<button class="submit" type="submit">Send</button>
</li>
</ul>
</form>
Here's how to do it. It will add a background color to the parent LI of the form field that has focus, and after exiting the field the background color will be removed.
Working example on jsFiddle.
CSS:
.selected {
background: lightYellow;
}
jQuery:
$(function () {
var $form = $(".contact-form"),
selectedClass = "selected";
$form.on("focus", "input, textarea", function () {
$(this).closest("li")
.addClass(selectedClass);
});
$form.on("blur", "input, textarea", function () {
$(this).closest("li")
.removeClass(selectedClass);
});
});
Heres a basic jquery version which activates on focus like example
$('.contact-form').on('focus','input,textarea',function() {
$('.contact-form li').animate({'backgroundColor':'#00FF00'});
$(this).parent().animate({'backgroundColor':'#FF0000'});
});
fiddle
You can use the :hover selector in your CSS statement; no need for JS at all..
.contact-form ul li { background-color:#000000; }
.contact-form ul li:hover { background-color: #C0C0C0; }