I am using JQuery UI Autocomplete in my JSP. Whenever user keys character, i made the request to server and get the data as JSON and load with the pulgin.
It's working fine. But Whenever i typed the same character as previous term. It's not populating any values.
For eg., First i typed p, it lists the p starting elements. I have the button to reset the text content of autocompleter. After reset, if i am typing same character p, it doesn't show anything.
my code as follows,
var cache = {};
$("#Name").autocomplete({
source: function(req, add){
if (req.term in cache) {
add(cache[req.term]);
return;
}
$.getJSON("/store/StockManagement?action=getMedicinesStock",req, function(data) {
var medicines = [];
$.each(data, function(i, val){
medicines.push(val.name + "," + val.code);
});
cache[req.term] = medicines;
add(medicines);
});
},select: function(e, ui) {
var medicine = ui.item.value;
$('#Code').val(medicine.split(",")[1]);
setTimeout(function(){
var med = $('#Name').val();
$('#Name').val(med.split(",")[0]);
},500);
}
});
// Taken from jquery-ui-1.8.4.custom.min.js
if (a.term != a.element.val()) { // *** THE MATCH IS HERE
//console.log("a.term != a.element.val(): "+a.term+", "+a.element.val());
a.selectedItem = null;
a.search(null, c) // *** SEARCH IS TRIGGERED HERE
}
I just commented the condition. now it's works fine.
Related
I have a page where I am adding jquery-ui autocompletes dynamically
My .autocomplete() code includes a $.getJSON('my_url', my_payload) where, in my_payload,' I am trying to send the request.term (what I typed into the jqueryui textbox) as well as the id of the jquery ui text box.
The problem is, for all the dynamically added textboxes, they were just picking up the term and id of the original autocomplete.
I managed to find a way to get the id of the added (not original) autocomplete by wrapping the autocomplete in a function that has the added field passed in as a parameter, but because the 'term' is in the request, which comes from .autocomplete, I do not know how to get this for the new ones.
https://jsfiddle.net/amchugh89/1L8jvea5/4/
//=======dynamic formset script from https://medium.com/all-about-
django/adding-forms-dynamically-to-a-django-formset-375f1090c2b0======
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for", $(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function cloneMore(selector, prefix) {
var newElement = $(selector).clone(true);
var total = $('#id_' + prefix + '-TOTAL_FORMS').val();
newElement.find(':input:not([type=button]):not([type=submit]):not([type=reset])').each(function() {
if ($(this).attr('name')){
var name = $(this).attr('name').replace('-' + (total-1) + '-', '-' + total + '-');
var id = 'id_' + name;
$(this).attr({'name': name, 'id': id}).val('').removeAttr('checked');
if($(this).attr('id').includes('gl')){
console.log($(this).attr('id'))
make_autocomplete($(this))
}
}
});
newElement.find('label').each(function() {
var forValue = $(this).attr('for');
if (forValue) {
forValue = forValue.replace('-' + (total-1) + '-', '-' + total + '-');
$(this).attr({'for': forValue});
}
});
total++;
$('#id_' + prefix + '-TOTAL_FORMS').val(total);
$(selector).after(newElement);
var conditionRow = $('.form-row:not(:last)');
conditionRow.find('.btn.add-form-row')
.removeClass('btn-success').addClass('btn-danger')
.removeClass('add-form-row').addClass('remove-form-row')
.html('<span class="glyphicon glyphicon-minus" aria-hidden="true"></span>');
return false;
}
function deleteForm(prefix, btn) {
var total = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
if (total > 1){
btn.closest('.form-row').remove();
var forms = $('.form-row');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).find(':input').each(function() {
updateElementIndex(this, prefix, i);
});
}
}
return false;
}
$(document).on('click', '.add-form-row', function(e){
e.preventDefault();
cloneMore('.form-row:last', 'form');
return false;
});
$(document).on('click', '.remove-form-row', function(e){
e.preventDefault();
deleteForm('form', $(this));
return false;
});
//====================
//AUTOCOMPLETE==(that allows for multiple ACs
https://stackoverflow.com/questions/24656589/using-jquery-ui-autocomplete-
with-multiple-input-fields)===================================
function make_autocomplete(ee) {
ee.on("focus", function(){ //.autocomplete({
$(this).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
//with the formset, I want to get the row for which I am typing in the
'term'
var this_formset_row_autocomplete_id
=ee.attr('id');//$(this.element).prop("id");//
$(this).attr('id');
console.log(this_formset_row_autocomplete_id);
var corresponding_branch_html_id =
this_formset_row_autocomplete_id.replace('gl_account','branch');
var this_formset_row_branch_sym_id =
$('#'+corresponding_branch_html_id).val();
//console.log(corresponding_branch_html_id, this_formset_row_branch_sym_id)
var appended_data={term:term,
this_formset_row_branch_sym_id:this_formset_row_branch_sym_id};
console.log(appended_data);
$.getJSON( "{% url 'dashapp:account_autocomplete' %}", appended_data,
function( data,
status, xhr ) {
//cache[ term ] = data;
response( data );
});
}
});
});
}//end function make_autocomplete
var ee =$( ".account_autocomplete" )
make_autocomplete(ee)
//===============
You may want to try to make it more simple for testing. Something like:
function make_autocomplete(obj) {
obj.autocomplete({
minLength: 2,
source: function(req, resp) {
var myData = {
term: req.term,
original_form_branch_id: $(this).closest("form").attr("id"),
this_formset_row_branch_sym_id: $(this).closest(".row").find("select").val()
}
$.getJSON("myurl", myData, function(results) {
resp(results);
});
}
});
}
Fiddle: https://jsfiddle.net/Twisty/pywb9nhv/23/
This uses .closest() to gather details from the relative objects. Also I do not see any benefit to initializing Autocomplete on focus event.
If you would like further help, please provide Example Data that can be used in a working example.
Hope that helps a little.
On IOS, when I close photoswipe to return to the page, it wont return to the scroll position I was at when I clicked the thumbnail.
Instead the page scrolls back to the # which was specified when I initially called the page.
For example if photoswipe is on www.somepage.html, and I navigate to the page using:
www.somepage.html#footer
and then scroll up and click a thumnail in #middle of page, on closing photoswipe, the page scrolls back down to the footer.
I've tried disabling history in the photswipe options, and i've also tried clearing the hash data from the url using:
//clear hash
//$(document).ready(function (e) {
// window.location.hash = '';
// window.history.pushState("", document.title, window.location.pathname);
//
//});
But none of it seems to work. If I navigate to the page without the # in the page, everthing is fine.
I'm guessing I may have to pass a variable in the url instead of the # and scroll to the div in question via javascript?
I already have the javascript in place to scroll, but I'm not sure how to read the variable from the url and then use it's value in Javascript.
If this is likely to be the best fix for the issue, could anyone give an example of the javascript code needed?
Here's my current scroll code:
$(function () {
$('a[href*=#]:not([href=#],[data-toggle],[data-target],[data-slide])').click(function () {
if (location.pathname.replace(/^\//, '') == this.pathname.replace(/^\//, '') || location.hostname == this.hostname) {
var target = $(this.hash);
target = target.length ? target : $('[name=' + this.hash.slice(1) + ']');
if (target.length) {
$('html,body').animate({
scrollTop: target.offset().top
}, 1000);
return false;
}
}
});
});
If anyone else has the same issue, I've managed to fix this by passing the div id to the page in the query string rather than using a #.
Here's the code:
$(window).ready(function () {
if (document.location.search.length) {
target = getUrlVars()["id"];
scrollToID('#' + target, 750);
} else {
return;
}
//target = $url().param('id');
//if (target == '') return;
});
function getUrlVars() {
var vars = [], hash;
var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
for (var i = 0; i < hashes.length; i++) {
hash = hashes[i].split('=');
vars.push(hash[0]);
vars[hash[0]] = hash[1];
}
return vars;
}
// scroll function
function scrollToID(id, speed){
var offSet = 100;
var targetOffset = $(id).offset().top - offSet;
var mainNav = $('#main-nav');
$('html,body').animate({scrollTop:targetOffset}, speed);
if (mainNav.hasClass("open")) {
mainNav.css("height", "1px").removeClass("in").addClass("collapse");
mainNav.removeClass("open");
}
}
if (typeof console === "undefined") {
console = {
log: function() { }
};
}
I've created an app using tabBar. I've created a separate search Window Containing a searchBar and a TableView to display the recent search items. Whenever the return event is fired a new window called searchresult.js opens up displaying the data searched. When I click on the back button it goes from searchresult.js-->searchpage.js, but the problem is the table for recent data gets updated in the database but it isn't showing on the table and I've to go to the main page and open the searchpage.js again to see the correct data... Pls help...Thanx in advance
I've used the following code: searchpage.js
//*** Search Field ***
var search = Titanium.UI.createSearchBar({
barColor:'#000',
showCancel:true,
height:43,
hintText:'Name of the part you want to search',
autocorrect:true,
top:0,
});
content.add(search);
//*** Table For Recent Search ***
var db = Titanium.Database.install('car.db','dbversion1');
var sql = db.execute ('SELECT * FROM search_history ORDER BY id DESC LIMIT 0, 10');
var data = [];
while (sql.isValidRow()){
var searchQuery = sql.fieldByName('search_query');
var selectedCategory = sql.fieldByName('selected_category');
var searchID = sql.fieldByName ('id');
data.push({title: searchQuery});
sql.next();
}
var searchTable = Titanium.UI.createTableView({
headerTitle:'RECENT SEARCH',
data: data,
});
Ti.API.info(searchTable.title);
content.add(searchTable);
//Search Action
search.addEventListener('blur', function(e) {
Titanium.API.info('search bar:blur received');
});
search.addEventListener('cancel', function(e) {
Titanium.API.info('search bar:cancel received');
search.blur();
});
search.addEventListener('return', function(e){
var insertSql = db.execute('INSERT INTO search_history (search_query, selected_category) VALUES ("' + search.value + '", 1)');
var win = Titanium.UI.createWindow({
backgroundColor:'#ffffff',
url:'searchresult.js',
title: 'Search Result',
searchValue: search.value
});
Ti.API.info(search.value);
search.blur();
Titanium.UI.currentTab.open(win, {animation:true});
});
// Back Button Action
bckButton.addEventListener('click', function(e){
if (Ti.Android){
win.close();
}else{
win.close({animated:true});
}
});
and searchresult.js
// *** Content ***
var content = Titanium.UI.createView({
backgroundColor:'#fff',
height:'100%',
width:'100%',
layout:'vertical'
});
wrapper.add(content);
var searchQuery = win.searchValue;
var db = Titanium.Database.install('car.db', 'dbversion1');
var sql = db.execute ("SELECT * FROM part_category WHERE part_name LIKE \'%"+ searchQuery +"%\'");
var data = [];
while(sql.isValidRow()){
var partName = sql.fieldByName ('part_name');
var partID = sql.fieldByName ('id');
data.push({title: partName, hasChild:true, id:partID, url:'partsubcategory.js'});
sql.next()
};
var resultTable = Titanium.UI.createTableView({
data : data,
});
content.add(resultTable);
// Back Button Action
bckButton.addEventListener('click', function(e){
if (Ti.Android){
win.close();
}else{
win.close({animated:true});
}
});
you should save the search results in a data structure and fire an event after the search is complete. Any other tables that you want to update should be listening for that event and update when it recieves the event.
I believe there is an example of this in the training documentation for tiBountyHunter
http://docs.appcelerator.com/titanium/latest/#!/guide/Event_Handling
$("#username").autocomplete({
target: $('#usersss'),
source: function() {
var db = decoara.webdb.db;
db.transaction(function(tx) {
tx.executeSql("SELECT codigo as value, fantasia as label, tabela FROM clientes WHERE fantasia LIKE '%"+$("#username").val()+"%' LIMIT 4",null,
function (tx, results) {
jsonClientes = '[';
console.log('Rows:'+results.rows.length);
for (i=0; i<results.rows.length; i++) {
row = results.rows.item(i);
jsonClientes += '{"value":'+row['value']+',"label":"'+row['label']+'"}';
if (i!=results.rows.length-1)
jsonClientes += ',';
}
jsonClientes += ']';
console.log(jsonClientes);
return $.parseJSON(jsonClientes);
},function (tx, e) {
console.log('error: ' + e.message);
}
);
});
},
link: 'xxx.html?ops=',
minLength: 1
});
The source's function return this json code:
[{"value":27,"label":"NARDIM"},{"value":38,"label":"MORO"},{"value":39,"label":"MH"},{"value":40,"label":"IRMAO SAPIENZA"}]
But the list-view just don't appear. When I change the source to a var using the same jSON data, it works fine:
var autocompleteData = $.parseJSON('[{"value":27,"label":"NARDIM"},{"value":38,"label":"MORO"},{"value":39,"label":"MH"},{"value":40,"label":"IRMAO SAPIENZA"}]');
source: autocompleteData,
Why is that?
Try declaring the jsonClientes as an array and then use .push to store values inside it.
i.e
var jsonClientes = [];
console.log('Rows:'+results.rows.length);
for (i=0; i<results.rows.length; i++) {
row = results.rows.item(i);
jsonClientes.push ('{"value:"'+row.value+'",label:"'+row.label+'"},');
}
The database stuff happens asyncronous. When the .autocomplete() gets called, the function on the "source" gets called and in there a database query is executed. But this database query tx.executeSql() will finish at any time in the future (async) and the "source" of the autocomplete will not have the result.
Unfortunately I have not found out how to solve this for those kind of jquery addons, so I went ahead to build an autocomplete around my specific database query. Basically, I start with the database query and provide a callback for the tx.executeSql() that will fill my autocomplete dropdown.
I loop through an ajax recordset and insert rows into an html5 database.
In Google Chrome, the program inserts 581 rows, whereas on the iPad, it only inserts between 20 and 80 rows.
I output the commands to the document body just to make sure they are being run, so I know there are 581 insert statements being run on the iPad, but then the table only has a handful.
OK, here's how I do it.
I first drop the table, then when that's done, I create the table.
Then when that's done, I do my ajax call.
When that comes back, I loop through the recordset and insert into the html5 local database.
var DropTableiUsr = function() {
var DropTableDeferred = new $.Deferred();
var CreateTableDeferred = new $.Deferred();
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'drop table iUsr;'
,[]
,DropTableDeferred.resolve()
);
});
DropTableDeferred.done(function() {
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'CREATE TABLE IF NOT EXISTS iUsr'
+ '(UsrID Integer NOT NULL PRIMARY KEY'
+ ',UsrGradeDate Varchar(128)'
+ ');'
,[]
,CreateTableDeferred.resolve()
);
});
});
CreateTableDeferred.done(function() {
var settings = {};
settings.data = {};
settings.data.method = 'View0';
var myPromise = $(this).myAjax('com/Usr.cfc', settings); // 'this' normally points to the DOM element that is the context of what caused the Ajax call.
myPromise.done(function(result) {
if (result.RTN) {
var qryUsr = result.qry.DATA;
qryUsr.RecordCount = result.qry.ROWCOUNT;
// qryUsr.ColumnList = result.qry.COLUMNS;
for (var CurrentRow=0;CurrentRow < qryUsr.RecordCount;CurrentRow++) {
myFunction(CurrentRow);
};
function myFunction(CurrentRow) {
$('body').append('INSERT INTO iUsr(UsrID,UsrGradeDate) VALUES(' + qryUsr.USRID[CurrentRow] + ',' + qryUsr.USRGRADEDATE[CurrentRow] + ')<br>');
dbo.transaction(function(myTrans) {
myTrans.executeSql(
'INSERT INTO iUsr(UsrID,UsrGradeDate) VALUES(?,?)',
[
qryUsr.USRID[CurrentRow],
qryUsr.USRGRADEDATE[CurrentRow]
]
)
});
};
} else {
$('#msg').text(result.MSG);
}
});
myPromise.fail(function(jqXHR, textStatus,C ) {
alert('PopulateiUsr: ' + C);
$('.container').append(jqXHR.responseText);
})
$('body').append('iUsr<br>');
});
};
$('#Reset').click(function() {
DropTableiUsr();
});
If you move the screen around while something is processing, it stops the processing.
Try displaying a countdown on the INSERT INTO callback, and you will see that it stops the countdown if you scroll the screen down.