I have a field on which an autocomplete function is implemented. This is my code :
<%= f.text_field :auteur_1, size: 100, class:"champs_auteur", data: {autocomplete_source: auteurs_enum_path} %>
That creates the following html :
<input size="100" class="champs_auteur ui-autocomplete-input" data-autocomplete-source="/auteurs/enum" name="biblio[auteur_1]" id="biblio_auteur_1" autocomplete="off" type="text">
And this is in my javascript :
$(document).on('ready', function() {
return $('.champs_auteur').autocomplete({
source: $('.champs_auteur').data('autocomplete-source')
});
});
All that works fine. I am creating input fields using jquery after() and append(), like this :
$(document).on('ready', function () {
i = 2 ;
$(".extra_auteur").click(function(){
$('.premier_auteur').after('<div class="grid mbm"><div class="one-sixth"><label for="biblio_auteur">Auteur</label></div><input size="100" class="champs_auteur" data-autocomplete-source="/auteurs/enum" type="text" name="biblio[auteur_' + i++ + ']" id="biblio_auteur_1" /></div>');
});
});
This is minified code (mainly html) for :
<div class="grid mbm">
<div class="one-sixth">
<label for="biblio_auteur">Auteur</label>
</div>
<input size="100" class="champs_auteur" data-autocomplete-source="/auteurs/enum" type="text" name="biblio[auteur_' + i++ + ']" id="biblio_auteur_1" />
</div>
This does create the input field with an id="biblio_auteur_2" (and 3, 4 etc...).
The autocomplete doesn't work on the additional input fields. I don't see why not.
This is because you're using the element #ID instead of the class-name as in:
$( "#aut_extra" )
And #ID is always unique, and will therefore only work for 1 item. What yu need to do is have the jQuery select the CSS element class instead and not ID.
$( ".aut_extra" )
or whatever the class name is.
But you must be sure that the element which currently have the ID of aut_extra instead have a CSS class with the same name.
<div class="aut_extra"....
Crashtor is correct, page ids MUST be unique for proper functioning. However, you might have another issue. You're calling autocomplete during document ready, but when you change the dom by adding new fields, those existed after the autocomplete function was initialized.
Try calling autocomplete on each after append.
$('.extra_amatur:last').find('input[type=text]:last').autocomplete({
source: $(this).data('autocomplete-source')
});
Thanks both for your help. Both errors needed to be corrected, the first on that only classes should be used and the second that the autocomplete should be used on another event then document ready. I took on click.
This is the code (if this could ever help someone) :
$(document).on('click', '.champs_2_auteur', function() {
return $('.champs_2_auteur').autocomplete({
source: $('.champs_2_auteur').data('autocomplete-source')
});
});
Related
I'm using jquery autocomplete.In my case I have multiple autocomplete textbox and hidden field on my page.
e.g
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
<input class='myclass' type='text'> </input>
<input class='.emp_num_hidden' type='hidden'> </input>
and so on...
so when I fire change event on hidden field then it is raised multiple time
below is my code:
$(".myclass").each(function() {
var $empName= $(this);
var $empNumber = $empName.next('input:hidden');
//things to do
//Setting variable e.g url...
$empName.autocomplete(url,{
//code...
}).result(function(event,data,formatted)
{
$empNumber.val(formatted).change();
});
});
In above code $empNumber holds the hidden field which is used to store autocomplete value i.e in this case when
we select any text from autocomplete then that selected employees number will get store in hidden field.
Based on this hidden field value I want to do ajax call which will return full details of the employee based on his
employee number.
So I have written hanldler to change event of the hidden field as below.
$(.emp_num_hidden).on('change',function (
)};
here 'emp_num_hidden' is the class of the hidden field.
Please suggest how can I prevent multiple event on hidden field change.
This is done using the $(this) object. Since the change event has a target, it will only be effecting one element. The callback function is being executed on this element, this. For example:
$(".emp_num_hidden").on('change', function (e){
alert($(this).val());
});
What will happen is that an alert window will be shown when the hidden field is changed, containing the employee number from only that hidden field. You will also notices there are a few fixes to your code.
Personally, I would make use of both id and class attributes on your objects. This gives you wide scope and narrow scope to your selectors.
Example:
HTML
<input class='myclass' type='text' id='entry-txt-1' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-1' />
<input class='myclass' type='text' id='entry-txt-2' />
<input class='emp_num_hidden' type='hidden' id='hide-txt-2' />
jQuery
$(function(){
var $empName, $empNumber;
$(".myclass").each(function(key, el) {
$empName= $(el);
$empNumber = $empName.next("input[type='hidden']");
// things to do
// Setting variable e.g url...
$empName.autocomplete(url, {
//code...
}).result(function(e, d, f){
$empNumber.val(f).change();
});
});
$(".emp_num_hidden").on('change', function(e){
var empId = $(this).attr("id");
var $employeeNumberField = $("#" + empId);
// Do the needful...
});
});
Taking this a bit further, you may want to consider making use of data attributes. You may also want to look at select event for Autocomplete. Something like:
$(function(){
$(".myclass").autocomplete({
source: url,
select: function(e, ui){
$(this).val(ui.item.label);
$(this).data("emp-number", ui.item.value);
$.post("employeedata.php", { n: ui.item.value }, function(data){
$("#empData").html(data);
});
return false;
}
});
});
This assumes that url returns an array objects with label and value properties. This would add the Employee Number as a data-emp-number attribute to the field that the user was making a selection from. The label being their Employee Name, and the value being their Employee Number. You could also use this callback to show all the other employee data based on Employee Number.
A working example: https://jsfiddle.net/Twisty/zmevd0r0/
I have multiple forms on a page and also multiple input boxes with plus/minus signs.
I'm having trouble to get those input boxes to work seperately. Probably because of some wrong/same id's or something like that or maybe a wrong setup of my code. The thing is I can't find my error in the code and I don't get any errors in my console.
What I have:
function quantity_change(way, id){
quantity = $('#product_amount_'+id).val();
if(way=='up'){
quantity++;
} else {
quantity--;
}
if(quantity<1){
quantity = 1;
}
if(quantity>10){
quantity = 10;
}
$('#product_amount_'+id).val(quantity);
}
And my html:
//row 1
<div class="amount"><input type="text" name="quantity" value="1" id="product_amount_1234"/></div>
<div class="change" data-id="1234">
+
-
</div>
//row 2
<div class="amount"><input type="text" name="quantity" value="1" id="product_amount_4321"/></div>
<div class="change" data-id="4321">
+
-
</div>
I thought something like this would do the trick but it doesn't :(
$(document).ready(function(){
$('.change a').click(function(){
var id = $(this).find('.change').data('id');
quantity_change(id)
});
});
Any help greatly appreciated!
You should use closest() method to get access to the parent div with class change, then you can read the data attribute id's value.
var id = $(this).closest('.change').data('id');
alert(id);
Since you are already binding the click event using unobutrusive javascript, you do not need the onclick code in your HTML markup.
Also your quantity_change method takes 2 parameters and using both, but you are passing only one. You may keep the value of way in HTML 5 data attributes on the anchor tag and read from that and pass that to your method.
<div class="change" data-id="1234">
+
-
</div>
So the corrected js code is
$(document).ready(function(){
$('.change a').click(function(e){
e.preventDefault();
var _this=$(this);
var id = _this.closest('.change').data('id');
var way= _this.data("way");
quantity_change(way,id)
});
});
Here is a working sample.
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.
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.
I have a hidden div with a simple form:
<div id="mb_clookup" style="display: none;">
<strong><font color="#0066CC">Search for existing customers</font></strong><br /><br />
<font color="#FFF">
Postcode: <input type="text" name="cl_zipcode" id="cl_zipcode" />
<span id="cl_search">Search</span>
</font>
</div>
This is displayed when the user clicks a button on the page. The user puts in the ZIP code, click on search and a JSON query is called. I have managed to make the Search button work with .live() but I cannot get the value of the input field. Here is the code:
$(document).ready(function(){
$(document).on( "click", "#cl_search", function() {
var pc = $('#cl_zipcode').val();
if(pc === '') {
alert('Please type in a post code first.');
}
else {
// JSON
}
});
});
Th pc variable comes up empty. I tried:$(this).find('#cl_zipcode').val() this comes up with undefined.
Please advise.
You can use the following
var pc= $("#mb_clookup").find('#cl_zipcode').val();
or
var pc= $("#mb_clookup :input").val();
check fiddle
With regard to $(this).find('#cl_zipcode').val() the input elements is beside the clicked span, so your find will search from the span on down (and it contains nothing aside from the text).
You need to move up the DOM first before you find it.
$(this).parent().find('#cl_zipcode').val()
Please note that as IDs are unique, so your original code is actually fine (so long as you only have one of these added): http://jsfiddle.net/TrueBlueAussie/djqfharu/
If you load more than one of these (you mention dynamic adding of fields) you will need to switch to classes to identify the elements.
e.g
$(document).ready(function(){
$(document).on( "click", ".cl_search", function() {
var pc = $(this).parent().find('.cl_zipcode').val()
if(pc === '') {
alert('Please type in a post code first.');
}
else {
// JSON
}
});
});
This is because browser keeps a fast-lookup dictionary, of IDs vs DOM elements, so only a single entry is retained per ID. The upshot of that is that jQuery can only ever find the first matching element for a search of a duplicated ID. The solution there is to switch to using classes and class-based searched.
I strongly suggest you post the rest of your code as the part shown is not the problem in isolation.
i thing your html code wrong. Becouse tag not in use tag
tag not support HTML5..
change this
<div id="mb_clookup" style="display:block;">
<strong><font color="#0066CC">Search for existing customers</font></strong><br /><br />
<span style="color="#FFF">
Postcode: <input type="text" name="cl_zipcode" id="cl_zipcode" />
<span id="cl_search">Search</span>
</span>
</div>
good luck
Your code is working fine i checked it in jsfiddle by removing display none attribute. You can check it here
HTML
<div id="mb_clookup">
<strong><font color="#0066CC">Search for existing customers</font></strong><br /><br />
<font color="#FFF">
Postcode: <input type="text" name="cl_zipcode" id="cl_zipcode" />
<button id="cl_search">Search</button>
</font>
</div>
JS
$(document).ready(function(){
$(document).on( "click", "#cl_search", function() {
var pc = $('#cl_zipcode').val();
if(pc === '') {
alert('Please type in a post code first.');
}
else {
alert(pc);
}
});
});
Suppose you have the following code to update many elements:
<div class='item'>
Name:<input type='text' name='name' data-id='123' value='Name 1'>
<button class='update'>update</button>
</div>
<div class='item'>
Name:<input type='text' name='name' data-id='456' value='Name 2'>
<button class='update'>update</button>
</div>
And JavaScript to handle the update:
function updateName(name, id){
...
}
What is the jQuery handler that can find the value and id and call updateName?
$('button.update').click(function() {
name = ?
id = ?
updateName(name, id)
}
EDIT:
The expected behavior is that when the user updates the input field, the updated value is sent to updateName(), not the original value.
Also, note that the data-id and value are on the input, not the button.
http://jsfiddle.net/e3g6nfc1/8/
Inside event handlers this is the unwrapped DOM element
$('button.update').click(function() {
var name = this.name
var id = $(this).data('id');
updateName(name, id)
}
note that you want var in this case or else name and id jump out of the scope of that function and possibly become global variables.
I've argued before that this is awkward and bad to use. You can achieve the same effect without using it like so:
$('button.update').click(function(e) {
var name = e.currentTarget.name
var id = $(e.currentTarget).data('id');
updateName(name, id)
}
You also don't have to use jquery for data. on reasonably modern browsers $(domElement).data('foo') is equivalent to domElement.dataset['foo']
Edit: Not sure if I missed this in the question or if it got edited but it seems like you're asking not for attributes on the button but the element before it. In that case you want $.fn.prev which will look something like this
$('button.update').click(function(e) {
var $prev = $(e.currentTarget).prev();
updateName($prev.name, $prev.data('id'))
}
note that this assumes that the input element is directly before the button. If you want to find the closest preceding input element you would use $.fn.prevAll
var $prev = $(e.currentTarget).prevAll('input').last();
Like this:
$('button.update').click(function() {
name = $(this).attr('name');//to get value of name attribute
id = $(this).data('id'); // to get value of attribute data-id
updateName(name, id)
}
You may also use prop() method to get name or data-id:
name = $(this).prop('name');
id = $(this).prop('data-id');
But best is to use data() method for data-* attribute.
Not sure why the answers here are trying to find the input attributes on the button element...
<div id="container">
<div class='item'>
Name:<input type='text' name='name' data-id='123' value='Name 1'>
<button class='update'>update</button>
</div>
<div class='item'>
Name:<input type='text' name='name' data-id='456' value='Name 2'>
<button class='update'>update</button>
</div>
</div>
Delegating the events to attach only to the container (selecting only those children with .update class), catching them as they "bubble up". previousElementSibling used to target the input but jQuery selectors could also be used to find it if the layout were more complex.
$('#container').on('click','.update',function(e) {
updateName(
e.currentTarget.previousElementSibling.name,
$(e.currentTarget.previousElementSibling).data('id')
);
});
JSFiddle