Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example using TroopJS #120

Closed
wants to merge 12 commits into from
Closed

Example using TroopJS #120

wants to merge 12 commits into from

Conversation

@mikaelkaron
Copy link
Contributor

@mikaelkaron mikaelkaron commented Mar 22, 2012

A TodoMVC example using TroopJS

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Mar 22, 2012

Thanks for the contribution :D

Can you explain what TroopJS is? Couldn't find any info on it.

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Mar 22, 2012

Just another front-end framework. Aims to package current javascript technologies and 'bind' them together with minimal effort for the developer.

  • jQuery for DOM operations
  • RequireJS for modularity
  • ComposeJS for object composition
  • Has.js for feature detection

On top of this we've added a pubsub system, templating, weaving (connect widget to dom) and auto wiring.

The TroopJS moto goes something like

Provide as little as possible to do as much as possible

The name is taken from what you'd call a group of monkeys (troop) as originally it was targeted at an 'embedded' environment using spidermonkey.

We're using todomvc as the onboarding project for new developers, so there's a step-by-step guide (in progress) that explains how we created this app.

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Mar 23, 2012

simplified the file structure quite a bit and provided an example using troopjs-bundle instead of individual modules.

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Apr 12, 2012

Not really sure what else I can do to get this merged. Perhaps use the new template from #126 when its ready?

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Apr 12, 2012

Sorry for the delay. I've been on holiday.

It looks pretty good :)

There are some things I'd appreciate if you could fix:

  • Use the latest template.
    As you've seen, I just landed a new UI. The HTML changes are minimal: You can see the changes in the diff here.
  • Make sure you follow the newly released App Specification.
    Please let me know if anything is unclear or could be improved. It's not field tested yet. The spine.js example, not yet landed, can be used as a reference.
  • This project uses tab indention and follows the Idiomatic guide to writing JavaScript. Please ensure your code follows this closely. If something is unclear, follow the existing style. Use double-quotes in HTML and single-quotes in JS and CSS.

I'll review it more thoroughly when the above changes are implemented :D


Some comments to your excellent TroopJS Todo app intro:

Ours is located in js/lib. As none of the other folders (css, js and img) were pluralized, we thought that it was silly to do it here.

I agree, changed in master.

We do this, but we felt it was natural to do the same when the user removes focus from the input box.

This is specified in the new App Specification.

Since the specification does not define what this checkbox should do when only some of the tasks are marked as completed, we've added an indeterminate state that covers this usecase.

Also in the App Specification.

Do let us know if you have any more feedback or if something is unclear :D

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Apr 30, 2012

@mikaelkaron Any updates?

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 2, 2012

hacking along on 0.0.2 ;) I'll make an updated todomvc as soon as I have that (using the new UI)

@addyosmani
Copy link
Member

@addyosmani addyosmani commented May 4, 2012

@mikaelkaron Thanks for the update! Do you think 0.0.2 might be ready sometime over the next few weeks? Im trying to establish whether you'll have time to bring the TroopJS app in line with specs for our next major version (probably aiming to go out in a month). If you do, I'll mark the target release for this as 1.0 otherwise we can do it in 1.1 (probably 1..a few months after).

We appreciate your contributions!

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 7, 2012

I'll try to land 0.0.2 ASAP, so please target this for 1.0

@addyosmani
Copy link
Member

@addyosmani addyosmani commented May 7, 2012

Marked accordingly. Let us know if you need any help :)

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented May 27, 2012

@mikaelkaron Any updates? The 1.0 release is close, and we need to get those apps that are going into the release merged.

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 29, 2012

I've been a bit slow over here. I'll take a stab at it today!

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 29, 2012

landed a bunch of stuff in my troopjs-todos repo (what I eventually 'copy' to todomvc). basically implemented all the requirements except routing. will take a stab at that tomorrow.

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 30, 2012

a bit of reset and a commit later. done.

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/css/app.css Outdated

.filter-active .completed,
.filter-completed .active {
display: none;

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

CSS shouldn't be tied to the filters functionality.

Instead you should just hide/show the items directly.

This comment has been minimized.

@mikaelkaron

mikaelkaron May 30, 2012
Author Contributor

just trying to save myself some coding for when you have a filter applied and add/remove items. I'll take a look at if it can be done without CSS.

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/create.js Outdated
@@ -0,0 +1,24 @@
define( [ "troopjs-core/component/widget" ], function CreateModule(Widget) {
var RE = /^\s+|\s+$/;
var ENTER = 13;

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

ENTER_KEY

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/create.js Outdated

switch($event.keyCode) {
case ENTER:
value = $element.val().replace(RE, EMPTY);

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Don't need regex for this: val().trim() instead

This comment has been minimized.

@mikaelkaron

mikaelkaron May 30, 2012
Author Contributor

does that trim of tabs etc?

This comment has been minimized.

@mikaelkaron

mikaelkaron May 30, 2012
Author Contributor

right. I was looking at $.trim. I'll update

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/create.js Outdated
define( [ "troopjs-core/component/widget" ], function CreateModule(Widget) {
var RE = /^\s+|\s+$/;
var ENTER = 13;
var EMPTY = "";

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Unnecessary constant, just compare against an empty string directly.

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/filters.js Outdated
@@ -0,0 +1,20 @@
define( [ "troopjs-core/component/widget", "jquery" ], function FiltersModule(Widget, $) {

var SELECTED = "selected";

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Don't need a constant here either.

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/item.html Outdated
var item = data.item;
var completed = item.completed;
%>
<li class="<%= (completed ? 'completed' : 'active') %>">

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

-> <li class="<%= (completed ? 'completed' : '') %>">

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
define( [ "troopjs-core/component/widget", "troopjs-core/store/local", "jquery", "template!./item.html" ], function ListModule(Widget, store, $, template) {
var RE = /^\s+|\s+$/;
var ENTER = 13;
var EMPTY = "";

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Same as earlier comments

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
var self = this;

// Defer initialization
$.Deferred(function deferredInit(dfdInit) {

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Use something like deferInit, instead of the ambiguous dfdInit, same with the below.

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
case "/completed":
$element
.removeClass(FILTER_ACTIVE)
.addClass(FILTER_COMPLETED);

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

.toggeClass( FILTER_COMPLETED );

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
// Update UI
$($event.target)
.closest("li")
.slideUp("slow", function hidden() {

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Don't animate

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
// Get INPUT and disable
var $input = $li
.find("input")
.prop(DISABLED, true);

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Why do you disable the input? it's only visible when in editing mode anyway.

This comment has been minimized.

@mikaelkaron

mikaelkaron May 30, 2012
Author Contributor

right now we know that localstorage is fast, so there's no need to disable the UI during write. But I'd like to have it there simply if one would try to implement a remote storage module, in which case it would disable the input box during write callback.

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Ok, sure, I agree ;)

@sindresorhus
sindresorhus reviewed May 30, 2012
View changes
architecture-examples/troopjs/js/widget/list.js Outdated
var $target = $($event.target);
var title = $target
.val()
.replace(RE, EMPTY);

This comment has been minimized.

@sindresorhus

sindresorhus May 30, 2012
Member

Same as before val().trim()

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented May 30, 2012

Thanks for finishing this. I have to say, I like to good use of $.Deferred ;)

I've done a review of your app and have some comments in addition to the inline ones:

  • Move it to the labs/architecture-examples folder. Remember to update all the references in the HTML.

Develop in a topic branch (not master) and submit against the labs folder in the master branch

  • Counter should say e.g: 2 items left
  • When in editing mode and remove the todo contents and hit enter, i get this error msg:

Uncaught Error: NOT_FOUND_ERR: DOM Exception 8

  • Drop the animation stuff
  • Use the jQuery in the assets folder
  • Minified:

Use minified version of third-party code and put it in the lib folder.

  • Too much use of unnessecary constants
@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 30, 2012

I'll get on the CSS update tomorrow. Do you want me to make a topic branch for all of this as per:

Develop in a topic branch (not master) and submit against the labs folder in the master branch

or are you ok with this pull request as it is (besides the outstanding CSS fix)?

I was also unable to reproduce your error, do you still have it?

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented May 30, 2012

I'll get on the CSS update tomorrow. Do you want me to make a topic branch for all of this as per:

No not necessary, but keep it in mind for your next pull request. It makes your life a lot easier if you've ever need to submit multiple pull requests to the same project.

  • I've just added require.js to our assets folder. Can you use that instead? (Note that it's Require 2.0)

I was also unable to reproduce your error, do you still have it?

Yes, I still have that issue, Chrome 19 Mac Lion:

Steps: Double-click the item, remove all the text, hit enter

Uncaught Error: NOT_FOUND_ERR: DOM Exception 8 jquery.min.js:4
f.fn.extend.remove jquery.min.js:4
onDelete list.js:139
b troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
q troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
r troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
f.each.f.fn.(anonymous function) jquery.min.js:3
onCommitFocusOut list.js:208
b troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
q troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
r troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
f.each.f.fn.(anonymous function) jquery.min.js:3
onCommitKeyUp list.js:194
b troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
q troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3
f.event.trigger jquery.min.js:3
f.fn.extend.trigger jquery.min.js:3
e.extend.each jquery.min.js:2
e.fn.e.each jquery.min.js:2
f.fn.extend.trigger jquery.min.js:3
r troopjs-bundle.js:11
f.event.dispatch jquery.min.js:3
f.event.add.h.handle.i jquery.min.js:3

Other than that, it looks good :)

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented May 31, 2012

Ok, I'm able to reproduce in chrome. I'll take a look at that now.

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented May 31, 2012

@addyosmani Actually 2.0 has been released.

@addyosmani
Copy link
Member

@addyosmani addyosmani commented May 31, 2012

@sindresorhus Oh wow! That I did not know. He must have had a few late nights to wrap it all up so quickly :)

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Jun 1, 2012

There. Fixed what needed to be fixed to be RequireJS 2.0 'compatible'.

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Jun 1, 2012

Cool, just need that error fixed and we're golden ;)

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Jun 1, 2012

Fixed.

Funny problem there actually, it's jQuery that triggers a simulated focusout event on the containing input as I .remove() the li, thereby re-triggering the whole chain (I click() a corresponding .destroy when the input is empty and we lose focus)

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Jun 1, 2012

Right, when I think about it I think we had another app with the same problem, turned out to actually be a Chrome bug.

Landed. Thanks for this addition to our collection ;)

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Jun 1, 2012

Well, I was only able to reproduce in chrome, and the underlying error is that jQuery will try to remove a node that does not exist anymore. I guess it's possible that this is the same problem (were you removing an element that had input descendants?).

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Jun 1, 2012

Can't remember, but here is the Chromium bug: http://code.google.com/p/chromium/issues/detail?id=104397

And here's the jQuery bug: http://bugs.jquery.com/ticket/11663

@mikaelkaron
Copy link
Contributor Author

@mikaelkaron mikaelkaron commented Jun 1, 2012

looks like the same to me. nice to know ppl are aware about it.

@sindresorhus
Copy link
Member

@sindresorhus sindresorhus commented Jun 1, 2012

But unfortunately not a lot of activity on the Chrome ticket...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

3 participants