MVC 5 BeginCollectionItem remove item from the page - c#

I'm trying to remove items from a list that I created following This question. The add part of the functionality works just fine.
When I specify an event in the onclick event on the partial page I get a javascript error. "'Function Name' is undefined." Looking it over I think the onclick attribute isn't required if the jquery is working. However, even after updating it to work with the latest version of JQuery it isn't detecting a click event, or at least it isn't triggered.
Main_View just the relevant sections
<table id="pastSchoolContainer">
<tr>
<td>
<input type="button" id="addPastSchool" name="addPastSchool" value="Add School" />
</td>
</tr>
#foreach (var school in Model.SchoolsAttended)
{
Html.RenderPartial("_SchoolRemovablePartial", school, new ViewDataDictionary(ViewData)
{
TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "SchoolsAttended" }
});
}
</table>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).ready(function () {
$("#addPastSchool").click(function () {
$.ajax({
async: false,
url: '/Student/AddPastSchool',
}).success(function (partialView) {
$("#pastSchoolContainer").append(partialView);
return;
});
});
return;
});
$("#addPastSchool").on("click", ".deleteRow", function () {
$(this).parents("#pastSchool:first").remove();
return false;
});
</script>
}
_SchoolRemovablePartial
#model ScholarSponsor.Models.SchoolModel
#using ScholarSponsor.Helper
#using (Html.BeginCollectionItem("pastSchool"))
{
<tr id="pastSchool">
<td>
#Html.EditorForModel()
<br />
#*Delete*#
<input type="button" class="deleteRow" value="Remove School" onclick="remove()" />
</td>
</tr>
}

Extending Stephen's answer the remove function needs to be inside a function that runs when the document is ready. Also, the button shouldn't have an onclick attribute.
The relevant code sections look like this.
Main_View
<table id="pastSchoolContainer">
<tr>
<td>
<input type="button" id="addPastSchool" name="addPastSchool" value="Add School" />
</td>
</tr>
#foreach (var school in Model.SchoolsAttended)
{
Html.RenderPartial("_SchoolRemovablePartial", school, new ViewDataDictionary(ViewData)
{
TemplateInfo = new TemplateInfo { HtmlFieldPrefix = "SchoolsAttended" }
});
}
</table>
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
$(document).ready(function () {
$("#addPastSchool").click(function () {
$.ajax({
async: false,
url: '/Student/AddPastSchool',
}).success(function (partialView) {
$("#pastSchoolContainer").append(partialView);
return;
});
});
$("#pastSchoolContainer").on("click", ".deleteRow", function () {
$(this).closest(".pastSchool").remove();
return;
});
});
</script>
}
_SchoolRemovablePartial
#model ScholarSponsor.Models.SchoolModel
#using ScholarSponsor.Helper
#using (Html.BeginCollectionItem("pastSchool"))
{
<tr class="pastSchool">
<td>
#Html.EditorForModel()
<br />
<input type="button" class="deleteRow" value="Remove School" />
</td>
</tr>
}

Related

How can I get my Popup to close on submit button from AJAX call in ASP.NET MVC?

I have a view that lists a bunch of items. I'm trying to make it so that when a user clicks on the "Action Event" for one of these items (from a table row), a pop-up will appear. The user can then update same information about this item, and either submit the information or close it. Regardless of which option they choose, I'm trying to get the pop-up window to close.
I'm 90% there, I just can't seem to work out one little detail - closing the popup after the submit button is pressed! A lot of the solutions I have seen don't appear to be working, and I just seem to be having some trouble tweaking them to work with my issue. Given the following code, what changes do I need to do to make this work?
Here is what I have:
View
Index.cshtml
<table>
#foreach (var item in Model)
<tr>
<td colspan="5" align="right">
Action Event
</td>
</tr>
}
</table>
<div id="myModal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
<div id="myModalContent"></div>
</div>
</div>
</div>
<script>
var TeamDetailPostBackURL = '/Database/Edit';
$(function () {
$(".anchorDetail").click(function () {
var $buttonClicked = $(this);
var id = $buttonClicked.attr('data-id');
var options = { "backdrop": "static", keyboard: true };
$.ajax({
type: "GET",
url: TeamDetailPostBackURL,
contentType: "application/json; charset=utf-8",
data: { "Id": id },
datatype: "json",
success: function (data) {
$('#myModalContent').html(data);
$('#myModal').modal(options);
$('#myModal').modal('show');
},
error: function () {
alert("Dynamic content load failed.");
}
});
});
});
</script>
Popup View
Edit.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.AID)
<table>
<tr>
<td>#Html.LabelFor(model => model.Comment)</td>
<td>#Html.TextAreaFor(model => model.Comment, new { #class = "form-control", rows = "5" })</td>
</tr>
<tr>
<td><input type="submit" value="Save" class="btn btn-primary" id="btnSave"/></td>
<td><button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button></td>
</tr>
</table>
</div>
}
Controller
DatabaseController.cs
public ActionResult Index()
{
return View(db.ActionableEvents.ToList());
}
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ActionableEvents actionableEvents = db.ActionableEvents.Find(id);
if (actionableEvents == null)
{
return HttpNotFound();
}
return View(actionableEvents);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "AID,Comment")] ActionableEvents actionableEvents)
{
if (ModelState.IsValid)
{
db.Entry(actionableEvents).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(actionableEvents);
}
I did see this resource here: asp.net submit button close Jquery Ajax, but I'm just not seeing how I would be able to tweak this into what I've got going on right now.
The cancel button I have right now works perfectly. Is there some way to use data-dismiss for my submit button and have it still save the data like I have for the cancel button? I've also seen some solutions use an onClick() parameter in the submit button, but then it would use a window.close() option. I don't want the entire window to close, nor do I want the user to be prompted about it either.
What is a good way I can approach this problem? I want my submit button to work just like my cancel button, only save the data. Thanks in advance for any advice!!!
Can you try the following in your Index.cshtml (make sure you set an id for the form and correct it below):
$("form").submit(function(){
$('#modal').modal('toggle');
});
If you want to make an AJAX request to the server and save the data you can do as follows (just include the code below in a click event on the dismiss button from the modal):
$.ajax({
type: "POST",
url: "SaveData",
content: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(data),
success: function (result) {
// do something
},
error: function (result) {
// do something
}
});
And have a MVC action similiar to:
[HttpPost]
public JsonResult SaveData()
{
// save data
}
Edit:
After a second reading of your question, you need to make Edit.cshtml a partial view, then on Index.cshtml include your partial view in the div for the modal like this:
<div id="myModal" class="modal">
<div class="modal-dialog">
<div class="modal-content">
#Html.Partial("_EditView")
</div>
</div>
</div>
And your JS should look like this:
$("form").submit(function () {
e.preventDefault();
formData = $(this).serialize();
$.ajax({
type: "POST",
url: "SaveData",
content: "application/json; charset=utf-8",
dataType: "json",
data: formData ,
success: function (result) {
// do something
},
error: function (result) {
// do something
}
});
$('#modal').modal('toggle');
});
The JS should be in the Index.cshtml because that's where your partial exists, try it and you'll see.
So, after a lot of playing around, I was able to come up with the following solution:
View
Index.cshtml
<table>
#foreach (var item in Model)
<tr>
<td>
<button class="btn btn-primary" onclick="ActionAway(#item.AID)">Action Event</button>
</td>
</tr>
}
</tbody>
</table>
<div class="modal fade" id="myModal1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
×
<h3 class="modal-title">Action This Event</h3>
</div>
<div class="modal-body" id="myModalBodyDiv1">
</div>
</div>
</div>
</div>
</div>
<script>
var ActionAway = function (theid) {
var url = "/Database/Edit?id=" + theid;
$('#myModalBodyDiv1').load(url, function () {
$('#myModal1').modal("show");
})
}
</script>
Pop-up View
Edit.cshtml
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.AID)
<table>
<tr>
<td>#Html.LabelFor(model => model.Comment)</td>
<td>#Html.TextAreaFor(model => model.Comment, new { #class = "form-control", rows = "5" })</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Save" class="btn btn-primary" id="btnSave"/>
<button type="button" class="btn btn-primary" data-dismiss="modal">Cancel</button>
</td>
</tr>
</table>
</div>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
<script>
$(document).ready(function () {
$("#btnSave").click(function () {
$.ajax({
success: function () {
$("#myModal").modal("hide");
}
})
})
})
</script>
The controller I was able to leave as it was without making any changes. Thanks again for all the help!

PartialView dosen't appear on click

I have trouble getting my partial view appear in the "div" when I click on a button. I can see that it fetches the data when I debug, but does not display it. Anybody that might now the problem?.
View
#model IEnumerable<ActiveDirectorySearch.Models.UserModel>
<div id="searchList">
<table>
#foreach (var user in #Model)
{
<tr>
<td>
<ul class="user" data-user-id="#user.DistinguishedName">
<li><b>#user.DisplayName</b></li>
<li><i>Cdsid:</i> #user.CdsId</li>
<li><i>Name:</i> #user.GivenName #user.SurName</li>
<li><i>Title:</i> #user.Title</li>
<li><i>Department:</i> #user.Department</li>
<li><i>MemberOf:</i> Groups</li>
<li class="userInfo">More Info</li>
<li>
</li>
</ul>
</td>
</tr>
}
</table>
<div class="col-md-6 col-md-offset-3 display-groups">
</div>
</div>
Controller
public ActionResult GetUserInfo(string searchTerm)
{
GroupRepository groupRepository = new GroupRepository();
var groups = groupRepository.FindGroups(searchTerm);
return PartialView(groups);
}
Script
<script>
$(function () {
$('.LoadGroupsViewButton').click(function () {
var self = this;
var $user = $(self).closest('.user');
var userDistinguisedName = $user.data("user-id");
$.ajax({
method: "GET",
url: 'Home/GetUserInfo',
data: { searchTerm: userDistinguisedName }
}).done(function (data) {
$(self).find('.display-groups').html(data);
});
});
});
</script>
change your code from
$(self).find('.display-groups').html(data);
to
$("#searchList").find('.display-groups').html(data);
as here 'self' is the DOM element that triggered the event because of this piece of code
var self = this;
So it will not find div having class 'display-groups'

MVC 5 - jQueryUI Dialog View not displaying

I am working on a MVC website and for my delete function I decided to use jQuery UI Dialog to display a popup style dialog box for the user to confirm that they wish to delete the object. My problem is that it is not displaying as intended, when I select to delete I can see my partial view dialog popup for a split second before I am redirected to another page that displays my confirmation message and the button to delete.
This is my delete controller:
//Deletes a selected club
[HttpGet]
public ActionResult DeletePartialView(int? id) //Original: public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Club club = db.Clubs.Find(id);
if (club == null)
{
return HttpNotFound();
}
return PartialView(club);
}
[HttpPost, ActionName("DeletePartialView")]
public ActionResult DeleteConfirmed(int id) //Original: public ActionResult DeleteConfirmed(int id)
{
Club club = db.Clubs.Find(id);
var MembersToDelete = club.ClubMembers.ToList();
foreach (var item in MembersToDelete)
{
db.ClubMembers.Remove(item);
}
db.Clubs.Remove(club);
db.SaveChanges();
return RedirectToAction("Index");
}
This is the Delete button and the partial view in its div:
#Html.ActionLink("Delete", "Delete", new { id = item.ClubID }, new { #class = "btn btn-danger btn-xs" }) |
#*#Html.ActionLink("Delete Partial", "DeletePartialView", new { id = item.ClubID }, new { #class = "btn btn-danger btn-xs" })*#
#Html.ActionLink(
"Delete Partial",
"DeletePartialView",
new { id = item.ClubID },
new
{
#class = "btn btn-danger btn-xs",
id = "deleteClub-opener" //Button ID
})
#* Delete Club Popup*#
<div id="DelteClub-dialog" title="Delete Club">
#Html.Partial("DeletePartialView", new ultimateorganiser.Models.Club())
</div>
This is the jQuery code:
//Delete Club Dialog Window with effects
$(function () {
$("#DelteClub-dialog").dialog({
autoOpen: false,
height: 500,
width: 600,
show: {
effect: "clip",
duration: 500
},
hide: {
effect: "highlight",
duration: 1000
}
});
//Open Delete Club Dialog Window
$("#deleteClub-opener").click(function () {
$("#DelteClub-dialog").dialog("open");
});
})
;
This is how it is currently displaying:
This is what my DeletePartialView looks like:
#model ultimateorganiser.Models.Club
#{
ViewBag.Title = "Delete";
}
<h3 class="text-warning">Are you sure you want to delete this club?</h3>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-danger" />
#Html.ActionLink("Back to List", "Index")
</div>
}
So far your are good now. To make the delete work add following in your Delete partial view after begin form
<input type="hidden" name="id" value="#Model.Id"/>
please check this code.and tell me another problem for using the dialog box.
only use this library
<html>
<head>
<link href="~/library/jquery-ui.min.css" rel="stylesheet" />
<script src="~/library/jquery.js"></script>
<script src="~/library/jquery-ui.min.js"></script>
</head>
<div>
<button id="btnCreate" class="btn-btn-primary">open the dialog</button>
</div>
<script type="text/javascript">
$(document).ready(function () {
$(function () {
$.noConflict(true);
$("#dialog").dialog({
autoOpen: false,
draggable: true,
resizable: true,
dialogClass: "alert",
modal: true
});
$("#btnCreate").click(function () {
$('#dialog').dialog('open');
});
});
});
<body>
<div id="dialog" style ="display:none" class="form" title="Basic dialog">
<table>
<tr>
<th>Name</th>
</tr>
<tr>
<th>Name</th>
<td><input type ="text" id="txtName" style= "width:200px" />
</tr>
<tr>
<th>Age</th>
<td><input type ="text" id="txtAge" style= "width:200px" />
</tr>
<tr>
<td><input type="submit" value="Create" id="btnCreateId" class="btn btn-Sucess" />
<td><input type="button" value="Cancel" id="txtCancel" class="btn btn-danger"/>
</tr>
</table>
</div>
</body>
<html>
You can use preventDefault in the jQuery binding.
$("#deleteClub-opener").click(function (e) {
e.preventDefault();
$("#DelteClub-dialog").dialog("open");
});
Alternatively, you can also return false in the binding function to prevent event propagation.

Redirect to Action-Controller MVC 4 inside Jquery

I need a little help with this since I am very new to AJAX in general. In a given page that I have (a view) I display a button which brings up a form. What I ultimately want is to pass the data input in that form to a controller inside my application. I know there are plenty of tutorials on how to do it out there...however, I seem to have a problem understanding how this is done; therefore, I want to traverse this step-by-step. I just simply want to display a different view after the user clicks on the "Save" button on the dialog. I hope that is clear. Here is my HTML + jQuery
#model AccommodationEditViewModel
#{
ViewBag.Title = "Edit";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<table>
<tr>
<td>
#Html.ActionLink("Back to list", "List", "Accommodation")
</td>
</tr>
<tr>
<td>
#if ( Model.Accommodation.LocaleID != Guid.Empty)
{
#Html.DisplayAccommodation(IAccommodationDisplay);
}
</td>
</tr>
</table>
<div class="genericform">
<form id="form" method="post">
#Html.AccommodationEditDisplay()
<table>
<tr>
<td>
#Html.ActionLink("Add New Address", "", "", new { id = "addaddresses" }, null)
</td>
</tr>
#if (Model != null && Model.Accommodation.Addresses.Count() == 0)
{
<tr>
<td>
This Locale Contains No Addresses
</td>
</tr>
}
else
{
foreach (Address address in Model.Accommodation.Addresses)
{
<tr>
<td>
#address.Address1
</td>
</tr>
}
}
</table>
<br /> <br />
<input type="submit" name="command" value="Save" />
<input type="submit" name="command" value="Delete" />
</form>
</div>
<button id="opener">Add Address</button>
<div id="dialog" title="Add Address" style="display:none;">
<label for="Address1">Address: </label><input id="Address1" />
<label for="Address2">Address 2: </label><input id="Address2" />
<label for="City">City: </label><input id="City" />
<label for="State">State: </label><input id="State" />
<label for="PostalCode">Postal Code: </label><input id="PostalCode" />
</div>
<script type="text/javascript" src="~/Scripts/jquery-1.7.1.js"></script>
<script type="text/javascript" src="~/Scripts/jquery-ui-1.8.20.js"></script>
<link type="text/css" href="~/Content/themes/base/jquery.ui.all.css" rel="stylesheet" />
<script type="text/javascript">
$(document).ready(function () {
$("#dialog").dialog({
autoOpen: false,
show: {
effect: "explode",
duration: 250
},
hide: {
effect: "explode",
duration: 250
},
buttons: {
"Save": {
text: "Save",
class: "",
click: function () {
//**redirect here**
$(this).dialog("close");
}},
"Cancel": {
text: "Cancel",
class: "",
click: function () {
$(this).dialog("close");
}
}},
modal: true
});
$("#opener").click(function () {
$("#dialog").dialog("open");
});
});
</script>
I have tried using $.ajax({}) and setting this: Url: "/Areas/Website/Controller/Action
but scripting stops working at that point.
Any and all help is appreciated! Thank you!
EDIT
Do I even need to use AJAX at all? I just want to pass the information in that form (inside the dialog) to a controller.
Ok, try replacing your <form id="form" method="post"> form fields </form> with
#using (Html.BeginForm("NameOfControllerMethod", "NameOfControllerClass"))
{
<!-- fields for gathering data, your input fields essentially -->
}
THEN you need to go to your controller class, and add [HttpPost] above your controller method, like this:
[HttpPost]
public ActionResult MethodName(AccomodationEditViewModel viewModel) {
//do stuff in here with the viewModel, for example viewModel.Location, or viewModel.Name
}
NOTE that the [HttpPost] requires that you add a new "using" insert at the top of your controller class.
The NameOfControllerMethod is the method that has the HttpPost above it. The name of the controller class is like "MyClass", coming from the controller named MyClassController, as an example.
Try this:
window.location = "/Areas/Website/Controller/Action";
inside your click function.

MVC Razor button click even pass parameter with it

I'm new to MVC Razor.
I have this view:
#model SuburbanCustPortal.Models.CustomerModel
#{
ViewBag.Title = "Customer Summary";
}
<h2>Customer Summary Screen</h2>
<p>
Please select an account below or add an existing account.
</p>
<script src="#Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true, "Account creation was unsuccessful. Please correct the errors and try again.")
<div>
<fieldset>
<legend>Existing Accounts</legend>
#Html.Action("ExistingAccounts2")
<p>
<input type="submit" value="Add an Account" />
</p>
</fieldset>
</div>
}
Which calls this method:
[Authorize]
public ActionResult ExistingAccounts2()
{
return PartialView("ExistingAccounts", _client.RequestCustomersForAccount(User.Identity.Name));
}
Which in turn calls this partial view:
#model IEnumerable<SuburbanCustPortal.SuburbanService.CustomerData >
<br />
<br />
<table>
#if (Model != null)
{
foreach (var usr in Model)
{
<tr>
<td>
<input id="btnShowCustomer" name="btnShowCustomer2" type="submit" value="View"/>
</td>
<td>
#usr.AccountId
</td>
<td>
#usr.Name
</td>
#* <td>
#usr.DeliveryStreet
</td>*#
</tr>
}
}
</table>
<br />
Which ends up displaying this:
This works up to this point.
What I want to so is be able to click on the button next to the customer's name and it pull up the customer's account.
How do I tie that customer to the button to know who to pull up and how do have the button click pull it up?
You need to pass the Customer Number back once the button is clicked:
If you have the customer number as a property in the Model you could do something like:
<input id="btnShowCustomer" data-customerNumber="#usr.CustomerNumber" />
You could then POST this data to the Server using an #Html.ActionLink, #Ajax.ActionLink, or jQuery:
Action Link
#Html.ActionLink("LoadInfo", "Info", new {customerId=#usr.CustomerNumber})
jQuery
$("#btnShowCustomer").click(function() {
var customerId = $("#btnShowCustomer").attr("data-customerNumber");
$.ajax({
type: "POST",
data: "customerId=" + customerId,
url: '#Url.Action("MyAction", "MyController")',
success: function (result) {
}
});
I think this would do the trick ! oid would be the id of the customer (i dont think the path is ok :) )
#Ajax.RawActionLink("Action", "Controller", new { oid = '#Model.customerID'}, new AjaxOptions { HttpMethod = "POST", UpdateTargetId = "the view you want to show" }, new { id = "btnNewB", #class = "your btn class" })
good luck ;)

Categories