Search code examples
javascriptknockout.jsknockout-2.0knockout-mvc

Knockout js passing textbox value to viewmodel


I have model class and viewmodel and I am creating an instance of the model class.

When i enter some text inside the input tag the value won't get into the viewmodel, when I click the "save" button I get an empty array.

HTML

<div id="UserID">
    <lable>UserName</lable>
    <input type="text" data-bind="value:currentUser().userName" />
    <br />
    <!--<span data-bind="text:firstName" /><br />-->
    <label>MobileNumber</label>
    <input type="text" data-bind="value:currentUser().userMobileNumber" /><br />
    <label>Email</label>
    <input type="text" data-bind="value:currentUser().userEmail" /><br />
    <label>Image</label>
    <input type="text" data-bind="value:currentUser().userImageBase64" /><br />
    <label>Image</label>
    <input type="text" data-bind="value:currentUser().userImageType" /><br />
    <label>DeviceUID</label>
    <input type="text" data-bind="value:currentUser().deviceUId" /><br />
    <input type="button" value="save" data-bind="click:currentUser().saveuserDetail" />
</div>

JS

// Model class///
var userModel = function() {
    self = this;
    self.userName = ko.observable()
    self.userMobileNumber = ko.observable();
    self.userEmail = ko.observable();
    self.userImageBase64 = ko.observable();
    self.userImageType = ko.observable();
    self.deviceUId = ko.observable();
}

//ViewModel//
var userDetails = function() {
    self = this;
    self.currentUser = ko.observable(new userModel());
    //ajax post
    self.saveuserDetail = function() {
        var model = ko.toJSON(currentUser());
        console.log(model);
        jQuery.support.cors = true;
        $.ajax({
            url: baseurl + 'api/xxxx/xxxxx',
            type: 'POST',
            data: model,
            contentType: 'application/json; charset=utf-8',
            dataType: 'json',
            success: function(data) {}
        });
    }
};

$(document).ready(function() {
    ko.applyBindings(new userDetails());
});

Solution

  • You've bound the click even on the <input type="button"/> element to a saveuserDetail function on the nested curretUser view-model, whereas you've actually located this function on the parent userDetails view-model.

    <input type="button" value="save" data-bind="click:curretUser().saveuserDetail" />
    

    Either change this binding to

    <input type="button" value="save" data-bind="click:saveuserDetail" />
    

    or relocate the saveuserDetail function to the curretUser view-model.

    Also, you should favour the textInput binding for <input/> elements instead of the value binding. Here is an explanation of the difference.