Setting value in Javascript results in null property at controller

3 posts, 1 answers
  1. Marc
    Marc avatar
    6 posts
    Member since:
    Sep 2013

    Posted 24 Oct 2018 Link to this post

    I'm fairly new to MVC (and web development in general) and I keep coming across several 'gotchas' which result in unexpected behaviour. I am using Kendo UI for ASP.NET MVC, however I'm 99% certain that my problem is due to my lack of understanding of either Javascript or MVC rather than anything to do with Kendo.
    You should be able to reproduce the problem using the following code:

    Models:

    public class DemoClass
        {
            public int id { get; set; }
            public string randomData { get; set; }
     
            public List<DemoPartyDetails> partyDetails { get; set; }
     
            public DemoClass()
            {
                partyDetails = new List<DemoPartyDetails>();
            }
        }
    public class DemoPartyDetails
        {
            public int id { get; set; }
            public string firstName { get; set; }
            public string surname { get; set; }
     
            public string gender { get; set; }
     
            public DemoPartyDetails()
            {
     
            }
        }

     

    Controller:

    public class DemoController : Controller
        {
            // GET: Demo
            public ActionResult Index()
            {
                DemoClass demo = new DemoClass();
                return View(demo);
            }
     
            [HttpPost]
            public ActionResult Create(DemoClass model)
            {
                try
                {
                    if (model.partyDetails[0].gender != null)
                        Console.WriteLine("Party details populated");
                    else
                        Console.WriteLine("Something went wrong...");
     
                    return RedirectToAction("Index");
                }
                catch
                {
                    return View();
                }
            }
        }

     

    View:

    @model DemoPortal.Models.DemoClass
     
    <html>
    <head>
        <meta name="viewport" content="width=device-width" />
        <title></title>
    </head>
    <body>
        @using (Html.BeginForm("Create", "Demo", FormMethod.Post))
        {
            <div>
                @Html.EditorFor(model => model.randomData)
            </div>
     
            <div>
                <a class="k-button k-button-icontext k-add-button" href="#"><span class="k-icon k-i-add"></span>Add Party</a>
                @(Html.Kendo().ListView(Model.partyDetails)
                        .Name("demoListView")
                        .TagName("div")
                        .ClientTemplateId("demoTemplate")
                        .DataSource(dataSource => dataSource
                            .Model(model => model.Id(x => x.id))
                            )
                        .Editable(editable => editable.TemplateName("DemoPartyDetails"))
                )
            </div>
     
            <input type="submit" value="Submit" />
        }
    </body>
    </html>
     
     
    <script type="text/x-kendo-tmpl" id="demoTemplate">
        <div class="demoParty">
            <h3>#:firstName#</h3>
            <span>#:surname#</span>
     
            <input type="hidden" name="PartyDetails[#:index(data)#].firstName" value="#:firstName#" />
            <input type="hidden" name="PartyDetails[#:index(data)#].surname" value="#:surname#" />
            <input type="hidden" name="PartyDetails[#:index(data)#].gender" value="#:gender#" />
        </div>
    </script>
     
     
    <script>
    $(function() {
            var listView = $("#demoListView").data("kendoListView");
     
            $(".k-add-button").click(function(e) {
                listView.add();
                e.preventDefault();
            });
    });
     
    function index(dataItem) {
        var data = $("#demoListView").data("kendoListView").dataSource.data();
     
        return data.indexOf(dataItem);
     
    }
     
    function maleClick(e) {
        document.getElementById("gender").value = "M";
     
        document.getElementById("randomData").value = "random";
     
        var maleButton = document.getElementById("IsMale");
        var femaleButton = document.getElementById("IsFemale");
        femaleButton.classList.remove("k-primary");
        maleButton.classList.add("k-primary");
    };
     
    function femaleClick(e) {
        document.getElementById("gender").value = "F";
     
        var maleButton = document.getElementById("IsMale");
        var femaleButton = document.getElementById("IsFemale");
        maleButton.classList.remove("k-primary");
        femaleButton.classList.add("k-primary");
    };
    </script>

     

    DemoPartyDetails Editor Template

    @model DemoPortal.Models.DemoPartyDetails
     
    @using (Html.BeginForm())
    {
        <div>
            <div>
                <label>Gender:</label>
                @(Html.Kendo().Button()
                        .Name("IsMale")
                        .Content("Male")
                        .HtmlAttributes(new { type = "button" })
                        .Events(ev => ev.Click("maleClick")))
     
                @(Html.Kendo().Button()
                        .Name("IsFemale")
                        .Content("Female")
                        .HtmlAttributes(new { type = "button", @class = "k-primary" })
                        .Events(ev => ev.Click("femaleClick")))
            </div>
     
            @(Html.HiddenFor(model => model.id))
            @(Html.EditorFor(model => model.gender))
            @(Html.EditorFor(model => model.firstName))
            @(Html.EditorFor(model => model.surname))
     
            <div class="btnArea">
                <a class="k-button k-update-button" href="\\#"><span class="k-icon k-update"></span></a>
                <a class="k-button k-cancel-button" href="\\#"><span class="k-icon k-cancel"></span></a>
            </div>
        </div>
     
    }

     

    When running this code, I can click the button to add a new party, the editor template appears as expected and I press the 'Male' button, which populates the gender field with "M".

    I then fill in the other two fields with generic "Test" and "Person" data before confirming the entry and then pressing submit.
    What I find when I place a breakpoint at the controller however is that the model being passed through has the gender set to null. The first name and surname ("Test" and "Person") are fully populated however. The randomData is also fully populated as expected.

    Interestingly, if I go back and manually type something like "Male" into the gender field, that is now also populated. It's only when I try to use javascript to set the value that it's null.

    The ultimate goal is to have a hidden field populated by javascript when a button is pressed, so if someone could point out my mistake it would be very much appreciated!

  2. Answer
    Konstantin Dikov
    Admin
    Konstantin Dikov avatar
    2466 posts

    Posted 26 Oct 2018 Link to this post

    Hi Marc,

    When a value is change manually with JavaScript, you need to ensure that you are triggering the "change" event of the editor after the value in the input is changed:
    $("#gender").trigger("change");

    Please give this a try and let me know if the value is passed correctly.


    Regards,
    Konstantin Dikov
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  3. Marc
    Marc avatar
    6 posts
    Member since:
    Sep 2013

    Posted 01 Nov 2018 in reply to Konstantin Dikov Link to this post

    Hi Konstantin,

    That was the missing piece!

    Thanks for your help.

Back to Top