Custom Fields
Re-Envisioned
Support Meta Box Conditional Logic Conditional MB Using Clone-able Select Field

This topic contains 5 replies, has 2 voices, and was last updated by  Anh Tran 7 months, 1 week ago.

Viewing 5 replies - 1 through 5 (of 5 total)
  • Author
    Replies
  • #10468

    Anh 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

    mgratch
    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 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

    mgratch
    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 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 5 replies - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.