TLBB
TLBB

Reputation: 89

Knockout Validation Failing to Fire

I have a knockout model with a string property, an int property and two lists of other models. Within the view, I am trying to validate the properties in the knockout object, at this point simply making sure they exist.

I'm using the Knockout.Validation lib, using extends.

The issue I run into, is when I click the button to send off the validation request, there is a javascript error self.isValid is not a function

I've looked it up online, and it seems others had the issues, only what ever solutions they had did not work for me.

Javascript model

EditTestStep

var StringParameterViewModel = function(data) {
    var self = this;

    if (data != null) {
        ko.mapping.fromJS(data, stringParameterMapping, self);
    } else {
        self.ParameterName = ko.observable().extend({
            required: {message: 'Please enter a parameter name.'}
        });
        self.StringValue = ko.observable().extend({
            required: { message: 'A value for the parameter is needed.' }
        });

    }
}

var XmlParameterViewModel = function (data) {
    var self = this;

    if (data != null) {

        ko.mapping.fromJS(data, xmlParameterMapping, self);
    } else {
        self.ParameterName = ko.observable().extend({
            required: true
        });
        self.XmlValue = ko.observable().extend({
            required: true
        });
    }
}

var xmlParameterMapping = {
    craete: function(options) {
        return XmlParameterViewModel(options.data);
    }
}


var stringParameterMapping = {
    create: function(options) {
        return StringParameterViewModel(options.data);
    }
}

var editTestStepMapping = {
    create: function(options) {
        return EditTestStepViewModel(options.data);
    }
}

var EditTestStepViewModel = function(data) {
    var self = this;
    if (data != null) {
        ko.mapping.fromJS(data, {}, self);

    } else {
        self.StringParameters = ko.observableArray();
        self.XmlParameters = ko.observableArray();
        self.TestStepName = ko.observable().extend({
            required: true
        });
    }

    self.saveTestStep = function() {
        var dataToSend = ko.mapping.toJSON(self);
        $.ajax({
            url: "/Home/SaveEdit/",
            type: "POST",
            contentType: "application/json",
            data: dataToSend
        });
    };

    self.Errors = ko.validation.group(self);

    self.checkValid = function () {
        if (self.isValid()) {
            alert('All ok!');
        } else {
            self.Errors.showAllMessages();
        }
    }


}


var validationOptions = {
    insertMessages: true,
    decorateElement: true,
    errorElementClass: 'errorCSS',
    messagesOnModified: true,
    debug: true,
    grouping: {
        deep: true,
        observable: false //Needed so added objects AFTER the initial setup get included
    }
};

ko.validation.init(validationOptions, true);

View

@using System.Web.Script.Serialization
@model MvcNewPatternsDemo.Models.EditTestStepViewModel


@{ string data = new JavaScriptSerializer().Serialize(Model);}

@{
    ViewBag.Title = "Home Page";
}
@section scripts{


    <script src="~/Scripts/knockout-3.4.0.js"></script>
    <script src="~/Scripts/knockout.validation.js"></script>
    <script src="~/Scripts/knockout.mapping-latest.js"></script>
    <script src="~/Scripts/jquery-1.10.2.js"></script>
    <script src="~/Scripts/EditTestStep.js"></script>
    <script type="text/javascript">
        var editTestStepViewModel = new EditTestStepViewModel(@Html.Raw(data));
        ko.applyBindingsWithValidation(editTestStepViewModel);
    </script>
    }

<form>

    <input class="form-control" name="ParameterName" data-bind="value: TestStepName"/>
    <input class="form-control" name="TestStepId" data-bind="value: TestStepId"/>

    <table class="table table-striped">
        <tr>
            <th>StringParameters</th>
        </tr>

        <tbody data-bind="foreach: StringParameters">
        <tr>
            <td class="form-group"> <input name="ParameterName" class="form-control input-sm" data-bind="value: ParameterName"/></td>
            <td class="form-group"> <input name="StringValue" class="form-control input-sm" data-bind="value: StringValue"/></td>
        </tr>
        </tbody>

    </table>

    <table class="table table-striped">
        <tr>
            <th>XmlPara</th>
        </tr>

        <tbody data-bind="foreach: XmlParameters">
            <tr>
                <td class="form-group"> <input name="ParameterName" class="form-control input-sm" data-bind="value: ParameterName" /></td>
                <td class="form-group"> <input name="XmlValue" class="form-control input-sm" data-bind="value: XmlValue" /></td>
            </tr>
        </tbody>

    </table>


</form>




<div class="row">
    <button data-bind="click: saveTestStep" type="submit">Save Test Step</button>
    <button data-bind="click: checkValid"type="button">Check Valid</button>
</div>

Models

namespace MvcNewPatternsDemo.Models
{



    public class TestStepDisplayModel
    {
        public int TestStepId { get; set; }
        public string TestStepName { get; set; }

    }

    public class StringParameterViewModel
    {
        public string ParameterName { get; set; }
        public string StringValue { get; set; }
    }

    public class XmlParameterViewModel
    {
        public string ParameterName { get; set; }
        public string XmlValue { get; set; }
    }


    [Serializable]
    public class EditTestStepViewModel
    {
        public string TestStepName { get; set; }
        public int TestStepId { get; set; }
        public List<StringParameterViewModel> StringParameters { get; set; }
        public List<XmlParameterViewModel> XmlParameters { get; set; }

        public EditTestStepViewModel()
        {
            this.StringParameters = new List<StringParameterViewModel>();
            this.XmlParameters = new List<XmlParameterViewModel>();
        }

    }

}

The ajax call to the controller works and all the data from the object is being sent, I simply need to get the validation to function.

Upvotes: 0

Views: 111

Answers (1)

Rick
Rick

Reputation: 11

I don't see a line in your javascript where you registered your extenders.

Try adding this at the end:

ko.validation.registerExtenders();

Upvotes: 1

Related Questions