Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link on dropdown Selectize.js

I'm trying to put a link on a selectize dropdown in order to allow the user make an operation other than select an item while still allowing that the user selects the item as main option.

Here is an example of what I want to achieve (but is not working as expected): Here is an example on what I want to achieve

What I did is plainly insert links on the HTML. But it's not working, I suppose that for some kind of event propagation stop, is it possible to achieve with selectize?


Nobody did answer yet and I think there's more to say about, so, here is an example of what I did:

render: {
    option: function(item) {
        return '<div><span>'+item.label+'</span>'
            + '<div class="pull-right">'
            + '<a href="#link">Link</a>'
            + '</div></div>';
    }
}

As you can see, I did change the "option" renderization, and inserted a link in plain HTML. The problem is that -as shown on image- when I do click the link, the browser does not follow the link, but executes the default action for selectize, which is selecting the clicked element.

What I want to achieve is to make it follow the link when clicked.

Here is a fiddle of what I did: http://jsfiddle.net/uetpjpa9

like image 694
Felix Avatar asked Oct 19 '25 09:10

Felix


1 Answers

The root problem is that Selectize has mousedown and blur handlers that are dismissing the dropdown before the mouseup event that would complete the click that your link is waiting for from ever occurring. Avoiding this without direct support from Selectize is not easy, but it is possible thanks to its plugin system and the amount of access it gives you to Selectize internals.

Here's a plugin that allows a dropdown element with the class clickable to be clicked on. (demo)

Selectize.define('option_click', function(options) {
    var self = this;
    var setup = self.setup;
    this.setup = function() {
        setup.apply(self, arguments);

        var clicking = false;

        // Detect click on a .clickable
        self.$dropdown_content.on('mousedown click', function(e) {
            if ($(e.target).hasClass('clickable')) {
                if (e.type === 'mousedown') {
                    clicking = true;
                    self.isFocused = false; // awful hack to defuse the document mousedown listener
                } else {
                    self.isFocused = true;
                    setTimeout(function() {
                        clicking = false; // wait until blur has been preempted
                    });
                }
            } else { // cleanup in case user right-clicked or dragged off the element
                clicking = false;
                self.isFocused = true;
            }
        });

        // Intercept default handlers
        self.$dropdown.off('mousedown click', '[data-selectable]').on('mousedown click', '[data-selectable]', function() {
            if (!clicking) {
                return self.onOptionSelect.apply(self, arguments);
            }
        });
        self.$control_input.off('blur').on('blur', function() {
            if (!clicking) {
                return self.onBlur.apply(self, arguments);
            }
        });
    }
});

To use it, you need to pass the plugin option to the selectize call (.selectize({plugins:['option_click']})) and add the clickable class to links in your dropdown template. (This is fairly specific. If there are nested elements, make sure clickable is on the one that will first see the mousedown event.)

Note that this is a fairly hackish approach that may have edge cases and could break at any time if something about how Selectize dispatches events changes. It would be better if Selectize itself would make this exception, but until the project catches up to its backlog and becomes more receptive to requests and PRs this may be the most practical approach.

like image 104
Nathan Williams Avatar answered Oct 21 '25 21:10

Nathan Williams



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!