2015-12-09 3 views
0

Я знаю, что для этого есть другие сообщения, но я все равно не обворачиваю ее.MVC выпадающее меню обновить форму не работает

Я хотел бы написать свой MVC-просмотр для использования ViewModel, который позволит изменять текстовые поля в зависимости от выбора в выпадающем списке?

В приведенном ниже примере у меня есть коллекция шаблонов. Я хотел бы увидеть раскрывающийся список шаблонов, тогда пользователь будет выбирать элемент из DropDownList, код будет заполнять текстовые поля, пользователь может редактировать эти текстовые поля и, наконец, отправить форму с их изменениями.

Что происходит, так это то, что каждый раз, когда вызывается код Submit, он действует так, как если бы выбрано выпадающее меню.

Модель и 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; } 
} 

Вид:

@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 Код:

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}); 
} 
+0

Что вы подразумеваете под «он действует так, как если бы выбрано выпадающее меню»? – David

+0

'if (! String.IsNullOrEmpty (SelectedTemplateId))' по-прежнему истинно, поскольку выпадающий список по-прежнему выбран. Мне нужно, чтобы выпадающий список и кнопка отправки возвращались к контроллеру, но мне нужен способ узнать, что именно. Мне нужно различать обратный вызов dropdownlist и обратный вызов кнопки отправки. Большинство примеров, которые я нашел, останавливаются на этом. –

+0

Ну, где вы заселяете значение 'SelectedTemplateId' перед этим оператором' if'? Если ничего не задано, это будет «null». Кроме того, нет такой вещи, как «обратный вызов dropdownlist». Если вам нужно извлечь информацию с сервера при изменении списка, я бы рекомендовал создать отдельное действие только для этой цели и использовать AJAX для вызова этого действия и получения данных на стороне клиента. – David

ответ

0

Я понял это. Благодаря вашим комментариям, я разработал способ использовать Ajax, чтобы сделать это для нашей ситуации (я пытался сделать это как родовое как можно повторно использовать в других местах):

Вид:

<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); 
     } 
    }); 
}; 

контроллер:

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); 
} 

Я также последовали этому примеру, хотя она была неполной: CodeProject example

Смежные вопросы