Click here to Skip to main content
15,891,943 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I want to send selected listbox values to another listbox. I want to implement this using C# code in controller section but not with JavaScript code.

I got stuck here. I am generating integer values and want to select these values to send to another list box and vice-versa.


What I have tried:

public class NumberClass
  {
    public IEnumerable<SelectListItem> leftnumbers { get; set; }
    public IEnumerable<int> leftSelectednumbers { get; set; }

    public IEnumerable<SelectListItem> rightnumbers { get; set; }
    public IEnumerable<int> rightSelectednumbers { get; set; }
  }


[HttpGet]
      public ActionResult Index()
      {
        List<SelectListItem> items = new List<SelectListItem>();

        for (int i = 1; i <= 20; i++)
        {
            SelectListItem selectList = new SelectListItem()
            {
                Text = i.ToString(),
                Value = i.ToString()

            };

            items.Add(selectList);

        }

        NumberClass num = new NumberClass()
        {
            leftnumbers = items,
            rightnumbers = null

        };
        return View(num);

    }


    [HttpPost]
    public string Index(IEnumerable<int> selectedvalue)
    {
        if (selectedvalue == null)
        {
            return "you have not selected";
        }
        else
        {
            //
            return;
        }

    }


@using (Html.BeginForm())
{
  <div class="col-md-6" style="font-family:Arial">
    @Html.ListBoxFor(m => m.leftSelectednumbers, Model.leftnumbers, new { size = 20, @class = "listBox" })
    <br />
    <input type="submit" value="move left" />
</div>

<div class="col-md-6" style="font-family:Arial">

    @Html.ListBoxFor(m => m.leftSelectednumbers, new List<SelectListItem>(), new { size = 20, @class = "listBox" })
    <br />
    <input type="submit" value="move right" />
</div>

}
Posted
Updated 29-Apr-19 1:34am
Comments
Christian Graus 28-Apr-19 23:58pm    
Using the back end for UI elements to communicate is a TERRIBLE idea. You'd basically have to send the selected options from box one to the back end, which simply returns them, and then send them back down to put in the other box. If you want the back end to know what items are in the listbox, send the information, but after you populate the UI in javascript

The issue with select \ list boxes is that when the form is submitted only the selected items are submitted with the form, so if you have 20 items in the select box, select 3 of them and submit the form then your controller code has no idea how many items were in your list box originally, only that the user has selected three of them.

So you need to track the non-selected items yourself. There are loads of different ways of doing this, but in the sample code below I simply store them in a hidden field as a comma separated list.

The updated model

public class NumberClass
{
    public string currentLeftNumbers { get; set; }
    public IEnumerable<SelectListItem> leftnumbers { get; set; }
    public IEnumerable<int> leftSelectednumbers { get; set; }

    public string currentRightNumbers { get; set; }
    public IEnumerable<SelectListItem> rightnumbers { get; set; }
    public IEnumerable<int> rightSelectednumbers { get; set; }
}


View

@using (Html.BeginForm())
{
    <input type="hidden" name="CurrentLeftNumbers" value="@Model.currentLeftNumbers"/>

    <div class="col-md-6" style="font-family:Arial">
        @Html.ListBoxFor(m => m.leftSelectednumbers, Model.leftnumbers, new { size = 20, @class = "listBox" })
        <br />
        <input type="submit" value="move right" />
    </div>

    <input type="hidden" name="CurrentRightNumbers" value="@Model.currentRightNumbers" />

    <div class="col-md-6" style="font-family:Arial">

        @Html.ListBoxFor(m => m.rightSelectednumbers, Model.rightnumbers, new { size = 20, @class = "listBox" })
        <br />
        <input type="submit" value="move left" />
    </div>
}


Controller

[HttpGet]
public ActionResult Index()
{
    List<int> items = new List<int>();

    for (int i = 1; i <= 20; i++)
    {
        items.Add(i);
    }

    NumberClass num = GetModel(items, new List<int>());

    return View(num);
}

[HttpPost]
public ActionResult Index(NumberClass model)
{
    List<int> left = GetNumbers(model.currentLeftNumbers);
    List<int> right = GetNumbers(model.currentRightNumbers);

    if (model.leftSelectednumbers != null)
    {
        foreach (var i in model.leftSelectednumbers)
        {
            left.Remove(i);
            right.Add(i);
        }
    }

    if (model.rightSelectednumbers != null)
    {
        foreach (var i in model.rightSelectednumbers)
        {
            right.Remove(i);
            left.Add(i);
        }
    }

    return View(GetModel(left, right));
}

private List<int> GetNumbers(string numbers)
{
    if (string.IsNullOrWhiteSpace(numbers))
    {
        return new List<int>();
    }
    else
    {
        return numbers.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(n => int.Parse(n)).ToList();
    }
}

private NumberClass GetModel(IEnumerable<int> left, IEnumerable<int> right)
{
    NumberClass model = new NumberClass();

    if (left.Any())
    {
        model.currentLeftNumbers = left.Select(n => n.ToString()).Aggregate((x, y) => x + "," + y);
        model.leftnumbers = left.OrderBy(x => x).Select(n => new SelectListItem { Value = n.ToString(), Text = n.ToString() });
    }
    else
    {
        model.leftnumbers = new List<SelectListItem>();
    }
            
    if (right.Any())
    {
        model.currentRightNumbers = right.Select(n => n.ToString()).Aggregate((x, y) => x + "," + y);
        model.rightnumbers = right.OrderBy(x => x).Select(n => new SelectListItem { Value = n.ToString(), Text = n.ToString() });
    }
    else
    {
        model.rightnumbers= new List<SelectListItem>();
    }

    return model;
}


You'll probably need to step through the code to see how it is working.
 
Share this answer
 
Comments
Rajeshyadav12 3-May-19 22:10pm    
Thank you for your answer. One more thing I would like to ask. I want to do client side validation as well. We can't move all items from one listbox to another. There should be at least one item in the listbox. Can you please guide me how to do it as well. Appreciated for your help.
Using the back end for UI elements to communicate is a TERRIBLE idea. You'd basically have to send the selected options from box one to the back end, which simply returns them, and then send them back down to put in the other box. If you want the back end to know what items are in the listbox, send the information, but after you populate the UI in javascript
 
Share this answer
 
Comments
Rajeshyadav12 29-Apr-19 1:23am    
Thank you for your comment. Can you please elaborate more to understand better.
Christian Graus 29-Apr-19 1:26am    
No, I don't see how to explain it better than that. The movement of data from one UI element to another does not require the back end. You inevitably need to write front end code to remove items (if it's a cut and paste) and put them in the new place
Rajeshyadav12 29-Apr-19 1:36am    
Thank you for guiding me. I will try to write some JavaScript code to do so.
Christian Graus 29-Apr-19 1:39am    
Great - you pretty much have to

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900