4

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

4
  • what you tried ? just image will get you down votes not answers. Commented Oct 19, 2015 at 4:46
  • I did just render the option element with plain html links, I don't think there's code needed, the issue is that selectize doesn't recognize when I do click a link, anyway, here a fiddle for eager hands: jsfiddle.net/fyor66ya Commented Oct 19, 2015 at 5:53
  • you have register some events on anchor tags Commented Oct 19, 2015 at 5:56
  • @JSantosh how to do do that? the event catching is not affected by the propagation limit that doesn't allow me to make a link work? Commented Oct 19, 2015 at 14:20

1 Answer 1

8

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I've been using SelectizeJS in production environments, and I'm giving +1 for showing the answer in the form of a Plugin -- perfect for behavior you might repeat elsewhere. Thanks man!
This is great don't get me wrong (it is. I will use it) - but why the extra class "clickable"? Why not the usual a href?
You can certainly tailor it to your requirements. My case involved internal click targets which weren't necessarily links. The idea was to support clickable internal structures without closing the dropdown.
Just added this to my system. Works like a charm. Thanks Nathan

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.