.NET MVC Ajax Form - How do you hide it? - asp.net-mvc

Ok, everything is 'functionally' working with what I am attempting to accomplish and once again, I am sure this is something dumb, but I cannot figure out how to do this one thing.
I have an edit form for an entity, lets say a car. This 'car' can have 0 - many passengers. So on my edit form, I have all the fields for the car, then a list view showing each passenger (partial). I also have a 'add new passenger' button that will render a new partial view that allows you to enter a passenger. This has a cancel link and an add button to submit an Ajax form. When you add a passenger, the passenger is automatically added to the list, but I need the enter passenger form to go away. I have tried using the onSuccess and onComplete functions to hide the div that the form is in, but both render just the partial view HTML elements (white screen, text) and not the partialView in the context of the entire page.
Sources:
1) Main Edit View
<script type="text/javascript">
Function hideForm(){
document.getElementById('newPassenger').style.display = 'none';
}
</script>
<h2>Edit</h2>
<%-- The following line works around an ASP.NET compiler warning --%>
<%= ""%>
<%Html.RenderPartial("EditCar", Model)%>
<h2>Passengers for this car</h2>
<%=Ajax.ActionLink("Add New Passenger", "AddPassenger", New With {.ID = Model.carID}, New AjaxOptions With {.UpdateTargetId = "newPassenger", .InsertionMode = InsertionMode.Replace})%>
<div id="newPassenger"></div>
<div id="passengerList">
<%Html.RenderPartial("passengerList", Model.Passengers)%>
</div>
<div>
<%= Html.ActionLink("Back to List", "Index") %>
</div>
2) AddPassenger View. The cancel link below is an action that returns nothing, thus removing the information in the div.
<% Using Ajax.BeginForm("AddPassengerToCar", New With {.id = ViewData("carID")}, New AjaxOptions With {.OnSuccess = "hideForm()", .UpdateTargetId = "passengerList", .InsertionMode = InsertionMode.Replace})%>
<%=Html.DropDownList("Passengers")%>
<input type="submit" value="Add" />
<%=Ajax.ActionLink("Cancel", "CancelAddControl", _
New AjaxOptions With {.UpdateTargetId = "newPassenger", .InsertionMode = InsertionMode.Replace})%><% end using %>

Ok - figured this out, I suppose it was getting too late last night. So, here is the answer, it actually turned out to be a few small issues culminating into one.
Function hideForm() in the javascript should be function hideForm(), no capitals. Too used to writing controller functions I suppose.
I was using "hideForm()" in the OnSuccess attribute, not "hideForm" - doh.
You probably don't want to hide the div as when you click the add new passenger link again, the div won't display. Changed hideForm function to set the innerHTML property of the div to ''.
Thanks again darin for your assistance, I was trying to making more out of it than it turned out to be.

Make sure that you've referenced both the MicrosoftAjax.js and MicrosoftMvcAjax.js scripts in your page. The reason for getting the partial view contents (white screen, text) could be a script error which prevents the ajax from executing correctly. Look with FireBug if there are some errors during the execution.
As far as hiding the form is concerned you could use the OnSuccess callback:
<% Using Ajax.BeginForm("AddPassengerToCar",
New With { .id = ViewData("carID")},
New AjaxOptions With {
.UpdateTargetId = "passengerList",
.InsertionMode = InsertionMode.Replace,
.OnSuccess = "hideForm"
}) %>
The hideForm javascript function will be executed if the AJAX call succeeds and will hide the desired div.

Related

Can't get RedirectToaction to show completely new page using Ajax.BeginForm in MVC

Hoping someone can help me solve this issue.
I'm using Ajax.BeginForm quite often when I need to update a part of my actual webpage. But if I have a second button in the web form where I need go to a complete different page, and for example do a search and get some values that I need to complete the form. The page turns up in the update panel (updateTargetID) instead of in a complete new View. That is happening even id a do a RedirectToAction in the controller. Of course the ajax.beginform does what I accept it to do, in other words update the panel that shall be updated. But is there a way to get ajax.Beginform to use redirectToaction without updating when the user is choosing to do for example a search instead of sending the form?
I'm working with asp.net MVC,
Problem;
<% using (Ajax.BeginForm(new AjaxOptions() { LoadingElementId = "loadingElement", UpdateTargetId = "SearchResult", InsertionMode = InsertionMode.Replace}))
{%>
<% Html.RenderPartial("Searchfields", Model); %>
<div>
<%:Html.ActionLink("blank", "Index")%>
</div>
<div id="loadingElement" style="display: none">
Load data...
</div>
<div id="SearchResult">
<% if (Model.SearchResult != null)
{
Html.RenderPartial("SearchResult", Model.SearchResult);
} %>
</div>
<% } %>
In the controller (post) I do this among other stuff;
if (Request.IsAjaxRequest())
{
return PartialView("SearchResult", data.SearchResult);
}
But before this I need to do:
if (data.SearchResult.Count() == 1)
{
return RedirectToAction("Edit", "Person", new { Id = data.SearchResult.First).Id});
}
but ofcourse if I do that the hole page i rendered in the corresponding updateTargetId,
I need to render a new view instead. So how can I for exampel use javascript to redirect oncomplete and have the values from the model sent to the script to for exampel do a window.location.replace?
I'm struggling with javascript, so please help me!

Click event is launching only once

I have a form in which I have many checkboxes. I need to post the data to the controller upon any checkbox checked or unchecked, i.e a click on a checbox must post to the controller, and there is no submit button. What will be the bet method in this case? I have though of Ajax.BeginForm and have the codes below. The problem im having is that the checkbox click event is being detected only once and after that the click event isnt being launched. Why is that so? How can I correct that?
<% using (Ajax.BeginForm("Edit", new AjaxOptions { UpdateTargetId = "tests"}))
{%>
<div id="tests">
<%Html.RenderPartial("Details", Model); %>
</div>
<input type="submit" value="Save" style="Visibility:hidden" id="btnSubmit"/>
<%}
%>
$(function() {
$('input:checkbox').click(function() {
$('#btnSubmit').click();
});
});
Try $('#myForm').submit().
Check this post out. I think you need to use the each keyword and bind so that binding is done everytime.
As a debugging step, try doing something else during the click event, like
$('input:checkbox').click(function() {
$('#debugDiv').append('click event fired at ' + new Date().toString());
});
to see if the issue has something to do with the form submission.
Something else you can try is using jQuery's live function instead of click: http://api.jquery.com/live/

Self-AJAX-updating partial-view/controller in ASP.Net MVC and the duplicating div

I have a partial view in MVC that goes something like:
<div id="comments">
...
</div>
Inside that div there's a form that calls a controller using AJAX and gets back that same partial view. The problem is that the results of calling the view replaces the contents of the div, not the whole div, and I end up with:
<div id="comments">
<div id="comments">
...
</div>
</div>
The only solution I can think about with my week of experience in ASP.Net MVC and AJAX is to put the div outside the partial view and make the partial view only contain the inside part, but then the form would refer to an id outside the view where the form is located breaking the little encapsulation I have left there. Is there any better solution?
The unobtrusive Ajax library that ships with .NET MVC 3 uses callbacks that are based on the four callbacks from jQuery.ajax. However, the InsertionMode = InsertionMode.Replace from the Ajax.BeginForm method does not result in jQuery's replaceWith being called. Instead, .html(data) is used to replace the contents of the target element (and not the element itself).
I have described a solution to this problem on my blog:
http://buildingwebapps.blogspot.com/2011/11/jquerys-replacewith-and-using-it-to.html
Are you using an AjaxHelper.Form or jQuery. If you are using jQuery, have you tried using replaceWith()? Using AjaxHelper are you using AjaxOptions { InsertionMode = InsertionMode.Replace }? I would think that using either you would be able to replace the entire DIV with the results from the partial view.
Using
AjaxOptions { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace }
should replace the whole content of '#myDiv' element, as tvanfosson says. Your problem is where is '#myDiv' located. Here's an example:
<div id="myDiv">
<% Html.RenderPartial("MyPartialView"); %>
</div>
where MyPartialView is:
<div id="comments">
<% using (Ajax.BeginForm(new AjaxOptions() { UpdateTargetId = "myDiv", InsertionMode = InsertionMode.Replace } )) {%>
...
<input type="submit" value="Submit comment" />
<% } %>
</div>
If you include '#myDiv' div inside the partial view, it will be rendered right after receiving the response (together with its content), and then it's content will be replace with the response which is the same partial view (including its own '#myDiv' div), and that's why you always end up with 2 nested divs.
You should always use a container for your partial views and then set the UpdateTargetId to the container id.
Edit: I updated the code to represent the exact situation you describe in your question.
I had this same problem in Asp.Net MVC 5.
I did not want the PartialView to have some knowledge about what div it might be contained within, so I did not accept that work around.
Then, I noticed the other answers referring to ReplaceWith and found the simple solution:
InsertionMode = InsertionMode.ReplaceWith
Now, the mvc partial view can completely replace itself with the ajax helpers without having any dependencies on names outside itself.
Your should try with jQuery too (from my answer on MS MVC form AJAXifying techniques):
<script type="text/javascript">
$(document).ready(function() {
ajaxify($('div#comments'));
});
function ajaxify(divWithForm) {
var form = $('form', divWithForm);
$(':submit', form).click(function (event) {
event.preventDefault();
$.post(form.attr('action'), form.serialize(),
function(data, status) {
if(status == 'success') {
var newDivWithForm = $(data);
ajaxify(newDivWithForm);
divWithForm.after(newDivWithForm).remove();
}
}
);
});
}
</script>
Did you solved the problem? I had the same issue but I found this:
http://buildingwebapps.blogspot.ro/2011/11/jquerys-replacewith-and-using-it-to.html
I hope it helps you.

asp.net MVC Ajax Request Not Firing Correctly

I cannot figure out why this Ajax request is not firing correctly. For simplicity's sake I've been trying to implement Ajax request using this tutorial. However I cannot get my controller to recognize the request as being so. I've tried placing the Ajax.ActionLink within the div to be updated (outside of it here).
Using the Response.Write to place the Datetime, the one within the Div does get updated, whilst the one outside of the target div does not (as expected). I'm not all too familiar with how the MS Ajax library works, but on the surface it seems to be updating the right section of the page, but my controller won't recognize the request type, and therefore outputs the incorrect information.
...
<script src="../../Scripts/MicrosoftAjax.js" type="text/javascript"></script>
<script src="../../Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>
<script src="../../Scripts/jquery-1.2.6.min.js" type="text/javascript"></script>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<div class="chart" id="divChart">
<% Html.RenderPartial("GraphView", Model); %>
<br />
<% Response.Write(DateTime.Now); %>
<br />
</div>
<%= Ajax.ActionLink("no parameters", "MyWorkouts", new AjaxOptions{ UpdateTargetId = "divChart"}) %>
<%= Ajax.ActionLink("id parameter", "MyWorkouts", new {chtype=1},new AjaxOptions { UpdateTargetId = "divChart", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
<%= Ajax.ActionLink("all parameters", "MyWorkouts", new {chtype=2, range=ViewData["daterangevalue"]},new AjaxOptions { UpdateTargetId = "divChart", OnBegin = "beginContactList", OnSuccess = "successContactList", OnFailure = "failureContactList" })%>
<br />
<% Response.Write(DateTime.Now); %>
<h2>
...
And then my ActionResult looks like so...
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult MyWorkouts(int? chtype, int? range) {
int dateRange = 3;
// do some stuff here - left out for readability
if (Request.IsAjaxRequest()) {
if (range != null) {
dateRange = (int)range;
}
}
//do some other stuff...
if (Request.IsAjaxRequest()) {
return PartialView("GraphView", workouts);
} else {
return View(workouts);
}
}
(Everything is pretty much default as this is just a test page to implement it once I have it figured out). As a result, I keep getting the full view inside of the targeted div.
It looks like you may be using an older version of MVC framework?
If so I recommend updating to the release version and ensuring that you are using the newest jquery and mvc scripts... There were some changes specifically in how the Request.IsAjaxRequest() method works that may be related to your problem.
Also, if there is a RedirectToAction call involved in there you might want to read about a similar problem here.
I'm not sure what the problem is but Fiddler and the RouteDebugger might help in debugging it.
It doesn't show in the snippet you have posted, but you most likely have form /form tags. These are interfering with the Ajax.BeginForm which generates the form tags as well. Once you remove the outer form tags, the Request.IsAjaxRequest will return true.

How to prevent auto filling posted values in asp.net mvc ajax form

Inside of an asp.net mvc partial view, I have an Ajax form that posts a value and replaces the contents of its parent container with another instance of the form.
Index.aspx view:
<div id="tags">
<% Html.RenderPartial("Tags", Model); %>
</div>
Tags.ascx partial view:
<% using(Ajax.BeginForm("tag", new AjaxOptions { UpdateTargetId = "tags" }))
{ %>
Add tag: <%= Html.TextBox("tagName")%>
<input type="submit" value="Add" />
<% } %>
The controller:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Tag(string tagName) {
// do stuff
return PartialView("Tags", ...);
}
The problem is when the new instance of the form returns, the posted value is already stored in the input field. As in, whatever I posted as the 'tagName' will stay in the textbox. Firebug shows that the value is hardcoded in the response.
Is there any way to clear the input textbox's value when returning the partial view?
I've tried:
<%= Html.TextBox("tagName", string.Empty)%>
and
<%= Html.TextBox("tagName", string.Empty, new { value = "" })%>`
neither of which do anything.
EDIT:
I realize there are js solutions, which I may end up having to use, but I was wondering if there were any ways of doing it in the backend?
I'm not sure if this solution is "good enough" for you, but couldn't you just empty the form in a JS callback function from your ajax call? If you're using jQuery on your site, the callback function could look something like this:
function emptyFormOnReturn() {
$(':input').val();
}
I am not entirely sure if it will, but in case the above code also removes the text on your submit button, change the selector to ':input[type!=submit]'.
yes you should use jquery to set values on response
if you change your code to use jquery for ajax operations, you can call you settingvalues function on success callback...example:
http://docs.jquery.com/Ajax/jQuery.ajax#options

Resources