0

I want to do client side validation of listbox. We can't move all items from one listbox to another. There should be at least one item in the listbox.

Listbox should not be blank completely as there should be at least one item in it.

Can you please guide me how to do it. Appreciated for your help.

Class

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

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;

}

Index.cshtml

@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>
}
  • you means you want both dropdown (left and right) to be validate? – Ajay2707 May 04 '19 at 02:48
  • also what will render at client side, give that html – Ajay2707 May 04 '19 at 02:49
  • @Ajay2707, Yes Ajay. I want to do in both side. But initially there will be nothing in right side. But when we start moving items then the validation should start. –  May 04 '19 at 02:50
  • @Ajay2707, it should be something like you can't move the last item from the listbox. –  May 04 '19 at 02:52
  • understood that you have to move left to right value, now where is the object/control to move. you mention submit button, it means you move all left to right or selected move. – Ajay2707 May 04 '19 at 02:54
  • i.e. which control you want to add javascript – Ajay2707 May 04 '19 at 02:55
  • @Ajay2707, Please have a look in controller section code. –  May 04 '19 at 02:56
  • just check that id is generated with this code where you apply the class: "@class = "listBox", id= "cmb_left" " – Ajay2707 May 04 '19 at 03:02
  • @Ajay2707, Sorry Ajay. I did not understand. You want me to check something in the code level. –  May 04 '19 at 03:08
  • @Ajay2707, If possible from your end then please invite me to chat. –  May 04 '19 at 03:10
  • yes, add in the code and check in browser that id is render. – Ajay2707 May 04 '19 at 03:11
  • @Ajay2707, it shows something like this. `` –  May 04 '19 at 03:18

2 Answers2

1

You can write a script for validation. Check if length of select == length of selected you can prevent to remove.

$('#moveLeft').click(function () {
        var leftselected = $('#leftSelectednumbers').val();

        var length = $('#leftSelectednumbers option').length;
        //alert(length)
        var selected = $('#leftSelectednumbers :selected').length;
        if (length === selected) {
            alert('Can not move all item to right...');
        } else {
            $.each(leftselected, function (key, value) {
                $('#rightSelectednumbers').append($("<option></option>").attr("value", value).text(value));
            });

            $('#leftSelectednumbers :selected').remove();

        }

    })

cshtml file

@model TestMVC.Controllers.NumberClass
@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="button" id="moveLeft" value="move left" />
    </div>

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

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

}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
    $('#moveLeft').click(function () {
        var leftselected = $('#leftSelectednumbers').val();

        var length = $('#leftSelectednumbers option').length;
        //alert(length)
        var selected = $('#leftSelectednumbers :selected').length;
        if (length === selected) {
            alert('Can not move all item to right...');
        } else {
            $.each(leftselected, function (key, value) {
                $('#rightSelectednumbers').append($("<option></option>").attr("value", value).text(value));
            });

            $('#leftSelectednumbers :selected').remove();

        }

    })

</script>

Update script for sort after moved

@model TestMVC.Controllers.NumberClass
@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="button" id="moveLeft" value="move left" />
    </div>

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

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

}

<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
    $('#moveLeft').click(function () {
        var leftselected = $('#leftSelectednumbers').val();

        var length = $('#leftSelectednumbers option').length;
        //alert(length)
        var selected = $('#leftSelectednumbers :selected').length;
        if (length === selected) {
            alert('Can not move all item to right...');
        } else {
            var currentrightvalue = [];
            $('#rightSelectednumbers option').each(function (item, option) {
                debugger
                currentrightvalue.push(option.value);
            });

            leftselected = leftselected.concat(currentrightvalue);
            leftselected.sort(function(a,b) { return a - b; });
            $('#rightSelectednumbers option').remove();
            $.each(leftselected, function (key, value) {
                $('#rightSelectednumbers').append($("<option></option>").attr("value", value).text(value));
            });

            $('#leftSelectednumbers :selected').remove();


        }

    })

</script>
Hien Nguyen
  • 24,551
  • 7
  • 52
  • 62
  • Your code works but it does not sort when appended into another list box. Can you please have a look. Previously, my back end code was sorting if moved items from one to another and vice-versa.I just want to validate the items. –  May 04 '19 at 03:55
0

Just add id in your combo-box and add javascript to validate

@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",   id="cmb_right"})
        <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", id="cmb_left" })
        <br />
        <input type="submit" value="move left"  />
    </div>
}

window.onload = function() {
    var form = document.querySelector("form");
    form.onsubmit = submitted.bind(form);
}

function submitted(event) {
   if( document.getElementById("cmb_left").options.length == 0){
    alert("Please move element");
    event.preventDefault();
   }
   if( document.getElementById("cmb_right").options.length == 0){
    alert("Please add element");
    event.preventDefault();
   }
}

You can check further in this link - How can I listen to the form submit event in javascript?

Ajay2707
  • 5,690
  • 6
  • 40
  • 58
  • Does not work even I select some items from left listbox, it throws message `Please move element` –  May 04 '19 at 03:59
  • you can modify this logic based on your requirement, the alert shows that its fired javascript function. I am added that both dropdown have some value while submitting a form and if not then alert message and stop the form submit. – Ajay2707 May 04 '19 at 04:20
  • can you explain your logic, because you are submitting the form via submit button, ideally at that time validation fire and second option while move items from on left to right. – Ajay2707 May 04 '19 at 04:24