How to force disable the modal or a button?

Viewed 199

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.

enter image description here

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.

4 Answers

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