View State
A starter code to implement a multi-screen or views in your web app.
Introduction
This starter code uses the first child of a container element to toggle display a view. For example, the following code has Main Screen and a the Settings page. The Settings page is hidden initially.
<div class="_rootViewContainer">
[ data-view-name="screenMain"
[h1 'Main Screen']
]
<template data-view-name="screenSettings">
[ data-hidden
[h1 'Settings']
]
</template>
</div>
You then create a view state manager for each view container to control what's rendered on the screen.
let viewStateRoot = new ViewState({
containerSelector: '._rootViewContainer',
viewDataKey: 'data-view-name',
});
// set active view to ._rootViewContainer > [data-view-name="screenSettings"]
viewStateRoot.SetActiveView('screenSettings');
Due to how it's implemented, it is not suitable for handling a view group, e.g. toggling authorized feature at several places at once when the user is logged in.
Takeaway Code
js/infrastructure/models/view-state.js
Script:
<script src="https://cdn.jsdelivr.net/gh/tmpmachine/vanilla-framework@bfb379f/js/infrastructure/models/view-state.js"></script>
CDN:
https://cdn.jsdelivr.net/gh/tmpmachine/vanilla-framework@bfb379f/js/infrastructure/models/view-state.js
Repository:
index.html
<div class="_rootViewContainer">
[ data-view-name="screenMain"
[h1 'Main Screen']
]
<template data-view-name="screenSettings">
[ data-hidden
[h1 'Settings']
]
</template>
</div>
js/application/uis/view-states.js
let viewStateRoot = new ViewState({
containerSelector: '._rootViewContainer',
viewDataKey: 'data-view-name',
});
index.js
viewStateRoot.SetActiveView('screenSettings');
Example
The following example toggling between two views using a button.
index.html
<div class="_rootViewContainer">
[ data-view-name="screenMain"
[btn onclick="navigateScreen(this)" 'Settings' data-target="screenSettings"]
[h1 'Main Screen']
]
<template data-view-name="screenSettings">
[ data-hidden
[btn onclick="navigateScreen(this)" 'Back' data-target="screenMain"]
[h1 'Settings']
]
</template>
</div>
<script src="https://cdn.jsdelivr.net/gh/tmpmachine/vanilla-framework@d7f078b/js/infrastructure/models/view-state.js"></script>
<script>
let viewStateRoot = new ViewState({
containerSelector: '._rootViewContainer',
viewDataKey: 'data-view-name',
});
function navigateScreen(btnEl) {
let viewName = btnEl.dataset.target;
viewStateRoot.SetActiveView(viewName);
}
</script>
Configuration
If your use case require to register event listeners on all views on application load, you can omit the use of <template>
and instead assign the view key directly on the view container accompanied by data-hidden
attribute.
<div class="_rootViewContainer">
[ data-view-name="screenMain"
[btn onclick="navigateScreen(this)" 'Settings' data-target="screenSettings"]
[h1 'Main Screen']
]
[ data-view-name="screenSettings" data-hidden
[btn onclick="navigateScreen(this)" 'Back' data-target="screenMain"]
[h1 'Settings']
]
</div>
Extending Functionality
View Transition
To integrate view transition, implement the following list:
Start and wait transition out of the current view.
Set the new active view.
Start transition in.
async function navigateScreen(btnEl) {
// start and wait transition out before changing active view
// implementation may vary
// ...
let viewName = btnEl.dataset.target;
viewStateRoot.SetActiveView(viewName);
// start transition in, no need to wait in most cases
// ...
}
Open comments page