Reputation: 3447
I have a partial view on a cshtml page as follows :-
@model MvcCommons.ViewModels.CompositeViewModel
@{
ViewBag.Title = "Edit";
}
@using (Html.BeginForm()) {
@Html.ValidationSummary(true)
<fieldset>
<legend>Article</legend>
@Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID)
<div class="editor-label">
@Html.LabelFor(model => model.ArticleViewModel.Article.CategoryID, "Category")
</div>
<div class="editor-field">
@Html.DropDownListFor(model => model.ArticleViewModel.Article.CategoryID, (SelectList)ViewBag.CategoryID)
@Html.ValidationMessageFor(model => model.ArticleViewModel.Article.CategoryID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ArticleViewModel.Article.ArticleTitle)
@Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleTitle)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.ArticleViewModel.Article.ArticleDate)
@Html.ValidationMessageFor(model => model.ArticleViewModel.Article.ArticleDate)
</div>
@Html.HiddenFor(model => model.PageViewModel.Page.PageTitle, new { id = "PageTitle" })
@Html.HiddenFor(model => model.PageViewModel.Page.PageAction, new { id = "PageAction" })
@Html.HiddenFor(model => model.ArticleViewModel.Article.ArticleID, new { id = "ArticleID" })
<div class="ImageGallery">
@Html.Partial("~/Views/Shared/ImageGallery.cshtml", Model)
</div>
</fieldset>
}
<div>
@Html.ActionLink("Back to List", "Index")
The ImageGallery.cshtml Partial View is as follows :-
@model MvcCommons.ViewModels.CompositeViewModel
@{
ViewBag.Title = "Modal image uploader";
}
<script type="text/javascript">
var pageTitle = $('#PageTitle').val();
var pageAction = $('#PageAction').val();
var id = $('#ArticleID').val();
$(document).ready(function () {
$('.modal_block').click(function (e) {
$('#tn_select').empty();
$('.modal_part').hide();
});
$('#modal_link').click(function (e) {
$('.modal_part').show();
var context = $('#tn_select').load('/Upload/UploadImage?Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id, function () {
initSelect(context);
});
e.preventDefault();
return false;
});
$('#delete_images').click(function (e) {
var sList = "";
$('input[type=checkbox]').each(function () {
var sThisVal = (this.checked ? this.value : "");
sList += (sList == "" ? sThisVal : "," + sThisVal);
});
$.ajax({
url: "/Upload/DeleteImages?IDs=" + sList + '&Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id,
data: sList,
cache: false,
type: "POST",
dataType: "json"
});
reloadGallery();
return false;
});
function reloadGallery() {
$.ajax({
type: "GET",
url: '/Upload/Index/',
data: "{}",
cache: false,
dataType: "html",
success: function (data)
{ $().html(data); }
})
}
});
</script>
<div class="modal_block modal_part"></div>
<div class="modal_dialog modal_part" id="tn_select"></div>
<h2>List of images</h2>
<p>
This page contains the list of all uploaded images.
</p>
@if (Model.ImageViewModel.Images.Count > 0)
{
<div class="imageContainer">
<div class="div-table">
<div class="div-table-row-title">
<div class="div-table-col">Image</div>
<div class="div-table-col">Image Name</div>
</div>
</div>
}
</div>
<div class="DeleteImages">
<a href="#" id="delete_images">Delete Selected Images.</a>
</div>
}
else
{
<div class="imageCenter">
No images have been uploaded so far.
</div>
}
<p>
<a href="#" id="modal_link">Click here to open modal dialog.</a>
</p>
<div class="clear"></div>
Here is the code in the Controller to delete the images:-
[HttpPost]
public ActionResult DeleteImages(string IDs)
{
_Page = Request.QueryString["Page"];
_Action = Request.QueryString["Action"];
_ItemID = Convert.ToInt32(Request.QueryString["id"]);
Generics.PageIDS currentPage = (Generics.PageIDS)Enum.Parse(typeof(Generics.PageIDS), _Page);
_PageID = Convert.ToInt32(currentPage);
string[] sepImageIds = IDs.Split(',');
foreach (string strImageId in sepImageIds)
{
imageViewModel.DeleteFromXML(strImageId);
}
return RedirectToAction(_Action, _Page, new { id = _ItemID });
}
Everything works fine in this Partial View, except for when I delete an image, the deletion is done correctly, however when the code is passed back to the View, the Partial View is not refreshed.
Is there something I am missing?
Thanks for your help and time!
------------------UPDATE--------------------------------------------- This is the Edit Controller Action after the Delete has finished :-
public ActionResult Edit(int id = 0)
{
articleViewModel.Article = unitOfWork.ArticleRepository.GetByID(id);
pageViewModel.Page.PageTitle = "Article";
pageViewModel.Page.PageAction = "Edit";
if (articleViewModel.Article == null)
{
return HttpNotFound();
}
PopulateDropDownList(articleViewModel.Article.CategoryID);
viewModel.ArticleViewModel = articleViewModel;
int ImageCount = 0;
imageViewModel.Images = imageViewModel.PopulateFromXML(pageViewModel.GetPageID(_PageName), id, out ImageCount).ToList();
viewModel.ImageViewModel = imageViewModel;
viewModel.PageViewModel = pageViewModel;
return View(viewModel);
//return Json(viewModel, JsonRequestBehavior.AllowGet);
}
Upvotes: 8
Views: 20570
Reputation: 1832
I think it is because all partial views are cached by default, what I would do is to create a method in the controller to return an ActionResult like so, with the output cache attribute of 0, so it does not cache
[OutputCache(Duration = 0)]
public ActionResult ImageGalleryAction()
{
// do return your cshtml name here
return PartialView("ImageGallery");
}
I would give an id to your imageGalleryDiv, change your reloadGallery method to load the partial view on onload event as well and remove the @Html.Partial like so
<script>
function reloadGallery(){
$('#myImageGallery').load("ImageGalleryAction");
}
</script>
<div id="myImageGallery" class="ImageGallery" onload="reloadGallery()">
</div>
That way, your partial view will be manually injected/refreshed via jquery and it won't be cached.
Cheers
Upvotes: 15
Reputation: 819
I think it might be in your ajax call
function reloadGallery() {
$.ajax({
type: "GET",
url: '/Upload/Index/',
data: "{}",
cache: false,
dataType: "html",
success: function (data)
{ $().html(data); }
})
}
remove the data: "{}" or replace it with data: {}
Upvotes: 0
Reputation: 1038720
You need to call the reloadGallery
function once your DELETE ajax call succeeds, which is inside the success callback:
$.ajax({
url: '/Upload/DeleteImages?IDs=' + sList + '&Page=' + pageTitle + '&Action=' + pageAction + '&id=' + id,
data: sList,
cache: false,
type: 'POST',
success: function(data) {
reloadGallery();
}
});
Not to mention that your DeleteImages
action doesn't return any JSON, so you should remove the dataType: 'json'
switch. You seem to be redirecting at the end of the DeleteImages
action. Are you sure that you are redirecting to a controller action that returns a partial?
Also instead of firing yet another AJAX request in your reloadGallery
method why not simply have your DeleteImages
action return the partial and inside the success
call update the corresponding section of your DOM using the .html
method?
Upvotes: 0