2
\$\begingroup\$

I need to run the following checks in two occasions:

  1. When a certain modal is first shown or clicked,
  2. When one of two inputs is filled.

How can I remove redundancy in the following code?

jQuery(document).ready( function($) {
    $(document.body).on( 'DOMNodeInserted click',  '.media-modal', function( event ) {
        var test = $('label.setting[data-setting=alt] input:visible').val();
        var test2 = $('input[data-setting=alt]:visible').val();
        if (!test && !test2) {
            $('.media-modal .media-button-insert').prop("disabled",true);
            $('.media-modal .media-button-select').prop("disabled",true);
        } else {
            $('.media-modal .media-button-insert').prop("disabled",false);
            $('.media-modal .media-button-select').prop("disabled",false);
        }
        $(document.body).on( 'input propertychange paste',  'label.setting[data-setting=alt] input, input[data-setting=alt]', function( event ) {
            var test = $('label.setting[data-setting=alt] input:visible').val();
            var test2 = $('input[data-setting=alt]:visible').val();
            if (!test && !test2) {
                $('.media-modal .media-button-insert').prop("disabled",true);
                $('.media-modal .media-button-select').prop("disabled",true);
            } else {
                $('.media-modal .media-button-insert').prop("disabled",false);
                $('.media-modal .media-button-select').prop("disabled",false);
            }
        });
    });
});
\$\endgroup\$

2 Answers 2

2
\$\begingroup\$

I would write it as something like:

jQuery(document).ready( function($) {

    function updateDisabled() {
        var test     = $('label.setting[data-setting=alt] input:visible').val();
        var test2    = $('input[data-setting=alt]:visible').val();
        var disabled = !test && !test2;
        $('.media-modal .media-button-insert').prop("disabled", disabled);
        $('.media-modal .media-button-select').prop("disabled", disabled);
    }   

    $(document.body).on( 'DOMNodeInserted click', '.media-modal', updateDisabled);
    $(document.body).on( 'input propertychange paste', 'label.setting[data-setting=alt] input, input[data-setting=alt]', updateDisabled);

}

You could also rewrite:

$('.media-modal .media-button-insert').prop("disabled", disabled);
$('.media-modal .media-button-select').prop("disabled", disabled);

As

$('.media-modal .media-button-insert, .media-modal .media-button-select').prop("disabled", disabled);

(Although I prefer keeping them separate) or maybe better giving your buttons an extra class and writing:

$('.media-modal .media-button').prop("disabled", disabled);
\$\endgroup\$
1
  • \$\begingroup\$ Amazing, exactly what I needed! Thanks! I also rewrote the var lines as a single line. \$\endgroup\$ Commented Jun 21, 2017 at 0:46
2
\$\begingroup\$

Marc's answer is pretty much what I would have posted, except his code differs from yours in that your input/paste/propertychange handler is not registered until after the node/click handler. He did that because yours is going to register that inner event handler over and over exponentially every time there's a click. You can fix that by removing the handler after it's no longer needed.

jQuery(document).ready( function($) {

    function updateDisabled() {
        var test     = $('label.setting[data-setting=alt] input:visible').val();
        var test2    = $('input[data-setting=alt]:visible').val();
        var disabled = !test && !test2;
        $('.media-modal .media-button-insert').prop("disabled", disabled);
        $('.media-modal .media-button-select').prop("disabled", disabled);
    }   

    $(document.body).on( 'DOMNodeInserted click', '.media-modal', function(){
        updateDisabled();
        $(document.body).on( 'input propertychange paste', 'label.setting[data-setting=alt] input, input[data-setting=alt]', function(){
            updateDisabled();
            $(document.body).off('input propertychange paste', 'label.setting[data-setting=alt] input, input[data-setting=alt]');
        });
    });

}
\$\endgroup\$
3
  • \$\begingroup\$ Thanks for calling my attention to the unnecessary event nesting! \$\endgroup\$ Commented Jun 20, 2017 at 13:54
  • \$\begingroup\$ Wouldn't this only handle the first change to the input as you disable the event afterwards? \$\endgroup\$ Commented Jun 21, 2017 at 4:36
  • \$\begingroup\$ Yes. But the even is registered again when the element is clicked. It's hard to tell wht the OP wanted. \$\endgroup\$ Commented Jun 21, 2017 at 11:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.