PubSub jQuery State Management
jQuery does not ship with State Management out of the box. We are required to use $.data()
to manage state within our modules.
When a module becomes too complex to rely on $.data()
we only have one option, to adopt a JavaScript MVC. For some projects this makes sense. For others this is like shooting a fly with a shotgun.
This plugin attempts to be the middle ground, allowing you to handle state without having to drastically re-architect your application
You set state on collections. Your collections can obviously reference 1+ elements.
Consider the HTML:
<button type="button" class="btn">Button 1</button>
<button type="button" class="btn">Button 2</button>
<button type="button" class="btn">Button 3</button>
and the JavaScript:
$('.btn')
.state({ active: false }, 'buttonActivation')
.on('click', function (event) {
event.preventDefault();
$(event.currentTarget).state({ active: true }, 'buttonActivation');
});
We can see that each .btn
starts out in the { active: false }
state, which is subscribed to the buttonActivation
namespace.
On click of any button, we will apply the state of { active: true }
.
This operation is naturally paranoid, meaning that the state is accrued rather than replaced.
Each of these objects are also stored in a global state history array.
When the state of an element changes, it announces the change as an event triggered on the element. By listening for these changes we can allow other modules to respond to state change:
$('.btn').on('state:buttonActivation', function (event, fullState, currentState) {
if (currentState.active) {
$(event.currentTarget).addClass('btn--active');
}
});
Passed to the event handler are the following arguments:
- the jQuery Event object,
- the full, accumulated state object for the element,
- an object representing the state change that just occurred
To return the state of an element:
$('.btn:last').state();
If you pass a collection of 1+ elements to the state
method, it will return the first element's state.
$('.btn').state();
To retrieve all of the state applied to all of the elements on a page, use:
$.state()
Though you probably wouldn't want to, unless you knew exactly what you were doing, you are able to destroy the page's global history by calling:
$.state('destroy');
Note: this destroys the global array, not state that has already been set on individual elements. This was mostly added for testing purposes.
You can use:
$.state('elementsIn', 'buttonActivation');
to return a collection of all elements that have state subscribed to the given namespace.
This software carries with it an MIT license. Please use at your own risk.
If you find this library useful, please submit pull-requests to make it better!
- v0.3.0
$.state('destroy')
to truly deconstruct plugin- clean
$.state()
output to be more useful