I want to pass list of ids into sql database in ASP MVC. In here there are two listbox where from one to other listbox able pass selected course names and then need to save those course ids with including the student id. How is this need to do using the jQuery? please help me on this. Here is my code upto now..
Create View
Create
.....
using (Html.BeginForm()) {
#Html.ValidationSummary(true)
<fieldset>
<legend>StudentCourseVM</legend>
<div class="editor-label">
#Html.LabelFor(model => model.StudentId)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StudentId)
#Html.ValidationMessageFor(model => model.StudentId)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StudentName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StudentName)
#Html.ValidationMessageFor(model => model.StudentName)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.StudentAddress)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.StudentAddress)
#Html.ValidationMessageFor(model => model.StudentAddress)
</div>
<div class="editor-label">
#Html.LabelFor(model => model.CourseName)
</div>
<div class="editor-field">
<table>
<tr>
<td> Available Courses <br />
<select multiple="multiple" id="listboxCourse">
#foreach (var item in Model.courseList)
{
<option title="#item.CourseName" id="#item.CourseID">
#item.CourseName
</option>
}
</select>
</td>
<td>
<button type="button" id="btnAdd">Move Right>></button>
<br/>
<button type="button" id ="btnRemove">Move Left<<</button>
</td>
<td> Selected Courses<br />
<select multiple="multiple" id="addcourselist" >
</select>
</td>
</tr>
</table>
</div>
<p>
<input type="submit" value="Create" id="Create" />
</p>
</fieldset>
}
<script>
$(document).ready(function() {
$("#btnAdd").click(function() {
$("#listboxCourse > option:selected").appendTo("#addcourselist");
});
$("#btnRemove").click(function() {
$("#addcourselist > option:selected").appendTo("#listboxCourse");
});
})
$(function () {
$("#Create").click(function () {
var listCourse = new Array();
for (var i = 0; i < addcourselist.length ; i++) {
listCourse.push(Option[i].value);
}
});
$.ajax({
type: "POST",
data: listCourse,
dataType : "json",
url: "Student/Create",
success: function (data) {
alert("Code is running...............");
}
});
})
Controller
[HttpGet]
[ActionName("Create")]
public ActionResult Create()
{
StudentCourseVM studentcourse = new StudentCourseVM();
StudentBusinessLayer studentBusinessLayer = new StudentBusinessLayer();
List<Course> coursestudentList = studentBusinessLayer.CourseList.ToList();
studentcourse.courseList = coursestudentList;
return View(studentcourse);
}
[HttpPost]
[ActionName("Create")]
public ActionResult Create(StudentCourseVM studentcourse)
{
if (ModelState.IsValid)
{
StudentBusinessLayer studentBusinessLayer = new StudentBusinessLayer();
List<Course> coursestudentList = studentBusinessLayer.CourseList.ToList();
studentcourse.courseList = coursestudentList;
studentBusinessLayer.AddStudent(studentcourse);
return RedirectToAction("Index");
}
return View();
}
How am i supposed to do this. Two listbox are like this. The items in second listbox need to be saved in database with the relate studentid.
You can save it as JSON (objets) strings
Check out How To Populate Html.Listbox with Ajax result using mvc 4
Related
For example, in my project I'm using #using(Html.BeginForm(some stuff))to create an instance of my model and finally appending it to my database. But, when I'm editing (updating) some object of model, I'm usingn ajax get to retrieve data and finally using #Html.BeginForm() to post the update. Well, this is breaking some pattern of coding in MVC or whatever good principle?
Retrieving data and filling in the input fields
$.ajax({
url: "../../Obra/" + id,
type: "POST",
success: function(data) {
var obj = JSON.parse(JSON.stringify(data));
tit.value = obj.titulo;
ed.value = obj.editora;
obj.autores.forEach(x => {
var newn = divAutor.appendChild(aut.cloneNode());
newn.value = x;
});
img.value = obj.imagem;
divAutor.removeChild(aut);
},
error: function() {
alert('Error.');
}
});
All modal:
<div class="modal" id="modalOverlay">
<div class="modal-content" id="modalContent">
<header class="modal-header">
<h1 id="updateObraModalTitulo"></h1>
</header>
#using(#Html.BeginForm("Update", "Obra", FormMethod.Post, new { id="form-update" })) {
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Titulo, "Título:")
#Html.TextBoxFor(m => m.Titulo, new { #class="editInputValue", #id="editTituloInput" })
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Editora, "Editora:")
#Html.TextBoxFor(m => m.Editora, new { #class="editInputValue", #id="editEditoraInput"})
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Autores, "Autores:")
<div id="divInputAutores">
#Html.TextBoxFor(m => m.Autores, new { #class="inputPostValue", id="addAutoresInput"})
</div>
<div class="btnNewAutorOp">
<button type="button" id="btnAddAutor" onclick="addNewAutor()">+</button>
<button type="button" id="btnDeleteAutor" onclick="deleteNewAutor()">×</button>
</div>
</div>
<div class="updateObraDivProp">
#Html.LabelFor(m => m.Imagem, "Imagem:")
#Html.TextBoxFor(m => m.Imagem, new { #class="inputPostValue", #id="editImagemInput" })
</div>
<input type="submit">
}
</div>
</div>
Because I can't retrieve the Id property when I click in the modal with mvc (or maybe I can using partial views?), I'm using javascript to create a function with the param id and getting data with ajax and finally updating with form
I am using a modal bootstrap but my data is not loading into the bootstrap even though I am passing it trough from the controller.
My Grid pulls in data from a list for Notes Object
#foreach (var notes in Model) {
<tr>
<td>#notes.LastModifedDate</td>
<td>#notes.LastModifiedBy</td>
<td>#notes.Notes </td>
<td>
<p>#notes.Id</p> <i class="glyphicon glyphicon-pencil"></i>Edit
|<p>#notes.Id</p> <i class="glyphicon glyphicon-trash"></i>Delete
</td>
</tr>
}
I am using the following to Return the data to the popup.
public ActionResult NotesEditPopupPartial(int id ) {
var record = _context.MISNotes.Where(w => w.Id == id).FirstOrDefault();
return PartialView("NotesEditPopupPartial", record);
}
And using the following call to load the data but the data is not in the model for me to edit the text fields are still blank.
<script>
var AddOrEditNotes = function (id) {
var url = "/MISOjbects/NotesEditPopupPartial?id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#MyEditUpateModal").modal("show");
})
}
</script>
<script>
function EditModal(id) {
$("#editMode").val(id);
}
</script>
My Modal
<div class="modal fade" id="NotesEditPopupPartial">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Notes Entry</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
<div>
<input type="text" name="linkId" id="linkId" />
#using (Html.BeginForm("SaveCaseNotes", "MISObjects", FormMethod.Post, new { #id = "myNotesEditForm", #name = "myNotesEditForm", enctype = "multipart/form-data" })) {
<form id="myForm" asp-action="">
<div asp-validation-summary="All" class="text-danger"></div>
#Html.LabelFor(model => model.Title)
#Html.TextBoxFor(model => model.Title, new { #class = "form-control", #placeholder = "Title" })
#Html.ValidationMessageFor(model => model.Title, string.Empty, new { #style = "color:red;" })
<div class="form-group">
#Html.LabelFor(model => model.Notes, new { #class = "col-lg-2 control-label" })
<div class="col-lg-9">
#Html.TextAreaFor(model => model.Notes, new { #class = "form-control", #row = 5 })
</div>
</div>
#Html.LabelFor(model => model.DateActioned)
#Html.EditorFor(model => model.DateActioned, new { htmlAttributes = new { #class = "form-control datetimepicker" } })
#Html.ValidationMessageFor(model => model.DateActioned)
#Html.DisplayNameFor(model => model.LastModifiedBy)
#Html.LabelFor(model => model.LastModifiedBy)
<input name="IsValid" type="hidden" value="#ViewData.ModelState.IsValid.ToString()" />
<div class="modal-footer">
<button type="submit" id="btnEditSave" class="btn btn-primary">Save</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</form>
}
</div>
<div style="text-align:center;display:none" id="loaderDiv">
<img src="~/Content/InternetSlowdown_Day.gif" width="150" />
</div>
</div>
</div>
Wrap your modal with div:
<div id="modalWrapper">
<div class="modal fade" id="NotesEditPopupPartial">
...
</div>
</div>
and then load and show the modal:
$("#modalWrapper").load(url, function () {
$("#NotesEditPopupPartial").modal("show");
})
<script>
var AddOrEditNotes = function (id) {
var url = "/MISOjbects/NotesEditPopupPartial?id=" + id;
$("#myModalBodyDiv1").load(url, function () {
$("#MyEditUpateModal").modal("show");
})
}
</script>
<script>
function EditModal(id) {
$("#editMode").val(id);
}
</script>
According to your code, I didn't find where you call the AddorEditNotes function to call the NotesEditPopupPartial action and display the partial, and in the EditModel method, you also didn't call the action method to show the partial, so, the popup modal is blank.
In my opinion, I suggest you put the bootstrap Modal on the main page (with note grid), because the trigger button (Edit hyperlink) is on this page. Then, in the hyperlink click event, you could use JQuery Ajax to call the action method and load the partial view and put it on the Bootstrap Modal.
Sample code as below:
Code in the Main page:
#model IEnumerable<NetMvcSample.Models.Note>
#{
ViewBag.Title = "ShowNotes";
}
<h2>ShowNotes</h2>
<script>
function EditModal(id) {
event.preventDefault(); // prevent the hyperlink default event.
$.ajax({
type: "POST",
url: "/Home/NotesEditPopupPartial", //change the url to your owns.
data: '{id: '+ id + "}",
contentType: "application/json; charset=utf-8",
success: function (data) {
console.log(data)
//put the partial view in the modal content.
$('#myModalBodyDiv1').html(data);
},
failure: function (response) {
console.log(response.responseText);
},
error: function (response) {
console.log(response.responseText);
}
});
}
</script>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.LastModifyDate)
</th>
<th>
#Html.DisplayNameFor(model => model.LastModifiedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.Notes)
</th>
<th></th>
</tr>
#foreach (var notes in Model) {
<tr>
<td>
#notes.LastModifyDate
</td>
<td>
#notes.LastModifiedBy
</td>
<td>
#notes.Notes
</td>
<td>
<p>#notes.Id</p> <i class="glyphicon glyphicon-pencil"></i>Edit
|<p>#notes.Id</p> <i class="glyphicon glyphicon-trash"></i>Delete
</td>
</tr>
}
</table>
<div class="modal fade" id="NotesEditPopupPartial">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Notes Entry</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
Code in the controller method:
[HttpPost]
public ActionResult NotesEditPopupPartial(int id)
{
var record = GetNotes().Where(c => c.Id == id).FirstOrDefault();
return PartialView("NotesEditPopupPartial", record);
}
public ActionResult SaveCaseNotes(Note note)
{
// do something
return View();
}
Code in the NotesEditPopupPartial view (NotesEditPopupPartial.cshtml):
#model NetMvcSample.Models.Note
#using (Html.BeginForm("SaveCaseNotes", "Home", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Note</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.Id)
<div class="form-group">
#Html.LabelFor(model => model.LastModifyDate, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastModifyDate, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastModifyDate, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.LastModifiedBy, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.LastModifiedBy, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.LastModifiedBy, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Notes, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Notes, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Notes, "", new { #class = "text-danger" })
</div>
</div>
<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>
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
The output like this:
I need to run Partial View from action method as a child action method but it redirect me to another view.
1- I tried to use Html.Action("myAction","myController") and I use [ChildActionOnly] data annotation but without any benefit
2- I tried to use Html.RenderAction("myAction", "My Controller") and I change the action method as PartialViewResult and return PartialView("View", myData) but without any benefit.
3- I tried to use JQuery AJAX but without any benefit also.
What I get
What I Expect
** This is the controller
[Authorize(Roles = "Admin")]
[HttpPost]
[ChildActionOnly]
public ActionResult _GetUserRoles(string UserName)
{
SqlParameter param1 = new SqlParameter("#UserName", UserName);
try
{
IList<GetUserRolesViewModel> roles = Identitydb.Database.SqlQuery<GetUserRolesViewModel>("admin.sp_GetUserRoles #UserName",
((ICloneable)param1).Clone()).ToArray().ToList();
return View(roles);
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
}
** This is PartialView Code
#model IEnumerable<AMSIdentity.Controllers.GetUserRolesViewModel>
#if (Model == null)
{
<table></table>
}
else
{
<table class="table table-responsive table-striped table-hover table-bordered table-condensed container" style="margin-top: 5%;">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Id)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
</tr>
}
</tbody>
</table>
<br />
#Html.ActionLink("Return Back", "RemoveRoleFromUser", "Manage")
}
** This is Parent Page Code
ViewBag.Title = "RemoveRoleFromUser";
var error = ViewBag.Error as IEnumerable<String>;
}
<h2> Remove role from user </h2>
<ul></ul>
<div class="row container">
<div class="col-md-6">
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
<hr />
#Html.Label("Role Id", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("RoleId", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Remove" class="btn btn-default btn-danger" />
</div>
</div>
</div>
}
</div>
<div class="col-md-6">
<div class="row container">
<div class="col-md-12">
<h3> Get user roles </h3>
#using (Html.BeginForm("_GetUserRoles", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Get rules" class="btn btn-default btn-success" id="btnRules"/>
</div>
</div>
</div>
}
</div>
</div>
<div class="row container">
<div class="col-md-12">
#Html.Partial("_GetUserRoles")
</div>
</div>
</div><!--Second Column-->
</div> <!--End of row-->
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
** This is the view Model
public class GetUserRolesViewModel
{
[DisplayName("Username")]
public string Name { get; set; }
[Key]
[DisplayName("Role Id")]
public string Id { get; set; }
}
** This is AJAX Code that i used to run partial view
<script type="text/javascript">
//$(document).ready(function ()
//{
$("#btnRules").click(function (e)
{
var UserName = $("#UserName").val();
$.ajax({
url: '/Manage/_GetUserRoles',
dataType: 'html',
data:{"UserName": UserName},
success: function (data)
{
$('#listRules').html(data);
},
error: function (xhr, ajaxOptions, thrownError)
{
alert('Failed to retrieve rules.');
}
});
});
//});
</script>
** Route Picture
Route Config Picture
I expect to run the Action Method (_GetUserRoles) Partially in the same view of RemoveRoleFromUser.
your return must be a PartialView() and not a view. view() will return a complete view where as PartialView() will return a partial view. So yo need to change your
return View();
to
return PartialView("YourPartialViewName");
and if you need to pass a parameter to your partial view
return PartialView("YourPartialViewName",roles);
if you are rendering a partial view from your View them you can use Html hepler
return PartialView("~/views/ABC/PartialViewName.cshtml", Yourmodel);
I am assuming that your ajax call hits the controller action. And the partial view needs to be placed in the parent view code at-
<div class="row container">
<div class="col-md-12">
#Html.Partial("_GetUserRoles")
</div>
</div>
Based on these assumptions, you need to change few things in your code:
return PartialView instead of View from the action. Something like this:
return PartialView("_GetUserRoles", roles);
// the partial view name mentioned here is just a sample based on the context.
//You need to give your partial view's name here.
add an id attribute to the div inside which you have written #Html.Partial("_GetUserRoles"). Something like this:
<div class="row container">
<div class="col-md-12" id="userRoles">
</div>
</div>
within the success function in the ajax method, you need to use the id attribute set in above step and populate the data inside it. Something like this:
success: function (data)
{
$('#userRoles').html(data);
}
Install the Microsoft.Jquery.Unobtrusive.Ajax and Microsoft.Jquery.Unobtrusive.Validation in your project. Then add the reference of these two within your view file. Something like this:
#section scripts{
#Scripts.Render("~/Scripts/jquery{version}.js")
#Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")
}
This way you should be able to see the partial view within your existing view itself.
Here is the answer
I use ViewData[""] rather than PartialView and i put one parameter in the same action result to check which view i will use.
** Action Method RemoveRoleFromUserConfirmed
public ActionResult RemoveRoleFromUserConfirmed(string UserName, string RoleId, string btnval)
{
if (btnval == "Remove")
{
if (UserName == null && RoleId == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
SqlParameter param1 = new SqlParameter("#RoleId", RoleId);
SqlParameter param2 = new SqlParameter("#UserName", UserName);
try
{
Identitydb.Database.ExecuteSqlCommand("admin.sp_RemoveUserFromRole #RoleId, #UserName", param1, param2);
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
return RedirectToAction("Roles");
}
else if (btnval == "Get Rules")
{
SqlParameter param1 = new SqlParameter("#UserName", UserName);
try
{
IList<GetUserRolesViewModel> roles = Identitydb.Database.SqlQuery<GetUserRolesViewModel>("admin.sp_GetUserRoles #UserName",
((ICloneable)param1).Clone()).ToArray().ToList();
string result = "";
foreach (var item in roles)
{
result += "<tr>"
+ "<td>" + item.Name + "</td>"
+ "<td>" + item.Id + "</td>"
+ "</tr>";
}
ViewData["getrules"] = result;
return View();
}
catch (Exception ex)
{
ViewBag.Error = ex.ToString();
return RedirectToAction("ErrorSaveData");
}
}
return View();
}
** This is the view
#{
ViewBag.Title = "RemoveRoleFromUser";
var error = ViewBag.Error as IEnumerable<String>;
}
<h2> Remove role from user </h2>
<ul></ul>
<div class="row container">
<div class="col-md-6">
#using (Html.BeginForm("RemoveRoleFromUser", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
<hr />
#Html.Label("Role Id", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("RoleId", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Remove" name="btnval" class="btn btn-default btn-danger" />
</div>
</div>
</div>
}
</div>
<div class="col-md-6">
<div class="row container">
<div class="col-md-12">
<h3> Get user roles </h3>
#using (Html.BeginForm("RemoveRoleFromUser", "Manage", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.Label("Username", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.Editor("UserName", new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Get Rules" name="btnval" class="btn btn-default btn-success" id="btnRules" />
</div>
</div>
</div>
}
</div>
</div>
<div class="row container">
<div class="col-md-12" id="listRules">
<!--Data Come from ViewData-->
<table class="table table-responsive table-striped table-hover table-bordered table-condensed container" style="margin-top: 5%;">
<thead>
<tr>
<th>
Role Name
</th>
<th>
Role Id
</th>
</tr>
</thead>
<tbody>
#Html.Raw(ViewData["getrules"])
</tbody>
</table>
</div>
</div>
</div><!--Second Column-->
</div> <!--End of row-->
<div>
#Html.ActionLink("Back to List", "Roles")
</div>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
I put the name of button same in two buttons (remove and get rules)
after that i checked the value of the button in ActionMethod and if it
is remove it will do some function and if it is get rules i will use
ViewData[""] to put the view.
Regards,
Ali Mosaad
Software Developer
I would suggest changing
return View(roles);
to
return PartialView(roles);
or
return PartialView("_GetUserRoles", roles);
Using ajax
$.ajax({
url: '/Manage/_GetUserRoles',
dataType: 'html',
data:{"UserName": UserName},
success: function (data)
{
$('#listRules').html(data);
},
error: function (xhr, ajaxOptions, thrownError)
{
alert('Failed to retrieve rules.');
}
});
...
<div class="row container">
<div id="listRules" class="col-md-12">
#Html.Partial("_GetUserRoles", Model.Roles)
</div>
</div>
I have a strongly typed view, which has a form in which I put one field showtime when the submit button is clicked I want to save the entry into database also display that entry along with other entries on the database inside the partial view I put on the main view . When the Index action method is called the Main view is rendered .I want to update the Partial view when a new entry is saved without reloading the whole page ,just refresh the partial page.
Here is my view :
#model Bookmany.Admin.Models.Theater.TheaterShowTimeViewModel
#{
ViewBag.Title = "Theater showTimes / BookMany";
}
<h3>Theater ShowTimes</h3>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.TheaterID, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.TheaterID, Model.AvailableTheaters)
#Html.ValidationMessageFor(model => model.TheaterID)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ShowTimeName, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ShowTimeName)
#Html.ValidationMessageFor(model => model.ShowTimeName)
</div>
</div>
<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>
}
<div>
#Html.Partial("_TheaterShowTimeList", Model.TheaterShowTimeList)
</div>
Here is my partial view :
#model IEnumerable<Bookmany.Core.Domain.TheaterShowTime>
<table class="table">
<tr>
<th>
Theater Name
</th>
<th>
#Html.DisplayNameFor(model => model.ShowTimeName)
</th>
<th></th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Theater.TheaterName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TheaterShowTimeID }) |
#Html.ActionLink("Details", "Details", new { id = item.TheaterShowTimeID }) |
#Html.ActionLink("Delete", "Delete", new { id = item.TheaterShowTimeID })
</td>
</tr>
}
My action method :
public ActionResult Index()
{
var model = new TheaterShowTimeViewModel();
//Bind Theater dropdown with selected value
model.AvailableTheaters = GetTheaters();
model.TheaterShowTimeList = _theaterShowTimeService.GetAllTheaterShowTime();
return View(model);
}
[HttpPost]
public ActionResult Index(TheaterShowTimeViewModel model)
{
if (ModelState.IsValid)
{
InsertOrUpdateTheaterShowTime(model);
model.TheaterShowTimeList=_theaterShowTimeService.GetAllTheaterShowTime();
return PartialView("_TheaterShowTimeList", model.TheaterShowTimeList);
}
return View(model);
}
my problems :
when I enter one value in the field and submit the form ,the entry saved now the partial view is only returned with the updated list
I want to update the partial view without reloading the whole page how do achieve that?
Like Stephen Muecke said I posted the form using ajax when the submit button clicked
<script type="text/javascript" >
$(function () {
$('form').submit(function () {
if ($(this).valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
$('#ShowTimeName').val("");
$('#theaterShowList').html(result);
}
});
}
return false;
});
});
</script>
In my action method which returns the partial view :
[HttpPost]
public ActionResult Index(TheaterShowTimeViewModel model)
{
if (ModelState.IsValid)
{
InsertOrUpdateTheaterShowTime(model);
model.TheaterShowTimeList=_theaterShowTimeService.GetAllTheaterShowTime();
//return RedirectToAction("Index", new { id = model.TheaterID });
//return Json(model.TheaterShowTimeList);
return PartialView("_TheaterShowTimeList", model.TheaterShowTimeList);
}
return View(model);
}
this resolved my issue
i have added extra three input fields to my view to enable the system admin to submit four objects at the same time instead of one object at a time; the view looks as the following:-
#model Elearning.Models.Answer
#{
ViewBag.Title = "Create";
}
<div id = "partialWrapper">
#using (Ajax.BeginForm("Create", "Answer", new AjaxOptions
{
HttpMethod = "Post",
InsertionMode = InsertionMode.InsertAfter,
UpdateTargetId = "incrementanswer",
OnSuccess = "removePartial",
LoadingElementId = "progress2"
}))
{
<div id = "returnedquestion">
#Html.ValidationSummary(true)
<fieldset>
<legend>Answer here</legend>
<ol>
<li> <div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.TextBox("answer[0].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>
</li>
<li> <div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.TextBox("answer[1].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> </li>
<li> <div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.TextBox("answer[2].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> </li>
<li> <div class="editor-label">
#Html.LabelFor(model => model.Description)
</div>
<div class="editor-field">
#Html.TextBox("answer[3].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> </li>
<ol>
</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>
and the following Post Ation Method:-
[HttpPost]
public ActionResult Create(int questionid, ICollection<Answer> answer)
{
if (ModelState.IsValid)
{
foreach (var a in answer){
repository.AddAnswer(a);
repository.Save();
}
return PartialView("_details2",answer);
}
return View("_details2",answer);}
and last thing the _details2 partial view which contains the newly added objects:-
#model IEnumerable<Elearning.Models.Answer>
#{
ViewBag.Title = "Details";
}
#foreach (var m in Model)
{
<tr id = #m.AnswersID>
<td>
#Html.DisplayFor(modelItem => m.Description)
</td>
<td>
#*#Html.DisplayFor(modelItem => Model.Answer_Description.description)*#
#ViewBag.Answerdesription
</td>
<td>
#Ajax.ActionLink("Delete", "Delete", "Answer",
new { id = m.AnswersID },
new AjaxOptions
{
Confirm = "Are You sure You want to delete this Answer ?",
HttpMethod = "Post",
UpdateTargetId = #m.AnswersID.ToString(),
OnSuccess = "removePartial2"
})
</td>
</tr>
}
but the above is not working nethier the objects will be added nor the partial view will be returned , so how i can solve this issue???
BR
You bind your view to a single Elearning.Models.Answer object, how are you expecting to get a collection of Answers as a parameter in your Action? The default model binder will try to bind your view fields to the parameter in the Action but it won't be able to as it's a collection.
What you could try to do is to bind your View to a List<Elearning.Models.Answer> and feed it 4 empty Answer objects, then you can create a strongly typed Partial view that expects one Elearning.Models.Answer, add the Partial in a foreach and, when posting the form, expect that the default model binder does it work and fill your action method with a brand new List of Answer objects.
As an alternative, you can create a View Model object that contains the fields in your View, including those 4 description fields. You add them as Html.TextboxFor to bind each of them to a different property in the View Model. Then you can collect them in your action, provided you change it to public ActionResult Create(int questionid, ViewModelAnswer answer)
Does it make sense?
Your model should contain a list and code like this:
#for (int i=0; i < Model.FavouriteMovies.Count; i++) {
#Html.LabelFor(model => model.YourList[i].Field)
#Html.EditorFor(model => model.YourList[i].Field)
#Html.ValidationMessageFor(model => model.YourList[i].Field)
}
which will print something like:
<label for="YourList_0__Field">Field Name</label>
The Field Name field is required.
And receive the model back in your controller:
public ActionResult MyAction(MyModel model)
{
// First element?
model.YourList[0].
}