Last active
August 29, 2015 14:02
-
-
Save uglow/34450d0e31c2b6c56759 to your computer and use it in GitHub Desktop.
AngularJS Melbourne - Companion Demo Files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------- sitemap.jsonp ----------// | |
mwApp.SITEMAP=[ | |
{ | |
"title": "Section Title", | |
"children": [ | |
{ | |
"title": "Page title", | |
"children": [ | |
{ | |
"id": "a65079e4-6327-4393-9bec-c537066a2aa0", | |
"title": "Domestic product", | |
"route": "/view/domestic-parcels.json", | |
"faq": "DomPar100" | |
}, | |
{ | |
"id": "147a8cb3-4b57-4fea-8ef7-02176a4aa6ee", | |
"title": "Internationl Product", | |
"route": "/view/parcel-post.json", | |
"faq": "ParPos100" | |
}, | |
//... | |
//---------- index.html ----------// | |
<!DOCTYPE html> | |
<html lang="en" id="ng:app" ng-app="mwApp" ng-controller="MainController"> | |
<head> | |
<!-- ... --> | |
<script> | |
// Load the sitemap.jsonp BEFORE loading the AngularJS files | |
document.write('<script src="/m-static/sitemap.jsonp"><' + '/script>'); | |
</script> | |
</head> | |
<body ...> | |
<!-- ... --> | |
<script> | |
// Load AngularJS at the end of the BODY tag | |
document.write('<script src="jslib/angular.js"><' + '/script>'); | |
document.write('<script src="jslib/angular-route.js"><' + '/script>'); | |
document.write('<script src="jslib/angular-animate.js"><' + '/script>'); | |
document.write('<script src="jslib/angular-sanitize.js"><' + '/script>'); | |
document.write('<script src="jslib/global.js"><' + '/script>'); | |
document.write('<script src="js/core.js"><' + '/script>'); | |
//... Other modules ... | |
</script> | |
</body> | |
</html> | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Routing... so when do we see $routeProvider.when() ??? | |
//---------- moduleA/routes.jsonp ----------// | |
moduleRoutes = [ | |
{ | |
"title": "Tools", | |
"type": "section", | |
"menuPriority": 100, | |
"children": [ | |
{ | |
"id": "ModuleA", | |
"title": "Calculator", | |
"route": "/view/calc", | |
"template": "partials/ModuleA/pac.html", | |
"faq": ["CalPos100", "Calculator"], | |
"icon": "a001-calculate", | |
"menuPriority": 102, | |
"promoted": false | |
}, | |
{ | |
"id": "ModuleA_Location", | |
"title": "Calculator", | |
"route": "/view/calc/domestic-location", | |
"template": "partials/moduleA/calc-domestic-location.html", | |
"faq": ["CalPos100", "Calculator"], | |
"parentRoute": "/view/pac", | |
"hidden": true | |
}, | |
//... | |
//---------- sitemap.jsonp ----------// | |
// Compare to above routes, this needs to massaged into shape. (menuPriority missing, | |
// template property is useless) | |
// Our CMS module does this itself by walking the tree and changing the nodes as required | |
mwApp.SITEMAP=[ | |
{ | |
"title": "Section Title", | |
"children": [ | |
{ | |
"title": "Page title", | |
"children": [ | |
{ | |
"id": "a65079e4-6327-4393-9bec-c537066a2aa0", | |
"title": "Domestic product", | |
"route": "/view/domestic-parcels.json", | |
"faq": "DomPar100" | |
}, | |
{ | |
"id": "147a8cb3-4b57-4fea-8ef7-02176a4aa6ee", | |
"title": "Internationl Product", | |
"route": "/view/parcel-post.json", | |
"faq": "ParPos100" | |
}, | |
//... | |
//---------- _moduleA.js ----------// | |
var mod = angular.module('moduleA', [...]); | |
function getRoutes() { | |
var routes = []; | |
// Way of separating the code from the data at design-time, but including | |
// the data during compile-time... | |
////@@include('../includes/moduleA/routes.jsonp') | |
return routes; | |
} | |
configureModuleRoutes(mod, getRoutes()); | |
function configureModuleRoutes (mod, sitemap) { | |
'use strict'; | |
// Create the routes in the $routeProvider | |
mod.config(['$routeProvider', 'RouteServiceProvider', ... | |
function ($routeProvider, RouteServiceProvider, ...) { | |
// Add the routes to the RouteService | |
RouteServiceProvider.registerSitemapRoutes($routeProvider, ..., sitemap); | |
}]); | |
} | |
//---------- RouteService.js ----------// | |
//... | |
this.registerSitemapRoutes = function ($routeProvider, ..., sitemap) { | |
// Add the tree-data to the sitemap | |
addToSiteMap(sitemap); | |
// We need to extract the routing information into a routing-object | |
// (containing just the routes, no UI nodes (like "Tools"), no hierarchy) | |
var routeObject = getRouteObjectFromSitemapTree(sitemap); | |
createRouteConfig($routeProvider, routeObject, routes); | |
return routes; | |
}; | |
function createRouteConfig($routeProvider, routeObject, routes) { | |
// Setup our routes based on the data in the ROUTES collection | |
for (var routeKey in routeObject) { | |
var routeItem = routeObject[routeKey], | |
routeTemplate = routeItem.template; | |
/**/ $routeProvider.when(routeItem.route, { templateUrl: routeTemplate }); | |
//... | |
// Append the route to the parentRouteConfig | |
routes[routeKey] = routeObject[routeKey]; | |
} | |
} | |
//... | |
// Finally, at RUNTIME, the RouteService has the following methods: | |
// getRoutes() : Object-map | |
// getSitemap(): Array (tree) // Used by the navigation menu | |
// getRoutes() returns an object... | |
TNC: Object | |
id: "TNC" | |
title: "Terms & Conditions", | |
menuPriority: 953 | |
promoted: false | |
route: "http://mysite.com.au/terms-conditions.html" | |
routeParams: Array[0] | |
template: false, | |
hidden: false, | |
__proto__: Object | |
TRACKING: Object | |
YOUTH_REG_FORM: Object | |
YOUTH_REG_FORM_THANKYOU: Object | |
a2ec7b37-3c29-4c18-bdee-87e78183cc1d: Object | |
a0430f92-4979-4ab0-9dfd-9a23b69422cf: Object | |
a1876c79-c833-46da-9ebb-82fc7e8cf9f0: Object |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------- Gruntfile.js ----------// | |
//... | |
concat: { | |
/* This builds the moduleName.js file in the output/js folder */ | |
moduleJS: { | |
files: [ | |
{ | |
expand: true, | |
cwd: '<%= paths.src.jsDir %>', | |
src: ['<%= paths.src.jsFilesToIncludeFirst %>', '<%= paths.src.jsFiles %>', '!<%= paths.test.jsFiles %>'], | |
dest: '<%= paths.dest.jsDir %>', | |
rename: function(dest, src) { | |
// use the source directory to create the file | |
// example with your directory structure | |
// dest = 'dev/js/' | |
// src = 'module1/js/main.js' | |
return dest + src.substring(0, src.indexOf('/')) + '.js'; | |
} | |
} | |
] | |
} | |
} | |
//... | |
//----------- paths.js ----------// | |
paths: { | |
src: { | |
//... | |
jsDir: 'src/modules/', | |
jsFiles: '**/*.js', | |
jsFilesToIncludeFirst: '**/_*.js' //<------ THIS is required so that your conc | |
///... | |
} | |
} | |
//----------- _module1.js ----------// | |
(function (angular) { | |
'use strict'; | |
// Module DEFINITION | |
var mod = angular.module('module1', ['core']); | |
})(window.angular); | |
//----------- _module1Controller.js ----------// | |
(function (angular) { | |
'use strict'; | |
// Module REFERENCE | |
var mod = angular.module('module1'); | |
mod.controller(...); | |
//... | |
})(window.angular); | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------- Example of form policies ----------// | |
// DISPLAY_FILTERS - these represent an expression which which will be tested to determine whether to show an error | |
angular.module('ui.formPolicy.displayError.onSubmit', []) | |
.constant('formPolicyErrorExistsWhen', (function () { | |
return function (formName, fieldName) { | |
return formName + '._formSubmitAttempted && ' + fieldName + '.$invalid'; | |
}; | |
})()); | |
angular.module('ui.formPolicy.displayError.onSubmitOrDirty', []) | |
.constant('formPolicyErrorExistsWhen', (function () { | |
return function (formName, fieldName) { | |
return '(' + formName + '._formSubmitAttempted || ' + fieldName + '.$dirty) && ' + fieldName + '.$invalid'; | |
}; | |
})()); | |
// App module definition which includes the desired form policies | |
angular.module('mwApp', ['ngSanitize', 'ngRoute', 'ngAnimate', 'core', | |
// Form policy modules. Need to load modules for each behaviour | |
'ui.formPolicy.checkForErrors.onBlurUntilSubmitThenOnChange', | |
'ui.formPolicy.displayError.onSubmitOrDirty', | |
'ui.formPolicy.focusBehaviour.onSubmitFocusFirstField', | |
//... | |
]); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//---------- some-partial.html (DESIGN TIME)----------// | |
// Can add your own directives to the input using ff-my-directive="..."! | |
<form-input id="businessAdviceForm-email" name="email" required="true" label="Email address" | |
ff-class="span12" ff-type="email" ff-ng-model="business.email" | |
ff-maxlength="55" ff-minlength="33" | |
field-errors="{required: 'Please enter a valid email address', email: 'Please enter a valid email address'}" | |
></form-input> | |
//---------- some-partial.html (RUN TIME)----------// | |
// Example: https://m.auspost.com.au/view/solutions/businessadvice | |
<div> | |
<label for="businessAdviceForm-email">Email address | |
<span class="required ng-isolate-scope" aria-hidden="true" ng-class="{'ng-hide': hide}" hide="!(true)"></span></label> | |
<div class="controls-row"> | |
<input id="businessAdviceForm-email" name="email" | |
class="span12 ng-pristine ng-invalid ng-invalid-required ng-valid-email" type="email" | |
ng-model="business.email" maxlength="55" ng-required="true" aria-required="true" | |
field-error-controller="" aria-invalid="false" required="required"> | |
<span ng-transclude=""></span> | |
</div> | |
<div class="container-error" id="businessAdviceForm-email-errors"> | |
<span class="sr-only" aria-hidden="true" id="businessAdviceForm-email-errors-aria"></span> | |
</div> | |
</div> | |
//----------------------------------- | |
// Core function used by the <form-input> directive that copies directive-aliases onto the actual input element: | |
decorateInputField: function (inputElem, hostElement, attr, id, name, required) { | |
inputElem.attr('id', id).attr('name', name); | |
// Apply all of the ff-* attributes to the input element. Use the original attribute names | |
// attr.$attr contains the snake-case names e.g. 'form-field' vs camel case 'formField' | |
for (var a in attr.$attr) { | |
if (a.indexOf('ff') === 0) { // Don't search for 'ff-' as the '-' has been replaced with camel case now | |
var origAttrName = attr.$attr[a].substr(3); | |
inputElem.attr(origAttrName, attr[a]); | |
// Remove all attributes off the host element | |
hostElement.removeAttr(attr.$attr[a]); | |
} | |
} | |
// Make aria-required's value an interpolation-directive... | |
inputElem.attr('ng-required', required); | |
inputElem.attr('aria-required', '{{!!(' + required + ')}}'); // evaluates to true / false | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment