The Story So far....
Trying to learn JS and JQuery and i thought i would start with the basics and try alittle AJAX "search as you type" magic. Firstly i just wanted to get the AJAX part right and iterating through the return JSON object and appending it to a unordered list. Im doing no validation on the inputted value vs. the returned JSON results at this time, i just want a controlled way of when to do the AJAX getJSON call. Later i will do the validation once i get this right.
Anyways im having trouble displaying the Account Numbers in in the ul. At the moment the only thing that is being displayed is AccountNumber in the li and not my ACCOUNT NUMBERS
My JS Code is here:
http://jsfiddle.net/garfbradaz/HBYvq/54/
but for ease its here as well:
$(document).ready(function() {
$("#livesearchinput").keydown(function(key) {
$.ajaxSetup({
cache: false
});
$.getJSON(" /gh/get/response.json//garfbradaz/MvcLiveSearch/tree/master/JSFiddleAjaxReponses/", function(JSONData) {
$('<ul>').attr({
id: "live-list"
}).appendTo('div#livesearchesults');
$.each(JSONData, function(i, item) {
var li = $('<li>').append(i).appendTo('ul#live-list');
//debugger;
});
});
});
});
My JSON file is hosted on github, but again for ease, here it is:
https://github.com/garfbradaz/MvcLiveSearch/blob/master/JSFiddleAjaxReponses/demo.response.json
{
"AccountNumber": [
1000014,
1015454,
1000013,
1000012,
12
]
}
Also here is my Fiddler results proving my JSON object is being returned.
EDIT:
There were so queries about what i was trying to achieve, so here it goes:
Learn JQuery
To build a "Search as you Type" input box. Firstly i wanted to get the AJAX part right first, then i was going to build an MVC3 (ASP.NET) Application that utilises this functionality, plus tidy up the JQuery code which includes validation for the input vs. the returned JSON.
Cheesos answer below worked for me and the JSFiddle can be found here:
http://jsfiddle.net/garfbradaz/JYdTU/
First, I think keydown is probably the wrong time to do the json call, or at least... it's wrong to do a json call with every keydown. That's too many calls. If I type "hello" in the input box, within about .8 seconds, then there are 5 json requests and responses.
But you could make it so that it retrieves the json only the first time through, using a flag.
Something like this:
$(document).ready(function() {
var $input = $("#livesearchinput"), filled = false;
$.ajaxSetup({ cache: false });
$input.keydown(function(key) {
if (!filled) {
filled = true;
$.getJSON("json101.js", function(JSONData) {
var $ul =
$('<ul>')
.attr({id: "live-list"})
.appendTo('div#livesearchesults');
$.each(JSONData, function(i, item) {
$.each(item, function(j, val) {
$('<li>').append(val).appendTo($ul);
});
});
});
}
});
});
The key thing there is I've used an inner $.each().
The outer $.each() is probably unnecessary. The JSON you receive has exactly one element in the object - "AccountNumber", which is an array. So you don't need to iterate over all the items in the object.
That might look like this:
$.each(JSONData.AccountNumber, function(i, item) {
$('<li>').append(item).appendTo($ul);
});
What you probably want is this:
$.each(JSONData.AccountNumber, function(i, item) {
var li = $('<li>').append(item).appendTo('ul#live-list');
});
Your code:
$.each(JSONData, function(i, item) {
var li = $('<li>').append(i).appendTo('ul#live-list');
});
Says "iterate over the keys and values of the outer JSON structure, and print the keys". The first key is "AccountNumber", so you end up printing that.
What you want to do is iterate over the array stored at JSONData.AccountNumber, and print the values:
$.each(JSONData.AccountNumber, function() {
var li = $('<li>').append(this).appendTo('ul#live-list');
});
Related
lately I have been studing nightmare module I think it's very simple and useful but I have question.
how to use callback when I click ajax button
MyCode
var Nightmare = require('nightmare'),
nightmare = Nightmare();
nightmare
.goto('https://motul.lubricantadvisor.com/Default.aspx?data=1&lang=ENG&lang=eng')
.click('input[title="Cars"]')
.wait(1000)
.evaluate(function () {
//return $('#ctl00_ContentPlaceHolder1_lstModel option');
var links = document.querySelectorAll('#ctl00_ContentPlaceHolder1_lstMake option');
return [].map.call(links, function (e) {
return {value: e.value, name: e.text};
});
})
.end()
.then(function (items) {
console.log(items);
});
there is wait method. most people use wait methed I searched googling
.wait(1000)
I don't use wait method. because If it's network disconnect or slow. It's not good code
Could you help me callback method??
Thanks. So I have motify the code but It's doesn't work
var Nightmare = require('nightmare'),
nightmare = Nightmare();
nightmare
.goto('https://motul.lubricantadvisor.com/Default.aspx?data=1&lang=ENG&lang=eng')
.click('input[title="Cars"]')
.wait('#result > #ctl00_ContentPlaceHolder1_lstMake option')
.evaluate(function () {
$(document).ajaxSuccess(function () {
var links = document.querySelectorAll('#ctl00_ContentPlaceHolder1_lstMake option');
return [].map.call(links, function (e) {
return {value: e.value, name: e.text};
});
});
})
.end()
.then(function (items) {
console.log(items);
});
There are many ways to solve this. The easiest would be the following.
Suppose when an Ajax request finishes, it always changes something on the page. Most of these changes can be easily detected when waiting for specific elements to appear which can be matched by CSS selectors.
Let's say you click something and the result is written into the element matched by "#result". If there wasn't such an element before the click then you can wait until the existence of this element:
.click("button")
.wait("#result")
// TODO: do something with the result
You can also use CSS selectors to count things. For example, let's say there are ten elements that can be matched with "#result > a". If a click adds 10 more, then you can wait for the 20th using:
.click("button")
.wait("#result > a:nth-of-type(20)")
// TODO: do something with the result
The world of CSS selectors is pretty big.
Of course, you could use evaluate to add a general Ajax event handler like $(document).ajaxSuccess(fn) to be notified whenever some callback finished, but the source code of a page changes all the time. It would be easier to maintain your code if you would look for the results that can be seen in the DOM.
Use this, ajax callback..
$.ajax(url,{dataType: "json", type: "POST" })
.then(function successCallback( data ) { //successCallback
console.log(data);
}, function errorCallback(err) { //errorCallback
console.log(err);
});
// console.log(2);
});
I am trying to create an JQM app and are doing so by getting a lot of data from database. When I click on a link from a ajax/json generated calendar list I should then be able to get the info for that event by calling the server and get the data. As it is now I do this in 2 steps like this.
My ajax generated event list:
$.each(groupcalendar, function (i, val) {
output += '<li><h2>' + val.matchformname + '</h2><p><strong>' + val.matchday + '</strong></p><p>' + val.coursename + '</p><p class="ui-li-aside"><strong>' + val.matchtime + '</strong></p></li>';
});
When I click on one of the links I want to goto a page called prematchdata.html and get the data fro that specific event. I do so by first calling the click and get the eventid from data-id like this:
$(document).on('click', '#gotoMatch', function () {
var matchid = $(this).attr("data-id");
$.get("http://mypage.com/json/getmatchinfo.php?matchid="+matchid, function(data) {
localStorage["matchinfo"] = JSON.stringify(data);
$.mobile.changePage( "prematchdata.html", { transition: "slide", changeHash: true} );
}, "json");
});
I save the returned data as localStorage and then uses this data in my pageinit like this:
$(document).on("pageinit", "#prematchdata", function() {
var matchinfo = {};
matchinfo = JSON.parse(localStorage["matchinfo"])
var content = '<h2>'+matchinfo["matchname"]+'</h2>';
$('.infoholder').html(content);
});
It works, although for me it seems like the last 2 steps should be done in one, but i am not sure how to do so? It seems a little bit wrong get data, save locally and then use it? Can't this be done without the $(document).on('click', '#gotoMatch', function () {});?
Hoping for some help and thanks in advance :-)
You could try sending it up using a query string. When you're using changePage, change your code like this :
$(document).on('click', '#gotoMatch', function () {
var matchid = $(this).attr("data-id");
$.get("http://mypage.com/json/getmatchinfo.php?matchid=" + matchid, function (data) {
paramData = data[0];
$.mobile.changePage("prematchdata.html", {
transition: "slide",
changeHash: true,
data: paramData //added this extra parameter which will pass data as a query string
});
}, "json");
});
When you're getting it back,
$(document).on("pageinit", "#prematchdata", function() {
var url = $.url(document.location);
var name= url.param("matchname");
var content = '<h2>'+ name +'</h2>';
$('.infoholder').html(content);
});
Another easy way would be use a singlepage template instead of a multi page template. Then, you could just use a global variable to get and set data.
That said, what you're doing right now is more secure than this query string method. By using this, anyone can see what you are sending over the URL. So I advise you keep using localStorage. For more info on this, look into this question.
How to call the ajax auto complete when particular time?
here this is my code
function auto(x){
x.autocomplete('ajax/getFriends',{
max:500,
width:300,
minChars:2,
autoFill: false,
formatItem: formatItem,
formatResult: formatResult
});
function formatItem(row) {
return row[0];
//return row[0] + " (<strong>id: " + row[1] + "</strong>)";
}
function formatResult(row) {
return row[0].replace(/(<.+?>)/gi, '');
}
$("#comment").result(function(event, data, formatted) {
$("#test1").val(data[1]);
$("#test2").val(data[2]);
});
}
but it says error x.autocomplete is not a function
i am calling the above is like
auto("string");
can any one help me how to solve this one
Thanks in advance
i am not good in english if any mistakes excuse me
I think you are confusing the way jQuery autocomplete works alltogether. It seems to me that you are attaching autocomplete to your string and building up the HTML elements for the suggestions. This is not how the autocomplete functionality works.
What you want to do is attach the autocomplete functionality to your input box. Then whenever something is entered in there the autocomplete function fires automatically on the input. That's just how it's built.
So let's say for instance you have an input box with an ID equal to myAwesomeInputBox in your HTML code:
<input type="text" id="myAwesomeInputBox"/>
To bind autocomplete (with ajax) to this input field just do this in Javascript:
$("#myAwesomeInputBox").autocomplete({
source: function( request, response ) {
// request.term is the input in the textbox, encode for security reasons
var input = encodeURI(request.term);
$.ajax({
// your ajax endpoint
url: 'ajax/getFriends',
// the request method, modify to your actual method
type: 'GET',
// whatever data you want to pass to your endpoint.
// I'm assuming at least the input (with key userInput here)
// and maybe the limit of the elements in the response array
// the server should send back
data: {userInput: input, limit: 500},
// what to do on success (process the response)
success: function(data){
// assuming your ajax endpoint returns a JSON encoded array with the suggestions as a response
var responseArray = $.parseJSON(data);
// pass the decoded response array to the jquery defined response method for autocomplete
response(responseArray);
},
// what to do if the server returns an error
error: function(jqXHR, textStatus, errorThrown){
// pass an empty suggestions array maybe?
response(new Array());
}
}, 'json');
}
});
The tricky part for me was
response(responseArray);
but once you examine it it's quite understandable. You're just passing an array to the jQuery autocomplete handler for further processing.
I'm not sure how previous versions of jQuery handled ajax autocomplete but this is how version 1.8.0 (and up) handles it.
What i am trying to do is to get the value of the selected elements by jquery selection. After that, those value are post to php script via ajax and then retrieve the data from the database and display it on the same page (something called autocompete).
var marvalue=$("input[name=m_status]:checked").val();
var fromhvalue=$("#fromheight").val();
var tohvalue=$("#toheight").val();
var value = $("#edu_det1").val();
alert (value);
var regvalue = $("#religion").val();
alert (regvalue);
var occvalue = $("#occupation").val();
alert (occvalue);
var convalue = $("#country").val();
alert (convalue);
Alert is there to check the correct values. As you see the code above this will get the values from the different input elements.
Below is the code i used to post to php
/*
$.post("regsearch.php", {queryString: ""+value+"",queryString1: ""+marvalue+"",queryStringfage: ""+fage+"",queryStringtage: ""+tage+""+queryStringfromh: ""+fromhvalue+""+queryStringtoh: ""+tohvalue+""+}, function(data) { // Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
*/
The problem :
when the comment is removed nor the alert popup and neither the result displayed. Ok about the result as no query is posted.
Major part is that when i use the below code which hold only m_status and edu_det1 it works.
marvalue=$("input[name=m_status]:checked").val();
alert (marvalue);
var value = $("#edu_det1").val();
alert (value);
The post code for above is
$.post("regsearch.php", {
queryString: ""+value+"",
queryString1: ""+marvalue+"",
queryStringfage: ""+fage+"",queryStringtage: ""+tage+""
}, function(data) {
// Do an AJAX call
$('#suggestions').fadeIn(); // Show the suggestions box
$('#suggestions').html(data); // Fill the suggestions box
});
The code for age and it verification is not added here. What is the problem and how to sort this out?
It will be better if you use jquery serialize() function. This will make your life easier to work with forms.
var querstring = $(form).serialize();
above will help
I guess using ajax post jQuery.ajax() will do the same thing and you can even serialize the fields in your page.
http://api.jquery.com/jQuery.ajax/#jQuery-ajax-settings
I have done similar type of code
UserName is the field Which I am passing
var data = $('#Username').serialize();
$('#usernameCheck').empty();
if (!$("form").validate().element("#Username"))
return;
$.ajax({
url: '/SignUp/CheckUsername',
type: 'POST',
data: data,
async: true,
success: function (result) {
if (result == 1) {
$('#usernameCheck').html('<font color=green>Username available</font>');
usernameOK = true;
}
else if (result == 2) {
$('#usernameCheck').html('<font color=red>Username not available</font>');
usernameOK = false;
}
else {
$('#usernameCheck').empty();
usernameOK = false;
}
}
});
First of all you should use your console to see Javascript errors, as I'm sure this will generate some. For example that querystring is undefined.
I'd also console.log instead of alert, it is less annoying and more informative.
Then: you dont need to use f.e. ""+marvalue+"" - just use marvalue. On the other hand f.e. queryString should be quoted...
$.post("regsearch.php", {'queryString':value,'queryString1': marvalue,'queryStringfage':fage,'queryStringtage':tage,'queryStringfromh': fromhvalue,'queryStringtoh':tohvalue}, function(data) {
$('#suggestions').fadeIn();
$('#suggestions').html(data);
});
In our MVC application we use jQuery autocomplete control on several pages. This works fine on Create, but I can't make it work on Edit.
Effectively, I don't know how to make the autocomplete controls preload the data from model and still behave as an autocomplete in case the user wants to change the value.
Also how can I make sure that the value is displayed in the same format that is used in Create calls?
All our autocomplete controls have corresponding controllers and all parse Json results.
Let's Try this! Alright Do this:
Suppose you had a list of countries you needed to filter
Auto Complete knows how to some default things by default but suppose you really wanted CountryName and also you know every keypress does an ajax call to the URL you specify.
Create an action method like so:
public ActionResult LookupCountry(string q, int limit)
{
var list = GetListOfCountries(q, 0, limit);
var data = from s in list select new {s.CountryName};
return Json(data);
}
Here is the Jquery:
$(document).ready( function() {
$('#txtCountryName').autocomplete('<%=Url.Action("LookupCountry", "MyController") %>', {
dataType: 'json',
parse: function(data) {
var rows = new Array();
for(var i=0; i<data.length; i++){
rows[i] = { data:data[i], value:data[i].CountryName, result:data[i].CountryName};
}
return rows;
},
formatItem: function(row, i, n) {
return row.CountryName;
},
width: 300,
mustMatch: true,
});
});
Here is the Html
<html><head></head><body>#Html.TextBox("txtCountryName",Model.CountryName)</body></html>
Basically, The magic is in the call to LookUpCountry
The GetCountriesList(string query, int startindex, int limit)
Returns MyCountries.Where(c => c.CountryName.SubString(startindex, limit).Contains(query)).ToList();
So you are making your own trimming function because JQuery has no idea what CountryName is or how to trim it. How ever if it was a javascript object I am not quite sure but do
var jsonString = #Html.GetListOfCountries() //Or Model.Countries.ToJSONString()
var json = JSON.stringify(jsonString); //also JSON.Parse(jsonString) if stringify won't work
which would return the necessary countries as a Html Helper Extension method. And perhaps as a list of javascript objects it would be smart enough to handle it that way in it's native language. However the first approach works for me.