I'm fairly new to MVC and I'm not coming up with the right question to get my answer from Google, so here I am.
I have a dropdownlist box that holds a 'list' of addresses associated to a customer, on this page I want to be able to click on one of the addresses and use the selected 'id' to get the correct address model from a list to populate all the address fields and switch when a different address is selected. Can this be done with binding or do I have to do a lot of 'manual' resetting of the values?
<table>
<tr>
<td colspan="2">
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.CityState, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.Location.City
, Model.Carrier.Locations.Select(x => new SelectListItem { Value = x.ID.ToString(), Text = x.CityState })
, new { #rows = 6, #multiple = false, style = "width: 300px;", onchange = "onChangeLocationDDL(this)" })
</div>
</div>
</td>
</tr>
<tr>
<td valign="top">
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Address1, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Address1)
#Html.ValidationMessageFor(model => model.SelectedLocation.Address1)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Address2, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Address2)
#Html.ValidationMessageFor(model => model.SelectedLocation.Address2)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.City, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.City)
#Html.ValidationMessageFor(model => model.SelectedLocation.City)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.State, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.State)
#Html.ValidationMessageFor(model => model.SelectedLocation.State)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Zip, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Zip)
#Html.ValidationMessageFor(model => model.SelectedLocation.Zip)
</div>
</div>
</td>
<td valign="top">
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Country, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Country)
#Html.ValidationMessageFor(model => model.SelectedLocation.Country)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Latitude, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Latitude)
#Html.ValidationMessageFor(model => model.SelectedLocation.Latitude)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.Longitude, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.SelectedLocation.Longitude)
#Html.ValidationMessageFor(model => model.SelectedLocation.Longitude)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.SelectedLocation.LocationType, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(model => model.SelectedLocation.LocationType, (new CarrierDirectoryWeb.Models.LocationTypes()).ToSelectList())
#Html.ValidationMessageFor(model => model.SelectedLocation.LocationType)
</div>
</div>
<div class="form-group">
<div class="col-md-10">
#Html.HiddenFor(model => model.SelectedLocation.CarrierID)
</div>
</div>
</td>
</tr>
</table>
If your ok hitting the controller to update a part of the page here is how you could do it:
-create a partial view for your html that is responsible for displaying the address.
-have your original view call this partial and pass in the address model.
-create an action that will take an Id and return the PartialViewResult.
-pass onchange as an html attribute for your dropdown that will should be a one liner using jquery to call the action method and replace the div that contains the address.
Related
I have a problem while uploading a File to a DMS server..I seem to not get value from a File label on my Insert page, I would be thankful for a suggestion or answer..
Here is my Create_Form
#model InsertDbProcedure
<div class="form-horizontal">
<div class="form-group">
#Html.LabelFor(model => model.IP_FILETYPE, new { #class = "control-label col-md-2" })
<div class="col-md-1">
#Html.EditorFor(model => model.IP_FILETYPE)
#Html.ValidationMessageFor(model => model.IP_FILETYPE)
</div>
#Html.LabelFor(model => model.File, new { #class = "control-label col-md-2" })
<div class="col-md-5">
#Html.EditorFor(model => model.File)
#Html.ValidationMessageFor(model => model.File)
#Html.ValidationMessageFor(model => model.FileName)
#Html.ValidationMessageFor(model => model.NewFileName)
</div>
</div>
</div>
<script>
const myFileForm = $('#File')[0].form;
$(myFileForm).attr('enctype', 'multipart/form-data');
</script>
and here is where i get error in my controller
Stream fileSteam = form.File.InputStream;
I have a edit view whose textboxes needs to be assigned with some fields after i click an edit button against a record in a table in another view.
<tbody>
#foreach (var client in this.Model.ClientsList)
{
<tr>
<td>#client.Name</td>
<td>#client.PhoneNo</td>
<td>#client.Address</td>
<td>#client.ProjectNo</td>
<td class="text-center">
<a href="../Downloads/Clients/#client.Logo" target="_blank">
<i class="fa fa-file-text"></i>
</a>
</td>
<td>#Html.ActionLink("Edit", "Edit")</td>
</tr>
}
</tbody>
This is the Edit view
#using (Html.BeginForm("Edit","Clients", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Clients</h4>
<hr />
#Html.ValidationSummary(true)
#Html.HiddenFor(model => model.ID)
<div class="form-group">
#Html.LabelFor(model => model.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Name)
#Html.ValidationMessageFor(model => model.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Address, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Address)
#Html.ValidationMessageFor(model => model.Address)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PhoneNo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.PhoneNo)
#Html.ValidationMessageFor(model => model.PhoneNo)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Logo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Logo)
#Html.ValidationMessageFor(model => model.Logo)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.ProjectNo, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.ProjectNo)
#Html.ValidationMessageFor(model => model.ProjectNo)
</div>
</div>
<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>
}
I tried my best but couldn't do it. So asking here. I also tried putting it an object but that also didn't work. I know it can be shared via query strings but that's not very efficient.
I assume that you want to edit the client data so You can pass data to another view by passing in TModelValue as third params like this
#Html.ActionLink("Edit","Edit", new { ID = client.Id })
Hope it will help.
Regrads.
Simply You can do this way
#Html.ActionLink("Edit", // <-- Link text
"url/GetClientDataById/2" // <-- Action Method Name
)
Preferred Way
#Html.ActionLink("Edit", "url/GetClientDataById", new { Id = client.Id })
public string GetClientDataById(int Id)
{
//perform your DB logic here and then return your object to view
}
I have this in my View:
<div class="form-group">
#Html.LabelFor(model => model.Q7, new { #class = "control-label col-md-4" })
<div class="col-md-5">
#Html.EditorFor(model => model.Q7)
#Html.ValidationMessageFor(model => model.Q7)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Q8, new { #class = "control-label col-md-4" })
<div class="col-md-5">
#Html.EditorFor(model => model.Q8)
#Html.ValidationMessageFor(model => model.Q8)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Q9, new { #class = "control-label col-md-4" })
<div class="col-md-5">
#Html.EditorFor(model => model.Q9)
#Html.ValidationMessageFor(model => model.Q9)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Q10, new { #class = "control-label col-md-4" })
<div class="col-md-5">
#Html.EditorFor(model => model.Q10)
#Html.ValidationMessageFor(model => model.Q10)
</div>
</div>
The user will enter this values and I have to sum all the values and show the result in another control, how can I do this in my View? Do i have to use Javascript or can i do it in a different way?
Thanks
You can invoke jquery's .focusout() for each editor, as all your editors will have their model property name id.
> $("#Q7").focusout(function() {
> // access the values of each textbox through $( "#Qn" ).text()
// cast, validate and add
> })
I have a Bootstrap Modal in ASP.Net with MVC 5 which I use to edit an entry on a FullCalendar javascript plugin.
_Edit.cshtml:
#model Models.CalendarEntry
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="myModalLabel">Edit Calendar Entry</h4>
</div>
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="modal-body">
<div class="form-horizontal">
<h4>#Model.Title</h4>
<hr />
#Html.ValidationSummary(true, "", new { #class = "text-danger" })
#Html.HiddenFor(model => model.CalendarEntryId)
#Html.HiddenFor(model => model.PostId)
<div class="form-group">
#Html.LabelFor(model => model.Title, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Title, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Title, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EntryDateTime, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
<div class="input-group" id="datetimepicker">
#Html.EditorFor(model => model.EntryDateTime, new { htmlAttributes = new { #class = "form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
</div>
#Html.ValidationMessageFor(model => model.EntryDateTime, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Length, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Length, new { htmlAttributes = new { #class = "form-control" } })
#Html.ValidationMessageFor(model => model.Length, "", new { #class = "text-danger" })
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.EntryStatus, htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EnumDropDownListFor(model => model.EntryStatus, htmlAttributes: new { #class = "form-control" })
#Html.ValidationMessageFor(model => model.EntryStatus, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" type="button">Cancel</button>
<input class="btn btn-primary" type="submit" value="Save" />
</div>
<script>
$(document).ready(function ()
{
$("#datetimepicker").datetimepicker();
});
</script>
}
For some reason two things are happening that I cannot figure out why.
Firstly, the glyphicon-calendar does not sit next to the input:
Secondly, when the Modal Form load, all the other fields except for the datetime field gets populated with data, until I click the calendar glyphicon, then the datetime field gets populated with the current date and time. The value from the model never gets displayed.
Web interfaces are not my forté and would appreciate any assistance.
When you create a new MVC project, it comes with a default css file(Site.css) which has some predefined css styles in it. By default, it has input field's max-width defined as 280px. That is the reason, your input groups are not working as expected.
If you remove/make adjustments to this css class in your ~/Content/Site.css, You css problem will be resolved.
turns out, that I needed to set options for the datetimepicker, more specifically, a default value it would seem like:
<script>
$(document).ready(function ()
{
$("#datetimepicker").datetimepicker(
{
defaultDate: '#Model.EntryDateTime',
showTodayButton: true,
format: 'YYYY-MM-DD HH:mm',
showClose: true,
showClear: true,
toolbarPlacement: 'top',
stepping: 15
});
});
</script>
Would you try to put an attribute:
[DataType(DataType.DateTime)]
public DateTime EntryDateTime {get; set;}
and comment the JS script?
Example
Another quick solution is to also format the date like this in your javascript:
defaultDate: '#Model.EntryDateTime.ToString("yyyy-MM-dd HH:mm")'
The solution of using the [DisplayFormat] as an attribute is just as valid if not a better solution.
<div class="container">
<div class="row">
<div class='col-md-12'>
<div class="form-group">
<span col-sm-6> #Html.Label("Date of Birth", htmlAttributes: new { #class = "control-label col-md-2" })</span>
<div class='input-group date col-sm-3' id='datetimepicker1'>
#Html.EditorFor(model => model.DateOfBirth, new { htmlAttributes = new { #class = "form-control" } })
<span class="input-group-addon">
<span class="glyphicon glyphicon-calendar"></span>
</span>
#Html.ValidationMessageFor(model => model.DateOfBirth, "", new { #class = "text-danger" })
</div>
</div>
</div>
</div>
</div>
I've been following the nerd dinner tutorial. I branched off to create my own project based on it and I'm having trouble getting UpdateModel to work. It seems pretty complicated so I'll try to explain it in as much detail below.
In ServersController.cs:
public ActionResult Create(FormCollection formValues)
{
Server server = new Server();
try
{
UpdateModel(server); <----- This is not working
// server.Name = "testAdd";
// server.OS = "2008 R2";
serverRepository.Add(server);
serverRepository.Save();
return RedirectToAction("Details", new { id = server.ServerID });
}
catch
{
**not important**
}
If I try to use UpdateModel(Server), nothing gets saved to the database table. However, If I comment out that line, and use the commented lines in the code that sets the server.Name and server.OS, this DOES save it to the table. However, any other form input that's being posted doesn't save..
For example, if I explicitly set the server.Name and server.OS as in the code above, but then set other properties such as LastBackedUp and Model through the form, none of the properties set from the form are saved to the database table, nor are they reflected in the "details" view when the page gets redirected.
Here's the code for the "Details" GET method, also in ServersController.cs:
public ActionResult Details(int id)
{
Server server = serverRepository.GetServer(id);
RackInfo rackInfo = rackRepository.GetRack(id);
if (server == null)
return View("NotFound");
else
return View(new ServerDetailViewModel(rackInfo, server));
}
Basically, After the new server is created and saved, it's supposed to load the above "Detail" view, which uses a "ServerDetailViewModel" class to generate some data to pass to the view.
Here's the ServerDetailViewModel() code:
public class ServerDetailViewModel
{
public RackInfo RackInfo { get; private set; }
public Server Server { get; private set; }
public string Name { get; private set; }
public ServerDetailViewModel(RackInfo rackInfo, Server server)
{
Server = server;
RackInfo = rackInfo;
*more code here that sets stuff*
}
}
I think my problem has something to do with how my form parameters are passed around.
It seems odd that I can explicitly code in some server properties, and then save those into the database table. But when I try to do anything with UpdateModel, nothing seems to go through. When I use UpdateModel, it will redirect me to the details page, but none of the values I input for the properties seem to appear. Additionally, none of the properties I put in through the form gets saved to the database table.
If any of you have walked through the Nerd Dinner tutorial (http://weblogs.asp.net/scottgu/archive/2009/04/28/free-asp-net-mvc-nerddinner-tutorial-now-in-html.aspx), that's what I've been using. When I got through about halfway, I decided to start a new project that implemented what I was using.
I was initially able to get Create to work, but after adding another separate repository to the controller, the create method broke..
Any input or insight on this would be much appreciated. Please let me know if you need any additional information.
Thanks S.O.!!
EDIT (Including the "Create" Form):
#model PACSSL.Models.ServerFormViewModel
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Server</h4>
<hr />
#Html.ValidationSummary(true)
<div class="form-group">
#Html.LabelFor(model => model.Server.Name, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.Name)
#Html.ValidationMessageFor(model => model.Server.Name)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Domain, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.Domain, Model.Domain)
#Html.ValidationMessageFor(model => model.Domain)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.BackedUp, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.BackedUp, Model.BackedUp)
#Html.ValidationMessageFor(model => model.BackedUp)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.Role, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.Role)
#Html.ValidationMessageFor(model => model.Server.Role)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.GroupOwner, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.GroupOwner)
#Html.ValidationMessageFor(model => model.Server.GroupOwner)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.PatchNotes, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.PatchNotes)
#Html.ValidationMessageFor(model => model.Server.PatchNotes)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.LastPatched, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.LastPatched) Format: yyyy-mm-dd
#Html.ValidationMessageFor(model => model.Server.LastPatched)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.PatchedBy, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.PatchedBy, Model.PatchedBy)
#Html.ValidationMessageFor(model => model.PatchedBy)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.VP, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownListFor(x => x.VP, Model.VP)
#Html.ValidationMessageFor(model => model.VP)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.VMHost, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.VMHost)
#Html.ValidationMessageFor(model => model.Server.VMHost)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.Location, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.Location)
#Html.ValidationMessageFor(model => model.Server.Location)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.PurchaseDate, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.PurchaseDate) Format: yyyy-mm-dd
#Html.ValidationMessageFor(model => model.Server.PurchaseDate)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.OS, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.OS)
#Html.ValidationMessageFor(model => model.Server.OS)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.Model, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.Model)
#Html.ValidationMessageFor(model => model.Server.Model)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.DellST, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.DellST)
#Html.ValidationMessageFor(model => model.Server.DellST)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.ServiceContract, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.ServiceContract) Format: yyyy-mm-dd
#Html.ValidationMessageFor(model => model.Server.ServiceContract)
</div>
</div>
<div class="form-group">
#Html.LabelFor(model => model.Server.IsLive, new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.EditorFor(model => model.Server.IsLive)
#Html.ValidationMessageFor(model => model.Server.IsLive)
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
Here's your problem.
When you generate a form field with the expression model => model.Server.OS, you produce a field that has a 'name' attribute like this:
"Server.OS"
Then, when you try and bind it to a model, it will bind to a model property matching the expression "Server.OS" - so, if your model object is server, it will bind to the following:
server.Server.OS
When, I presume, you want to bind to server.OS. My suggestion would be to flatten out your view model so instead of having Model.Server.OS you just have Model.OS. Then when you do...
UpdateModel(server);
... it should bind the "OS" field to the "OS" property.
In short: your view model has an extra level of property nesting compared to your server object, so there is a mismatch in the generated field names and the properties you're trying to bind to.
Better still, bind back to the same view model by modifying your controller action to have the signature:
public ActionResult Create(ServerDetailViewModel model)
And then do the mapping manually in the controller (or some static mapping class) - your view models and domain model should be completely independent.
You are trying to update a "empty" Model. It is empty because you are creating a new instance.
Server server = new Server();
try
{
//At this point you have an empty model because you just
//created a new Instance of your Server class,
//It is updating the Model with all Null values because they aren't assigned to anything
UpdateModel(server); <----- This is not working
//Here you assign values to your model, hence why they are not null anymore
// Your other values aren't getting saved because they still don't have a value.
server.Name = "testAdd";
server.OS = "2008 R2";
serverRepository.Add(server);
serverRepository.Save();
return RedirectToAction("Details", new { id = server.ServerID });
}