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>
<b>Buttons are used to simulate a navigation bar</b>
<br/>
<button id="index" class="nav-btn active-tab">Index</button>
<button id="contact" class="nav-btn">Contact</button>
<div id="page-content">
<div id="index-content">
<p>This is index page. <b>Click on Contact</b> to put index's content in cache and load Contact page's content where the Angular's form is setted <b>(let form empty)</b>. As you can see, <b>Submit Button of form is disabled (expected result).</b> <br/>Then <b>click on index button</b>. This will put Contact page's content in cache (js obj pagesCache.contact).</p>
<p>If you then <b>re-click on Contact</b>, the angular's form <b>validation status has changed</b>: 'ng-pristine ng-valid ng-valid-required'</p><p><b>The Submit button is now enabled (not expected behaviour)</b></p>
<p>On this jsfiddle, there is an other bug. If you field with some text 'password input' the input-help div appear. If you then switch to index and re-switch to contact, the input-help div is no more responding and you have to enter new text in password input which makes the form's validation status changed to make it disappear on blur (code for this behaviour is in directive). As this bug is only in the jsfiddle (not on my own site), i neglected it. Maybe this bug is related to my problem too, i don't know... Seems like 'link' in directive is no more responding correctly.</p>
</div>
<div id="contact-content"></div>
</div>
<!-- this is the Angular's Form -->
<!--<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"...
CSS
.active-tab{background-color:blue;color:white;font-weight:bold}
#page-content{background-color:#ccc;padding:20px}
.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...
JavaScript
/*** Relevant code part for Angular ***/
var formExample = angular.module('form-example-app', []);
formExample.directive('passwordValidate', function () {
return {
require: 'ngModel',
link: function (scope, elm, attrs, ctrl) {
elm.on('blur', '.immediate-help', function () {
elm.next('.input-help').fadeOut();
}).on('focus', '.immediate-help', function () {
elmnext('.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;
}
});
}
};
});/*** END of angular code ***/
/*** this code is just used for testing purpose and is not relevant to issue ***/
var pagesCache = {}, firstLoadAngular = true;
$('.nav-btn').on('click', function () {
if($(this).is('.active-tab')) return;
var $activeTab = $('.active-tab');
pagesCache[$activeTab[0].id] = $('#' + $activeTab[0].id + '-content').detach();
$('.active-tab').removeClass('active-tab');
$(this).addClass('active-tab');
if (pagesCache[this.id]) //already in cache, we load content from cache
$('#page-content').append(pagesCache[this.id]);
else //for test we use temp var. On my site, i use ajax request
$('#' + this.id + '-content').html(tempContactContent);
//still for testing, we use this code for loading angular.bootstrap()
//we load...