Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
1906c3b
removed trailing whitespace and added radio buttons for education level
ksmithut Feb 20, 2014
f29d694
added symantic classes to css and added styling for input fields
ksmithut Feb 20, 2014
6b636d0
cleaned up markup and css to use symantic classes for styling
ksmithut Feb 20, 2014
10f1201
added media queries for basic responsiveness
ksmithut Feb 20, 2014
fffda5d
added bower components
ksmithut Feb 20, 2014
b6ccbe9
initial angular app setup for form
ksmithut Feb 20, 2014
8d80d2a
added in basic form data processing
ksmithut Feb 22, 2014
cc2eeed
fixed scope for dynamic radio button
ksmithut Feb 22, 2014
3086b51
changed code to be more modular, split concerns into folders and files
ksmithut Feb 22, 2014
884b372
changed filtering to use angular filters to order the list of educati…
ksmithut Feb 22, 2014
a931cf6
removed uneeded files
ksmithut Feb 22, 2014
275f35e
removed reference to deleted files
ksmithut Feb 22, 2014
a6da104
decided to use angular ui modules for masking
ksmithut Feb 22, 2014
35016a7
added telephone number masking for telephone field
ksmithut Feb 22, 2014
487762d
added viewport metatag
ksmithut Feb 22, 2014
423bddd
removed self closing /> to use more of an html5 standard
ksmithut Feb 22, 2014
13f7c07
added field-error directive
ksmithut Feb 22, 2014
eb93c1f
fixed syntax error
ksmithut Feb 22, 2014
829c683
added error fields to form for invalid answers
ksmithut Feb 22, 2014
adc6e4a
added successful form entry data gathering
ksmithut Feb 22, 2014
b660c59
make responsive fonts and things a bit better
ksmithut Feb 22, 2014
fc1dd84
added grunt task management for packaging
ksmithut Feb 22, 2014
21f7253
added timemout for request
ksmithut Feb 22, 2014
b86bf9a
added watch statements to watch scripts
ksmithut Feb 22, 2014
13d9473
added submit function to app-form script
ksmithut Feb 22, 2014
85db0fd
added comments to visually split form components
ksmithut Feb 22, 2014
76d130d
added flip animation on submittion complete
ksmithut Feb 23, 2014
5a211c5
fixed some of the flipping styles
ksmithut Feb 23, 2014
c603582
added fastclick functionality
ksmithut Feb 23, 2014
3cfc982
removed flipping animations for simpler show-hide
ksmithut Feb 24, 2014
5e0a7df
adjusted templates and directives only show errors once the user has …
ksmithut Feb 24, 2014
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
node_modules
bower_components
.DS_Store
npm-debug.log
51 changes: 51 additions & 0 deletions Gruntfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
'use strict';

var bowerFiles = require('bower-files')
, pkg = require('./package')
, scriptFiles
;

module.exports = function (grunt) {

grunt.initConfig({
uglify: {
prod: {
options: {
mangle: true,
compress: true,
sourceMap: true
},
files: scriptFiles()
}
},
watch: {
scripts: {
files: scriptFiles(),
tasks: ['uglify:prod'],
options: {
atBegin: true,
livereload: true
}
}
}
});

grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');

grunt.registerTask('default', ['uglify:prod']);

};

scriptFiles = function () {
var libJs = bowerFiles({ext: 'js'})
, files = {}
, filesKey = 'scripts/app-' + pkg.version + '.min.js'
;
files[filesKey] = libJs.concat([
'scripts/main.js',
'scripts/**/*.js',
'!scripts/app-*'
]);
return files;
};
10 changes: 10 additions & 0 deletions bower.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "fedtest",
"version": "0.0.0",
"private": true,
"dependencies": {
"angular-ui-utils": "~0.1.1",
"angular": "~1.2.13",
"fastclick": "~0.6.12"
}
}
104 changes: 72 additions & 32 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,51 +1,91 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Front-End Developer Test</title>
<link rel="stylesheet" href="styles/main.css" />
<link rel="stylesheet" href="styles/main.css">
</head>
<body>
<body data-ng-app="FedTestApp">
<div class="header">
<h1>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1>
<h1 class="main-heading">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</h1>
</div>
<div class="container">
<img class="banner" src="images/banner.jpg" alt="" />
<form method="post" action="index.html">
<h2>Nibh Hendrerit Sodales</h2>
<label>
First Name:
<input type="text" name="first_name" />
</label>
<label>
Last Name:
<input type="text" name="last_name" />
</label>
<label>
Phone Number:
<input type="text" name="phone" />
</label>
<label>
Email Address:
<input type="text" name="email" />
</label>
<div class="actions">
<button type="submit">Request Information</button>
<div class="container" data-ng-controller="MainFormController">
<img class="banner" src="images/banner.jpg" alt="">
<!-- Main Form -->
<div class="form-container">
<form class="main-form" name="mainForm" novalidate data-ng-submit="submit()" data-ng-hide="validSubmission">
<h2 class="form-heading">Nibh Hendrerit Sodales</h2>
<!-- First Name Field -->
<label class="input-label">
First Name:
<input class="input input-text" type="text" name="firstName" data-ng-model="firstName" required>
<div data-field-error="mainForm.firstName" data-field-name="First Name"></div>
</label>
<!-- Last Name Field -->
<label class="input-label">
Last Name:
<input class="input input-text" type="text" name="lastName" data-ng-model="lastName" required>
<div data-field-error="mainForm.lastName" data-field-name="Last Name"></div>
</label>
<!-- Phone Number Field -->
<label class="input-label">
Phone Number:
<input class="input input-text" type="tel" name="phone" data-ng-model="phone" required ui-mask="(999) 999-9999">
<div data-field-error="mainForm.phone" data-field-name="Phone Number" data-mask-error="must be a valid phone number"></div>
</label>
<!-- Email Address Field -->
<label class="input-label">
Email Address:
<input class="input input-text" type="email" name="email" data-ng-model="email" required>
<div data-field-error="mainForm.email" data-field-name="Email"></div>
</label>
<!-- Education Level Field -->
<div data-ng-show="educationLevels">
<span class="input-label">Current Education Level:</span>
<div data-field-error="mainForm.educationLevel" data-field-name="Education Level"></div>
<label class="input-label input-radio-label" data-ng-repeat="level in educationLevels | orderBy:educationLevelOrder">
<input class="input input-radio" type="radio" name="educationLevel" data-ng-value="level.key" data-ng-model="$parent.educationLevel" required>{{level.value}}
</label>
</div>
<!-- Form Submit -->
<div class="actions">
<button type="submit" class="form-submit">Request Information</button>
<div class="pre-valid" ng-show="preValid">
<p>Submitting...</p>
</div>
</div>
</form>
<div class="form-back" data-ng-show="validSubmission">
<h2 class="form-heading">Thank You</h2>
<p>Your submission has been entered into our records.</p>
<p>Someone will be contacting you shortly to help you along your way.</p>
</div>
</form>
</div>
<!-- END Main Form -->
<div class="content">
<p>
Aliquam sed nibh elit. Morbi non augue eu turpis dictum convallis sed et sapien.
Donec ac pretium nisi. Cras ac erat ut nibh hendrerit sodales eget in orci. Duis
pellentesque gravida orci ac ornare. In hac habitasse platea dictumst. Sed justo
Aliquam sed nibh elit. Morbi non augue eu turpis dictum convallis sed et sapien.
Donec ac pretium nisi. Cras ac erat ut nibh hendrerit sodales eget in orci. Duis
pellentesque gravida orci ac ornare. In hac habitasse platea dictumst. Sed justo
sapien, faucibus eu aliquet et, molestie quis orci.
</p>
<p>
Vivamus pulvinar, felis sed porttitor luctus, ligula nisl hendrerit nibh, vitae
lobortis massa odio at elit. Sed et felis metus, nec eleifend dui. Quisque eget
Vivamus pulvinar, felis sed porttitor luctus, ligula nisl hendrerit nibh, vitae
lobortis massa odio at elit. Sed et felis metus, nec eleifend dui. Quisque eget
semper eros. Etiam gravida lobortis nibh, vitae viverra velit rhoncus sodales.
</p>
</div>
</div>
<script src="scripts/app-0.0.0.min.js"></script>
<script type="text/ng-template" id="partials/field-error.html">
<div class="field-error" data-ng-show="field.$dirty && field.$invalid && field.$hasVisited">
<ul class="field-error-list">
<li class="field-error-list-item" data-ng-show="field.$error.required">{{fieldName}} is required.</li>
<li class="field-error-list-item" data-ng-show="field.$error.mask">{{fieldName}} {{maskError}}</li>
<li class="field-error-list-item" data-ng-show="field.$error.email">{{fieldName}} must be a valid email address</li>
</ul>
</div>
</script>
</body>
</html>
20 changes: 20 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "fedtest",
"version": "0.0.0",
"description": "Keith Smith's Front-end development test package",
"repository": {
"type": "git",
"url": "git://github.com/ksmithut/fedtest.git"
},
"license": "MIT",
"bugs": {
"url": "https://github.com/ksmithut/fedtest/issues"
},
"homepage": "https://github.com/ksmithut/fedtest",
"devDependencies": {
"grunt": "^0.4.2",
"grunt-contrib-uglify": "^0.3.2",
"bower-files": "0.0.3",
"grunt-contrib-watch": "^0.5.3"
}
}
6 changes: 6 additions & 0 deletions scripts/app-0.0.0.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions scripts/app-0.0.0.min.map

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions scripts/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Set up the base App
angular.module('FedTestApp', [
'FedTestApp.Controllers',
'FedTestApp.Services',
'FedTestApp.Filters',
'FedTestApp.Directives',
'ui.mask'
])
.run(function () {
FastClick.attach(document.body);
});
angular.module('FedTestApp.Controllers', []);
angular.module('FedTestApp.Services', []);
angular.module('FedTestApp.Filters', []);
angular.module('FedTestApp.Directives', []);
75 changes: 75 additions & 0 deletions scripts/controllers/main-form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
angular.module('FedTestApp.Controllers')
.controller('MainFormController', [
'$scope',
'appForm',
function ($scope, appForm) {
'use strict';

var defaultOrder
, formComplete
;

// This is the default order that the fields should be in. If the api values
// end up being different later on, we'll need to change these values.
//
// The reason we need the order is because the api endpoint gives us an
// object with keys, and we can't rely on the order of javascript objects
// in the browser (at least in chrome)
// http://dev-answers.blogspot.com/2012/03/javascript-object-keys-being-sorted-in.html
defaultOrder = [
'high',
'asso',
'bach',
'mast',
'doct'
];

// This is where we use the appForm service to get the data
appForm.getEducationLevels(function (data) {
if (data) {
$scope.educationLevels = data;
}
});

/**
* educationLevelOrder
*
* The order function to be used with the orderBy filter. It determines the
* order of the education levels. It uses the defaultOrder array defined
* above to order things. Any 'keys' that aren't in the array will be
* ordered first in the list
*/
$scope.educationLevelOrder = function (level) {
return defaultOrder.indexOf(level.key);
};

$scope.submit = function () {
var submitObject;
angular.forEach($scope.mainForm, function (field, key) {
// This is how we filter out all of the angular fields. Kinda hacky,
// need to adjust this later
if (key.charAt(0) === '$') { return; }
field.$dirty = true;
});
if ($scope.mainForm.$valid) {
submitObject = {
first_name: $scope.firstName,
last_name: $scope.lastName,
phone: $scope.phone,
email: $scope.email,
edu_level: $scope.educationLevel
};
$scope.preValid = true;
appForm.submit(submitObject, formComplete);
}
};

formComplete = function (err, valid) {
if (err) {
console.log('Unexpected Error:', err);
}
$scope.validSubmission = valid;
};

}
]);
34 changes: 34 additions & 0 deletions scripts/directives/field-error.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
angular.module('FedTestApp.Directives', [])
.directive('fieldError', function () {
'use strict';

return {
restrict: 'A',
scope: {
field: '=fieldError',
fieldName: '@',
maskError: '@'
},
replace: true,
templateUrl: 'partials/field-error.html'
};
})
.directive('input', function () {
'use strict';

return {
restrict: 'E',
require: '?ngModel',
link: function (scope, elem, attrs, ctrl) {
if (!ctrl) {
return;
}

elem.on('blur', function () {
scope.$apply(function () {
ctrl.$hasVisited = true;
});
});
}
}
});
Loading