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.
Related
I am still having issues. I think what I am trying to do is simple. I have a viewbag droplist - which is working fine. I just want to redirect on selection it redirect just like: #Html.ActionLink("Branch", "Employees", new { Branch = item.Branch }) | (but with the selection from the droplist) Should this be difficult?
#Html.DropDownList("Branches", ViewBag.Branches as SelectList, "Select a Branch", new { #id = "ddlBranch" })
<script>
$(function () {
$("#ddlBranch").on("change", function () {
var deptId = $(this).val();
var routeVal = { Id: deptId };
var url = '#Url.Action("Department", "Home")';
$.ajax({
url: url,
type: 'POST',
data: routeVal
}).done(function (result) {
window.location.href = result.newUrl;
})
})
})
</script>
From a comment on the question above:
So now I just need to redirect to: #Html.ActionLink("Branch", "Employees", new { Branch = item.Branch }) but Item.Branch would be $(this).val(). Can this be done?
There may be a more elegant way, but an approach I've always taken is something like this:
let url = '#Html.ActionLink("Branch", "Employees", new { Branch = "REPLACEME" })';
url = url.replace('REPLACEME', $(this).val());
window.location.href = url;
On the client-side this turns into something like:
let url = '/Brand/Employees?Branch=REPLACEME';
url = url.replace('REPLACEME', encodeURIComponent($(this).val()));
window.location.href = url;
Which would look silly to anybody examining only the client-side code, I'm sure. But since the Branch parameter might be in the query string or might be in the route, and since it's the ASP.NET MVC Framework's responsibility to manage that, generating the URL and putting the client-side value into the URL are two separate responsibilities here.
So we use the server-side code to generate the URL with a placeholder (can be any string, "REPLACEME" was an arbitrary choice) and then use the client-side code to dynamically replace that placeholder with the desired value.
This essentially replaces whatever you're trying to do with AJAX in the original question. Unless you need to invoke a server-side operation to get a result not known to the client-side code in order to build the URL, you can just omit the AJAX entirely and build the URL directly.
I want to give dynamic action name in Url.action through javascript.
// I want to change Index name by dynamic
$.ajax({
url: '#Url.Action("Index", "Home")',
type: "Post",
data: { Surveyid: surveyid, Category: catcode },
success: function (data) {
window.location.href = data.Url
}
like
var x="xxxx";
#Url.Action(x,"Home") -> not working throws error
#Url.Action(x.toString(),"Home") -> not working
then how can i ?
Url.Action is server generated, whereas it seems you want to change the action on the browser. What you can do is tokenize the Action, get Url.Action to generate the tokenized URL, and then substitute this in js:
var jsUrl = '#Url.Action("##", "Home")'; // ## is the token
$.ajax({
url: jsUrl.replace('##', someDynamicAction),
...
(You may need to do the same for the controller)
Edit
My conscience has gotten the better of me - doing this isn't a good idea, given that any invalid action name (or a change in the Controller or Action names) will only be picked up at run time e.g. with 404 errors.
The number of controllers and actions that you need to ajax to should be finite, and T4MVC has already solved this kind of issue.
You can create the urls to the various links:
var urlToIndex = '#Url.Action(MyControllerAssembly.Index.Home())))';
var urlToOtherAction = ...
... etc for all actions needed in the 'switch' for ajax call.
and then choose the appropriate URL for your ajax call. (T4MVC also has methods Url.JavaScriptReplacableUrl and Ajax.ActionLink although for slightly different scenarios)
Best way to use urls in your mvc application is that you define a global app_url in layout page like following:
_Layout.cshtml
<script>
var app_root = '#Url.Content("~/")';
</script>
and use in content page
any_page that inherited from _Layout.cshtml
$.ajax({
url: app_root + 'Home/Index', // or url: app_root + 'Home/' + x
something odd in your example, but I believe what you are trying to do is this
function axajThis(numberthing,path) {
var newUrl = "htttp://somplace/"+path;
/* and what ever the number x is doing */
$.ajax({
url: newUrl,
type: "Post",
data: ....
});
};
}
axajThis(x,"Home");
Little more info needed on what 'x' is.
I'm trying to use the jquery ui spinner on forms dynamically inserted through ajax calls.
To handle ajax calls I'm relying on ajaxy.
On success I call this function like so:
response: function(){
var Ajaxy = $.Ajaxy; var data = this.State.Response.data; var state = this.state;
var State = this.State;
var Action = this;
Action.documentReady($content);
updater(); // THE FUNCTION TO BIND NEW ELEMENTS
return true;
},
Here's the function
function updater(){
$('.spin').spinner();
}
And this works without any problem. But then When I call that same function on "normal" jquery requests (not ajaxy ones), it doesn't work anymore:
$.ajax({
type: "GET",
url: url,
cache: false,
dataType:"json",
success: function(res) {
updateTarget(res,target,animation);
updater();
}
}
});
I really don't see why in one case it is working, while in the other it isn't...
I've figured it out... My error was that I was running updater() after updateTarget(res,target,animation);, which is the function that analyses the json response and attach html elements to the page, while I must run updater() inside updateTarget(res,target,animation); right after the attachment to the page through .html().
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']);
Im trying to create an ajax (post) event that will populate a table in a div on button click.
I have a list of groups, when you click on a group, I would like the table to "disappear" and the members that belong to that group to "appear".
My problem comes up when using jQuery's .ajax...
When I click on the button, it is looking for a controller that doesnt exist, and a controller that is NOT referenced. I am, however, using AREAS (MVC2), and the area is named Member_Select where the controller is named MemberSelect. When I click on the button, I get a 404 stating it cannot find the controller Member_Select. I have examined the link button and it is set to Member_Select when clicked on, but here's the ajax call:
$.ajax({
type: "POST",
url: '/MemberSelect/GetMembersFromGroup',
success: function(html) { $("#groupResults").html(html); }
});
I havent been able to find any examples/help online.
Any thoughts/suggestions/hints would be greatly appreciated.
Thanks!
Have you tried navigating to /MemberSelect/GetMembersFromGroup to see what you get? - if it's 404'ing it's because the route can't be matched to a controller/ action.
I've not used the new areas functionality, but I'm not sure that the URL you've got is correct...I would have thought it would have been /AREANAME/MemberSelect/GetMembersFromGroup...but I could be wrong..!
When I did this, it worked fine. I didn't use POST and I don't know what AREAS means.
$("#item").autocomplete({
source: function(req, responseFn) {
addMessage("search on: '" + req.term + "'<br/>", true);
$.ajax({
url : ajaxUrlBase1 + "GetMatchedCities/" + req.term,
cache : false,
type : "GET", // http method
success : function(msg){
// ajax call has returned
var result = msg;
var a = [];
if (result !== null){
for(var i=0; i < result.length; i++) {
a.push({label: result[i].prop1, id: result[i].prop2});
}
}
responseFn(a);
}
});
}
});
Use:
area_name/controller_name/action_name
Instead of doing $.ajax I would use jQuery Form Plugin.
and have my form set as:
Html.BeginForm("Index","AdminArea/Admin",FormMethod.Post,
new { id="form-user", name="form-user"})
To use jQuery Form Plugin have a look here:
http://arturito.net/2010/12/02/asp-net-mvc2-jquery-form-post-tutorial/
You cold save your url in a Hidden Form element in (Html.HiddenForm()) and use the #id javascript operator to retrieve it. Just found this out today.