I've made an editable implementation which behaviour is:
dblclick on element makes it editable:
an input is created
element contents emptied
input appended to element
attach keydown event handler to input, to disable edition when user presses Enter
idem with blur event
It works fine in decents browsers, but it breaks on IE8.
there are two problems:
input.focus() will call the blur event handler (wtf??)
keystrokes won't generate events intercepted by keydown handler, so my handler to validate when enter is hit don't work
I checked clicks events on the input and they are fine
The thing is it still works if I run the sample in a minimalist sample, but in my application, it won't.
what could prevent those keydown events from being fired / catch ?
here's the implementation:
widget.Editable = function( el, options ) {
this.element = $(el).addClass('editable');
this.value = this.element.text();
var _that = this;
this.element.dblclick( function(e) {
_that.enableEdition();
} );
};
widget.Editable.prototype = {
disableEdition: function( save, e ) {
this.value = this.input.val();
this.input.remove();
this.element.text( this.value ).removeClass('dragDisable');
this.editionEnabled = false;
this.onupdate( e, this.value, this.element );
},
/**
* enables the field for edition. Its contents will be placed in an input. Then
* a hit on "enter" key will save the field.
* #method enableEdition
*/
enableEdition: function() {
if (this.editionEnabled) return;
var _that = this;
this.value = this.element.text();
this.input = $( document.createElement('input') ).attr({
type:'text',
value:this.value
});
this.element
.empty().append( this.input )
.addClass('dragDisable'); //We must disable drag in order to not prevent selection
this.input.keydown( function(e) {
IScope.log('keydown editable:', e );
switch ( e.keyCode ) {
case 13:
_that.disableEdition( true );
break;
default:
break;
}
} );
this.input.click( function() {
console.log('input clicked');
});
//if ( !YAHOO.env.ua.ie )
// this.input.blur( function( e ) {
// IScope.log( "editable blurred", e );
// _that.disableEdition( true );
// });
//this.input.focus();
this.editionEnabled = true;
}
};
Related
Can we stop checkout process on woocommerce using javascript manually?
I am using this code for submit and want to stop process if certain condition occurs. I tried return false but it doesn't work.
JQuery("form.woocommerce-checkout").on('submit', function() {
var np = $('#notepopup').val();// val = 0
if(ne == 0){
return false;
}
});
please suggest something
You can prevent the form from submitting by prevent its default behavior (submit):
$("form.woocommerce-checkout").on('submit', function(e) {
if(ne == 0){
e.preventDefault();
}
});
More doc on preventDefault().
Edit
Using these alerts,
$("form.woocommerce-checkout").on('submit', function(e) {
alert("Before if ");
if(ne == 0){
alert("Inside if ");
e.preventDefault();
}
alert("After if ");
});
When exactly do you see you form submitted?
Event Relay with Validator
Figured out a way of doing this by building a kind of Relay system for the submit events attached to the checkout.
Just treat the "canSubmit()" as your event handler and return true only if you want the checkout form to submit as normal.
( ($) => {
var confirmDetails = true;
function canSubmit( e ) {
// Handle event here. Return true to allow checkout form to submit
return false;
}
function init() {
// Use set timeout to ensure our $( document ).ready call fires after WC
setTimeout( () => {
var checkoutForm = $( 'form.checkout' );
// Get JQuery bound events
var events = $._data( checkoutForm[0], 'events' );
if( !events || !events.submit ) {
return;
}
// Save Submit Events to be called later then Disable Them
var submitEvents = $.map( events.submit, event => event.handler );
$( submitEvents ).each( event => checkoutForm.off( 'submit', null, event ) );
// Now Setup our Event Relay
checkoutForm.on( 'submit', function( e ) {
e.preventDefault();
var self = this;
if( !canSubmit( ...arguments ) ) {
return;
}
// Trigger Event
$( submitEvents ).each( ( i, event ) => {
var doEvent = event.bind( self );
doEvent( ...arguments );
} );
} );
}, 10);
}
$( document ).ready( () => init() );
} )( jQuery );
For anyone looking for a solution this now, the below code worked for me. It needs jQuery(document).ready(function($) and to use the event checkout_place_order to work like so:
jQuery(document).ready(function($) {
jQuery("form.woocommerce-checkout").on('checkout_place_order', function(e) {
console.log("Submission Stopped");
return false;
});
});
If you require WooCommerce's validation to run first before stopping the checkout, there is a solution here!
I'm using a script (impress.js) that bins some particular action to keyup and keydown events for left, right, up and down arrows.
In some particular moments (for example while typing in a textarea) I want back the default behaviour for the arrows.
I tried without success with
$("a#show-ta").click( function() {
document.addEventListener("keydown", function ( event ) {
if (event.keyCode >= 37 && event.keyCode <= 40) {
return;
}
});
document.addEventListener("keyup", function ( event ) {
if (event.keyCode >= 37 && event.keyCode <= 40) {
return;
}
});
});
where a#show-ta is the button that shows my textarea.
You want to prevent the keypress from bubbling up to the document where (I assume) Impress binds its handlers:
$("textarea").on('keyup keydown keypress', function(e) {
e.stopPropagation();
});
If you need the event in a specific zone, such as a texarea, you should stop the propagation of the event like this :
$('textarea').keydown( function(ev) {
ev.stopPropagation();
});
If the events are necessary for the whole page but you want to exclude while you are in a textarea, for example, you could raise a flag which you would validate in the event.
var keydownActivated = true;
$('textarea').keydown( function(ev) {
if (keydownActivated) {
ev.preventDefault();
// dostuff
}
});
This will more or less get you where you are going. Create a flag that tracks whether or not the textarea has focus, and check that flag in your current key press event handlers. I can't see all of your code, so this is just a simple example:
var textareaHasFocus = false;
var textarea = document.querySelector('#yourTextarea');
textarea.addEventListener('focus', function(event) {
textareaHasFocus = true;
}, false);
textarea.addEventListener('blur', function(event) {
textareaHasFocus = false;
}, false);
document.addEventListener("keydown", function ( event ) {
if (textareaHasFocus) return true;
// your current keyboard handler
});
document.addEventListener("keyup", function ( event ) {
if (textareaHasFocus) return true;
// your current keyboard handler
});
This is really straight forward but I'm still fairly new to JavaScript and just found JSFiddle. I'm trying to find the element with the getElementById() to disable and enable a button. What am I missing?
<form name="frm" >
<div id="chkObj">
<input type="checkbox" name="setChkBx" onclick="basicList.modifyAndEnableButton(this)"></input>
</div>
<div id="Hello">
<input type="button" name="btn" value="Hello"></input>
</div>
</form>
This is a list that I am using to add checkboxes because there is going to be more than one:
var basicList = {
'items': {},
'modifyAndEnableButton': function(obj1) {
var element = document.getElementsByName("btn");
if (obj1.checked == true && element.getAttribute('disabled') == false) {
element.getAttribute('disabled') = true;
this.addRecord(obj2);
} else if (element.getAttribute('disabled') == true) {
if (hasItems == false) {
element.getAttribute('disabled') = false;
}
}
}
};
http://jsfiddle.net/Arandolph0/E9zvc/3/
All browsers support this (see example here):
mySelectedElement.onclick = function(e){
//your handler here
}
However, sometimes you want to add a handler (and not change the same one), and more generally when available you should use addEventListener (needs shim for IE8-)
mySelectedElement.addEventListener("click",function(e){
//your handler here
},false);
Here is a working example:
var button = document.getElementById("myButton");
button.addEventListener("click",function(e){
button.disabled = "true";
},false);
And html:
<button id='myButton'>Hello</button>
(fiddle)
Here are some useful resources:
addEventListener on mdn
The click event in the DOM specification
Click example in the MDN JavaScript tutorial
Benjamin's answer covers quite everything. However you need a delegation model to handle events on elements that were added dynamically then
document.addEventListener("click", function (e) {
if (e.target.id == "abc") {
alert("Clicked");
}
});
For IE7/IE8
document.attachEvent('onclick', function (e) {
if (window.event.srcElement == "abc") {
alert("Clicked");
}
});
You have a Error here
btnRush should be Rushbtn
This is a example of cross browser event's I just made (not tested) )
var addEvent = function( element, type, callback, bubble ) { // 1
if(document.addEventListener) { // 2
return element.addEventListener( type, callback, bubble || false ); // 3
}
return element.attachEvent('on' + type, callback ); // 4
};
var onEvent = function( element, type, callback, bubble) { // 1
if(document.addEventListener) { // 2
document.addEventListener( type, function( event ){ // 3
if(event.target === element || event.target.id === element) { // 5
callback.apply(event.target, [event]); // 6
}
}, bubble || false);
} else {
document.attachEvent( 'on' + type, function( event ){ // 4
if(event.srcElement === element || event.srcElement.id === element) { // 5
callback.apply(event.target, [event]); // 6
}
});
}
};
Steps
Create a function that accepts 4 values ( self explaining )
Check if the browser supports addEventListener
Add event on the element
else add event on the element for older IE
Check that the (clicked) element is = to the passed element
call the callback function pass the element as this and pass the event
The onEvent is used for event delegation.
The addEvent is for your standard event.
here's how you can use them
The first 2 are for dynamically added elements
onEvent('rushBtn', 'click', function(){
alert('click')
});
var rush = document.getElementById('rushBtn');
onEvent(rush, 'click', function(){
alert('click');
});
// Standard Event
addEvent(rush, 'click', function(){
alert('click');
});
Event Delegation is this basically.
Add a click event to the document so the event will fire whenever & wherever then you check the element that was clicked on to see if it matches the element you need. this way it will always work.
Demo
I have a canvas which listens for mouse down event... but I wanted to make it more detailed by listening on the buttons and if they were double clicks or not.
I have this:
canvas.addEventListener("mousedown", what_button, false);
Then a function named what_button:
function what_button(e){
//check which button on the mouse
//was it a double click ?
}
Is this possible in JavaScript?
I don't think that the 'mousedown' event is able to anticipate whether or not a second mouse click will occur. You'll have to bind to both 'click' and 'dblclick' and then override the behavior if a double-click occurred...
Inside the handler, the e.button property tells you which button was clicked:
0 => left
1 => middle
2 => right
This works for me:
var dblclick;
var timeout;
$( document ).on( 'click', function ( e ) {
if ( !timeout ) {
timeout = setTimeout( function () {
timeout = 0;
handler( dblclick ? 'dblclick' : 'click' );
dblclick = false;
}, 200 );
}
});
$( document ).on( 'dblclick', function ( e ) {
dblclick = true;
});
// this function receives either 'click' or 'dblclick'
// and performs the corresponding action
function handler ( type ) {
alert( type );
}
Live demo: http://jsfiddle.net/f73tY/1/
I use a delay value of 200. I have found that (at least on my machine) a value of 100 does not detect a double-click.
Use click/dblclick:
var button = document.getElementById('myButton');
button.ondblclick = function() {
doubleClick = true;
};
You can even add an normalClick = false then use that information in your code.
I have a small div above (hover) a big one.
I assign onmouseover and onmouseout events to the wrapper div.
For image caption roll-over animation.
The problem is when the mouse is above the caption itself, causing an unwanted result (probably event bubbling).
And another problem: sometimes when you move mouse from outside to container you get a a triple sequence: (it should be just 2):
-I am over-
-I am out-
-I am over-
How to make it work? (no jQuery)
Must work on all browsers.
Demo
I have added firebug console log, to a better debugging.
UPDATE:
I've added this (not in the online demo) in RollOverDescription:
if (!eventHandle) var eventHandle = window.event;
var srcEle = eventHandle.srcElement.id;
if(srcEle=="imageDescription" ){
return;
}
But it doesn't help.
This article on quirksmode ( near the bottom ) has an explanation of what you are experiencing and a script that might help you. There is a lot of cross browser info regarding mouse events too
OK, here's some working code. I don't promise this is the most efficient or that it won't cause memory leaks in IE (or that it works in IE - please let me know ). This is why people use libraries, much safer and easier.
// a general purpose, cross browser event adder
// returns a function that if run removes the event
function addEvent( el, eventType, handler, capturing ) {
if( el.addEventListener ) {
el.addEventListener( eventType, handler, capturing || false );
var removeEvent = function() { el.removeEventListener( eventType, handler, capturing || false ) };
} else if( el.attachEvent ) {
var fn = function() {
handler.call( el, normalise( window.event ) );
};
el.attachEvent( 'on'+eventType, fn );
var removeEvent = function(){ el.detachEvent( 'on'+eventType, fn ) };
}
function normalise( e ) {
e.target = e.srcElement;
e.relatedTarget = e.toElement;
e.preventDefault = function(){ e.returnValue = false };
e.stopPropagation = function(){ e.cancelBubble = true };
return e;
};
return removeEvent;
};
// adds mouseover and mouseout event handlers to a dom element
// mouseover and out events on child elements are ignored by this element
// returns a function that when run removes the events
// you need to send in both handlers - an empty function will do
function addMouseOverOutEvents( element, overHandler, outHandler ) {
function out( e ) {
var fromEl = e.target;
var toEl = e.relatedTarget;
// if the mouseout didn't originate at our element we can ignore it
if( fromEl != element ) return;
// if the element we rolled onto is a child of our element we can ignore it
while( toEl ) {
toEl = toEl.parentNode;
if( toEl == element ) return;
}
outHandler.call( element, e );
}
function over( e ) {
var toEl = e.target;
var fromEl = e.relatedTarget;
// if the mouseover didn't originate at our element we can ignore it
if( toEl != element ) return;
// if the element we rolled from is a child of our element we can ignore it
while( fromEl ) {
fromEl = fromEl.parentNode;
if( fromEl == element ) return;
}
overHandler.call( element, e );
}
var killers = [];
killers.push( addEvent( element, 'mouseover', over ) );
killers.push( addEvent( element, 'mouseout', out ) );
return function() {
killers[0]();
killers[1]();
}
}
Example of use:
// add the events
var remover = addMouseOverOutEvents(
document.getElementById( 'elementId' ),
function( e ) {
this.style.background = 'red';
console.log( 'rolled in: '+e.target.id );
},
function( e ) {
this.style.background = 'blue'
console.log( 'rolled out: '+e.target.id );
}
);
//remove the events
remover();