Reputation: 3
I can load Twitter typeahead just fine on a static form. However, in this situation, I would like to apply it to a dynamically-generated field. Even though my duplication script adds the required ".typeahead" class to the new input, it never seems to work. Indeed, the static form is surrounded by several additional classes, which are not generated for the dynamic fields.
I feel like there is something more I need to do in order for the dynamic fields to function like the static field, but I am not sure.
The Javascript:
<!-- Dataset: First Names -->
var firstnames = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('name'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 5,
prefetch: {
url: './datasets/firstnames.json',
filter: function(list) {
return $.map(list, function(firstname) { return { name: firstname }; });
}
}
});
firstnames.initialize();
$('.typeahead').typeahead(null, {
name: 'firstnames',
displayKey: 'name',
source: firstnames.ttAdapter()
});
<!-- Dataset: First Names (End) -->
<!-- Dynamic Fields -->
var count=2;
$("#add").click(function(){
var html="<div id='div"+count+"'><input id='firstname"+count+"' type='text' class='typeahead' placeholder='Additional First Name'></input><button type='button' onclick=remover('"+count+"')>Remove</button></div>";
$("#additionalnames").append(html);
count++;
});
function remover(which){
$("#div"+which).remove();
}
<!-- Dynamic Fields End -->
The HTML:
<p>Standard field works fine (type a letter from a to g):</p>
<input type="text" id="firstname" name="firstname" class="typeahead" placeholder="First Name">
<br /><br /><br /><br /><br /><br />
<p>Dynamic field does not:</p>
<div id="additionalnames"></div>
<button id="add" type="button">Add Another</button>
I don't think JSFiddle can handle my json file, so a live implementation is here: http://drjoeseriani.com/firstnames
A downloadable version of this resides here: http://drjoeseriani.com/firstnames.zip
Thanks for any help.
Upvotes: 0
Views: 1242
Reputation: 33618
Creating elements using javascript instead of appending raw markup can be useful. Why ?
Because if you create an element using javascript (or jQuery), you can attach an event/plugins to it and in this case it can be a typeahead plugin.
Like this
var input = $('<input>').attr('id', 'firstname' + count).addClass('typeahead').prop('placeholder', 'Additional First Name');
Now that you have an input element you can attach .typehead({ ... })
to it.
So your click event should be something like this.
$("#add").click(function() {
// creating a new <div id=count></div>
var div = $('<div>').attr('id', count);
// creating a new <input id=count class="typeahead" placeholder=".."></input>
var input = $('<input>').attr('id', 'firstname' + count)
.addClass('typeahead')
.prop('placeholder', 'Additional First Name');
// creating a new <button>Remove</button> (with a click event)
var button = $('<button>').text('Remove')
.on('click', function() {
$(this).closest('div').remove();
});
div.append(input); // appending the input to the div
div.append(button); // appending the button to div
// attaching typeahead to the newly creating input
input.typeahead(null, {
name: 'firstnames',
displayKey: 'name',
source: firstnames.ttAdapter()
});
// appending our newly creating div with all the element inside to #additionalnames
$("#additionalnames").append(div);
// incrementing count
count++;
});
Also, I changed the took the liberty of removing the remover
script all together.
You can attach a click event to the button and look for the parent div and remove it using .closest()
Hope this helps.
Upvotes: 1