使用jQuery和部分视图在MVC中添加一个新的DropDownList项 [英] Using jQuery and Partial Views to Add A New DropDownList Item in MVC

查看:107
本文介绍了使用jQuery和部分视图在MVC中添加一个新的DropDownList项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个调度MVC应用程序。在ViewModel中,我结合了来自CodeFirst EF字段的字段,以包括会议主持人,访问者和时间等。我想要能够从此表单创建新的访问者,如果它们不存在,并通过Ajax发回到更新可用访问者列表。



ViewModel:

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

}

控制器:

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

// GET:预约
public ActionResult Create()
{
ViewBag.HostID = new SelectList(db.Hosts.OrderBy(x => x。名称),id,名称);
//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 =创建;
}

< h2>创建< / h2>

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

< div class =form-horizo​​ntal >
< 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, - 请选择 - ,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, - 请选择 - ,htmlAttributes:new {@class =form-control})
@ Html.ValidationMessageFor (model => model.VisitorID,,new {@class =text-danger})
< / div>
< button type =buttonid =addVisitor>添加新的访问者< / 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 ,,新的{@class =text-danger})
< / div>
< / div>

< div class =form-group>
< div class =col-md-offset-2 col-md-10>
< input type =submitvalue =Saveclass =btn btn-default/>
< / div>
< / div>

< / div>
}

< div>
@ Html.ActionLink(返回列表,索引)
< / div>


@section脚本{
@ 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 ,,新的{@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 ,,新的{@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 ,,新的{@class =text-danger})
< / div>
< / div>

< div class =form-group>
< div class =col-md-offset-2 col-md-10>
< input type =submitvalue =Createclass =btn btn-defaultid =visitorform/>
< / div>
< / div>

@section脚本{
< script type =text / javascript>
$('#visitorform')。submit(function(){
var data = $(this).serialize();
var url ='@ Url.Action(CreateVisitor ,Appointment)';
var text = $('#surname')。val(); //从表单中选择一个值作为选项文本
$ .post(url,数据,函数(响应){
if(response){
$('#HostID')。append($('< option>< / option>文本(文本))val(响应);
} else {
// Oops
}
})。fail(function(){
// Oops
});
// ...关闭模态
return false; //取消默认提交
});
< / script>}

我知道应该改进样式,访客表单应该以模态显示,但是一旦我有逻辑工作,我希望修复。



点击添加新访问者将显示部分视图,包括按钮将新访问者提交回控制器。点击部分视图中的创建按钮关闭视图,但表单数据不会被提交回控制器。



有关为什么事件不是 t

一旦新的访客被添加到DropDownList,我认为需要填写表格的其余部分并提交约会。

解决方案

您没有第二个表单与 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 ,,新的{@class =text-danger})
< / div>
< / div>
.... // VisitorFirstName,VisitorSurname等的其他元素
< div class =form-group>
< div class =col-md-offset-2 col-md-10>
< input type =submitvalue =Createclass =btn btn-default/>
< / div>
< / div>
< / form>

请注意,您需要删除 id =visitorform从部分的按钮。



您还需要从主视图的< form> 标签并将其移动到最后(嵌套表单是无效的html并且不支持。

  @model VisitorManager.Models。 App _ b //在这里移动部分/模式
< div id =VisitorModal>< / div>

您还应该将部分的脚本移动到主视图(脚本应该只在主视图或布局中)脚本还需要使用事件委托( .on ()),因为表单正在动态添加

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

旁注:你有一个多余的 ViewBag.HostID = new SelectList(..)从上一个问题遗留下来,应该从控制器方法中删除。


I am attempting to create a scheduling MVC app. In a ViewModel I combine the fields (from CodeFirst EF fields) to include the meeting hosts, visitors and times, etc. I want to be able to create a new visitor from this form if they don't already exist and postback via Ajax to update the list of available visitors.

ViewModel:

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

}

Controller:

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

View:

@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>

Partial View:

@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>}

I know that the styling should be improved and the new visitor form should be displayed modally, but that I hope to fix once I've got the logic working.

Clicking "Add New Visitor" displays the partial view, including the button to submit the new visitor back to the controller. Clicking the "Create" button in the partial view closes the view but the form data isn't submitted back to the controller.

Any thoughts as to why the event isn't firing?

Once the new visitor is added to the DropDownList I think need to complete the remainder of the form and submit the appointment.

解决方案

You do not have a second form with id="visitorform". The elements in you partial need to be wrapped in <form> tags

@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>

Note that you need to remove id="visitorform" from the button in the partial.

You also need to move the partial from the main view's <form> tags and move it to the end (nested forms are invalid html and not supported.

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

you should also move the script in the partial to the main view (scripts should only ever be in the main view or layout) The script also need to use event delegation (.on()) because the form is being dynamically added

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

Side note: you have a superfluous ViewBag.HostID = new SelectList(..) left over from a previous question which should be removed from the controller method.

这篇关于使用jQuery和部分视图在MVC中添加一个新的DropDownList项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆