I have a form with CSS animations, when form field is selected labels animate out and when text is filled labels shouldn't animate back. And this works for input fields but not with textarea. Can't seem to find the problem, and I've been playing with it for some time now.
This is my JS code:
<script>
(function() {
// trim polyfill : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim
if (!String.prototype.trim) {
(function() {
// Make sure we trim BOM and NBSP
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
String.prototype.trim = function() {
return this.replace(rtrim, '');
};
})();
}
[].slice.call( document.querySelectorAll('input.input_field', 'input-textarea.input_field-textarea') ).forEach( function( inputEl ) {
// in case the input is already filled..
if( inputEl.value.trim() !== '' ) {
classie.add( inputEl.parentNode, 'input--filled' );
}
// events:
inputEl.addEventListener( 'focus', onInputFocus );
inputEl.addEventListener( 'blur', onInputBlur );
} );
function onInputFocus( ev ) {
classie.add( ev.target.parentNode, 'input--filled' );
}
function onInputBlur( ev ) {
if( ev.target.value.trim() === '' ) {
classie.remove( ev.target.parentNode, 'input--filled' );
}
}
})();
</script>
EDIT: This was the problem, code was going like this:
document.querySelectorAll('textarea.input_field-textarea', 'input.input_field'))
Instead of removing those 2 extra '':
document.querySelectorAll('textarea.input_field-textarea, input.input_field'))
Thanks to all for help!
Change the input-textarea.input_field-textarea selector to textarea.input_field-textarea. There's no such <input-textarea/> element:
[].slice.call(document.querySelectorAll('input.input_field', 'textarea.input_field-textarea')).forEach(function(inputEl) {
// ...
});
Related
I want to place two separate multiselct dropdown menus on one page for a form I am designing.
I found this lovely dropdown with checkboxes that I would like to use:
https://codepen.io/bseth99/pen/fboKH
I am trying to figure out the best way to run two instances of this dropdown on the same page, so that each dropdown's selections are saved in their own array.
var options = [];
$( '.dropdown-menu a' ).on( 'click', function( event ) {
var $target = $( event.currentTarget ),
val = $target.attr( 'data-value' ),
$inp = $target.find( 'input' ),
idx;
if ( ( idx = options.indexOf( val ) ) > -1 ) {
options.splice( idx, 1 );
setTimeout( function() { $inp.prop( 'checked', false ) }, 0);
} else {
options.push( val );
setTimeout( function() { $inp.prop( 'checked', true ) }, 0);
}
$( event.target ).blur();
console.log( options );
return false;
});
Right now, if I place two instances of the button's HTML on my page, both dropdowns will modify the same "options" array because it's using a class selector for dropdown-menu. I know I can use an ID selector instead of a class selector, and then just use the same block of jQuery over again with a different array, but is that really the best way to do this? I am new to jQuery but that seems bloated.
$( '.dropdown-menu a' ).on( 'click', function( event ) {
var $target = $( this ),
val = $target.data( 'value' ),
$inp = $target.find( 'input' ),
idx;
var options = $target.closest('.dropdown-menu').data('options') || [];
if ( ( idx = options.indexOf( val ) ) > -1 ) {
options.splice( idx, 1 );
setTimeout( function() { $inp.prop( 'checked', false ) }, 0);
} else {
options.push( val );
setTimeout( function() { $inp.prop( 'checked', true ) }, 0);
}
$target.closest('.dropdown-menu').data('options', options);
$( event.target ).blur();
return false;
});
console.log($( '.dropdown-menu:eq(0)' ).data('options'));
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 know this is simple but I cant get the conditional if below to work...
This line below " if ( !$section.id == "no-transition" ) " is not correct.
I'm trying to stop javascript from working on section elements that have the id of "no-transition".
Can someone point me in the right direction?
function initEvents() {
$sections.each( function() {
var $section = $( this );
if ( !$section.id == "no-transition" ) {
// expand the clicked section and scale down the others
$section.on( 'click', function() {
[code taken out to shorten post...]
if( !supportTransitions ) {
$section.removeClass( 'bl-expand-top' );
}
$el.removeClass( 'bl-expand-item' );
return false;
} );
}
} );
You really should not have multiple elements with the same id on a page.
Your if condition should be modified to:
...
if ( $section.attr('id') != "no-transition" ) {
...
I search a JSON tree with jQuery on keyup-event. If the input is equal to the desired entry the input will disabled.
Now I need to call a function if they all are filled and correct. The if queries are long so i have written them into variables.
I've tried this, but it fails:
if (simple_present && simple_past && past_participle) {
alert('All right!');
}
Now, when I write something like this, it works:
if (simple_present || simple_past || past_participle) {
alert('All right!');
}
Here's a fiddle of what I have so far.
Any ideas?
BTW: What is the best way to combine long if queries with reg expressions​?
Consider this:
var json = {
"vocables": {
"irregular": {
"sein": {
"simple_present": "be",
"simple_past": "was were",
"past_participle": "been"
},
"schlagen": {
"simple_present": "beat",
"simple_past": "beat",
"past_participle": "beaten"
},
"werden": {
"simple_present": "become",
"simple_past": "became",
"past_participle": "become"
}
}
}
};
var word = $( 'h1' ).text();
$( 'input' ).on( 'keyup', function () {
if ( this.value === json.vocables.irregular[ word ][ this.id ] ) {
$( this ).prop( 'disabled', true ).next( 'input' ).focus();
}
if ( $( 'input:not(:disabled)' ).length === 0 ) {
alert( 'SUCCESS' );
}
});
Live demo: http://jsfiddle.net/NnAMu/1/
As you can see, I have:
changed the JSON structure to suit my needs better,
cached the current word into a variable.
With those changes, the resulting "keyup" handler code is much simpler.
You run all of the following code in the same event handler for each element:
$this.attr('id') == 'simple_present'
$this.attr('id') == 'simple_past'
$this.attr('id') == 'past_participle'
They can't be all true, so && is guaranteed to give you false.
Add a debug line just before the if:
alert( simple_present.toString() + '\n' + simple_past.toString() + '\n' + past_participle.toString() );
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();