I am using jquery tab ui. My second tab contains this form when posted, does not refresh a partial view I have nested. What could be the problem?
_Partial_Item_Tab.cshtml
#model Mvc5.Models.ORDER_DETAILSMetadata
#{
var ordernumber = (int)Session["Order_Number"];
}
#using (Ajax.BeginForm("Items", "Order",
new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "target"
}))
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.TextBoxFor(model => model.id)
<input type="submit" value="Add" class="btn btn-default" />
}
<div id="target">
#Html.Action("Items_List", new { id = ordernumber }); <==== This does not show up after postback. Only after clicking browser refresh button does it show.
</div>
Items Controller (HttpPOST)
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Items(ORDER_DETAILSMetadata model)
{
// check to see if exists
//update order
Order order = new Order();
....
return PartialView("_Partial_Item_Tab", order);
}
Item_List Controller
public ActionResult Items_List(int id)
{
List<ORDER_DETAILS> result = db.ORDER_DETAILS.Where(p => p.Order_Number == id).ToList();
return PartialView("_Partial_Items_List", result);
}
Related
I am in learning phase and I want to create partial view from Ajax call. But for every click the page gets redirected to a altogether New Page. Below is my attempt.
Link I referred from Stack Overflow SO LINK
Model
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
Home Controller:
public ActionResult PartialViewContainer()
{
return View();
}
public PartialViewResult All()
{
var students = _context.Students.ToList();
return PartialView("_Student", students);
}
public PartialViewResult Top3()
{
var students = _context.Students.OrderByDescending(s => s.Age).Take(3);
return PartialView("_Student", students);
}
public PartialViewResult Bottom3()
{
var students = _context.Students.OrderBy(s => s.Age).Take(3);
return PartialView("_Student", students);
}
Main View located inside Home Folder
#{
ViewBag.Title = "PartialViewContainer";
}
<div style="font-family: Arial">
<h2>Students</h2>
#Html.ActionLink("All", "All", new AjaxOptions {
HttpMethod = "GET",
UpdateTargetId = "divStudents",
InsertionMode = InsertionMode.Replace
})
<span style="color:Blue">|</span>
#Html.ActionLink("Top3", "Top3", new AjaxOptions{
HttpMethod = "GET",
UpdateTargetId = "divStudents",
InsertionMode = InsertionMode.Replace
})
<span style="color:Blue">|</span>
#Html.ActionLink("Bottom", "Bottom3", new AjaxOptions{
HttpMethod = "GET",
UpdateTargetId = "divStudents",
InsertionMode = InsertionMode.Replace
})
<div id="divStudents"></div>
</div>
"_Student" Partial view located inside "Shared" folder
#model IEnumerable<WebApplication3.Models.Student>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table" style="border: 1px solid black; background-color: silver">
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</table>
Initial page:
After Ajax Call
P.S: I have included jquery plug in.
But I could not find jquery.unobstrusice-ajax.js in my ASP.Net MVC
5 project template, so I have not included it.
Please guide me what am I doing wrong here.
EDIT 1
Replaced #html.ActionLink with #Ajax.ActionLink, but still it's
getting redirected to a new page.
try this:
Replace #html.ActionLink with #Ajax.ActionLink
#Ajax.ActionLink("All", "All", new AjaxOptions {
HttpMethod = "GET",
UpdateTargetId = "divStudents",
InsertionMode = InsertionMode.Replace
})
Keep in mind. AJAX CANNOT change the page.
I personally steered away from the unobtrusive ajax framwork. I just used good ole AJAX
What is happening is that ajax is not actually working and it is actually just doing an html GET.
Invoke a function like this when you press a button. This is how I solved the similar problem that I had.
This code may not be a direct cut and paste, but it is pretty close.
function CallAjax(actionPath) {
$.ajax({
url: actionPath,
type: 'POST',
success: function (partialView) {
$("#sampleContainer").html(partialView);
},
error: function () {
alert('error');
}
});
}
I tried to minimize huge problem to a small one so I created the new sample web project; mvc-empty in VS. I created one view named „Index” in Home controller. Index view code:
#model WebApplication16.ViewModels.Home.IndexVM
#{
ViewBag.Title = "Index";
}
#Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders)
#section scripts{
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script>
$("#Type").change(function () {
$('#order-current > img').remove();
var currentOrder = "#Type_" + $("#Type").find('option:selected').text();
var $img = $(currentOrder).clone();
$img.removeClass("hidden");
$("#order-current").append($img);
$("#ajax-form").submit();
});
</script>
}
Home controller code:
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
IndexVM dataVM = new IndexVM();
GetControlsDataSource(dataVM.Orders);
return View(dataVM);
}
private static void GetControlsDataSource(OrdersVM dataVM)
{
List<SelectListItem> typeControlDataSource = new List<SelectListItem>();
foreach (var en in Enum.GetValues(typeof(TypeEnum)))
{
SelectListItem item = new SelectListItem();
item.Text = en.ToString();
item.Value = ((int)en).ToString();
typeControlDataSource.Add(item);
}
dataVM.TypeControlDataSource = typeControlDataSource;
}
[HttpPost]
public ActionResult Pay(IndexVM dataVM)
{
GetControlsDataSource(dataVM.Orders);
if (ModelState.IsValid)
{
dataVM.Orders.Info = "Info bla bla bla";
return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders);
}
else
{
return View(dataVM);
}
}
}
There is also a partial view named “_Orders”, which is rendered on the Index view.The code of _Orders partial view:
#model WebApplication16.ViewModels.Home.OrdersVM
#using (Ajax.BeginForm("Pay", "Home", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "result",
}, new { id = "ajax-form" }))
{
<div id="result">
<div id="order-current">
</div>
<div>
#Html.TextBoxFor(x => x.Name, new { #class = "form-control", style = "margin-top:10px;", id = "Name" })
#Html.ValidationMessageFor(x => x.Name)
</div>
<div>
#Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { #class = "form-control", style = "margin-top:10px;", id = "Type", })
#Html.ValidationMessageFor(x => x.Type)
</div>
<div>
<p>#Model.Info</p>
</div>
<button type="submit" class="btn btn-primary" name="ok"> OK</button>
</div>
}
<div id="orders-container">
<img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" />
<img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" />
<img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden"/>
</div>
Index model is described by class IndexVM:
public class IndexVM
{
public IndexVM()
{
this.Orders = new OrdersVM();
}
public OrdersVM Orders { get; set; }
}
_Orders model is described by class OrdersVM:
public class OrdersVM
{
[Required]
public string Name { get; set; }
public string Info { get; set; }
[Required]
public TypeEnum Type { get; set; }
public List<SelectListItem> TypeControlDataSource { get; set; }
}
public enum TypeEnum
{
I,
II,
III
}
After change of value in DropDownListFor control with id=”Type”, the picture from hidden field should be injected by jquery code located in Index view into container with id=”order-current” and after that operation the ajax-form should be submitted. It works properly but after calling
return PartialView("~/Views/Home/_Orders.cshtml", dataVM.Orders);
from the HomeController, the field Info is updated properly but the injected picture from the “order-current” div container is gone. I tried to see what’s wrong in Google Chrome using F12 button and there are no errors but appeared an infinite loop in “browserLink” script. I can’t explain why.
All I want is to see the injected picture in container with id=”order-current after submitting the ajax-form. How to do this and what I did wrong?
Thanks to my friend I finally solved the problem. After updating the “result” container, all events added by jQuery to controls located in this container are unpinned. That’s why it crashes.
The way to make it work correctly is to create a function and pin it to the event OnComplete of AjaxBeginForm. After each update of the result container via ajax, this function is called. I also made a small mistake in Home controller because I inserted a wrong view model class. After all changes, it looks like this;
Home controller code:
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
IndexVM dataVM = new IndexVM();
GetControlsDataSource(dataVM.Orders);
return View(dataVM);
}
private static void GetControlsDataSource(OrdersVM dataVM)
{
List<SelectListItem> typeControlDataSource = new List<SelectListItem>();
foreach (var en in Enum.GetValues(typeof(TypeEnum)))
{
SelectListItem item = new SelectListItem();
item.Text = en.ToString();
item.Value = ((int)en).ToString();
typeControlDataSource.Add(item);
}
dataVM.TypeControlDataSource = typeControlDataSource;
}
[HttpPost]
public ActionResult Pay(OrdersVM dataVM)
{
GetControlsDataSource(dataVM);
if (ModelState.IsValid)
{
dataVM.Info = "Info bla bla bla";
return PartialView("~/Views/Home/_Orders.cshtml", dataVM);
}
else
{
return View(dataVM);
}
}
}
Index view:
#model WebApplication16.ViewModels.Home.IndexVM
#{
ViewBag.Title = "Index";
}
#Html.Partial("~/Views/Home/_Orders.cshtml", Model.Orders)
<div id="orders-container">
<img id="Type_I" src="~/App_Images/Type_I.png" class="img-responsive hidden" />
<img id="Type_II" src="~/App_Images/Type_II.png" class="img-responsive hidden" />
<img id="Type_III" src="~/App_Images/Type_III.png" class="img-responsive hidden" />
</div>
#section scripts{
<script src="~/Scripts/jquery.validate.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.js"></script>
<script>
function imageOnChangeEvent() {
$("#ajax-form").submit();
}
function OnCompleteAjaxForm() {
$('#order-current > img').remove();
var currentOrder = "#Type_" + $("#Type").find('option:selected').text();
var $img = $(currentOrder).clone();
$img.removeClass("hidden");
$("#order-current").append($img);
}
</script>
}
_Orders partial view code:
#model WebApplication16.ViewModels.Home.OrdersVM
<div id="result">
#using (Ajax.BeginForm("Pay", "Home", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "result",
OnComplete = "OnCompleteAjaxForm()"
}, new { id = "ajax-form" }))
{
<div id="order-current">
</div>
<div>
#Html.TextBoxFor(x => x.Name, new { #class = "form-control", style = "margin-top:10px;", id = "Name" })
#Html.ValidationMessageFor(x => x.Name)
</div>
<div>
#Html.DropDownListFor(x => x.Type, Model.TypeControlDataSource, new { #class = "form-control", style = "margin-top:10px;", id = "Type", onchange = "imageOnChangeEvent()" })
#Html.ValidationMessageFor(x => x.Type)
</div>
<div>
<p>#Model.Info</p>
</div>
<button type="submit" class="btn btn-primary" id="button_ok" name="ok"> OK</button>
}
</div>
Create click (2nd Partial view) is not hit into action controller. I have used two partial view. I tried the below steps. please see the attached screen shot
While clicking Add button (Index), Dropdown Selected value is added into partial view(1st partial view)
On Click Edit, another partial view(2nd) is loaded into div.
2'nd PV (Create) click, i'm planning to validate model(SubmitReview), generate xml and update to previous partial view, but this is not happening. please see the below code and suggest me how to achieve?
public ActionResult Index()
{
var DBQList = DBActivity.Getdbqlist();
DBQModel viewmodel = new DBQModel();
var DBQSelectList = new SelectList(DBQList, "DBQ_ID", "DBQ_Name", "IsSelected");
viewmodel.selectList = DBQSelectList;
Session["Session_DBQModel"] = viewmodel;
return View(viewmodel);
}
[HttpPost]
public ActionResult Index(DBQModel dbqModel)
{
if (ModelState.IsValid)
{
//
}
var mdl = (DBQModel)Session["Session_DBQModel"];
var selectedvalue = Convert.ToInt32(Request.Form["SelectedId"].ToString());
var rows = DBActivity.Getdbqlist().FirstOrDefault(x => x.DBQ_ID == selectedvalue);
if (rows != null)
{
DBQTable tbl = new DBQTable();
tbl.DBQ_ID = rows.DBQ_ID;
tbl.DBQ_Name = rows.DBQ_Name;
tbl.DBQ_Desc = rows.DBQ_Desc;
tbl.VAFormNo = rows.VAFormNo;
mdl.dbqTable.Add(tbl);
}
Session["Session_DBQModel"] = mdl;
return View(mdl);
}
public PartialViewResult LoadDBQ(int id)
{
if (id==1)
{
EatingDisorder eatingDisorder = new EatingDisorder();
return PartialView("_EatingDisorderPV", eatingDisorder);
}
return PartialView("_DefaultPV");
}
[HttpPost]
public ActionResult SubmitReview(EatingDisorder _model)
{
try
{
if (!ModelState.IsValid)
{
string messages = string.Join("; ", ModelState.Values
.SelectMany(x => x.Errors)
.Select(x => x.ErrorMessage));
throw new Exception("Please correct the following errors: " + Environment.NewLine + messages);
}
if (_model.s1_Bulima)
{
if ((_model.s1_Bulima_Date != null) && (string.IsNullOrEmpty(_model.s1_Bulima_ICD)) && (!string.IsNullOrEmpty(_model.s1_Bulima_Name)))
{
//ok
}
else
{
ModelState.AddModelError("s1_Bulima_Date", "s1_Bulima_Date is required.");
ModelState.AddModelError("s1_Bulima_ICD", "s1_Bulima_ICD is required.");
ModelState.AddModelError("s1_Bulima_Name", "s1_Bulima_Name is required.");
}
}
//save to db
//return Json(new { Result = "OK" });
}
catch (Exception ex)
{
//return Json(new { Result = "ERROR", Message = ex.Message });
ModelState.AddModelError("", ex.Message);
}
return PartialView("_EatingDisorderPV", _model);
}
Iindex.cshtml
#model WebApplication1.Models.DBQModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
#Html.DropDownListFor(n => n.SelectedId, Model.selectList, "Please select dbq", new { #class = "from-control col-md-4" })
<input type="submit" value="Add" class="btn btn-default" />
#Html.Partial("_DBQGridPV", Model.dbqTable)
<div id="DBQHolder"></div>
}
_DBQGridPV.cshtml
#model IEnumerable<WebApplication1.Models.DBQTable>
<table class="table">
<tr>
<th>#Html.DisplayNameFor(model => model.DBQ_ID)</th>
.....
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>#Html.DisplayFor(modelItem => item.DBQ_ID)</td>
.....
<td>
#Ajax.ActionLink("Edit", "LoadDBQ", new { id = item.DBQ_ID },
new AjaxOptions { HttpMethod = "GET", UpdateTargetId = "DBQHolder", InsertionMode = InsertionMode.Replace })|
#Html.ActionLink("Delete", "DeleteDBQ", new { id = item.DBQ_ID })
</td>
</tr>
}
</table>
_EatingDisorderPV.cshtml
#model WebApplication1.Models.EatingDisorder
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
.....
<input type="submit" value="Create" />
}
I have a textbox on my MVC 4 view, and I would like to let the user press Enter on changing the text and call a controller's action method. Thanks.
Here is a part of my view:
#using (Html.BeginForm())
{
<div class="editor">
#Html.LabelFor(m => m.FolderPath)
#Html.TextBoxFor(m => m.FolderPath, new { #Id = "FolderPath", #style="width:500px;" })
#Html.ValidationMessageFor(m => m.FolderPath)
</div>
And a part of the controller:
[HttpPost]
[MultipleButton(Name = "action", Argument = "Refresh")]
public ActionResult Refresh(EdiFileModel ediFileModel)
{
if (Directory.Exists(ediFileModel.FolderPath))
{
FolderPath = ediFileModel.FolderPath;
}
else
{
ModelState.AddModelError("FolderPath", "This folder does not exist!");
}
ediFileModel = Load();
return View("Index", ediFileModel);
}
Add a submit button...
<input type="submit" value="Submit"/>
inside your form.
how to bind Kendo ui dropdownlist with model and how to send that selected value to controller with a button Click
for other operations....
could you please explain be in detail...am a fresher...
thanks in advance
View:
#model Contract
#{
var vendors = ViewData["Lookups"] as List<Vendor>;
}
#using (Html.BeginForm("Create", "Contract", FormMethod.Post, new { id = "contractDetailsForm" }))
{
#Html.ValidationSummary(true)
<fieldset>
<legend>Contract</legend>
<div>
#{
Html.Kendo().DropDownListFor(model => model.VendorId).Name("VendorId")
.BindTo(new SelectList(vendors, "ID", "DisplayName", "Nothing Selected"))
.HtmlAttributes(new { #style = "width:250px;" })
.Value(Model.VendorId.ToString())
.Render();
}
</div>
<div>
<button type="submit" class="k-button k-button-icontext">
<span class="k-icon k-insert"></span>Create Contract</button>
</div>
</fieldset>
}
Controller:
[HttpPost]
public ActionResult Create(Contract contract)
{
if (ModelState.IsValid)
{
contract.ID = Guid.NewGuid();
_repository.Add(contract);
_repository.SaveChanges();
//return or redirect to another View ...
}
return View("Create", contract);
}
write select event for the dropdown list like
function onSelect(e) {
var DropDownval = $("#QuestionType").val();
}
put this value in the session or in a variable and pass it to the controller.