How to trigger delete key in jQuery - javascript

I am looking for a way to trigger the delete key on jQuery. However, for example, the whole selection (Ctrl+A) works well, The Delete key does not work.
Below is a part of my code:
var ctrlA = $.Event( "keydown", { keyCode: 65, ctrlKey:true } ),
e = $.Event( "keydown", { keyCode: 46 } );
....
$( editor.getBody() ).trigger( ctrlA );
$( editor.getBody() ).trigger( e );
This will make the entire selection but it will not be deleted.
How to trigger the Delete key in jQuery?

Related

JQuery click event fires on second click but not on first

I've google for this but I could no find a solution for my issue. I have some events on a js function (Immediate function invocation). Therefore the click event is not working well. It fires only on the second invocation.
The first three fields (To, Cc, and Cco) should expand when you type a long text. The click event should collapse the "To", "Cc" and "Cco" fields when you click on "Subject" field. It works, but only on the second time I click in subject.
Heres my js (IIF)
function initTextareaEvents(){
$('section textarea').on({
focusin:function( ev ) {
if($( this ).closest( '.info-box' ).length > 0){
$( this ).elastic();
}
},
keypress:function( ev ) {
var key = ev.which;
if(key == 13 || key == 32){
ev.preventDefault();
var str = $( this ).val().trim();
str += ', ';
$( this ).val( str );
}
},
click:function ( ev ) {
if($( this ).closest( '.info-box' ).length === 0){
$( '#to, #cc, #cco' ).css( 'height', 'auto' );
}
}
});
}
Here is Codepen
The first click is acting as "Focus Out" I think. try adding something like
focusout:function( ev ) {
if($( this ).closest( '.info-box' ).length > 0){
$( this ).elastic();
}
},
This seems to get you closer to the behavior you want.

jQuery change and click events

Binding events to an element should be something like:
$( document ).on( 'change', '#mySelect', showEvent );
$( document ).on( 'click', '#mySelect', showEvent );
function showEvent() {
console.log( event.target );
}
But by doing a simple test as shown below, binding the change and click events to the object mySelect they are triggered on different elements (change only by changing the select and the click by clicking anywhere on the document).
var mySelect = $( '#mySelect' );
$( document ).on( 'change', mySelect, showEvent );
$( document ).on( 'click', mySelect, showEvent );
function showEvent( event ) {
console.log( event.target );
}
Two questions:
How does the change event work? By the documentation it shouldn't work because the selector must be a string:
A selector string to filter the descendants of the selected elements that trigger the event.
It souldn't work but, if the change works, why doesn't the click?
selector
Type: String A selector string to filter the descendants of the selected elements that trigger the event. If the selector is null or omitted, the event is always triggered when it reaches the selected element.
Taken from http://api.jquery.com/on/
You are using the selector as a jQuery object, this method is mainly using for event delegation for binding event to dynamically generated element. So you can bind event directly to the jQuery object as
var mySelect = $( '#mySelect' );
mySelect.on( 'change', mySelect, showEvent )
.on( 'click', mySelect, showEvent );
function showEvent() {
console.log( event.target );
}
If it's dynamically generated then remove the $ wrapping just provide it as string
var mySelect = '#mySelect';
$( document ).on( 'change', mySelect, showEvent );
$( document ).on( 'click', mySelect, showEvent );
function showEvent() {
console.log( event.target );
}

Multiple events on same element, stop immediate propagation

I have two click events on the same element. One of them is a delegated event, and the the other one is not.
$( document ).on( 'click.bar', 'p', function( e ) {
console.log( 'click.bar', e );
e.stopImmediatePropagation();
});
$( 'p' ).on( 'click.foo', function( e ) {
console.log( 'click.foo' );
});
I want to disable the "click.foo" in a specific situation, when "click.bar" is executed. The problem is, that "click.foo" is always called before "click.bar" is called. Any ideas?
If you handle both events from $(document), the event.stopImediatePropagation works fine.
You have to register the first event (the one with the event.stopImediatePropagation) first in the script, so it is called first when document is clicked.
$( document ).on( 'click.bar', 'p', function( e ) {
console.log( 'click.bar', e );
e.stopImmediatePropagation();
});
$( document ).on( 'click.foo', 'p', function( e ) {
console.log( 'click.foo' );
});
Other way it won't work because jQuery bubbles the event up (inner to outer), so the event registered in p is triggered first before it reaches the document.

Popup window not showing div

I have this JQuery code:
function JQueryPopup(value) {
$(value).toggle();
$('#JQueryClose').click(function(){
$(value).hide();
});
$( document ).on( 'click', function ( e ) {
$(value).hide();
});
$( document ).on( 'keydown', function ( e ) {
if ( e.keyCode === 27 ) { // ESC
$(value).hide();
}
});
}
and a HTML button that calls this function, it doesn't seem to be showing the popup window/div.
here is a fiddle with my full code: http://jsfiddle.net/XHLY8/3/
P.S. i do have this code on another page, i call the function like this:
<script type="text/javascript">JQueryPopup('#customer_popup_notes');</script>
which works fine.
You need to add the following:
$('#inbox_button').on('click', function(event){
event.preventDefault(); // This isn't critical, but you would need
event.stopPropagation();
JQueryPopup('#inbox_div');
});
You want to stop the click event from bubbling up and triggering the following:
$( document ).on( 'click', function { ... });
Otherwise your #inbox_div will be hidden before you can see it.
Here is a working fiddle.
I suggest reading up on stopPropagation and preventDefault.
You dont need
$( document ).on( 'click', function ( e ) {
$(value).hide();
});
Which always hides the Bottom div no matter where u click .
Working fiddle

How to test a function which has a setTimeout with jasmine?

I need to write a test for a function that has a setTimeout() call inside, but i can't find how i should do.
This is the function
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( 'type', 'hidden' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn't work in chrome.
setTimeout(function() {
$( '#facebook input[type=submit]' ).prop( 'disabled', true );
}, 10);
// unbind all click handler from ajax
$( '#facebook a.btn' ).unbind( "click" );
// Disable all AJAX buttons.
$( '#facebook a.btn' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
And this is my test
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
console.log( 'f' );
expect( el ).toHaveProp( 'disabled', true );
} );
} );
I've tried using jasmine.Clock.useMock(); and jasmine.Clock.tick(11); but i couldn't get things to work, the test never pass
The overall approach varies based on your Jasmine version.
Jasmine 1.3
You can use waitsFor:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// Wait 100ms for all elements to be disabled.
waitsFor('button to be disabled', function(){
var found = true;
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
if (!el.prop('disabled')) found = false;
});
return found;
}, 100);
});
You could also use waits if you know exactly how long it will take:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// Wait 20ms before running 'runs' section.
waits(20);
runs(function(){
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
expect( el ).toHaveProp( 'disabled', true );
});
});
});
There is also a third way of doing this, without the need for waits, waitsFor, and runs.
it( "Disable all submit buttons", function() {
jasmine.Clock.useMock();
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
jasmine.Clock.tick(10);
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
expect( el ).toHaveProp( 'disabled', true );
});
});
Jasmine 2.0
You can use done, the test callback:
it( "Disable all submit buttons", function(done) {
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
utility_functions.block_all_submit_and_ajax( $button.get(0) );
setTimeout(function(){
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
expect( el ).toHaveProp( 'disabled', true );
});
// Let Jasmine know the test is done.
done();
}, 20);
});
you can mock out the timer behavior:
it( "Disable all submit buttons", function() {
jasmine.clock().install();
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
jasmine.clock().tick(10);
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
expect( el ).toHaveProp( 'disabled', true );
});
jasmine.clock().uninstall()
});
For anyone googling this, a better answer can be found timer testing
import { fakeAsync, tick, discardPeriodicTasks } from '#angular/core/testing';
it('polls statusStore.refreshStatus on an interval', fakeAsync(() => {
spyOn(mockStatusStore, 'refreshStatus').and.callThrough();
component.ngOnInit();
expect(mockStatusStore.refreshStatus).not.toHaveBeenCalled();
tick(3001);
expect(mockStatusStore.refreshStatus).toHaveBeenCalled();
tick(3001);
expect(mockStatusStore.refreshStatus).toHaveBeenCalledTimes(2);
discardPeriodicTasks();
}));
Since Jasmine 2 the syntax has changed: http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
You now can simply pass a done callback to beforeEach, it, and afterEach:
it('tests something async', function(done) {
setTimeout(function() {
expect(somethingSlow).toBe(true);
done();
}, 400);
});
Update: Since writing this it's now also possible to use async/await which would be my preferred approach.
I've never done any testing with jasmine, but I think I understand your problem. I would restructure the code a little to allow for you to wrap the function being called in a proxy function like this:
Modify your code that is being test to extract the setTimeout code into another function:
Original Code:
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( 'type', 'hidden' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn't work in chrome.
setTimeout(function() {
$( '#facebook input[type=submit]' ).prop( 'disabled', true );
}, 10);
// unbind all click handler from ajax
$( '#facebook a.btn' ).unbind( "click" );
// Disable all AJAX buttons.
$( '#facebook a.btn' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
Modified Code:
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( 'type', 'hidden' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn't work in chrome.
setTimeout(disableSubmitButtons, 10);
// unbind all click handler from ajax
$( '#facebook a.btn' ).unbind( "click" );
// Disable all AJAX buttons.
$( '#facebook a.btn' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
var utilityFunctions =
{
disableSubmitButtons : function()
{
$( '#facebook input[type=submit]' ).prop( 'disabled', true );
}
}
Next I would modify the testing code like this:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( '#ai1ec_subscribe_users' );
var originalFunction = utilityFunctions.disableSubmitButtons;
utilityFunctions.disableSubmitButtons = function()
{
// call the original code, and follow it up with the test
originalFunction();
// check that all submit are disabled
$( '#facebook input[type=submit]' ).each( function( i, el ) {
console.log( 'f' );
expect( el ).toHaveProp( 'disabled', true );
});
// set things back the way they were
utilityFunctions.disableSubmitButtons = originalFunction;
}
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
});

Categories

Resources