How i can update two DOM elements using Ajax.beginform inside my asp.net mvc web application - ajax

i have the following ajax.actionlink :-
<div id ="link">
#Ajax.ActionLink("Add New Answer", "Create", "Answer",
new { questionid = Model.QuestionID },
new AjaxOptions
{
HttpMethod = "Get",
UpdateTargetId = "link",
InsertionMode = InsertionMode.InsertAfter,
LoadingElementId = "progress"
})
</div>
where the above link will retrun the following _answer partial view which contains an Ajax.Actionlink:-
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "incrementanswer",
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer here</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsRight)
</div>
<div class="editor-field">
#Html.DropDownList("IsRight", String.Empty)
#Html.ValidationMessageFor(model => model.IsRight)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
currently after clicking on the submit button the "UpdateTargetId = "incrementanswer", will be updated with the result of the submition, but the problem is that i also need to remove the current _answer partial view (currently the view containing the values i have inserted will still be displayed after clicking on the submit ajax.beginform)

load your partial view inside a wrapper div
<div id="partialWrapper">
#Html.partial("yourpartial")
</div>
declare an OnSuccess event handler
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "incrementanswer",
OnSuccess="removePartial"
}))
define the removePartial
<script>
function removePartial(){
$("#partialWrapper").remove();
}
</script>

Related

MVC 5 Ajax posting whole form - instead of ajax call

I have a basic ajax call setup in MVC 5 but it seems that my Ajax form is actually posting the full form, instead of getting back PartialViewResult in the main view, the whole window just renders with the PartialView for the result
suggestion what I may be missing here ?
I also do have the following jquery renders in my _Layout.cshtml
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
MainView
#{
ViewBag.Title = "Puzzles 1 & 2";
}
<h2>#ViewBag.Title</h2>
<div>
#Html.Partial("Puzzle1Form")
</div>
PartialView
#model SixPivot_Code_Puzzles.Models.Puzzle1Model
#using (Ajax.BeginForm("Puzzle1","Puzzles",new AjaxOptions {
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
UpdateTargetId = "puzzle1-result",
}))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Puzzle1</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.IntegerList, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.IntegerList, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.IntegerList, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Find Largest No." class="btn btn-default" />
</div>
</div>
</div>
}
<div id="puzzle1-result"></div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
}
Controller
[HttpPost]
public PartialViewResult Puzzle1(Puzzle1Model model)
{
if (ModelState.IsValid)
{
Puzzle1Model result = new Puzzle1Model();
result.LargestInteger = FindLargestInt(model.IntegerList).ToString();
result.IntegerList = model.IntegerList;
return PartialView("Puzzle1FormResult",result);
}
else {
return PartialView("Puzzle1Form",model);
}
}
PartialViewResult on Success (Puzzle1FormResult.cshtml)
#model SixPivot_Code_Puzzles.Models.Puzzle1Model
<div>
<h4>Largest Integer</h4>
<hr />
<p>
Largest Integer for the list "#Model.IntegerList" is : #Model.LargestInteger
</p>
</div>
I tend to try not use the Ajax helpers in MVC because I find jQuery easier to understand. You could try doing it how I would.
PartialView
#model SixPivot_Code_Puzzles.Models.Puzzle1Model
<form class="form-horizontal" id="frmPuzzle1">
#Html.AntiForgeryToken()
<div>
<h4>Puzzle1</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.IntegerList, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.TextBoxFor(model => model.IntegerList, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.IntegerList, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Find Largest No." class="btn btn-default" />
</div>
</div>
</div>
<div id="puzzle1-result"></div>
<div>
#Html.ActionLink("Back to List", "Index")
</div>
*Notice I removed the scripts section, you should have this in your layout instead.
MainView
#{
ViewBag.Title = "Puzzles 1 & 2";
}
<h2>#ViewBag.Title</h2>
<div>
#Html.Partial("Puzzle1Form")
</div>
<script>
$(document).ready(function() {
$(document).on('submit', '#frmPuzzle1', function(e) {
// stop default form submission
e.preventDefault();
$.ajax({
url: '#Url.Action("Puzzle1", "Puzzles")',
type: 'POST',
data: $('#frmPuzzle1').serialize(),
success: function(html) {
$('#puzzle1-result').html(html);
}
});
});
});
</script>
The Ajax.* family of helpers simply add a standard HTML setup (a regular old form, for example) and some JavaScript that intercepts the default behavior, sending it as AJAX instead. In other words, the code is unobtrusive. If for whatever reason the JavaScript can't be run, it will fallback to standard behavior of doing a simple form post.
Therefore, if it's doing a standard form post, rather than sending an AJAX request, you most likely have some JavaScript error on the page that is preventing the AJAX code from running.
The Ajax.* family of helpers simply add a standard HTML setup (a regular old form, for example) and some JavaScript that intercepts the default behavior, sending it as AJAX instead. In other words, the code is unobtrusive. If for whatever reason the JavaScript can't be run, it will fallback to standard behavior of doing a simple form post.

Use ajax in asp.net mvc 5 in a tab

I want to use ajax to update the content of a TAB and it doesn't work, when I press the buton submit i update all the page. I don't know how to solve it.
Thanks.
Controller PeticioUsuarisController:
// POST: PeticioUsuaris/_Demanar
// To protect from overposting attacks, please enable the specific properties you want to bind to, for
// more details see http://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult _Demanar([Bind(Include = "Nom,PrimerCognom,SegonCognom")] PeticioUsuari peticioUsuari)
{
if (ModelState.IsValid)
{
peticioUsuari.IdUsuariFaPeticio = 1;
db.PeticioUsuari.Add(peticioUsuari);
db.SaveChanges();
return PartialView("_PeticioCorrecte");
}
return PartialView("_PeticioCorrecte");
}
View Index.cshtml:
#{
ViewBag.Title = "";
}
<!-- Tab Buttons -->
<ul id="tabstrip" class="nav nav-tabs" role="tablist">
<li class="active">Demanar</li>
<li>Acceptar</li>
</ul>
<!-- Tab Content Containers -->
<div class="tab-content">
<div class="tab-pane fade in active" id="_Demanar">#Html.Partial("_Demanar")</div>
<div class="tab-pane fade" id="_AcceptarPeticio"></div>
</div>
#section scripts {
<script>
$('#tabstrip a').click(function (e) {
e.preventDefault()
var tabID = $(this).attr("href").substr(1);
$(".tab-pane").each(function () {
console.log("clearing " + $(this).attr("id") + " tab");
$(this).empty();
});
//$("#" + tabID).load("/#ViewContext.RouteData.Values["controller"]/" + tabID)
$.ajax({
url: "/#ViewContext.RouteData.Values["controller"]/" + tabID,
cache: false,
type: "get",
dataType: "html",
success: function (result) {
$("#" + tabID).html(result);
}
})
$(this).tab('show')
});
</script>
}
View _Demanar:
#model Peticions.Models.PeticioUsuari
#{
AjaxOptions options = new AjaxOptions
{
HttpMethod = "Post",
UpdateTargetId = "content",
InsertionMode = InsertionMode.InsertAfter
};
}
#using (Ajax.BeginForm("_Demanar", "PeticioUsuaris", null, options))
{
#Html.AntiForgeryToken()
<div class="form-horizontal tabs">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Nom, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Nom, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Nom, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PrimerCognom, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PrimerCognom, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.PrimerCognom, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SegonCognom, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SegonCognom, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.SegonCognom, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default"/>
</div>
</div>
</div>
}
<div id="content"></div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
View _PeticioCorrecte:
#model Peticions.Models.PeticioUsuari
<div class="alert alert-success">
<a href="#Url.Action("Index", "PeticioUsuaris", new { id = UrlParameter.Optional })">
PeticiĆ³ enviada correctament! Clica aquĆ­ per a crear-ne un altre.
</a>
</div>
try this
#{
AjaxOptions options = new AjaxOptions
{
HttpMethod = "Post",
UpdateTargetId = "formContent"
};
}
#using (Ajax.BeginForm("_AcceptarPeticio", "PeticioUsuaris", null,options ))
{
}

FormCollection parameter is empty while using #Ajax.BeginForm and #Ajax.ActionLink

I've went through whole bunch of SO questions regarding my problem and I wasn't able to find a solution, so I've decided to post this question. The problem is that FormColection fc is empty when I do that Ajax POST request by clicking the search button from _Sidebar.cshtml. What am I missing here?
Code part:
_MyLayout.cshtml:
#using (Ajax.BeginForm("Results", "Search", null, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "d_content", LoadingElementId = "spinner", OnBegin = "ToggleContent", OnComplete = "ToggleContent" },null))
{
<div class="wrapper row-offcanvas row-offcanvas-left">
<div id="a_sidebar">
#{ Html.RenderAction("_Sidebar"); }
</div>
<aside class="right-side">
<section class="content">
<img id="spinner" src="~/Content/img/lightbox-ico-loading.gif" style="display: none;">
<div id="d_content">
#RenderBody()
</div>
</section>
</aside>
</div>
}
_Sidebar.cshtml:
<ul class="treeview-menu">
<li>
<div class="form-group">
<label>F1</label>
#Html.ListBox("ddF1", (MultiSelectList)ViewData["ddF1"])
</div>
<div class="form-group">
<label>F2</label>
#Html.ListBox("ddF2", (MultiSelectList)ViewData["ddF2"])
</div>
<div class="form-group">
<label>Status</label>
#Html.ListBox("ddStatusFilter", (MultiSelectList)ViewData["ddStatusFilter"])
</div>
<div class="form-group">
<label>Name</label>
#Html.TextBox("tbName")
</div>
</li>
</ul>
<li class="treeview">
<div style="text-align: center;">
<button type="reset" class="btn btn-warning">Clear Filters</button>
#Ajax.ActionLink("Search", "Results", "Search", new { }, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "d_content", LoadingElementId = "spinner", OnBegin = "ToggleContent", OnComplete = "ToggleContent" }, new { #class = "btn btn-success", #style = "color: white;" })
</div>
</li>
SearchController.cs:
[HttpPost]
[AcceptVerbs(HttpVerbs.Post)]
public PartialViewResult Results(FormCollection fc)
{
//TODO: Implement filtering through FormCollection in passed parameter
// but that freakin' fc var is empty
var model = db.vw_MainTable.ToList();
return PartialView("_SearchResultGrid", model);
}
Much appreciated.
From the code, It looks like you don't need a form tag covering your entire html. You can place it in the _Sidebar.cshtml like this.
Also replace the action link with a submit button (check below code).
#using (Ajax.BeginForm("Results", "Search", null, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "d_content", LoadingElementId = "spinner", OnBegin = "ToggleContent", OnComplete = "ToggleContent" },null))
{
<ul class="treeview-menu">
<li>
<div class="form-group">
<label>F1</label>
#Html.ListBox("ddF1", (MultiSelectList)ViewData["ddF1"])
</div>
<div class="form-group">
<label>F2</label>
#Html.ListBox("ddF2", (MultiSelectList)ViewData["ddF2"])
</div>
<div class="form-group">
<label>Status</label>
#Html.ListBox("ddStatusFilter", (MultiSelectList)ViewData["ddStatusFilter"])
</div>
<div class="form-group">
<label>Name</label>
#Html.TextBox("tbName")
</div>
</li>
</ul>
<li class="treeview">
<div style="text-align: center;">
<button type="reset" class="btn btn-warning">Clear Filters</button>
<button type="submit" class="btn"> Search</button>
</div>
</li
}
There might be multiple reasons for this. In my case, it was happening because my form fields only had the ID property and not the Name property.
After adding the Name property to the input fields, the Controller could see them just fine.

how i can reset all the field values inside a Div element using Jquery in my asp.net mvc application

i have the following view:-
<div id = "partialWrapper">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "incrementanswer",
OnSuccess = "removePartial"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer here</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Description)
#Html.ValidationMessageFor(model => model.Description)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.IsRight)
</div>
<div class="editor-field">
#Html.DropDownList("IsRight", String.Empty)
#Html.ValidationMessageFor(model => model.IsRight)
</div>
</fieldset>
<input type= "hidden" name = "questionid" value = #ViewBag.questionid>
<input type= "hidden" name = "assessmentid" value = #ViewBag.assessmentid>
<input type="submit" value="Add answer" />
</div>
}
</div>
i want to clear all the data inside the fields so that the users can easily add new objects, i tried the following but these will remove the text and fields :-
function removePartial() {
$("#partialWrapper").remove();
}
and
function removePartial() {
$("#partialWrapper").empty();
}
so is there a way to clear the text inside the all the fields within a Div without removing the fields themself.
BR
Try reseting the form:
$('#partialWrapper form')[0].reset();

How to add elements without reloading the page

I create view by model Article.
class Article
{
public string Title {get;set;}
public List<string> Terms {get;set}
}
Terms - can be any count, and I want that they can be added gradually
#using (Html.BeginForm("Create"))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>CreateArticle</legend>
<div class="editor-label">
#Html.LabelFor(model => model.Title)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Title)
#Html.ValidationMessageFor(model => model.Title)
</div>
<div class="editor-label">
Terms:
</div>
<div id="divList">
</div>
#using (Ajax.BeginForm("Update", new AjaxOptions() { Confirm = "Add", HttpMethod = "Post", UpdateTargetId = "divList", InsertionMode = InsertionMode.InsertAfter }))
{
#Html.Partial("_TermPP", "")
<input id="count" name="count" type="hidden" value="-1" />
<input type="submit" value="add" onclick="javascript:plus()" />
}
</fieldset>
}
_TermPP:
#model String
<div>
<input type="text" name="terms[#(ViewBag.Count==null?0:ViewBag.Count)]" value="#(Model == null ? "" : Model)" /> </div>
when the click is sent to a form of ADD but I need to create on the Update. How do this?
You may take a look at the following blog post. Also please note that you cannot nest 2 <form> elements as you did in your code - this is invalid HTML and might result in undefined behavior.

Resources