Commit 07274e75 authored by Colin Eberhardt's avatar Colin Eberhardt

Further whitespace tidyup

Fixed whitespace issues

Added routing
Fixed bug, CSS class 'done' applied to cells should have been 'completed'
parent 48e183af
#todo-count span.word { /* The CSS that is common to all TodoMVC implementations, base.css, styles the selected routing filter using the
font-weight: normal; following selector:
#filters li a.selected
In the GWT implementation, a Hyperlink widget is used for the routing filters. This widget allows you to
specify a history - and will handle the clicks accordingly. The HTML for this widget is as follows:
<div><a ...></a></div>
Where the 'div' element represents the hyperlink GWT widget. This results in the following GWT
specific style. */
#filters li div.selected a {
font-weight: bold;
} }
/* The GWT TodoMVC uses a CellList - a framework widget for rendering a list of cells - to /* The GWT TodoMVC uses a CellList - a framework widget for rendering a list of cells - to
......
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
function gwttodo(){var M='',dc='\n-',ub='" for "gwt:onLoadErrorFn"',sb='" for "gwt:onPropertyErrorFn"',Sb='"<script src=\\"',fb='"><\/script>',W='#',cc=');',Wb='-\n',ec='-><\/scr',Tb='.cache.js\\"><\/scr" + "ipt>"',Y='/',ib='//',Jb='2598AEA8366C96B57FECAE2C9CF852C2',Kb='290DF5E2344EE252BFA83EE54A18660C',Lb='46BBAD516CEA92A1558EB6AC364EDBDD',Mb='510BCB5AECF42013A6248A2D3FC4B7AE',Nb='8F467762443B9109859B7EBDAA5DDC2A',Pb=':',mb='::',Ub='<scr',eb='<script id="',pb='=',X='?',rb='Bad handler "',Gb='Cross-site hosted mode not yet implemented. See issue ',Ob='DE8E639EC5E34893D46F03386463AC34',Qb='DOMContentLoaded',gb='SCRIPT',db='__gwt_marker_gwttodo',hb='base',_='baseUrl',Q='begin',P='bootstrap',$='clear.cache.gif',ob='content',bc='document.write(',V='end',Zb='evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),',_b='evtGroup: "moduleStartup", millis:(new Date()).getTime(),',Db='gecko',Eb='gecko1_8',R='gwt.codesvr=',S='gwt.hosted=',T='gwt.hybrid',tb='gwt:onLoadErrorFn',qb='gwt:onPropertyErrorFn',nb='gwt:property',N='gwttodo',bb='gwttodo.nocache.js',lb='gwttodo::',Hb='http://code.google.com/p/google-web-toolkit/issues/detail?id=2079',Cb='ie6',Bb='ie8',Ab='ie9',Z='img',fc='ipt>',Vb='ipt><!-',Rb='loadExternalRefs',jb='meta',Yb='moduleName:"gwttodo", sessionId:window.__gwtStatsSessionId, subSystem:"startup",',U='moduleStartup',zb='msie',kb='name',wb='opera',yb='safari',ab='script',Ib='selectingPermutation',O='startup',$b='type: "end"});',ac='type: "moduleRequested"});',cb='undefined',Fb='unknown',vb='user.agent',xb='webkit',Xb='window.__gwtStatsEvent && window.__gwtStatsEvent({';var m=window,n=document,o=m.__gwtStatsEvent?function(a){return m.__gwtStatsEvent(a)}:null,p=m.__gwtStatsSessionId?m.__gwtStatsSessionId:null,q,r,s=M,t={},u=[],v=[],w=[],x=0,y,z;o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:Q});if(!m.__gwt_stylesLoaded){m.__gwt_stylesLoaded={}}if(!m.__gwt_scriptsLoaded){m.__gwt_scriptsLoaded={}}function A(){var b=false;try{var c=m.location.search;return (c.indexOf(R)!=-1||(c.indexOf(S)!=-1||m.external&&m.external.gwtOnLoad))&&c.indexOf(T)==-1}catch(a){}A=function(){return b};return b} function gwttodo(){var M='',dc='\n-',ub='" for "gwt:onLoadErrorFn"',sb='" for "gwt:onPropertyErrorFn"',Sb='"<script src=\\"',fb='"><\/script>',W='#',cc=');',Wb='-\n',ec='-><\/scr',Tb='.cache.js\\"><\/scr" + "ipt>"',Y='/',ib='//',Jb='11269AA57F495539D3888C07B9EB3B17',Kb='11502D2DBBE27FDC3BF44BACE45F84B6',Lb='28574D07C51C1139889498637093E3B0',Mb='2AC272A01A9C4D209D21D674CB52AB0C',Nb='5C490F07F777E65FD19DF9ECC16C17FB',Pb=':',mb='::',Ub='<scr',eb='<script id="',pb='=',X='?',rb='Bad handler "',Gb='Cross-site hosted mode not yet implemented. See issue ',Qb='DOMContentLoaded',Ob='F07E0067CA72074137C8A4F29F19B2C3',gb='SCRIPT',db='__gwt_marker_gwttodo',hb='base',_='baseUrl',Q='begin',P='bootstrap',$='clear.cache.gif',ob='content',bc='document.write(',V='end',Zb='evtGroup: "loadExternalRefs", millis:(new Date()).getTime(),',_b='evtGroup: "moduleStartup", millis:(new Date()).getTime(),',Db='gecko',Eb='gecko1_8',R='gwt.codesvr=',S='gwt.hosted=',T='gwt.hybrid',tb='gwt:onLoadErrorFn',qb='gwt:onPropertyErrorFn',nb='gwt:property',N='gwttodo',bb='gwttodo.nocache.js',lb='gwttodo::',Hb='http://code.google.com/p/google-web-toolkit/issues/detail?id=2079',Cb='ie6',Bb='ie8',Ab='ie9',Z='img',fc='ipt>',Vb='ipt><!-',Rb='loadExternalRefs',jb='meta',Yb='moduleName:"gwttodo", sessionId:window.__gwtStatsSessionId, subSystem:"startup",',U='moduleStartup',zb='msie',kb='name',wb='opera',yb='safari',ab='script',Ib='selectingPermutation',O='startup',$b='type: "end"});',ac='type: "moduleRequested"});',cb='undefined',Fb='unknown',vb='user.agent',xb='webkit',Xb='window.__gwtStatsEvent && window.__gwtStatsEvent({';var m=window,n=document,o=m.__gwtStatsEvent?function(a){return m.__gwtStatsEvent(a)}:null,p=m.__gwtStatsSessionId?m.__gwtStatsSessionId:null,q,r,s=M,t={},u=[],v=[],w=[],x=0,y,z;o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:Q});if(!m.__gwt_stylesLoaded){m.__gwt_stylesLoaded={}}if(!m.__gwt_scriptsLoaded){m.__gwt_scriptsLoaded={}}function A(){var b=false;try{var c=m.location.search;return (c.indexOf(R)!=-1||(c.indexOf(S)!=-1||m.external&&m.external.gwtOnLoad))&&c.indexOf(T)==-1}catch(a){}A=function(){return b};return b}
function B(){if(q&&r){q(y,N,s,x);o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:U,millis:(new Date).getTime(),type:V})}} function B(){if(q&&r){q(y,N,s,x);o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:U,millis:(new Date).getTime(),type:V})}}
function C(){function e(a){var b=a.lastIndexOf(W);if(b==-1){b=a.length}var c=a.indexOf(X);if(c==-1){c=a.length}var d=a.lastIndexOf(Y,Math.min(c,b));return d>=0?a.substring(0,d+1):M} function C(){function e(a){var b=a.lastIndexOf(W);if(b==-1){b=a.length}var c=a.indexOf(X);if(c==-1){c=a.length}var d=a.lastIndexOf(Y,Math.min(c,b));return d>=0?a.substring(0,d+1):M}
function f(a){if(a.match(/^\w+:\/\//)){}else{var b=n.createElement(Z);b.src=a+$;a=e(b.src)}return a} function f(a){if(a.match(/^\w+:\/\//)){}else{var b=n.createElement(Z);b.src=a+$;a=e(b.src)}return a}
...@@ -12,6 +12,6 @@ function D(){var b=document.getElementsByTagName(jb);for(var c=0,d=b.length;c<d; ...@@ -12,6 +12,6 @@ function D(){var b=document.getElementsByTagName(jb);for(var c=0,d=b.length;c<d;
function E(a){var b=t[a];return b==null?null:b} function E(a){var b=t[a];return b==null?null:b}
function F(a,b){var c=w;for(var d=0,e=a.length-1;d<e;++d){c=c[a[d]]||(c[a[d]]=[])}c[a[e]]=b} function F(a,b){var c=w;for(var d=0,e=a.length-1;d<e;++d){c=c[a[d]]||(c[a[d]]=[])}c[a[e]]=b}
function G(a){var b=v[a](),c=u[a];if(b in c){return b}var d=[];for(var e in c){d[c[e]]=e}if(z){z(a,d,b)}throw null} function G(a){var b=v[a](),c=u[a];if(b in c){return b}var d=[];for(var e in c){d[c[e]]=e}if(z){z(a,d,b)}throw null}
v[vb]=function(){var b=navigator.userAgent.toLowerCase();var c=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(function(){return b.indexOf(wb)!=-1}())return wb;if(function(){return b.indexOf(xb)!=-1}())return yb;if(function(){return b.indexOf(zb)!=-1&&n.documentMode>=9}())return Ab;if(function(){return b.indexOf(zb)!=-1&&n.documentMode>=8}())return Bb;if(function(){var a=/msie ([0-9]+)\.([0-9]+)/.exec(b);if(a&&a.length==3)return c(a)>=6000}())return Cb;if(function(){return b.indexOf(Db)!=-1}())return Eb;return Fb};u[vb]={gecko1_8:0,ie6:1,ie8:2,ie9:3,opera:4,safari:5};gwttodo.onScriptLoad=function(a){gwttodo.onScriptLoad=null;q=a;B()};if(A()){alert(Gb+Hb);return}D();C();o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:Ib});var H;try{F([Cb],Jb);F([yb],Kb);F([wb],Lb);F([Bb],Mb);F([Ab],Nb);F([Eb],Ob);H=w[G(vb)];var I=H.indexOf(Pb);if(I!=-1){x=Number(H.substring(I+1));H=H.substring(0,I)}}catch(a){return}var J;function K(){if(!r){r=true;B();if(n.removeEventListener){n.removeEventListener(Qb,K,false)}if(J){clearInterval(J)}}} v[vb]=function(){var b=navigator.userAgent.toLowerCase();var c=function(a){return parseInt(a[1])*1000+parseInt(a[2])};if(function(){return b.indexOf(wb)!=-1}())return wb;if(function(){return b.indexOf(xb)!=-1}())return yb;if(function(){return b.indexOf(zb)!=-1&&n.documentMode>=9}())return Ab;if(function(){return b.indexOf(zb)!=-1&&n.documentMode>=8}())return Bb;if(function(){var a=/msie ([0-9]+)\.([0-9]+)/.exec(b);if(a&&a.length==3)return c(a)>=6000}())return Cb;if(function(){return b.indexOf(Db)!=-1}())return Eb;return Fb};u[vb]={gecko1_8:0,ie6:1,ie8:2,ie9:3,opera:4,safari:5};gwttodo.onScriptLoad=function(a){gwttodo.onScriptLoad=null;q=a;B()};if(A()){alert(Gb+Hb);return}D();C();o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:Ib});var H;try{F([Bb],Jb);F([yb],Kb);F([wb],Lb);F([Eb],Mb);F([Cb],Nb);F([Ab],Ob);H=w[G(vb)];var I=H.indexOf(Pb);if(I!=-1){x=Number(H.substring(I+1));H=H.substring(0,I)}}catch(a){return}var J;function K(){if(!r){r=true;B();if(n.removeEventListener){n.removeEventListener(Qb,K,false)}if(J){clearInterval(J)}}}
if(n.addEventListener){n.addEventListener(Qb,function(){K()},false)}var J=setInterval(function(){if(/loaded|complete/.test(n.readyState)){K()}},50);o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:V});o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:Rb,millis:(new Date).getTime(),type:Q});var L=Sb+s+H+Tb;n.write(Ub+Vb+Wb+Xb+Yb+Zb+$b+Xb+Yb+_b+ac+bc+L+cc+dc+ec+fc)} if(n.addEventListener){n.addEventListener(Qb,function(){K()},false)}var J=setInterval(function(){if(/loaded|complete/.test(n.readyState)){K()}},50);o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:P,millis:(new Date).getTime(),type:V});o&&o({moduleName:N,sessionId:p,subSystem:O,evtGroup:Rb,millis:(new Date).getTime(),type:Q});var L=Sb+s+H+Tb;n.write(Ub+Vb+Wb+Xb+Yb+Zb+$b+Xb+Yb+_b+ac+bc+L+cc+dc+ec+fc)}
gwttodo(); gwttodo();
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<module rename-to='gwttodo'> <module rename-to='gwttodo'>
<!-- Inherit the core Web Toolkit stuff. --> <!-- Inherit the core Web Toolkit stuff. -->
<inherits name='com.google.gwt.user.User'/> <inherits name='com.google.gwt.user.User' />
<inherits name='com.google.gwt.json.JSON'/> <inherits name='com.google.gwt.json.JSON' />
<!-- Don't inherit any GWT styles - they're ugly! --> <!-- Don't inherit any GWT styles - they're ugly! -->
<!-- <inherits name='com.google.gwt.user.theme.clean.Clean'/>--> <!-- <inherits name='com.google.gwt.user.theme.clean.Clean'/> -->
<!-- Other module inherits --> <!-- Other module inherits -->
<!-- Specify the app entry point class. --> <!-- Specify the app entry point class. -->
<entry-point class='com.todo.client.GwtToDo'/> <entry-point class='com.todo.client.GwtToDo' />
<!-- Specify the paths for translatable code --> <!-- Specify the paths for translatable code -->
<source path='client'/> <source path='client' />
<add-linker name="xs" /> <add-linker name="xs" />
</module> </module>
...@@ -82,7 +82,7 @@ public class ToDoCell extends AbstractCell<ToDoItem> { ...@@ -82,7 +82,7 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
} else { } else {
SafeHtml rendered = SafeHtml rendered =
templates.view(value.isDone() ? templates.inputChecked() : templates.inputClear(), templates.view(value.isDone() ? templates.inputChecked() : templates.inputClear(),
SafeHtmlUtils.fromString(value.getTitle()), value.isDone() ? "listItem view done" SafeHtmlUtils.fromString(value.getTitle()), value.isDone() ? "listItem view completed"
: "listItem view", : "listItem view",
// NOTE: The addition of a timestamp here is a bit of a HACK! The problem // NOTE: The addition of a timestamp here is a bit of a HACK! The problem
// is that the CellList uses a HasDataPresenter for rendering. This class // is that the CellList uses a HasDataPresenter for rendering. This class
...@@ -158,9 +158,9 @@ public class ToDoCell extends AbstractCell<ToDoItem> { ...@@ -158,9 +158,9 @@ public class ToDoCell extends AbstractCell<ToDoItem> {
// update the 'row' style // update the 'row' style
if (input.isChecked()) { if (input.isChecked()) {
getViewRootElement(parent).addClassName("done"); getViewRootElement(parent).addClassName("completed");
} else { } else {
getViewRootElement(parent).removeClassName("done"); getViewRootElement(parent).removeClassName("completed");
} }
} else if (tagName.equals("BUTTON")) { } else if (tagName.equals("BUTTON")) {
......
...@@ -4,12 +4,15 @@ import java.util.ArrayList; ...@@ -4,12 +4,15 @@ import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONArray;
import com.google.gwt.json.client.JSONBoolean; import com.google.gwt.json.client.JSONBoolean;
import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser; import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONString;
import com.google.gwt.storage.client.Storage; import com.google.gwt.storage.client.Storage;
import com.google.gwt.user.client.History;
import com.google.gwt.view.client.AbstractDataProvider; import com.google.gwt.view.client.AbstractDataProvider;
import com.google.gwt.view.client.ListDataProvider; import com.google.gwt.view.client.ListDataProvider;
...@@ -53,6 +56,11 @@ public class ToDoPresenter { ...@@ -53,6 +56,11 @@ public class ToDoPresenter {
* Adds the handler to the events raised by the view. * Adds the handler to the events raised by the view.
*/ */
void addhandler(ViewEventHandler handler); void addhandler(ViewEventHandler handler);
/**
* Informs the view of the current routing state.
*/
void setRouting(ToDoRouting routing);
} }
/** /**
...@@ -96,10 +104,14 @@ public class ToDoPresenter { ...@@ -96,10 +104,14 @@ public class ToDoPresenter {
} }
}; };
private final ListDataProvider<ToDoItem> todos = new ListDataProvider<ToDoItem>(); private final List<ToDoItem> todos = new ArrayList<ToDoItem>();
private final ListDataProvider<ToDoItem> filteredTodos = new ListDataProvider<ToDoItem>();
private final View view; private final View view;
private ToDoRouting routing = ToDoRouting.ALL;
private boolean suppressStateChanged = false; private boolean suppressStateChanged = false;
public ToDoPresenter(View view) { public ToDoPresenter(View view) {
...@@ -107,19 +119,64 @@ public class ToDoPresenter { ...@@ -107,19 +119,64 @@ public class ToDoPresenter {
loadState(); loadState();
String initialToken = History.getToken();
routing = parseRoutingToken(initialToken);
view.addhandler(viewHandler); view.addhandler(viewHandler);
view.setDataProvider(todos); view.setDataProvider(filteredTodos);
view.setRouting(routing);
updateTaskStatistics(); updateTaskStatistics();
setupHistoryHandler();
}
/**
* Set up a the history changed handler, which provides routing.
*/
private void setupHistoryHandler() {
History.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();
routing = parseRoutingToken(historyToken);
view.setRouting(routing);
updateFilteredList();
}
});
}
/**
* Converts the string routing token into the equivalent enum value
*/
private ToDoRouting parseRoutingToken(String token ) {
if (token.equals("/active")) {
return ToDoRouting.ACTIVE;
} else if (token.equals("/completed")) {
return ToDoRouting.COMPLETED;
} else {
return ToDoRouting.ALL;
}
}
/**
* Updates the filtered list, which is rendered in the UI.
*/
private void updateFilteredList() {
filteredTodos.getList().clear();
for (ToDoItem task : todos) {
if (routing.getRoutingFunction().matches(task)) {
filteredTodos.getList().add(task);
}
}
} }
/** /**
* Computes the tasks statistics and updates the view. * Computes the tasks statistics and updates the view.
*/ */
private void updateTaskStatistics() { private void updateTaskStatistics() {
int totalTasks = todos.getList().size(); int totalTasks = todos.size();
int completeTask = 0; int completeTask = 0;
for (ToDoItem task : todos.getList()) { for (ToDoItem task : todos) {
if (task.isDone()) { if (task.isDone()) {
completeTask++; completeTask++;
} }
...@@ -132,9 +189,8 @@ public class ToDoPresenter { ...@@ -132,9 +189,8 @@ public class ToDoPresenter {
* Deletes the given task and updates statistics. * Deletes the given task and updates statistics.
*/ */
protected void deleteTask(ToDoItem toDoItem) { protected void deleteTask(ToDoItem toDoItem) {
todos.getList().remove(toDoItem); todos.remove(toDoItem);
updateTaskStatistics(); taskStateChanged();
saveState();
} }
/** /**
...@@ -148,9 +204,17 @@ public class ToDoPresenter { ...@@ -148,9 +204,17 @@ public class ToDoPresenter {
// if the item has become empty, remove it // if the item has become empty, remove it
if (toDoItem.getTitle().trim().equals("")) { if (toDoItem.getTitle().trim().equals("")) {
todos.getList().remove(toDoItem); todos.remove(toDoItem);
} }
taskStateChanged();
}
/**
* When the task state has changed, this method will update the UI and persist
*/
private void taskStateChanged() {
updateFilteredList();
updateTaskStatistics(); updateTaskStatistics();
saveState(); saveState();
} }
...@@ -162,18 +226,12 @@ public class ToDoPresenter { ...@@ -162,18 +226,12 @@ public class ToDoPresenter {
// update the completed state of each item // update the completed state of each item
suppressStateChanged = true; suppressStateChanged = true;
for (ToDoItem task : todos.getList()) { for (ToDoItem task : todos) {
task.setDone(completed); task.setDone(completed);
} }
suppressStateChanged = false; suppressStateChanged = false;
// cause the view to refresh the whole list - yes, this is a bit ugly! taskStateChanged();
List<ToDoItem> items = new ArrayList<ToDoItem>(todos.getList());
todos.getList().clear();
todos.getList().addAll(items);
updateTaskStatistics();
saveState();
} }
/** /**
...@@ -188,24 +246,24 @@ public class ToDoPresenter { ...@@ -188,24 +246,24 @@ public class ToDoPresenter {
ToDoItem toDoItem = new ToDoItem(taskTitle, this); ToDoItem toDoItem = new ToDoItem(taskTitle, this);
view.clearTaskText(); view.clearTaskText();
todos.getList().add(toDoItem); todos.add(toDoItem);
updateTaskStatistics();
saveState(); taskStateChanged();
} }
/** /**
* Clears completed tasks and updates the view. * Clears completed tasks and updates the view.
*/ */
private void clearCompletedTasks() { private void clearCompletedTasks() {
Iterator<ToDoItem> iterator = todos.getList().iterator(); Iterator<ToDoItem> iterator = todos.iterator();
while (iterator.hasNext()) { while (iterator.hasNext()) {
ToDoItem item = iterator.next(); ToDoItem item = iterator.next();
if (item.isDone()) { if (item.isDone()) {
iterator.remove(); iterator.remove();
} }
} }
updateTaskStatistics();
saveState(); taskStateChanged();
} }
/** /**
...@@ -217,8 +275,8 @@ public class ToDoPresenter { ...@@ -217,8 +275,8 @@ public class ToDoPresenter {
// JSON encode the items // JSON encode the items
JSONArray todoItems = new JSONArray(); JSONArray todoItems = new JSONArray();
for (int i = 0; i < todos.getList().size(); i++) { for (int i = 0; i < todos.size(); i++) {
ToDoItem toDoItem = todos.getList().get(i); ToDoItem toDoItem = todos.get(i);
JSONObject jsonObject = new JSONObject(); JSONObject jsonObject = new JSONObject();
jsonObject.put("task", new JSONString(toDoItem.getTitle())); jsonObject.put("task", new JSONString(toDoItem.getTitle()));
jsonObject.put("complete", JSONBoolean.getInstance(toDoItem.isDone())); jsonObject.put("complete", JSONBoolean.getInstance(toDoItem.isDone()));
...@@ -245,12 +303,14 @@ public class ToDoPresenter { ...@@ -245,12 +303,14 @@ public class ToDoPresenter {
String task = jsonObject.get("task").isString().stringValue(); String task = jsonObject.get("task").isString().stringValue();
boolean completed = jsonObject.get("complete").isBoolean().booleanValue(); boolean completed = jsonObject.get("complete").isBoolean().booleanValue();
// add a new item to our list // add a new item to our list
todos.getList().add(new ToDoItem(task, completed, this)); todos.add(new ToDoItem(task, completed, this));
} }
} catch (Exception e) { } catch (Exception e) {
} }
} }
updateFilteredList();
} }
} }
package com.todo.client;
public enum ToDoRouting {
/**
* Displays all todo items
*/
ALL(new ToDoRoutingAll()),
/**
* Displays active todo items - i.e. those that have not been done
*/
ACTIVE(new ToDoRoutingActive()),
/**
* Displays completed todo items - i.e. those that have been done
*/
COMPLETED(new ToDoRoutingCompleted());
private final ToDoRoutingFunction routingFunction;
private ToDoRouting(ToDoRoutingFunction routingFunction) {
this.routingFunction = routingFunction;
}
public ToDoRoutingFunction getRoutingFunction() {
return routingFunction;
}
}
package com.todo.client;
/**
* A routing function that matches active todo items.
*/
public class ToDoRoutingActive implements ToDoRoutingFunction {
@Override
public boolean matches(ToDoItem item) {
return !item.isDone();
}
}
package com.todo.client;
/**
* A routing function that matches all todo items.
*/
public class ToDoRoutingAll implements ToDoRoutingFunction {
@Override
public boolean matches(ToDoItem item) {
return true;
}
}
package com.todo.client;
/**
* A routing function that matches completed todo items.
*/
public class ToDoRoutingCompleted implements ToDoRoutingFunction {
@Override
public boolean matches(ToDoItem item) {
return item.isDone();
}
}
package com.todo.client;
/**
* A routing function filters todo items, based on some criteria
*/
public interface ToDoRoutingFunction {
/**
* Determines whether the given todo item matches this routing function.
*/
boolean matches(ToDoItem item);
}
...@@ -18,6 +18,7 @@ import com.google.gwt.user.client.Event; ...@@ -18,6 +18,7 @@ import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener; import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.view.client.AbstractDataProvider; import com.google.gwt.view.client.AbstractDataProvider;
import com.todo.client.ToDoPresenter.ViewEventHandler; import com.todo.client.ToDoPresenter.ViewEventHandler;
...@@ -33,6 +34,15 @@ public class ToDoView extends Composite implements ToDoPresenter.View { ...@@ -33,6 +34,15 @@ public class ToDoView extends Composite implements ToDoPresenter.View {
interface ToDoViewUiBinder extends UiBinder<Widget, ToDoView> { interface ToDoViewUiBinder extends UiBinder<Widget, ToDoView> {
} }
@UiField
Hyperlink routingAll;
@UiField
Hyperlink routingActive;
@UiField
Hyperlink routingCompleted;
@UiField @UiField
TextBoxWithPlaceholder taskText; TextBoxWithPlaceholder taskText;
...@@ -143,6 +153,22 @@ public class ToDoView extends Composite implements ToDoPresenter.View { ...@@ -143,6 +153,22 @@ public class ToDoView extends Composite implements ToDoPresenter.View {
toggleAll.setChecked(totalTasks == completedTasks); toggleAll.setChecked(totalTasks == completedTasks);
} }
@Override
public void setRouting(ToDoRouting routing) {
selectRoutingHyperlink(routingAll, ToDoRouting.ALL, routing);
selectRoutingHyperlink(routingActive, ToDoRouting.ACTIVE, routing);
selectRoutingHyperlink(routingCompleted, ToDoRouting.COMPLETED, routing);
}
private void selectRoutingHyperlink(Hyperlink hyperlink, ToDoRouting currentRoutingState,
ToDoRouting routingStateToMatch) {
if (currentRoutingState == routingStateToMatch) {
hyperlink.getElement().addClassName("selected");
} else {
hyperlink.getElement().removeClassName("selected");
}
}
private void hideElement(Element element, boolean hide) { private void hideElement(Element element, boolean hide) {
if (hide) { if (hide) {
element.setAttribute("style", "display:none;"); element.setAttribute("style", "display:none;");
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder" <ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:cv="urn:import:com.google.gwt.user.cellview.client" xmlns:g="urn:import:com.google.gwt.user.client.ui" xmlns:cv="urn:import:com.google.gwt.user.cellview.client"
xmlns:todo="urn:import:com.todo.client"> xmlns:todo="urn:import:com.todo.client">
<ui:style>
.inline { display:inline; }
</ui:style>
<g:HTMLPanel> <g:HTMLPanel>
<section id="todoapp"> <section id="todoapp">
<header id="header"> <header id="header">
...@@ -25,6 +28,17 @@ ...@@ -25,6 +28,17 @@
<span class="word" ui:field="remainingTasksLabel"></span> <span class="word" ui:field="remainingTasksLabel"></span>
left left
</span> </span>
<ul id="filters">
<li>
<g:Hyperlink targetHistoryToken="/" styleName="{style.inline}" ui:field="routingAll">All</g:Hyperlink>
</li>
<li>
<g:Hyperlink targetHistoryToken="/active" styleName="{style.inline}" ui:field="routingActive">Active</g:Hyperlink>
</li>
<li>
<g:Hyperlink targetHistoryToken="/completed" styleName="{style.inline}" ui:field="routingCompleted">Completed</g:Hyperlink>
</li>
</ul>
<g:Button ui:field="clearCompleted"> <g:Button ui:field="clearCompleted">
Clear completed (<span class="number-done" ui:field="clearTasksCount"></span>) Clear completed (<span class="number-done" ui:field="clearTasksCount"></span>)
</g:Button> </g:Button>
......
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