I've seen some similar posts here, but unfortunately none of them have solved my problem. My experience with JQuery is minimal, so I'm sure there's something I'm missing. If someone could help me with this, I'd really appreciate it!
I created an ASP.NET/C# page that uses a JQuery/AJAX autocomplete function to display a list of tag or lot numbers the user can select from as they type values in a textbox (txtLookup).
$(document).ready(function ()
{
$("#txtLookup").on("keyup",function () {
var textCheck = $("#txtLookup").val();
if ($("#txtLookupType").val() == "tagNo")
{
$(".autosuggest").autocomplete(
{
source: function (request, response) {
$.ajax(
{
type: "POST",
url: "Inventory.aspx/GetAutoCompleteData",
data: '{"lookup":' + textCheck + '}',
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (data) { response(data.d); },
});
}
, minLength: 2,
});
}
else if ($("#txtLookupType").val() == "lotNo")
{
var jsonText = JSON.stringify({ lookup: textCheck + '%' });
$(".autosuggest").autocomplete(
{
source: function (request, response) {
$.ajax(
{
type: "POST",
url: "Inventory.aspx/GetAutoCompleteData3",
data: jsonText,
contentType: "application/json;charset=utf-8",
dataType: "json",
success: function (data) { response(data.d); },
//error: function (ts) { alert(ts.responseText); }
});
}
, minLength: 2,
});
}
else
{
}
});
});
The function works great when a keyboard is used to enter the values, but users can also enter numbers via an on-screen number pad I created (the program runs on a touchscreen). When users click a number button, the number is written to the textbox via Javascript. I'd like to trigger the autocomplete at this time, but I can't figure out how to do it. Some of the things I've tried are commented in the code block below. I've also tried modifying the function to use $("[id$=txtLookup").keyup(function () { instead of $("#txtLookup").on("keyup",function () {. I've tried different events, like keydown, keypress, and change, but haven't had any luck.
This Javascript block runs when the user clicks the "1" button:
if (object.id == "imgNum1")
{
var x;
x = "1";
var textObj = document.getElementById('txtLookup');
insertTextAtCursor(textObj, x);
document.getElementById("txtLookup").focus();
document.getElementById("txtLastClickedBtnValue").value = '';
//Failed attempts...
//$("#txtLookup").trigger("keyup");
//jQuery(document).ready(function(){});
//$(".autosuggest").autocomplete("search");
//$("input#txtLookup").autocomplete("search");
//$("[id$=txtLookup]").autocomplete("search");
}
Can someone please tell me what I'm doing wrong? Thanks in advance!
Edited to add the ASP.NET code:
Textbox:
<asp:TextBox id="txtLookup" runat="server" Height="16px" Width="155px" CSSClass="labelAlignTop autosuggest" onfocus="javascript: setTextboxID(this);"></asp:TextBox>
The setTetboxID function just writes the textbox name to a hidden field to store it to track the last clicked textbox.
Number button:
<asp:ImageButton ID="imgNum1" ImageUrl="Images/InvNumPad/btn_1.png" runat="server" onmouseover="this.src='Images/InvNumPad/btn_1_Over.png'" onmouseout="this.src='Images/InvNumPad/btn_1.png'" CssClass="inv_btnNum1" onfocus="javascript: getButtonClicked(this)" onclientclick="return false;" Width="50px" Height="50px"/>
The getButtonClicked function contains the Javascript block I posted above that runs when the user clicks the "1" button and handles the caret positioning.
After much fiddly work, Divine intervention blessed me with the solution to my question. I wanted to add an update in case someone in the future is tearing their hair out looking for the answer. To trigger the autocomplete code I posted above, I needed to trigger two events: touchstart and input.
function triggerAC()
{
//Triggers txtLookup autocomplete after touchscreen event
$("#txtLookup").trigger("touchstart");
$("#txtLookup").trigger("input");
}
I also added touchstart to the third line of the code block I originally posted, changing
$("#txtLookup").on("keyup",function () {
to
$("#txtLookup").on("keyup touchstart",function () {
Related
I have an autocomplete field, and on type I go to the PHP/Database to retrieve the matching options.
Thing is, my suggestion list isn't exactly matches of the text. I explain:
Say I type "Jon". My list will bring from the database "John Doe", "Jonatan", etc. Only "Jonatan" will be visible as the suggestion to the input, but I do need them all, because it considers approximation (there's a soundex element on my backend search).
My JavaScript/Ajax code:
function prePatientsList(){
//I'm limiting search so it only starts on the second character
if (document.getElementById("name").value.length >= 2) {
try
{
listExecute.abort();
}catch(err) {
null;
}
var nome= $("#name").val();
var nomeList = "";
listExecute = $.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
async: true,
datatype: 'json',
data: { nome: nome}
}).done(function(data){
source = JSON.parse(data);
});
$(function() {
$("input#nome").autocomplete({
source: source,
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
}
}
Thanks.
I think you'd have to set your remote endpoint directly as the autocomplete's source (e.g. similar to https://jqueryui.com/autocomplete/#remote) so that it's the backend which does all the filtering. Right now, the autocomplete effectively thinks you've fed it a static list of options from which further filtering should take place, and therefore it decides to handle the filtering itself.
Your code can be as simple as this I think, no need to have a separate handler or an ajax request outside the scope of the autocomplete.
$(function() {
$("input#nome").autocomplete({
minLength: 2, //limit to only firing when 2 characters or more are typed
source: function(request, response)
{
$.ajax({
url: '/web/aconselhamento/Atendimento/PrePacientesAutocomplete',
type: "POST",
dataType: 'json',
data: { nome: request.term } //request.term represents the value typed by the user, as detected by the autocomplete plugin
}).done(function(data){
response(data); //return the data to the autocomplete as the final list of suggestions
});
},
// I know I probably don't need this, but I have a similar component which has an URL as value, so when I select an option, it redirects me, and I'll apply you kind answer on both.
select: function( event, ui ) {
ui.item.label;
}
});
});
See http://api.jqueryui.com/autocomplete/#option-source for more info.
I'm trying to call a funtion in textextjs method-
//my function
function GetAreaTags() {
return "some text";
}
//textext initializtion
$('#territory').textext({
plugins: 'tags prompt focus autocomplete ajax',
ajax: {
url: '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags(),
dataType: 'json',
cacheResults: false
}
});
But GetAreaTags() is not being called. How can i make it happen?
It should work... But try this:
function GetAreaTags() {
return "some text";
};
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags(),
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
If that doesn't work out try this:
function GetAreaTags() {
return "some text";
};
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: function() {return '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags()},
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
Check the console both times to see if your url is what you desire.
[EDIT: I rejected the edit by mistake, sorry about that]
Edit2
From s.k.paul's comment:
GetAreaTags() should execute every time i type in that textbox.
However, console says- 1. /Admin/Search/GetTerritorySuggestions?area=
2. localhost:12788/Admin/Dashboard/…}&q= 404 (Not Found)
Therefore you need another event handler to dynamically change the url (the plugin must be recalled with another url):
function GetAreaTags() {
return "some text";
};
$("#territory").keyup(function() {
var yourObj= {
plugins: 'tags prompt focus autocomplete ajax',
ajax : {
url: function() {return '/Admin/Search/GetTerritorySuggestions?area=' + GetAreaTags()},
dataType: 'json',
cacheResults: false
}
};
$('#territory').textext(yourObj);
console.log(yourObj.ajax.url);
});
However, this may be very heavy... The plugin expects you to have a single reference for your auto-complete resource. If you're dynamically changing it, it may reset the already existing stuff.
Edit3
Edit 2 : textextjs does not work at all now. And, url function returns
whole function text
This means the plugin doesn't handle well being recalled twice or more times in the same element. The only possible solution I am seeing is to change the plugin's code in order to dynamically change the resources according to your function...
Which makes me wonder, if it's easier for you to allow the user to have a broader data resource (include all areas) when typing, this way there would be only one URL and the plugin wouldn't have any trouble with that.
I was working on a simple form page and I was wondering what happens if someone clicks the submit button many many times (incase my shared hosting somehow seems to be slow at that time).
Also, incase anyone wants to look at my code
$.ajax({
url: "submit.php",
type: 'POST',
data: form,
success: function (msg) {
$(".ressult").html("Thank You!");
},
error: function () {
$(".result").html("Error");
}
});
Is there a way to make it so after the user clicks it once, it won't run it again until the first click is done?
Thank you
You can use jQuery's .one() function:
(function handleSubmit() {
$('#submitBtn').one('click', function() {
var $result = $('.result');
$.ajax({
url: 'submit.php',
type: 'POST',
data: form,
success: function (msg) {
$result.html('Thank You!');
handleSubmit(); // re-bind once.
},
error: function () {
$result.html('Error');
}
}); // End ajax()
}); // End one(click)
}()); // End self-invoked handleSubmit()
*Edit: * Added recursion for multiple submissions.
Use a boolean flag
if (window.isRunning) return;
window.isRunning = true;
$.ajax({
url:"submit.php",
type: 'POST',
data: form,
success: function (msg){
$(".ressult").html("Thank You!");
},
error: function (){
$(".result").html("Error");
},
complete : function () {
window.isRunning = false;
}
});
var $button = $(this);
$button.prop('disabled', true); // disable the button
$.ajax({
url:"submit.php",
type: 'POST',
data: form,
success: function (msg){
$(".ressult").html("Thank You!");
},
error: function (){
$(".result").html("Error");
},
complete: function() {
$button.prop('disabled', false); // enable it again
}
});
Have you considered replacing your submit button with a loader image while the query executes, then re-adding it once the query is complete?
EDIT: Using the loader image is a sort of universal "I'm doing something" indicator, but disabling the button would work too!
You could disable the submit button, before the ajax call is made. And then, if required, enable it on success.
Bear with me. I recently started implementing jquery at work. I created a new app already so I do have an understanding of what goes but I have not fully grasped it yet.
I have this function below that is being called everytime someone clicks a checkbox in a table wrapped in a unique div id. Currently, the table does not refresh until you close the dialog box. I want the div to refresh after the the server finishes its request.
I got it to work only for the first row in the table by simply calling the displayMid function again (that is commented out in the code below).
How do I get this to work for all the table rows? You can see I have been trying a few things already. ;-)
Any help is appreciated! Thanks!
function addRemoveMid(count, testpid) {
var x = testpid;
var y = $("#Mid" + count).text();
var a = $("#midcheckbox" + count).is(':checked');
//alert(x);
if (!$("#midcheckbox" + count).is(':checked')) {
$.ajax({
url: "content_backend_pub_pid.ashx",
data: { cmd: '10', pid: x, mid: y },
type: "get",
async: false,
success: function(o) {
//displayMid(count);
//$("#inputDiv4").replaceWith($('#inputDiv4', $(html)));
}
});
//$(this.addRemoveMid(count);
}
else {
$.ajax({
url: "content_backend_pub_pid.ashx",
data: { cmd: '9', pid: x, mid: y },
type: "get",
async: false,
success: function(o) {
//displayMid(count);
//$("#inputDiv4").replaceWith($('#inputDiv4', $(html)));
}
});
//displayMid(count);
}
//$("#inputDiv4").fadeOut("fast").html('reload.php').fadeIn("fast");
}
'Currently, the table does not refresh until you close the dialog box' what this means? I see only a commented alert(x).What dialog box are you talking about?
Plans changed and my boss said he would rather have it refresh on close. So it is fine the way it is.
With this code:
function setupRow(event, ui) {
var textbox, // how do i get to the textbox that triggered this? from there
// on i can find these neighbours:
hiddenField = textbox.next(),
select = textbox.parents('tr').find('select');
textbox.val(ui.item.Name);
hiddenField.val(ui.item.Id);
$.each(ui.item.Uoms, function(i, item){
select.append($('<option>' + item + '</option>'));
});
return false;
}
function setupAutoComplete(){
var serviceUrl = "/inventory/items/suggest";
$("input.inputInvItemName").autocomplete({
source: function(request, response) {
$.ajax({
url: serviceUrl,
data: request,
dataType: "json",
success: function(data) {
response($.map(data.InventoryItems, function(item) {
return {
value: item.Name
};
}));
},
select: function(event, ui) {
setupRow(event, ui);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
}
});
},
minLength: 3,
delay: 500
});
}
everything seems ok. Problem is the select handler never fires, not even the anonymous function that wraps my original delegate setupRow for debugging purposes is ever called.
anyone can see my error?
I also left a question in the comment: how do I get to the textbox that had the autosuggestion. Cannot use id here, because these text boxes are multiples and generated on the fly, interactively. Or is there another way to do the same thing?
Thanks for any help!
OP point of view
var textbox, // how do i get to the textbox that triggered this? from there
// on i can find these neighbours:
My Point of view
have you tried,
var textbox = $(event.target);
or you can do this,
OP point of view
select: function(event, ui) {
setupRow(event, ui);
},
My point of view
select: setupRow;
then
var textbox = this; // just a guess... wait..
anyone can see my error?
I think you forgot to put ';' .
$.ajax({
url: serviceUrl,
data: request,
dataType: "json",
success: function(data) {
response($.map(data.InventoryItems, function(item) {
return {
value: item.Name
}
}));
Or is there another way to do the same thing?
I think u are using the jquery ui autocomplete plugin.If yes, you can retreive like this.
$('.ui-autocomplete-input')
Otherwise, you can set a specific class to those textboxes and access those textbox through that class.
ok, got a step closer by using
inputs.bind("autocompleteselect", setupRow);
now setupRow fires.
Now it seems, that the success callback transforms the data, I get returned.I need to find a way, to both display the right value in the dropdown, without destroying the requests response...
Any ideas?