Ok, so .load() uses...
The POST method is used if data is
provided as an object; otherwise, GET
is assumed.
I have the following...
// an array of itemIds
var items = $selected.map(function() {
return $(this).find('.item').text();
}).get();
// post the data
$container.load(
_url,
$.param(data, true),
function(response, status, xhr) {
//...
}
);
The problem I have is that if I use $.param to serialise the data, it seems that GET is used.
If I don't use $.param then POST is used but I run into the problem again with the array not being serialised correctly and I don't receive the data in my controller.
Is there an easy way around this?
You can use jQuery.get() instead of .load():
$.get(_url, $.param(data, true), function(data) {
$container.html(data);
});
This will have the same effect as a call to load with parameters, but with a GET request instead of a POST request.
Related
One of my multi-steps Zaps has a Zapier.Webhook-GET as a step 2.
Step 3 is Zapier.RunScript-Javascript.
I canĀ“t figure out a way to set up that intire JSON object resulted from step 2 as the input variable required for step 3. The list of options shows only children and nested fields, but I need to take the object from the root.
I don't believe Zapier will allow that, specifically.
Here's an alternative that may work perfectly: Put the GET in the step 3 script and use fetch!
Here's an example:
//Put in your url with querystring
var url = "https://somewhere.com/rest?para1=value1";
//Add the method and headers here
fetch(url, {method: "GET", headers: {"Content-Type": "application/json"}})
.then(function (response) {
console.log(response);
return response.json();
}).then(function (data) {
//This is the entire JSON. Put your code here
// Remember to do a callback! Do not set to "output"
console.log(data);
//This will return data as output
callback(null, data);
});
//Code here will execute BEFORE code within the then functions because it's asynchronus
See this link for more on fetch: https://github.com/bitinn/node-fetch/tree/32b60634434a63865ea3f79edb33d17e40876c9f#usage
Hope this helps!
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.
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;
}
}
});
I need to show user all autocomplete choices, no matter what text he already wrote in the field? Maybe i need some other plugin?
$('#addressSearch').autocomplete("search", "");
That doesn't work.
There are two scenarios:
You're using a local data source. This is easy to accomplish in that case:
var src = ['JavaScript', 'C++', 'C#', 'Java', 'COBOL'];
$("#auto").autocomplete({
source: function (request, response) {
response(src);
}
});
You're using a remote data source.
$("#auto").autocomplete({
source: function (request, response) {
// Make AJAX call, but don't filter the results on the server.
$.get("/foo", function (results) {
response(results);
});
}
});
Either way you need to pass a function to the source argument and avoid filtering the results.
Here's an example with a local data source: http://jsfiddle.net/andrewwhitaker/e9t5Y/
You can set the minLength option to 0, then it should work.
I built an ajax chat in one of my mvc website. everything is working fine. I am using polling. At certain interval i am using $.post to get the messages from the db. But there is a problem. The message retrieved using $.post keeps on repeating. here is my javascript code and controller method.
var t;
function GetMessages() {
var LastMsgRec = $("#hdnLastMsgRec").val();
var RoomId = $("#hdnRoomId").val();
//Get all the messages associated with this roomId
$.post("/Chat/GetMessages", { roomId: RoomId, lastRecMsg: LastMsgRec }, function(Data) {
if (Data.Messages.length != 0) {
$("#messagesCont").append(Data.Messages);
if (Data.newUser.length != 0)
$("#usersUl").append(Data.newUser);
$("#messagesCont").attr({ scrollTop: $("#messagesCont").attr("scrollHeight") - $('#messagesCont').height() });
$("#userListCont").attr({ scrollTop: $("#userListCont").attr("scrollHeight") - $('#userListCont').height() });
}
else {
}
$("#hdnLastMsgRec").val(Data.LastMsgRec);
}, "json");
t = setTimeout("GetMessages()", 3000);
}
and here is my controller method to get the data:
public JsonResult GetMessages(int roomId,DateTime lastRecMsg)
{
StringBuilder messagesSb = new StringBuilder();
StringBuilder newUserSb = new StringBuilder();
List<Message> msgs = (dc.Messages).Where(m => m.RoomID == roomId && m.TimeStamp > lastRecMsg).ToList();
if (msgs.Count == 0)
{
return Json(new { Messages = "", LastMsgRec = System.DateTime.Now.ToString() });
}
foreach (Message item in msgs)
{
messagesSb.Append(string.Format(messageTemplate,item.User.Username,item.Text));
if (item.Text == "Just logged in!")
newUserSb.Append(string.Format(newUserTemplate,item.User.Username));
}
return Json(new {Messages = messagesSb.ToString(),LastMsgRec = System.DateTime.Now.ToString(),newUser = newUserSb.ToString().Length == 0 ?"":newUserSb.ToString()});
}
Everything is working absloutely perfect. But i some messages getting repeated. The first time page loads i am retrieving the data and call GetMessages() function. I am loading the value of field hdnLastMsgRec the first time page loads and after the value for this field are set by the javascript.
I think the message keeps on repeating because of asynchronous calls. I don't know, may be you guys can help me solve this.
or you can suggest better way to implement this.
Kaivalya is correct about the caching, but I'd also suggest that your design could and should be altered just a tad.
I made a very similar app recently, and what I found was that my design was greatly enhanced by letting the controllers work with the fairly standard PRG pattern (post-redirect-get). Why enhanced? well, because POST methods are built to add stuff to an app, GET methods are supposed to be used to get information without side effects. Your polling should be just getting new messages w/o side effects.
So rather than your $.post call expecting data and handling the callback, what I'd recommend is having your controller expose a method for creating new chat messages via POST and then another method that get the last X chat messages, or the messages since a certain timestamp or whatever.
The javascript callback from the post action, then can update some variables (e.g. the last message id, timestamp of the last message, or even the whole URL of the next message based on the info contained in a redirect, whatever).
The $.post would fire only in response to user input (e..g type in a box, hit 'send') Then, you have (separately) a $.get call from jquery that's set up to poll like you said, and all it does is fetch the latest chat messages and it's callback updates the chat UI with them.
I got my answer here: ASP.NET AJAX CHAT
The names below i am referring to are from above link.
i think the actual problem was with the timestamp thing and asynchronous behaviour of $.post. after calling "GetMessages()" method, even if the previous request to retrive chat message was not complete anathor call to same method used to fire due to setting timeout for "GetMessages()" method outside the $.post method. In my question you can see that timeout for "GetMessages()" method is set outside the $.post method. Now i set the timeout for "GetMessages()" method inside the $.post method. so that next call to "GetMessages()" only occur after 3 seconds of completion of current $.post method. I have posted the code below.
var t;
function GetMessages() {
var LastMsgRec = $("#hdnLastMsgRec").val();
var RoomId = $("#hdnRoomId").val();
//Get all the messages associated with this roomId
$.post("/Chat/GetMessages", { roomId: RoomId, lastRecMsg: LastMsgRec }, function(Data) {
if (Data.LastMsgRec.length != 0)
$("#hdnLastMsgRec").val(Data.LastMsgRec);
if (Data.Messages.length != 0) {
$("#messagesCont").append(Data.Messages);
if (Data.newUser.length != 0)
$("#usersUl").append(Data.newUser);
$("#messagesCont").attr({ scrollTop: $("#messagesCont").attr("scrollHeight") - $('#messagesCont').height() });
$("#userListCont").attr({ scrollTop: $("#userListCont").attr("scrollHeight") - $('#userListCont').height() });
}
else {
}
t = setTimeout("GetMessages()", 3000);
}, "json");
}
I addition to that i also changed few things. As suggested by ignatandrei i placed $("#hdnLastMsgRec").val(Data.LastMsgRec); immediately after function(Data) {.
and also
as said by MikeSW i changed the data retrieval process. Previously i was extracting data on the basis of timespan(retrieve all the data associated with
this room id that has greater timespan than last data retrieved message timespan) but now i keep track of the messageid. Now i retrieve only those data that
has message id greater than last retrieved message id.
and guess what no repeataion and perfectly working chat application so far on my intranet.
I still got to see it's performance when deployed on internet.
i think it solved my problem.
i will still test the system and let u guys know if there is any problem.
By default $.post() caches the results
You can either call $.ajaxSetup ({ cache: false}); before JS GetMessages function call to ensure caching is disabled or change the $.post to $.ajax and set cache attribute to false. In the end $.post() is a short cut to this:
$.ajax({
type: 'POST',
url: url,
data: data,
success: success
dataType: dataType
});