I have an MVC blog app that makes a call to Ajax for updating a flag.
In IE (and only in IE, in other browsers it runs fine), I can call an ActionLink only once. If I click after the first time, the ajax action in the controller is not invoked.
Here is the partial part of code of the View:
<div id="news_comment_state_#(Model.Id)">#(Model.FlControlled==false?"Da approvare":#Model.FlApproved?"Approvato":"Respinto")</div>
#Ajax.ActionLink("Approva", "ApproveDenyComment", new { IdComment = Model.Id, ApproveDeny = true }, new AjaxOptions { UpdateTargetId = "news_comment_state_"+#Model.Id})
<br />
#Ajax.ActionLink("Respingi", "ApproveDenyComment", new { IdComment = Model.Id, ApproveDeny = false }, new AjaxOptions { UpdateTargetId = "news_comment_state_"+#Model.Id})
If I put a breakpoint in the controller it is fired only once per Link, then it is never called again. Where is the error? Maybe cache problem?
Another way to avoid the caching problem is to add the following to the line above your method in the controller:
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult MyMethod() {
...
}
This will make sure it runs the server-side code.
Sounds like cache. Add a random integer to the end to make sure you get a fresh request.
Related
I am having some difficulties using quote marks in ASP.Net Razer view as I keep ending up with them replaced with '
If I for example type:
#{string test = "String 'with' quotes"}
#test
I end up with:
String 'with' quotes
In the above example this is desirable.
However, take this second example:
#{string myJSFunction = myJSFunction('myString')"}
#myJSFunction
I end up with:
myJSFunction('myString')
Which results in a broken javascript function.
I have tried excaping the quote marks with \, but they don't seem to be having any effect.
Here is the actual problem I am faced with:
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = #myJSFunction
}))
Any advice?
The # operator always HTML-encodes strings. If you want the raw string value, use #Html.Raw(myJSFunction).
In razor, # will encode and render. Try Html.Raw method. This method returns markup that is not HTML encoded.
#Html.Raw(myJSFunction)
So if you want to execute the function in a script block, you can do it like
#{string myJSFunction = "alert('Rise and Shine')";}
<script type="text/javascript">
#Html.Raw(myJSFunction)
</script>
The solution to your issue is already mentioned (Html.Raw()) but I'm not sure why you're using # in your code sample given. From the looks of it you're already in code block when you try to assign it, so why use the razor.
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = #myJSFunction
}))
should be
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = myJSFunction
}))
# is what tells the StreamWriter for the page to write the result to the response, and as such is intended to be injected into the page after HtmlEncoding. Using Html.Raw bypasses the Html encoding aspect but in your case you're not writing it the page directly yourself, you're letting Html.BeginForm handle that, so you don't need the # in the assignment of your OnComplete function.
UPDATE: Ok, another thing I forgot to mention is that the methods passed to the AjaxOptions are Javascript functions only, no parameters by the looks of it. Parameters are passed in automatically by the Unobtrusive scripts that handle all the wiring. So your form should look like this...
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new { id = ViewBag.InputResourceID },
new AjaxOptions {
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = "myJSFunction"
}))
And it will handle the rest. If you need to pass additional parameters in the myJSFunction function, you're probably going to have to expose them via other means. Either as a javascript variable or by associating it with some other element and access it using $("elementselector").data("dataAttributeName") (this is my preferred and suggested method). One of the common requested modifications made to the unobtrusive ajax JavaScript libraries (I wish Microsoft would just adopt this change and be done with it) is to set the context of this to the element that triggered the ajax event. So for in this case it would make this equal to the form element. With all this in mind, here's my recommendation.
First:
Modify your Unobtrusive Ajax script file so that the source element gets assigned to the this keyword so that's it's available in your JavaScript handling the unobtrusive events.
This question outlines what it involves (one line added to the file)
Second:
Add your string to one of the data attributes on your form
#using (Ajax.BeginForm(
"_MonthRanges",
"Projects",
new {id = ViewBag.InputResourceID},
new AjaxOptions
{
HttpMethod = "POST",
UpdateTargetId = "MonthRanges",
InsertionMode = InsertionMode.Replace,
OnComplete = "myJSFunction"
},
new { data_parameter_name = "myString" }))
Third:
Access your parameter from inside of the javascriptfunction handling your event.
<script>
function myJSFunction(data, textStatus, jqXHR)
{
//data, textStatus and jqXHR are set for you by the unobtrusive ajax script file automatically, feel free to use them
var parameter = $(this).data("parameterName");
alert(parameter);
}
</script>
I have the following issue.
My url structure is like this:
/people/edit/usercode
In my controller i have the following:
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult LoanRefresh(string id)
{
PeopleModel p = new PeopleModel();
return PartialView("_LoanHistory", p.getPersonLoanHistory(id));
}
In my view i have:
#Ajax.ActionLink("Refresh", "LoanRefresh", new { id = Model.IdentityCode }, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "loanHistory", LoadingElementId = "Loading" }, new { #class = "button" })
and
<div id="loanHistory">
#Html.Partial("_LoanHistory", Model.Loans)
</div>
When run the Ajax.ActionLink it gets the data back ok and it updates the div, but the url of the sort links on the webgrid then change their address to:
/People/LoanRefresh/AFU0006?sort=CreatedOn&sortdir=ASC
i need to stay as:
/People/Edit/AFU0006?sort=CreatedOn&sortdir=ASC
Any help would be greatly appreciated.
Well #Nick, that's because your action name is LoanRefresh and not Refresh. To do that you will probably have to do some routing or even redirect your LoanRefresh results to an action named Refresh.
Try setting ajaxUpdateContainerId to an object that is specified in the partial view, rather than an object in the view from which the partial view is originally called. The sort URLs should work correctly then.
I have a code block in my MVC view as follows:
<%using (Ajax.BeginForm("MyAction", new { action = "MyAction", controller = "Home", id = ViewData["selected"].ToString() }, new AjaxOptions { UpdateTargetId = "Div1" }))
{ %>
<%=Html.DropDownList("ddl", ViewData["MyList"] as SelectList, new { onchange = "this.form.submit()" })%>
<%} %>
I want to set the value of ViewData["selected"] so that i can send it to the desired action.
Can anyone please suggest how can i do this?
thanks!
Instead of using a form, why not use a jQuery onChange event on your drop down?
$(document).ready(function() {
$("#ddl").change(function() {
var strSelected = "";
$("#ddl option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Home/MyAction/" + strSelected;
$.post(url, function(data) {
// do something if necessary
});
});
});
ViewData is not the place to pass data back to the server side. Values of html input controls within form tag are conveniently available in action method. You can get these values either from various types of action method arguments (model, formcollection etc).
Here is a link to free asp.net mvc ebook tutorial. Is a good resource for asp.net mvc.
Found solution at this post it is just small chnge
Yes, that’s right – only change is replacing:
onchange = “this.form.submit();”
with:
onchange = “$(this.form).submit();”
I dont think i quite get the Ajax functions in mvc, because i get this wierd problem.
I got the following code which makes my ajax call, it is placed in a partial view with a productList:
<% using(Ajax.BeginForm("AddToBasket", "Basket",
new { productID = item.Id },
new AjaxOptions { HttpMethod = "Post", UpdateTargetId = "Basket", OnSuccess = "productAdded(" + item.Id + ")" })) { %>
<input type="image" src="/Content/addToCart.png" />
<% } %>
I have a <div id="Basket"></div> on my masterpage
And this method in BasketController, which returns a partial view that is found in Basket/BasketList.ascx:
[HttpPost]
public ActionResult AddToBasket(int productID)
{
// DO STUFF
return PartialView("BasketList");
}
When i am logged in using the default asp.net membership it all works fine, it updates the basket and it is all async, but when i am logged out and is clicking the addToCart, it redirects me to Basket/AddToBasket?productID=1, which is a partial view.
Does anyone know why this happens?
I have a similar problem with an ajax.actionlink
<%= Ajax.ActionLink("Gem", "SaveBasket", "Basket", new AjaxOptions { HttpMethod = "Post" })%>
where it says "The resource cannot be found." when it should fire, which is placed in the BasketController
[HttpPost]
public void SaveBasket()
{
// DO STUFF
}
It sounds like you have a javascript error somewhere that is blocking the AJAX stuff that should be happening. Can't say why that would only happen when logged out though.
Do you have any errors in the error console/firebug?
Are you sure all your pages are including the Microsoft Ajax libraries? And in the correct order?
I'm trying to clear an ajax form after an item has been added to the database however the OnComplete and OnSuccess AjaxOptions get called before the form is submitted. How can I get it so the form is submitted first and the the OnComplete is called.
<% using (Ajax.BeginForm("AddTable", new AjaxOptions
{
UpdateTargetId = "tables",
InsertionMode = InsertionMode.InsertAfter,
OnComplete = "ClearForm()"
}))
{%>
which calls
function ClearForm() {
$('#DisplayName').val('');
}
However the DisplayName textbox is cleared before the balue is sent to the controller the form submits to. Is there a way around this.
OnComplete = "ClearForm()" should be called without the parentheses, i.e. OnComplete = "ClearForm". I can't say for sure that it would fix your issue though.