Add items in listbox in view when button is clicke

2019-07-21 07:32发布

问题:

I have this model

public class CreateAppointmentSelectPersons
{

    [DataType(DataType.EmailAddress, ErrorMessageResourceType = typeof (Resource), ErrorMessageResourceName = "CreateAppointment_Email_Invalid_Email_Address")]
    [EmailAddress]
    [Display(ResourceType = typeof(Resource), Name = "RegisterViewModel_EmailId_Email_Id")]
    public string Email { get; set; }

    public Boolean IsSuperOfficeConnected { get; set; }

    [Display(ResourceType = typeof (Resource), Name = "CreateAppointmentSelectPersons_SelectedSuperOfficeEmail_SuperOffice_Contact")]
    public string SelectedSuperOfficeEmail { get; set; }



    public Boolean IsInternalAddressBookEmpty { get; set; }
    [Display(ResourceType = typeof(Resource), Name = "CreateAppointmentSelectPersons_InternalAddressBookPersons_AddressBook_Contact")]
    public string SelectedAddressBookPerson { get; set; }


    [Display(ResourceType = typeof (Resource), Name = "CreateAppointmentSelectPersons_AttendeesListBox_Invited_Persons")]
    [Required]
    public List<string> AttendeesListBox { get;set; }
}

Also, i'm new to listbox in view. The idea is users will have upto three box, and when they type in a email address and click button next to it, I want to to add it to Listbox in view, I want to retrieve the values from listbox only upon posting of the form.

This is what I have in view currently,

@using System.Web.Mvc.Html
@model DatePicker.Models.ViewModels.Appointment.CreateAppointmentSelectPersons
@{
    ViewBag.Title = "Create";
    Layout = "~/Views/Shared/_Layout.cshtml";
    <link href="~/Content/themes/base/minified/jquery-ui.min.css" rel="stylesheet"/>
}

<h2>Create</h2>
@using(Html.BeginForm("Create","Appointment", new { @class = "form-horizontal", role = "form" }))
{
     @Html.AntiForgeryToken()
    <hr />
    @Html.ValidationSummary()
    <div class="form-group">

        @Html.LabelFor(m => m.Email, new { @class = "col-md-8 control-label" })
        <div class="col-md-8">
            @Html.TextBoxFor(m => m.Email, new { @class = "form-control" }) <input type='button' id="btnEmail" class="btn-default form-inline" value="Add>>" />
        </div>

        @if (Model.IsSuperOfficeConnected)
        {
        @Html.LabelFor(m=>m.SelectedSuperOfficeEmail, new {@class="col-md-8 control-label"})
        <div class="col-md-8">

            @Html.TextBoxFor(m=>m.SelectedSuperOfficeEmail,new{@class="form-control",PlaceHolder="Search in SuperOffice..."}) <input type='button' id="btnSuperOffice" class="btn-default" value="Add>>">
        </div>

        }
        @if (Model.IsInternalAddressBookEmpty)
        {
        @Html.LabelFor(m => m.SelectedAddressBookPerson, new { @class = "col-md-8 control-label" })
        <div class="col-md-8">
            @Html.TextBoxFor(m=>m.SelectedAddressBookPerson,new{@class="form-control",PlaceHolder="Search in AddressBook..."}) <input type='button' id ="btnAddressBook" class="btn-default" value="Add>>">
        </div>
        }
        @Html.ListBoxFor(m => m.AttendeesListBox, new SelectList(Model.AttendeesListBox), new { style = "width:100%;" })
    </div>
}

@section Scripts{
    @Scripts.Render("~/Scripts/jquery-ui-1.10.4.min.js")

    <script type="text/javascript">
        $(function() {
            $("#SelectedSuperOfficeEmail").
                autocomplete({
                    source: '/Appointment/SuperOfficePerson',
                    minLength: 1,  
                    });   
        });
        $(function() {
            $("#SelectedAddressBookPerson").autocomplete({
                source: '/Appointment/AddressBookPerson',
                minLength: 1,
            });
        });
        $(function() {
            $('#btnEmail').click(function(e) {
                var name = $('#Email').val();
                $('#AttendeesListBox').append($("<option></option>").attr("value"), name).text(name);
            });
        });
        $(function () {
            $('#btnSuperOffice').click(function (e) {
                var name = $('#SelectedSuperOfficeEmail').val();
                $('#AttendeesListBox').append($("<option></option>").attr("value"), name).text(name);
            });
        });
        $(function () {
            $('#btnEmail').click(function (e) {
                var name = $('#SelectedAddressBookPerson').val();
                $('#AttendeesListBox').append($("<option></option>").attr("value"), name).text(name);
            });
        });
    </script>
}

Right now I'm getting a complain that says "Cannot resolve ListBoxFor(lambda expression)".

What should I do, to make my view work so that upon button click the value gets added to list box and upon submission i get only the values of listbox

回答1:

Here goes the solution -

Let your model be -

public class ListBoxModel
{
    public List<string> Names { get; set; }
    public List<string> SelectedNames { get; set; }
}

Let your controller actions be -

public class ListBoxController : Controller
{
    public ActionResult Index()
    {
        ListBoxModel model = new ListBoxModel();
        model.Names = new List<string>();
        model.Names.Add("Rami");
        return View(model);
    }

    public ActionResult Submit(ListBoxModel model)
    {
        return null;
    }
}

Index controller is simply going to create the List of items and send it to Index View. Index view is going to be -

@model MVC.Controllers.ListBoxModel

@{
    ViewBag.Title = "Index";
}

<h2>View1</h2>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
    $(function () {
        $('#click1').click(function (e) {

            var name = $("#txt1").val();

            $('#SelectedNames').
                append($("<option></option>").
                attr("value", name).
                text(name));
        });
    });
</script>

@using (Html.BeginForm("Submit", "ListBox", FormMethod.Post))
{
    @Html.ListBoxFor(m => m.SelectedNames, new SelectList(Model.Names))

    <input type="text" id="txt1" />
    <input type="button" value="Click" id="click1" />

    <input type="submit" value="submit"/>
}

In the Index view, when you enter a name in textbox and click on button 'Click', it will be added to Listbox on clientside -

And when you select items in the ListBox and Click on Submit button, form will be submitted with selected values to the Submit Action of Listbox Controller.

UPDATE

As per question update, To send all the ListBox Items to server, we add hidden fields in the form dynamically using JQuery.

View -

@model MVC.Controllers.ListBoxModel

@{
    ViewBag.Title = "Index";
}

<h2>View1</h2>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>

    $(function () {
        $('#click1').click(function (e) {

            var name = $("#txt1").val();
            $('#SelectedNames').
                append($("<option></option>").
                attr("value", name).
                text(name));

            $('#hiddensq').append("<input name='UserValues' type='hidden' value='"+ name +"'/>");
        });
    });
</script>

@using (Html.BeginForm("Submit", "ListBox", FormMethod.Post))
{
    <div id="hiddensq">
    </div>

    for (int i = 0; i < Model.Names.Count; i++)
    {
        @Html.Hidden("UserValues", Model.Names[i]);
    }

    @Html.ListBoxFor(m => m.SelectedNames, new SelectList(Model.Names))

    <input type="text" id="txt1" />
    <input type="button" value="Click" id="click1" />

    <input type="submit" value="submit" />
}

And in the controller -

    public ActionResult Submit(ListBoxModel model, IEnumerable<string> UserValues)
    {
        var c = Request.Form;

        return null;
    }

Output - All the selected values will be coming in the ListBoxModel, but all the listbox items will be coming in UserValues parameter.