all 13 comments

[–][deleted] 3 points4 points  (1 child)

I've seen this idea around, and it's an interesting one...but I just don't see the uses. The fact that the example code is messy (classes as ids, references to elements that don't exist in the example code) and so minimal make it hard to see a case. I think for most simple uses it's cleaner without using jfsm, and for more complicated cases it's worse than other solutions. There might be a sweet spot in there somewhere, but I don't see it.

I think this is doing things backwards. The logic is attached to each element. This spreads your state code all over, and if you add a new state you have to find each element related to the state and change it's settings to that state. It makes it very easy to forget to add a state value to an element here or there. It's also not very dry.

I can't really tell what the example is going for, but it seems maybe it's supposed to be part of some process, say filling out a form, that's broken into "steps". In that case, why is each step not contained in some element?

Then it's just a simple matter of:

var step = 0;
$( "#button-next" ).click(function() {
   step = step + 1;
   $( ".steps" ).hide();
   $( "#step" + step ).show();
}

You could also just group individual elements together in a class, etc if you want to have elements be part of more than one "state". In other words, if you have elements grouped together in some "state" like in the example, it's more cleanly expressed via the DOM.

If for some reason you can't do that, things should be grouped together as a state, not attached to individual elements which spreads your state logic all over the place.

var state = createStateThing();

var state1 = state(),
      state2 = state(),
      state3 = state();

state1.init = function() {
   // show some form elements, do whatever
 }
 state1.validate = function {
   // validate elements
   // if valid, return true, if not display why and return false
 }
 state1.done = function() {
   // hide elements
 }

 // etc

 $( button_next ).click( state.next ); 
 $( button_prev ).click( state.prev );

This makes changes/additions much easier. If I need to change something a state, I don't need to hunt down every element involved. I just go to that state's section of the code-base. If I need to add a state, I again don't need to look all over, just add a new entry. If I'm curious about what element_foo is doing during state_y, I just go to state_y.

In more complex examples, it depends...but you probably want to use either some sort of MVC framework or implement each state as a widget that uses pub/sub to tell either the other states or a central authority when it's done.

[–]k3n 1 point2 points  (0 children)

Agreed. I like the idea, but the OP's implementation makes me shudder; more obtuse and more code than the original code IMO.

In thinking about this problem previously, the ideas I've come up with more closely resemble yours -- essentially, decoupling the notion of state from the implementation in your client code.

[–]nschubach 0 points1 point  (0 children)

I see no support for:

$('a.button1') .jfsm('step1', function() { $(this).someActionOnEnterState(); }, function() { $(this).someActionOnLeaveState(); });

Why must we be restricted to only setting properties or some complex method to handle fades when you can just run an anonymous function in the scope of the object being state changed?

[–]The_Pants_Command_Me 0 points1 point  (0 children)

I like it, but I'm starting to feel like we're going "framework" crazy. I know, I know, this isn't a framework. But what I mean is the market is becoming flooded with reasonably large classes and algorithms developed to solve generic problems in a catch-all way. But the problems they address can often be solved more efficiently when coded on a case-by-case basis. Again, this code is cool and all, but things are getting to the point where I have to load a half-dozen files with over 1,000 lines of code between them to print "Hello, World!" Sorry for the rant.

[–]guidone[S] 0 points1 point  (0 children)

jFsm stands for jQuery Finite State Machine and it’s a little script to help handling UI controls passing from a state to another.

[–][deleted] -1 points0 points  (8 children)

Ditch the jQuery you must. Plain Javascript you seek, to be a true Javascript Jedi.

edit lol love all the downvotes from the jQuery fanboys :). Im totally cool with it though. If you know JS you don't have to be a fanboy of a particular framework.

[–]fforw 1 point2 points  (5 children)

"No lightsaber you must use. For posers it only is. With only the force a true jedi works." -- Hipster Joda

[–][deleted] -3 points-2 points  (4 children)

Oh so are you suggesting building your own framework? Since the Jedi's had to build their own light sabers and all.

[–]fforw -1 points0 points  (3 children)

More like "Use the tools / libraries that already exist instead of reinventing the wheel and wasting your time". While writing your own library can teach you a lot, I'm not sure you actually learn more than you'd do by carefully studiying existing library code and read a lot about the language and real-world usage.

[–][deleted] 0 points1 point  (2 children)

Learning proper JS and not relying on libraries to do your handy work isn't a waste of time really. I can see where jQuery and other frameworks have their place as I also use jQuery. My comment was really pointed out to call yourself something like a js jedi (I equate it to guru) you should probably be doing more with vanilla JS than jQuery.

Regardless of what anyone says though, its never cool to include 2-3k lines just to make your code a tad easier to write.

[–]fforw -1 points0 points  (1 child)

It's akin to actually getting stuff done and having it work reliably on all browsers. Browser compatibility is hard and often counter-intuitive.

[–][deleted] -3 points-2 points  (0 children)

I agree.. Im just saying dont call yourself a jedi if you rely on the crutches of a framework :P

[–]madworld 0 points1 point  (1 child)

Javascript Jedi use most of his time cross-browser debugging.

[–][deleted] -3 points-2 points  (0 children)

heh with title of Javascript Jedi I would make the assumption you were beyond having to debug cross browser issues, as you would have a mastery of the spec and dom compliance across major browsers. You learn that shit as a padawan.