<!DOCTYPE html>
<html ng-app="superForm">
<head>
<meta charset="utf-8" />
<title>AngularJS superForm</title>
<link rel="stylesheet" href="https://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" />
<script>
document.write('<base href="' + document.location + '" />');
</script>
<link rel="stylesheet" href="style.css" />
<script src="https://code.angularjs.org/1.2.10/angular.js" data-semver="1.2.10"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.10/angular-animate.min.js"></script>
<script src="https://angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.10.0.js"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl" id="body">
<div class="animate-switch-container" ng-switch on="selection"
ng-class="{forward: direction, backward:!direction,longStage: longStage}">
<div class="animate-switch" ng-switch-default>
<form name="form" role="form" novalidate="" class="formClass">
<div class="row">
<div class="col-xs-6">
<div class="form-group" ng-class="{'has-error': form.uName.$invalid, 'has-success': !form.uName.$invalid}">
<label for="uName ">User Name</label>
<input type="text " class="form-control " name="uName " placeholder="User Name " ng-model="user.name " required=" " />
<div class="err_tip " ng-show="form.uName.$dirty && form.uName.$invalid ">
<span ng-show="form.uName.$error.required ">User name is required.</span>
</div>
</div>
</div>
<div class="col-xs-6 ">
<div class="form-group " ng-class="{ 'has-error': form.uEmail.$invalid, 'has-success': !form.uEmail.$invalid}">
<label for="uEmail">Email address</label>
<input type="email" class="form-control" name="uEmail" placeholder="Enter email" ng-model="user.email" required="" />
<div class="err_tip" ng-show="form.uEmail.$dirty && form.uEmail.$invalid">
<span ng-show="form.uEmail.$error.required">This field is required.</span>
<span ng-show="form.uEmail.$error.email">This is not a valid email.</span>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-xs-6">
<div class="form-group" ng-class="{'has-error': form.uPass.$invalid, 'has-success': !form.uPass.$invalid}">
<label for="uPass ">Password</label>
<input type="password" class="form-control" name="uPass" placeholder="Password " ng-model="user.pass " required=" " ng-pattern="/^(?=.*\d)(?=.*\D).{6,}$/"/>
<div class="err_tip " ng-show="form.uPass.$dirty && form.uPass.$invalid ">
<span ng-show="form.uPass.$error.required ">Password is required.</span>
<span ng-show="form.uPass.$error.pattern">Password must contain at least one digit and one letter and be at least 6 characters.</span>
</div>
</div>
</div>
<div class="col-xs-6 ">
<div class="form-group " ng-class="{ 'has-error': form.uPassConf.$invalid, 'has-success': !form.uPassConf.$invalid}">
<label for="uPassConf">Confirm Password</label>
<input type="password" class="form-control" name="uPassConf" placeholder="Confirm Password" ng-model="user.passconf" required="" password-match="user.pass" />
<div class="err_tip" ng-show="form.uPassConf.$dirty && form.uPassConf.$invalid">
<span ng-show="form.uPassConf.$error.required">This field is required.</span>
<span ng-show="form.uPassConf.$error.unique">Password does not match the confirm password.</span>
</div>
</div>
</div>
</div>
<button class="btn" ng-click="update(user,'stage2')" ng-disabled="form.$invalid" ng-class="{'btn-danger': form.$invalid, 'btn-success': !form.$invalid } ">Next</button>
</form>
</div>
<div class="animate-switch" ng-switch-when="stage2">
<form name="form" role="form" novalidate="" class="formClass">
<div class="row">
<div class="col-xs-8">
<div class="form-group " ng-class="{ 'has-error': form.uSecQuest.$invalid, 'has-success': !form.uSecQuest.$invalid}">
<label for="uSecQuest">Security Questions</label>
<select class="form-control" name="uSecQuest" required="" ng-options="c.quest for c in questions" ng-model="user.secQuest">
<option value="">-- Choose Security Questions --</option>
</select>
</div>
</div>
<!-- <div class="col-xs-4">
{{questions | json}}
</div> -->
</div>
<button class="btn btn-primary" ng-click="backTo('default')">Back</button>
<button class="btn" ng-click="pushToServer(user)" ng-disabled="form.$invalid " ng-class="{'btn-danger': form.$invalid, 'btn-success': !form.$invalid } ">Next</button>
</form>
</div>
<div class="animate-switch" ng-switch-when="finish">
<div class="row">
<div class="col-xs-12 fade" ng-class="{in:longStage}">
<pre>form = {{user | json}}</pre>
<pre>master = {{master | json}}</pre>
</div>
</div>
</div>
<a id="blog" target="_blank" href="https://kwakwak-code.blogspot.co.il/">My Blog</a>
</div>
</body>
</html>
#body {
background-color: #BFBAAF;
margin:20px;
}
.animate-switch-container.forward.longStage {
transition:all 0.5s;
height: 500px;
}
.fade {
opacity: 0;
-webkit-transition: opacity 0.25s ease-in;
-moz-transition: opacity 0.25s ease-in;
-o-transition: opacity 0.25s ease-in;
-ms-transition: opacity 0.25s ease-in;
transition: opacity 0.25s ease-in;
transition-delay: 0.25s;
}
.fade.in{
opacity: 1;
}
.animate-switch-container {
position:relative;
overflow: hidden;
height: 300px;
width: 550px;
border: solid 1px black;
box-shadow: 6px 6px 15px gray;
padding:10px;
border-radius:10px;
background-color: #D1E5D3;
background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.2) 25%, rgba(0, 0, 0, 0) 25%, rgba(0, 0, 0, 0) 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, rgba(0, 0, 0, 0) 75%, rgba(0, 0, 0, 0));
background-size: 50px 50px;
}
.animate-switch{
padding:10px;
width: 100%;
}
.animate-switch.ng-animate {
-webkit-transition:all 0.5s;
transition:all 0.5s;
position:absolute;
}
/* hide leaving slide */
/* show */
.animate-switch.ng-leave{
left:0;
}
/* hide */
.forward .animate-switch.ng-leave.ng-leave-active{
left:-100%;
}
.backward .animate-switch.ng-leave.ng-leave-active{
left: 100%;
}
/* show entering slide */
/* hide */
.forward .animate-switch.ng-enter {
left:100%;
}
.backward .animate-switch.ng-enter {
left:-100%;
}
/* show */
.animate-switch.ng-enter.ng-enter-active {
left:0;
}
/*Error Tooltip */
.err_tip {
position: absolute;
bottom: 50px;
right: 0px;
width: 200px;
background-color: #DA362A;
color: white;
padding: 2px;
border-radius: 16px;
box-shadow: 3px 3px 10px #888888;
margin: 5px;
text-align: center;
border: 2px solid #000000;
z-index: 1;
}
.err_tip:after, .err_tip:before {
top: 100%;
left: 50%;
border: solid transparent;
content: " ";
height: 0;
width: 0;
position: absolute;
pointer-events: none;
}
.err_tip:after {
border-color: rgba(218, 54, 42, 0);
border-top-color: #DA362A;
border-width: 10px;
margin-left: -10px;
}
.err_tip:before {
border-color: rgba(0, 0, 0, 0);
border-top-color: #000000;
border-width: 13px;
margin-left: -13px;
}
#blog{
position: absolute;
bottom: 10px;
right: 10px;
}
'use strict';
var app = angular.module('superForm', ['ngAnimate']);
/* Controllers */
function MainCtrl($scope, $http) {
$scope.fetchSecQuestUrl ='http://www.mocky.io/v2/52ea5a9a7cf0cd6806540819?callback=JSON_CALLBACK';
$scope.pushToServerUrl ='http://www.mocky.io/v2/52f0f1bdbf227b1603d8a146?callback=JSON_CALLBACK'; //true
// $scope.pushToServerUrl ='http://www.mocky.io/v2/52f0f29dbf227b2103d8a147?callback=JSON_CALLBACK'; //false
$scope.master = {
name: "Ronny",
pass: "1q2w3e",
passconf: "1q2w3e",
email: "ronihcohen@gmail.com",
};
$scope.longStage = 0;
$scope.update = function(user,nextStage) {
$scope.master = angular.copy(user);
$scope.direction = 1;
$scope.selection = nextStage;
if (nextStage=="stage3"){
$scope.longStage = 1;
}
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
$scope.isUnchanged = function(user) {
return angular.equals(user, $scope.master);
};
$scope.backTo = function(stage) {
$scope.direction = 0;
$scope.selection = stage;
};
$scope.fetchSecQuest = function() {
$scope.code = null;
$scope.response = null;
// cache set to false for IE
var httpHeaders = { 'If-Modified-Since': "0" };
// Data sent to the server
var myParams = {a:"q",did:"1",l:"ja-jp"};
$http({
method: 'JSONP',
url: $scope.fetchSecQuestUrl,
cache: false,
headers: httpHeaders,
params: myParams
}).
success(function(data, status) {
// pre-selecting question two
$scope.questions = data.questions;
$scope.user.secQuest= $scope.questions[1];
}).
error(function(data, status) {
$scope.questions = data.questions || "Request failed";
$scope.status = status;
});
};
$scope.pushToServer = function(user) {
$scope.master = angular.copy(user);
$scope.code = null;
$scope.response = null;
// cache set to false for IE
var httpHeaders = { 'If-Modified-Since': "0" };
// Data sent to the server
var myParams = $scope.master;
$http({
method: 'JSONP',
url: $scope.pushToServerUrl,
cache: false,
headers: httpHeaders,
params: myParams
}).
success(function(data, status) {
if (data.suc===true){
$scope.direction = 1;
$scope.longStage = 1;
$scope.selection = "finish";
} else if (data.suc===false) {
console.log (data.suc);
}
}).
error(function(data, status) {
console.log ("pushToServer: Request failed");
$scope.status = status;
});
};
$scope.fetchSecQuest();
};
/* Directives */
app.directive('passwordMatch', [
function() {
return {
restrict: 'A',
scope: true,
require: 'ngModel',
link: function(scope, elem, attrs, control) {
var checker = function() {
//get the value of the first password
var e1 = scope.$eval(attrs.ngModel);
//get the value of the other password
var e2 = scope.$eval(attrs.passwordMatch);
return e1 == e2;
};
scope.$watch(checker, function(n) {
//set the form control to valid if both
//passwords are the same, else invalid
control.$setValidity("unique", n);
});
}
};
}
]);
This Pen doesn't use any external CSS resources.
This Pen doesn't use any external JavaScript resources.