Posting Form with Empty MultiSelect

7 posts, 0 answers
  1. Tyler
    Tyler avatar
    46 posts
    Member since:
    Nov 2013

    Posted 26 Apr Link to this post

    Hi,

    I have a form with a MultiSelect displaying 'Exercises'. When the form is submitted the Exercise data is passed to the model as part of the form data (e.g.Exercises:"f86a60ce-04dc-4208-a2b6-a5ee00a1990f")

    However when nothing is selected in the list, the 'Exercises' parameter is excluded from the post data. As the Exercise data is not included, the model.Entity.Exercises remains unchanged and contains the original selected values.

    Is there any way the Kendo MultiSelect can pass in a null value when posting an empty list, so that the form data includes the Exercise parameter? e.g. Exercises:Null 

     

    @{if (edit)
    {
      @(Html.Kendo().MultiSelect()
      .Name("Exercises")
      .Placeholder("  ")
      .BindTo(ViewBag.Exercises)
      .HtmlAttributes(new { @class = "universalWidth" }))
    }

    [HttpPost]
    [ActionName("CourseEdit")]
    public ActionResult CourseEditPost(TypedModel<Course> model, string mode)
    {
      if (mode != "view")
      {
        if (UserController.EffectiveUser.GetClassAccess(typeof(Course)).Allows(Access.Update))
        {
          // Save Mode
          if (mode == "new")
          {
     
          }
          else if (mode == "edit")
          {           
            CourseService service = new CourseService(this.DbSession, new ModelStateWrapper(this.ModelState));
            if (service.Save(model)) //model.Entity.Exercises error when no exercises selected in list
            {
              //Sucessfully saved
              DbSession.Flush();
            }
          }
        }
      }
     
      CourseEditHelper(model);
      return View(model);
    }

         

  2. Nencho
    Admin
    Nencho avatar
    1457 posts

    Posted 28 Apr Link to this post

    Hello Tyler,

    I am afraid that I was unable to locally replicate the described issue. This is why, I would like to ask you to send us a runnable sample, so we could investigate and test the exact implementation that you have at your end and pin down the reason for the experienced issue.

    Regards,
    Nencho
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. UI for ASP.NET MVC is VS 2017 Ready
  4. Tyler
    Tyler avatar
    46 posts
    Member since:
    Nov 2013

    Posted 29 Apr in reply to Nencho Link to this post

    Hi,

    Having problems reducing demo zip to 2Mb. Here is a code sample that works...

    View 

    @{
        ViewBag.Title = "Home Page";
    }
    @model TelerikMvcApp1.Models.SimpleModel
     
    @using (Html.BeginForm("Save", "Home", FormMethod.Post ))
    {
      @(Html.LabelFor(model => model.Notes))
      @(Html.TextBoxFor(model => model.Notes))
       
      @(Html.LabelFor(model => model.Exercises))
      @(Html.Kendo().MultiSelect()
                        .Name("Exercises")
                        .Placeholder(" ")
                        .ValuePrimitive(true)
                        .BindTo(ViewBag.VbExercises)                  
                        .HtmlAttributes(new { @class = "universalWidth" })) 
     
      <div>
        <input type="submit" value="Save" class="k-button" />
      </div>
    }

    Controller

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using TelerikMvcApp1.Entity;
    using TelerikMvcApp1.Models;
     
    namespace TelerikMvcApp1.Controllers
    {
        public class HomeController : Controller
        {
          public ActionResult Index()
            {
                ViewBag.Message = "Welcome to ASP.NET MVC!";
                ViewBag.VbExercises = MultiExercise();
                return View();
            }
     
            [HttpPost]
            public ActionResult Save(FormCollection form)
            {
              //
              if (form != null)
              {
                string selectedValues = form["Exercises"];
                return Content("Selected Ids:" + selectedValues);
              }
     
              return new EmptyResult();
            }
     
            private static MultiSelectList MultiExercise()
            {
              IList<Exercise> list = new List<Exercise>();
              Exercise ex1 = new Exercise("Exercise 1", new Guid("180f12af-2155-4c1a-a915-32e13b7f6243"));
              Exercise ex2 = new Exercise("Exercise 2", new Guid("fc7989cd-7b10-47b5-b474-72083f2673c4"));
              Exercise ex3 = new Exercise("Exercise 3", new Guid("4334a7f1-8066-4c61-ad18-89f2c0933cdf"));
              list.Add(ex1);
              list.Add(ex2);
              list.Add(ex3);
     
              MultiSelectList result = new MultiSelectList(list, "Oid", "Title", list.Select(s => new Guid("180f12af-2155-4c1a-a915-32e13b7f6243").ToString()).ToList());
     
              return result;
            }
     
        }
    }

    Model

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using TelerikMvcApp1.Entity;
     
    namespace TelerikMvcApp1.Models
    {
      public class SimpleModel
      {
        private IList<Exercise> exercises;
     
        public virtual string Notes { get; set; }
     
        /// <summary>
        /// Exercise
        /// </summary>
        public virtual IList<Exercise> Exercises
        {
          get
          {
            return exercises;
          }
          set
          {
            exercises = value;
          }
        }
      }
    }

    Entity

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
     
    namespace TelerikMvcApp1.Entity
    {
      public class Exercise
      {
        /// <summary>
        /// Title
        /// </summary>
        public virtual string Title { get; set; }
     
        /// <summary>
        /// Oid
        /// </summary>
        public virtual Guid Oid { get; set; }
     
        public Exercise(string title, Guid oid)
        {
          this.Title = title;
          this.Oid = oid;
        }
      }
    }

     

     

  5. Tyler
    Tyler avatar
    46 posts
    Member since:
    Nov 2013

    Posted 29 Apr in reply to Tyler Link to this post

    The above sample application showing what happens when no items are selected. You will see that "Exercises" do not exist in the FormCollection when the multi-select is empty. 

    Ideally the Html.Kendo().MultiSelect() component would have a setting that when set to true, will submit an empty string when the multi-select is empty.
  6. Nencho
    Admin
    Nencho avatar
    1457 posts

    Posted 03 May Link to this post

    Hello Tyler,

    I understand your concerns, however this is the pattern on how the FormCollection works - if there is no data selected/filled for the control - it is never initialized.

    In order to achieve your scenario, you can verify whether the value for form["Exercises"] is null and use an empty string in the subsequent logic of your application.

    Please let us know, should you have any further questions.

    Regards,
    Nencho
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  7. Tyler
    Tyler avatar
    46 posts
    Member since:
    Nov 2013

    Posted 04 May in reply to Nencho Link to this post

    Hi,

    The custom framework we have implement merges data posted in the form with a pre loaded object and this seems to be the multi-select seems to be the only component causing issues. I understand not everyone will have this requirement. For anyone that needs an empty value posted by the form, I have created a JavaScript function to do this. Thanks for your help.

     

    <script type="text/javascript" language="javascript">
     
    function saveCourseForm() {
      $('#courseEditForm select').each(
        function (index) {
          var input = $(this);
          if (input.val() == null) {
            var selectName = input.attr('name');
            var selectNameHidden = $('input:hidden[name=' + selectName + ']').val();
            if (selectNameHidden == null) {
              $('<input />').attr('type', 'hidden')
              .attr('name', selectName)
              .attr('value', "")
              .appendTo('#courseEditForm');
            }
          }
        }
        )
     
      $("#courseEditForm").submit();
     
    }
    </script>

     

    @{if (edit)
    {
      @(Html.Kendo().MultiSelect()
      .Name("Prerequisites")
      .Placeholder(" ")
      .BindTo(ViewBag.Prerequisites)                           
      .HtmlAttributes(new { @class = "universalWidth" }))
    }
     
     
    <div class="float-right">
        <input type="button" value="Save" class="k-button" onclick="javascript: saveCourseForm()" />
        <input type="button" value="Close" class="k-button" onclick="javascript: cancelEditor('editCourseWindow')" />
    </div>

  8. Nencho
    Admin
    Nencho avatar
    1457 posts

    Posted 05 May Link to this post

    Hello Tyler,

    Thank you for sharing your solution with the community.

    Regards,
    Nencho
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
UI for ASP.NET MVC is VS 2017 Ready