Unspaguetti
Toggle class name on click in jQuery
by jeyssonguevara
HTML
<div id="app">
<strong>Full Name: </strong>
<span data-tag="name" data-text></span>
<span data-tag="lastName" data-text></span>
<div>
<input id="name" type="text" placeholder="First Name" data-tag="name" data-value />
<input id="lastName" type="text" placeholder="Last Name" data-tag="lastName" data-value />
<button id="submit" type="submit" data-tag="isValid" data-visible>
Submit
</button>
<button id="clear">Cancel</button>
</div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Last Name</th>
</tr>
</thead>
<tbody data-tag="people" data-each>
<tr>
<td data-tag="people.name" data-text>Yo</td>
<td data-tag="people.lastName" data-text>Yo</td>
</tr>
</tbody>
</table>
</div>
CSS
#app {
background-color: #ffffff;
}
JavaScript
function Unspaguetti($context) {
const appState = {};
let hasRunFirstTime = false;
this.calculated = (name, callback) => {
appState[name] = callback;
return callback;
};
this.state = (name, initial) => {
appState[name] = initial;
return [
() => appState[name],
value => {
appState[name] = value;
updateUI();
}
];
};
this._firstRun = () => !hasRunFirstTime && updateUI();
function updateUI() {
Unspaguetti.stateHandlers.forEach(handler => {
$(`[data-${handler.name}]`, $context).each((index, el) => {
const $el = $(el);
const tag = $el.attr("data-tag");
const state = appState[tag];
const value = typeof state === "function" ? state() : state;
handler.handle($el, value, tag);
});
});
}
}
Unspaguetti.stateHandlers = [];
Unspaguetti.addStateHandler = (name, handle) => Unspaguetti.stateHandlers.push({
name,
handle
});
// Add standard state handlers
Unspaguetti.addStateHandler('text', ($el, value) => $el.text(value));
Unspaguetti.addStateHandler('visible', ($el, value) => $el.toggle(!!value));
Unspaguetti.addStateHandler('value', ($el, value) => $el.val(value));
const eachTemplates = {};
Unspaguetti.addStateHandler('each', ($el, value, tag) => {
if (!eachTemplates[tag]) {
eachTemplates[tag] = $el.find(":first-child").clone().detach();
}
const $template = eachTemplates[tag];
$el.empty();
(value || []).map(item => Unspaguetti.run(function(u) {
Object.entries(item).map(([name, value]) => u.state(`${tag}.${name}`, value));
}, $template.clone(false, false).appendTo($el).show()));
});
Unspaguetti.run = function(component, $context) {
const unspaguetti = new Unspaguetti($context);
component(unspaguetti);
unspaguetti._firstRun();
}
function App(unspaguetti) {
// Declare state management
const [getName, setName] = unspaguetti.state("name");
const [getLastName, setLastName] = unspaguetti.state("lastName");
...