Commit 224a0cc0 authored by James Thomas's avatar James Thomas

Final changes to merge dojo example with new template & spec

parent 4e5a65bb
#clear-completed, #footer, #main {
#clear-completed, #footer, #main,
.plural {
display: none;
}
#todoapp.todos_selected #clear-completed,
#todoapp.todos_present #footer,
#todoapp.todos_present #main {
#todoapp.todos_present #main,
.multiple .plural {
display: inherit;
}
......
define(
//begin v1.x content
{
"dateFormat-medium": "MMM d, y G",
"dateFormatItem-MMMEd": "E, MMM d",
"dateFormatItem-MEd": "E, M/d",
"dateFormatItem-yMEd": "EEE, M/d/y G",
"dateFormatItem-Hm": "HH:mm",
"dateFormatItem-y": "y G",
"timeFormat-full": "h:mm:ss a zzzz",
"dateFormatItem-hm": "h:mm a",
"dateFormatItem-Md": "M/d",
"months-standAlone-narrow": [
"J",
"F",
"M",
"A",
"M",
"J",
"J",
"A",
"S",
"O",
"N",
"D"
],
"dateFormatItem-EEEd": "d EEE",
"dateFormatItem-M": "L",
"days-standAlone-narrow": [
"S",
"M",
"T",
"W",
"T",
"F",
"S"
],
"dateFormatItem-yQQQ": "QQQ y G",
"timeFormat-medium": "h:mm:ss a",
"dateFormatItem-Hms": "HH:mm:ss",
"dateFormat-long": "MMMM d, y G",
"dateFormatItem-ms": "mm:ss",
"dateFormat-short": "M/d/yy G",
"dateFormatItem-yMMMEd": "EEE, MMM d, y G",
"months-format-wide": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"dateFormatItem-d": "d",
"dateFormatItem-yM": "M/y G",
"timeFormat-short": "h:mm a",
"months-format-abbr": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"timeFormat-long": "h:mm:ss a z",
"days-format-wide": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"dateFormatItem-hms": "h:mm:ss a",
"dateFormatItem-yQ": "Q y G",
"dateFormatItem-MMM": "LLL",
"dateFormatItem-yMMM": "MMM y G",
"quarters-format-wide": [
"1st quarter",
"2nd quarter",
"3rd quarter",
"4th quarter"
],
"dateFormat-full": "EEEE, MMMM d, y G",
"dateFormatItem-MMMd": "MMM d",
"days-format-abbr": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
]
}
//end v1.x content
);
\ No newline at end of file
define(
//begin v1.x content
{
"HKD_displayName": "Hong Kong Dollar",
"CHF_displayName": "Swiss Franc",
"JPY_symbol": "¥",
"CAD_displayName": "Canadian Dollar",
"CNY_displayName": "Chinese Yuan",
"USD_symbol": "$",
"AUD_displayName": "Australian Dollar",
"JPY_displayName": "Japanese Yen",
"USD_displayName": "US Dollar",
"GBP_displayName": "British Pound Sterling",
"EUR_displayName": "Euro"
}
//end v1.x content
);
\ No newline at end of file
define(
//begin v1.x content
{
"dateFormatItem-yM": "M/y",
"field-dayperiod": "AM/PM",
"dateFormatItem-yQ": "Q y",
"dayPeriods-format-wide-pm": "PM",
"field-minute": "Minute",
"eraNames": [
"Before Christ",
"Anno Domini"
],
"dateFormatItem-MMMEd": "E, MMM d",
"dateTimeFormat-full": "{1} {0}",
"field-day-relative+-1": "Yesterday",
"field-weekday": "Day of the Week",
"dateFormatItem-hms": "h:mm:ss a",
"dateFormatItem-yQQQ": "QQQ y",
"days-standAlone-wide": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"dateFormatItem-MMM": "LLL",
"months-standAlone-narrow": [
"J",
"F",
"M",
"A",
"M",
"J",
"J",
"A",
"S",
"O",
"N",
"D"
],
"dateTimeFormat-short": "{1} {0}",
"field-era": "Era",
"field-hour": "Hour",
"dayPeriods-format-wide-am": "AM",
"dateTimeFormat-medium": "{1} {0}",
"dateFormatItem-y": "y",
"timeFormat-full": "h:mm:ss a zzzz",
"months-standAlone-abbr": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"dateFormatItem-yMMM": "MMM y",
"field-day-relative+0": "Today",
"field-day-relative+1": "Tomorrow",
"days-standAlone-narrow": [
"S",
"M",
"T",
"W",
"T",
"F",
"S"
],
"eraAbbr": [
"BC",
"AD"
],
"dateFormat-long": "MMMM d, y",
"timeFormat-medium": "h:mm:ss a",
"dateFormatItem-EEEd": "d EEE",
"field-zone": "Zone",
"dateFormatItem-Hm": "HH:mm",
"dateFormat-medium": "MMM d, y",
"dateFormatItem-Hms": "HH:mm:ss",
"quarters-standAlone-wide": [
"1st quarter",
"2nd quarter",
"3rd quarter",
"4th quarter"
],
"dateFormatItem-ms": "mm:ss",
"field-year": "Year",
"quarters-standAlone-narrow": [
"1",
"2",
"3",
"4"
],
"dateTimeFormat-long": "{1} {0}",
"field-week": "Week",
"months-standAlone-wide": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"dateFormatItem-MMMd": "MMM d",
"timeFormat-long": "h:mm:ss a z",
"months-format-abbr": [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec"
],
"dayPeriods-format-wide-noon": "noon",
"timeFormat-short": "h:mm a",
"field-month": "Month",
"quarters-format-abbr": [
"Q1",
"Q2",
"Q3",
"Q4"
],
"days-format-abbr": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"dateFormatItem-M": "L",
"days-format-narrow": [
"S",
"M",
"T",
"W",
"T",
"F",
"S"
],
"field-second": "Second",
"field-day": "Day",
"dateFormatItem-MEd": "E, M/d",
"months-format-narrow": [
"J",
"F",
"M",
"A",
"M",
"J",
"J",
"A",
"S",
"O",
"N",
"D"
],
"dateFormatItem-hm": "h:mm a",
"days-standAlone-abbr": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"dateFormat-short": "M/d/yy",
"dateFormatItem-yMMMEd": "EEE, MMM d, y",
"dateFormat-full": "EEEE, MMMM d, y",
"dateFormatItem-Md": "M/d",
"dateFormatItem-yMEd": "EEE, M/d/y",
"months-format-wide": [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
],
"dateFormatItem-d": "d",
"quarters-format-wide": [
"1st quarter",
"2nd quarter",
"3rd quarter",
"4th quarter"
],
"days-format-wide": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
],
"eraNarrow": [
"B",
"A"
]
}
//end v1.x content
);
\ No newline at end of file
define(
//begin v1.x content
{
"dateFormatItem-yM": "M/y",
"dateFormatItem-yyyyMMMEd": "EEE, MMM d, y G",
"dateFormatItem-yQ": "Q y",
"eraNames": [
"AH"
],
"dateFormatItem-MMMEd": "E, MMM d",
"dateFormatItem-hms": "h:mm:ss a",
"dateFormatItem-yQQQ": "QQQ y",
"dateFormatItem-MMM": "LLL",
"months-standAlone-narrow": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12"
],
"timeFormat-full": "h:mm:ss a zzzz",
"dateFormatItem-yyyy": "y G",
"months-standAlone-abbr": [
"Muh.",
"Saf.",
"Rab. I",
"Rab. II",
"Jum. I",
"Jum. II",
"Raj.",
"Sha.",
"Ram.",
"Shaw.",
"Dhuʻl-Q.",
"Dhuʻl-H."
],
"dateFormatItem-yMMM": "MMM y",
"days-standAlone-narrow": [
"S",
"M",
"T",
"W",
"T",
"F",
"S"
],
"eraAbbr": [
"AH"
],
"dateFormat-long": "MMMM d, y G",
"timeFormat-medium": "h:mm:ss a",
"dateFormatItem-EEEd": "d EEE",
"dateFormatItem-Hm": "HH:mm",
"dateFormat-medium": "MMM d, y G",
"dateFormatItem-Hms": "HH:mm:ss",
"dateFormatItem-ms": "mm:ss",
"months-standAlone-wide": [
"Muharram",
"Safar",
"Rabiʻ I",
"Rabiʻ II",
"Jumada I",
"Jumada II",
"Rajab",
"Shaʻban",
"Ramadan",
"Shawwal",
"Dhuʻl-Qiʻdah",
"Dhuʻl-Hijjah"
],
"dateFormatItem-yyyyMEd": "EEE, M/d/y G",
"dateFormatItem-MMMd": "MMM d",
"timeFormat-long": "h:mm:ss a z",
"months-format-abbr": [
"Muh.",
"Saf.",
"Rab. I",
"Rab. II",
"Jum. I",
"Jum. II",
"Raj.",
"Sha.",
"Ram.",
"Shaw.",
"Dhuʻl-Q.",
"Dhuʻl-H."
],
"timeFormat-short": "h:mm a",
"days-format-abbr": [
"Sun",
"Mon",
"Tue",
"Wed",
"Thu",
"Fri",
"Sat"
],
"dateFormatItem-M": "L",
"dateFormatItem-yyyyQQQ": "QQQ y G",
"dateFormatItem-MEd": "E, M/d",
"months-format-narrow": [
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
"10",
"11",
"12"
],
"dateFormatItem-hm": "h:mm a",
"dateFormat-short": "M/d/yy G",
"dateFormatItem-yyyyM": "M/y G",
"dateFormatItem-yMMMEd": "EEE, MMM d, y",
"dateFormat-full": "EEEE, MMMM d, y G",
"dateFormatItem-Md": "M/d",
"dateFormatItem-yyyyQ": "Q y G",
"dateFormatItem-yMEd": "EEE, M/d/y",
"months-format-wide": [
"Muharram",
"Safar",
"Rabiʻ I",
"Rabiʻ II",
"Jumada I",
"Jumada II",
"Rajab",
"Shaʻban",
"Ramadan",
"Shawwal",
"Dhuʻl-Qiʻdah",
"Dhuʻl-Hijjah"
],
"dateFormatItem-yyyyMMM": "MMM y G",
"dateFormatItem-d": "d",
"quarters-format-wide": [
"1st quarter",
"2nd quarter",
"3rd quarter",
"4th quarter"
],
"eraNarrow": [
"AH"
],
"days-format-wide": [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
]
}
//end v1.x content
);
\ No newline at end of file
......@@ -11,10 +11,10 @@
<ul id="todo-list" data-dojo-attach-point="todo_list" data-dojo-type="dojox.mvc.Repeat" data-dojo-props="ref: this.model.todos, exprchar: '#'">
<li data-dojo-type="dojox.mvc.Group" data-dojo-props="ref: '#{this.index}'">
<div class="view">
<label class="dijitInline inline_edit" data-dojo-type="dijit.InlineEditBox"
data-dojo-props='ref: "todo_text", editor:"dijit.form.TextBox", autosave:true'></label>
<label class="dijitInline inline_edit" data-dojo-type="todo.form.InlineEditBox"
data-dojo-props='ref: "title", editor:"dijit.form.TextBox", autosave:true'></label>
<input class="toggle" type="checkbox" data-dojo-type="todo.form.CheckBox" data-dojo-props='ref: "isDone"'>
<input class="toggle" type="checkbox" data-dojo-type="todo.form.CheckBox" data-dojo-props='ref: "completed"'>
<button class="destroy" data-model-id="#{this.index}">
</button>
</div>
......@@ -27,7 +27,7 @@
<strong>
<span data-dojo-type="dojox.mvc.Output" data-dojo-props="ref: this.model.incomplete" class="number"></span>
</strong>
<span class="word">items</span> left.
<span class="word">item<span class="plural">s</span></span> left.
</span>
<!-- Remove this if you don't implement routing -->
<ul id="filters">
......
......@@ -6,14 +6,14 @@ define(["dojo/_base/declare",
// Parent classes
"dijit/_WidgetBase", "dijit/_TemplatedMixin", "dijit/_WidgetsInTemplateMixin",
// General application modules
"dojo/_base/lang", "dojo/_base/event", "dojo/on", "dojo/dom-class", "dojo/dom-attr", "dojo/query",
"dojo/keys", "dojox/mvc", "dojo/hash", "dojo/_base/connect", "todo/model/TodoModel",
"dojo/_base/lang", "dojo/_base/event", "dojo/on", "dojo/dom-class", "dojo/dom-attr", "dojo/query", "dojo/string",
"dijit/_base/manager", "dojo/keys", "dojox/mvc", "dojo/hash", "dojo/_base/connect", "todo/model/TodoModel",
// Widget template
"dojo/text!./app.html",
// Template Widgets
"dijit/InlineEditBox", "todo/form/CheckBox", "dojox/mvc/Group", "dojox/mvc/Repeat", "dojox/mvc/Output"],
"todo/form/InlineEditBox", "todo/form/CheckBox", "dojox/mvc/Group", "dojox/mvc/Repeat", "dojox/mvc/Output"],
function(declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin, lang, _event, on, domClass, domAttr,
query, keys, mvc, hash, connect, TodoModel, template) {
query, str, manager, keys, mvc, hash, connect, TodoModel, template) {
return declare("todo.app", [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
/** Widget template HTML string */
......@@ -60,6 +60,7 @@ define(["dojo/_base/declare",
*/
postCreate: function () {
on(this.domNode, ".destroy:click", lang.hitch(this, "onRemove"));
on(this.domNode, ".view:dblclick", lang.hitch(this, "onEdit"));
this.onItemStatusUpdate();
},
......@@ -87,7 +88,7 @@ define(["dojo/_base/declare",
* index and, instead, decrement the total item count.
*/
while (idx < len) {
if (this.model.todos[idx].isDone.value) {
if (this.model.todos[idx].completed.value) {
this.model.todos.remove(idx);
len--;
continue;
......@@ -100,9 +101,9 @@ define(["dojo/_base/declare",
* Add new a new todo item as the last element
* in the parent model.
*/
addToModel: function (content, isDone) {
addToModel: function (content, completed) {
var insert = mvc.newStatefulModel({
data: {todo_text: content, isDone: isDone}
data: {title: content, completed: completed}
});
this.model.todos.add(this.model.todos.length, insert);
......@@ -118,9 +119,12 @@ define(["dojo/_base/declare",
length = this.model.todos.get("length");
domClass.toggle(this.domNode, "todos_selected", completed > 0);
domClass.toggle(this.domNode, "multiple", completed > 1);
domClass.toggle(this.domNode, "todos_present", length);
domAttr.set(this.mark_all, "checked", length && length === completed);
setTimeout(lang.hitch(this, "onHashChange", hash()));
},
/**
......@@ -132,7 +136,7 @@ define(["dojo/_base/declare",
var checked = this.mark_all.checked;
for(var i = 0, len = this.model.todos.length; i < len; i++) {
this.model.todos[i].isDone.set("value", checked);
this.model.todos[i].completed.set("value", checked);
}
},
......@@ -142,7 +146,10 @@ define(["dojo/_base/declare",
* text value as new todo item in the model.
*/
onKeyPress: function (event) {
if (event.keyCode !== keys.ENTER) return;
if (event.keyCode !== keys.ENTER ||
!str.trim(event.target.value).length) {
return;
}
this.addToModel(event.target.value, false);
event.target.value = "";
......@@ -153,11 +160,21 @@ define(["dojo/_base/declare",
* Event handler when user has clicked to
* remove a todo item, just remove it from the
* model using the item identifier.
**/
*/
onRemove: function (event) {
this.model.todos.remove(domAttr.get(event.target, "data-model-id"));
},
/**
* Whenever the user double clicks the item label,
* set inline edit box to true.
*/
onEdit: function (event) {
query(".inline_edit", event.target).forEach(function (inline_edit) {
manager.byNode(inline_edit).edit();
});
},
/**
* When the URI's hash value changes, modify the
* displayed list items to show either completed,
......@@ -169,7 +186,7 @@ define(["dojo/_base/declare",
(hash === this.ACTIVE? true : null));
query("#todo-list > li").forEach(lang.hitch(this, function (item, idx) {
var done = this.model.todos[idx].isDone.get("value");
var done = this.model.todos[idx].completed.get("value");
domClass.toggle(item, "hidden", done === showIfDone);
}));
......
/**
* Extension to the "InlineEditBox" widget to support editing on double click
* events rather than single clicks. We need to override base "postMixInProperties"
* lifecycle method where the event handlers are setup. This method is just a clone
* of that code with the modified event list.
*/
define([
"dijit/InlineEditBox",
"dojo/_base/declare",
"dojo/_base/lang",
"dojo/dom-class"
], function (InlineEditBox, declare, lang, domClass) {
InlineEditBox._InlineEditor.prototype._onChange = function () {
if(this.inlineEditBox.autoSave && this.inlineEditBox.editing && this.enableSave()){
this._onBlur();
}
};
return declare("todo.form.InlineEditBox", InlineEditBox, {
postMixInProperties: function () {
// save pointer to original source node, since Widget nulls-out srcNodeRef
this.displayNode = this.srcNodeRef;
// connect handlers to the display node
var events = {
ondblclick: "_onClick",
onmouseover: "_onMouseOver",
onmouseout: "_onMouseOut",
onfocus: "_onMouseOver",
onblur: "_onMouseOut"
};
for(var name in events){
this.connect(this.displayNode, name, events[name]);
}
this.displayNode.setAttribute("role", "button");
if(!this.displayNode.getAttribute("tabIndex")){
this.displayNode.setAttribute("tabIndex", 0);
}
if(!this.value && !("value" in this.params)){ // "" is a good value if specified directly so check params){
this.value = lang.trim(this.renderAsHtml ? this.displayNode.innerHTML :
(this.displayNode.innerText||this.displayNode.textContent||""));
}
if(!this.value){
this.displayNode.innerHTML = this.noValueIndicator;
}
domClass.add(this.displayNode, 'dijitInlineEditBoxDisplayMode');
},
_onChange: function () {
this.inherited(arguments);
this._onBlur();
}
});
});
......@@ -7,7 +7,7 @@ define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorag
* items found in localStorage.
*/
data: {
id: "todos_dojo",
id: "todos-dojo",
todos : [],
incomplete: 0,
complete: 0
......@@ -47,9 +47,9 @@ define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorag
/**
* Bind all pre-populated todo items to update the
* total item values when the "isDone" attribute is changed.
* total item values when the "completed" attribute is changed.
*/
array.forEach(this.todos, lang.hitch(this, "bindIsDone"));
array.forEach(this.todos, lang.hitch(this, "bindItemProps"));
/**
* Whenever the "todos" array is modified, an element is added
......@@ -64,21 +64,41 @@ define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorag
* Set up binding on a todo item, so that when the
* item's checked attribute changes, we re-calculate
* the composite model attribute's value, "complete".
*
* We also need to remove any tasks with empty titles.
*/
bindIsDone: function (item) {
mvc.bindInputs([item.isDone], lang.hitch(this, "updateTotalItemsLeft"));
bindItemProps: function (item) {
mvc.bindInputs([item.completed], lang.hitch(this, "updateTotalItemsLeft"));
mvc.bindInputs([item.title], lang.hitch(window, setTimeout, lang.hitch(this, "deleteEmptyTasks")));
},
/**
* Search through current tasks list, removing all
* with empty titles.
*/
deleteEmptyTasks: function () {
var len = this.todos.length, idx = 0;
while (idx < len) {
if (!this.todos[idx].title.value.length) {
this.todos.remove(idx);
len--;
continue;
}
idx++;
}
},
/**
* When todos array is modified, we need to update the composite
* value attributes. If the modification was an addition, ensure the
* "isDone" attribute is being watched for updates.
* "completed" attribute is being watched for updates.
*/
onTodosModelChange: function (prop, oldValue, newValue) {
this.updateTotalItemsLeft();
if (typeof prop === "number" && !oldValue && newValue) {
this.bindIsDone(newValue);
this.bindItemProps(newValue);
}
},
......@@ -89,7 +109,7 @@ define(["dojo/_base/declare", "dojox/mvc/StatefulModel", "todo/store/LocalStorag
*/
updateTotalItemsLeft: function () {
this.incomplete.set("value", array.filter(this.todos, function (item) {
return item && !item.isDone.value;
return item && !item.completed.value;
}).length);
}
});
......
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