Problem with autocomplete (jquery) - jquery-ui

I have problem with autocomplete. The code below is returnig me
["foo#foo.com","bar#bar.com"]
$('.autocomplete').keyup(function() {
tid = $(this).attr('id')
$(this).autocomplete({
source: function (req, resp){
$.ajax(
{
url: "autocompl.asp",
data:$("#msgForm").serialize() + "&field="+tid ,
success : function( resp ) {
return resp
}
})
}
});
});
But the suggestions don't appear. It worked for me when I have called autocomplete without any extra parameters.
Any clue?
Thanks in advance
Magda

Note that one of your parameters for the source function is resp, and you're using another resp afterwards. I think you need to use the first resp to send the response object back.
I'm using this as well and this works for me (Instead of sending an array of values, I'm sending an array of objects with two attributes, but I don't think it's mandatory).
id
label
so the code inside the ajax success should look something like this (my data variable is your second resp variable, a different name to avoid mixup):
success: function(data) {
for (i in data) {
a = {}
a.id = data[i]
a.label = data[i]
options.push(a)
}
resp(options)
}

Related

PagedList parameter too long

I have an MVC PagedList which works just fine. I am filtering that list and the filter predicate is sent to the client during roundtrips. I use unobtusive ajax replacing. My pager code looks as:
#Html.PagedListPager((IPagedList)Model.Items,
page => Url.Action("Filter",
new ClientSearch
{
Page = page,
PageSize = Model.PageSize,
Predicate = Model.Predicate
}),
PagedListRenderOptions.EnableUnobtrusiveAjaxReplacing(
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "clients-list",
}))
The problem is, that the Predicate parameter is too long. And it should be. I get the following exception:
"The request filtering module is configured to deny a request where the query string is too long."
I do not want to alter the web.config in order to allow long parameters. I would like to pass the model in a POST header instead of query string parameter. Is it possible with PagedList?
Thanks in advance.
I still couldn't figure out whether PagedList supported posting large data, however I ended up with the following workaround.
I have a post method which posts the model to the controller function and replaces the partial view content with the results.
function postToPage(url, size, predicate, replace) {
var data = {
size: size,
predicate: predicate
};
$.ajax({
url: url,
data: data,
type: 'POST',
success: function (result) {
$('#' + replace).html(result);
}
});
}
I also have another function to replace the URLs in the pagination-container div and wire up the click event to call the post method. The click event stops event propagation, so the URL in the href attribute won't be used.
function replaceHrefs() {
$('div[class = pagination-container').find('a').each(function (index, value) {
var url = value.href.toString();
value.addEventListener('click', function (event) {
event.stopPropagation();
post(url);
});
value.href = '#';
});
I created a custom version of post method in order to generate the pagesize and predicate from the model.
function post(url) {
postToPage(url, #Model.PageSize, '#Model.Predicate', 'clients-list');
}
I had to wire up the URL replacing procedure to two places: when the document becomes ready and when the ajax call completes. These covered all the cases I needed.
$( document ).ajaxComplete(function() {
replaceHrefs();
});
$( document ).ready(function() {
replaceHrefs();
});
I hope it helps someone.

Loop through html tables data and submit back to server

I have spent the last couple of hours battling to write some javascript and jquery.
Basically I am trying to loop through a table checking if an attribute exists within a TD if it does add its info into an array and post it back to the server
My code (I am sure it could be better)
$("#save-changes").click(function () {
var param = [];
var table = $("#products-grid > .t-grid-content > table tbody tr").each(function (i) {
//find checkboxes using class
var td = ($(this).find("td:nth-child(2)").find(".cb"));
var attr = $(td).attr('data-item');
if (typeof attr !== 'undefined' && attr !== false) {
console.log(td);
param.push({ "itemId": attr, "productId": td.val() });
}
});
console.log(param);
$.ajax({
url: '#Url.Action("ApplyProduct")',
data: param,
type: 'POST',
success: function (e) {
I am now stuck on trying to pass the array back to the server. What do I need to do to send the data back to the server as a parameter the server can understand?
Any help would be great!
add two parameters
dataType: "json",
data: JSON.stringify(param)
to your .ajax call.
Crate an object server side which has two int properties int called itemId and productId and then create a JsonResult route that takes an array of your object that you post too (this would be ApplyProduct in your case).
you cannot send arrays to a server , they have to be strings.
you could join the array together like this
param.join(";");
that would create a string with each value seperated by a ;
also you need to specify the data option as a key-value json
$.ajax({
url: '#Url.Action("ApplyProduct")',
data: {
param : param
},
type: 'POST',
then on the serverside you can split the string back into an array
$param = explode(";",$_POST['param']);

use ajax call in jquery autocomplete only if result is not found in locally built array

In my web app , I am showing rates of stocks.I am using jquery autocomplete to show options while entring stocks name. But I have built local copy of javascript array. I want to show the options from this local array , If search term is not found in local array then ajax call must be made to get the list from server side.
Thanks !!!
//Local array
var local_array=["option1","option2"];
//jqueryUI call of autocomplete function
$('#search_stock').autocomplete({
source:function(){
if(search term is found in local array)
{
show suggestion from local array.
}
else
{
make ajax call to show suggestions of stock names.
}
}
});
UPDATE
Here's the actual code
$(function() {
var cache = {'option1':'option1','option2':'option2'}, lastXhr;
$( "#stock_rates" ).autocomplete({
minLength: 2,
source: function( request, response ) {
var term = request.term;
if ( term in cache ) {
response( cache[ term ] );
return;
}
lastXhr = $.getJSON( "stock_rates.php", request, function( data, status, xhr ) {
cache[ term ] = data;
if ( xhr === lastXhr ) { response( data ); }
});
}
});
});
The example pages for jQuery UI autocomplete have an example of exactly this issue.
http://jqueryui.com/demos/autocomplete/#remote-with-cache. Click the 'View Source' link on that page to see the code for the example.
The key part is that 'source' takes arguments.
source: function(request, response){
You need to read request, either fetch the value from your cache, or do a request, and then call the response function and pass it the matched values.
Update
Your problem now is that the format that you are storing in your cache is wrong. The cache just stores data as it would be returned from your getJSON call, indexed by the search term. It is up to you do to do the prefix checking and such.
To continue the way you are trying now, you'll either need to populate the cache properly.
var cache = {
"o": ['option1', 'option2'],
"op": ['option1', 'option2'],
// ....
"option1": ['option1'],
"option2": ['option2']
};
Otherwise, you could store the data differently and put more logic in your 'source' function to do the prefix checking on a static array or something. That all really depends on the data you are caching though.
Use search event of autocomplete and check your condition in that event and based on that return true or false if you want to make a ajax call respectively.
Below is the sample code.
$('#search_stock').autocomplete({
search:function(event,ui){
if(search term is found in local array)
{
return false;
}
else
{
return true;
}
}
});

How to wait for all ajax queries to finish (and use combined result)

var display_message="";
$('input:checked').each(function(index) {
var profile_id=$(this).val();
$.ajax({
type: 'post',
url: 'myUrl',
data: data,
success: function(data) {
if(data=="ok")
display_message = display_message + data +", ";
}
});
});
alert(display_message);
alert(display_message);
if($.trim(display_message)!=""){
jAlert("Your birthdate already exits in "+display_message.substring(0, display_message.length - 2)+".", "Bdate");
return false;
}
in this code, i use two alert-box for display display_message variable value.
when i run successfully this code, in 1st alert-box i get blank value and second alert-box i get value which i needed, then it will go in if condition.
if i doesn't use alert box then it will always take null value in display_message variable and never enters into the if condition. so what i need to change to run this code without alert box?
You are making an asynchronous call via AJAX, but your code is executing synchronously. So it is returning before the AJAX call completes. The first alert box just gives the function time to catch up. You need to handle all this code in your success callback.
var display_message="";
$('input:checked').each(function(index) {
var profile_id=$(this).val();
$.ajax({
type: 'post',
url: 'myUrl',
data: data,
success: function(data) {
if(data=="ok")
display_message = display_message + data +", ";
if($.trim(display_message)!=""){
jAlert("Your birthdate already exits in "+display_message.substring(0, display_message.length - 2)+".", "Bdate");
return false;
}
});
});
You want all your ajax queries to finish and return results, right?
Then this is a synchronization problem.
I would suggest this approach (code is simplified for clarity).
var inputs_processed = -1;
var inputs_to_process = -1;
function queryData() {
inputs_to_process = $('input:checked').length;
$('input:checked').each(function() {
$.ajax({success: function(data) {
inputs_processed += 1;
// build up that message
}});
});
}
function displayResult() {
if (inputs_processed == inputs_to_process) {
// display result
} else {
// not all queries finished yet. Wait.
setTimeout(displayResult, 500);
}
}
queryData();
displayResult();
Basically, you know how many requests should be made and you don't display result until that number of requests returns.
Why your data is "data"? I cant see any variable called data is declared here. You should pass in the value you want to use as the parameter into the data options.
Edit: This is why u getting the null value. data is not initialize into anything. Only after the success function, your "data" will have the value since you declare the return value with the same name

Working with XML in a Firefox Add-on(ex Jetpack)

I'm currently developing a Firefox add-on(using https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/ ) that consumes an API where the return data is in xml.
My problem is that I need to parse the returned data, and would like to do that using a xml object.
Since the request module only supports JSON and Text ( https://addons.mozilla.org/en-US/developers/docs/sdk/1.0/packages/addon-kit/docs/request.html#Response ) I need to convert the response.text to XML.
The code looks like this:
var Request = require('request').Request
.......
var req = Request({
url: https://to-the-api.com,
content: {
op: 'get-the-data-op',
password: "super-sec",
user: "username"
},
onComplete: function (response) {
dataAsText = response.text;
console.log("output: " + dataAsText);
}
});
req.post();
I have tried to user (new DOMParser).parseFromString(response.text, 'text/xml') but unfortunately it just fails with a error like ReferenceError: DOMParser is not defined
The question is if anyone of you guys have been able to create a Xml object inside a Firefox add-on, and if so, how?
Looks like the capability to parse response as xml was present, but has been removed. check out this bugzilla reference
Can't you use a normal XMLHttpRequest if you want to process the response as XML?
If DOMParser is unavailable you can try E4X:
var xml = new XML(response.text);
alert(xml.children().length());
You want to use the XMLHttpRequest object to handle your xhr request. Then when you get a response back access the responseXML object of the request variable. In the responseXML you'll have the documentElement and can use the querySelectorAll or querySelector to find elements you want. In each element you want just grab the textContent you need.
Here's an example to get you going (this looks for the 'xmls' element in the response):
var request = new require("xhr").XMLHttpRequest();
request.open('GET', 'https://to-the-api.com', true);
request.onreadystatechange = function (aEvt) {
if (request.readyState == 4) {
if(request.status == 200) {
var xmls = request.responseXML.documentElement.querySelectorAll("xmls");
for (var i = 0; i < xmls.length; i++) {
console.log("xml", i, xmls[i], xmls[i].textContent);
}
}
else {
console.log('Error', request.responseText);
}
}
};
request.send(null);

Resources