Razvan
Razvan

Reputation: 181

How to use select2 with multiple options using Razor and MVC

I am trying to create a multiple choice list using Select2, Razor and the MVC framework. My problem is that the object in the controller that receives the array input is always null. The front-end looks as follows:

<form class="form-horizontal" method="post" action="@Url.Action(MVC.Configurazione.Contatori.Edit())">
    <div class="form-group">
        <div class="col-lg-8">
            <select class="form-control attributoSelect2" name="attributiSelezionati" value="@Model.AttributiSelezionati">
                <option value="@Model.AttributiSelezionati" selected>@Model.AttributoDescrizione</option>
            </select>
        </div>
    </div>
</form>

The action method "Edit", is the controller method that receives the array of chosen items from the drop-down list.

The Javascript is the following:

    $('.attributoSelect2').select2({
        placeholder: "Search attribute",
        multiple: true,
        allowClear: true,
        minimumInputLength: 0,
        ajax: {
            dataType: 'json',
            delay: 150,
            url: "@Url.Action(MVC.Configurazione.Attributi.SearchAttrubutes())",
            data: function (params) {
                return {
                    search: params.term
                };
            },
            processResults: function (data) {
                return {
                    results: data.map(function (item) {
                        return {
                            id: item.Id,
                            text: item.Description
                        };
                    })
                };
            }
        }
    });

And finally the C# controller has an object that is expected to retrieve the data from the view and is defined:

public string[] AttributiSelezionati { get; set; }

and the HttpPost method that receives the data is:

[HttpPost]
public virtual ActionResult Edit(EditViewModel model) { }

Could someone give me some insight into what I am doing wrong and the areas that I should change in order to find the problem?

Upvotes: 2

Views: 9271

Answers (3)

Murat Yıldız
Murat Yıldız

Reputation: 12050

You can try the following approach that has been used in some of our projects without any problem:

View:

@Html.DropDownListFor(m => m.StudentId, Enumerable.Empty<SelectListItem>(), "Select")

$(document).ready(function () {

    var student = $("#StudentId");

    //for Select2 Options: https://select2.github.io/options.html
    student.select2({
        language: "tr",//don't forget to add language script (select2/js/i18n/tr.js)
        minimumInputLength: 0, //for listing all records > set 0
        maximumInputLength: 20, //only allow terms up to 20 characters long         
        multiple: false,
        placeholder: "Select",
        allowClear: true,
        tags: false, //prevent free text entry
        width: "100%",

        ajax: {
            url: '/Grade/StudentLookup',
            dataType: 'json',
            delay: 250,
            data: function (params) {
                return {
                    query: params.term, //search term
                    page: params.page
                };
            },
            processResults: function (data, page) {
                var newData = [];
                $.each(data, function (index, item) {
                    newData.push({
                            //id part present in data 
                            id: item.Id,     
                            //string to be displayed
                            text: item.Name + " " + item.Surname
                    });
                });
                return { results: newData };
            },
            cache: true
        },
        escapeMarkup: function (markup) { return markup; }
    });


    //You can simply listen to the select2:select event to get the selected item
    student.on('select2:select', onSelect)

    function onSelect(evt) {
        console.log($(this).val());
    }

        //Event example for close event
        student.on('select2:close', onClose)

        function onClose(evt) {
            console.log('Closed…');
        } 
});


Controller:

public ActionResult StudentLookup(string query)
{
    var students = repository.Students.Select(m => new StudentViewModel
    {
        Id = m.Id,
        Name = m.Name,
        Surname = m.Surname
    })
    //if "query" is null, get all records
    .Where(m => string.IsNullOrEmpty(query) || m.Name.StartsWith(query)) 
    .OrderBy(m => m.Name);
    return Json(students, JsonRequestBehavior.AllowGet);
}

Hope this helps...

Update:

Dropdown option groups:

<select>
  <optgroup label="Group Name">
    <option>Nested option</option>
  </optgroup>
</select>

For more information have a look at https://select2.org/options.

Upvotes: 0

Mashhad Saleem
Mashhad Saleem

Reputation: 177

There are multiple reason for not being receiving data on server. First of all you need to change your select code as follow

@Html.DropDownList("attributiSelezionati", Model.AttributiSelezionati, new { @class = "form-control attributo select2" })

now go to console in browser and get the data of element to confirm that your code properly works in HTML & JS

After that you need to add attribute at your controller's action method as

[OverrideAuthorization]
[HttpPost]

Upvotes: 0

Mars.Tsai
Mars.Tsai

Reputation: 184

you class name error not attributoSelect2 is attributesSelect2 , I also make this mistake often. haha

 <select class="form-control attributoSelect2" name="attributiSelezionati" value="@Model.AttributiSelezionati">
                <option value="@Model.AttributiSelezionati" selected>@Model.AttributoDescrizione</option>
            </select>

Upvotes: 0

Related Questions