This is a migrated thread and some comments may be shown as answers.

Setting value in Javascript results in null property at controller

2 Answers 4134 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Marc
Top achievements
Rank 1
Marc asked on 24 Oct 2018, 10:04 AM

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 Answers, 1 is accepted

Sort by
1
Accepted
Konstantin Dikov
Telerik team
answered on 26 Oct 2018, 07:06 AM
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.
0
Marc
Top achievements
Rank 1
answered on 01 Nov 2018, 09:53 AM

Hi Konstantin,

That was the missing piece!

Thanks for your help.

Tags
General Discussions
Asked by
Marc
Top achievements
Rank 1
Answers by
Konstantin Dikov
Telerik team
Marc
Top achievements
Rank 1
Share this question
or