Edit,Detail,Delete not Working in partial View - asp.net-mvc

I am using Partial View for Searching after search Record and i want to delete record when i click on delete then open new page and show message delete successfully but i want to show this message in the same page not new page
this is my Controller
public string Delete(string id)
{
oj.Delete(id);
return "del Successfuly";
}
Here is my view
when i am click on delete link the open new page and show Successfully message
bu i want to show message in the same page
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.emp_id)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_fname)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_lname)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_dob)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_contact1)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_address1)
</td>
<td>
#Html.DisplayFor(modelItem => item.emp_cnic)
</td>
<td>
#Html.DisplayFor(modelItem => item.dept_id)
</td>
<td >
<div id="tdi">
#Ajax.ActionLink("Delete", "Delete", new { id = item.emp_id }, new AjaxOptions
{
UpdateTargetId = "#tdi",
HttpMethod = "Get",
InsertionMode = InsertionMode.Replace
})
</div>

You need install the jQuery AJAX Unobtrusive library:
If you don't have this libary in your project, don't works the ajax request, so, the link opened in another page.
Install:
Install-Package Microsoft.jQuery.Unobtrusive.Ajax
View:
#Scripts.Render("~/Scripts/jquery.unobtrusive-ajax.min.js")

Related

MVC View change specified row bgcolor

In my MVC view, I am displaying list of data from my model in a table as shown below. How to make a specified row to change color when one of the field satisfy certain condition within my if-else statement? It does not seems like I can add a jquery inside my if-else there for the purpose...
My View:
...
<table>
...
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.field1)
</td>
<td>
#Html.DisplayFor(modelItem => item.field2)
</td>
<td>
#if(item.field3== 0){
//change this row to grey color
}
else {
#Html.DisplayFor(modelItem => item.field3)
}
</td>
....
</table>
You just need to do it up where you are outputting the row. One way would be:
<table>
...
#foreach (var item in Model) {
<tr style='background-color: #(item.field3 == 0 ? "gray" : "white");'>
<td>
#Html.DisplayFor(modelItem => item.field1)
</td>
<td>
#Html.DisplayFor(modelItem => item.field2)
</td>
<td>
#Html.DisplayFor(modelItem => item.field3)
</td>
}
....
</table>
There are all sorts of ways to construct that conditional, just depends on your scenario. But the key is that you can access the field3 property of the item object anywhere in that foreach loop, just like a normal C# foreach

Create a dynamic amount of columns for each item

I have a template maker which creates Scorecards with a possibility of having 10 sections with up to 10 questions in each. When creating my MVC View I only want to show sections that have questions. I have a column in my DB table that has a count of the sections and also for each section I have a column indicating the amount of questions in that section. I have tried this but the model binding does not like the insertion of dynamic names. I think it could be my syntax. Below is what I tried but it doesn't work:
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.DepartmentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotSections)
</td>
#for (var i = 0; i < item.TotSections; i++ )
{
var section = 1;
var SN = "S" + section + "Name";
var SNUP = "S" + section + "NumUP";
var SNQ = "S" + section + "NumQuest";
<td>
#Html.DisplayFor(modelItem => item[SN])
</td>
<td>
#Html.DisplayFor(modelItem => item[SNUP])
</td>
<td>
#Html.DisplayFor(modelItem => item[SNQ])
</td>
}
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TemplateId }) |
#Html.ActionLink("Details", "Details", new { id = item.TemplateId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.TemplateId })
</td>
</tr>
}
IS there a way of doing this or do I need to rethink?
Thanks in advance.
Edit:
If I had a Scorcard Template with one section in it the static table row would look like this:
#foreach (var item in Model)
{
<tr>
<!--These are Constant for each item-->
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.DepartmentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotSections)
</td>
<!--BELOW IS WHERE I AM HAVING THE PROBLEM-->
<!--I want to create these columns dynamically,-->
<!--depending on how many sections in column '**TotSections**' above-->
<td>
#Html.DisplayFor(modelItem => item.S1Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.S1NumUP)
</td>
<td>
#Html.DisplayFor(modelItem => item.S1NumQuest)
</td>
<!--Below will be constant for each table row-->
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TemplateId }) |
#Html.ActionLink("Details", "Details", new { id = item.TemplateId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.TemplateId })
</td>
</tr>
}
if there were two sections:
#foreach (var item in Model)
{
<tr>
<!--These are Constant-->
<td>
#Html.DisplayFor(modelItem => item.Description)
</td>
<td>
#Html.DisplayFor(modelItem => item.DepartmentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.TotSections)
</td>
<!--BELOW IS WHERE I AM HAVING THE PROBLEM-->
<!--I want to create these columns dynamically,-->
<!--depending on how many sections in column '**TotSections**' above-->
<td>
#Html.DisplayFor(modelItem => item.S1Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.S1NumUP)
</td>
<td>
#Html.DisplayFor(modelItem => item.S1NumQuest)
</td>
<td>
#Html.DisplayFor(modelItem => item.S2Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.S2NumUP)
</td>
<td>
#Html.DisplayFor(modelItem => item.S2NumQuest)
</td>
<!--Below will be constant-->
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.TemplateId }) |
#Html.ActionLink("Details", "Details", new { id = item.TemplateId }) |
#Html.ActionLink("Delete", "Delete", new { id = item.TemplateId })
</td>
</tr>
}
The end view will look like this:
You can see above under the TotSections column:
Test Template 1 has 1 section. If I display these with a static viewmodel, columns will be displayed when they shouldn't be and columns won't be displayed when they should. As in the above picture it is showing 2 sections worth when it only has one.
Test Template 2 has 6 sections but is only displaying 2 of the six's columns so is missing 4 sections worth of columns.
The code I originally posted was my attempt to get the number of sections from item.TotSections and then create the section columns dynamically.
Hope this is a bit clearer

How to update Partial View without full replacement

I have this partial view. This works, ie, when the user clicks the button, an ajax trip is made to the server, and it updates the partial view and it comes down and replaces the current div with the updated Div and shows the Promo Message.
However, it seems there should be a better way to do this. In other words, is it necessary to replace the entire partial view? Isn't there a way to send just the data up to the server, and then update just the message when it gets back, like maybe via a JSON call?
Controller:
public ActionResult ApplyPromoCode(OrderViewModel orderViewModel) {
orderViewModel.PromoMessage = "Promo has been applied";
return PartialView("PromoPartial", orderViewModel);
}
Partial View:
#model NTC.PropertySearch.Models.OrderViewModel
#using (Ajax.BeginForm("ApplyPromoCode", "OrderSummary", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "promo" }))
{
<div id="promo">
<table>
<td>
#Html.LabelFor(m => m.PromoCode)
</td>
<td>
#Html.TextBoxFor(m => m.PromoCode)
</td>
<td>
#Html.ValidationMessageFor(m => m.PromoCode)
</td>
<td>
<input type="submit" value="Apply Promo Code" />
</td>
<td>
#Html.DisplayFor(m=> m.PromoMessage)
</td>
</table>
</div>
}
you can do this to
Controller
public ActionResult ApplyPromoCode(OrderViewModel orderViewModel) {
//your processing code
return Content("Promo has been applied");
}
View
#model NTC.PropertySearch.Models.OrderViewModel
#using (Ajax.BeginForm("ApplyPromoCode", "OrderSummary", new AjaxOptions { UpdateTargetId = "pcode" }))
{
<div id="promo">
<table>
<td>
#Html.LabelFor(m => m.PromoCode)
</td>
<td>
#Html.TextBoxFor(m => m.PromoCode)
</td>
<td>
#Html.ValidationMessageFor(m => m.PromoCode)
</td>
<td>
<input type="submit" value="Apply Promo Code" />
</td>
<td>
<div id="pcode"></div>
</td>
</table>
</div>
}
Instead of returning a PartialView you can always return a JSON object/array or some XML and use jQuery/JavaScript on your callback function to update the values of your input fields.
Here's an example of some code I use to return JSON from a Controller:
public ActionResult CurrentTags(int entityID)
{
Entity entity = db.Entity.Find(entityID);
var tags = from tag in entity.Tag
select new
{
id = tag.Name,
text = tag.Name
};
return this.Json(tags, JsonRequestBehavior.AllowGet);
}

Why do textboxes not clear out after clearing out Model

I have a form which is submitted via ajax to the Controller. The Controller collects the data from the Model and then creates a new ViewModel and passes it to the partial view which is then updated on the Client.
The problem is that the textboxes are not cleared out as expected. The message arrives in the View as expected, so it doesn't make sense that the TextBoxes are not cleared out.
Yet it seems to be a browser issue as this is the resulting HTML, which note, does not have anything in the value:
<input id="Address_Address1" name="Address.Address1" type="text" value="" />
Yet the user sees the value that was priorly entered.
Here is the controller:
//Process Order Here
//This should clear out the ViewModel.
order = new OrderViewModel();
order.Message = "Report Added to your cart";
return PartialView("_NewOrderPartial", order);
This is the partial View:
#model NTC.PropertySearch.Models.OrderViewModel
#using (Ajax.BeginForm("NewOrder", "Order", new AjaxOptions { InsertionMode = InsertionMode.Replace, UpdateTargetId = "neworder" }))
{
<div id="neworder">
<table>
<tr>
<th style="width: 300px;">
<h3>Enter property address below</h3>
</th>
<th style="width: 30px;"></th>
<th style="width: 300px;">
<h3>Choose your report below</h3>
</th>
</tr>
<tr>
<td>
<div class="form">
<table>
<tr>
<td>
#Html.LabelFor(m => m.Address.Address1)
</td>
<td>
#Html.TextBoxFor(m => m.Address.Address1)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.Address1)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.Address2)
</td>
<td>
#Html.TextBoxFor(m => m.Address.Address2)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.Address2)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.City)
</td>
<td>
#Html.TextBoxFor(m => m.Address.City)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.City)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.State)
</td>
<td>
#Html.TextBoxFor(m => m.Address.State)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.State)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(m => m.Address.ZipCode)
</td>
<td>
#Html.TextBoxFor(m => m.Address.ZipCode)
</td>
<td>
#Html.ValidationMessageFor(m => m.Address.ZipCode)
</td>
</tr>
</table>
<input type="submit" value="Add Report" />
#Html.DisplayFor(m=> m.Message)
</div>
</td>
</tr>
</table>
</div>
The reason for this is because the Html helpers such as TextBox are first looking at the ModelState when binding their values and only after that in the View model. This often happens when people attempt to modify/clear some value to the view model in an HttpPost controller action. The corresponding view will use the initial POSTed value and not the value in the view model.
You should clear the ModelState as well in your controller action:
ModelState.Clear();
order = new OrderViewModel();
Alternatively if you do not want to clear the entire ModelState (although in your case this seems to be the case as you are reinitializing the entire view model) you could clear only some properties that you intend to modify:
ModelState.Remove("SomeProperty");
viewModel.SomeProperty = "some new value";

How to pass a list of objects to a [HTTPPost]controller parameter, in ASP.Net MVC?

i have the next view:
#model IEnumerable<L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer>
#using (Html.BeginForm("ExpenseMonthlyTransferProcessing", "BudgetTransfer", Model.ToList())){
<table class ="divTable">
<tr>
<th>Transferir</th>
<th>
Clave
</th>
<th>
Monto
</th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.CheckBoxFor(x => item.MTR_Bool, new { #class = "checkMTR", #checked = "checked" })
</td>
<td>
#Html.TextBoxFor(x => item.MTR_Key, new {#class = "longInput" })
</td>
<td>
#String.Format("{0:F}", item.MTR_Amount)
</td>
</tr>
}
</table>
}
and my controller like this
[HttpPost]
public ActionResult ExpenseMonthlyTransferProcessing(List<MTR_MonthlyTransfer> lstMtr)
{ return View(lstMTR); }
But when i do the post my list is null, how can i send my list through the submit button ?
You should change the #model to an array (L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer[]) or something else that implements IList<>:
#model L5ERP.Model.BLL.BusinessObjects.MTR_MonthlyTransfer[]
#for (var i = 0; i < Model.Length; i ++) {
<tr>
<td>
#Html.CheckBoxFor(x => Model[i].MTR_Bool, new { #class = "checkMTR", #checked = "checked" })
</td>
<td>
#Html.TextBoxFor(x => Model[i].MTR_Key, new {#class = "longInput" })
</td>
<td>
#String.Format("{0:F}", item.MTR_Amount)
</td>
</tr>
receive a FormCollection and parse the items in it manually
Use F12 to check the post in your navigator to see if it are sending the content you expected.

Resources