On my main edit view I have 3 partial views that contain child data for the main view model. I also have html text boxes for entering and saving related data such as notes etc.
After an item is entered or select and passed to a controller action, how do I refresh my partial views? Here is the code I have so far but it does not work. I think I need to pass a model back with my partial view?
I am using ajax to call my controller method.
Partial View:
#model cummins_db.Models.CaseComplaint
<table width="100%">
<tr>
<td>
#Html.DisplayFor(modelItem => Model.ComplaintCode.ComplaintCodeName)
</td>
<td>
#Html.DisplayFor(modelItem => Model.ComplaintCode.ComplaintType)
</td>
</tr>
</table>
This is the html where the partial view is located:
<div class="editor-label">
#Html.Label("Search and select a complaint code")
</div>
<div class="textarea-field">
<input id = "CodeByNumber" type="text" />
</div>
#Html.ActionLink("Refresh", "Edit", new { id = Model.CasesID })
<table width="100%">
<tr>
<th>Complaint Code</th>
<th>Complaint Description</th>
</tr>
#try
{
foreach (var comp_item in Model.CaseComplaint)
{
<div id="complaintlist">
#Html.Partial("_CaseComplaintCodes", comp_item)
</div>
}
}
catch
{
}
</table>
Here is the controller method that returns the partial view.
public ActionResult SelectForCase(int caseid, int compid, string compname)
{
if (ModelState.IsValid)
{
CaseComplaint c = new CaseComplaint
{
CasesID = caseid,
ComplaintCodeID = compid
};
db.CaseComplaints.Add(c);
db.SaveChanges();
}
return PartialView("_CaseComplaintCodes");
}
jQuery ajax calling the controller, it is part of an autocomplete function select.
$('#CodeByNumber').autocomplete(
{
source: function (request, response) {
$.ajax({
url: "/Cases/CodeByNumber", type: "GET", dataType: "json",
data: { searchText: request.term, maxResults: 10 },
contentType: "application/json; charset=utf-8",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.ComplaintType,
value: item.ComplaintCodeName,
id: item.ComplaintCodeID
}; //return
}) //map
); //response
} //success
}); //ajax
}, //source
select: function (event, ui) {
var url = "/Cases/SelectForCase";
$.ajax({
type: "GET",
dataType: "html",
url: url,
data: { caseid: $('#CaseID').val(), compid: ui.item.id, compname: ui.item.label },
success: function (result) { $('#complaintlist').html(result); }
});
},
minLength: 1
});
Should the partial view not be as below:
#model cummins_db.Models.CaseComplaint
<table width="100%">
<tr>
<td>
#Html.DisplayFor(m => m.ComplaintCodeName)
</td>
<td>
#Html.DisplayFor(m => m.ComplaintType)
</td>
</tr>
</table>
This is what I ended up doing to make it work. I changed by controller action to this:
public ActionResult SelectForCase(int caseid, int compid)
{
if (ModelState.IsValid)
{
CaseComplaint c = new CaseComplaint
{
CasesID = caseid,
ComplaintCodeID = compid
};
db.CaseComplaints.Add(c);
db.SaveChanges();
var m = from d in db.CaseComplaints
where d.CasesID == caseid
select d;
return PartialView("_CaseComplaintCodes", m);
}
return PartialView("_CaseComplaintCodes");
}
It works now
Related
I'm implementing asp.net core 3.1 project. In my project I have an Index view that shows a table of records and near each record there is a 'Delete' button. After user clicks the 'Delete' button I call jQueryAjaxDelete function (which is in site.js) and send Delete action and its controller container to it. Now my problem is when I click the 'Delete' button a confirmation message shows to me but after clicking the button to delete the record, it doesn't call 'Delete' action in Gate controller so it doesn't delete the record. Here is what I have tried:
Index view:
<div id="tablecontainer" class="my-5 col-sm-12 p-4">
<table id="myDummyTable" class="table">
<thead>
<tr id="headerrow">
<th>
Desc
</th>
<th>
Operation
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
<a onclick="jQueryAjaxDelete('#Url.Action("Delete","Gates",new {id=item.Id},Context.Request.Scheme)','Delete')" class="btn btn-info text-white"><i class="fas fa-pencil-alt"></i> delete</a>
</td>
</tr>
}
</tbody>
</table>
</div>
Here is Delete action in Gate controller:
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Delete(int id)
{
Console.WriteLine("Deleted id:" + id);
var gate = await _context.Gate.FindAsync(id);
gate.IsDeleted = true;
_context.Gate.Update(gate);
await _context.SaveChangesAsync();
//return RedirectToAction(nameof(Index));
return Json(new { html = Helper.RenderRazorViewToString(this, "_ViewAll", _context.Gate.ToList()) });
}
Here is jQueryAjaxDelete in site.js:
jQueryAjaxDelete = form => {
if (confirm('Are you sure to delete this record?')) {
try {
$.ajax({
type: 'POST',
url: form.action,
data: new FormData(form),
contentType: false,
processData: false,
success: function (res) {
$('#view-all').html(res.html);
},
error: function (err) {
console.log('confirm deleteAjax error');
console.log(err);
}
})
} catch (ex) {
console.log(ex)
}
}
I appreciate if anyone suggest to me a solution.
You need to add RequestVerificationToken in the frontend, because you have added [ValidateAntiForgeryToken] in the backend.
The form itself is a url. You can use it directly.
You have pass the parameter with querystring. So you can remove the FormData.
Here is the code can call the action.
<!--in .cshtml-->
#Html.AntiForgeryToken()
#section Scripts{
<script>
var jQueryAjaxDelete = form => {
if (confirm('Are you sure to delete this record?')) {
console.log(form)
try {
$.ajax({
type: 'POST',
url: form,
headers: {
RequestVerificationToken: $('input:hidden[name="__RequestVerificationToken"]').val()
},
success: function (res) {
$('#view-all').html(res.html);
},
error: function (err) {
console.log('confirm deleteAjax error');
console.log(err);
}
})
} catch (ex) {
console.log(ex)
}
}
}
</script>
}
If <a> reloads or redirects when you click, you could pass an event into jQueryAjaxDelete and use this method.
event.preventDefault()
Actually when i debugging my code it is hitting the json action but searching value is passing like \"\a\" this,what is the problem am not getting, anybody help me
this is my view:
#model IEnumerable<autoCompelte.Models.Student>
<script type="text/javascript">
$(document).ready(function() {
$("#search").autocomplete({
source: function (request, response) {
$.ajax({
url: "/Home/AutoComplte",
data: {term :JSON.stringify( request.term)},
type: "POST",
datatype:"json",
success: function (data) {
response($.map(data, function (item) {
return {
label: item.Description,
value: item.Id
}
}))
},
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to retrieve states.');
}
})
}
})
})
</script>
....
<p><input type="text" id="search" name="search"></p>
<table>
<tr>
<th>#Html.DisplayNameFor(model => model.Name)</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>#Html.DisplayFor(modelItem => item.Name)</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
This is my controller
public ActionResult Index()
{
return View(db.Students.ToList());
}
public JsonResult AutoComplte( string term)
{
var result = from n in db.Students
where n.Name.ToLower().StartsWith(term.ToLower())
select n.Name;
return Json(result, JsonRequestBehavior.AllowGet);
}
i write this code with ajax to delete some info after that i update my updateAjax div with ajax for refreshing content and this view have masterpage.in picture u see what happen.
this is my code
#using Common.UsersManagement.Entities;
#model IEnumerable<VwUser>
#{
Layout = "~/Views/Shared/Master.cshtml";
}
<form id="userForm">
<div id="updateAjax">
#if (string.IsNullOrWhiteSpace(ViewBag.MessageResult) == false)
{
<div class="#ViewBag.cssClass">
#Html.Label(ViewBag.MessageResult as string)
</div>
<br />
}
<table class="table" cellspacing="0">
#foreach (VwUser Item in Model)
{
<tr class="#(Item.IsActive ? "tRow" : "Disable-tRow")">
<td class="tbody">
<input type="checkbox" id="#Item.Id" name="selected" value="#Item.FullName"/></td>
<td class="tbody">#Item.FullName</td>
<td class="tbody">#Item.Post</td>
<td class="tbody">#Item.Education</td>
</tr>
}
</table>
</div>
<br />
<br />
<div class="btnContainer">
delete
<br />
<br />
</div>
<script>
$(function () {
// function for delet info and update #updateAjax div
$("#DeleteUser").click(function (event) {
var list = [];
$('#userForm input:checked').each(function () {
list.push(this.id);
});
$.ajax({
url: '#Url.Action("DeleteUser", "UserManagement")',
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: "html",
traditional: true,
data: JSON.stringify(list),
success: function (data, textStatus, jqXHR) {
$('#updateAjax').html(data);
// window.location.reload()
},
error: function (data) {
//$('#updateAjax').html(data);
window.location.reload()
}
}); //end ajax
});});
</script>
</form>
this my controller code
public ActionResult View1()
{
ViewBag.PageTittle = "user list";
ViewBag.FormTittle = "user list";
SetUserManagement();
var Result = userManagement.SearchUsers(null);
if (Result.Mode == Common.Extensions.ActionResultMode.Successfully)
{
return View(Result.Data);
}
else
{
return View(new VwUser());
}
}
public ActionResult DeleteUser(string[] userId)
{
SetUserManagement();
string message = "", CssClass = ""; ;
foreach (string item in userId)
{
//TODO:show Message
var Result = userManagement.DeleteUser(int.Parse(item));
if (Result.Mode != Common.Extensions.ActionResultMode.Successfully)
{
var messageResult = XmlReader.FindMessagekey(Result.Mode.ToString());
message += messageResult.MessageContent + "<br/>";
CssClass = messageResult.cssClass;
}
}
if (string.IsNullOrEmpty(message))
{
SetMessage(Common.Extensions.ActionResultMode.Successfully.ToString());
}
else
{
ViewBag.MessageResult = message;
ViewBag.cssClass = CssClass;
}
//
{
var Result = userManagement.SearchUsers(null);
if (Result.Mode == Common.Extensions.ActionResultMode.Successfully)
{
return View("~/Views/UserManagement/View1.cshtml", Result.Data);
}
else
{
return View("~/Views/UserManagement/View1.cshtml", new VwUser());
}
}
}
It looks to me that your view ViewUserList.cshtml is using a Layout that would either be set through Layout or through the _ViewStart.cshtml file. Make sure you're not using any of these.
For disabling the use of your Layout, you could take a look at this question. Or just set Layout = null
I have a table with my data from base and 3 buttons to delete, create and update which return PartialViews.
I want to update the part of my page with data after clicking the submit button in the corresponding dialog (delete, update, ...).
What is the easiest way to achive this?
This is what I've got now
I will just add, delete is mostly the same.
<div id="delete-dialog" title="Delete Product"></div>
<script type="text/javascript" >
$(".deleteLink").button();
var deleteLinkObj;
// delete Link
$('.deleteLink').click(function () {
deleteLinkObj = $(this);
var name = $(this).parent().parent().find('td :first').html();
$('#delete-dialog').html('<p>Do you want delete ' + name + ' ?</p>');
//for future use
$('#delete-dialog').dialog('open');
return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
dialogClass: "ConfirmBox",
autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
</script>
And after dialog close I want something like a reload of a part of the page.
The data looks like
<table>
<tr>
<th> Name </th>
<th> Date </th>
<th> </th>
</tr>
#foreach (var m in this.Model)
{
<tr>
<td>
<div class="ProductName">#Html.DisplayFor(Model => m.Name)</div>
</td>
<td>
#Convert.ToDateTime(m.AddDate).ToShortDateString()
</td>
<td>
<div class="ProductPrice">#string.Format("{0:C}", m.Price)</div>
</td>
<td>
<div class="CategoryName">#Html.DisplayFor(Model => m.CategoryName)</div>
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = m.ID }, new { #class = "editLink" })
#Html.ActionLink("Delete", "Delete", new { id = m.ID }, new { #class = "deleteLink" })
</td>
</tr>
}
</table>
I'm not sure if im doing this well
I tried to put this action after click the button but nut sure if is right
I changed the Index to a Partial View
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$.ajax.ActionLink("Index",
"Index", // <-- ActionMethod
"Shop", // <-- Controller Name.
new { }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. Y
)
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
I suggest you use the ASP.NET MVC ActionLink helper in your .cshtml file, and not jQuery:
[...]
<script type="text/JavaScript">
function openPopup()
{
// Set your options as needed.
$("#yourPopupDialogId").dialog("open");
}
</script>
[...]
#Ajax.ActionLink(
"Delete",
"Delete",
"Controller",
new { someValue = 123 },
new AjaxOptions
{
// Set your options as needed
HttpMethod = "GET",
UpdateTargetId = "yourPopupDialogId",
OnSuccess = "openPopup()"
}
)
[...]
<div id="yourPopupDialogId" style="display: none;"></div>
Now in your Controller for the methods you want to use for your popups you should return PartialViews:
public ActionResult Delete(int id)
{
RecordDeleteModel model = YourRepository.GetModel( id );
return PartialView( model );
}
Hi Greetings for the day!
(1) The view model (MyViewModel.cs) which is bound to the view is as below...
public class MyViewModel
{
public int ParentId { get; set; } //property1
List<Item> ItemList {get; set;} //property2
public MyViewModel() //Constructor
{
ItemList=new List<Item>(); //creating an empty list of items
}
}
(2) I am calling an action method through ajax postback (from MyView.cshtml view) as below..
function AddItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/AddItem")',
cache: false,
data: serializedform,
success: function (html) {$('#MyForm').html(html);}
});
}
The below button click will call the ajax postback...
<input type="button" value="Add" class="Previousbtn" onclick="AddItem()" />
(3) I have an action method in the (MyController.cs controller) as below...
public ActionResult AddItem(MyViewModel ViewModel)
{
ViewModel.ItemList.Add(new Item());
return View("MyView", ViewModel);
}
Now the issue is, after returning from the action, there is no data in the viewmodel. But i am able to get the data on third postback !! Can you pls suggest the solution..
The complete form code in the view is below...
#model MyViewModel
<script type="text/javascript" language="javascript">
function AddItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/AddItem")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
function RemoveItem() {
var form = $('#MyForm');
var serializedform = form.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/RemoveItem")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
function SaveItems() {
var form = $('#MyForm');
var serializedform = forModel.serialize();
$.ajax({
type: 'POST',
url: '#Url.Content("~/MyArea/MyController/SaveItems")',
cache: false,
data: serializedform,
success: function (html) {
$('#MyForm').html(html);
}
});
}
</script>
#using (Html.BeginForm("SaveItems", "MyController", FormMethod.Post, new { id = "MyForm" }))
{
#Html.HiddenFor(m => Model.ParentId)
<div>
<input type="button" value="Save" onclick="SaveItems()" />
</div>
<div>
<table>
<tr>
<td style="width: 48%;">
<div style="height: 500px; width: 100%; overflow: auto">
<table>
<thead>
<tr>
<th style="width: 80%;">
Item
</th>
<th style="width: 10%">
Select
</th>
</tr>
</thead>
#for (int i = 0; i < Model.ItemList.Count; i++)
{
#Html.HiddenFor(m => Model.ItemList[i].ItemId)
#Html.HiddenFor(m => Model.ItemList[i].ItemName)
<tr>
#if (Model.ItemList[i].ItemId > 0)
{
<td style="width: 80%; background-color:gray;">
#Html.DisplayFor(m => Model.ItemList[i].ItemName)
</td>
<td style="width: 10%; background-color:gray;">
<img src="#Url.Content("~/Images/tick.png")" alt="Added"/>
#Html.HiddenFor(m => Model.ItemList[i].IsSelected)
</td>
}
else
{
<td style="width: 80%;">
#Html.DisplayFor(m => Model.ItemList[i].ItemName)
</td>
<td style="width: 10%">
#if ((Model.ItemList[i].IsSelected != null) && (Model.ItemList[i].IsSelected != false))
{
<img src="#Url.Content("~/Images/tick.png")" alt="Added"/>
}
else
{
#Html.CheckBoxFor(m => Model.ItemList[i].IsSelected, new { #style = "cursor:pointer" })
}
</td>
}
</tr>
}
</table>
</div>
</td>
<td style="width: 4%; vertical-align: middle">
<input type="button" value="Add" onclick="AddItem()" />
<input type="button" value="Remove" onclick="RemoveItem()" />
</td>
</tr>
</table>
</div>
}
You must return PartialViewResult and then you can do something like
$.post('/controller/GetMyPartial',function(html){
$('elem').html(html);});
[HttpPost]
public PartialViewResult GetMyPartial(string id
{
return PartialView('view.cshtml',Model);
}
In my project i get state data with country id using json like this
in my view
<script type="text/javascript">
function cascadingdropdown() {
var countryID = $('#countryID').val();
$.ajax({
url: "/City/State",
dataType: 'json',
data: { countryId: countryID },
success: function (data) {
alert(data);
$("#stateID").empty();
$("#stateID").append("<option value='0'>--Select State--</option>");
$.each(data, function (index, optiondata) {
alert(optiondata.StateName);
$("#stateID").append("<option value='" + optiondata.ID + "'>" + optiondata.StateName + "</option>");
});
},
error: function () {
alert('Faild To Retrieve states.');
}
});
}
</script>
in my controller return data in json format
public JsonResult State(int countryId)
{
var stateList = CityRepository.GetList(countryId);
return Json(stateList, JsonRequestBehavior.AllowGet);
}
i think this will help you ....
I resolved the issue as below...
Issue:
The form code i have shown here is actually part of another view page
which also contains a form. So, when i saw the page source at
run-time, there are two form tags: one inside the other, and the
browser has ignored the inner form tag.
Solution:
In the parent view page, earlier i had used Html.Partial to render
this view by passing the model to it.
#using(Html.BeginForm())
{
---
---
#Html.Partial('/MyArea/Views/MyView',MyViewModel)
---
---
}
But now, i added a div with no content. On click of a button, i'm
calling an action method (through ajax postback) which then renders
the above shown view page (MyView.cshmtl) into this empty div.
#using(Html.BeginForm())
{
---
---
<div id="divMyView" style="display:none"></div>
---
---
}
That action returns a separate view which is loaded into the above
div. Since it is a separate view with its own form tag, i'm able to
send and receive data on each postback.
Thank you all for your suggestions on this :)