简体   繁体   中英

MVC dropdown update the form not working

I know there are other posts for this, but I'm still not wrapping my head around it.

I would like write my MVC view to use a ViewModel that will allow text fields to change based on selections in a dropdownlist?

In the below example, I have a collection of Templates. I would like to see the dropdown list the Templates, then the user would select an item from the DropDownList, the code would populate the text fields, the user could edit those text fields, and finally submit the form with their changes.

What happens now is that every time the Submit code is called, it acts as if the dropdown was selected.

Model and ViewModel:

public class Template
{
    [Display(Name = "Template")]
    public int TemplateId {get; set;}
    public string TemplateName {get; set;}
    public string Subject {get; set;}
    public string Message {get; set;}
}

public class TemplateViewModel
{
    [Display(Name = "Template")]
    public int LetterTemplateId {get; set;}
    public ICollection<Template> Templates { get; set; }
}

View:

@model MyWebProject.ViewModels.TemplateViewModel
@using (Html.BeginForm("callforcontentproposaldetail","Project", FormMethod.Post, new {id = "frmProposalDetail"}))
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">
        <h4>Email Template</h4>
        <hr />
        @Html.ValidationSummary(true, "", new { @class = "text-danger" })

        <div class="form-group">
            @Html.LabelFor(model => model.LetterTemplateId, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-4">
                @Html.DropDownListFor(m => m.LetterTemplateId,
                    new SelectList(Model.Templates as IEnumerable, "TemplateId", "TemplateName"),
                    new { @class = "form-control", onchange = "document.getElementById('frmProposalDetail').submit();", id = "ddlTemplate" })
                @Html.ValidationMessageFor(model => model.LetterTemplateId, "", new { @class = "text-danger" })
            </div>
        </div>

        <div id="letterTemplateEditArea">
            <div class="form-group col-md-12">
                <div class="row">
                    @Html.TextBoxFor(model => model.SelectedTemplate.TemplateSubject, new { @class = "form-control" })
                    @Html.LabelFor(model => model.SelectedTemplate.Message, new { @class = "control-label" })
                    @Html.TextAreaFor(model => model.SelectedTemplate.Message, new { @class = "form-control", @style = "max-width:100%;height:400px;font-size:11px;" })
                </div>
            </div>
            <br />
        </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>
}

Controller Code:

public ActionResult callforcontentproposaldetail(Guid id)
{
    var proposal = db.CallForContentProposal.Find(id);

    var model = Mapper.Map<CallForContentProposalViewModel>(proposal);

    if (TempData["LetterTemplateId"] != null)
    {
        var emailTempId = 0;
        if (int.TryParse((string)TempData["LetterTemplateId"], out emailTempId))
        {
            var template = model.Templates.FirstOrDefault(t => t.TemplateId == emailTempId);
            model.SelectedTemplateId = emailTempId;
            model.Subject = template.Subject;
            model.Message = template.Body;
        }
    }

    return View(model);
}

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult callforcontentproposaldetail(CallForContentProposalViewModel model, string SelectedTemplateId = "")
{
    // Do some saving of the current data
    // ...
    db.SaveChanges();

    // If this is the dropdownlist calling, redirect back to display the text fields populated
    if (!string.IsNullOrEmpty(SelectedTemplateId))
    {
        TempData["LetterTemplateId"] = SelectedTemplateId;
        return RedirectToAction("callforcontentproposaldetail", new { id = model.CallForContentProposalId });
    }

    // On Submit, do other tasks

    return RedirectToAction("callforcontent", new {id =  model.CallForContentId});
}

I figured it out. Thanks to your comments, I worked out a way to use Ajax to do this for our situation (I tried to make it as generic as possible to reuse elsewhere):

View:

<div class="form-group">
    @Html.LabelFor(model => model.LetterTemplateId, htmlAttributes: new { @class = "control-label col-md-2" })
    <div class="col-md-4">
        @Html.DropDownListFor(m => m.LetterTemplateId,
            Model.EmailTemplateSelect(),
        new { @class = "form-control", onchange = "EmailTemplateLoad.call(this,this.options[this.selectedIndex].value,'LetterTemplateSubject','LetterTemplateBody');", id = "ddlReviewRole" })
        @Html.ValidationMessageFor(model => model.LetterTemplateId, "", new { @class = "text-danger" })
    </div>
</div>

Javascript:

EmailTemplateLoad = function(id, subjectTbName, messageTbName) {
    debugger;
    var ServiceUrl = "/Project/LoadTemplate?id=" + id;
    var content = '';
    $.support.cors = true;
    $.ajax({
        type: 'GET',
        url: ServiceUrl,
        async: true,
        cache: false,
        crossDomain: true,
        contentType: "application/json; charset=utf-8",
        dataType: 'json',
        error: function (xhr, err) {
        },
        success: function (result, status) {
            $('#' + subjectTbName).val(result[0].Subject);
            $('#' + messageTbName).val(result[0].Message);
        }
    });
};

Controller:

public ActionResult LoadTemplate(int id)
{
    var result = (from t in db.EmailBodyTemplate
        where t.EmailTemplateId == id
        select new
        {
            t.Subject,
            Message = t.Body
        });

    return Json(result, JsonRequestBehavior.AllowGet);
}

I also followed this example, although it was incomplete: CodeProject example

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM