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:
Related
I have a table view with list of roles and an action link to create new roles. Below is my roles.cshtml page
#model List<ExpenCare.Models.CompanyRole>
<div class="row">
#Html.Partial("_RightSidePane")
<div class="col-10 col-sm-8 col-xs-8 col-md-10">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade" id="list-Roles-Content" role="tabpanel" aria-labelledby="list-Roles"></div>
#using (#Html.BeginForm("UpdateRoles", "Admin", FormMethod.Post))
{
<table class="table">
<tr>
<th>
Name
</th>
<th>
Enable
</th>
</tr>
#for (var i = 0; i < Model.Count(); i++)
{
<tr>
<td>
#Html.HiddenFor(m => m[i].Id)
#Html.HiddenFor(m => m[i].Name)
#Html.DisplayFor(m => m[i].Name)
</td>
<td>
#Html.EditorFor(m => m[i].Enabled, new { #checked = "checked" })
</td>
</tr>
}
</table>
<p><input type="submit" value="Save Changes" /></p>
<p style="color:green; font-size:12px;">#ViewBag.Message</p>
<p>
#Html.ActionLink("Create new Roles", "ViewCreateRoles", "Admin", null, new { id = "CreateRoles", #class = "appao-btn" })
</p>
}
</div>
</div>
</div>
"Create new roles" button calls to ViewCreateRoles method in admin controller, which stated below.
public ActionResult ViewCreateRoles()
{
return View("Roles/CreateRoles");
}
In CreateRoles.cshtml page user can create a role and submit. when submitting it redirects to action CreateRoles in the same admin controller.
#model ExpenCare.Models.CompanyRole
#{
ViewBag.Title = "CreateRoles";
}
<div class="row">
#Html.Partial("_RightSidePane")
<div class="col-10 col-sm-8 col-xs-8 col-md-10">
<div class="tab-content" id="nav-tabContent">
<div class="tab-pane fade show active" id="list-Profile-Content" role="tabpanel" aria-labelledby="list-Profile">
#using (Html.BeginForm("CreateRoles", "Admin", FormMethod.Post))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="form-group">
#Html.LabelFor(model => model.Name, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Name, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Enabled, "Enable", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="checkbox">
#Html.EditorFor(model => model.Enabled)
#Html.ValidationMessageFor(model => model.Enabled, "", new { #class = "text-danger" })
</div>
</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>
</div>
</div>
</div>
Below is the CreateRoles methodin admin controller.
public ActionResult CreateRoles(CompanyRole role)
{
List<CompanyRole> roles;
HttpClient client = new HttpClient();
client.BaseAddress = new Uri("http://localhost:1888/api/");
var responseTask = client.PostAsJsonAsync("CompanyRoles", role);
responseTask.Wait();
var result = responseTask.Result;
if (result.IsSuccessStatusCode)
{
var readTask = result.Content.ReadAsAsync<List<CompanyRole>>();
readTask.Wait();
roles = readTask.Result;
return View("Roles/Roles", model: roles);
}
else
{
ViewBag.Message = "not updated.";
return View("Roles/CreateRoles");
}
}
After creating a role on success user is redirecting to roles.cshtml mentioned above which shows all the roles. My problem is that my process of adding a role (go to roles page-> create new role-> redirect to roles page) is working fine. But just after redirecting to the roles page I get "An exception of type 'System.Web.Http.HttpResponseException' occurred in ExpenCare.dll but was not handled in user code" error in my web api which is getting called in CreateRoles. when I debug the process I see that after going to "Dispose" method of admin contoller "CreateRoles" method is getting called again and null "CompanyRole role" data is passed to the web API. I dunno how it is getting called again. I checked in google and tried removing all "#" from href and src of my view and layout pages, but it is still not working. I can't find why the same method is getting called twice without the button click.
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'm trying to put tabs in a partial view which is inside a set of tabs already,the admin index view has a set of tabs which when selected render a partial view,I would like to put another set of tabs or side menu in this partial view but it doesn't seem to work,any suggestions would be great,thanks
This is the Admin index view
<script>
$(function () {
$("#tabs").tabs({
beforeLoad: function (event, ui) {
ui.jqXHR
}
});
});
</script>
<body>
<div id="tabs" >
<ul>
<li>All Users</li>
<li>Doctor</li>
<li>Staff</li>
</ul>
</div>
</body>
This is the partial view
<script>
$( function() {
$( "#tabs" ).tabs({
beforeLoad: function( event, ui ) {
ui.jqXHR.fail(function() {
ui.panel.html(
"Couldn't load this tab. We'll try to fix this as soon as possible. " +
"If this wouldn't be a demo." );
});
}
});
} );
</script>
<body>
<div id="tabs">
<ul>
<li>Add Doctor</li>
<li>Tab 1</li>
<li>Tab 2</li>
</ul>
<div id="tab1">
<h2>Create Doctor</h2>
#Html.ValidationSummary(false)
#using (Html.BeginForm("Create", "Doctor", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="form-group">
<label>First Name</label>
#Html.TextBoxFor(x => x.FirstName, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Last Name</label>
#Html.TextBoxFor(x => x.LastName, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Address</label>
#Html.TextBoxFor(x => x.Address, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Telephone</label>
#Html.TextBoxFor(x => x.Telephone, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Date Of Birth</label>
#Html.TextBoxFor(x => x.DOB, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Email</label>
#Html.TextBoxFor(x => x.Email, new { #class = "form-control" })
</div>
<div class="form-group">
<label>Password</label>
#Html.PasswordFor(x => x.Password, new { #class = "form-control" })
</div>
<button type="submit" class="btn btn-primary">Create</button>
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-default" })
}
</div>
</div>
</body>
You have 2 tab sets with the sameid... Generate a random id on your views, or whatever to make sure that your tab components are not bouncing against each other..
I followed an online tutorial to dynamically add items to a bound list model using ajax, which works perfectly. (http://www.mattlunn.me.uk/blog/2014/08/how-to-dynamically-via-ajax-add-new-items-to-a-bound-list-model-in-asp-mvc-net/comment-page-2/#comment-68909)
My question is, how would I correctly remove items from the list?
Right now what I have done is add a delete link which when clicked removes the item from the view. However, when I submit the form I noticed that the modelState is no longer valid and it has null entries for the item that was removed from the view. So I guess the model is not being updated.
Test.cshtml
#model TesterManager.Models.Test
<div class="form-group">
#Html.LabelFor(model => model.Software, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="form-group">
<div class="col-md-5">
#Html.DropDownListFor(m => m.Software, TesterManager.Models.Helper.GetTestSoftwares(), "Choose a USB Card", new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.Software, "", new { #class = "text-danger" })
</div>
<div class="col-md-5">
#Html.EditorFor(model => model.Version, new { htmlAttributes = new { #class = "form-control", #title = "Enter a USB FW Version", #placeholder = "Enter a USB FW Version" } })
#Html.ValidationMessageFor(model => model.Version, "", new { #class = "text-danger" })
</div>
<div class="col-md-2">
Delete
</div>
</div>
</div>
</div>
AdminTesterConfigurations.cshtml (snippet):
#model TesterManager.Models.AdminTesterConfigurations
<div class="form-group">
<div class="col-md-6">
....
</div>
</div>
<hr />
<div class="form-group">
<div class="col-md-12">
<h3>Test Software</h3>
<div id="test-list">
#Html.EditorForMany(x => x.Tests, x => x.Index)
</div>
<input type="button" id="add-test" value="Add" />
</div>
</div>
RequestEditViewModel.cshtml:
#model TesterManager.Models.RequestEditViewModel
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.EditorFor(model => model.ShippingLocation)
#Html.EditorFor(model => model.RequesterTesterConfigurations)
#Html.EditorFor(model => model.AdminTesterConfigurations)
<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>
Edit.cshtml:
#model TesterManager.Models.RequestEditViewModel
#Styles.Render("~/Content/Edit")
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#section Scripts
{
<script>
jQuery(document).ready(function ($) {
$('#add-test').on('click', function () {
jQuery.get('/TesterManager/Request/AddTest').done(function (html) {
$('#test-list').append(html);
});
});
});
</script>
}
#using (Html.BeginForm())
{
<h2>Edit</h2>
#Html.AntiForgeryToken()
#Html.EditorFor(x => x);
}
<div>
#Html.ActionLink("Back to List", "Index")
</div>
RequestController.cs
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(RequestEditViewModel request)
{
if (ModelState.IsValid)
{
Request domainRequest = new Request(request);
requests.Add(domainRequest);
return RedirectToAction("Index");
}
return View(request);
}
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public ActionResult AddTest()
{
var request = new RequestEditViewModel();
request.AdminTesterConfigurations.Tests.Add(new Test());
return View(request);
}
I realized that the problem was that when I would remove the item from the list in the view, I was not removing the hidden input for the collection indexer as well. I updated the code to remove the hidden input and it works fine now.
I am trying to populate a 'transaction model' form with previously entered data if the user wants to 'edit' the transaction. The transaction is being passed into the View as a IEnumerable<Transaction>. I'm displaying each transaction in a table with each row containing a transaction and actions that can be performed on it. Once the user clicks edit I've set up a modal to popup with the form inside. In order to populate the form I've created a jquery GET request each time the user clicks on edit this requests retrieves the transaction from the database and returns the properties that I want as json data. The problem is that this request works for the first transaction in the IEnumerable.
Here is my View:
<div class="row">
<div class="col-sm-12">
<table class="table table-bordered table-hover" cellspacing="0" width="100%" id="TransactionTable">
<thead>
<tr>
<th>Date</th>
<th>Description</th>
<th>Category</th>
<th>Amount</th>
<th>Reconciled</th>
<th>Updated By</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
#foreach (var t in Model.Transactions)
{
<tr>
<td>#t.Created</td>
<td>
#t.Description
</td>
<td>
#t.Category.Name
</td>
<td>
#t.Amount
</td>
<td>
#if(t.Reconciled == 0)
{
<span class="fa fa-check-square-o"></span>
}
else
{
#t.Reconciled
}
</td>
<td>
#t.UpdatedBy.DisplayName
</td>
<td>
<!--Edit Modal Begin-->
<div class="modal fade" id="edit-#t.Id" tabindex="-1" role="dialog" aria-hidden="true">
<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">Edit Transaction <span class="fa fa-pencil fa-2x"></span></h4>
</div>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
#Html.HiddenFor(m => m.AccountId)
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
<div class="modal-body">
<!--Description-->
<div class="form-group">
#Html.LabelFor(m => m.Transaction.Description, htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(m => m.Transaction.Description, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Transaction.Description, "", new { #class = "text-danger" })
</div>
<!--Amount. +/- -->
<div class="form-group">
#Html.LabelFor(m => m.Transaction.Amount, htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(m => m.Transaction.Amount, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Transaction.Amount, "", new { #class = "text-danger" })
#Html.RadioButtonFor(m => m.Transaction.IsIncome, true, new { #checked = true, }) Deposit
#Html.RadioButtonFor(m => m.Transaction.IsIncome, false) Purchase
</div>
<div class="form-group">
#Html.LabelFor(m => m.Transaction.Reconciled, htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(m => m.Transaction.Reconciled, new { #class = "form-control" })
#Html.ValidationMessageFor(m => m.Transaction.Reconciled, "", new { #class = "text-danger" })
</div>
<div class="form-group">
<div class="ui-widget">
#Html.LabelFor(m => m.Transaction.Category, "Category", htmlAttributes: new { #class = "control-label" })
#Html.DropDownList("CategoryId", null, "-- select a category --", htmlAttributes: new { #class = "form-control", id = "categories" })
#Html.ValidationMessageFor(m => m.Transaction.Category, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(m => m.Transaction.Created, "Date", htmlAttributes: new { #class = "control-label" })
#Html.TextBoxFor(m => m.Transaction.Created, new { #class = "form-control", id = "datepicker1" })
</div>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-primary">Update</button>
<button type="reset" class="btn btn-success">Reset</button>
<button type="button" class="btn btn-facebook" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
}
</div>
</div>
</div>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<a href="#Url.Action("Index", "HouseAccount", new {householdid = Model.Account.HouseHoldId })" >Back to List <<</a>
</div>
</div>
The Javascript below the view:
#section page{
<script src="//cdn.datatables.net/plug-ins/1.10.7/integration/bootstrap/3/dataTables.bootstrap.js"></script>
<script src="/Scripts/jquery-ui.min.js"></script>
<script src="/Scripts/bootstrap-datepicker.js"></script>
<script type="text/javascript">
$('#editform').click(function (e) {
$.ajax({
type: 'GET',
url: '/Transaction/EditTransactionInfo/',
dataType: 'json',
contentType: 'application/json',
data: { transId: $("#editform").data('transaction-id') },
success: function (data) {
alert(data.Description);
}
})
})
$('#TransactionTable').DataTable();
$('#datepicker1').datepicker();
</script>
}
And my request controller action:
[HttpGet]
public JsonResult EditTransactionInfo(int transId)
{
var trans = db.Transactions.Find(transId);
return Json(new { Description = trans.Description,
Amount = trans.Amount,
}, JsonRequestBehavior.AllowGet);
}
You're outputting your <a id=#editform> in a loop, which means you're producing MULTIPLE duplicate IDs. DOM ids MUST be unique through the entire document.
Since you have duplicates, $('#editform') will return only the FIRST matching element it finds - it will not return any others, since it's not supposed to.
Either change to using a class instead of an id to tag the <a> elements, or use the event you capture inside the on-click and extract the click target from that instead.
You create multiple ID's for DOM. Instead id use class attribute inside foreach and $(".className") in your jQuery selectors.