Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get ModelState.AddModel Error to bind to knockout dynamically created validation spans?

I have setup Knockoutjs to dynamically create an editable list of values using the following code:

       var requirementModel = function() {
        var self = this;
        self.requirementtypes = ko.observableArray(@Html.Interpret(Model.requirementtypes));
        self.requirementid = ko.observable(@Html.Interpret(Model.requirementid));
        self.AddRequirementType = function() {
            self.requirementtypes.push({
                requirementtypeid: null,
                number: "",
                requirementid: 0
            });
        };
        self.RemoveType = function(Type) {
            self.requirementtypes.remove(Type);
        };
        self.hookUpValidation = function() {
            $.validator.unobtrusive.parseDynamicContent('.dynamicData');
        };
    };
    var viewModel = new requirementModel();
    ko.applyBindings(viewModel);

With html:

 <div class="small-box dynamicData"  data-bind="template:{ name: 'requirementType-template', foreach: requirementtypes, afterRender:$root.hookUpValidation }" ></div>
<button data-bind='click: AddType'>Add Type</button>

I have hooked up validation for dynamic data using the code recommended on stackoverflow.

When I post back to the server (I'm not using JSON just form post) I can do more complex validation and if something fails I can use ModelState.AddModelError("input field name", "I pity the fool that broke this"); This works perfectly with either strongly type or @Html.ValidationMessage("input field name") for non dynamic fields

However I can't find a way to hook Server Side Model Error to dynamic content.

I have the span tags that work with the client side and they work perfectly. However they aren't getting hooked into data returned after serverside validation fails and return page. Any idea how to acheive this?

Thanks

like image 616
GraemeMiller Avatar asked Feb 03 '12 12:02

GraemeMiller


1 Answers

I've just finished coding this for my current work project. I cannot post the code for propitiatory rules. Like your comment above says, there isn't an elegant way. I will describe the steps that we took to display our error messages.

First, modify your dynamically generated html so that each has the equivalent code to MVC3 @Html.ValidationFor(...) control. Next each dynamic control needs to have an id field that you can use to locate control to add error message to.

Steps I took were, starting after the controller receives the ajax data for validation -

  1. Validate the received data model

  2. Create a class to return the results that looks like this

    Class AjaxResults{
        bool success {get; set;);
        object returnedData {get; set;);
    }
    
  3. If model validates, return AjaxResults with success = true and returnedData = "validated data model"

  4. If models does not validate then

  5. Collect all the errors into a list of pairs. Where key = fieldID and value = "the error message".
  6. return AjaxResults with success = false and returnedData = "list of errors"

  7. After client receives the AjaxResults object

  8. If success = true, process result normally.

  9. If success = false, iterate through list highlighting the fields with the error and displaying the error message.

In the last step, you can use the jquery validation message display the error code. If you want to do this, then in jquery.unobtrusive.valiation.js file

  1. Add code to duplicate the functionality of onError method in the file.
  2. Add code to interate through the error list calling your onError method to display the messages. Be careful here in that information is stored in the .data attribute of the Error Message span.
  3. You may need to write code to clear all of these errors upon submitting the form.

This is a fairly long procedure. But the code is easily modularized into callable routines. We are currently using this in our production code and in practice, it becomes part of our framework code.

Hope this helps.

like image 110
photo_tom Avatar answered Nov 15 '22 04:11

photo_tom