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?
Related
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 () {
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 am using jquery-ui-1.11.4 and autocomplete. My source is obtained by ajax which is properly returning this type of JSON
[
{"label":"foo", "value":"01-1013"},
{"label":"bar", "value":"01-1003"}
]
When I scroll down to select my choice everything works correctly. The value is added to printTag and the label is added to the text box (inputTag). The problem is that as I use the down arrow to select my choice, the value is displayed in the text box, not the label. The label is ONLY displayed in after I select my choice.
I read a couple of reviews and have tried to modify my code but I can't figure it out. Here is my autocomplete.
$(inputTag).autocomplete({
source: function(request, response) {
$.ajax({
url: myAjaxFile,
method: "GET",
dataType: "JSON",
data: getData+'='+ request.term,
success: function(data){
response(data)
}
});
},
focus: function(event, ui){
event.preventDefault();
$(inputTag).val(ui.item.label);
return false;
},
select: function(event, ui) {
$(printTag).val(ui.item.value);
// prevent autocomplete from updating the textbox
event.preventDefault();
$(inputTag).val(ui.item.label);
return false;
},
minLength: 2
});
How do I display the label in the text box rather than the value?
I try to make a link fire a javascript function wich fires a ajax call to delete an item.
Like so:
<a class="delete" href="#item.Product.Id">(x)</a>
Clicking the cross caries the id of the product to be deleted.
The only reason the href attribute is there is to carry the value.
$(document).ready(function () {
$('.delete').click(function (e) {
e.preventDefault();
var id = $(this).attr("href");
deleteItem(id);
return false;
});
});
Ajax call: as requested:
function deleteItem(id) {
$.ajax({
url: "/Shoppingcart/RemoveItem",
type: "POST",
data: "id=" + id,
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function () {
$.ajax({
url: "/Shoppingcart/Index",
type: "GET",
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function (result) {
success(result);
}
});
}
});
}
The success function is there to get an updated version of the cart.
And this actually works just fine. However I get a wierd page refresh half way trough the cycle.
I click the link.
the page refreshes and the item is not deleted.
I click the link once more.
the page is not refreshed.
the item is deleted.
Why do I have to click two time and what can I do to resolve this?
The most correct answer is: You don't know what the error is,
because the page is refreshing before you see the error.
Return false prevents the page from refreshing after a click event, but if the code runs into an error before that point...
So you could try to remove the href tag and make it an rel (or something else) tag instead. read that and use it for your AJAX call. give the href a value like # or #removeItem.
This will give you the error your craving for.
Hope this helps!
Usually you get such behavior when page the is quite big and the document.ready event just hasn't fired yet when you click the link. The second time it may load faster (scripts/css already downloaded and coming from cache).
As per my knowledge, have a hidden field or a hidden span to save the "ProductId" and remove the href attribute altogether something like below.
<span id="productIdSpan">#item.Product.Id</span>
<a class="delete"></a>
jQuery:
$(document).ready(function () {
$('.delete').click(function (e) {
var id = $("#productIdSpan").html();
deleteItem(id);
return false;
});
});
EDIT:
Approach-2:
You can store the ProductId in the anchor tag's "title" attribute something like below
jQuery:
$(document).ready(function () {
$(".delete").on("click", function (e) {
deleteItem($(this).attr("title"));
return false;
});
});
This should solve your problem. Hope this helps!!
The correct answer is:
When you add an element to your html after the page is loaded ( for example with AJAX ) and you want to have, in any way, fire an event. You have to rebind the click event to the new element.
When the page is loaded and your javascript and jQuery are loaded. The element isn't their yet so they can't find it or interact with it.
So in my situation:
function addItem(id, amount) {
$.ajax({
url: "/Shoppingcart/AddItem",
type: "POST",
data: "id=" + id + "&amount=" + amount,
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function () {
// Calls for the new update version of the shopping cart.
$.ajax({
url: "/Shoppingcart/Index",
type: "GET",
cache: false,
error: function (xhr, status, error) {
console.log(xhr, status, error);
},
success: function (result) {
//Call the function that changes the html
success(result);
}
});
}
});
}
function success(result) {
$("#shoppingcart").html(result);
//The tricky part: rebinding the new event.
$('.delete').click(function (e) {
e.preventDefault();
var id = $(this).attr("data-id");
deleteItem(id);
return false;
});
}
The delete button did work after a refresh because in that way javascript got reloaded and the element was correctly bound.
I have used JQuery UI autocomplete to cut down on the list of parts I have to display in a drop down, I am also using json to pass the list of parts back but I am failing to see the results, I am sure this is to do with my limited understanding of JQuery's Map function.
I have the following json
{"parts":[{"partNumber":"654356"},{"partNumber":"654348"},{"partNumber":"654355-6"},{"partNumber":"654355"},{"partNumber":"654357"},{"partNumber":"654357-6"},{"partNumber":"654348-6"}]}
which on JSONLint is validated correct
I have viewed the post and response utilising Firebug and seen them to be correct but my auto complete does not seem to display, the closest I have got it to doing so, was when I displayed the entire JSON string with each character having a new line.
here is my JS
$('.partsTextBox').autocomplete({
minLength: 3,
source: function(request, response) {
$.ajax({
url: './PartSearch.ashx',
data: $('.partsTextBox').serialize(),
datatype: 'JSON',
type: 'POST',
success: function(data) {
response($.map(data, function(item) {
return { label: item.partNumber }
}))
}
});
},
select: function(e) {
ptb.value = e;
}
});
Any help anyone can give would be much appreciated. Have edited to include help given by soderslatt
I'm not sure, but shouldn't parts.part be an array ?
http://jsfiddle.net/jfTVL/3/
From the jQuery autocomplete page:
The local data can be a simple Array of Strings, or it contains Objects for each item in the array, with either a label or value property or both. The label property is displayed in the suggestion menu. The value will be inserted into the input element after the user selected something from the menu. If just one property is specified, it will be used for both, eg. if you provide only value-properties, the value will also be used as the label.
Which means that if you use "value" instead of "partNumber", you should get want you want.
jquery autocomplete plugin format out have to
{"query":"your_query","suggestions":["suggestions_1","suggestions_2"],"data":[your_data]}}
and use autocomplete that
$('#your_input').autocomplete({
minChars: 2
, serviceUrl: './PartSearch.ashx'
, deferRequestBy: 50
, noCache: true
, params: { }
, onSelect: function(value, data) {
}
, ajaxCallBack: function() {
response($.map(data, function(item) {
return { label: item.partNumber}
}))
}
});