Why does listener activate twice? - javascript

I have the following html:
<ul id="all-terminals">
<li data-terminal-id="101" class="">
<label>
<input type="radio" name="terminal" class="all" data-terminal-id="101">
<a ...></a>
...
</label>
</li>
<li data-terminal-id="100" class="active">
<label>
<input type="radio" name="terminal" class="all" data-terminal-id="100">
<a ..></a>
...
</label>
</li>
<li data-terminal-id="102" class="">
<label>
<input type="radio" name="terminal" class="all" data-terminal-id="102">
<a...></a>
...
</label>
</li>
</ul>
I wrote the following listener:
$(document).on('click', '#all-terminals li label', function(){alert(123)});
when I click on label, I see that alert executes twise.
Why?

Clicking a label automatically creates a click event on an input within it.
Assuming all your labels have inputs, you can simply change to:
$(document).on('click', '#all-terminals li input', function(event) {
alert(123);
});
Fiddle

Not exactly sure why, but mouseup works.
$(document).on('mouseup', '#all-terminals li label', function(){alert(123)});

I think bubbling is occurring in your case .
Read about on Bubbling and Capturing

I'm not completely sure, but I think that when you click on the label, you hit 2 of its child overlapping elements. Because they are part of the label but still separate elements, it fires two click events on label.
On the fiddle, it appears the it's the [a] element overlapping the ...

Related

Javascript event to change its child to checked

I want an event in which when i click the list tag so the radio button gets checked.
<li class="morning-time">
<div class="morning-icon"></div>
<div class="timeTxt">Morning <span>7am - 12am</span></div>
<div class="checkBox">
<label>
<input type="radio" class="option-input checkbox" id="rbt_Time1" name="rbt_Time" value="1" data-text="Morning 7am - 12am">
<span></span>
</label>
</div>
<div class="clear"></div>
</li>
You will have to include jquery for using the following code:
$(function() {
$('.morning-time').on('click', function(){
$('.option-input', $(this)).prop("checked", true);
});
});
Here, on li(class='morning-time'), the radio(class='option-input') is searched inside(the li tag) and set checked.
You need setAttribute to do so AND to explain the code, radio styled input have a checked attribute. Just set it to true and the input get check.
Here the code :
function CheckMe()
{
var radioInput = document.getElementById("rbt_Time1");
radioInput.setAttribute("checked", "true");
}

AngularJS : one ng-click call the function twice why?

I have following angularjs code. When I click li tag that function is invoke twice. That means on click two request is passing and i'm getting two response why? Even i change ng-click to only radio button that function invoke only once why?
<li ng-click="togglePrice(2);">
<input type="radio" name="personalGroup" ng-model="watchlist" value="watchlist" id="watchlist">
<label for="watchlist" >My Watchlist</label>
</li>
script
$scope.togglePrice = function (price) {
console.log(price+"newwww");
.................
}
You get this behaviour because of <input type="radio"> inside your <li>
You can write <li ng-click="togglePrice(2);$event.preventDefault()"> to get rid of second click. However your radio button state will not change.
DEMO plunkr 1
Maybe you wanted something like:
Controller
$scope.watchlist = 'City1';
$scope.list = ["City1", "City2","City3"];
HTML
<li ng-repeat="watchlist in list">
<label>
<input type="radio" name="personalGroup"
ng-model="$parent.watchlist"
ng-value="watchlist"
ng-change="togglePrice(watchlist)" />{{watchlist}}
</label>
</li>
DEMO plunkr 2

Submit filter form on link click

I'm trying to make something a bit like this:
This is my code: http://jsfiddle.net/928Dj/19/
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
});
I'm trying to make it degradable so without javascript they can submit the form to adjust the results, but with javascript they can just click the text of the desired result.
Question A
How can I make it so by them clicking the text alone, with javascript enabled, it not only selects the radio button but also submit the form.
Question B
Is my code the right approach to achieve this desired outcome?
Replace the radio buttons with submit buttons.
<input type="submit" name="status" value="Status 1">
i think google uses <a> tag instead <input> and (but i'm not sure) catches the click and makes a ajax call to update only the result (without any form)... like: http://jsfiddle.net/928Dj/25/
HTML, change <input> in <a>:
Status 1
JS
$('ul.opt a').click(function(e){
e.preventDefault();
$(this).parents(".opt").find("a").removeClass("active");
$(this).addClass("active");
$.get($(this).attr("href"),function(res){
//do something with response
});
});
On <a> click the JS simply perform search.action (or other search service) with sortDate=status1 like parameter via AJAX, for sort the result.
You can concat the sorting parameters status=status1&date=date1 for multiple sorting.
I don't know if there are any ways to perform the submit without using javascript (and without reload all page).
I've updated your fiddle with submit buttons that are hidden if javascript is enabled.
<div>
<form action="/echo/html/">
<ul id="filter">
<li> Any status ▾
<ul class="opt">
<li>
<label>
<input type="radio" name="status" />Status 1</label>
</li>
<li>
<label>
<input type="radio" name="status" />Status 2</label>
</li>
<li>
<input type="submit" value="submit"/>
</li>
</ul>
</li>
<li> Any date ▾
<ul class="opt">
<li>
<label>
<input type="radio" name="date" />Date 1</label>
</li>
<li>
<label>
<input type="radio" name="date" />Date 2</label>
</li>
<li>
<input type="submit" value="submit"/>
</li>
</ul>
</li>
</ul>
</form>
</div>
<div id="results">
Filtered results go here
</div>
<script>
$("ul.opt").addClass("hidden");
$('#filter > li > a').on("click", function (e) {
var cache = $(this).next('ul');
$('#filter ul:visible').not(cache).hide();
cache.toggle();
$('#filter li input[type=submit]').hide();
});
$('#filter input[type=radio]').click(function() {
var $form = $(this).closest('form');
$('#results').html('filtering...');
$.post($form.attr('action'),$form.serialize(),function(response) {
if ( response ) {
$('#results').html(response);
} else {
$('#results').html('no results found');
}
});
});
</script>

On click of label add class to previous div, just not working

I'm trying to add a class to a div (.checkbox) when clicking on the label that follows from it. It doesn't seem to be working at all though and I don't know why.
Below is the javascript and the basic form layout that I have set up.
JS
$('#filter ul label').click(function() {
if ($(this).prev('.checkbox').hasClass('checked')) {
$(this).prev('.checkbox').removeClass('checked');
} else {
$(this).prev('.checkbox').addClass('checked');
}
});
HTML
<form id="filter">
<div>
Service <span></span>
<ul>
<li>
<div class="checkbox"></div>
<label for="new-build">
<input type="checkbox" name="new-build" id="new-build">
New Build
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="extensions">
<input type="checkbox" name="extensions" id="extensions">
Extensions
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="refurbishments">
<input type="checkbox" name="refurbishments" id="refurbishments">
Refurbishments
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="fit-out">
<input type="checkbox" name="fit-out" id="fit-out">
Fit Out
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="maintenance">
<input type="checkbox" name="maintenance" id="maintenance">
Maintenance
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="design-build">
<input type="checkbox" name="design-build" id="design-build">
Design & Build
</label>
</li>
<li>
<div class="checkbox"></div>
<label for="listed-building">
<input type="checkbox" name="listed-building" id="listed-building">
Fit Out
</label>
</li>
</ul>
</div>
<input type="submit">
</form>
Any help would be greatly appreciated, I'm assuming it is something really simple that I'm missing completely.
Thank you.
Your solution works perfectly fine. Please make sure that you included jQuery and put your javascript in a
$(document).ready(function() {
});
block.
It seems like the click event is not fired when writing the markup like you did. You can bind your function to the change event of the checkbox instead. This should work as expected:
$('#filter input[type=checkbox]').change(function() {
var $div = $(this).parent().prev('.checkbox');
if ($div.hasClass('checked')) {
$div.removeClass('checked');
} else {
$div.addClass('checked');
}
});
Check Fiddle for demo: http://jsfiddle.net/g3v4F/3/
I think you have a problem with the order of code. At the time your JavaScript code is executed the DOM elements are not there because they come after the JS.
Move the JS behind the HTML or use the jQuery(document). ready(function () {...}) construct (recommended).
http://api.jquery.com/ready/
This worked for me:
$('#filter ul label').click(function() {
var $cb = $(this).prev('.checkbox');
$cb.toggleClass('checked', !$cb.hasClass('checked'));
});
Working JSFiddle
JS should be either below your HTML or wrapped in document.ready
$(function(){
// your JS here
});

close other div when div1 is show and duplicate code pb jquery

I have 2 problems
1.First i need to allow only one div open , so when div question1 is show
div question2 and all other should hide, actually its not case in my poor code :).
2.Second problem , I achieve to made a code with an addclass when "is checked", but actually i duplicate all the code for each div .. Perhaps someone have a better elegant option to merge the code and avoiding duplicate code..
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$(".checkbox").toggle(10);
});
$('#test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question').addClass("question-active");
} else {
$('div.question').removeClass("question-active");
}
});
$(".checkbox2").hide();
$(".question2").show();
$('.question2').click(function(){
$(".checkbox2").toggle(10);
});
$('#test2').change(function(){
if($(' input[type=checkbox]:checked').length) {
$('div.question2').addClass("question-active");
} else {
$('div.question2').removeClass("question-active");
}
});
Here is my code : http://jsfiddle.net/5C3p9/3/
Thanks for help
Regards
If you want to keep your HTML markup as it is, this should work:
// The ^= selector is used to select the elements which have the
// property starting with the text provided.
// ie: class starting with checkbox
$("div[class^='checkbox']").hide();
$("div[class^='question']").show();
$("div[class^='question']").click(function () {
// This way you are able to close the clicked one itself
$("div[class^='checkbox']").not($(this).next()).hide();
$(this).next("div[class^='checkbox']").toggle(10);
});
$("ul[id^='test']").change(function () {
// You can use the .toggleClass() method giving the class name
// and a boolean (add/remove) as parameters
$(this)
.parents()
.prev("div[class^='question']")
.toggleClass("question-active", $("input[type='checkbox']:checked").length != 0);
});
Demo: http://jsfiddle.net/5C3p9/7/
EDIT: I've put some comments in the code.
Some minor dom changes
<div class="quest question"></div>
<div class="ans checkbox">
<ul id="test">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
<div class="quest question2"></div>
<div class="ans checkbox2">
<ul id="test2">
<li>
<input type="checkbox" name="question-1" value="1"
/> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"
/> is it melon ?
</li>
</ul>
</div>
then
$(".quest").show();
$(".ans").hide();
$('.quest').click(function(){
$(this).next().toggle(10);
});
$('.ans').change(function(){
var $ans = $(this).closest('.ans');
$ans.prev().toggleClass('question-active', $ans.find('input:checkbox:checked').length > 0)
});
Demo: Fiddle
I made some modifications to your code. What I did is that I added some HTML-classes and made the javascript more general and traverse the HTML instead of pointing straight to the element.
Here's the jsFiddle: http://jsfiddle.net/E595w/1/
The new HTML:
<div class="question"></div>
<div class="checkbox">
<ul id="test" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
<div class="question"></div>
<div class="checkbox">
<ul id="test2" class="test">
<li>
<input type="checkbox" name="question-1" value="1"> is it vegetables ?
</li>
<li>
<input type="checkbox" name="question-2" value="2"> is it melon ?
<li>
</ul>
</div>
And here's the resulting Javascript:
$(".checkbox").hide();
$(".question").show();
$('.question').click(function(){
$('.checkbox').hide();
$(this).next(".checkbox").toggle(10);
});
$('.test').change(function(){
if($(' input[type=checkbox]:checked').length) {
$(this).parents('.checkbox').prev('div.question').addClass("question-active");
} else {
$(this).parents('.checkbox').prev('div.question').removeClass("question-active");
}
});
EDIT: Updated with code to answer your #1 question. See updated link to jsFiddle.
put to all your questions same class .question
if you want to differentiate between questions, use ids instead
also, put to to all answers container .checkbox
then use this function which will work for questions , no matter how many you have
$('.question').click(function(){
$(".checkbox").hide();
$(this).next(".checkbox").show(10);
});

Categories