Ajax in ASP.NET MVC3 Razor - ajax

I have a problem with Ajax.
I want to make multiple forms and replace div containing one after submiting with some Partial View. It's working for me when I use only one form. I don't know what I'm doing wrong here. Maybe it's becasue of custom editorfor?
Here is my code, plese try to help me, I've been trying do this for 2 days.
Index
#model MetriceWeb.Models.TaskInputModel
#{
ViewBag.Title = "Tasks";
}
<h3>
Tasks</h3>
#if (Model.Values.Count == 0)
{
<p>No pendings forms for you at the moment</p>
}
else
{
#Html.EditorFor(x => x.Values)
}
TaskInputValue (editorfor)
#model MetriceWeb.Models.TaskInputValue
#{string s = "task" + Model.TaskId;}
#using (Ajax.BeginForm("GetFromLibrary", "Metrice", new AjaxOptions
{
HttpMethod = "Get",
UpdateTargetId = s,
InsertionMode = InsertionMode.Replace
}))
{
<div class="editor-field" id="#s">
#Html.HiddenFor(x => x.TaskId, new { #class = "TaskId" , id = "TaskId" })
#Html.HiddenFor(x => x.InputId, new { #class = "InputId" })
<h2>
#Html.DisplayFor(x => x.Task)
</h2>
<span>Created: </span>
#Html.DisplayFor(x => x.Date)
<div>
Input Value
#Html.EditorFor(x => x.DateValue)
#Html.ValidationMessageFor(x => x.DateValue)
</div>
<input type="submit" value="Submit" />
</div>
<br />
}
It's entering method in my controller where I'm returning partial view. After submitting my div isn't replacing, the whole new site is loaded. What is wrong here? Please help me, I am in big need.

In order to the Ajax helpers like Ajax.BeginForm work correctly (e.g sending an AJAX request) you need reference in your view the following JavaScript file
jquery.unobtrusive-ajax.js
(and of course before that jquery)
From the Unobtrusive Ajax in ASP.NET MVC 3
An interesting note: since there is no actual JavaScript being emitted
when you use unobtrusive Ajax, if you forget to include one or the
other script, you won’t see any errors when attempting to submit the
Ajax request; it will simply behave like a non-Ajax request.

Related

Ajax.BeginForm preload data

I have this view and everything fine with Ajax.BeginForm:
<h2>Index</h2>
#using (Ajax.BeginForm("Search", new AjaxOptions {
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "users"
})) {
<input name="q" type="text" />
<input type="submit" value="Search" />
}
<div class="table-responsive" id="users">
</div>
But, i have a little question.
Right now, when i open this page, there are no table with data - it loads only when form is submitted.
So, my question: is it possible to have preload data (without adding other code)?
When page is loaded, i would like to have already all data without filtering (input uses for filtering when value is typed and form submitted).
Just call your Search action from users div when the page loads. You may not specify any parameter or use the default one. I assume you have something like this:
public ActionResult Search(string q)
{
var users = _usersRepository.GetAll();
if(!string.IsNullOrEmpty(q))
users = users.Where(user => string.Equals(user.Name, q));
return PartialView("_Search", users);
}
And in the view:
<div class="table-responsive" id="users">
#Html.Action("Search")
</div>

How to return a view from a partial view post to a Controller?

So I have a partial view "_Customer "with a text box and a save button. Currently, the partial view code, I have this:
#model CompositeViews.Models.Customer
#using (Ajax.BeginForm("Edit", "Customer", new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, UpdateTargetId = "customerDiv" }))
{
<div id="customerDiv">
#Html.ValidationSummary(true)
<fieldset>
<legend>Customer</legend>
#Html.HiddenFor(model => model.CustomerId)
<div class="editor-label">
#Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
<p><input type="submit" value="Save" /></p>
</fieldset>
</div>
}
the view lives withing a parent view called index (which also provides the model the partial view is dependent upon):
#model CompositeViews.ViewModels.CompositeViewModel
<h2>Index</h2>
#Html.Partial("_Customer", Model.Customer)
The parent view is named Index.cshtml and is fed by a simple controller action. When I click on the Save button in the partial view, it goes to the appropriate action on the appropriate controller, but I'm not too sure how to return the updated model data BACK into the partial view.
In all the examples out there, it's a form that does an async post, but the UpdateTargetId targets a that is then filled with some type of updated content. That seems pretty straight-forward and simple.
What I'm struggling with is how to return the same form, with the updated model information using the existing view (_Customer). Basically, it's a BeginForm which targets itself with the result from the controller action, not some other div that is not part of the form.
I'd like to NOT have to rebuild all the HTML by hand that the _Customer view does for me via the MVC framework and return that for rendering. I guess I'm stuck with the form in the partial view submitting the data to the controller, and then needing a way for that same view to re-draw itself on returning from the action method.
Any ideas?
I hope I got you right and you want to show your updated on post back.
In that case you can try this:
<div id="customerDiv">
#Html.RenderAction("Edit", "Customer", Model)
</div>
and put your #using (Ajax.BeginForm()) in Edit result.

Ajax.BeginForm with UpdateTarget Inside AjaxForm

Is this possible to use Ajax.Beginform with update target inside of ajax form. like this:
using(Ajax.BeginForm("EditPhone", new { id = item.Id.Value }, new AjaxOptions {
UpdateTargetId = "TRTarget"})) {
<tr class="gradeA odd" id="TRTarget">
<input type"submit" value="submit" />
</tr>
}
Update
OK if it's possible so what is wrong with this?
This is my partial view that another partial view rendered inside it:
using(Ajax.BeginForm("EditPhone", new { id = item.Id.Value }, new AjaxOptions {
UpdateTargetId = "TRTarget"})) {
<tr class="gradeA odd" id="TRTarget">
#{Html.RenderPartial("_PhoneRow", item);}
</tr>
}
and _PhoneRow:
#model MyModel
<td>#Html.DisplayFor(model=>model.Number)</td>
<td>#Html.DisplayFor(modelItem => Model.PhoneKind)</td>
<td><input type="submit" value="Edit" class="button" /></td>
And EditPhone Action:
public ActionResult EditPhone(long Id){
//Get model
return PartialView("_EditPhoneRow", model);
}
And _EditPhoneRow:
<td>#Html.EditorFor(model => model.MainModel.Number)</td>
<td>#Html.EditorFor(model => model.MainModel.PhoneKind)</td>
<td><input type="submit" value="Save" class="button" /></td>
Actually each of my rows have an Ajax form so when click on edit I want to replace the row with another as you see, but when I add the Edit, all of my page destroyed and just _EditPhoneRow shown like I select all page for updateTrget where is the problem? and what is your suggestion to change all the specific row like this?
According to the HTML specification forms cannot be nested. This produces invalid HTML and depending on the user agent either the outer or the inner <form> simply won't work. That's a limitation of the HTML specification, don't be confused with ASP.NET MVC, it has nothing to do with it. One possibility is to replace your Ajax.BeginForm with an Ajax.ActionLink:
<tr class="gradeA odd" id="TRTarget">
#Ajax.ActionLink(
"Submit",
"EditPhone",
new { id = item.Id.Value },
new AjaxOptions { UpdateTargetId = "TRTarget" }
)
</tr>
UPDATE:
After you have updated your question and explained the symptoms I think you might have forgotten to reference the jquery.unobtrusive-ajax.min.js script to your page:
<script type="text/javascript" src="#Url.Content("~/scripts/jquery.unobtrusive-ajax.min.js")"></script>
If you don't include this script the Ajax.* helpers such as Ajax.BeginForm and Ajax.ActionLink will be simple HTML forms and anchors. No AJAX at all. It is this script that reads the HTML5 data-* attributes emitted by those helpers and unobtrusively AJAXifies them.

MVC4 - Ajax.BeginForm and Partial view gives 'undefined'

I'm working on an activity booking and I'm having trouble using ajax.beginform with a partial view. When I click submit, it just goes to a new page and there is an 'undefined' in the top left corner. I have "../../Scripts/jquery.unobtrusive-ajax.min.js" in my layout page. What I want to do is when the user submits the form, the div "AjaxTest" gets updated with the partial view and the form is under the search results.
Here is what I have so far (I took out all the structure and styling so its easier to read):
Main View - Activities
#model Project.Models.ActivityModel
<div id="AjaxTest"></div>
#using (Ajax.BeginForm(new AjaxOptions
{
UpdateTargetId = "AjaxTest",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST"
}))
{
#Html.ValidationSummary(true)
#Html.TextBoxFor(x => x.Activity_CityName)
<div class="editor-label">
<strong>#Html.LabelFor(x => x.Activity_StartDate)</strong>
</div>
<div class="editor-field">
<input id="checkin" type="text" name="Activity_StartDate" />
</div>
#Html.TextBoxFor(x => x.Activity_EndDate)
#Html.DropDownListFor(x => x.Activity_NumAdults, AdultNum)
#Html.DropDownListFor(x => x.Activity_NumChildren)
#Html.DropDownListFor(x => x.Activity_ChildAge1, ChildAge)
#Html.DropDownListFor(x => x.Activity_ChildAge2, ChildAge)
#Html.DropDownListFor(x => x.Activity_ChildAge3, ChildAge)
<div class="submitbutton">
<input data-inline="true"type="submit" id="activity_search" value="Search" />
</div>
}
Controller
[HttpPost]
public ActionResult Activities(ActivityModel activitysubmission) {
return PartialView("PartialActivities_Success", activitysubmission);
}
Partial View - PartialActivities_Success
#model Project.Models.ActivityModel
<p>City: #Model.Activity_CityName</p>
<p>StartDate: #Model.Activity_StartDate</p>
<p>EndDate: #Model.Activity_EndDate</p>
<div>
<p><strong>Ticket</strong></p>
<p>Number of Adults: #Model.Activity_NumAdults</p>
<p>Number of Children: #Model.Activity_NumChildren</p>
<p>Child 1 age: #Model.Activity_ChildAge1</p>
<p>Child 2 age: #Model.Activity_ChildAge2</p>
<p>Child 3 age: #Model.Activity_ChildAge3</p>
</div>
Scripts in Layout Page
<script src="../../Scripts/jquery.unobtrusive-ajax.min.js" type="text/javascript"> </script>
<script src="../../Scripts/xdate.js" type="text/javascript"></script>
<script src="../../Scripts/xdate.i18n.js" type="text/javascript"></script>
<script src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
<script>
$(document).bind("mobileinit", function() {
// As of Beta 2, jQuery Mobile's Ajax navigation does not work in all cases (e.g.,
// when navigating from a mobile to a non-mobile page, or when clicking "back"
// after a form post), hence disabling it.
$.mobile.ajaxEnabled = true; // originally false.
});
</script>
I noticed one mistake in the code. Your div has an id Ajaxtest but the parameter you are passing to BeginRequest is AjaxTest the T is capital
Are you using MVC 4? I would make sure that UnobtrusiveJavaScriptEnabled is set to true in your WebConfig file. I believe it is by default, though. The only other thing I can think of is to verify that you have your other jQuery files and that they're being loaded in the right order. If you load your unobrusive jQuery file before the main one then it won't work.
You haven't specified which action to call when posting the Ajax form. Try changing it to this:
#using (Ajax.BeginForm("Activities", new AjaxOptions
{
UpdateTargetId = "AjaxTest",
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST"
}))

MVC3 with Ajax - return data not "plugged" to the right spot

I'm trying to get started with Ajax on MVC
In my main view I have the following code:
#Ajax.ActionLink("Click here to get the data","LoadData",
new AjaxOptions
{
UpdateTargetId = "dataPanel",
InsertionMode = InsertionMode.InsertAfter,
HttpMethod="GET"
})
<div id="dataPanel">
</div>
I created the controller's action as below:
public PartialViewResult LatestReview()
{
var myData = GetMyData();
return PartialView("_PartialData", myData);
}
_PartialData is defined as below:
#model MyApp.Models.Data
<div>
#if (Model == null)
{
<p>There is no data yet</p>
}
else
{
<p>
#Model.Body
</p>
}
</div>
But when I click the link, my data (rendered in the _PartialData) is loaded fully in browser, replacing the source page (so not inside the dataPanel div)
When I look at original page source (before clicking the ajax link) It see the ajax actions define as below:
<a data-ajax="true" data-ajax-method="GET" data-ajax-mode="after" data-ajax-update="#dataPanel" href="/Home/LoadData">Click here to get the data</a>
<div id="dataPanel">
</div>
What am I doing wrong?
Thanks
I suspect that you forgot to include the jquery unobtrusive ajax script to your page:
<script src="#Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")" type="text/javascript"></script>
It is this script that makes sense of all Ajax.* helper in ASP.NET MVC 3. Without it they generate standard markup with HTML5 data-* attributes which are used by the script.

Resources