Replacing a form text field with drop-down list - asp.net-mvc

I created a simple Tasks webapp using .NET 4.0 MVC & Entity Framework. Pulling data from a database.
I have tables:
Staff {PkId, FirstName, LastName}
Tasks {PkId, Task, TaskDescription, DueDate}
TasksAssigned {PkId, StaffId, TaskId}
When I go to Edit TasksAssigned record (Edit page) I'll get a form (stripped div/css for space)
#Html.LabelFor(model => model.PkId)
#Html.EditorFor(model => model.PkId)
#Html.LabelFor(model => model.StaffId)
#Html.EditorFor(model => model.StaffId)
#Html.LabelFor(model => model.TaskId)
#Html.EditorFor(model => model.TaskId)
But I need to be shown Task instead TaskId, and LastName instead StaffId. And I need is to have drop-downs in the form instead text field with all names and all tasks available so I can select other person or other task (or both).
I'm assuming I should use DropDownList() or DropDownListFor() ?
Thanks for any help.
(addon)
Let me try to explain better...
So, let's say there are Staff members:
{ 12, "John", "Dow" },
{ 15, "Bill", "Smith" }.
Let's say there is task
{ 3, "Clean the printer", "Call company to clean the printer... ", "2016-06-25" }.
So, there's going to be a record in TaskAssigned
{ 8, 12, 3 }
Ok?
Let's change the the record so the task is assigned to Bill instead John. So, I would click on "Edit" button and on the Edit page I would have form with two text fields ( [ and ] represent text field of the form)
Staff: John Dow
Task: Clean the printer
To change it I have to replace the name with 15, Bill's ID, right? I would like to have a drop-down with names of John and Bill and then select Bill's name and when submit, Bill's ID will be stored in TasksAssigned table.

I'm assuming you're including the other two tables when you call for your data. If so you should easily be able to display the fields you're needing with referencing towards the correct ones. Purely based on what's in your question this should look something like the below.
#Html.HiddenFor(model => model.TaskId)
#Html.LabelFor(model => model.Tasks.Task)
#Html.EditorFor(model => model.Tasks.Task)
#Html.LabelFor(model => model.Staff.LastName)
#Html.EditorFor(model => model.Staff.LastName)
I don't see the immediate need to show or even give an option to edit the PK value of the TaskAssigned entry. That's the reason I moved it to Hidden
If you want to give the users a dropdownlist you'll have to make sure you're sending the potential choices along in your Model. In this case you'll preferably want to be using a ViewModel to send along the choices.
That way you'll be able to do something like the below.
List<SelectListItem> listOfStaff = new List<SelectListItem>();
listOfStaff.Add(new SelectListItem
{
Text = "Mark",
Value = "1"
});
listOfStaff.Add(new SelectListItem
{
Text = "John",
Value = "2",
Selected = true
});
Leading you to the DropDownListFor you already referenced in your question.
#Html.DropDownListFor(model => model.StaffId, model.listOfStaff, "-- Select Staffmember --")
Hope this helps you along a little more towards a working solution.

Related

ASP>NET MVC concatenate two details onto dropdown list

If I'm using this viewbag
ViewBag.employee = (from e in db.Employees
select e.FullName).Distinct();
to use in this dropdown list
<div class="form-group">
#Html.LabelFor(model => model.EmployeeID, "EmployeeID", htmlAttributes: new { #class = "control-label col-md-2" })
<div class="col-md-10">
#Html.DropDownList("EmployeeID", new SelectList(ViewBag.employee), "--Select--")
#Html.ValidationMessageFor(model => model.EmployeeID, "", new { #class = "text-danger" })
</div>
</div>
Is there a way to concatenate on another detail?
For example EmployeesID so that when you use the dropdown list, the EmployeeID will appear beside their name? I need this feature as some employees might have the same name.
One way to get what you've asked for is to use
select e.FullName + " (" + e.ID + ")"
to concatenate the values together at source in the query.
And remove the Distinct() as it's unnecessary.
P.S. As a broader point, your dropdown list really ought to be using the ID to identify the selected item anyway. So your SelectList should be passed a list of SelectListItem (these can hold both an ID and a display value) instead of a simple list of strings. That way when the form is submitted back to the server you can be certain exactly which employee was selected. You want Razor to render options like <option id="2">Joe Bloggs (2)</option> so that "2" will be the value submitted back to the server. The display value is just for the user and isn't very useful when sending the data back. If you do some searching you'll soon find examples of creating and using SelectListItems.

How to save the user email address into 2 different textboxes

Basically I have 2 textboxes; I would like whatever the user types into the email textbox to be saved into the name textbox as well.
Basically saving the email address in 2 places. I’m new to MVC any examples would be good, cheers.
#Html.TextBoxFor(m => registerModel.Name, new { #class = "form-control" })
#Html.TextBoxFor(m => registerModel.Email, new { #class = "form-control" })
If you want to save the same values for the both text fields, you can assign same value to both on post function, there is no need for an additional text field.
But if you want to display same value for both text box while typing on one text box. Then try following javascript.
$("#Name").keyup(function(){
var Names = $("#Name").val();
$("#Email").val(Names);
})

MVC models to populate KendoUI Multiselect - preloading selected items

I currently have the multiselect working the way I want it with one exception. Preloading previously selected items.
My view looks:
<div class="editor-field">
#Html.LabelFor(model => model.UntaggedPersons)
#Html.ListBoxFor(model => model.PeopleToTag,
new SelectList(Model.CommitteeMembers, "PersonId", "FullName"))
</div>
JS:
$("#PeopleToTag").kendoMultiSelect({ "dataTextField": "FullName", "dataValueField": "PersonId", "placeholder": "Tag or Untag Persons to Action Item" });
PeopleToTag is an IEnumerable<int> int that posts to the controller
CommitteeMembers consists of a persons First, Last, FullName, and PersonId
This works perfectly, I can manipulate who is tagged in the post to the controller.
Now I want to add the functionality of preselecting those that are currently tagged.
How do I add a preselected Value? I have a model with:
model.TaggedPersons consists of a persons First, Last, Fullname, PersonId.
How do I wire up the javascript to display the model.TaggedPersons as the already selected value?
I don't mind using the MVC wrapper approach if it is easier.
I've tried something like:
<div class="editor-field">
#Html.LabelFor(model => model.TaggedPersons)
#(Html.Kendo().MultiSelectFor(model => model.PeopleToTag)
.Name("PeopleToTag")
.Placeholder("These people are Tagged")
.DataTextField("FullName")
.DataValueField("PersonId")
.BindTo(Model.CommitteeMembers)
.Value(Model.TaggedPersons)
)
</div>
However this isn't even rendering a kendo multiselect for me at present. That's the general thought of how I want to approach it though.
Any help is much appreciated!
Change:
DataTextField("FullName") to DataTextField("Text")
DataValueField("PersonId") to DataValueField("Value")
SelectList uses "Text" and "Value", respectively. You already filled the fields of the select list with FullName and PersonId when the selectlist was created.

Editor And ReadOnly Error

I have simple edit form, where you can edit user profile, but you cannot edit username.
So instead this code:
#Html.EditorFor(model => model.username)
I use this line:
#Html.TextBoxFor(model => model.username, new {disabled = "disabled", #readonly = "readonly" })
This works fine, but, I cannot save other fields which are "EditorFor"
e.g. I have column Customers, so one user can have one or more customers, so if I make change in edit, e.g. add new user to customer, and then when I click save, it does not save it. But if I change code again to #Html.EditorFor(model => model.username) then it save it...
Any idea how to fiks this?
The problem is that a read only textbox is not sent back (value is not in POSTed datas).
So if you want to have a readonly textbox AND have the value of username in POSTed datas, you'll have to add a
#Html.HiddenFor(m => m.username)
But... if you just wanna display them, you should just manage that in your controller (don't try to update username... as you don't wanna update username).

What is the best way to persist data between several views

I am working on an MVC 5 application and have the following scenario.
The user clicks my registration link to create an account and is served with a view like so. Works as expected.
[HttpGet]
[AllowAnonymous]
public ActionResult RenderRegisterModal(string userType)
{
IList<UserTypesDto> userTypes = _userService.GetUserTypes();
var usersRegisterUserViewModel = new UsersRegisterUserViewModel {UserTypes = new List<SelectListItem>()};
usersRegisterUserViewModel.UserTypes.Add(new SelectListItem
{
Text = "Select a registration type",
Value = "0"
});
foreach (UserTypesDto userTypeDto in userTypes)
{
usersRegisterUserViewModel.UserTypes.Add(new SelectListItem
{
Text = userTypeDto.UserType,
Value = userTypeDto.UserTypeId.ToString()
});
}
return PartialView("_RegisterModal", usersRegisterUserViewModel);
}
Now based on the type of customer / userType they choose I need to present different views. Should not have any issue getting the view into the modal as it is ajax... So lets call this a pseudo wizard to collect data. The issue I am having and the basis for this probably simple question, that I am thinking too much about, is how do I save the data from each step?? Temp Table? InMemory Cache using the session id as the key? Cookies? "Gross"
The ActionMethod that the post goes to looks like this.
[AllowAnonymous]
[HttpPost]
public ActionResult Register(UsersRegisterUserViewModel usersRegisterUserViewModel)
{
//TODO Return a view for the next step based on the CustomerType contained in the viewModel
return View();
}
Any feedback would be greatly appreciated.
OPTION 1:
The easiest way, is that the NEXT view have a set of hidden fields with the information entered in the previous view and which was posted to the Action.
This way, once you post the second view, you will be posting all the information (previous one and the one you entered in the second view).
OPTION 2:
If you are not comfortable with the first approach, you can have several PartialViews that are shown or hidden in javascript on UserType combo changes. Your ViewModel should have all the propertied you need to hold the information before posting back to server.
This option came in 2 flavors: you render all your usertype partials at the begining (so you need to hide them at first), or you can get the partial via Ajax once the user selected one user type.
OPTION 3:
You can use Session to hold the sensitive data from the register form, redirect to the next view depending on user type, post the new form, and in the Action you retrieve the information from Session... and with all the information in your hands store it in database.
If you're using razor, persist the different parts of your model like this
#Html.EditorFor(model => model.data1)
#Html.EditorFor(model => model.data2) #*Wizard part 1*#
then in the next view for your wizard
#Html.HiddenFor(model => model.data1)
#Html.HiddenFor(model => model.data2)
#Html.EditorFor(model => model.data3)
#Html.EditorFor(model => model.data4) #*Wizard part 2*#
and then
#Html.HiddenFor(model => model.data1)
#Html.HiddenFor(model => model.data2)
#Html.HiddenFor(model => model.data3)
#Html.HiddenFor(model => model.data4)
#Html.EditorFor(model => model.data5) #*Wizard part 3...*#
and so on...

Resources