I have the following view , which mainly view a list of items as a displayfor:-
#foreach (var item in Model.Resources) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.SystemInfo.MODEL)
</td>
<td>
#Html.DisplayFor(modelItem => item.RESOURCENAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.ResourceLocation.SiteDefinition.AccountDefinition.SDOrganization.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.ResourceLocation.SiteDefinition.SDOrganization.NAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.ComponentDefinition.COMPONENTNAME)
</td>
<td>
#Html.DisplayFor(modelItem => item.ResourceState.STATEDESC)
</td>
<td id = "#item.RESOURCEID">
#using (Ajax.BeginForm("CreateOn","VirtualMachine", new AjaxOptions {
InsertionMode = InsertionMode.Replace,
UpdateTargetId = item.RESOURCEID.ToString() ,
LoadingElementId = "progress",
HttpMethod = "POST"})){
<span class="f">Hypervisor Server</span>
#Html.DropDownListFor(model =>model.VirtualMachine.ServerID, ((IEnumerable<t.Models.Server>)ViewBag.Servers).Select(option => new SelectListItem {
Text = (option == null ? "None" : option.Technology.Tag),
Value = option.ServerID.ToString(),
Selected = (Model != null) && (Model.VirtualMachine != null) && (option.ServerID == Model.VirtualMachine.ServerID)
}), "Choose...")
#Html.ValidationMessageFor(model =>model.VirtualMachine.ServerID)
#Html.Hidden("IT360id", item.RESOURCEID)
#Html.Hidden("CustomerName",item.ResourceLocation.SiteDefinition.AccountDefinition.SDOrganization.NAME)
#Html.Hidden("SiteName",item.ResourceLocation.SiteDefinition.SDOrganization.NAME)
#Html.Hidden("ResourceName",item.RESOURCENAME)
<input type="submit" value="Add To" class="btn btn-primary"/>
}
But the user can read the data and chose to create the item on our database, using the ajax.beginform. But to do so I need to pass some values of the DisplayFor to the model binder. Currently I have added all the needed data as a hiddenfields, and then I will pass these values to my action method as follow:-
[HttpPost]
public ActionResult CreateOn(VirtualMachineOnIT360Only vm, long IT360id, string CustomerName, string SiteName, string ResourceName)
{
I found that my approach is not very reliable and I am trying to figure out a more reliable solution. So can anyone advice please?
Thanks
To post DisplayFor back, I prefer to use hiddenfor instead of hidden like this:
#Html.HiddenFor(item => item.RESOURCENAME);
Related
I want to update only a single value from a row on click of the update button against a specific ID, the id is available at controller but the updated value field is not available so when I press the update button controller updated the database but store a null value in DB.
//View Code
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(m => item.Id)
</td>
<td>
#Html.DisplayFor(m => item.TagName)
</td>
<td>
#Html.DisplayFor(m => item.TagCategory)
</td>
<td>
#Html.TextBoxFor(m => item.TagValue, new { htmlAttributes = new { #class = "form-control" } })
</td>
<td>
#Html.ActionLink("Update", "Update", new { id = item.Id}, new { htmlAttributes = new { #class = "form-control" } })
</td>
</tr>
}
</tbody>
//Controller Code
public ActionResult Update([Bind(Include = "Id,TagValue") ]Tag tags)
{
var data = db.Tags.Where(x => x.Id == tags.Id).FirstOrDefault();
if (data!=null)
{
data.TagValue = tags.TagValue;
db.SaveChanges();
return RedirectToAction("Index");
}
return View();
}
So right now your update button makes a GET request. The database is storing null because when you create the ActionLink you are not passing in the TagValue as a parameter because with GET requests the variables need to be passed in the url. You could add the TagValue as a parameter like this
#Html.ActionLink("Update", "Update", new { id = item.Id, TagValue = item.TagValue }, new { htmlAttributes = new { #class = "form-control" } })
I don't think this will work the way you want though because I am assuming you want the user to be able to change the value of TagValue and then hit update to save the value. What this solution does is it just grabs the original value of whatever TagValue is.
If you want to be able to edit the TagValue and then submit you could change your html to look like this
<tbody>
#foreach (var item in Model)
{
<tr>
<form action="#Url.Action("Update")" method="post">
<td>
#Html.HiddenFor(m => item.Id, new { #Name = "Id" })
#Html.DisplayFor(m => item.Id)
</td>
<td>
#Html.DisplayFor(m => item.TagName)
</td>
<td>
#Html.DisplayFor(m => item.TagCategory)
</td>
<td>
#Html.TextBoxFor(m => item.TagValue, new { #class = "form-control", #Name="TagValue" })
</td>
<td>
<input type="submit" value="Update" />
</td>
</form>
</tr>
}
This will create a form for every Tag you have and then generate a POST request when you hit submit.
vikscool's comment is also another good solution you could use.
You just need to Bind your View with The table from which you are sending and receiving data and you can do it with Html Begin Forms
I have created a very simple search form in my MVC application which allows the user to search for a string term and returnt he results. I would like to let my users search between two dates but I'm not sure how I'd program that.
Here is my code so far. As you'll notice this is only for searching for a string that is passed into the controller as a parameter. I have started writing the code for the date pickers but I've gotten stuck.
View
<h2>Search</h2>
#using (Ajax.BeginForm("Search", "Search", new AjaxOptions
{
OnSuccess = "Success",
OnFailure = "Failure",
UpdateTargetId = "test",
InsertionMode = InsertionMode.Replace
}))
{
<table class="table">
<tr>
<td><label>Vessel Name</label></td>
<td>#Html.TextBox("term",null, new { #class = "k-textbox" })</td>
</tr>
<tr>
<td>
<label>From</label>
#(Html.Kendo().DatePicker()
.Name("date_from")
.Value(DateTime.Today)
)
</td>
<td>
<label>To</label>
#(Html.Kendo().DatePicker()
.Name("date_to")
.Value(DateTime.Today)
)
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Search" />
</td>
</tr>
</table>
}
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Location</th>
<th>MMSI</th>
<th>Created</th>
</tr>
</thead>
<tbody id="test">
#Html.Partial("_results")
</tbody>
</table>
Controller
public ActionResult Search(string term, DateTime date_from, DateTime date_to)
{
var vessels = (from o in db.vessels
select o);
if (!String.IsNullOrEmpty(term))
{
vessels = vessels.Where(s =>
s.vessel_name.Contains(term) ||
s.vessel_location.Contains(term) ||
s.vessel_mmsi.Contains(term));
}
return PartialView("_results", vessels);
}
Partial View
Since I'm using ajax to update a target ID I return the results as in a partial view using the 'replace' insertion method.
#model IEnumerable<Multiple_Table_Post.Models.vessel>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.vessel_name)
</td>
<td>
#Html.DisplayFor(modelItem => item.vessel_location)
</td>
<td>
#Html.DisplayFor(modelItem => item.vessel_mmsi)
</td>
<td>
#Html.DisplayFor(modelItem => item.created)
</td>
</tr>
}
As you'll notice I have started putting the date pickers in place but I don't know how to write the c# to allow me to search between them. I'm passing them into the method as datetime parameters but after is where I'm totally stuck.
Many thanks
You could do this in either of the LINQ queries you have shown.
var vessels= (from o in db.vessels
where (o.created>= date_from && o.created<= date_to)
select o);//I have not tested this.
More Info:
C# Linq Where Date Between 2 Dates
You can also filter the dates in the second LINQ query as seen in the other answers
var vessels = (from o in db.vessels
where o.vessel_date => date_from
&& o.vessel_date =< date_to
&& ( term==null
|| o.vessel_name.Contains(term)
&& o.vessel_location.Contains(term)
&& o.vessel_mmsi.Contains(term))
select o);
I'm new to ASP.NET MVC and have been searching for a solution to this problem for hours. I'm trying to create a site where admins can go in and approve registration user requests and also assign them to a user group. I'm getting data from multiple tables so I created a viewmodel.
I finally have the GET Edit controller working to display the data, but can't figure out how the POST Edit should work. When I was debugging, I realized that the viewmodel I was trying to return had only null values.
I'm not sure if there are many things wrong with this code or just one. On postback, I need to update some values in the Access table. If you need more information from me, just let me know. Thanks!
ViewModel:
using System.Collections.Generic;
using AccessRequests.Models;
using System.ComponentModel.DataAnnotations;
namespace AccessRequests.ViewModels
{
public class UserAccessData
{
public IEnumerable<User> Users { get; set; }
public IEnumerable<Access> Accesses { get; set; }
public IEnumerable<UserGroup> UserGroups { get; set; }
}
}
Controller:
// GET: Accesses/Edit/5
public ActionResult Edit(string brand, string group)
{
var viewModel = new UserAccessData();
viewModel.Users = db.Users
.Include(i => i.Accesses)
.OrderBy(i => i.UserName);
viewModel.UserGroups = db.UserGroups
.Where(i => i.Groups.Contains(group));
if (brand != null)
{
viewModel.Accesses = db.Accesses
.Include(x => x.User)
.Where(x => x.Brand.ToUpper() == brand);
}
return View(viewModel);
}
// POST: Accesses/Edit/5
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Access access, UserAccessData editaccess)
{
//code here
}
View:
#model AccessRequests.ViewModels.UserAccessData
#{
ViewBag.Title = "Edit";
}
<h2>Edit Access</h2>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<table class="table">
<thead>
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Email</th>
<th>Company</th>
<th>Role</th>
<th>Region</th>
<th>User Group</th>
<th>Approve</th>
<th>Deny Reason</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.Accesses)
{
#Html.HiddenFor(modelItem => item.UserName)
<tr>
<td>
#Html.DisplayFor(modelItem => item.User.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Email)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Company)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Role)
</td>
<td>
#Html.DisplayFor(modelItem => item.User.Region)
</td>
<td>
#Html.DropDownListFor(m => m.UserGroups, new SelectList(Model.UserGroups, "Groups", "GroupDescription"), "Please select a User Group")
</td>
<td>
#Html.DropDownListFor(modelItem => item.Approved, new SelectList(
new List<Object>{
new { value = 0 , text = "" },
new { value = "YES" , text = "YES" },
new { value = "NO" , text = "NO"}
},"value","text", 2))
</td>
<td>
#Html.EditorFor(modelItem => item.DenyReason, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(modelItem => item.DenyReason, "", new { #class = "text-danger" })
</td>
</tr>
}
</tbody>
</table>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
}
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
In order to post to a collection property, your field names need to be in the form of something like: Accesses[0].Approved, Accesses[1].Approved, etc. In order to achieve that, you need to use a for loop rather than foreach. You'll also need to change your property's type from IEnumerable<Access> to List<Access>.
#for (var i = 0; i < Model.Accesses.Count(); i++)
{
...
#Html.DropDownListFor(m => Model.Accesses[i].Approved, ...)
}
Also, bear in mind that only those properties which have actual HTML fields that participate in the the post will have values in your post action. Everything else will either be null or whatever default value the property may have. If you save an entity with properties that have been nulled out because they weren't posted, you will overwrite those properties in your database. You need to take care to either make sure all the necessary data comes through in the post or that you repopulate said data from the the database before attempting to save anything.
I am using Jquery Datatable in asp.net MVC. I bind the sql query in datatable and the datatable i am using one Editfor, here i am using datetime picker. i attached my code on below. please help me.
<table id="datatable" class="display" border="1" cellpadding="2" cellspacing="2">
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.RMAKey)
</td>
<td>
#Html.DisplayFor(modelItem => item.SalesPerson)
</td>
<td>
#Html.DisplayFor(modelItem => item.SalesRep)
</td>
<td>
#Html.DisplayFor(modelItem => item.Datecreated)
</td>
<td>
#Html.EditorFor(model => model.First().FollowupDate)
#Html.ValidationMessageFor(model => model.First().FollowupDate)
</td>
<td>
#Ajax.ActionLink("Followup", "FollowupUpdate", new { RMAKey = item.RMAKey, FollowupDate=item.FollowupDate }, new AjaxOptions { UpdateTargetId = "modal", InsertionMode = InsertionMode.Replace, HttpMethod = "GET", OnSuccess = "onModalLoad" }, new { #class = "icon-secondary note" })
</td>
</tr>
}
</tbody>
</table>
The above code i am using #Html.EditorFor(model => model.First().FollowupDate). This is my problem occur here i get the date and send the date to partial view. How to generate the date dinamically?
I want to call a controller when click the button in view.How can I do it in MVC?.
This is my first controller.
public ActionResult DetailForm()
{
graduandModel model = new graduandModel();
var ceremonyList = _ceremonyService.GetAllCeremonyByDate(DateTime.Now);
if (ceremonyList.Count == 0)
{
return Content("No ceremony can be loaded");
}
else
{
foreach (var c in ceremonyList)
{
model.AvailableCeremony.Add(new SelectListItem() {
Text = "Ceremony at " + c.ceremony_date.ToString(),
Value = c.ceremony_id.ToString() });
}
return View(model);
}
}
This is my view.
#{
Layout = "~/Views/Shared/_ColumnsThree.cshtml";
}
#model graduandModel
#using Nop.Web.Models.Hire;
#using Nop.Web.Framework;
#using Telerik.Web.Mvc.UI;
#using System.Linq;
<table>
<tr>
<td>
#Html.LabelFor(model => model.ceremony_id)
</td>
<td>
#Html.DropDownListFor(model => model.ceremony_id, Model.AvailableCeremony)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.first_name):
</td>
<td>
#Html.EditorFor(model => model.first_name)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.middle_name):
</td>
<td>
#Html.EditorFor(model => model.middle_name)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.last_name):
</td>
<td >
#Html.EditorFor(model => model.last_name)
</td>
</tr>
<tr>
<td>
#Html.LabelFor(model => model.student_id):
</td>
<td>
#Html.EditorFor(model => model.student_id)
</td>
</tr>
<tr>
<td colspan="2" class="buttons">
<input type="submit" id="btnsearchgraduand" name="btnsearch"
class="searchbutton" value="#T("Search")" />
</td>
</tr>
</table>
Then When I click the search button I want to check the input data.
Should I write new controller like this
public ActionResult CheckDegreeDetails()
{
graduandModel model = new graduandModel();
var degreeList = _graduandService.GetGraduandByStudent(
model.ceremony_id, model.first_name,
model.middle_name, model.last_name);
return View(model);
}
Or...
I don't know how to call controller when click the button...
You want to wrap your user input fields and the submit button in a form. You can use an html helper that will also let you specify the controller action to call.
So modify your view:
...
#model graduandModel
#using Nop.Web.Models.Hire;
#using Nop.Web.Framework;
#using Telerik.Web.Mvc.UI;
#using System.Linq;
#using(Html.BeginForm("DetailForm", "ControllerName", FormMethod.Post, new {enctype="multipart/form-data"})
{
<table >
<tr>
<td >
#Html.LabelFor(model => model.ceremony_id)
</td>
...
//code omitted for brevity
...
<input type="submit" id="btnsearchgraduand" name="btnsearch" class="searchbutton" value="#T("Search")" />
})
Then in your controller you need to add the method to 'catch' this form. You're already using a strongly typed view so capturing the data is easy
[HttpPost]
public ActionResult DetailForm (graduandModel model)
{
//do what you need to do with the data here
//the model passed into this method's parameter should
//contain all the data from the editor templates in the view
}
The way you have your button, it won't make the request.
You can use jQuery/javascript.
HTML:
Javascript:
function callController()
{
$.get("YourController/Action",data, callBackMethod);
}
Or you can wrap your input, buttons etc... using #using(Html.BeginForm(..))