ASP.NET MVC Refresh usercontrols - asp.net-mvc

ASP.NET MVC
I have one page Index.aspx where I'm loading two usercontrols into divs. This is working fine. For the moment the usercontrols just shows data and thats working fine. But now I want to add a delete function in the usercontrols and then refresh the div in the Index.aspx page. Is this possible?
Index.aspx
<!-- Panel One -->
<div id="panel1">
<img src="/Content/ajax-loader.gif" alt="Loading..." />
</div>
<script type="text/javascript">
$('#panel1').load('../Reports/ReportOne')
</script>
<!-- Panel Two -->
<div id="panel2">
<img src="/Content/ajax-loader.gif" alt="Loading..." />
</div>
<script type="text/javascript">
$('#panel2').load('../Reports/ReportTwo')
</script>
ReportOne.ascx and ReportTwo
Just listing some data with a foreach. Here I want to add a deletebutton for each item in the lists.

Make your "delete" action into something like this:
[AcceptVerbs(HttpVerbs.Post), ValidateAntiForgeryToken]
public ActionResult Delete(int id) {
try {
// do what ever here in deleting the record etc
// ...
return null;
} catch (Exception ex) {
TempData[TempDataKeys.ErrorMessage] = "Error in deleting: " + ex.Message;
return RedirectToAction("List");
}
}
In you ascx/aspx, create a jQuery method to wrap your ajax call to the controller:
function deleteRecord(recordId) {
if (confirm("Are you sure that you want to delete this record?")) {
var token = $("input[name='__RequestVerificationToken']")[0].value;
url = '<%= Url.Action("Delete", "MyController") %>';
$.post(
url,
{ id: recordId, __RequestVerificationToken: token },
function(data) {
if (!data == "") {
// success - reload/refresh panel control
$('#panel1').load('../Reports/ReportOne');
} else {
// failed - handle error
}
}
);
}
}
You will need to put your AntiForgeryToken appropriately so the script can access it - you only need 1 for the whole page. Your delete link should then call to the javascript, instead of to the action in the controller directly:
Delete

When the user clicks on the delete button inside the user control you could invoke an action that will delete the necessary information from the database and return a partial view refreshing the control. So put a delete link inside the control:
<%= Html.ActionLink("Delete", "DeleteReportOne", null, new { id = "deleteReportOne" }) %>
and then inside the main page register the click callback for this link:
$(function() {
$('#deleteReportOne').click(function() {
$('#panel1').load(this.href);
});
});

You may use JQuery UI tabs to add and remove the content from the page
JQuery UI Manipulate tabs
JQuery Tabs and ASP.NET MVC Partial Views

you need to modify your user controls

Related

return partialview after httppost asp.net mvc

I am creating a web app in asp.net mvc
I have a partial view to reset password which opens inside bootstrap modal,
now on HttpPost I have a if condition which looks like below
if (string.IsNullOrEmpty(model.NewPassword))
{
TempData["PMessage"] = CustomHelper.Translate("Please Enter new Password");
return PartialView(model);
}
but my main url is changing to this partial view like below
http://localhost:8080/User/ResetPassword
here ResetPassword is my partialview name
my partialView looks like below
#(Html.BeginForm("ResetPassword", "User", FormMethod.Post))
{
<div class="modal-dialog modal-sm">
<!-- Modal data-->
</div>
}
my full post method
[HttpPost]
public ActionResult ResetPassword(ResetPasswordModel model)
{
if (string.IsNullOrEmpty(model.NewPassword))
{
TempData["PMessage"] = "Please Enter new Password";
return PartialView(model);
}
//if success
return RedirectToAction("Index");
}
how can I prevent this, I just want to load modal and not whole page,
what can be the fixes here?
or Should I go for client side validation?
Page flow in detail
this is how my page looks
if the user clicks on reset password, the below bootstrap modal appears
without entering any data if user clicks on OK, post method has been called and the page is being redirected to resetpassword.cshtml as I am returning like below
return PartialView(model);
what I need to do if I only want to refresh modal/partial view on validation on controller
You are making normal HTTP request it's used to handle regular browser calls (like form submits) and return full HTML pages to client.
In your case you have to make ajax request to handle ResetPassword post method to avoid redirect.
<!-- modal placeholder-->
<div id='myModal' class='modal fade in'>
<div class="modal-dialog">
<div class="modal-content">
<div id='myModalContent'></div>
</div>
</div>
</div>
this url return your reset form and load it into a modalcontent
<a href="#Url.Action("Reset", "Account", new { class = "resetpassword" })" ></a>
$(function () {
$(document).on("click", "a.resetpassword", function (e) {
$('#myModalContent').load(this.href, function () {
$('#myModal').modal({
/*backdrop: 'static',*/
keyboard: true
}, 'show');
bindForm(this);
});
return false;
});
});
function bindForm(dialog) {
$('form', dialog).submit(function (e) {
e.preventDefault();
if ($('#resetFormId').valid()) {
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.success) {
$('#myModal').modal('hide');
} else {
$('#myModalContent').html(result);
bindForm(dialog);
}
}
});
}
return false;
});
}

Partial View Dialog Events Do Not Work in Chrome

A partial view page (cshtml) is opened as a dialog by angularjs by a window click in a parent view page (cshtml), but the embedded component in the dialog does not respond to mouse inputs - eg it does not respond to clicks in chrome although it does in ie11.
specifically, I have a FileUltimate file browser control in the partial view page opened as a dialog. the cshtml is:
#using GleamTech.FileUltimate
#model FileManager
#using MyCompany.OWL.Website.Helpers
#{
Layout = null;
}
<head>
<title>File Browser</title>
#Html.RenderCss(Model)
#Html.RenderJs(Model)
</head>
<div class="overlay" id="fileBrowser">
<h1>File Manager<a href data-icon="×" data-ng-click="close()"></a></h1>
<div>
<div style="width:800px">
#Html.RenderControl(Model)
</div>
</div>
</div>
it is opened by an angularjs controller for the parent page
$scope.openFileManager = function () {
var modalItem = { project: $scope.item };
fileManager.openFileManager(modalItem);
};
which in turn calls
fileManagerFactory.factory('FileManager', ['$modal', function ($modal) {
return {
openFileManager: function (data) {
var modalInstance = $modal.open({
templateUrl: '/filemanager/filemanager?projectid=' + data.project.projectId,
controller: 'FileManagerController',
resolve: {
projectData: function () {
return data;
}
}
});
}
};
}]);
the associated mvc controller for the partial view is
[AccessAuthorize(Roles = "ProjectManagers")]
public ActionResult FileManager(int ProjectID)
{
FileManagerApiController api = new FileManagerApiController();
//return View(new[] { fileManager });
return PartialView("_FileManager",api.Get(ProjectID));
}
I am stumped for reasons why ie11 dialogs would work, but chrome and firefox would not. some keyboard input is processed by chrome, but no mouse. the failure is only on the fileultimate control. Does anyone know why the control does not respond in chrome? is it angularjs?
since the vendor does not believe that his control has a problem, I am exploring other ways of opening it without embedding it in a dialog cshtml, but my biggest problem is passing data from the parent view to the mvc controller of the file browser. the data is held in the html controls of the parent page and $scope variable which seems to preclude calling the control in a #Html.BeginForm. the file browser can only be opened after it is configured with record specific data in the parent window, and I cannot navigate away from the parent page. the file browser has its own stand alone ui.
ps - one other odd observance is that ie11, chrome44, and firefox33 render the dialog differently - 3 different renditions of the same cshtml.

MVC 4 - Unable to update a partial view via an Ajax call

I have an MVC 4 view that contains a partial view. The partial view is included in the main view as follows:
<div id="PartialView">
#Html.Partial("_PhotoList", #Model)
</div>
My partial view looks as follows:
#model ExchangeSite.Entities.EstateSaleSellerListing
<div style="width: 1300px; height: 300px; overflow: auto">
#foreach (var photo in #Model.ImageList)
{
<a href="javascript:DeletePhoto(#photo.ImageId);">
<img src="#Url.Action("GetPhoto", new { id = photo.ImageId })" alt="" title="Click on the image to remove it" width="250" height="190"/>
</a>
}
</div>
<script>
function DeletePhoto(imageId) {
var Url = "/EstateSaleSellerListing/DeletePhoto";
$.get(Url, { imageId: imageId }, function (data) {
$("#PartialView").html(data);
});
}
</script>
As you can see, when a user clicks on an image, the DeletePhoto() method is called. It makes a call to an action method named DeletePhoto on the named controller. The action method deletes the photo, generates a new list of photos and updates the partial view. Everything works except the partial view is never updated.
My controller code is as follows:
public ActionResult DeletePhoto(int imageId)
{
var photo = this._systemLogic.GetItem<Photo>(row => row.ImageId == imageId);
this._systemLogic.DeleteItem(photo);
EstateSaleSellerListing listing = new EstateSaleSellerListing();
GetPhotoList(listing);
return PartialView(listing);
}
The EstateSaleSellerListing entity has a list of photo objects that get displayed in the partial view.
I don't have enough experience to know why my partial view isn't updating when the action method returns.
Try to move your javascript to your main page and change
return PartialView(listing);
to
return PartialView("_PhotoList", listing);
Check your cache settings in jQuery (it looks like you're using jQuery by the syntax anyway). And I think your second parameter is a bit off (not assigning it to data)... Try this
<script>
function DeletePhoto(imageId) {
var Url = "/EstateSaleSellerListing/DeletePhoto";
$.get(Url, { cache: false, data: { imageId: imageId }}, function (data) {
$("#PartialView").html(data);
});
}
</script>
You could also have the controller method render the partial view to string if it is being loaded in a partial.
Controller...
model.PartialViewContent=PartialToString("Partials/SmallerPart",model);
return PartialView("Partials/LargerPart",model);
View
$("#PartialView").html(data.PartialViewContent);
Fyi, PartialToString is not built into mvc. I had to hack that together

Can you just update a partial view instead of full page post?

Is there a way to submit a partial view form in asp.net mvc without reloading the parent page, but reloading the partial view only to its new state? Similar to how knockout.js updates using data-bind.
My data table renders with a variable number of columns/names so I don't think knockout.js is an option for this one, so I am trying to use a partial view instead.
Not without jQuery.
What you would have to do is put your Partial in a div, something like:
<div id="partial">
#Html.Partial("YourPartial")
</div>
Then, to update (for example clicking a button with the id button), you could do:
$("#button").click(function () {
$.ajax({
url: "YourController/GetData",
type: "get",
data: $("form").serialize(), //if you need to post Model data, use this
success: function (result) {
$("#partial").html(result);
}
});
})
Then your action would look something like:
public ActionResult GetData(YourModel model) //that's if you need the model
{
//do whatever
return View(model);
}
Actually, if your Partial has a child action method, you can post (or even use an anchor link) directly to the child action and get an Ajax-like affect. We do this in several Views.
The syntax is
#Html.Action("MyPartial")
The Child Action is
public ActionResult MyPartial()
{
return PartialView(Model);
}
If your form posts to the child action
#using (Html.BeginForm("MyPartial"))
{
    ...
}
The Partial View will be updated with the partial view returned from the child action.
Jquery is still a legitimate way to update a partial. But technically, the answer to your question is YES.
As normal what I find when looking for things like this is people give too limited information so I will attempt to help here. The key is to set up a div with an ID you can append the return html to. Also when hitting your controller make sure it returns the partial. There are some potential problems with this method but on a good day it should work.
<div id="CategoryList" class="widget">
#{
Html.RenderPartial("WidgetCategories.cshtml");
}
</div>
function DeleteCategory(CategoryID) {
$.get('/Dashboard/DeleteWidgetCategory?CategoryID=' + CategoryID,
function (data) {
if (data == "No") {
alert('The Category has report widgets assigned to it and cannot be deleted.');
}
else {
$('#CategoryList').html(data);
}
}
);
}
[HttpGet("DeleteWidgetCategory")]
[HttpPost("DeleteWidgetCategory")]
public IActionResult DeleteWidgetCategory(string CategoryID)
{
string Deleted = CategoryModel.DeleteCategory(CategoryID);
if (Deleted == "Yes")
{
return PartialView("WidgetCategories");
}
else
{
return this.Json("No");
}
}
I would use the Ajax Form helper for such scenarios using a partial view and #html.RenderPartial("partialName")
partial helpers
In your Main View
<div id=SearchResult>
#Html.Partial("_NameOfPartialView", Model)
</div>
<input type="button" id="btnSubmit" value="Submit">
In your Javascript file
$('#btnSubmit').click(function () {
GetData(Id);
});
function GetData(Id){
$.ajax({
url: "/Home/GetEmployee/",
type: "get",
data: { Id:Id },
success: function (result) {
$('#SearchResult').html(result);
}
});
}
In your Home Controller
public ActionResult GetEmployee(int Id)
{
var employee= context.Employee.Where(x=> x.EmployeeId == Id)
return this.PartialView("_NameOfPartialView", employee);
}

MVC - Need to pass data from View to Controller

I need to pass some information I have in a view to the controller.
When it goes to the controller, I like to then send out an email with that information.
I was thinking about using the #HTML.ActionLink the view but from my understanding, that goes to an ActionResult which I do not want as I want to be able to send out an email and not go back to the View.
Here is a way to do it with the post being done through jquery. There are other options but this was fresh in my mind since I just did it the other day.
HTML and javascript
#using (Html.BeginForm())
{
<input type="submit" value="SendEmail" onclick="SendEmail(); return false;" />
}
<script type="text/javascript">
function SendEmail() {
$.post('PathToController/SendEmail',
{
parameter: parameterValue
})
.success(function (result) {
// Display a message that the email was sent????
});
}
</script>
Controller
[HttpPost, ActionName("SendEmail")]
public string SendEmail(parameters)
{
}
You could also let the page handle the post as normal and not use the jquery. If this is the case, then your parameters would need to match the IDs of your controls you would need to use.

Resources