Ajax.BeginForm routing to new page instead of a partial view - ajax

I have a Ajax.BeginForm call that is supposed to return a partial view but is rerouting the page to the Action instead. Any ideas on what is wrong?
Here is the code on the main page that I want to render the partial view on:
<div class="col-md-6">
#using (Ajax.BeginForm("Search", "Home", new AjaxOptions
{
HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "searchResults"
}))
{
<div class="form-group" style="width:85%;">
<div class="right-inner-addon">
<i class=" glyphicon glyphicon-search"></i>
<input type="text" data-autocomplete="#Url.Action("Quicksearch","Home")" class="form-control" placeholder="Search" name="q" />
</div>
</div>
<div class="form-group">
<button class="btn btn-default form-inline" type="submit">Search</button>
</div>
}
<br />
</div>
</div>
<div id="searchResults">
</div>
Here is the Partial view (items removed due to length):
<div class="row" id="searchResults">
...removed form elements
<div class="row">
<table class="table">
....stuff
</table>
</div>
</div>
Here is the controller:
public PartialViewResult Search(string q)
{
var items = db.items_with_descriptions
.Where(r => r.name.Contains(q) || string.IsNullOrEmpty(q))
.Take(10);
return PartialView("_Items", items);
}
As stated above, when I click my search button it redirects to localhost:24942/Home/Search instead of staying on the page and simply loading the partial view. I am new to MVC, so please keep that in mind. :)

The jquery-unobtrusive js file has to be included in your page to make the ajax.beginform work

Related

Ajax.BeginForm submitting the form twice

I have a problem with my modal on inserting data. Every time I add a new row it get's a second identical row into the database. I don't really know exactly what I did wrong so if you have a ideea on how to solve this please help me.
This is my controller:
public ActionResult IndexEvent()
{
return View(db.tbl_Event.ToList());
}
[HttpGet]
public ActionResult AddEvent()
{
return PartialView();
}
[HttpPost]
public ActionResult AddEvent(BOL3.tbl_Event eve)
{
if(ModelState.IsValid)
{
db.tbl_Event.Add(eve);
db.SaveChanges();
}
return PartialView("_Detail", db.tbl_Event.ToList());
}
,here is my Index view, _Detail partial view and Add partial view (in the same order):
#model IEnumerable<BOL3.tbl_Event>
#{
ViewBag.Title = "Index";
}
<link href="#Url.Content("~/Content/bootstrap/css/bootstrap.min.css")" rel="stylesheet" />
<link href="#Url.Content("~/Content/bootstrap/css/bootstrap-theme.min.cs")" rel="stylesheet" />
<link href="#Url.Content("~/Content/bootstrap/css/font-awesome.min.cs")" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
<script src="~/Scripts/bootstrap.min.js"></script>
<div id="main-div">
<div class="clearfix"> </div>
<div class="clearfix"> </div>
<div class="container">
<i class="glyphicon glyphicon-plus"></i> Add New
<br />
<br />
<div id="div-record">
#Html.Partial("_Detail")
</div>
</div>
</div>
<div class="modal fade" id="Add-Model" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title">Add Event</h4>
</div>
<div class="divForAdd">
</div>
</div>
</div>
</div>
<script>
$(document).ready(function () {
$('#Add').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForAdd').html(response);
});
$('#Add-Model').modal({
backdrop: 'static',
}, 'show');
});
#model IEnumerable<BOL3.tbl_Event>
<div class="table-responsive">
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Event Name</th>
<th>Starting Event (Date and Time)</th>
<th>Ending Event (Date and time)</th>
<th>All Day ?</th>
<th>Edit</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
#foreach(var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Event)
</td>
<td>
#Html.DisplayFor(modelItem => item.Start_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.End_Date)
</td>
<td>
#Html.DisplayFor(modelItem => item.All_Day)
</td>
<td>
<i class="glyphicon glyphicon-pencil"></i> Edit
</td>
<td>
#Ajax.ActionLink(" Delete", "DeleteEvent", "Prog", new { #id = item.ID }, new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "div-record" }, new { #class = "glyphicon glyphicon-trash" })
</td>
</tr>
}
</tbody>
</table>
</div>
#model BOL3.tbl_Event
#using (Ajax.BeginForm("AddEvent", "Prog", new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "div-record", OnSuccess = "$('.close').click()" }))
{
<div class="modal-body">
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-pushpin"></i></span>
#Html.TextBoxFor(m => m.Event, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.Start_Date, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.End_Date, new { #class = "form-control" })
</div>
</div>
</div>
<div class="row form-group">
<div class="col-md-12">
<div class="input-group">
<span class="input-group-addon"><i class="glyphicon glyphicon-calendar"></i></span>
#Html.TextBoxFor(m => m.All_Day, new { #class = "form-control" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-success" name="cmd">Save</button>
</div>
}
I tried something else but that also gave me a problem (see this link: "Refresh table list using Ajax in Asp.Net Mvc") Thank you.
this problem is occuring because you have loaded <script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script> twice in the _layout page as well as index page and because of that it causes ajax to send request twice. so remove the link either from Index page or _layout page
Why it causes to submit twice?
if you look at the code of unobtrusive-ajax it has function $(document).on("click", "form[data-ajax=true] which is responsible for sending the request so when you submit the form this function trigger's differently on each script you loaded which causes the request to send twice (if someone can explain better feel free to edit)
It is because you have JS function binded to element #Add and you are not disabling anchror href correctly, thus having two requests (since your anchor has link attribute as well). In this SO question How can I disable HREF if onclick is executed? you can se, that correct click handling should be like
$('#Add').click(function (event) {
event.preventDefault();
$.get(this.href, function (response) {
$('.divForAdd').html(response);
});
$('#Add-Model').modal({
backdrop: 'static',
}, 'show');
return false; // this is essential
});

FormCollection parameter is empty while using #Ajax.BeginForm and html5 controls

I'm developing ASP.NET MVC5 project with boostrap, jquery, jquery UI. Submit is working fine but FormCollection in create Action is arriving empty in HomeController. I don't know what I'm doing wrong or is missing. PLease need help. Below snippet code.
Index.cshtml:
<div class="modal fade" id="modal" tabindex="-1" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title">Empleado</h4>
</div>
<div class="modal-body">
#using (Ajax.BeginForm("Create", "Home", new AjaxOptions() { HttpMethod = "post" }, new { id = "dialog", name = "dialog" }))
{
<div class="panel">
<div class="panel-body">
<div class="form-group">
<label class="control-label">Nombres</label>
<input type="text" class="form-control" id="modalNombres" placeholder="Nombres" />
</div>
<div class="form-group">
<label class="control-label">Apellidos</label>
<input type="text" class="form-control" id="modalApellidos" placeholder="Apellidos" />
</div>
<div class="form-group">
<label class="control-label">Fecha de Nacimiento</label>
<input type="text" class="form-control" id="modalFechaNacimiento" placeholder="Fecha Nacimiento" />
</div>
<div class="form-group">
<label class="control-label">Tipo Documento</label>
<select class="form-control" id="modalTipoDocumento">
<option class="placeholder" selected disabled value="">--- Seleccione ---</option>
#foreach (var item in ViewBag.TiposDocumento)
{
<option value="#item.Id">#item.Descripcion</option>
}
</select>
</div>
<div class="form-group">
<label class="control-label">Número de Documento</label>
<input type="text" class="form-control" id="modalNumeroDocumento" placeholder="Número Documento" />
</div>
</div>
<div class="panel-footer">
<button type="button" role="button" class="btn btn-default" data-dismiss="modal">Cerrar</button>
<button type="submit" role="button" class="btn btn-primary" id="btnGrabar">Grabar</button>
</div>
</div>
}
</div>
<div class="modal-footer">
</div>
</div>
</div>
</div>
HomeController is:
[HttpPost]
public ActionResult Create(FormCollection collection)
{
try
{
string nombres = collection["modalNombres"];
return RedirectToAction("Index");
}
catch
{
return View();
}
}
None of you <input> elements have name attributes so there is nothing sent to the server. Change
<input type="text" class="form-control" id="modalNombres" placeholder="Nombres" />
to
<input type="text" class="form-control" name="modalNombres" placeholder="Nombres" />
There is no need for id attributes unless you using javascript/jquery to refer to them.
However, I very strongly recommend you go to the MVC site and work through some basic tutorials and learn how to generate a view in MVC. You should have a model, use the strongly typed html helpers to bind to the properties of your model, and the POST method should have a parameter for the model so it is bound (you should never use FormCollection in MVC)
Note also, you using Ajax.BeginForm() which uses ajax to post the form values so return RedirectToAction("Index"); in your POST method is pointless. Ajax calls stay on the same page, they do not redirect.

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.

Ajax GET request calling POST instead (ASP.NET MVC5)

I've created an ajax GET call to perform a search feature. But every time the search button is clicked, it is calling the POST instead (thereby returning null error for the model). I am not sure what I have done wrong. Care to give a hand please?
My controller:
//
// GET: /DataEntry/ChargeBack
public ActionResult ChargeBack(string dwName, string searchTerm = null)
{
var model = createModel();
if (Request.IsAjaxRequest())
{
return PartialView("_Suppliers", model);
}
return View(model);
}
//
// POST: /DataEntry/ChargeBack
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult ChargeBack(ChargeBackViewModel model)
{
if (ModelState.IsValid)
{
model.someAction();
}
return View(model);
}
My Main View:
#model CorporateM10.Models.ChargeBackViewModel
#using (Ajax.BeginForm(
new AjaxOptions
{
HttpMethod = "get",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "SuppliersList"
}))
{
#Html.AntiForgeryToken()
<input type="search" name="searchTerm" class="form-control col-md-2" />
<input type="submit" value="Search by Name" class="btn btn-info" />
}
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true)
#Html.Partial("_Suppliers", Model)
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
My Partial View:
#model CorporateM10.Models.ChargeBackViewModel
<div class="form-group" id="SuppliersList">
<div class="col-md-10">
#Html.EditorFor(model => model.Suppliers)
#Html.ValidationMessageFor(model => model.Suppliers)
</div>
</div>
I've found it. It is being caused by not including jquery.unobtrusive-ajax library. Once included, the Ajax action works as intended.

mvc 4 Validation summary appearing before submit

I am creating an application in MVC4.
I have a validationsummary on my page as follows,
<div>
#Html.ValidationSummary()
</div>
when the page loads, it shows the validation summary and says one of the required fields is required. Why is this shown on load? I thought the validation summary was only shown after a submit?
thanks
<div id="GeneratePaymentContainer" class="content-container">
<div>
#Html.ValidationSummary()
</div>
<div id="GeneratePaymentPage1">
<div id="PageHeaderContainer">
<div id="HelpContainer">
<h2>#SearchPayment.SearchPlacementsHeader</h2>
#Html.PageHelp()
</div>
#{ Html.RenderPartial("PlacementFilter", Model); }
</div>
<div id="BodyContainer">
<div id="GridActions" class="buttons-container">
<a id="Print" class="button">#Buttons.PrintButton</a>
</div>
#{ Html.RenderPartial("SearchGridResults", Model); }
<div id="StandardCost"></div>
<div id="SelectedPlacementContainer"></div>
<br />
</div>
</div>
#using (Html.BeginForm("RequestAction", "Request", FormMethod.Post, new { id = "SundryEntryForm" }))
{
}...
try to write your #Html.ValidationSummary() before Html.BeginForm tag
Update : According to this Post
Therefore, just create a css rule as follows;
.validation-summary-valid
{
display:none;
}

Resources