JSFiddle - React, Tailwind, and code Playground

by Cristian Trifan

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-debug.js"></script>
<script src="https://cdn.rawgit.com/Knockout-Contrib/Knockout-Validation/master/dist/knockout.validation.js"></script>
<p>I need to edit model fields on the popup. I bind model field throught observable wrapper when popup open, but validation doesn't work.</p>
<button data-bind="click: editField">Edit with wrapper</button>
<div id="popup" style="display: none" data-bind="with: selectedField">  
    <div>
        <input data-bind='value: $rawData'/>
    </div>
    <button data-bind="click: $parent.closePopup.bind(null,'popup')()">Close</button>
</div>

<p>If I bind model field on input element without wrapper, validation works good. But doesn't work on the popup.</p>
<button data-bind="click: editField2">Edit 1 model field</button>
<button data-bind="click: editField3">Edit 2 model field</button>
<div id="popup2" style="display: none">  
    <div>
        <input data-bind='value: firstField'/>
    </div>
    <button data-bind="click: closePopup.bind(null,'popup2')()">Close</button>
</div>
<div id="popup3" style="display: none">  
    <div>
        <input data-bind='value: secondField'/>
    </div>
    <button data-bind="click: closePopup.bind(null,'popup3')()">Close</button>
</div>

CSS

.input-validation-error {
    -webkit-box-shadow: inset 0px 2px 3px -1px #aaaaaa, 0px 0px 2px 2px #FF9292;
    box-shadow: inset 0px 2px 3px -1px #aaaaaa, 0px 0px 2px 2px #FF9292;
    outline: none;    
}

JavaScript

var viewModel = function() {
    ko.validation.init({
        insertMessages: false,
        decorateInputElement: true,
        decorateElementOnModified: false,
        errorClass: 'input-validation-error',
        errorElementClass: null,
        errorMessageClass: null,
        messagesOnModified: false
    });
    
    this.firstField = ko.observable('').extend({ required: true });
    this.secondField = ko.observable('').extend({ required: true });
    
    this.selectedField = ko.observable(ko.observable());
    
    this.editField = function(){
        this.selectedField(this.firstField);
        this.closePopups();
        $("#popup").css('display', 'block');
    }
    
    this.editField2 = function(){   
        this.closePopups();
        $("#popup2").css('display', 'block');
    }
    
    this.editField3 = function(){
        this.closePopups();
        $("#popup3").css('display', 'block');
    }
    
    this.closePopup = function(selector){        
        $("#"+ selector).css('display', 'none');
    }
    
    this.closePopups = function(){
        this.closePopup('popup');
        this.closePopup('popup2');
        this.closePopup('popup3');
    }
};
 
ko.applyBindings(new viewModel());