Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

twitter typeahead Force selection with prefetched content

I am currently using the twitter typeahead plugin for my website, as seen here.

The list opens and, on selection, a hidden input field is updated with the ID of selection. I need typeahead to force the selection in order for the ID to work with what the user has typed. If the value changes, the id should be removed until a valid selection has been made. If the box closes with out a selection they both should be emptied.

So far I have:

$('.cp').typeahead({                              
  name: 'nom',                                                          
  prefetch: 'ajax_recherche_ville.php',                                         
  limit: 50                                                    
});

$('.cp').bind('typeahead:selected', function(obj, datum) {        
        $('input:hidden[name=ville_id]').val(datum.id); 
});

I cannot find an example of forced selection that applies to this code - specifically because I use the prefetch method. Therefore, I can't validate if the value is in the list, or at least I don't know how yet. How can I get this to function as intended?

like image 875
Patrick Simard Avatar asked Jul 26 '13 18:07

Patrick Simard


2 Answers

I don't know any straight forward solution for this but I guess I can provide a workaround.

You can clear the hidden input on change() event, it will be updated on typeahead:selected event later:

$('.cp').typeahead({                              
    name: 'nom',                                                          
    prefetch: 'ajax_recherche_ville.php',                                         
    limit: 50                                                    
}).change(function () {
     $('input[name=ville_id]').val(''); // don't use :hidden since it slow down performance and doesn't do anything special, I suppose the input with name ville_id is unique
}).bind('typeahead:selected', function(obj, datum) {        
     $('input[name=ville_id]').val(datum.id); 
});

The weak spot of this method are:

  • It doesn't clear the typeahead input if user input something that doesn't trigger the autocomplete
  • The user has to click on the autocomplete dropdown (trigger typeahead:selected) in order for the hidden input to populate

Demo: http://jsfiddle.net/hieuh25/zz85q/

Hope it helps.

like image 83
Hieu Nguyen Avatar answered Oct 18 '22 22:10

Hieu Nguyen


I believe you code is on the right track, could add in a few enhancements to ensure modified and corrected text is still valid

$sourceSelect = @$el.find('[name="source_venue_name"]')
$sourceSelect.typeahead [
  {
    valueKey: 'name'
    remote:
      url: '/apis/venues?q=%QUERY'
    ]
  }
]

# hidden id
$sourceId = @$el.find('[name="source_venue_id"]')

$sourceSelect.on 'typeahead:selected', (e, item) =>
  # set hidden id on selection
  $sourceId.val item.id
  # remember selection
  $sourceSelect.attr 'data-name', item.name
  $sourceSelect.attr 'data-id', item.id

$sourceSelect.on 'change', () =>
  # if changed value is same as selected text
  if $sourceSelect.val() is $sourceSelect.attr 'data-name'
    $sourceId.val $sourceSelect.attr 'data-id'
  else # changed to be invalid
    $sourceId.val ''

PS: I believe Typeahead would like to avoid feature creep for all use cases https://github.com/twitter/typeahead.js/issues/368

like image 31
Desmond Lua Avatar answered Oct 18 '22 23:10

Desmond Lua