As mentioned in Extending EvoToolkit, element, object and component logic is stored in classes.
These contain methods, which allow you to trigger certain functionality or actions (For example:- modal open or toggle expander). To access these, we use the evo()
selector.
The evo()
selector is a simple jQuery-like function allowing you to easily select EvoToolkit elements, objects and components (eg:- c-button-group
) and then trigger their class methods through a similarly named intermediary function (eg:- buttonGroup()
).
The example below would find the first .js-modal
modal and fire its open
method:-
evo('.js-modal').modal('open');
evo('.js-modal')
is very similar to document.querySelector('.js-modal')
in plain JavaScript or $('.js-modal')
in jQuery. However it is not intended to replace these, as evo()
only returns a matching class instance, rather than a DOM node.
When adding extra logic to existing components, it's recommended that you add a new class with a js
prefix to your target element. Why? You may not want your new logic to apply to every instance of the component in use, and it also implies to other devs that JS logic is being applied to the element.
You can also pass an object containing any options as a second parameter to the intermediary function. These would override any option data attributes attached to the element which trigger the same behaviour.
evo('.js-my-expander').expander('toggle', {
behaviour: 'open',
speed: 500,
delay: 10
});
Finally, there is a third parameter only required for layer parts which have classes on the top level block from 2 identically named parts from different layers (o-expander
, c-expander
etc). In this instance, you need to specify which layer the evo()
function should reference.
In this example, you're telling the evo()
function that it should call the close()
method from the expander class on the object layer, rather than the expander class on the component later.
evo('.c-expander').expander('close', false, 'object');
Besides a string, the evo
selector can accept a number of input types. Here's the full breakdown:-
js-my-expander
expander found.
evo('.js-my-expander').expander('toggle');
true
would toggle all js-my-expander
expanders.
evo('.js-my-expander', true).expander('toggle');
evo()
selector.
const myExpanders = document.querySelectorAll('.js-my-expander');
evo(myExpanders).expander('toggle');
You can find a full list of each layer part's methods on each of their respective documentation pages.
Alongside a component's own methods, there are a few global methods which are available across all components.
For a component, returns an array of available public methods for debugging purposes.
evo('.c-calendar').calendar('getMethods');
/*
[
"getMethods",
"getState",
"setState",
"init",
"nextMonth",
"prevMonth",
"setDate"
]
*/
Certain components have a requirement to maintain some level of UI state, so a state
object exists which holds this data. Using getState
, you can retrieve this object.
evo('.c-calendar').calendar('getState');
/*
{
currentDate: Mon Nov 25 2019 12:41:28 GMT+0000 (Greenwich Mean Time)
selected: {
dateObj: Wed Nov 13 2019 00:00:00 GMT+0000 (Greenwich Mean Time)
day: 13
hour: 0
minute: 0
month: 11
year: 2019
}
visibleDate: Mon Nov 25 2019 12:41:28 GMT+0000 (Greenwich Mean Time)
}
*/
Allows you to directly set a component's state. Default behaviour appends new / overrides existing state, but if you pass a `replaceState: true` key/value then the whole state object will be replaced.
evo('.c-calendar').calendar('setState', {
foo: 'bar'
});
/*
{
currentDate: Mon Nov 25 2019 12:41:28 GMT+0000 (Greenwich Mean Time)
selected: {
dateObj: Wed Nov 13 2019 00:00:00 GMT+0000 (Greenwich Mean Time)
day: 13
hour: 0
minute: 0
month: 11
year: 2019
}
visibleDate: Mon Nov 25 2019 12:41:28 GMT+0000 (Greenwich Mean Time),
foo: 'bar'
}
*/
evo('.c-calendar').calendar('setState', {
foo: 'bar',
replaceState: true
});
/*
{
foo: 'bar'
}
*/
Besides intermediary functions which connect HTML elements to JavaScript class objects, the evo
selector also has helper functions available. These are:-
On page load, the register()
function fires for each layer part, triggering the init
function in the class where you would typically apply event listeners.
If any layer parts are added dynamically after initial page load, they wouldn't have been picked up by this process, so won't work as expected. This is because their init
function hasn't run, so no event listeners have been assigned.
To get around this, when dynamically injecting a layer part, you can manually rerun the register process and target only your new element. This is demonstrated in the example below, where a new tabs component is created, registered, and then added to the DOM:-
// Create a new HTML element.
const newTabs = document.createElement('div');
// Add the tab classes
newTabs.classList.add('c-tabs', 'js-my-tabs');
// Inject the HTML content
newTabs.innerHTML = '- Mercedes Benz
- Audi
- Range Rover
123';
// Register
evo(newTabs).register('component', 'tabs');
// Append to DOM
document.body.appendChild(newTabs);
The delete
method in most cases simply removes the element from the DOM. For layer parts with state (such as calendar), it also removes the class instance containing that state from the global evotoolkit
object.
evo('.js-my-calendar').delete();