Commit c2f442d9 authored by Pascal Hartig's avatar Pascal Hartig

Merge branch 'schubertha-gh-pages' into gh-pages

parents e7272037 39339dfd
......@@ -8,6 +8,7 @@
- Aria Templates
- Enyo + Backbone.js
- React
- SAPUI5
- Updates since 1.1:
- Backbone 1.0
......
......@@ -150,6 +150,9 @@
<li class="routing labs">
<a href="labs/architecture-examples/react/" data-source="http://facebook.github.io/react/" data-content="React is a JavaScript library for building user interfaces.">React</a>
</li>
<li class="routing labs">
<a href="labs/architecture-examples/sapui5/" data-source="http://scn.sap.com/community/developer-center/front-end" data-content="SAPUI5 is SAP's HTML5-based UI technology that allows you to build rich, interactive Web applications.">SAPUI5</a>
</li>
</ul>
<hr>
<h2>Compile To JavaScript</h2>
......
{
"name": "todomvc-sapui5",
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.7"
}
}
(function () {
'use strict';
// Underscore's Template Module
// Courtesy of underscorejs.org
var _ = (function (_) {
_.defaults = function (object) {
if (!object) {
return object;
}
for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
var iterable = arguments[argsIndex];
if (iterable) {
for (var key in iterable) {
if (object[key] == null) {
object[key] = iterable[key];
}
}
}
}
return object;
}
// By default, Underscore uses ERB-style template delimiters, change the
// following template settings to use alternative delimiters.
_.templateSettings = {
evaluate : /<%([\s\S]+?)%>/g,
interpolate : /<%=([\s\S]+?)%>/g,
escape : /<%-([\s\S]+?)%>/g
};
// When customizing `templateSettings`, if you don't want to define an
// interpolation, evaluation or escaping regex, we need one that is
// guaranteed not to match.
var noMatch = /(.)^/;
// Certain characters need to be escaped so that they can be put into a
// string literal.
var escapes = {
"'": "'",
'\\': '\\',
'\r': 'r',
'\n': 'n',
'\t': 't',
'\u2028': 'u2028',
'\u2029': 'u2029'
};
var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
// JavaScript micro-templating, similar to John Resig's implementation.
// Underscore templating handles arbitrary delimiters, preserves whitespace,
// and correctly escapes quotes within interpolated code.
_.template = function(text, data, settings) {
var render;
settings = _.defaults({}, settings, _.templateSettings);
// Combine delimiters into one regular expression via alternation.
var matcher = new RegExp([
(settings.escape || noMatch).source,
(settings.interpolate || noMatch).source,
(settings.evaluate || noMatch).source
].join('|') + '|$', 'g');
// Compile the template source, escaping string literals appropriately.
var index = 0;
var source = "__p+='";
text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
source += text.slice(index, offset)
.replace(escaper, function(match) { return '\\' + escapes[match]; });
if (escape) {
source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
}
if (interpolate) {
source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
}
if (evaluate) {
source += "';\n" + evaluate + "\n__p+='";
}
index = offset + match.length;
return match;
});
source += "';\n";
// If a variable is not specified, place data values in local scope.
if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
source = "var __t,__p='',__j=Array.prototype.join," +
"print=function(){__p+=__j.call(arguments,'');};\n" +
source + "return __p;\n";
try {
render = new Function(settings.variable || 'obj', '_', source);
} catch (e) {
e.source = source;
throw e;
}
if (data) return render(data, _);
var template = function(data) {
return render.call(this, data, _);
};
// Provide the compiled function source as a convenience for precompilation.
template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
return template;
};
return _;
})({});
if (location.hostname === 'todomvc.com') {
window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
}
function redirect() {
if (location.hostname === 'tastejs.github.io') {
location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
}
}
function findRoot() {
var base;
[/labs/, /\w*-examples/].forEach(function (href) {
var match = location.href.match(href);
if (!base && match) {
base = location.href.indexOf(match);
}
});
return location.href.substr(0, base);
}
function getFile(file, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', findRoot() + file, true);
xhr.send();
xhr.onload = function () {
if (xhr.status === 200 && callback) {
callback(xhr.responseText);
}
};
}
function Learn(learnJSON, config) {
if (!(this instanceof Learn)) {
return new Learn(learnJSON, config);
}
var template, framework;
if (typeof learnJSON !== 'object') {
try {
learnJSON = JSON.parse(learnJSON);
} catch (e) {
return;
}
}
if (config) {
template = config.template;
framework = config.framework;
}
if (!template && learnJSON.templates) {
template = learnJSON.templates.todomvc;
}
if (!framework && document.querySelector('[data-framework]')) {
framework = document.querySelector('[data-framework]').getAttribute('data-framework');
}
if (template && learnJSON[framework]) {
this.frameworkJSON = learnJSON[framework];
this.template = template;
this.append();
}
}
Learn.prototype.append = function () {
var aside = document.createElement('aside');
aside.innerHTML = _.template(this.template, this.frameworkJSON);
aside.className = 'learn';
// Localize demo links
var demoLinks = aside.querySelectorAll('.demo-link');
Array.prototype.forEach.call(demoLinks, function (demoLink) {
demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
});
document.body.className = (document.body.className + ' learn-bar').trim();
document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
};
redirect();
getFile('learn.json', Learn);
})();
html,
body {
margin: 0;
padding: 0;
}
button {
margin: 0;
padding: 0;
border: 0;
background: none;
font-size: 100%;
vertical-align: baseline;
font-family: inherit;
color: inherit;
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea url('../bower_components/todomvc-common/bg.png');
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
.sapUiTv, .sapUiBtnS {
font: inherit;
font-size: inherit;
}
#todoapp {
background: #fff;
background: rgba(255, 255, 255, 0.9);
margin: 130px 0 40px 0;
border: 1px solid #ccc;
position: relative;
border-top-left-radius: 2px;
border-top-right-radius: 2px;
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.2),
0 25px 50px 0 rgba(0, 0, 0, 0.15);
}
#todoapp:before {
content: '';
border-left: 1px solid #f5d6d6;
border-right: 1px solid #f5d6d6;
width: 2px;
position: absolute;
top: 0;
left: 40px;
height: 100%;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#todoapp input:-moz-placeholder {
font-style: italic;
color: #a9a9a9;
}
#todoapp h1 {
position: absolute;
top: -120px;
width: 100%;
font-size: 70px;
font-weight: bold;
text-align: center;
color: #b3b3b3;
color: rgba(255, 255, 255, 0.3);
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
-webkit-text-rendering: optimizeLegibility;
-moz-text-rendering: optimizeLegibility;
-ms-text-rendering: optimizeLegibility;
-o-text-rendering: optimizeLegibility;
text-rendering: optimizeLegibility;
}
#header {
padding-top: 15px;
border-radius: inherit;
}
#header:before {
content: '';
position: absolute;
top: 0;
right: 0;
left: 0;
height: 15px;
z-index: 2;
border-bottom: 1px solid #6c615c;
background: #8d7d77;
background: -webkit-gradient(linear, left top, left bottom, from(rgba(132, 110, 100, 0.8)),to(rgba(101, 84, 76, 0.8)));
background: -webkit-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -moz-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -o-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: -ms-linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
background: linear-gradient(top, rgba(132, 110, 100, 0.8), rgba(101, 84, 76, 0.8));
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#9d8b83', EndColorStr='#847670');
border-top-left-radius: 1px;
border-top-right-radius: 1px;
}
#main {
position: relative;
z-index: 2;
border-top: 1px dotted #adadad;
}
#new-todo,
.sapUiTfBrd.sapUiTfRo.todo,
.sapUiTfBrd.sapUiTfStd.todo {
position: relative;
margin: 0;
margin-right: 153px;
width: 100%;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
background-color: transparent;
border: 0;
outline: none;
color: #4D4D4D;
padding: 6px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-ms-box-sizing: border-box;
-o-box-sizing: border-box;
box-sizing: border-box;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
.sapUiTfBrd.sapUiTfStd.todo {
border: 1px solid #999;
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
}
.sapUiTfBrd.sapUiTfRo.todo[data-completed="true"] {
color: #a9a9a9;
text-decoration: line-through;
}
#toggle-all {
display: block;
outline: none;
}
#toggle-all input {
z-index: 3;
position: absolute;
text-align: center;
top: 9px;
left: -15px;
width: 65px;
height: 41px;
-webkit-transform: rotate(90deg);
/* transform: rotate(90deg); */
-webkit-appearance: none;
appearance: none;
}
#toggle-all input:before {
content: '»';
font-size: 28px;
color: #d9d9d9;
padding: 0 25px 7px;
}
#toggle-all input:checked:before {
color: #737373;
}
#new-todo {
padding: 15px 15px 16px 60px;
border: none;
background: rgba(0, 0, 0, 0.02);
z-index: 2;
box-shadow: none;
}
#todo-list {
margin: 0;
padding: 0;
list-style: none;
}
#todo-list li {
position: relative;
font-size: 24px;
border-top: 1px dotted #ccc;
}
#todo-list input[type='checkbox'] {
text-align: center;
width: 40px;
/* auto, since non-WebKit browsers doesn't support input styling */
height: auto;
position: absolute;
top: 0;
bottom: 0;
margin: auto 0;
-webkit-appearance: none;
/*-moz-appearance: none;*/
-ms-appearance: none;
-o-appearance: none;
appearance: none;
}
#todo-list input[type='checkbox']:after {
content: '✔';
line-height: 62px;
font-size: 20px;
color: #d9d9d9;
text-shadow: 0 -1px 0 #bfbfbf;
}
#todo-list input[type='checkbox']:checked:after {
color: #85ada7;
text-shadow: 0 1px 0 #669991;
bottom: 1px;
position: relative;
}
#todo-list input:not([type='checkbox']) {
word-break: break-word;
padding: 15px;
margin-left: 45px;
display: block;
line-height: 1.2em;
-webkit-transition: color 0.4s;
-moz-transition: color 0.4s;
-ms-transition: color 0.4s;
-o-transition: color 0.4s;
transition: color 0.4s;
}
#todo-list li .destroy {
outline: none;
background-color: transparent;
display: none;
position: absolute;
top: 0;
right: 10px;
bottom: 0;
width: 40px;
height: 40px;
margin: auto 0;
font-size: 22px;
color: #a88a8a;
-webkit-transition: all 0.2s;
-moz-transition: all 0.2s;
-ms-transition: all 0.2s;
-o-transition: all 0.2s;
transition: all 0.2s;
}
#todo-list li .destroy:hover {
text-shadow: 0 0 1px #000,
0 0 10px rgba(199, 107, 107, 0.8);
-webkit-transform: scale(1.3);
-moz-transform: scale(1.3);
-ms-transform: scale(1.3);
-o-transform: scale(1.3);
transform: scale(1.3);
}
#todo-list li .destroy:after {
content: '✖';
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list .sapUiRrNoData,
#todo-list .sapUiRrPtb,
#todo-list .sapUiRrFtr {
display: none;
}
#footer {
color: #777;
padding: 0 15px;
position: absolute;
right: 0;
bottom: -31px;
left: 0;
height: 20px;
z-index: -1;
text-align: center;
}
#footer:before {
content: '';
position: absolute;
right: 0;
bottom: 31px;
left: 0;
height: 50px;
z-index: -1;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.3),
0 6px 0 -3px rgba(255, 255, 255, 0.8),
0 7px 1px -3px rgba(0, 0, 0, 0.3),
0 43px 0 -6px rgba(255, 255, 255, 0.8),
0 44px 2px -6px rgba(0, 0, 0, 0.2);
}
#footer #AllTodos, #footer #ActiveTodos, #footer #CompletedTodos {
color: #83756f;
}
#footer #clear-completed {
color: inherit;
}
#footer .sapUiHLayoutChildWrapper:nth-of-type(1) {
float: left;
text-align: left;
}
#todo-count {
vertical-align: 1px;
}
#todo-count:first-letter {
font-weight: bold;
}
#filters {
margin: 0;
padding: 0 2px 0 0;
position: absolute;
right: 0;
left: 0;
outline: none;
}
#filters .sapUiBtnStd,
#filters .sapUiBtnFoc {
background-color: transparent;
font-weight: normal;
outline: none;
padding-right: 3px;
margin-top: -1px;
}
#filters .sapUiSegButtonSelected.sapUiBtnStd,
#filters .sapUiSegButtonSelected.sapUiBtnAct.sapUiBtnFoc {
font-weight: bold;
}
#footer .sapUiHLayoutChildWrapper:nth-of-type(3) {
float: right;
}
#clear-completed {
float: right;
position: relative;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
font-size: 11px;
padding: 0 10px;
border-radius: 3px;
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2);
height: 20px;
outline: none;
}
@-moz-document url-prefix() {
#clear-completed {
top: -22px;
}
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.3);
}
#info {
margin: 65px auto 0;
color: #a6a6a6;
font-size: 12px;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
text-align: center;
}
#info a {
color: inherit;
}
<!doctype html>
<html lang="en" data-framework="sapui5">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>SAPUI5 • TodoMVC</title>
<link href="css/base.css" rel="stylesheet">
</head>
<body role="application">
<section id="todoapp">
<header id="header">
<h1>todos</h1>
</header>
<section id="main"></section>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Written by Harald Schubert</p>
<p>Part of <a href="http://todomvc.com/">TodoMVC</a></p>
</footer>
<script
src="https://sapui5.netweaver.ondemand.com/resources/sap-ui-core.js"
id="sap-ui-bootstrap"
data-sap-ui-libs="sap.ui.commons,sap.ui.ux3,sap.ui.table"
data-sap-ui-theme="base">
</script>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="js/app.js"></script>
</body>
</html>
/*global jQuery, sap */
/*jshint unused:false */
(function () {
'use strict';
var oRootView;
jQuery.sap.registerModulePath('todo', 'js/todo');
// build the application root view and place on page
oRootView = sap.ui.view({
type: sap.ui.core.mvc.ViewType.JS,
id: 'todoView',
viewName: 'todo.Todo'
});
oRootView.placeAt('main');
})();
/*global jQuery, sap */
/*jshint unused:false */
/*
* A text field that supports placeholder values and autofocus
*/
(function () {
'use strict';
jQuery.sap.declare('todo.SmartTextField');
jQuery.sap.require('sap.ui.core.Core', 'sap.ui.commons.TextField');
sap.ui.commons.TextField.extend('todo.SmartTextField', {
metadata: {
properties: {
placeholder: 'string',
autofocus: 'boolean',
strongediting: 'boolean'
}
},
renderer: {
renderInnerAttributes: function (oRm, oTextField) {
if (oTextField.getProperty('placeholder')) {
oRm.writeAttributeEscaped('placeholder', oTextField
.getPlaceholder());
}
}
},
onAfterRendering: function (e) {
var $domRef = this.$();
if (this.getProperty('autofocus')) {
$domRef.focus();
}
if (this.getProperty('strongediting')) {
this.setEditable(false);
this.attachBrowserEvent('dblclick', function (e) {
var $domRef = this.$();
this.setEditable(true);
$domRef.get(0).selectionStart = $domRef.get(0).selectionEnd = $domRef.val().length;
});
this.attachChange(function () {
this.setEditable(false);
});
}
},
onfocusout: function (e) {
if (this.getProperty('strongediting')) {
if (!this.getEditable()) {
return;
}
this.setEditable(false);
this.getModel().updateBindings(true);
}
}
});
})();
/*global jQuery, sap, todo */
/*jshint unused:false */
/*
* Performs no UI logic and has therefore has no references to UI controls.
* Accesses and modifies model and relies on data binding to inform UI about changes.
*/
(function () {
'use strict';
jQuery.sap.require('todo.TodoPersistency');
sap.ui.controller('todo.Todo', {
// Stores todos permanently via HTML5 localStorage
store: new todo.TodoPersistency('todos'),
// Stores todos for the duration of the session
model: null,
// Retrieve todos from store and initialize model
onInit: function () {
var data = null;
if (this.store.isEmpty()) {
data = this.store.set({
todos: []
}).get();
} else {
data = this.store.get();
}
this.model = new sap.ui.model.json.JSONModel(data);
this.getView().setModel(this.model);
},
// Create a new todo
createTodo: function (todo) {
todo = todo.trim();
if (todo.length === 0) {
return;
}
this.model.setProperty('/todos/', this.model.getProperty('/todos/')
.push({
id: jQuery.sap.uid(),
done: false,
text: todo
}));
this.store.set(this.model.getData());
this.model.updateBindings(true);
},
// Clear todo
clearTodo: function (todo) {
var todos = this.model.getProperty('/todos/');
for (var i = todos.length - 1; i >= 0; i--) {
if (todos[i].id === todo.getProperty('id')) {
todos.splice(i, 1);
}
}
this.model.setProperty('/todos/', todos);
this.store.set(this.model.getData());
this.model.updateBindings(true);
},
// Clear all completed todos
clearCompletedTodos: function () {
var todos = this.model.getProperty('/todos/');
for (var i = todos.length - 1; i >= 0; i--) {
if (todos[i].done === true) {
todos.splice(i, 1);
}
}
this.model.setProperty('/todos/', todos);
this.store.set(this.model.getData());
this.model.updateBindings(true);
},
// Complete / reopen all todos
toggleAll: function () {
var todos = this.model.getProperty('/todos/');
var hasOpenTodos = todos.some(function (element, index, array) {
return element.done === false;
});
todos.forEach(function (todo) {
todo.done = hasOpenTodos;
});
this.store.set(this.model.getData());
this.model.updateBindings(true);
},
// Complete / reopen a todo
todoToggled: function (todo) {
this.store.set(this.model.getData());
this.model.updateBindings(true);
},
// Rename a todo
todoRenamed: function (todo) {
var text = todo.getProperty('text').trim();
if (text.length === 0) {
this.clearTodo(todo);
} else {
todo.getModel().setProperty(todo.getPath() + '/text', text);
this.store.set(this.model.getData());
this.model.updateBindings(true);
}
},
// Change model filter based on selection
todosSelected: function (selectionMode) {
if (selectionMode === 'AllTodos') {
this.getView().changeSelection([]);
} else if (selectionMode === 'ActiveTodos') {
this.getView().changeSelection(
[new sap.ui.model.Filter('done',
sap.ui.model.FilterOperator.EQ, false)]);
} else if (selectionMode === 'CompletedTodos') {
this.getView().changeSelection(
[new sap.ui.model.Filter('done',
sap.ui.model.FilterOperator.EQ, true)]);
}
}
});
})();
/*global jQuery, sap, todo, $ */
/*jshint unused:false */
/*
* Does all UI-related things like creating controls, data binding configuration,
* setting up callbacks, etc. Does not perform any business logic.
*/
(function () {
'use strict';
jQuery.sap.require('todo.SmartTextField');
jQuery.sap.require('todo.formatters');
sap.ui.jsview('todo.Todo', {
getControllerName: function () {
return 'todo.Todo';
},
controls: [],
repeater: false,
createContent: function (oController) {
var toggleAll, newTodo, todosRepeater, completedDataTemplate, todoTemplate, todoCount,
todosSelection, clearCompleted, todosFooter;
// Toggle button to mark all todos as completed / open
toggleAll = new sap.ui.commons.CheckBox({
id: 'toggle-all',
checked: {
path: '/todos/',
formatter: todo.formatters.allCompletedTodosFormatter
},
visible: {
path: '/todos/',
formatter: todo.formatters.isArrayNonEmptyFormatter
}
}).attachChange(function () {
oController.toggleAll();
});
this.controls.push(toggleAll);
// Text field for entering a new todo
newTodo = new todo.SmartTextField('new-todo', {
placeholder: 'What needs to be done?',
// Don't autofocus in case of MSIE and Opera as both hide placeholder on focus
autofocus: !$.browser.msie && !$.browser.opera
}).attachChange(function () {
oController.createTodo(this.getProperty('value'));
this.setValue('');
}).addStyleClass('create-todo');
this.controls.push(newTodo);
// Row repeater that will hold our todos
todosRepeater = new sap.ui.commons.RowRepeater('todo-list', {
design: sap.ui.commons.RowRepeaterDesign.Transparent,
numberOfRows: 100
});
this.repeater = todosRepeater;
// Completed flag that is later bound to the done status of a todo
// We attach this to each text field and write it to the DOM as a data-*
// attribute; this way, we can refer to it in our stylesheet
completedDataTemplate = new sap.ui.core.CustomData({
key: 'completed',
value: {
path: 'done',
formatter: todo.formatters.booleanToStringFormatter
},
writeToDom: true
});
// A template used by the row repeater to render a todo
todoTemplate = new sap.ui.commons.layout.HorizontalLayout({
content: [new sap.ui.commons.CheckBox({
checked: '{done}'
}).attachChange(function () {
oController.todoToggled(this.getBindingContext());
}), new todo.SmartTextField({
value: '{text}',
strongediting: true
}).attachBrowserEvent('dblclick', function (e) {
$('.destroy').css('display', 'none');
}).attachChange(function () {
oController.todoRenamed(this.getBindingContext());
}).addStyleClass('todo').addCustomData(completedDataTemplate),
new sap.ui.commons.Button({
lite: true,
text: ''
}).addStyleClass('destroy').attachPress(function () {
oController.clearTodo(this.getBindingContext());
})]
});
// Helper function to rebind the aggregation with different filters
todosRepeater.rebindAggregation = function (filters) {
this.unbindRows();
this.bindRows('/todos/', todoTemplate, null, filters);
};
// Initially, we don't filter any todos
todosRepeater.rebindAggregation([]);
this.controls.push(todosRepeater);
// Counts open todos
todoCount = new sap.ui.commons.TextView('todo-count', {
text: {
path: '/todos/',
formatter: todo.formatters.openTodoCountFormatter
}
});
// Allows selecting what todos to show
todosSelection = new sap.ui.commons.SegmentedButton('filters', {
id: 'TodosSelection',
buttons: [new sap.ui.commons.Button({
id: 'AllTodos',
lite: true,
text: 'All'
}), new sap.ui.commons.Button({
id: 'ActiveTodos',
lite: true,
text: 'Active'
}), new sap.ui.commons.Button({
id: 'CompletedTodos',
lite: true,
text: 'Completed'
})]
}).attachSelect(function (e) {
oController.todosSelected(e.getParameters().selectedButtonId);
});
todosSelection.setSelectedButton('AllTodos');
// Button to clear all completed todos
clearCompleted = new sap.ui.commons.Button({
id: 'clear-completed',
lite: true,
text: {
path: '/todos/',
formatter: todo.formatters.completedTodoCountFormatter
},
visible: {
path: '/todos/',
formatter: todo.formatters.hasCompletedTodosFormatter
}
}).attachPress(function () {
oController.clearCompletedTodos();
});
todosFooter = new sap.ui.commons.layout.HorizontalLayout('footer', {
content: [todoCount, todosSelection, clearCompleted],
visible: {
path: '/todos/',
formatter: todo.formatters.isArrayNonEmptyFormatter
}
});
this.controls.push(todosFooter);
return this.controls;
},
changeSelection: function (filters) {
this.repeater.rebindAggregation(filters);
}
});
})();
/*global jQuery, todo */
/*jshint unused:false */
(function () {
'use strict';
jQuery.sap.declare('todo.TodoPersistency');
todo.TodoPersistency = function (aName) {
this.name = aName;
};
todo.TodoPersistency.prototype = (function () {
var storage = window.localStorage;
return {
get: function () {
return JSON.parse(storage.getItem(this.name));
},
set: function (data) {
storage.setItem(this.name, JSON.stringify(data));
return this; // for method chaining
},
remove: function () {
storage.removeItem(this.name);
return this; // for method chaining
},
isEmpty: function () {
return !(this.get());
}
};
}());
})();
/*global jQuery, todo */
/*jshint unused:false */
/*
* Formatters used for data binding.
*/
(function () {
'use strict';
jQuery.sap.declare('todo.formatters');
todo.formatters = {
// Returns whether all todos are completed
allCompletedTodosFormatter: function (aTodos) {
return !(aTodos.some(function (element, index, array) {
return element.done === false;
}));
},
// Converts booleans to strings
booleanToStringFormatter: function (value) {
if (value === true) {
return 'true';
}
return 'false';
},
// Counts the number of closed todos
completedTodoCountFormatter: function (aTodos) {
var numberOfCompletedItems = 0;
aTodos.forEach(function (todo) {
if (todo.done === true) {
numberOfCompletedItems++;
}
});
return 'Clear completed (' + numberOfCompletedItems + ')';
},
// Returns whether a completed todo is available
hasCompletedTodosFormatter: function (aTodos) {
return aTodos.some(function (element, index, array) {
return element.done === true;
});
},
// Returns whether a an array has elements
isArrayNonEmptyFormatter: function (aTodos) {
return aTodos.length > 0;
},
// Counts the number of open todos
openTodoCountFormatter: function (aTodos) {
var numberOfOpenItems = 0;
aTodos.forEach(function (todo) {
if (todo.done === false) {
numberOfOpenItems++;
}
});
return numberOfOpenItems === 1 ? '1 item left' : numberOfOpenItems + ' items left';
}
};
})();
......@@ -79,6 +79,7 @@ We also have a number of in-progress applications in Labs:
- [DeftJS](http://deftjs.org/)
- [Aria Templates](http://ariatemplates.com/)
- [Enyo + Backbone.js](http://enyojs.com/)
- [SAPUI5](http://scn.sap.com/community/developer-center/front-end)
## Live demos
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment