body.addEventListener called after checkbox checked - javascript

i'm confused about the behaviour from an addEventListener response.
In this jsFiddle you can see a Label for a checkbox called "My Profile" and a Popup, which is shown if the checkbox is checked, through the magic of CSS.
I'm trying to make it disappear if the popup is shown and the user clicks outside of the popup div...
But the reason i can't get it to work is, if you click on the label with the id 'header-profile-popup-toggler' first the Body.addEventListener, then bbb2.addEventListener(the checkbox) and afterwards once more the Body.addEventListener is called.
But if you click outside the Label Body.addEventListener is called only once, same as i click on bbb.addEventListener(the div).
Does someone know why the body.addEventListener is called after the bbb2.addEventListener??
For explanation.
Absolutely, i would only call
document.body.addEventListener('click', function(e){
if(bbb2.checked==true&&e.target!=bbb){
bbb2.checked=false;
}
});
Only if the Popup is shown (bbb2.checked==true) and you clicked outside the div (e.target!=bbb) uncheck the checkbox.
But since the body.addEventListener is called once more after bbb2.addEventListener and both statements are true - the checkbox is checked and the checkbox is outside of the popup div - the checkbox is unchecked instantaneous.
Thanks for any Support!
I got it!
Because of the constallation of a label for the checkbox the addEventListener is called for every Element, in this case for the Label and Checkbox with one click.
So, first of all the Label Event is called, then the Body. After that, the Checkbox Event and once more the Body Event are triggered.

I got it!
Because of the constallation of a label for the checkbox the addEventListener is called for every Element, in this case for the Label and Checkbox with one click.
So, first of all the Label Event is called, then the Body. After that, the Checkbox Event and once more the Body Event are triggered.
With the following Script i made a fully functional Popup-Menu, which also works if Javascript is deactivated:
var isOutSide = true,
bbb=document.getElementById('header-profile-popup'),
bbb2=document.getElementById('header-profile-popup-toggler'),
bbb3=document.getElementById('header-profile-popup-toggler-label');
document.body.addEventListener('click', function(){
if(isOutSide){
document.getElementById("header-profile-popup-toggler").checked = false;
}
isOutSide = true;
});
bbb.addEventListener('click', function(){
isOutSide = false;
});
bbb2.addEventListener('click', function(){
isOutSide = false;
});
bbb3.addEventListener('click', function(){
isOutSide = false;
});
On this Fiddle you can test it in Action

Related

how can I check if a particular item is clicked with .blur() in jquery

I have an autocomplete dropdown that appears when a user starts typing in a textbox (I'm using jquery mobile but I don't think that's important to my problem). I want to be able to hide the whole dropdown list when a user clicks anywhere on the page. However, I don't want to hide the dropdown when a user actually clicks on the dropdown itself.
Is there a way I could catch the click event in order to know what was clicked?
Here's my blur function:
//hide autocomplete when dropdown is not clicked
$("#search-div input").blur(function () {
$("#autocomplete-list").hide();
});
I was thinking of somehow putting an if statement in my blur function. Here's my pseudo code:
if( dropdown clicked)
{
run code to take text from dropdown and place in textbox
}
else
{
hide dropdown
}
Would it be possible to know whether my dropdown is clicked or something else is clicked while in my blur function? When I debug my javascript I'm only seeing an event that's related to the textbox doing the blur()
Edit:
Here is a function I'm using to handle when the dropdown is clicked:
$( document).on( "click", "#autocomplete-list li", function() {
var selectedItem = event.target.innerHTML;
$(this).parent().parent().find('input').val(selectedItem);
$('#autocomplete-list').hide();
runSearchQuery();
});
You can listen for any click, not just a blur, and then check what the clicked element was. e.currentTarget gives you what was clicked.
var clickHandler = function(e) {
if ($(e.currentTarget).hasClass('dropdown')) {
// do nothing
} else {
// Make sure you unregister your event every
// time the dropdown is hidden.
$(window).off('click', clickHandler);
// hide
}
}
// When the dropdown comes down, register an event on the whole page.
$(window).on('click', clickHandler);

How to trigger a function from click on document

Here's my situation: I've got a field that once the user double click, it'll edit the field. That's fine and working. I've got two functions: ok and cancel. Cancel disables the editing mode. ATM, the user has to click cancel to disable the editing mode. What I'd like to is to allow the editing mode to be disabled when the user clicks anywhere else on the page. How can I accomplish this with Angular?
EDIT: I'm adding my markup (Note: this is Jade):
tr(ng-repeat="user in users | filter:searchText"s)
td(ng-dblclick="editItem(user)", hm-double-tap="editItem(user)", ng-blur="cancelEditing()")
span(ng-hide="user.editing") {{user.name}}
form(ng-submit="doneEditing(user)", ng-show="user.editing", class="inline-editing-2", ng-blur="cancelEditing()")
input(type="text", class="form-control", ng-model="user.name")
button(class="btn btn-success mr-1", ng-show="user.editing", ng-click="doneEditing(user)")
span(ng-click="doneEditing(user)").fa.fa-check-circle
button(class="btn btn-warning mr-1", ng-show="user.editing", ng-click="cancelEditing(user)")
span(ng-click="cancelEditing(user)").fa.fa-times-circle
As you can see, I've got a hg-repeat on user. When double click on the td element it makes user.editing true so the form shows up. the cancelEditing(user) makes the variable false and only the field is displayed.
I've added ng-blur="cancelEditing()" on thetr,td,spanandform` and none of it worked.
Any ideas what am I missing?
Use ng-blur to bind your cancel event to the element. It will fire when the element loses focus.
IE: <input ng-blur="cancel()" />
Note: The cancel function must be within scope.
Angular ngBlur Docs
Update from comments:
Give the input element focus when your double tab event fires making the field editable. Your blur event is likely not firing because the input element never had focus.
You could do this from inside your editItem function or from inside the directive.
As an example:
yourApp.directive('hmDoubleTap', function(){
return function(scope, element, attr){
if(doubleTap) {
// Fire editItem(user)
// You could add your .focus() inside editItem().
// Or focus the first input element at the end of the directive.
element.find("input")[0].focus();
}
};
});
b1j's answer would work only if the element gains focus. Does hm-double-tap directive focuses the element after double click? If not you will have to trigger focus in editItem function.
Another approach would be to handle the click event on any other element like this:
$('#field-no-edit').click(function() {
$(this).hide();
$('#field-edit').show().focus();
});
$('body').on('click', function(e){
console.log($(e.target).attr('id'));
if ($(e.target).attr('id') != 'field-no-edit') {
console.log('not');
$('#field-no-edit').text($('#field-edit').val());
$('#field-edit').hide();
$('#field-no-edit').show();
}
});
JSFiddle

prevent immediate Radio :checked property on click event

I have a click event handler attached to a group of radio inputs, and want to see if I am clicking on the radio button that is already selected (has property 'checked' set). I figured the event handler would act in a daisy chained fashion (first calling my event handler on the click and then continuing down the chain to the default behavior of the click). Apparently this is not the case, because when I evaluate if the property 'checked' is true on the radio button I just clicked, it always returns true in my click event handler.
The click has already been processed by the default behavior and has already applied the 'checked' property to the radio button I just clicked. Again, I figured my click event handler would be processed prior to that default behavior. What's even more odd is that even when I prevent the default behavior, it still returns true for the 'checked' property. I assume this is because the 'checked' property is being processed by the 'change' event, so preventing the default behavior on my click event handler is not affecting anything.
$("input[type='radio']").click(function(e) {
e.preventDefault();
alert($(this).prop("checked")); // always returns true; i want prop value immediately prior to click
});
How can I achieve what I'm after? That is, to see whether or not the radio button that was just clicked on was the one already checked. Thanks.
Based on the response of #Jeffman , I was able to get something to work for what I needed to do. I have custom buttons, only one of which can be selected (hence the use of radio buttons). However, if you click on the one that's already selected, it should deselect and select the default value instead.
Things I had to do. Handle mousedown events on the radio labels. If I am clicking on the already selected radio, set the default button to be 'checked'. Else I just select the button that has been clicked on. I had to disable the 'click' event on these buttons, as that would override my irregular handling of the radio buttons (for some reason the selection would snap back to the one that was clicked when I overrode it and chose the default one manually). This also meant I would need to manually trigger the change event, as I do the custom radio button styling there.
$(".radios > label").mousedown(function(e) {
var l = $(this); // label
var t = l.parent(); // container for radio group
var i = l.find("input"); // input element of this label
if(i.prop("checked")) { // clicking on the already selected button
t.find(".default_radio input").prop("checked", true).trigger("change");
} else {
i.prop("checked", true).trigger("change");
}
}).bind('click',false);
$("input[type='radio']").change(function(e) {
// style the buttons here
});
Save radio status before click via mousedown
var was_checked;
$( "#radio" ).mousedown(function() {
was_checked = $(this)[0].checked;
});
$( "#radio" ).click(function() {
$(this).attr('checked', !was_checked);
});
i think you should also return false. not only preventDefault
Here is a sample code that would do the trick
<script>
$(function() {
var radios = {};
$("input[type='radio']").each(function() {
radios[$(this).uniqueId().attr('id')] = false;
});
function resetRadioState() {
$("input[type='radio']").each(function() {
radios[$(this).attr('id')] = $(this).is(':checked');
});
}
resetRadioState();
$("input[type='radio']").click(function(e) {
alert(radios[$(this).attr('id')]);
resetRadioState();
});
})
</script>
<input type="radio" name="group[]"/>
<input type="radio" name="group[]" checked/>

Override parrents onClick event with checkbox onClick?

First, sorry for my bad English.
I'm making a Coupons site and have trouble with selecting and deselecting the coupons. Each coupon is in a DIV 'box' in which there is a checkbox.
I made a onClick function on the DIV box (so the user can select the coupon by clicking on anything inside the DIV box. What I need now is, when the user want to deselect the coupon (by clicking on the checkbox inside the DIV box), I need to 'override' the DIV's onClick function (execute the checkbox onClick event, not the DIV's onClick event).
I know that everyone prefers some code as an example, but the question/problem is simple and I don't think you need all of my un'useless code inside the events/functions :)
Thanks :)
It seems like you want stopPropagation if the checkbox is being unchecked: http://jsfiddle.net/8Dcq8/.
$("div").click(function() {
alert("add"); // clicking anywhere in div to add coupon
});
$(":checkbox").click(function(e) {
if(!this.checked) { // if unchecking, remove coupon
alert("remove");
e.stopPropagation(); // don't run parent onclick
}
});
If the <div> click handler looks something like this:
var $boxes = $('div.box');
$boxes.on('click', function ()
{
// do whatever to select the coupon
});
Then the checkbox handler should look something like this:
$boxes.find('input[type="checkbox"]').on('click', function (event)
{
event.stopPropagation();
// do whatever to deselect the coupon
});
See event.stopPropagation().
You have to cancel bubbling. See here for an explanation.
You can use the jQuery Alternative, or create sub-elements with onClicks that don't target your checkbox. you might be able to use something like this also.
document.getElementById('element').checked.onreadystatechange=function(){
//code
}
good luck

Javascript function only executing one line

I've got a div that starts out as hidden, and shows up when a button is clicked. There is another button on the div, and the onclick event calls this function:
function popuppage2OK() {
alert("you clicked ok!");
var x = new Object();
x.name = $("#boxforname").val(); //this is a text input
x.option = $("#boxforoption").val();//this is a text input
alert("hiding newfactorpage2");
$("#popupform").hide(); //this is a div containing the text inputs and the button with the onlcick event that calls this function
alert("popupform hidden");
displaystuff(); //another function ive written that needs to be called
alert("this is after the display attempt");
}
My probelm is that the only line that seems to execute is the line to hide the div. None of the alert boxes appear, and the displaystuff() function doesn't get executed, but the div does go back to being hidden. Any thoughts on why lines of code might get skipped like that?
When do you attach the eventhandler to the button inside the div ?
You should do it after the page has done loading, so in Jquery you can do something like:
$(document).ready(function () {
//attach the eventhandler here
})
Usually this kind of behavior happens when you've got an error in your javascript. Check to ensure that all of your selectors are valid and that there aren't any errors elsewhere.

Categories

Resources