Conditional MB Using Clone-able Select Field

Support MB Conditional Logic Conditional MB Using Clone-able Select FieldResolved

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #10465
    mgratchmgratch
    Participant

    I a group field that begins with a select fields. Based on the select fields value determines what fields are visible in the rest of the group as well as trigger another metabox to be visible. The group is clone-able.

    The cloneable group is sf_sign_modules:
    https://gist.github.com/mgratch/6044e6178827f93f6943adf693c78305#file-functions-php-L17

    The select field sf_sign_module_type is defined here: https://gist.github.com/mgratch/6044e6178827f93f6943adf693c78305#file-functions-php-L22

    The room-availability metabox to show/hide is defined here: https://gist.github.com/mgratch/6044e6178827f93f6943adf693c78305#file-functions-php-L509

    The metabox conditional checks are defined here: https://gist.github.com/mgratch/6044e6178827f93f6943adf693c78305#file-functions-php-L576

    Expected behavior: When I select the value room-availability-module from the sf_sign_module_type select field or a cloned version of it i.e. sf_sign_modules[1][sf_sign_module_type] the room-availability metabox should be visible.

    What is happening: the room-availability metabox is not visible.

    Thank you, any help is appreciated.

    #10468
    Anh TranAnh Tran
    Keymaster

    Hi,

    Thanks a lot for your very detail topic!

    After looking at the bug and the code, I found a bug in this case. I've released a new version of the plugin. Please update it.

    #10470
    mgratchmgratch
    Participant

    Hi,

    Thank you for such a quick a reply.

    When I select the value room-availability-module from the sf_sign_module_type select field the room-availability metabox is visible. Unfortunately sf_sign_module_type clones i.e. sf_sign_modules[1][sf_sign_module_type] still do not trigger the conditional action.

    Thanks again!

    #10473
    Anh TranAnh Tran
    Keymaster

    I got it. The thing here is the plugin detects the first element that contains the condition, which is the first clone in this case.

    It would be very confusing if it detects all elements and parse the conditions. The plugin can't understand whether to show "room-availability" when all clones satisfy the condition or any clone satisfy it. In this case, this is "any", but in general, there's no way to know that :(.

    I think to solve this problem, please just set the first clone as the trigger for the rules.

    #10502
    mgratchmgratch
    Participant

    I get your point, I can't think of a situation where ALL clones would have to meet 1 condition, but regardless I get it.

    in case anyone needs it or you see a good way to include it I created the following callback:

    
    // js functions
        function checkCompareStatement(needle, haystack, compare) {
            if (needle === null || typeof needle === 'undefined') {
                needle = '';
            }
            switch (compare) {
            case '=':
                if ($.isArray(needle) && $.isArray(haystack)) {
                    return $(needle).not(haystack).length === 0 && $(haystack).not(needle).length === 0;
                }
                return needle == haystack;
    
            case '>=':
                return needle >= haystack;
    
            case '>':
                return needle > haystack;
    
            case '<=':
                return needle <= haystack;
    
            case '<':
                return needle < haystack;
    
            case 'contains':
                if ($.isArray(needle)) {
                    return $.inArray(haystack, needle) > -1;
                } else if ($.type(needle) === 'string') {
                    return needle.indexOf(haystack) > -1;
                }
                return false;
    
            case 'in':
                if (!$.isArray(needle)) {
                    return haystack.indexOf(needle) > -1;
                }
                var found = false;
                $.each(needle, function(index, value) {
                    if ($.isNumeric(value)) {
                        value = parseInt(value);
                    }
    
                    if (haystack.indexOf(value) > -1) {
                        found = true;
                    }
                });
    
                return found;
    
            case 'start_with':
            case 'starts with':
                return needle.indexOf(haystack) === 0;
    
            case 'end_with':
            case 'ends with':
                haystack = new RegExp(haystack + '$');
                return haystack.test(needle);
    
            case 'match':
                haystack = new RegExp(haystack);
                return haystack.test(needle);
    
            case 'between':
                if ($.isArray(haystack) && typeof haystack[0] !== 'undefined' && typeof haystack[1] !== 'undefined') {
                    return checkCompareStatement(needle, haystack[0], '>=') && checkCompareStatement(needle, haystack[1], '<=');
                }
        }
    }
    
    function check_for_clone(haystack, compare, needle) {
        var val;
        var $elements = $('[name*="' + haystack + '"]');
        $.each($elements, function() {
            if (true === checkCompareStatement(needle, this.value, compare)) {
                val = this.value;
                return false;
            }
        })
        return val;
    }
    
    // your field or metabox
            'visible'    => array(
                'when'     => array(
                    array( 'check_for_clone("sf_sign_module_type", "=", "room-availability-module")', '=', 'room-availability-module') ,
                    array( 'check_for_clone("sf_sign_module_type", "=", "room-current-activity-module")', '=', 'room-current-activity-module'),
                    array( 'check_for_clone("sf_sign_module_type", "=", "room-upcoming-activity-module")', '=', 'room-upcoming-activity-module'),
                ),
                'relation' => 'or',
            ),
    

    I am simply re-using the built-in checkCompareStatement -- if some of your functions had global access it could be very useful, along with other conditional passed parameters, i.e. needle, compare, haystack

    #10515
    Anh TranAnh Tran
    Keymaster

    Hey @mgratch, your solution is great! Thanks for posting it here for others. I completely forgot about the custom callback. Nice work!

Viewing 6 posts - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.