JSFiddle - React, Tailwind, and code Playground

HTML

<link rel="stylesheet" href="http://twitter.github.io/bootstrap/assets/css/bootstrap.css">
<script src="//code.angularjs.org/1.1.1/angular.js"></script>
<button id="test">Detach/Attach Form</button>
<div id="info"></div>

<form ng-app="form-example" class="row form-horizontal" novalidate>
    <div class="control-group">
        <label class="control-label" for="inputPassword">Password</label>
        <div class="controls">
            <input ng-model="password" class="immediate-help" password-validate required type="password" id="inputPassword" placeholder="Password">
            <div class="input-help">
                 <h4>Password must meet the following requirements:</h4>

                <ul>
                    <li ng-class="pwdHasLetter">At least <strong>one letter</strong>

                    </li>
                    <li ng-class="pwdHasNumber">At least <strong>one number</strong>

                    </li>
                    <li ng-class="pwdValidLength">At least <strong>8 characters long</strong>

                    </li>
                </ul>
            </div>
        </div>
    </div>
    <div class="control-group">
        <div class="controls">
            <button type="submit" class="btn translate pull-right clear-both">Create New Campaign</button>
            <button class="btn translate pull-right clear-both" disabled>Create New Campaign</button>
        </div>
    </div>
</form>

CSS

.input-help {
    display: none;
    position:absolute;
    z-index: 100;
    top: -6px;
    left: 160px;
    width:200px;
    padding:10px;
    background:#fefefe;
    font-size:.875em;
    border-radius:5px;
    box-shadow:0 1px 3px #aaa;
    border:1px solid #ddd;
    opacity: 0.9;
}
.input-help::before {
    content:"\25C0";
    position: absolute;
    top:10px;
    left:-12px;
    font-size:16px;
    line-height:16px;
    color:#ddd;
    text-shadow:none;
}
.input-help h4 {
    margin:0;
    padding:0;
    font-weight: normal;
    font-size: 1.1em;
}
/* Always hide the input help when it's pristine */
 input.ng-pristine + .input-help {
    display: none;
}
/* Hide the invalid box while the input has focus */
 .ng-invalid:focus + .input-help {
    display: none;
}
/* Show a blue border while an input has focus, make sure it overrides everything else */

/* Overriding Twitter Bootstrap cuz I don't agree we need to alarm the user while they're typing */
 input:focus {
    color: black !important;
    border-color: rgba(82, 168, 236, 0.8) !important;
    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
    -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
    box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6) !important;
}
/* Show green border when stuff has been typed in, and its valid */
 .ng-dirty.ng-valid {
    border-color:#3a7d34;
}
/* Show red border when stuff has been typed in, but its invalid */
 .ng-dirty.ng-invalid {
    border-color:#ec3f41;
}
/* Show the help box once it has focus */
 .immediate-help:focus + .input-help {
    display: block;
}
/* Immediate help should be red when pristine */
 .immediate-help.ng-pristine:focus + .input-help {
    border-color:#ec3f41;
}
.immediate-help.ng-pristine:focus + .input-help::before {
    color:#ec3f41;
}
/* Help hould be green when input is valid */
 .ng-valid + .input-help...

JavaScript

var $form;
$(document).on('click','#test',function(){ 
     $('#info').html('').append('form was ng-valid: '+ $('form').is('.ng-valid') +'<br/>');
        if($('form').length)
            $form = $('form').detach();
        else $('body').append($form);
    
    $('#info').append('form is ng-valid: '+ $('form').is('.ng-valid'));
    });

var app = angular.module('form-example', []);

app.directive('passwordValidate', function () {
    return {
        require: 'ngModel',
        link: function (scope, elm, attrs, ctrl) {
            elm.on('blur', function () {
                elm.next('.input-help').fadeOut();
            }).on('focus', function () {
                elm.next('.input-help').fadeIn();
            });
            ctrl.$parsers.unshift(function (viewValue) {

                scope.pwdValidLength = (viewValue && viewValue.length >= 8 ? 'valid' : undefined);
                scope.pwdHasLetter = (viewValue && /[A-z]/.test(viewValue)) ? 'valid' : undefined;
                scope.pwdHasNumber = (viewValue && /\d/.test(viewValue)) ? 'valid' : undefined;

                if (scope.pwdValidLength && scope.pwdHasLetter && scope.pwdHasNumber) {
                    ctrl.$setValidity('pwd', true);
                    return viewValue;
                } else {
                    ctrl.$setValidity('pwd', false);
                    return undefined;
                }

            });
        }
    };
});