How to force disable the modal or a button? - javascript

When my users are readOnly, I want to limit some access. In this case, the ability to edit notes. I can't explain why with this code, I still can open up my note when the user is readOnly
if(codeParam == '{{ $baby->readOnlyCode }}' ) {
//I am in side this code
$("a.btn, .btn-link, #logNote, pre, .btn").click(function() {
return false;
});
}
https://mybabies.app/baby/797b808a-e8c6-4a83-acf4-14ebe1f776b1?code=rithys4k
Please click on the note box, you will see that somehow it still be able to trigger.
I even tried added the check and return false in showModal()
function showModal(val, type, logId ) {
console.log("val, type, logId",val, type, logId);
if(codeParam == '{{ $baby->readOnlyCode }}' ) {
return false;
}
...
or tried preventDefault
if(codeParam == '{{ $baby->readOnlyCode }}' ) {
$("a.btn, .btn-link, #logNote, pre, .btn").click(function(e) {
e.preventDefault();
return false;
});
}
If you spotted what I missed, please let me know.

The problem you're having is you're attaching a second event listener that only returns false and prevents default, but the first event listener that pops the modal is still attached.
I.e.,
$("a.btn").click(function(e) {
alert("Hello World!");
});
$("a.btn").click(function(e) {
return false; // this does nothing to the previously attached event listener
});
Possible solutions:
From inspecting your code, you have some options:
$(document).on('show.bs.modal', '#noteModal', function (e) {
// move the check for the param here
if(codeParam == 'rithys4k' ) {
return false;
}
});
Or: Use disabled attributes on the buttons/links when in readonly mode.
To give you some more background - $().click() is really just shorthand for addEventListener on the click event

You have to use on method with suffix in jQuery, on jQuery Docs
const clickAction = (e) => {
// do anything
}
$('.btn, pre').on('click.go', clickAction);
Use off to remove events, off jQuery Docs
$('body').off("click.go", ".btn, pre");
// OR
$('body').off("click.go", ".btn, pre", clickAction);
// OR
$('.btn, pre').off("click.go");

You can debug the event order like this: $._data($("#logNote").get(0), "events");. New events go to the end and executed from top to bottom. In your case all you need to do is remember the trigger function and remove/add it when needed, example:
const cbToggleNoteModal = () => $("#toggleNoteModal").click();
// you have to store the cb in a variable
$("#logNote").click(cbToggleNoteModal);
// to disable the cb, just de-register the callback
$("#logNote").off("click", cbToggleNoteModal);
// and register it back when you need it
$("#logNote").click(cbToggleNoteModal);

Try doing this with css property pointer-events: none;
$("a.btn, .btn-link, #logNote, pre, .btn").css('pointer-events', 'none');

Related

Getting result of Confirm dialog on Cancel Button in jQuery event hander

On one side I have a form with submit/cancel buttons and the cancel has an onclick event (to do some cleanup) that is wrapped in a standard confirm dialog. All standard stuff.
But then I have a second script (and it MUST be a second script) that may only sometimes be loaded, that needs to add more tasks if the form is cancelled. So - I can listen for the onclick...
$( "#cancelBtn" ).on( "click", function(a) {
// do more stuff...
});
but I only want to 'do more stuff' if the confirm around the onclick is OK. I am probably missing something stupidly simple but I have been at this all day and am about to give up! Can anyone point me in the right direction?
Update: I can not change the form onclick code - it has to stay separate and as it now is.... so the confirm has to stay where it is.
Do it like this:
$( "#cancelBtn" ).on( "click", function(a) {
if (confirm('Are you sure you want to cancel?')) { // Standard confirmation message.
// Pressed OK.
// do more stuff...
} else {
// Pressed Cancel.
}
});
Hope this helps.
EDIT: Since you can't change the script performing form duty, a solution would be to overwrite the confirm()-function:
var _confirm = window.confirm;
window.confirm = function() {
//catch result
var confirmed = _confirm.apply(window,arguments);
if (confirmed) {
//confirm ok, do some tasks
} else {
//confirm cancelled, do some cleanup
}
//pass result on to the caller
return confirmed;
};
http://jsfiddle.net/sofcuoab/
put the tasks in the second script in
function doMoreStuff(){
//more tasks
}
and call it in your confirm-clause like this
if (typeof doMoreStuff === "function") {
doMoreStuff();
}
or like this
try {
doMoreStuff();
}
catch(err) {
//no second script loaded
}

Selectize.js: onItemAdd event triggered when silently adding an item

Using Selectize.js, I'm trying to initialize the dynamically pre-select one of the item of the list without triggering the onItemAdd event. In the following code, the event is triggered even if the silent parameter is truthy:
$(function () {
$('select').selectize({
onItemAdd: function () {
alert("Add item");
}
});
// this triggers an the event
$('select')[0].selectize.addItem('2', true);
});
JSFiddle: http://jsfiddle.net/zuzat0dc/1/
According to the documentation:
addItem(value, silent): "Selects" an item. Adds it to the list at the current caret position. If "silent" is truthy, no change event will be fired on the original input.
Any idea how to avoid triggering the onItemAdd event? Is the silent parameter b0rked or should I use the change event instead?
A quick fix that worked for me was to keep a state flag and refer to it in the event handler...
$(function () {
var initialising = true;
$('select').selectize({
onItemAdd: function () {
if(!initialising) {
alert("Add item");
}
}
});
// this triggers an the event
$('select')[0].selectize.addItem('2', true);
initialising = false;
});
The silent parameter in addItem(value, silent) affects only to the fact whether or not the change event. You can't avoid item_add event with silent = true.
The only thing that worked for me was to store item_add event locally, remove it from selectize instance and set it back after I added the item:
onItemAdd: function(val) {
var e = this._events['item_add'];
delete this._events['item_add'];
this.addItem(123);
this._events['item_add'] = e;
}

How to disable the click if a function is in active status

I have created a fiddle of my function here( http://jsfiddle.net/rhy5K/10/ ) . Now i want to disable the button click i.e play/pause if the sound is playing like Get ready,5,4,3,2,1 .
I know only how to disable the form submit button , but I am very confused how to disable the click in my case the hyperlinks.
Explanation using code example:
I want to disable this
PLAY
click, while interpreter is executing the below code:
var playGetReady = function (done) {
var ids = ['audiosource', 'a_5', 'a_4', 'a_3', 'a_2', 'a_1'],
playNext = function () {
var id = ids.shift();
document.getElementById(id).play();
if (ids.length) {
setTimeout(playNext, 1000);
} else {
done();
}
};
playNext();
};
Warning: This JS fiddle demo may play sound on load
You may try this (Changes in following function), but not sure if this is you want and maybe there are other ways to do it.
App.prototype.start = function () {
var self = this;
// unbind for a while
self.$button.unbind('click', self.buttonHandler); // <--
var start = function () {
// start countdown
self.intervalHandle = setInterval($.proxy(self.tick, self), 1000);
// bind again
self.$button.click($.proxy(self.buttonHandler, self)); // <--
// change button text to PAUSE
self.$button.text('PAUSE');
};
if (this.newTimer) {
playGetReady(start);
} else {
start();
}
};
DEMO.
In jquery, it can be done easily by cancel default action. Here's the sample.
$("#btn_start").click(function(event){
if(not_active_flag){
// Prevent anchor to active
return false;
}else{
// Anchor active as usual
return true;
}
});
In your case, the link will ultimately call this.buttonHandler, which has the following code:
App.prototype.buttonHandler = function (e) {
e.preventDefault(); // prevent anchor default action
this.toggle(); // toggle play/pause
};
Because buttonHandler is attached before playGetReady is executed, it is not possible to let playGetReady attach a click handler to that anchor element that uses .stopImmediatePropagation() to prevent the other click handler from executing.
In this case #gp.'s solution in the comments is most likely the best solution. In your case you might even be able to use a local variable in your app. If you use a global variable, reference it with window.yourglobalvariable. If you use a local variable, make sure you define it somewhere and reference it with this.yourvariable. Change your buttonHandler to:
App.prototype.buttonHandler = function (e) {
e.preventDefault(); // prevent anchor default action
if( this.soundready )
this.toggle(); // toggle play/pause
};
On the appropiate place make this variable false to prevent the 'button' from working. When the button should work, change the variable to true. I think that should be just before done() in the code you have in your question, but you probably have a better idea in what order the code is executed.

jQuery unbind click event function and re-attach depending on situation

The code below I use to create a sliding menu. I need to know how to unbind the function attached to the click event and re-attach it some other time. (using jQuery 1.7.2)
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
});
});
The code below is what I have so far
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
//else re-attach functionality?
}
});
Thanks
Simply make a named function. You can go low tech here and back to basics to unbind and reattach specific events.
function doStuff()
{
if($(this).,next('.section').is(':visible'))
...
}
$('.header').on('click', doStuff);
$('.header').off('click', doStuff);
Instead of unbind and re-bind, I suggest you to add a simple class to .header and check for the class in the click handler. See below,
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('dontClick');
} else {
$('.header').removeClass('dontClick');
}
});
And in your .header click handler,
$('.header').click(function(){
if ($(this).hasClass('dontClick')) {
return false;
}
//rest of your code
If you insist on having a unbind and bind, then you can move the handler to a function and unbind/bind the function any number of time..
You can try something like this.
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').addClass('clickDisabled');
}
else
{
$('.header').removeClass('clickDisabled');
}
});
And then in the click handler check for this class.
$(document).ready(function(){
$('.section').hide();
$('.header').click(function(){
if(!$(this).hasClass('clickDisabled')){
...
...
}
});
});
Why not make that top section a function, and then call it in your else statement?
You could try setting a variable as a flag. var canClick = ($('#formVersion').val() != 'Print'); Then in the click handler for your .header elements check to see if canClick is true before executing your code.
If you still want to remove the handler you can assign the events object to a variable. var eventObj = #('.header').data('events'); That will give you an object with all the handlers assigned to that object. To reassign the click event it would be like $('.header').bind('click', eventObj.click[0]);
After trying so hard with bind, unbind, on, off, click, attr, removeAttr, prop I made it work.
So, I have the following scenario: In my html i have NOT attached any inline onclick handlers.
Then in my Javascript i used the following to add an inline onclick handler:
$(element).attr('onclick','myFunction()');
To remove this at a later point from Javascript I used the following:
$(element).prop('onclick',null);
This is the way it worked for me to bind and unbind click events dinamically in Javascript. Remember NOT to insert any inline onclick handler in your elements.
You could put all the code under the .click in a separated function
function headerClick(){
if($(this).next('.section').is(':visible'))
{
$('.section:visible').slideUp()
$('.arrows:visible').attr("src","right.gif")
}
else
{
$('.section').slideUp();
$(this).next('.section').slideToggle();
$(this).find('.arrows').attr("src","down.gif")
}
}
and then bind it like this:
$(document).ready(function(){
$('.section').hide();
$('.header').click(headerClick);
});
$('#printVers').click(function(){
if($('#formVersion').val() != "Print")
{
$('.header').unbind('click');
}
else
{
$('.header').click(headerClick);
}
});

What is the opposite of evt.preventDefault();

Once I've fired an evt.preventDefault(), how can I resume default actions again?
As per commented by #Prescott, the opposite of:
evt.preventDefault();
Could be:
Essentially equating to 'do default', since we're no longer preventing it.
Otherwise I'm inclined to point you to the answers provided by another comments and answers:
How to unbind a listener that is calling event.preventDefault() (using jQuery)?
How to reenable event.preventDefault?
Note that the second one has been accepted with an example solution, given by redsquare (posted here for a direct solution in case this isn't closed as duplicate):
$('form').submit( function(ev) {
ev.preventDefault();
//later you decide you want to submit
$(this).unbind('submit').submit()
});
function(evt) {evt.preventDefault();}
and its opposite
function(evt) {return true;}
cheers!
To process a command before continue a link from a click event in jQuery:
Eg: Click me
Prevent and follow through with jQuery:
$('a.myevent').click(function(event) {
event.preventDefault();
// Do my commands
if( myEventThingFirst() )
{
// then redirect to original location
window.location = this.href;
}
else
{
alert("Couldn't do my thing first");
}
});
Or simply run window.location = this.href; after the preventDefault();
OK ! it works for the click event :
$("#submit").click(function(event){
event.preventDefault();
// -> block the click of the sumbit ... do what you want
// the html click submit work now !
$("#submit").unbind('click').click();
});
event.preventDefault(); //or event.returnValue = false;
and its opposite(standard) :
event.returnValue = true;
source:
https://developer.mozilla.org/en-US/docs/Web/API/Event/returnValue
I had to delay a form submission in jQuery in order to execute an asynchronous call. Here's the simplified code...
$("$theform").submit(function(e) {
e.preventDefault();
var $this = $(this);
$.ajax('/path/to/script.php',
{
type: "POST",
data: { value: $("#input_control").val() }
}).done(function(response) {
$this.unbind('submit').submit();
});
});
I would suggest the following pattern:
document.getElementById("foo").onsubmit = function(e) {
if (document.getElementById("test").value == "test") {
return true;
} else {
e.preventDefault();
}
}
<form id="foo">
<input id="test"/>
<input type="submit"/>
</form>
...unless I'm missing something.
http://jsfiddle.net/DdvcX/
This is what I used to set it:
$("body").on('touchmove', function(e){
e.preventDefault();
});
And to undo it:
$("body").unbind("touchmove");
There is no opposite method of event.preventDefault() to understand why you first have to look into what event.preventDefault() does when you call it.
Underneath the hood, the functionality for preventDefault is essentially calling a return false which halts any further execution. If you’re familiar with the old ways of Javascript, it was once in fashion to use return false for canceling events on things like form submits and buttons using return true (before jQuery was even around).
As you probably might have already worked out based on the simple explanation above: the opposite of event.preventDefault() is nothing. You just don’t prevent the event, by default the browser will allow the event if you are not preventing it.
See below for an explanation:
;(function($, window, document, undefined)) {
$(function() {
// By default deny the submit
var allowSubmit = false;
$("#someform").on("submit", function(event) {
if (!allowSubmit) {
event.preventDefault();
// Your code logic in here (maybe form validation or something)
// Then you set allowSubmit to true so this code is bypassed
allowSubmit = true;
}
});
});
})(jQuery, window, document);
In the code above you will notice we are checking if allowSubmit is false. This means we will prevent our form from submitting using event.preventDefault and then we will do some validation logic and if we are happy, set allowSubmit to true.
This is really the only effective method of doing the opposite of event.preventDefault() – you can also try removing events as well which essentially would achieve the same thing.
Here's something useful...
First of all we'll click on the link , run some code, and than we'll perform default action. This will be possible using event.currentTarget Take a look. Here we'll gonna try to access Google on a new tab, but before we need to run some code.
Google
<script type="text/javascript">
$(document).ready(function() {
$("#link").click(function(e) {
// Prevent default action
e.preventDefault();
// Here you'll put your code, what you want to execute before default action
alert(123);
// Prevent infinite loop
$(this).unbind('click');
// Execute default action
e.currentTarget.click();
});
});
</script>
None of the solutions helped me here and I did this to solve my situation.
<a onclick="return clickEvent(event);" href="/contact-us">
And the function clickEvent(),
function clickEvent(event) {
event.preventDefault();
// do your thing here
// remove the onclick event trigger and continue with the event
event.target.parentElement.onclick = null;
event.target.parentElement.click();
}
I supose the "opposite" would be to simulate an event. You could use .createEvent()
Following Mozilla's example:
function simulateClick() {
var evt = document.createEvent("MouseEvents");
evt.initMouseEvent("click", true, true, window,
0, 0, 0, 0, 0, false, false, false, false, 0, null);
var cb = document.getElementById("checkbox");
var cancelled = !cb.dispatchEvent(evt);
if(cancelled) {
// A handler called preventDefault
alert("cancelled");
} else {
// None of the handlers called preventDefault
alert("not cancelled");
}
}
Ref: document.createEvent
jQuery has .trigger() so you can trigger events on elements -- sometimes useful.
$('#foo').bind('click', function() {
alert($(this).text());
});
$('#foo').trigger('click');
This is not a direct answer for the question but it may help someone. My point is you only call preventDefault() based on some conditions as there is no point of having an event if you call preventDefault() for all the cases. So having if conditions and calling preventDefault() only when the condition/s satisfied will work the function in usual way for the other cases.
$('.btnEdit').click(function(e) {
var status = $(this).closest('tr').find('td').eq(3).html().trim();
var tripId = $(this).attr('tripId');
if (status == 'Completed') {
e.preventDefault();
alert("You can't edit completed reservations");
} else if (tripId != '') {
e.preventDefault();
alert("You can't edit a reservation which is already attached to a trip");
}
//else it will continue as usual
});
jquery on() could be another solution to this. escpacially when it comes to the use of namespaces.
jquery on() is just the current way of binding events ( instead of bind() ). off() is to unbind these. and when you use a namespace, you can add and remove multiple different events.
$( selector ).on("submit.my-namespace", function( event ) {
//prevent the event
event.preventDefault();
//cache the selector
var $this = $(this);
if ( my_condition_is_true ) {
//when 'my_condition_is_true' is met, the binding is removed and the event is triggered again.
$this.off("submit.my-namespace").trigger("submit");
}
});
now with the use of namespace, you could add multiple of these events and are able to remove those, depending on your needs.. while submit might not be the best example, this might come in handy on a click or keypress or whatever..
you can use this after "preventDefault" method
//Here evt.target return default event (eg : defult url etc)
var defaultEvent=evt.target;
//Here we save default event ..
if("true")
{
//activate default event..
location.href(defaultEvent);
}
You can always use this attached to some click event in your script:
location.href = this.href;
example of usage is:
jQuery('a').click(function(e) {
location.href = this.href;
});
In a Synchronous flow, you call e.preventDefault() only when you need to:
a_link.addEventListener('click', (e) => {
if( conditionFailed ) {
e.preventDefault();
// return;
}
// continue with default behaviour i.e redirect to href
});
In an Asynchronous flow, you have many ways but one that is quite common is using window.location:
a_link.addEventListener('click', (e) => {
e.preventDefault(); // prevent default any way
const self = this;
call_returning_promise()
.then(res => {
if(res) {
window.location.replace( self.href );
}
});
});
You can for sure make the above flow synchronous by using async-await
this code worked for me to re-instantiate the event after i had used :
event.preventDefault(); to disable the event.
event.preventDefault = false;
I have used the following code. It works fine for me.
$('a').bind('click', function(e) {
e.stopPropagation();
});

Categories

Resources