2016-07-17 50 views
0

我正在嘗試創建一個調度MVC應用程序。在ViewModel中,我組合了來自CodeFirst EF字段的字段以包含會議主持人,訪問者和時間等。我希望能夠通過此表單創建新的訪問者(如果他們尚不存在並通過Ajax回發)更新可用訪問者的列表。使用jQuery和部分視圖在MVC中添加新的DropDownList項目

視圖模型:

public class AppointmentViewModel 
{ 
    public int HostID{ get; set; } 
    public IEnumerable<SelectListItem> HostList{ get; set; } 
    public int? VisitorID { get; set; } 
    public IEnumerable<SelectListItem> VisitorList { get; set; } 
    public string VisitorTitle { get; set; } 
    public string VisitorFirstName{ get; set; } 
    public string VisitorSurname { get; set; } 
    public string VisitorCompany { get; set; } 
    public DateTime VisitTime { get; set; } 

} 

控制器:

public class AppointmentController : Controller 
{ 
    private VisitorManagerContext db = new VisitorManagerContext(); 

    // GET: Appointment 
    public ActionResult Create() 
    { 
     ViewBag.HostID = new SelectList(db.Hosts.OrderBy(x => x.Name), "id", "Name"); 
     //ViewBag.VisitorID = new SelectList(db.Visitors.OrderBy(x => x.LastName).ThenBy(y => y.FirstName), "id", "VisitorName"); 
     return View(new AppointmentViewModel() 
     { 
      HostList = db.Hosts.OrderBy(x => x.Name).Select(y => new SelectListItem() 
      { 
       Value = y.id.ToString(), 
       Text = y.Name 
      }), 
      VisitorList = db.Visitors.OrderBy(x => x.LastName).ThenBy(y => y.FirstName).Select(z => new SelectListItem() 
      { 
       Value = z.id.ToString(), 
       Text = z.Title + " " + z.FirstName + " " + z.LastName 
       }) 
      } 
     ); 
    } 

    [HttpPost] 
    public JsonResult CreateVisitor(AppointmentViewModel model) 
    { 
     var visitor = new Visitor() 
     { 
      Title = model.VisitorTitle, 
      FirstName = model.VisitorFirstName, 
      LastName = model.VisitorSurname 
     }; 
     db.Visitors.Add(visitor); 
     db.SaveChanges(); 
     return Json(visitor.id); 
    } 

    public PartialViewResult Add() 
    { 
     return PartialView(); 
    } 
} 

查看:

@model VisitorManager.Models.AppointmentViewModel 
@{ 
    ViewBag.Title = "Create"; 
} 

<h2>Create</h2> 

@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 

    <div class="form-horizontal"> 
     <h4>AppointmentViewModel</h4> 
     <hr /> 
     @Html.ValidationSummary(true, "", new { @class = "text-danger" }) 
     <div class="form-group"> 
      @Html.LabelFor(model => model.HostID, "HostID", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DropDownListFor(model => model.HostID, Model.HostList, "- Please select -", htmlAttributes: new { @class = "form-control" }) 
       @Html.ValidationMessageFor(model => model.HostID, "", new { @class = "text-danger" }) 
      </div> 
     </div> 

     <div class="form-group"> 
      @Html.LabelFor(model => model.VisitorID, "VisitorID", htmlAttributes: new { @class = "control-label col-md-2" }) 
      <div class="col-md-10"> 
       @Html.DropDownListFor(model => model.VisitorID, Model.VisitorList, "- Please select -", htmlAttributes: new { @class = "form-control" }) 
       @Html.ValidationMessageFor(model => model.VisitorID, "", new { @class = "text-danger" }) 
      </div> 
      <button type="button" id="addVisitor">Add new Visitor</button> 
     </div> 

     <div id="VisitorModal"></div> 

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

    <script type="text/javascript"> 
     $('#addVisitor').click(
      function() { 
       $('#VisitorModal').load('@Url.Action("Add", "Appointment")'); 
      } 
     ); 


    </script> 

管窺:

@model VisitorManager.Models.AppointmentViewModel 


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

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

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

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

<div class="form-group"> 
    <div class="col-md-offset-2 col-md-10"> 
     <input type="submit" value="Create" class="btn btn-default" id="visitorform" /> 
    </div> 
</div> 

@section Scripts { 
    <script type="text/javascript"> 
     $('#visitorform').submit(function() { 
      var data = $(this).serialize(); 
      var url = '@Url.Action("CreateVisitor", "Appointment")'; 
      var text = $('#surname').val(); // a value from the form that you want as the option text 
      $.post(url, data, function (response) { 
       if (response) { 
        $('#HostID').append($('<option></option>').val(response).text(text)).val(response); 
       } else { 
        // Oops 
       } 
      }).fail(function() { 
       // Oops 
      }); 
      // ... close the modal 
      return false; // cancel the default submit 
     }); 
</script>} 

我知道樣式應該改進,並且新的訪問者窗體應該以模態方式顯示,但是我希望在我有邏輯工作後修復。

單擊「添加新訪問者」將顯示部分視圖,包括將新訪問者提交回控制器的按鈕。單擊分部視圖中的「創建」按鈕將關閉視圖,但表單數據不會提交回控制器。

任何想法爲什麼事件沒有解僱?

將新訪問者添加到DropDownList後,我認爲需要填寫表單的其餘部分並提交約會。

回答

1

您沒有id="visitorform"的第二種形式。在您需要的部分元素被包裹在<form>標籤

@model VisitorManager.Models.AppointmentViewModel 
<form id="visitorform"> 
    <div class="form-group"> 
     @Html.LabelFor(model => model.VisitorTitle, htmlAttributes: new { @class = "control-label col-md-2" }) 
     <div class="col-md-10"> 
      @Html.EditorFor(model => model.VisitorTitle, new { htmlAttributes = new { @class = "form-control" } }) 
      @Html.ValidationMessageFor(model => model.VisitorTitle, "", new { @class = "text-danger" }) 
     </div> 
    </div> 
    .... // other elements for VisitorFirstName, VisitorSurname etc 
    <div class="form-group"> 
     <div class="col-md-offset-2 col-md-10"> 
      <input type="submit" value="Create" class="btn btn-default" /> 
     </div> 
    </div> 
</form> 

需要注意的是,你需要從部分按鈕刪除id="visitorform"

您還需要部分從主視圖的<form>標籤移動,並將其移動到結束(嵌套形式是無效的HTML,而不是支持。

@model VisitorManager.Models.AppointmentViewModel 
.... 
@using (Html.BeginForm()) 
{ 
.... // elements associated with AppointmentViewModel only 
} 
// Move the partial/modal here 
<div id="VisitorModal"></div> 

你也應該將劇本中的偏主視圖(腳本應該永遠只能是在主視圖或佈局)的腳本還需要使用事件代表團(.on()),因爲形式是動態添加

$('#VisitorModal').on('submit', '#visitorform', function() { 
    var data = $(this).serialize(); 
    .... 

旁註:你有多餘ViewBag.HostID = new SelectList(..)上一個問題應該從控制器方法中刪除。

+0

我已經通過你的建議(我想我得到了他們所有),雖然在部分視圖中的表單發佈,它不使用jQuery Ajax帖子,但將值附加到QueryString。 http:// localhost:53533/Appointment/create?VisitorTitle = 1&VisitorFirstName = 2&VisitorSurname = 3&VisitorCompany = 4 你能想到爲什麼jQuery事件觸發的原因嗎?上面的代碼編輯會有幫助嗎? –

+0

這意味着部分中的'

'標籤正在製作正常的GET帖子,而您沒有點擊腳本。你是否已經將腳本移到了主視圖中(它不會在局部工作,因爲它包含在'@section Scripts {'中,並且在部分中不支持) –

+0

另外,因爲您動態添加第二個表單,腳本將需要('#提交','#visitorform',函數(){'(不是'$('#visitorform')。submit(function(){' - 即使用事件委託(請參閱更新) –

相關問題