0

Web Dev noob here. I am currently using VS2019 and have created a MVC App to provide CRUD functionality (SQL) to inhouse users. We have a CostCentre field which should be a dropdown and not a text input.

How do I change the code to display dropdown instead of text input?

This is what contained in my controller:

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Magic,EmployeeCode,UserName,Entity,AD_SAM,MSTelNum,CostCentre,SysUser_AD,Sys_User_K8")] EmpCosDim empCosDim)
{
    if (ModelState.IsValid)
    {
        db.Entry(empCosDim).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index");
    }
    return View(empCosDim);
}

Am I looking at the right place?

UPDATE Edit View cshtml:

@model EmployeeBilling.EmpCosDim
@{
    ViewBag.Title = "Edit";
}

<h2>Edit</h2>

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()
    
    <div class="form-horizontal">
        <h4>EmpCosDim</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })
        @Html.HiddenFor(model => model.Magic)

        <div class="form-group">
            @Html.LabelFor(model => model.EmployeeCode, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.EmployeeCode, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.EmployeeCode, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.UserName, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.UserName, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.UserName, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Entity, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Entity, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Entity, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.AD_SAM, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.AD_SAM, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.AD_SAM, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.MSTelNum, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.MSTelNum, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.MSTelNum, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.CostCentre, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.CostCentre, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.CostCentre, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.SysUser_AD, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.SysUser_AD, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.SysUser_AD, "", new { @class = "text-danger" })
            </div>
        </div>

        <div class="form-group">
            @Html.LabelFor(model => model.Sys_User_K8, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                @Html.EditorFor(model => model.Sys_User_K8, new { htmlAttributes = new { @class = "form-control" } })
                @Html.ValidationMessageFor(model => model.Sys_User_K8, "", new { @class = "text-danger" })
            </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>
}

<div>
    @Html.ActionLink("Back to List", "Index")
</div>

@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

UPDATE Added the ForeignKey as per the link you sent, but still does not display the dropdown. I did the change here:

EmpCosDim.cs

// EmpCosDim.cs :

namespace EmployeeBilling
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;

    public class EmpCosDim
    {
        public int Magic { get; set; }
        public string EmployeeCode { get; set; }
        public string UserName { get; set; }
        public string Entity { get; set; }
        public string AD_SAM { get; set; }
        public string MSTelNum { get; set; }

        [ForeignKey("ContainingCostCentre")]
        public string CostCentre { get; set; }
        public virtual EmpCosDim ContainingCostCentre { get; set; }

        public string SysUser_AD { get; set; }
        public string Sys_User_K8 { get; set; }
    }
}

UPDATE So I've tried updating the CostCentre to a List in my EmpCosDim.cs file:

public class EmpCosDim
{
    [Key]
    public int Magic { get; set; }
    public string EmployeeCode { get; set; }
    public string UserName { get; set; }
    public string Entity { get; set; }
    public string AD_SAM { get; set; }
    public string MSTelNum { get; set; }

    public List<SelectCostCentreItem> CostCentre { get; set; }

    public string SysUser_AD { get; set; }
    public string Sys_User_K8 { get; set; }
}

public class SelectCostCentreItem
{
    public string CostCentre { get; set; }
}

But I'm getting an error on my Controller EmpCosDimsController.cs:

public ActionResult Index()
{
    return View(db.EmpCosDims.ToList());
}

Error

This seems to be because I replaced:

public string CostCentre { get; set; }

with

public List<SelectCostCentreItem> CostCentre { get; set; }

How can I update my controller to see the List and display in a dropdown?

David Liang
  • 20,385
  • 6
  • 44
  • 70
PKirby
  • 859
  • 3
  • 16
  • 36
  • Can you show the Edit View cshtml? – Julián Oct 27 '20 at 17:32
  • Hi @Julián , apologies for the late response. I have editted my original question to contain the edit view cshtml as requested. – PKirby Nov 02 '20 at 06:22
  • I think that MVC should match according to a foreign key in SQL, you could look at this and check your model: https://stackoverflow.com/questions/22046102/mvc-5-code-first-scaffolding-with-simple -relationship – Julián Nov 02 '20 at 14:35
  • Thanks @Julián , I added the ForeignKey as per the link but still not showing the dropdown. Its still just a free text field. I've updated the question with the script. – PKirby Nov 03 '20 at 08:53
  • A step-by-step on scaffolding a dropdown list: https://learn.microsoft.com/en-us/aspnet/mvc/overview/older-versions/working-with-the-dropdownlist-box-and-jquery/examining-how-aspnet-mvc-scaffolds-the-dropdownlist-helper – Alex Nov 03 '20 at 12:07
  • Hi @Alex , thank you for the link. I am struggling to impliment the dropdown list to the required field. Could you maybe assist by advising what should change on my code? My apologies for the noobness. – PKirby Nov 04 '20 at 09:41
  • Hi @Alex , I updated the post, any idea how I can get it to work? – PKirby Nov 05 '20 at 12:34
  • That error may be caused by this: https://stackoverflow.com/a/40388052/177416. For now, focus on the error and don't worry about the dropdown list. As far as the dropdown, I use the scaffolding to create the files; then I edit them to have dropdowns, text boxes, textareas, etc. – Alex Nov 06 '20 at 13:31

1 Answers1

1

The drop down list of CostCentre in your edit screen will actually display the list of all CostCentre that you want to be selected. This list is not readily available in the EmpCosDim model and the view. You need to build a selectlist and pass to your view and make change in view to get that list and display as dropdown. Follow these steps -

In the Edit action (for Get not the post action) populate the view bag like this

ViewBag.CostCentre = new SelectList([db.Concetres], ["Name"], ["Name"], 
[empCosDim.CostCentre]);

Here you have to replace the bracketed items with your appropriate variable/method. For the select list constructor first one is the source/list of the all costcenters, second one the field name of the EmpCosDim that you want to save as the value when it get selected, third one the field of the EmpCosDim that you want to display in the dropdown, and last one is the value you want to be selected by default.

In the Edit view replace following code

<div class="form-group">
    @Html.LabelFor(model => model.CostCentre, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.EditorFor(model => model.CostCentre, new { htmlAttributes = new { @class = "form-control" } })
        @Html.ValidationMessageFor(model => model.CostCentre, "", new { @class = "text-danger" })
    </div>
</div>

with the next code block

<div class="form-group">
        @Html.LabelFor(model => model.CostCentre, htmlAttributes: new { @class = "control-label col-md-2" })
        <div class="col-md-10">
            @Html.DropDownList("CostCentre", (IEnumerable<SelectListItem>)ViewBag.CostCentre, new { htmlAttributes = new { @class = "form-control" } })
            @Html.ValidationMessageFor(model => model.CostCentre, "", new { @class = "text-danger" })
        </div>
 </div>
Raihan
  • 395
  • 2
  • 9