2

I've got a collection of emails stored in a view model that I'm binding to a ListBox in a view.

@Html.TextBox("txtAddEmail") <img id="btnAddEmail">Add Email</img>
@Html.ListBox("Emails", Model.Emails)
@Html.ValidationMessageFor(m => m.Emails)

I'd like to have the user be able to add emails by entering them into the txtAddEmail text box and click the add image button which would then add the email to the listbox on the client. Then when the form is posted have news emails show up in the emails collection. I've got the client code working that adds the item, but on post the emails collection doesn't contain the new emails.

var emailToAdd = $("#txtAddEmail").val();

 $('#Emails').
     append($("<option></option>").
     attr("value", emailToAdd).
     text(emailToAdd)); 

Any ideas on how to do this?

UPDATE

I was able to add one item to a value in the ViewModel using this

 @Html.ListBox("EmailAdded", Model.Emails)

The email added on the client shows up in the EmailAdded string value, but how do I have it add to a collection? I decided to try binding directly to the list of emails. After adding to the listbox on the client the view model doesn't show the added email. Any ideas?

 @Html.ListBoxFor(model => model.Emails, new MultiSelectList(Model.Emails, "Id",    "Address"));
 @Html.ValidationMessageFor(m => m.Emails)

UPDATE

Found the answer I was looking for here

1
  • How about creating a hidden text-box and while you add an email to list-box it would also be added to the hidden text-box then keep them deliminator by coma such as email1,email2,email4,.... and the the collection would get all the email addresses in the hidden text-field and you can split the email string for every single email. Collection ussually gets the value of a selected field from list Commented Nov 9, 2011 at 1:41

2 Answers 2

2

I'm pretty sure that for the items in the listbox to show up in the form collection on the post, they need to be selected. So to work around this I usually have a jQuery function to select the items whenever the form is submitted.

Have your submit button like this:

<input type="submit" onclick="SelectEmails();" />

And a function like this:

function SelectEmails()
{
    $("#Emails option").attr("selected", "selected");
}
Sign up to request clarification or add additional context in comments.

Comments

1

Try changing your jQuery element to:

append($("<option selected='selected'></option>")

Make sure you also have:

<select multiple="multiple">

3 Comments

That worked as far as adding one value to a viewmodel property, but is there a way to add items to the collection?
Because it is a multiselect, you should get an array of email addresses posted back and they should automatically get reassigned to Model.Emails. If that is not happening, can you check the Request variables and the ValuesProvider collection to make sure they are being submitted (or use Firebug to see the submitted form variables). I think what you are seeing is problem with rebinding, because MVC always binds on POST to its ModelState, not your Model. So you can change your model in the postback but it won't affect what is bound. Try it with an ordinary string value and see...
So what you need to do is bind the selected values to one property, eg, SelectedEmails, but populate the dropdown from the full list, AllEmails. Every time the user adds an email, you have to manually add it to the AllEmails list. Hope that makes sense. Imagine that you had a single property called Email, whose ListBox was populated with an Emails collection. Html.ListBoxFor(m => m.Email, Model.AllEmails). You need to achieve the same but using a multiselect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.