Autocomplete on wrong form field - javascript

I know some php/html/css but javascript is where I need help. I found on web autocomplete script, but this doesn't work on more than two input fields.
There are two problems I need to solve.
When you type in first box, autocomplete shows in second one. How to make script show autocomplete on box where user is typing?
I need to use the same autocomplete on multiple fields on my site.
The javascript syntax I use is:
var MIN_LENGTH = 2;
$( document ).ready(function() {
$("#keyword").keyup(function() {
var keyword = $("#keyword").val();
if (keyword.length >= MIN_LENGTH) {
$.get( "http://example.com/autofill/auto-complete.php", { keyword: keyword } )
.done(function( data ) {
$('#results').html('');
var results = jQuery.parseJSON(data);
$(results).each(function(key, value) {
$('#results').append('<div class="item">' + value + '</div>');
})
$('.item').click(function() {
var text = $(this).html();
$('#keyword').val(text);
})
});
} else {
$('#results').html('');
}
});
$("#keyword").blur(function(){
$("#results").fadeOut(500);
})
.focus(function() {
$("#results").show();
});
});

In order to re-use the same autocomplete code you need to give the scope of the function the context of the correct DOM element.
Here's a a quick jsfiddle with some simple HTML code, but it should give a basic example of how to bind the same events to multiple dom structures.
DEMO: JSfiddle example
JS
var MIN_LENGTH = 2;
$(document).ready(function() {
$(".keyword").keyup(function() {
var $parent = $(this).parent();
var $results = $parent.find('.results');
var keyword = $(this).val();
if (keyword.length >= MIN_LENGTH) {
$.get("/echo/json/", {
keyword: keyword
})
.done(function(data) {
$results.html('');
data = ['test', 'test2'];
//data = jQuery.parseJSON(data);
$(data).each(function(key, value) {
$results.append('<div class="item">' + value + '</div>');
});
});
} else {
$results.html('');
}
});
});
HTML
<div class="autcomplete">
<input class="keyword" />
<ul class="results"></ul>
</div>
<div class="autcomplete">
<input class="keyword" />
<ul class="results"></ul>
</div>

Related

Bootstrap typeahed is one character behind using jquery

I am using bootstrap typeahead (GitHub) to create search forms. After user inputs something I am doing elasticsearch query using elasticsearch.js and returning results. The problem is that results displayed in typeahead are always one character behind, not suggesting correct values.
Typeahead input:
<input type="text" data-provide="typeahead" class="form-control typeahead" id="searchInputId" placeholder="Search" autocomplete="off">
Here is my code:
var elasticsearchAddress = "exampleserver.com:9200";
var elasticsearchClient = createElasticsearchClient(elasticsearchAddress);
var data = [];
$("#searchInputId").typeahead({ source:data, items:10, fitToElement:true });
$("#searchInputId").on("input", function(){
var searchTerm = $("#searchInputId").val();
elasticsearchMathPhrasePrefixSearch(elasticsearchClient, searchTerm, function () {
$("#searchInputId").data('typeahead').source = getElasticsearchSearchResultsArray();
});
});
elasticsearchMathPhrasePrefixSearch() function
function elasticsearchMathPhrasePrefixSearch(client, searchPhrase, callback) {
console.log("Searching for: " + searchPhrase);
client.search({
body: {
"query": {
"match_phrase_prefix": {
"accountName": searchPhrase
}
}
}
}, function (error, response) {
if (error) {
console.trace('ELASTICSEARCH: Search query failed');
} else {
console.log('ELASTICSEARCH: Search query OK');
var doc = response.hits.hits;
elasticsearchSearchResultsArray = getDocs(doc);
}
callback();
});
}
getDocs() function
function getDocs(doc){
var searchResultsArray=[];
for(var i = 0; i < doc.length; i++){
searchResultsArray.push(doc[i]._source.accountName);
}
return searchResultsArray;
getElasticsearchSearchResultsArray() function
function getElasticsearchSearchResultsArray(){
return elasticsearchSearchResultsArray;
}
elasticsearchSearchResultsArray is a global array that holds the results. Because of the JS async nature I had no other idea to make it work.
EDIT:
Ok, I modified my code so the source is updated correctly with help of this Issue #1997. But now I have got another problem. The typeahead dropdown is not displayed when I type.
My new code:
var empty = [];
$("#searchInputId").typeahead({ source:empty, items:10, fitToElement:true });
$("#searchInputId").on("keyup", function(ev){
ev.stopPropagation();
ev.preventDefault();
//filter out up/down, tab, enter, and escape keys
if( $.inArray(ev.keyCode,[40,38,9,13,27]) === -1 ){
var self = $(this);
//set typeahead source to empty
self.data('typeahead').source = [];
//active used so we aren't triggering duplicate keyup events
if( !self.data('active') && self.val().length > 0){
self.data('active', true);
//Do data request. Insert your own API logic here.
var searchTerm = self.val();
elasticsearchMathPhrasePrefixSearch(elasticsearchClient, searchTerm, function() {
//set this to true when your callback executes
self.data('active',true);
//set your results into the typehead's source
self.data('typeahead').source = getElasticsearchSearchResultsArray();
//trigger keyup on the typeahead to make it search
self.trigger('keyup');
//All done, set to false to prepare for the next remote query.
self.data('active', false);
});
}
}
});
Try to use on("keyup") instead. input is 1 character behind.
Ok, I resolved it myself. I switched from bootstrap3-typeahead to jQuery UI Autocomplete. It is working great and the script is much smaller.
New code:
$("#searchInputId").on("keydown", function () {
$("#searchInputId").autocomplete({
source: function(request, response) {
var searchTerm = $("#searchInputId").val();
elasticsearchMathPhrasePrefixSearch(elasticsearchClient, searchTerm, function (){
response(getElasticsearchSearchResultsArray());
});
}
});
});

How to differ inputs with same class?

I have one Button that duplicates this line to choose more products.
My Html:
<td>
<input type="hidden" class="cod_linha" name="cod_linha[]"style="width: 100%;" />
<input type="text" name="linha[]" class="linha" style="width: 100%;" />
</td>
The problem is, I have two functions that find the product and other that Fill all the fields that I want automatically, what I have to do to differ this filled field of the empty field ? I tried this:
var table = $('#tabelaPedido');
$(table).each(function() {
if($(this).find('input.linha').val()=== ''){
Executes my function to fill the fields and to add a new line.
}
else{ }
And this too :
var counter = $(table).find("input.linha").length;
for(var i =0; i < counter; i++){
if($(table).find('input.linha').eq(i).val()== ''{}
But those codes don't fill the other empty line. see the imagem :
My code to fill the fields :
function preencherCamposProduto(obj) {
var table = $('#tabelaPedido');
$(table).each(function() {
if($(this).find('input.linha').val()=== '' &&
$(this).find('input.ref').val()=== '' &&
$(this).find('input.material').val()=== '' &&
$(this).find('input.cor').val()=== '' &&
$(this).find('input.descricao_marca').val()=== ''){
$.ajax({type: "POST",
url: '/pedidoOnline/index.php/Pedidos/pesquisarCamposProduto',
async: false,
data: {
cd_cpl_tamanho: obj
},
dataType: 'json',
success: function(data) {
var linhaId = data[0].idLinha;
var linhaLabel = data[0].labelLinha;
var refId = data[0].idRef;
var refLabel = data[0].labelRef;
var corId = data[0].idCor;
var corLabel = data[0].labelCor;
var marcaId = data[0].idMarca;
var marcaLabel = data[0].labelMarca;
var materialId = data[0].idMaterial;
var materialLabel = data[0].labelMaterial;`
var table = $('#tabelaPedido');
$(table).each(function() {
$(this).find('input.cod_linha').val(linhaId);
$(this).find('input.linha').val(linhaLabel);
$(this).find('input.cod_ref').val(refId);
$(this).find('input.ref').val(refLabel);
$(this).find('input.cod_material').val(materialId);
$(this).find('input.material').val(materialLabel);
$(this).find('input.cod_cor').val(corId);
$(this).find('input.cor').val(corLabel);
$(this).find('input.id_marca').val(marcaId);
$(this).find('input.descricao_marca').val(marcaLabel);
});
}
});
chamaAdicionarCampo();
}else{
console.log('Entrei no else');
}
});
}
Thanks a lot.
I've read your code and wrote a sample code in jsfiddle, that does things that you are writing about. In my solution I use CSS selector #tabelaPedido tr:last to select the last added row, and then write values to fields in this row.
Hope this helps.
The following simple jquery solution may help you:
$(document).ready(function(){
$('.linha').each(function(){
if ($(this).val() == ''){
//Call Your fill input function $(this) as parameter
}
});
});
Checkout This DEMO
With the answer of #zegoline and #semsem I figure it out.. Now it's working ! I added $( "tr:last" ).find() to every field on my each function and the #table tr:last too... Thanks a lot !

Use jquery to get elements name of values

I need to get all text of value, then use json to send the value to insert all of price to the database, but i had the problem, i can't get the text of all value where input text name='price'.
here this is HTML code:
<input type='text' id='price1' name='price[]'/>
<input type='text' id='price2' name='price[]'/>
<button type='button' id='btn'/>
and this is JS code:
$('#btn').click(function (e) {
var myprice = [];
myprice = $("*[name='price']").val();
$.post(
"index.php",
{
type: "insert",
price: myprice,
}
).done(function (data) {
console.log(data);
})
});
You can use .map() to get all the values:
var myprice = $('[name="price[]"]').map(function(i,v) {
return v.value;
}).get().join(',');
//result: "value1,value2..."
DEMO
Or $.map():
var myprice = $.map($('[name="price[]"]'), function(v,i) {
return v.value;
}).join(',');
DEMO
You cannot get values once, you need to iterate as you need multiple input values.
and use the correct name, change your html:
<input type='text' id='price1' name='price'/>
<input type='text' id='price2' name='price'/>
and code:
var myprice = [];
for(var i=0; i < $("*[name='price']").length; i++){
myprice.push($("*[name='price']:eq("+i+")").val());
}
You can loop through your items (no brackets needed, no change to your HTML) and add them to the array easily -
$('#btn').click(function (e) {
e.preventDefault();
var myprice = [];
$("*[name='price']").each(function() {
myprice.push( $(this).val() );
});
console.log(myprice); // e.g., ["56", "42"]
});
Here is an EXAMPLE
The name is price[], not price.

Date entries in the array are not printed

I've just created an dynamic HTML form and two of its fields are of type date. Those two fields are posting their data into two arrays. I have 2 issues:
a) The array data are not printed when I press the button.
b) Since I created the arrays to store the data, my dynamic form doesn't seem to be fully functional. It only produces new fields when I press the first "Save entry" button on the form. It also doesn't delete any fields.
My code is:
$(document).ready(function () {
$('#btnAdd').click(function () {
var $address = $('#address');
var num = $('.clonedAddress').length;
var newNum = new Number(num + 1);
var newElem = $address.clone().attr('id', 'address' + newNum).addClass('clonedAddress');
newElem.children('div').each(function (i) {
this.id = 'input' + (newNum * 10 + i);
});
newElem.find('input').each(function () {
this.id = this.id + newNum;
this.name = this.name + newNum;
});
if (num > 0) {
$('.clonedAddress:last').after(newElem);
} else {
$address.after(newElem);
}
$('#btnDel').removeAttr('disabled');
});
$('#btnDel').click(function () {
$('.clonedAddress:last').remove();
$('#btnAdd').removeAttr('disabled');
if ($('.clonedAddress').length == 0) {
$('#btnDel').attr('disabled', 'disabled');
}
});
$('#btnDel').attr('disabled', 'disabled');
});
$(function () {
$("#datepicker1").datepicker({
dateFormat: "yy-mm-dd"
}).datepicker("setDate", "0");
});
var startDateArray = new Array();
var endDateArray = new Array();
function intertDates() {
var inputs = document.getElementsById('datepicker1').value;
var inputsend = document.getElementsById('datepicker2').value;
startDateArray[startDateArray.length] = inputs;
endDateArray[endDateArray.length] = inputsend;
window.alert("Entries added!");
}
function show() {
var content = "<b>Elements of the arrays:</b><br>";
for (var i = 0; i < startDateArray.length; i++) {
content += startDateArray[i] + "<br>";
}
for (var i = 0; i < endDateArray.length; i++) {
content += endDateArray[i] + "<br>";
}
}
JSFIDDLE
Any ideas? Thanks.
On your button you are using element ID's several times, this is so wrong, IDs must be unique for each element, for example:
<button id="btnAdd" onclick="insertDates()">Save entry</button>
</div>
</div>
<button id="btnAdd">Add Address</button>
<button id="btnDel">Delete Address</button>
jQuery will attach the $('#btnAdd') event only on the first #btnAdd it finds.
You need to use classes to attach similar events to multiple elements, and in addition to that simply change all the .click handlers to .on('click', because the on() directive appends the function to present and future elements where as .click() only does on the existing elements when the page is loaded.
For example:
<button id="btnDel">Delete Address</button>
$('#btnDel').click(function () {
[...]
});
Becomes:
<button class="btnDel">Delete Address</button>
$('.btnDel').on('click', function () {
[...]
});
Try this : I know its not answer but it's wrong to get element value using id
Replace
var inputs = document.getElementsById('datepicker1').value;
var inputsend = document.getElementsById('datepicker2').value;
With
var inputs = document.getElementById('datepicker1').value;
var inputsend = document.getElementById('datepicker2').value;
You are using jQuery so i will strongly recommend you to stick with the jQuery selector,
var inputs = $('#datepicker1').val();
var inputsend = $('#datepicker2').val();
where # is used for ID selector.

remove value from the list

I have a list of checkboxes. Upon clicking on each of the checkboxes i am adding the value to the hidden variable. But the question is if I want to remove the value from the list upon unchecking the checkbox . How this piece cab be done
here is the hidden form variable
<input name="IDList[]" type="hidden" id="IDList" value="" />
and the jquery
$(".myCheckboxClass").change(function() {
var output = 0;
$(".myCheckboxClass").change(function() {
if ($(this).is(":checked")) {
output += ", " + $(this).val();
} else {
output = $.grep(output, function(value) {
return value != $(this).val();
});
}
$("#IDList").val(output);
});
});
Something like this: (demo) http://jsfiddle.net/wesbos/5N2kb/1/
we use an object called vals to store the info. ADding and removing as we check/uncheck.
var vals = {};
$('input[type=checkbox]').click(function() {
var that = $(this);
if (that.is(':checked')) {
console.log(this.name);
vals[this.name] = "In your Object";
}
else {
delete vals[this.name];
}
console.log(vals);
});
Following your logic, you could do this:
$('#IDList').data('value', []);
$(".myCheckboxClass").change(function() {
var list = $('#IDList').data('value');
if ($(this).is(":checked")) {
list.push($(this).val());
} else {
var indexToRemove = list.indexOf($(this).val());
list.splice(indexToRemove, 1);
}
$('#IDList').val(list);
});
But if you only care about the value of #IDList upon data submission or other actions, you probably want to consider an alternative approach: collating the checked values when you need them.
$('#form').submit(function() {
var list = $('input.myCheckboxClass:checked', this).map(function() {
return $(this).val();
}).get();
$('#IDList').val(list);
});
See both of the above in action: http://jsfiddle.net/william/F6gVg/1/.

Categories

Resources