Search code examples
jqueryvalidationjsviews

JsViews top-level data-linked validation group syntax?


I see in this example for jsViews Validation Groups, that it exists inside a template and contains all of the fields to be validated. http://www.jsviews.com/#samples/tag-controls/datepicker/with-validation-wizard

Would it also be possible to form a validation group using top-level data-linked form elements, like in this jsfiddle? http://jsfiddle.net/xnerzqt6/

var app = {
    formData: {
        selectedThing: "",
        selectedPlace: "",
        selectedAction: ""
    }
};


$("#content").link(true, app);
.val-msg {
	margin-right: 5px;
}

.invalid.val-msg {
	border: 2px solid #cf321d;
}

.radiogroup.val-msg {
	padding: 3px;
	display: inline-block;
}

.radiogroup.invalid.val-msg {
	margin: 5px;
}

select.invalid.val-msg {
	margin: 4px;
}

select.val-msg {
	margin: 5px;
}

input[type=radio] {
	margin: 3px 3px 3px 5px;
	padding: 0;
}

label.error {
	color: #cf321d;
	font-style: italic;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://www.jsviews.com/download/jsviews.js"></script>
<script src="http://www.jsviews.com/download/sample-tag-controls/generic-edit/edit.js"></script>
<script src="http://www.jsviews.com/download/sample-tag-controls/validate/validate.js"></script>

<div id="content">
    <input data-link='{validate formData.selectedThing trigger=true minLength=8}'/><br/>
    <input data-link='{validate formData.selectedPlace trigger=true minLength=8}'/><br/>
    <span>large block of unrelated stuff</span><br/>
    <input data-link='{validate formData.selectedAction trigger=true minLength=8}'/><br/>
    <input type='button' value='Submit'/><br/>
    <span>should not be able to submit while any validation fails</span>
</div>


Solution

  • The validation wizard sample you linked to uses a "validation" validation group tag and a 'validate' tag which were written for nested tags in a template:

    {^{validation}}
        {^{validate .../}}
        {^{validate .../}}
    {{/validation}}
    

    So you have two options. 1) write a new validation group tag designed to work with top-level data-linking, or 2) include some 'shim code' in your page that programmatically hooks up the validate tag instances to the validation group tag.

    #2 is actually quite doable - and here it is in a jsfiddle: http://jsfiddle.net/BorisMoore/xf0Lnufw/

    The extra shim code is as follows:

    // Get the validationGroup 'validation' tag
    var validationGroup = $.view().childTags("validation")[0];
    
    $.view().childTags("validate").forEach(function(validateTag) {
        // For each 'validate' tag, associate with validationGroup.
        validateTag.validationGroup = validationGroup;
        validationGroup.addChild(validateTag);
    });
    
    validationGroup.validate(); // Run the validation group validate() method
    
    // Data-link the disabled state of the submit button to be disabled except
    // when the validationGroup is valid.
    $.link(
        "disabled{:!~validation.isValid}",
        "#submitBtn",
        app,
        {validation: validationGroup}
    );