From 4c3ab0912d8e7ae22dc9acda37d02c8f59a1b1d3 Mon Sep 17 00:00:00 2001 From: Amelia Winger-Bearskin Date: Thu, 30 Oct 2014 00:28:20 -0400 Subject: [PATCH 01/12] confused... --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 33d38f7..4f6f93f 100644 --- a/index.html +++ b/index.html @@ -1,7 +1,7 @@ - So-and-so's Stateful Assignment + Amelia's Stateful Assignment YOUR PROJECT HERE From 0b9a50ba7133e30c47eec391b4dd7fdce76d4753 Mon Sep 17 00:00:00 2001 From: Amelia Winger-Bearskin Date: Thu, 30 Oct 2014 00:29:03 -0400 Subject: [PATCH 02/12] ok ok --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 4f6f93f..8402a5f 100644 --- a/index.html +++ b/index.html @@ -4,6 +4,6 @@ Amelia's Stateful Assignment - YOUR PROJECT HERE +confused From b1368f99a3829146dccabb47501398a1f50af7ef Mon Sep 17 00:00:00 2001 From: Amelia Winger-Bearskin Date: Thu, 30 Oct 2014 00:31:48 -0400 Subject: [PATCH 03/12] learning how to do parse MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit hum… --- LICENSE | 128 +++++ README.markdown | 5 + css/todos.css | 470 ++++++++++++++++ images/bg.png | Bin 0 -> 2126 bytes images/destroy.png | Bin 0 -> 555 bytes images/spinner.gif | Bin 0 -> 8673 bytes index.html | 104 +++- js/todos.js | 407 ++++++++++++++ js/underscore.js | 1343 ++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 2455 insertions(+), 2 deletions(-) create mode 100755 LICENSE create mode 100755 README.markdown create mode 100755 css/todos.css create mode 100755 images/bg.png create mode 100755 images/destroy.png create mode 100755 images/spinner.gif mode change 100644 => 100755 index.html create mode 100755 js/todos.js create mode 100755 js/underscore.js diff --git a/LICENSE b/LICENSE new file mode 100755 index 0000000..c771f77 --- /dev/null +++ b/LICENSE @@ -0,0 +1,128 @@ +Creative Commons CC0 1.0 Universal + +CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE +LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN +ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION +ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE +USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND +DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT +OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. + +Statement of Purpose + +The laws of most jurisdictions throughout the world automatically confer +exclusive Copyright and Related Rights (defined below) upon the creator +and subsequent owner(s) (each and all, an "owner") of an original work +of authorship and/or a database (each, a "Work"). + +Certain owners wish to permanently relinquish those rights to a Work for +the purpose of contributing to a commons of creative, cultural and +scientific works ("Commons") that the public can reliably and without +fear of later claims of infringement build upon, modify, incorporate in +other works, reuse and redistribute as freely as possible in any form +whatsoever and for any purposes, including without limitation commercial +purposes. These owners may contribute to the Commons to promote the +ideal of a free culture and the further production of creative, cultural +and scientific works, or to gain reputation or greater distribution for +their Work in part through the use and efforts of others. + +For these and/or other purposes and motivations, and without any +expectation of additional consideration or compensation, the person +associating CC0 with a Work (the "Affirmer"), to the extent that he or +she is an owner of Copyright and Related Rights in the Work, voluntarily +elects to apply CC0 to the Work and publicly distribute the Work under +its terms, with knowledge of his or her Copyright and Related Rights in +the Work and the meaning and intended legal effect of CC0 on those +rights. + +1. Copyright and Related Rights. A Work made available under CC0 may be +protected by copyright and related or neighboring rights ("Copyright and +Related Rights"). Copyright and Related Rights include, but are not +limited to, the following: + +i. the right to reproduce, adapt, distribute, perform, display, +communicate, and translate a Work; + +ii. moral rights retained by the original author(s) and/or performer(s); + +iii. publicity and privacy rights pertaining to a person's image or +likeness depicted in a Work; + +iv. rights protecting against unfair competition in regards to a Work, +subject to the limitations in paragraph 4(a), below; + +v. rights protecting the extraction, dissemination, use and reuse of +data in a Work; + +vi. database rights (such as those arising under Directive 96/9/EC of +the European Parliament and of the Council of 11 March 1996 on the legal +protection of databases, and under any national implementation thereof, +including any amended or successor version of such directive); and + +vii. other similar, equivalent or corresponding rights throughout the +world based on applicable law or treaty, and any national +implementations thereof. + +2. Waiver. To the greatest extent permitted by, but not in contravention +of, applicable law, Affirmer hereby overtly, fully, permanently, +irrevocably and unconditionally waives, abandons, and surrenders all of +Affirmer's Copyright and Related Rights and associated claims and causes +of action, whether now known or unknown (including existing as well as +future claims and causes of action), in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or +promotional purposes (the "Waiver"). Affirmer makes the Waiver for the +benefit of each member of the public at large and to the detriment of +Affirmer's heirs and successors, fully intending that such Waiver shall +not be subject to revocation, rescission, cancellation, termination, or +any other legal or equitable action to disrupt the quiet enjoyment of +the Work by the public as contemplated by Affirmer's express Statement +of Purpose. + +3. Public License Fallback. Should any part of the Waiver for any reason +be judged legally invalid or ineffective under applicable law, then the +Waiver shall be preserved to the maximum extent permitted taking into +account Affirmer's express Statement of Purpose. In addition, to the +extent the Waiver is so judged Affirmer hereby grants to each affected +person a royalty-free, non transferable, non sublicensable, non +exclusive, irrevocable and unconditional license to exercise Affirmer's +Copyright and Related Rights in the Work (i) in all territories +worldwide, (ii) for the maximum duration provided by applicable law or +treaty (including future time extensions), (iii) in any current or +future medium and for any number of copies, and (iv) for any purpose +whatsoever, including without limitation commercial, advertising or +promotional purposes (the "License"). The License shall be deemed +effective as of the date CC0 was applied by Affirmer to the Work. Should +any part of the License for any reason be judged legally invalid or +ineffective under applicable law, such partial invalidity or +ineffectiveness shall not invalidate the remainder of the License, and +in such case Affirmer hereby affirms that he or she will not (i) +exercise any of his or her remaining Copyright and Related Rights in the +Work or (ii) assert any associated claims and causes of action with +respect to the Work, in either case contrary to Affirmer's express +Statement of Purpose. + +4. Limitations and Disclaimers. + +a. No trademark or patent rights held by Affirmer are waived, abandoned, +surrendered, licensed or otherwise affected by this document. + +b. Affirmer offers the Work as-is and makes no representations or +warranties of any kind concerning the Work, express, implied, statutory +or otherwise, including without limitation warranties of title, +merchantability, fitness for a particular purpose, non infringement, or +the absence of latent or other defects, accuracy, or the present or +absence of errors, whether or not discoverable, all to the greatest +extent permissible under applicable law. + +c. Affirmer disclaims responsibility for clearing rights of other +persons that may apply to the Work or any use thereof, including without +limitation any person's Copyright and Related Rights in the Work. +Further, Affirmer disclaims responsibility for obtaining any necessary +consents, permissions or other rights required for any use of the Work. + +d. Affirmer understands and acknowledges that Creative Commons is not a +party to this document and has no duty or obligation with respect to +this CC0 or use of the Work. diff --git a/README.markdown b/README.markdown new file mode 100755 index 0000000..26505a7 --- /dev/null +++ b/README.markdown @@ -0,0 +1,5 @@ +This is a sample application that showcases the [Parse JavaScript SDK](https://www.parse.com/docs/js_guide). It's based on the [canonical Backbone Todo app](http://addyosmani.github.com/todomvc/). + +[View the live application hosted on Parse here](http://todolist.parseapp.com). + +[Learn how we built it in the tutorial](https://parse.com/tutorials/todo-app-with-javascript). diff --git a/css/todos.css b/css/todos.css new file mode 100755 index 0000000..06206c3 --- /dev/null +++ b/css/todos.css @@ -0,0 +1,470 @@ +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; + -ms-appearance: none; + -o-appearance: none; + appearance: none; +} + +body { + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; + line-height: 1.4em; + background: #eeeeee url('../images/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; +} + +#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: 45px; + top: 0px; + 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: #888; + -webkit-text-rendering: optimizeLegibility; + -moz-text-rendering: optimizeLegibility; + -ms-text-rendering: optimizeLegibility; + -o-text-rendering: optimizeLegibility; + text-rendering: optimizeLegibility; +} + +.section { + position: relative; +} + +#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; +} + +#new-todo, +.edit { + position: relative; + margin: 0; + width: 100%; + font-size: 24px; + font-family: inherit; + line-height: 1.4em; + border: 0; + outline: none; + color: inherit; + padding: 6px; + border: 1px solid #999; + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); + -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; +} + +#new-todo { + padding: 16px 16px 16px 60px; + border: none; + background: rgba(0, 0, 0, 0.02); + z-index: 2; + box-shadow: none; +} + +#main { + position: relative; + z-index: 2; + border-top: 1px dotted #adadad; +} + +label[for='toggle-all'] { + display: none; +} + +#toggle-all { + position: absolute; + top: -56px; + left: -15px; + width: 65px; + height: 41px; + text-align: center; + border: none; /* Mobile Safari */ + -webkit-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; + -webkit-transform: rotate(90deg); + -ms-transform: rotate(90deg); + transform: rotate(90deg); +} + +#toggle-all:before { + content: '»'; + font-size: 28px; + color: #d9d9d9; + padding: 0 25px 7px; +} + +#toggle-all:checked:before { + color: #737373; +} + +#todo-list { + margin: 0; + padding: 0; + list-style: none; + text-align: center; +} + +#todo-list .spinner { + margin: 15px auto; +} + +#todo-list li { + text-align: left; + position: relative; + font-size: 24px; + border-bottom: 1px dotted #ccc; +} + +#todo-list li:last-child { + border-bottom: none; +} + +#todo-list li.editing { + border-bottom: none; + padding: 0; +} + +#todo-list li.editing .edit { + display: block; + width: 506px; + padding: 13px 17px 12px 17px; + margin: 0 0 0 43px; +} + +#todo-list li.editing .view { + display: none; +} + +#todo-list li .toggle { + text-align: center; + width: 40px; + height: 40px; + position: absolute; + top: 0; + bottom: 0; + margin: auto 0; + border: none; /* Mobile Safari */ + -webkit-appearance: none; + -ms-appearance: none; + -o-appearance: none; + appearance: none; +} + +#todo-list li .toggle:after { + font-size: 18px; + content: '✔'; + line-height: 43px; /* 40 + a couple of pixels visual adjustment */ + font-size: 20px; + color: #d9d9d9; + text-shadow: 0 -1px 0 #bfbfbf; +} + +#todo-list li .toggle:checked:after { + color: #85ada7; + text-shadow: 0 1px 0 #669991; + bottom: 1px; + position: relative; +} + +#todo-list li label { + word-break: break-word; + margin: 15px 15px 15px 60px; + display: inline-block; + line-height: 1.2; + -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.completed label { + color: #a9a9a9; + text-decoration: line-through; +} + +#todo-list li .todo-destroy { + 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 .todo-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 .todo-destroy:after { + content: '✖'; +} + +#todo-list li:hover .todo-destroy { + display: block; +} + +#todo-list li .edit { + display: none; +} + +#todo-list li.editing:last-child { + margin-bottom: -1px; +} + +#footer { + color: #777; + padding: 0 15px; + position: absolute; + right: 0; + bottom: -31px; + left: 0; + z-index: 1; + text-align: center; +} + +#footer:before { + content: ''; + position: absolute; + right: 0; + bottom: 31px; + left: 0; + height: 100px; + 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 42px 0 -6px rgba(255, 255, 255, 0.8), + 0 43px 2px -6px rgba(0, 0, 0, 0.2); +} + +#todo-count { + float: left; + text-align: left; +} + +#filters { + margin: 0; + padding: 0; + list-style: none; + position: absolute; + right: 0; + left: 0; +} + +#filters li { + display: inline; +} + +#filters li a { + color: #83756f; + margin: 2px; + text-decoration: none; +} + +#filters li a.selected { + font-weight: bold; +} + +#clear-completed { + float: right; + line-height: 20px; + text-decoration: none; + background: rgba(0, 0, 0, 0.1); + font-size: 11px; + padding: 0 10px; + position: relative; + border-radius: 3px; + box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.2); +} + +#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; +} + +/* + Hack to remove background from Mobile Safari. + Can't use it globally since it destroys checkboxes in Firefox and Opera + */ +@media screen and (-webkit-min-device-pixel-ratio:0) { + #toggle-all, + #todo-list li .toggle { + background: none; + } +} + +#todoapp .content .login { + width: 350px; + margin: 45px auto 25px auto; +} + +#todoapp .content .login h2 { + font-weight: normal; + font-size: 25px; + margin-bottom: 20px; +} + +#todoapp .content .login input { + display: block; + margin-bottom: 10px; + font-size: 20px; + padding: 5px; + width: 340px;; +} + +#todoapp .content .login .signup-form { + margin-top: 25px; +} + +#todoapp .content .login button { + padding: 5px 10px; + background: #eee; + font-size: 20px; + border: 1px solid #ccc; + border-radius: 5px; + margin-bottom: 25px; + font-family: "Helvetica Neue"; +} + +#todoapp .content .login .error { + border: 1px solid red; + background: #FDEFF0; + padding: 5px 15px; + margin-bottom: 15px; +} + +#todoapp .content #user-info { + padding: 5px 10px; + border-top: 1px solid #ededed; + margin-bottom: 0px; + text-align: right; +} + + +#todoapp .content .mark-all-done { + margin-left: 8px; +} + +#credits { + color: #888; + text-align: center; + padding-top: 25px; +} + +#credits a { + color: #888; +} + diff --git a/images/bg.png b/images/bg.png new file mode 100755 index 0000000000000000000000000000000000000000..b2a7600825ee11f21849ed475499c7d1ecbcc870 GIT binary patch literal 2126 zcmV-U2(kBxP)+9y`=HK7nt=~3t000O5Nklm=04hVa_lXl_bm=+M;=eI<%$rO2ta`suh*Sr#POw*?adq!O!CV z*0&b)rkCCEV)1nIuiLBntUH-MJI;&qYgz|d@Nhnn_abi2g`pu4NAMVid3hS%?quz~ zjlJf(x8cj{VS zUVEP1msg9`^OFUhSO5rtXHhRlyU2i>6$BT=glG`{JlctGHrwRIm)6Buu65jLQn^H8 zvl9lZqUBA+%qvM5XC+yY@mfA(YB~XP=e|6<{%$^eU8nrK?v2ccb@Jom5CG>rKAL7J zplHEIavVp|0p1&m!G`Ti?<7iZ;}@G7#Z)}Km%2!FHnQ0*&?PLR)G!HAaHgU#c|$dz zpj#0HmeadIe>`#)=Jjkb{B=FKnU3pc-&Y@j_j6(h4Y~+Uq!^J=LHunx1xi4QXK-Y{&MoT8ky6Vb9c|WhnOwF~c=3zOy8agktliS6# z`#8F`9H)D=bmk9B5MnW&_r#)f$c+;$LSr-@^An8dhc~Iquuv>jOK7pw7LJ;&X0i1C zGMsHdP1Os@ny$$j!>XAii%7bp5k>`pyNA!~epb)()p9zR4Yl6z=U}{CIdh1z(FpAo zQIW!;0zpCyC4*7YLkZCO@cul0R_&zghsA8Ek)z%jNpKa92{@NH+SstX%@}xB*Jk!l}PZ1cClIns~}5^!RncUk*rmA z%SIVgt58EQxLJ+OiFqKkBuwquyZLUp|gr zPUbUbFbBrPd1xO`^C*r-i3p9*F#(OBh!4Wy@aC&*!|O|GXcjDA&YhF{;cD7*o(GS^ z@pQSE7)x_81=Qyje6*LQ#TXu-7(o;S8u3tpDA0_ddj%hmCspeXdhYR}-i9A=C`EoChUYuH~^x!9+|&(Pgb*>Ck<=9j|)*@xyfT zpP#+Kt<}39b|3Wl4fxT(+G?aH>gG^d@MEaUOJRfy55TtFI7^Y)VuMU=7Pp0y55jS~ z+TJ)igMyrqkX;wU8j68iIDtqJYhS_D3_Oem-@g6me_RfiQ}uT_K-A-9qG%}gk3E9c z!8`KgsMNXm)beloPfMql*|&$M>1q`i!cY)RFYnjNYu*gSv@8XebV7%}xYL>6)GJPJ zJpA7K31lcJuIFKSw-{x4FX0K2Az)~Xg<`sOu$4|^-(^XJX4YzoiNRvL zyuY7~26w-P^Zw%6F}shBwV2$02c8RsSUy6dM92diCAxiX3IUqsq5ig6>U_!Vy*q5$ zjm}16tJr+QZ&T?HkkpeIwVX-r1EI=@%Zlt;6g*mj&E!A))%gXJ=x6u#l zcKEP>bx4rqV*k`BBrZ$Mqjt{TsHcxUH>;)iAK}B(Kila&VD%b?6m&^0WK4^&EZNAI z8AMYs_%$D%|M+@+cQqL-hi4yG>h*jwdii!W1{}p>ZhwFYt_4Su1kjY9<-5`!$VNOI1y(EDSH4WpCijE_>al!Nt=^eVER#uJ1=b z;BWF2IgyF5LexV+yec$Kin;Ai@myo;G>zJ&jrdW#ecXhIZph5OYqw_PEfcF56Z5Zu_ZZE#q3Mc+N&1O^7hoh9QR7`+L$cBP5pqG=fqA0uh zUBukaxTFmH)<|Xbvp2c=HSbNkpXw73a5lv7V$jb92#yZ141@$X?F}Jt8gIU7Wm6m9 z?e_;;zsnm6`LZeP>T=$)Kr>Z?kr*UmFqR7zx0C6^bmcsc@1AGtw_rNH>-Xm$d*|Q< zn&1Ln0u7=l&ILs>%CkJp`DiG9F18x4Ne+lg<#i?e7jL%x;4ZnRkN^Mx07*qoM6N<$ Ef(>0N!2kdN literal 0 HcmV?d00001 diff --git a/images/destroy.png b/images/destroy.png new file mode 100755 index 0000000000000000000000000000000000000000..56d763702ec215857c180108fc28be9b833ef8a7 GIT binary patch literal 555 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 MqHPia0{rxU0Q(+wo&W#< literal 0 HcmV?d00001 diff --git a/index.html b/index.html old mode 100644 new mode 100755 index 8402a5f..1b78e0a --- a/index.html +++ b/index.html @@ -1,9 +1,109 @@ - Amelia's Stateful Assignment + + Parse JavaScript Todo App Amelia's Project based on this tutorial + + + + + + -confused + + + +
+
+

Parse Todos

+
+ +
+
+
+ +
+ Powered by Parse using the JavaScript SDK.

+ Learn how we built it in the tutorial. +
+ + + + + + + + + + + + diff --git a/js/todos.js b/js/todos.js new file mode 100755 index 0000000..da4a048 --- /dev/null +++ b/js/todos.js @@ -0,0 +1,407 @@ +// An example Parse.js Backbone application based on the todo app by +// [Jérôme Gravel-Niquet](http://jgn.me/). This demo uses Parse to persist +// the todo items and provide user authentication and sessions. + +$(function() { + + Parse.$ = jQuery; + + // Initialize Parse with your Parse application javascript keys + Parse.initialize("your-application-id", + "your-javascript-key"); + + // Todo Model + // ---------- + + // Our basic Todo model has `content`, `order`, and `done` attributes. + var Todo = Parse.Object.extend("Todo", { + // Default attributes for the todo. + defaults: { + content: "empty todo...", + done: false + }, + + // Ensure that each todo created has `content`. + initialize: function() { + if (!this.get("content")) { + this.set({"content": this.defaults.content}); + } + }, + + // Toggle the `done` state of this todo item. + toggle: function() { + this.save({done: !this.get("done")}); + } + }); + + // This is the transient application state, not persisted on Parse + var AppState = Parse.Object.extend("AppState", { + defaults: { + filter: "all" + } + }); + + // Todo Collection + // --------------- + + var TodoList = Parse.Collection.extend({ + + // Reference to this collection's model. + model: Todo, + + // Filter down the list of all todo items that are finished. + done: function() { + return this.filter(function(todo){ return todo.get('done'); }); + }, + + // Filter down the list to only todo items that are still not finished. + remaining: function() { + return this.without.apply(this, this.done()); + }, + + // We keep the Todos in sequential order, despite being saved by unordered + // GUID in the database. This generates the next order number for new items. + nextOrder: function() { + if (!this.length) return 1; + return this.last().get('order') + 1; + }, + + // Todos are sorted by their original insertion order. + comparator: function(todo) { + return todo.get('order'); + } + + }); + + // Todo Item View + // -------------- + + // The DOM element for a todo item... + var TodoView = Parse.View.extend({ + + //... is a list tag. + tagName: "li", + + // Cache the template function for a single item. + template: _.template($('#item-template').html()), + + // The DOM events specific to an item. + events: { + "click .toggle" : "toggleDone", + "dblclick label.todo-content" : "edit", + "click .todo-destroy" : "clear", + "keypress .edit" : "updateOnEnter", + "blur .edit" : "close" + }, + + // The TodoView listens for changes to its model, re-rendering. Since there's + // a one-to-one correspondence between a Todo and a TodoView in this + // app, we set a direct reference on the model for convenience. + initialize: function() { + _.bindAll(this, 'render', 'close', 'remove'); + this.model.bind('change', this.render); + this.model.bind('destroy', this.remove); + }, + + // Re-render the contents of the todo item. + render: function() { + $(this.el).html(this.template(this.model.toJSON())); + this.input = this.$('.edit'); + return this; + }, + + // Toggle the `"done"` state of the model. + toggleDone: function() { + this.model.toggle(); + }, + + // Switch this view into `"editing"` mode, displaying the input field. + edit: function() { + $(this.el).addClass("editing"); + this.input.focus(); + }, + + // Close the `"editing"` mode, saving changes to the todo. + close: function() { + this.model.save({content: this.input.val()}); + $(this.el).removeClass("editing"); + }, + + // If you hit `enter`, we're through editing the item. + updateOnEnter: function(e) { + if (e.keyCode == 13) this.close(); + }, + + // Remove the item, destroy the model. + clear: function() { + this.model.destroy(); + } + + }); + + // The Application + // --------------- + + // The main view that lets a user manage their todo items + var ManageTodosView = Parse.View.extend({ + + // Our template for the line of statistics at the bottom of the app. + statsTemplate: _.template($('#stats-template').html()), + + // Delegated events for creating new items, and clearing completed ones. + events: { + "keypress #new-todo": "createOnEnter", + "click #clear-completed": "clearCompleted", + "click #toggle-all": "toggleAllComplete", + "click .log-out": "logOut", + "click ul#filters a": "selectFilter" + }, + + el: ".content", + + // At initialization we bind to the relevant events on the `Todos` + // collection, when items are added or changed. Kick things off by + // loading any preexisting todos that might be saved to Parse. + initialize: function() { + var self = this; + + _.bindAll(this, 'addOne', 'addAll', 'addSome', 'render', 'toggleAllComplete', 'logOut', 'createOnEnter'); + + // Main todo management template + this.$el.html(_.template($("#manage-todos-template").html())); + + this.input = this.$("#new-todo"); + this.allCheckbox = this.$("#toggle-all")[0]; + + // Create our collection of Todos + this.todos = new TodoList; + + // Setup the query for the collection to look for todos from the current user + this.todos.query = new Parse.Query(Todo); + this.todos.query.equalTo("user", Parse.User.current()); + + this.todos.bind('add', this.addOne); + this.todos.bind('reset', this.addAll); + this.todos.bind('all', this.render); + + // Fetch all the todo items for this user + this.todos.fetch(); + + state.on("change", this.filter, this); + }, + + // Logs out the user and shows the login view + logOut: function(e) { + Parse.User.logOut(); + new LogInView(); + this.undelegateEvents(); + delete this; + }, + + // Re-rendering the App just means refreshing the statistics -- the rest + // of the app doesn't change. + render: function() { + var done = this.todos.done().length; + var remaining = this.todos.remaining().length; + + this.$('#todo-stats').html(this.statsTemplate({ + total: this.todos.length, + done: done, + remaining: remaining + })); + + this.delegateEvents(); + + this.allCheckbox.checked = !remaining; + }, + + // Filters the list based on which type of filter is selected + selectFilter: function(e) { + var el = $(e.target); + var filterValue = el.attr("id"); + state.set({filter: filterValue}); + Parse.history.navigate(filterValue); + }, + + filter: function() { + var filterValue = state.get("filter"); + this.$("ul#filters a").removeClass("selected"); + this.$("ul#filters a#" + filterValue).addClass("selected"); + if (filterValue === "all") { + this.addAll(); + } else if (filterValue === "completed") { + this.addSome(function(item) { return item.get('done') }); + } else { + this.addSome(function(item) { return !item.get('done') }); + } + }, + + // Resets the filters to display all todos + resetFilters: function() { + this.$("ul#filters a").removeClass("selected"); + this.$("ul#filters a#all").addClass("selected"); + this.addAll(); + }, + + // Add a single todo item to the list by creating a view for it, and + // appending its element to the `