In my application I have an instance of a CKEditor. While the user is entering text into the editor the first latter should be in uppercase. For that I wrote a jQuery keydown event handler, like this:
$(document).ready(function () {
CKEDITOR.instances.CKEditor1.on('contentDom', function () {
CKEDITOR.instances.CKEditor1.document.on('keydown', function (event) {
if (this.selectionStart == 0 && event.keyCode >= 65 && event.keyCode <= 90 && !(event.shiftKey) && !(event.ctrlKey) && !(event.metaKey) && !(event.altKey)) {
var $t = $(this);
event.preventDefault();
var char = String.fromCharCode(event.keyCode);
$t.val(char + $t.val().slice(this.selectionEnd));
this.setSelectionRange(1, 1);
}
});
});
});
It gives an runtime error i.e,
0x800a138f - JavaScript runtime error: Unable to get property 'on' of undefined or null reference
How can I create keydown event for ckeditor.(the above code I wrote in .aspx page)
You can achieve this with the following code.
CKEDITOR.replace( 'editor1', {
on: {
instanceReady: function() {
alert( this.name ); // 'editor1'
},
key: function() {
setTimeout(function(){
console.log('key pressed');
},1);
}
}
});
Without the setTimeout function the editor cannot capture the last key pressed.
CKEditor version 4.x
I believe you're registering the contentDom event the wrong way.
To instantiate CKEDITOR and register the contentDom event you'd do
CKEDITOR.replace( 'editor1', {
on: {
instanceReady: function() {
alert( this.name ); // 'editor1'
var editor = this;
editor.on( 'contentDom', function() {
var editable = editor.editable();
editable.attachListener( editable, 'click', function() {
console.log( 'The editable was clicked.' );
});
});
}
}
} );
Your code is trying to access the CKEDITOR instance before it has finished instantiating.
More information can be found at http://docs.ckeditor.com/#!/api/CKEDITOR.config and http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDom
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 working on a form where I do not want enter/return to submit the form so I used a function like this.
$('[name="form"]').keypress(function(e) {
var charCode = e.charcode || e.keyCode || e.which;
if (charCode === 13) {
e.preventDefault();
return false;
}
});
That works, but now I want to assign the enter/return to perform functions on two inputs on the form. I'm totally stuck.
To get the inputs I've tried vanilla js calling by id, jQ calling by id and then a mixer of the two with variables. I've also tried .keypress, .keydown, .keyup instead of the attachEventListener method. No matter what I do, I get this error in console.
"TypeError: ...addEventListener is not a function" (or keypress, keydown etc.)
I've also researched a good deal but can't find any solution. I appreciate any suggestions.
Here is this block of code in it's current form that's giving the trouble.
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.addEventListener("keydown", function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
// Google
googleInput.addEventListener("keydown", function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
Thanks
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.keydown(function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
// Google
googleInput.keydown(function(e) {
if (e.keyCode === 13 ) {
alert('do stuff!');
}
});
yelpInput is jQuery wrapped object which does not have addEventListener method.
Use .on to attach event-handler on jQuery wrapped object or yelpInput[0].addEventListener/yelpInput.get(0).addEventListener to attach event using JavaScript as yelpInput[0] will be an DOMElement not jQuery-wrapped object.
var yelpInput = $('#inputURL');
var googleInput = $('#googleURL');
yelpInput.on("keydown", function(e) {
//-----^^^
if (e.keyCode === 13) {
alert('do stuff!');
}
});
googleInput.on("keydown", function(e) {
//-------^^^
if (e.keyCode === 13) {
alert('do stuff!');
}
});
BACKGROUND
I have a simple form within which the name cannot contain numerics.
So I capture the keypress:
// prevent number from being added in a name
$("#name1__firstname").keypress(function(e) {
rejectCharacterIfNumeric(e);
});
Then use this function to check if numeric, and if so, preventDefault():
// function to disallow numbers added into a text input
function rejectCharacterIfNumeric(e) {
var key = e.which;
key = String.fromCharCode(key);
var regex = /[0-9]|\./;
if (regex.test(key)) {
e.preventDefault();
}
console.log('foo'); // <-- not being fired
};
THE PROBLEM
I need to write a Jasmine test for this but it's not capturing the keypress.
This is what I'm trying:
describe("when text is entered in the input", function(){
var fixture;
beforeEach(function () {
fixture += "<input id='name1__firstname'>";
setFixtures(fixture);
});
it("it should not show if numeric", function(){
var textInput = $('#name1__firstname');
textInput.trigger(
$.Event( 'keypress', { keyCode: 65, which: 65 } ) // letter "a"
);
expect(textInput.val().length).toEqual(1);
});
afterEach(function () {
fixture = "";
fixture = null;
});
})
This test fails as the numbers are inserted into the input Expected 0 to equal 1.
I know the test is not calling rejectCharacterIfNumeric(e) as I've added a console.log() into the function which doesn't fire
QUESTION
How can I pass a keyPress so it fires the rejectCharacterIfNumeric(e) function?
The textInput variable in your spec didn't have the event attached to it:
it("it should not show if numeric", function(){
var textInput = $('#name1__firstname');
textInput.keypress(function(e) {
rejectCharacterIfNumeric(e);
});
textInput.trigger(
$.Event( 'keypress', { keyCode: 65, which: 65 } ) // letter "a"
).val('A');
expect(textInput.val().length).toEqual(1);
});
I have a page with just a searchbox on provided by google
<gcse:search></gcse:search>
Now when I type in the search box and hit enter I would like to trigger my script to run as the search results gets returned.
Things I have tried sofar
Here I tried to use the submit event to trigger my script
$(document).on('submit', 'input', function(e) {
alert('trig');
}
Here I tried to catch the enter key as I have removed the search button
$(document).keypress(function(e) {
alert('triggered');
});
Here I tried to catch the focus on the form id
$('#gsc-i-id1').focus().trigger(function(e) {
alert('triggered');
});
All unsuccessfull
Here is a list of id's and classes the gcse tag creates
#___gcse_0
.gsc-control-cse .gsc-control-cse-en
.gsc-control-wrapper-cse
.gsc-search-box .gsc-search-box-tools
.gsc-search-box
.gsc-input
#gsc-iw-id1
#gs_id50
#gs_tti50
#gsc-i-id1
Using the following CODE snippet you'll be able to capture keyboard event on enter key press in the search input field and mouse click event on the search button.
Note: This answer only captures keyboard enter & search button click events (as asked in the original question). I've added another answer that is similar, but also auto re-populates search result on every valid keystroke.
(function($, window) {
var elementName = '';
var initGCSEInputField = function() {
$( '.gcse-container form.gsc-search-box input.gsc-input' )
.on( "keyup", function( e ) {
if( e.which == 13 ) { // 13 = enter
var searchTerm = $.trim( this.value );
if( searchTerm != '' ) {
console.log( "Enter detected for search term: " + searchTerm );
// execute your custom CODE for Keyboard Enter HERE
}
}
});
$( '.gcse-container form.gsc-search-box input.gsc-search-button' )
.on( "click", function( e ) {
var searchTerm = $.trim( $( '.gcse-container form.gsc-search-box input.gsc-input' ).val() );
if( searchTerm != '' ) {
console.log( "Search Button Click detected for search term: " + searchTerm );
// execute your custom CODE for Search Button Click HERE
}
});
};
var GCSERender = function() {
google.search.cse.element.render({
div: 'gcse_container',
tag: 'search'
});
initGCSEInputField();
};
var GCSECallBack = function() {
if (document.readyState == 'complete') {
GCSERender();
}
else {
google.setOnLoadCallback(function() {
GCSERender();
}, true );
}
};
window.__gcse = {
parsetags: 'explicit',
callback: GCSECallBack
};
})(jQuery, window);
(function() {
var cx = '017643444788069204610:4gvhea_mvga'; // Insert your own Custom Search engine ID here
var gcse = document.createElement('script'); gcse.type = 'text/javascript'; gcse.async = true;
gcse.src = 'https://www.google.com/cse/cse.js?cx=' + cx;
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(gcse, s);
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="gcse-container" id="gcse_container">
<gcse:search enableAutoComplete="true"></gcse:search>
</div>
The above CODE snippet uses Google Custom Search element control API.
Is there a polyfill for the IE events mouseenter/mouseleave (or a conversion of the jQuery events) so it can be bound to raw JS events?
I.E. I is there a cross browser way to do this:
node.addEventListener('mouseenter', function() {
...
});
node.addEventListener('mouseleave', function() {
...
});
I know it should be possible custom events using:
var event = new Event('mouseenter');
node.addEventListener('mouseenter', function (e) { ... });
node.dispatchEvent(event);
etc
Ok, seems I figured out how to do it:
http://jsfiddle.net/HXwJH/5/
node.addEventListener('mouseover', function() {
if (!event.relatedTarget || (event.relatedTarget !== this && !(this.compareDocumentPosition(event.relatedTarget) & Node.DOCUMENT_POSITION_CONTAINED_BY))) {
this.dispatchEvent(new Event('mouseenter'));
}
});
node.addEventListener('mouseout', function() {
if (!event.relatedTarget || (event.relatedTarget !== this && !(this.compareDocumentPosition(event.relatedTarget) & Node.DOCUMENT_POSITION_CONTAINED_BY))) {
this.dispatchEvent(new Event('mouseleave'));
}
});