I'm still new to asp.net mvc, i want to delete list of partial view, the delete is working but i must reload the entire page to show the new list
What I want is the partial view show the new list after delete without load the entire page, so only the partial view is updated
Here is my code:
My view content some of partial view :
#model cc.Models.User
#{
Layout = "~/Views/Shared/_MemberLayout.cshtml";
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcValidation.debug.js")" type="text/javascript"></script>
<body class="container body-content">
<div id="partialView1">
#Html.Action(...)
</div>
<div id="partialView2">
#Html.Action(...)
</div>
<div id="partialView4">
#Html.Action(...)
</div>
<div id="partialView3" class="col-md-8 col-sm-1">
#Html.Action("UserHistory", "User")
</div>
</body>
Here is my partial view for UserHistory I tried to use ajax but it's not work. I already tried to use
$(this).closest('.historyRow').remove();
and
$("a.deleteHistory").live("click", function () {
$(this).parents("div.historyRow:first").remove();
return false;
});
Here is my code :
#model cc.Models.UserHistory
#{
Layout = null;
}
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script src="#Url.Content("~/Scripts/MicrosoftAjax.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/MicrosoftMvcValidation.debug.js")" type="text/javascript"></script>
<div id="formHistory">
<div id="historyDetail">
<div id="editDataHistoryUser">
#foreach (var item in Model.History)
{
#Html.Partial("UserHistoryDetail", item)
}
</div>
#Html.ActionLink("Add Form", "AddUserHistory", null, new { id = "btnFormHistory" })
</div>
</div>
<script type="text/javascript">
$("#btnFormHistory").click(function () {
$.ajax({
url: this.href,
cache: false,
success: function (html) { $("#editDataHistoryUser").append(html); }
});
return false;
});
$('#formHistory').on('click', '.deleteHistory', function () {
var id = $(this).data('id');
if (id == 0) {
$(this).closest('.historyRow').remove();
//$("a.deleteHistory").live("click", function () {
// $(this).parents("div.historyRow:first").remove();
// return false;
//});
} else {
var url = '#Url.Action("DeleteUserHistory", "User")';
$.post(url, { ID: id }, function (response) {
if (response) {
$(this).closest('.historyRow').remove();
//$("a.deleteHistory").live("click", function () {
// $(this).parents("div.historyRow:first").remove();
// return false;
//});
}
}).fail(function (response) {
});
}
});
</script>
Here is my UserHistoryDetail Code :
#model cc.Models.IUserHistory
#{
Layout = null;
}
<div id="formUserHistoryDetail">
#using (Ajax.BeginForm("UserHistoryDetail", "User", new AjaxOptions { HttpMethod = "POST" }))
{
<div id="historyRow">
<div>#Html.LabelFor(model => model.IDHistory, new { style = "display:none;" })</div>
...
delete
</div>
}
</div>
And here is my JsonResult when button delete clicked :
[HttpPost]
public JsonResult DeleteUserHistory(string ID)
{
db.delUserHistory(ID);
return Json(true);
}
I still cannot find the solution for this , or maybe i used ajax in wrong way, any suggestion?
Let's assume that the DeleteUserHistory post url is '/[Controller]/': '/UserHistory'
$('.deleteHistory').click(function(){
var url = '/UserHistory';
$.ajax({
type: "POST",
url: url,
data: data,
success: onSuccessCallback
});
});
What you should really do is use WebApi to manage data and use the views to display.
As for the delete, use method type 'delete' instead of 'post'. Post should be used for "adds".
Related
I am using MVCGrid.NET http://mvcgrid.net/
And I created a Non-Fluent grid http://mvcgrid.net/gettingstarted see Non-Fluent Example
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) =>
{
return new QueryResult<YourModelItem>()
{
Items = new List<YourModelItem>(),
TotalRecords = 0
};
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
Now I have my grid appear when you submit a form, but when I submit the form again, I am expecting new data, but the grid does not reload or refresh or anything. It does't even reset when I refresh the page, I have to do a full reload of the page to reset it, which is lame, does anyone know how to refresh or reload the grid when I want to show new data?
I have even tried this: http://mvcgrid.net/demo/NoQueryOnPageLoad
But it did not reload or refresh.
PLEASE HELP!
It reloads, try this,
//model class
public class YourModelItem
{
public int Id { get; set; }
public string YourProperty { get; set; }
}
//controller
public class HomeController : Controller
{
private static List<YourModelItem> _modelItems = new List<YourModelItem>();
public ActionResult Index()
{
GridDefinition<YourModelItem> def = new GridDefinition<YourModelItem>();
GridColumn<YourModelItem> column = new GridColumn<YourModelItem>();
column.ColumnName = "UniqueColumnName";
column.HeaderText = "Any Header";
column.ValueExpression = (i, c) => i.YourProperty;
def.AddColumn(column);
def.RetrieveData = (options) => new QueryResult<YourModelItem>()
{
Items = _modelItems,
TotalRecords = 0
};
MVCGridDefinitionTable.Add("NonFluentUsageExample", def);
return View();
}
[HttpPost]
public JsonResult Add(YourModelItem item)
{
_modelItems.Add(item);
return Json(true, JsonRequestBehavior.AllowGet);
}
}
index.cshtml
#{
ViewBag.Title = "Home Page";
}
#using MVCGrid.Web
<div class="jumbotron">
<div id="form1">
<div class="form-group">
<label for="Id">ID</label>
<input type="number" class="form-control" id="Id" aria-describedby="Id" placeholder="Enter Id">
</div>
<div class="form-group">
<label for="YourProperty">YourProperty</label>
<input type="text" class="form-control" id="YourProperty" placeholder="Enter Your Property">
</div>
<button id="addItem">Submit</button>
</div>
<br />
#Html.MVCGrid("NonFluentUsageExample")
</div>
#section scripts {
<script type="text/javascript">
$(document).ready(function () {
$("#addItem").click(function () {
var formData = { Id: $('#Id').val(), YourProperty: $('#YourProperty').val() };
$.ajax({
type: "POST",
url: "/Home/add",
dataType: 'json',
contentType: 'application/json',
data: JSON.stringify(formData),
success: function(data) {
if (data) {
MVCGrid.reloadGrid('NonFluentUsageExample');
}
}
});
});
});
</script>
}
_layout.cshtml -> body
<body>
<div class="container body-content">
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
<script src="~/MVCGridHandler.axd/script.js"></script>
#RenderSection("scripts", required: false)
</body>
It adds item and reloads after "Submit".
Just have installed MVCGrid in new asp.net mvc - Install-Package MVCGrid.Net
Put these lines as above
I have a view with a button, when click this button, an ajax function calls controller method ApplicationAndUse which is supposed to pass a list to a partial view included in my view. The partial view content is supposed to be refreshed, but this doesn't work, my partial is still empty.
My code :
Main view :
#model List<String>
<div class="row">
<div class="col-md-2">
#foreach (var item in Model)
{
<div id="univers-#item" class="btn btn-info">#item</div><br />
}
</div>
<div class="col-md-10">
#Html.Partial("_ApplicationAndUsePartial", null, new ViewDataDictionary())
</div>
</div>
#section scripts
{
<script type="text/javascript">
$(function () {
$('[id^=univers]').click(function () {
var selectedButton = $(this).attr('id');
var selectedUniverse = selectedButton.substring(selectedButton.indexOf('-') + 1, selectedButton.lenght);
$.ajax({
url: "http://" + window.location.host + "/UseAndNeed/ApplicationAndUse",
type: "POST",
data: { idUniverse: selectedUniverse },
dataType: "json",
});
});
});
</script>
}
Partial view :
#model List<int>
#if (Model!= null) {
foreach (var item in Model)
{
<div id="ApplicationUse-#item" class="btn btn-default">#item</div><br />
}
}
Controller function :
[OutputCache(Duration = 0)]
public ActionResult ApplicationAndUse(String idUniverse)
{
List<int> items = new List<int>();
items.Add(1);
items.Add(2);
return PartialView("_ApplicationAndUsePartial", (object)items);
}
what do i miss?
Give a unique Id to the div where we want to show the partial view content.
<div id="myPartial" class="col-md-10">
#Html.Partial("_ApplicationAndUsePartial", null, new ViewDataDictionary())
</div>
And in the success handler of the ajax method, update this div's innerHTML with the response coming from the ajax call. Also you do not need to pass specify the dataType value when making the ajax call.
var myUrl= "http://" + window.location.host + "/UseAndNeed/ApplicationAndUse";
$.ajax({ type: "POST",
url : myUrl,
data: { idUniverse: selectedUniverse },
success:function(result){
$("myPartial").html(result);
}
});
Always you should use the Url.Action or Url.RouteUrl html helper methods to build the url to the action methods. It will take care of correctly building the url regardless of your current page/path.
var myUrl= "#Url.Action("ApplicationAndUse","UseAndNeeed")";
This works if your js code is inside the razor view. But If your code is inside a seperate javascript file, you may build the url(s) in your razor view using the above helper methods and keep that in a variable which your external js file code can access. Always make sure to use javascript namespacing when doing so to avoid possible issues with global javascript variables.
#section Scripts
{
<script>
var myApp = myApp || {};
myApp.Urls = myApp.Urls || {};
myApp.Urls.baseUrl = '#Url.Content("~")';
</script>
<script src="~/Scripts/PageSpecificExternalJsFile.js"></script>
}
And in your PageSpecificExternalJsFile.js file, you can read it like.
var myUrl= myApp.Urls.baseUrl+"UseAndNeed/ApplicationAndUse";
$("#myPartial").load(myUrl+'?idUniverse=someValue');
I am trying to do something like, i have an index view which has some tags on each on one when click i want to return a partial view and append it to the div in main index.cshtml view
my code i below
Index.cshtml
#model OyeAPI.Models.User
#{
object user = Session["userId"];
ViewBag.Title = "Index";
}
<link href="#Url.Content("~/Content/css/style.css")" rel="stylesheet"/>
<div class="main_Container">
#if (Session["userId"] == null) {
<div class="login_div">
#Html.Partial("~/Views/Shared/_signin.cshtml")
</div>
}else
{
<div style="height:100px;">
<p>OyePortal</p>
</div>
// <p>#Html.ActionLink("clickme", "callLogs", "contactWeb")</p>
<div style="position:relative; left:400px;">
<div>
<p id="contacts">Contacts</p> | <p id="callLogs">Call Logs</p> |
<p id="messages">Phone Messages</p> | <p >Groups</p>
</div>
<div id="container_inner_frame">
<h1>Welcome fuck it clickme </h1>
</div>
</div>
}
</div>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
#*<script src="#Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"></script>*#4
<script type="text/javascript">
$("#contacts").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_contacts.cshtml")');
});
$("#callLogs").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_callLogs.cshtml")');
});
$("#messages").on("click", function () {
$("#container_inner_frame").html('#Html.Partial("~/Views/Shared/_Phonemessages.cshtml")');
});
</script>
shared View _callLogs.cshtml
#model OyeAPI.Models.CallLogs
#{
List<Model.CallLogsModel> ListCallLogs = (List<Model.CallLogsModel>)ViewData["Data"];
Int64 CallID = 0;
string callNumber = null;
string callDuration = null;
string callType = null;
string date = null;
string daytime = null;
}
<div class="main_Container">
<div>
<div>
<ul>
<li>Contact ID</li><li>Contact Name </li><li>Contact Number</li>
</ul>
</div>
#if (ListCallLogs != null)
{
foreach (var item in ListCallLogs)
{
CallID = item.CallId;
callNumber = item.PhoneNumber;
callDuration = item.CallDuration;
callType = item.CallType;
date = item.CallDate.ToShortDateString();
daytime = item.CallDayTime.ToShortTimeString();
<div>
<ul>
<li>#CallID</li><li>#callNumber </li><li>#callDuration</li><li>#callType</li><li>#date </li><li>#daytime</li>
</ul>
</div>
}
}
else
{
<p>Empty String list no messages</p>
}
</div>
</div>
Controller contactWeb function callLogs
[HttpPost]
[AllowAnonymous]
public ActionResult callLogs()
{
Int64 userID = Convert.ToInt64(Session["userId"]);
try
{
List<CallLogsModel> callModel = new List<CallLogsModel>();
ICallLogs callLogObject = new CallLogsBLO();
callModel = callLogObject.GetCallLogs(userID);
ViewData["Data"] = callModel;
}
catch (Exception e)
{
}
return PartialView("_callLogs", ViewData["Data"]);
}
But its not working, when i run the code before login it hit the _callLogs shared view first and after that it show the login screen and when i click the callLogs it dosen't display any thing. i my be missing something
Your approach is not right:
you are writing jquery event, you have to send an ajax call to an action and return partial view of CallLogs and then append it to container div.
do like this:
$("#callLogs").on("click", function () {
$("#container_inner_frame").load('#Url.Action("callLogs","YOurController")');
});
or like this:
$("#callLogs").on("click", function () {
$.ajax({
url: '#Url.Action("callLogs", "YourControllerName")',
success: function (response) {
$("#container_inner_frame").html(response);
}
error: function () {
alert("error occured");
}
});
});
If you use the jQuery unobtrusive Ajax library, you should be able to do something as simple as this to load content from a partial on a button/link click. Note that you need to have a controller which returns a PartialViewResult (this can then reference your view) :
#Ajax.ActionLink("Click Me", "Action", "Controller", new AjaxOptions{ InsertionMode=InsertionMode.InsertAfter, UpdateTargetId="MyTargetDivId"})
<div id="MyTargetDivId"></div>
Try this :
$("#callLogs").on("click", function () {
$.ajax({
url: '#Url.Action("callLogs", "YourController")',
type: 'get',
datatype: 'json',
success: function (data) {
$('div#container_inner_frame').html(data);
}
});
});
I have this script, what it intends to do is: in a view with a list of contacts, each one with a edit link whenever you click on one of these links it displays an edit form in a partial view (there's only one div in the parent view for holding it) just below the clicked contact, for that it does a get ajax call to the server and gets the information for that contact. After submitting, via ajax as well, it refreshes the list.
Everything seems to work fine, but if I edit a contact, after the list being refreshed I try to open again the form on the same contact and the information is the same as it was before being edited. Although debugging I see the list for the server is correct (and so is the display in the list, it's only wrong in the form)
Thing is that in chrome developer tool I can see the form with some "default values" set to the previous stuff. I didn't know about them till now and I don't know how to get rid of them, because to my understanding I'm making a get call to the server, anyway I have tried this
document.getElementById("editForm").reset();
with no luck.
Thanks
The script
(function ($) {
var editContainer = $(document.getElementById('editContainer'));
$('#editContainer').on('submit', '#editForm', ajaxEditCall);
$('a.edit').on("click", displayEditForm);
function displayEditForm(e) {
var clickedElement = $(this).parent(),
url = editContainer.data('amp-edit-url');
$.get(url, {
id: parseInt(this.id, 10)
}, function (result) {
editContainer.html(result);
$.validator.unobtrusive.parse(editContainer);
// Display edit form just below the "item" clicked
if (editContainer.is(":visible")) {
editContainer.slideToggle(300, function () {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
});
} else {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
}
}, "html");
e.preventDefault();
}
function ajaxEditCall(e) {
e.preventDefault();
//if ($('#editForm').valid()) {
var list = $(document.getElementById('list'));
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.passedValidation == true) {
$.get(result.action, function (partial) {
document.getElementById("editForm").reset();
list.html(partial);
$('a.edit').on("click", displayEditForm);
$('#editForm').slideUp(300);
setTimeout(function () {
list.effect("highlight", {}, 3000);
}, 1000);
});
} else {
$(document).scrollTop(0);
editContainer.html(result);
$.validator.unobtrusive.parse('#editForm');
}
}
});
//} return false;
}
}(jQuery));
And the view in case is relevant
#model ContactListViewModel
#{
ViewBag.Title = " My Contacts";
}
<div id="myContacts">
<h2>My Contacts</h2>
<div id="editContainer" data-amp-edit-url="#Url.Action("Edit", "Contacts")" class="initiallyHidden"></div>
<div id="list">
#{ Html.RenderPartial("_ContactList", Model); }
</div>
<div id="dialog" data-amp-del-url="#Url.Action("Delete", "Contacts")" title="Confirmation Required">
<p>Are you sure you want to delete this Contact?</p>
</div>
</div>
#section Foot
{
<script src="~/Scripts/AMPContacts.js"></script>
<script src="~/Scripts/conditional-validation.js"></script>
<script src="~/Scripts/Placeholders.min.js"></script>
}
Well that's obviously the parent view, the partial one is just a bunch of fields, I remove most of them to avoid increase the already long post
#model AddContactViewModel
#using (Html.BeginForm("Edit", "Contacts", FormMethod.Post, new { #id = "editForm", #class = "addTab" }))
{
#Html.ValidationSummary(true, "Please correct the errors and try again.")
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.OwnedItemId)
#Html.HiddenFor(m => m.AddressId)
<div id="editContactDetails">
<div>
#Html.DisplayFor(m => m.PlanName)
</div>
<div>
#Html.DropDownListFor(m => m.Title, Model.TitleList, "Title")
</div>
<div>
#Html.EditorFor(m => m.FirstName, new { #id="editFirstName", data_placeholders_focus = "false", placeholder = ViewData.ModelMetadata.Watermark })
#Html.ValidationMessageFor(m => m.FirstName)
</div>
// And so on....
<div class="addDEC">
<input class="addDECButton" type="submit" value="Save" />
</div>
}
I ran into this problem with a site I was working on. You'll need to disable your ajax caching:
//Disbable cache for all jQuery AJAX requests
$.ajaxSetup({ cache: false });
That will do it for all ajax calls, so you may only want to do that on certain pages, depending on your usage.
I am very new to both JQuery and Asp.net MVC 3 (C#), so I apologize if this is trivial. I have an MVC partial view (Index.cshtml) that has a list of tasks. These tasks are contained within indivudal divs that I have in a list style layout. I have a button called "add task" that opens a dialog. This dialog will save the added task to the database via an AJAX Json call to the controller.
This is where I am having trouble - after the dialog closes I would like the list of tasks to reload with the task i just added. I have found examples where the entire page is reloaded, and I found examples where the controller is supposed to return a rendered view. My problem is that the dialog is being opened from the partial I want to reload. Is there a way to accomplish what I am trying to do.
Index.cshtml
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
#foreach(var task in item.Tasks) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
</div>
</div>
}
</div>
<div id="dialog-form" title="Create new user">
<p class="validateTips">All form fields are required.</p>
<form>
<fieldset>
<label for="TaskName">Task Name</label>
<input type="text" name="TaskName" id="name" class="text ui-widget-content ui-corner-all" />
<label for="TaskDescription">Task Description</label>
<input type="text" name="TaskDescription" id="description" value="" class="text ui-widget-content ui-corner-all" />
<input type="hidden" name="TaskID" id="ID" />
<input type="hidden" name="ProjectID" id="ProjectID" />
</fieldset>
</form>
</div>
Partial Javascript
function GetTask(id) {
if (id.length > 0) {
$.ajax({
url: '/Project/GetTaskFromID',
type: "POST",
data: { "id": id },
success: PopulateDialogFields,
error: HandleError
});
}
}
function PopulateDialogFields(data) {
$("#name").val(data.TaskName);
$("#description").val(data.TaskDescription);
$("#ID").val(data.TaskID);
}
function HandleError(data) {
alert(data.error);
var foo = data;
}
function SaveTask() {
var taskName = $("#name").val();
var taskDescription = $("#description").val();
var id = $("#ID").val();
var projectID = $("#ProjectID").val();
if (id.length > 0) {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
});
}
else {
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "projectID": projectID }
});
}
}
$("#dialog-form").dialog({
autoOpen: false,
height: 300,
width: 350,
modal: true,
buttons: {
"OK": function () {
SaveTask();
$(this).dialog("close");
},
Cancel: function () {
$(this).dialog("close");
}
},
close: function () {
allFields.val("").removeClass("ui-state-error");
window.location.reload(true);
},
open: function () {
var id = $(this).data("id");
var projectID = $(this).data("projectID");
$("#ProjectID").val(projectID);
var button = $("#" + id);
GetTask(id);
}
});
$(".editTaskButton")
.button()
.click(function () {
$("#dialog-form").data('id', this.id).dialog("open");
});
$(".createTaskButton")
.button()
.click(function () {
$("#dialog-form").data('projectID', this.id).dialog("open");
});
I am relatively new to jQuery and ASP.NET MVC as well, however, here's what first comes to mind.
In order to maintain the AJAX-y aspect of the page, I suggest that you create a method that handles a POST which returns a JSON formatted set of TaskManagementApplication.Models.Project. This method can optionally return filtered results.
The markup would look like this,
<div id="ProjectAccordionWrapper">
<div id="ProjectWrapperTemplate" class="ProjectWrapper" style="display: none;">
<h3 id="itemName"></h3>
<div class="column">
<button class="createTaskButton" id="itemProjectID">Create New Task</button>
<div id="portletTemplate" class="portlet">
<div class="portlet-header" id="taskName"></div>
<div class="portlet-content" id="taskDescription"></div>
<button class="editTaskButton" id="taskID">Edit Task</button>
</div>
</div>
</div>
</div>
Next, you would have jQuery clone the ProjectWrapperTemplate element, and set all of the corresponding fields.
$(function () {
$.ajax({
url: '/Project/GetTasks',
type: "POST",
data: { }
}).done(function (data) {
data.forEach(function (element) {
AppendProjectWrapper(element);
});
});
function AppendProjectWrapper(data) {
var projectAccordionWrapper = $('#ProjectAccordionWrapper');
var projectWrapper = $('#ProjectWrapperTemplate').clone(true, true);
projectWrapper.id = nothing; // remove the id, so as to not have duplicates
projectWrapper.style.display = nothing; // remove the style "display: none"
var itemName = projectWrapper.children('#itemName'); // h3
itemName.id = nothing;
itemName.text(data.ItemName);
var itemProjectID = projectWrapper.children('#itemProjectID'); // button Create New Task
itemProjectID.id = data.ItemProjectID;
var portletTemplate = projectWrapper.children('#portletTemplate'); // div
data.Tasks.forEach(function (element) {
var portlet = portletTemplate.clone();
portlet.id = nothing;
var taskName = portlet.children('#taskName');
taskName.id = nothing;
taskName.text(element.TaskName);
var taskDescription = portlet.children('#taskDescription');
taskDescription.id = nothing;
taskDescription.text(element.TaskDescription);
var editTaskButton = portlet.children('#taskID');
editTaskButton.id = element.TaskID;
portlet.appendTo(projectWrapper);
});
portletTemplate.remove(); // remove the portlet template element
projectWrapper.appendTo(projectAccordionWrapper);
}
}
Finally, have '/Project/SaveTask' return a JSON formatted TaskManagementApplication.Models.Project of the currently saved task.
$.ajax({
url: '/Project/SaveTask',
type: "POST",
data: { "taskName": taskName, "taskDescription": taskDescription, "taskID": id }
}).done(function (data) {
AppendProjectWrapper(data);
});
The return data for '/Project/GetTasks' should look as follows:
[
{
ItemName: '#item.Name',
ItemProjectID: '#item.ProjectID',
Tasks: [
TaskName: '#task.TaskName',
TaskDescription: '#task.TaskDescription',
TaskID: '#task.TaskID'
]
}
]
The return data from '/Project/SaveTask' should follow the same format, except or the outer-most array.
Please note that a lot of this code is untested.
It may be easiest to refactor the list into another action+view. Then, you can call this in both the original Index.cshtml view, and via the .load() method in jQuery. So, assuming this:
Projects controller
[HttpGet]
[ChildActionOnly]
public ActionResult Tasks(int id)
{
// create the appropriate model object as an IEnumerable of your Task type
return View(model);
}
Tasks.cshtml
#foreach(var task in Model) {
var buttonClass = "taskID" + task.TaskID;
<div class="portlet">
<div class="portlet-header">#task.TaskName</div>
<div class="portlet-content">#task.TaskDescription</div>
<button class="editTaskButton" id="#task.TaskID">Edit Task</button>
</div>
}
You would adjust Index.cshtml like so:
#model IEnumerable<TaskManagementApplication.Models.Project>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div id="ProjectAccordionWrapper">
#foreach (var item in Model)
{
<div class="ProjectWrapper">
<h3>#item.Name</h3>
<div class="column">
<button class="createTaskButton" id="#item.ProjectID">Create New Task</button>
<div id="tasks-#item.ProjectID">
#Html.Action("Tasks", "Project", new { id = item.ProjectID })
</div>
</div>
</div>
}
</div>
//... the rest of the view
And finally,
// this should happen inside the callback of your .ajax() method
$('#tasks-'+projectID).load('/project/tasks/'+ projectID);