How to prevent Twitter typeahead from filling in the input with the selected value?

前端 未结 5 1575
深忆病人
深忆病人 2020-12-18 08:17

I\'m using Twitter\'s typeahead plugin for autocompletion with a text input. I want to change the behavior so that instead of putting the selected option\'s value into the t

相关标签:
5条回答
  • 2020-12-18 08:48

    While not necessarily the intention of typeahead, if you use it for a SEARCH PAGE this little tidbit will be very useful I feel as I was looking for this answer myself.

    Unbind Selection Event From Typeahead Results List:

    $('.typeahead.users').typeahead({
                rateLimitWait: 250,
                limit: 100,
                valueKey: 'title'
    
    }).on('typeahead:opened', function (obj, datum, name) {
        $('span.tt-dropdown-menu').unbind(); //UNBINDS TYPEAHEAD SELECTION EVENT
    });
    

    WTF Did You Do? : -- When typeahead object is opened, we simply unbind the selection action altogether in order to do what we want it to instead without closing it.

    Further Notes: This is sort of destructive, but if you are using for, say, a search page where the body of the result item is link to a profile with a follow button on the right to click - then the auto-filling is a super pain in the ass to fight off.

    Hope this helps! Know its a bit late but maybe anyone else looking for this in the future.

    0 讨论(0)
  • 2020-12-18 08:59

    Struggled with this for a while, before I found how to clear the text when you select an option:

    $("#typeahead-input").on('typeahead:selected', function (event, datum, name) {
       $(this).typeahead("val", "");
       // Do something with the datum...
    });
    
    0 讨论(0)
  • 2020-12-18 09:01

    Same as @Nate's answer except in version (0.11.1), the event is called typeahead:close not typeahead:closed and the only parameter is the event:

    $("#input").typeahead(
        // ...
    )
    .on('typeahead:close', function (evt) {
        console.log(evt);
        $(obj.currentTarget).val("");
    });
    
    0 讨论(0)
  • 2020-12-18 09:03

    There are a few ways the input can be filled with the selected value:

    1. clicking a suggestion with the mouse
    2. pressing the 'tab' key to autocomplete with the top-most suggestion
    3. using the cursor keys to move through the list of suggestions

    Dealing with (1) and (2) first, you can handle the corresponding before events:

    $('#the-typeahead').on('typeahead:beforeselect', function ($event, suggestion) {
        // do whatever with the suggestion
        // then either call $event.preventDefault(), or return false to cancel the event
        return false;
    })
    

    Method (3) is a bit trickier. There is a beforecursorchange event, but if you cancel it, you won't move through the menu. This is probably not what you want.

    The simplest way I've found to deal with this is to replace the setInputValue method on the typeahead's input object, and prevent the value being set:

    // get the actual typeahead instance 
    let typeahead = $('#the-typeahead').data('ttTypeahead'); 
    
    // capture the existing method
    let old = typeahead.input.setInputValue;
    
    typeahead.input.setInputValue = function setInputValue(value) {
        // Allow clearing the input
        if (value === '') {
            old.call(typeahead.input, value);
        }
    }
    

    Replacing this method stops the input value from being set by the library at all, so you'll need to consider if you really want to do this. In the above example, I've allowed clearing the input to still work, as this is useful for me. Using this approach, you don't need to bother with handling the beforeselect and beforeautocomplete events.

    If replacing the setInputValue method is too much, you could instead replace the moveCursor function on the typeahead instance, but that means re-implementing a lot more code. You'd also need to handle the beforeselect and beforeautocomplete events in this case.

    Either way, replacing internal methods isn't great, but seeing as the project is effectively abandoned, that's not so much of a problem.

    0 讨论(0)
  • 2020-12-18 09:08

    I tried every other thing under the sun, but just stumbled across a solution a few minutes after posting my question.

    In case anyone else needs help with this, adding the typeahead:closed event handler allows you to catch the entered value, as well as clear it from the input before it can be seen (maybe there's a way to prevent it from ever being entered into the input, but I haven't been able to find it).

    So here's what I'm doing:

          $("#input").typeahead({
                highlight: true
            },
            {
                name: 'my-dataset',
                displayKey: 'value',
                source: bloodHound.ttAdapter()
            }
        ).on('typeahead:closed', function (obj, datum, name) {
              $(obj.currentTarget).val("");
          });
    
    0 讨论(0)
提交回复
热议问题