• Hello Fabrik Community

    Fabrik is now in the hands of the development team that brought you Fabrik for Joomla 4. We have recently transitioned the Fabrik site over to a new server and are busy trying to clean it up. We have upgraded the site to Joomla 4 and are running the latest version of Fabrik 4. We have also upgraded the Xenforo forum software to the latest version. Many of the widgets you might have been used to on the forum are no longer operational, many abandoned by the developers. We hope to bring back some of the important ones as we have time.

    Exciting times to be sure.

    The Fabrik 4.0 Official release is now available. In addition, the Fabrik codebase is now available in a public repository. See the notices about these in the announcements section

    We wish to shout out a very big Thank You to all of you who have made donations. They have really helped. But we can always use more...wink..wink..

    Also a big Thank You to those of you who have been assisting others in the forum. This takes a very big burden off of us as we work on bugs, the website and the future of Fabrik.

Limit Database Dropdown max selections

chris.paschen

Chris Paschen
[this is a follow up to an original topic started in the community forum: http://fabrikar.com/forums/index.ph...own-multi-select-quantity.46282/#post-239400]

I need to restrict a databasejoin dropdown to only allow 3 selections.

Based on several other posts I've added the following JS on the onClick for the element:

/* enforce only 3 selections */
if(jQuery("#" + this.baseElementId ).val().length>3) {
jQuery("#" + this.baseElementId ).parent().next("div.fabrikErrorMessage").html('<span style="color:red">You must select no more than 3 items.</span>');
}else{
jQuery("#" + this.baseElementId ).parent().next("div.fabrikErrorMessage").html('');
}​

That adds an 'alert' to the element whenever the user has more than 3 selected.

However, I need a way to actually prevent the 4th one from being added?

Is there a way to stop values from being added (i.e. when > 2), but still allow items to be un-selected from the list?

NOTE: I have used the PHP validation using:

$this->setMessage('Too many fiction categories selected');
return count($formModel->formData['ked_books_books___fiction_categories']) < 4;​

However, I'd like to have the validation in real-time.

I tried a couple options like:

/* enforce only 3 selections */
var last_valid_selection = null;
if(jQuery("#" + this.baseElementId ).val().length>3) {
$(jQuery('#' + this.baseElementID ).val(last_valid_selection));
jQuery("#" + this.baseElementId ).parent().next("div.fabrikErrorMessage").html('<span style="color:red">You must select no more than 3 items.</span>');
}else{
last_valid_selection = $(jQuery('#' + this.baeElementID ).val());
jQuery("#" + this.baseElementId ).parent().next("div.fabrikErrorMessage").html('');
}​

based on other generic JS code snippets I've seen (trying to make them work with what I think it proper syntax for Fabrik). But this actually causes the script to do nothing (the notification doesn't even work any more).

Any ideas what I could add to the first code (or how to change it) to make it work to limit the max number of selections?
 
One potential way would be to use the "Enhanced Dropdowns" feature, with a little JS. The "enhanced" dropdowns use the jQuery Chosen plugin to prettify dropdowns / multiselects. And although we don't (yet) have a baked in way of setting a max selection, it does have that option:

https://harvesthq.github.io/chosen/options.html

So although we don't have a way (yet) of adding options to specific selects (we only provide a global setting), it would be possible to recreate the enhanced dropdown by doing ...

JavaScript:
jQuery('#yourtable___yourselect').chosen('destroy').chosen({'max_selected_options': 3);
jQuery('#yourtable___yourselect').on('chosen:maxselected', function() { alert("you can only select 3 thingies"); });

... at some point after Fabrik has applied the attributes. Which would probably mean wrapping it up in something like ...

JavaScript:
requirejs(['fab/fabrik'], function() {
   Fabrik.addEvent('fabrik.form.loaded', function() {
       // ... that code up there ^^ goes here
   });
});

I just played around with this, and the limiting works, I'm just having problems getting the chosen:maxselected event to fire.

-- hugh
 
Hmm.. I'm not sure how to tell if it is working. It doesn't appear to have any effect on the element, although I'm not 100% sure where to place this script. I tried placing it on the element JavaScript as onLoad and onClick and onChange and doesn't seem to work.

I did find one syntax problem in the post above. In the first set of code, first line is missing a "}" near the end. It should be:

jQuery('#yourtable___yourselect').chosen('destroy').chosen({ 'max_selected_options': 3 });

 
Did you get the enhanced multiselect? I think you may need to enable that feature in the Fabrik global options as well.

https://www.screencast.com/t/vGcAwqwSj

Note how after rebuilding the chosen() with the max-select option in the debugger console, it stops at 3, the select won't open.

The part I'm having issues with is getting the trigger for chosen:maxselected to work, which should allow us to provide some feedback when max is reached.

Basically, I'd much rather go this route, using a supported option of a supported UI - the 'chosen' plugin is actually shipped with J!, and part of the supported 'behavior' - rather than hacking some custom JS together to do it.

If I can get this working, I'll look at making per-dropdown options work, so I can just add this as a feature to the join element settings. Might not be trivial, for gory reasons to do with how we have to load and fire the 'chosen' plugin (especially on AJAX loaded popups), but I think I see a way.

BTW, not sure if you'll be able to fire this in an element JS. You may need to put it in a file, ./components/com_fabrik/js/list_X.js (where X is your numeric list ID), and wrap it up in an event.

-- hugh
 
OK, I had a quick stab at adding per-element options, and it's working. I'll play around with it some more, and commit it at some point soon.

-- hugh
 
Nope, guess I got distracted. I can see where I was playing around with it, and recall adding the code in our chosen-loader.js, with the data('chosen-options') which extends the base options ...

Code:
        Fabrik.buildChosen = function (selector, options) {
            if ($(selector).chosen !== undefined) {
                $(selector).each(function (k, v) {
                    var allOptions;
                    var moreOptions = $(v).data('chosen-options');
                    if (moreOptions) {
                        allOptions = $.extend({}, options, moreOptions);
                    }
                    else {
                        allOptions = options;
                    }
                    $(v).chosen(allOptions);
                    $(v).addClass('chzn-done');
                });
                return true;
            }
        };

... and in the database join code where I was playing with adding the max-selected-options into that data-chosen-options attribute ...

Code:
        if ($this->isEditable())
        {
            $multiSize     = (int) $params->get('dbjoin_multilist_size', 6);
            $advancedClass = $this->getAdvancedSelectClass();
            $attributes    = 'class="' . $class . ' ' . $advancedClass . '" size="' . $multiSize . '" multiple="true"';
            //$attributes    .= ' data-chosen-options=\'{"max_selected_options":3}\'';
            $html[]        = JHTML::_('select.genericlist', $tmp, $elName, $attributes, 'value', 'text', $default, $id);
        }

... but seems like I got as far as testing it with a hard coded value, which I then commented out, and never actually added the per-element setting in the join params.

I'm trying to remember why. I think the problem I was trying to work round was still that issue with the 'chosen:maxselected' event not firing. The chosen JS is supposed to fire that event when someone tries to make a selection once the maximum is reached, so you can provide feedback to the user rather than just silently ignoring them.

-- hugh
 
OK, I've added the option and solidified the code to add it in the join model.

At the moment, it'll only work for the "multi-select" mode. And there's no user feedback when they hit max, it just won't let them select any more. When I get a minute, I'll see if I can figure out that event.

-- hugh
 
We are in need of some funding.
More details.

Thank you.

Members online

Back
Top