RE:DOM – Tiny DOM library
redom.js.org
redom.js.org
el.email = input(props({ type: 'email' }))
better or easier than: <input type="email">
I think the example needs to be more compelling. el.email = (function(){
var input = document.createElement('input');
input.type = "email";
return input;
})();
...or something similar. Your could also use createContextualFragement or a little function that uses innerHTML, both of which parse a string into HTML (which is problematic). Or you could use a templating library, of which there are many and this is one. el.email = document.createElement('input');
el.email.type = "email"; el.email = Object.assign(document.createElement('input'),{type:'email'});Also used was object destructuring: http://odetocode.com/blogs/scott/archive/2014/09/11/features...
If anything it should be `var email = {...document.createElement('input'), type: 'email'}`
But that would result in `Object.assign({}, document.createElement('input'), { type: 'email' })`
Got 4 up votes though..
There is rarely a reason to build HTML using createElement, it's only sometimes needed. The majority of the time just write HTML - it's much easier.
> Or you could use a templating library
Or just use the built in <template> tag.
yes, almost by a factor of 4 :D
check out "render" test cases:
https://cdn.rawgit.com/localvoid/dd96890b82f1d1268df34330b14...
If you're a JS programmer you should definitely read Crockford's famous JS book, it explains a lot of JS patterns and the rationale behind them.
var input = crel('input', {type:'email'});
vs:
var wrapper = document.createElement('div'); wrapper.innerHTML = '<input type="email">'; var input = wrapper.children[0];
I feel like at this point, when there are so many, so so many, javascript frameworks to choose from, if you're going to build yet another one you need to take the time to explain why it exists. What are the advantages of this approach over the many existing alternatives? What problem does it solve? What does it do that others don't? What motivated its creation? Why should someone use this instead of riot or vue or knockout or transparency or $dom or snack or xui or or domtastic or crel or DOMinate or shaven or scriber or zepto or react or jquery or good old vanilla?
Maybe I'm just getting old and cranky (ok definitely I am that) but if someone can't be bothered to document their own code and expects others to dig through the source to figure out what it's for and how to use it, my default assumption is that the code itself is going to be similarly slipshod.
children(el => [
el.email = input(props({ type: 'email' })),
el.pass = input(props({ type: 'pass' })),
el.submit = button(text('Sign in'))
])
Can someone explains what this does and why it is used here?
As i understand it this function both modifies the `el` object (whatever that is) and returns an array containing the input elements, but why would you want to do both those things at the same time?> find('elements').clear('contents').add('border')
children(function(el) {
var a, b, c;
a = input(props({ type: 'email' }));
el.email = a;
// etc
return [a, b, c];
})
Entirely guesswork but:
El is the form element you're defining children on.
You need to provide references to the elements you're creating so that you can use them later (el.email and friends) but you also need to return them to the children function in an ordered manner so that it can actually attach them into the DOM.I'm still not sure how I feel about that bit of code though but it sure is clever...
Point is to be able to design: 1) how you create component 2) how you update it Both 1) and 2) are just simple functions.
const login = document.createElement('form');
login.email = document.createElement('input');
login.email.type = 'email';
login.pass = document.createElement('input');
login.pass.type = 'pass';
login.submit = document.createElement('button');
login.submit.textContent = 'Sign in';
login.appendChild(login.email);
login.appendChild(login.pass);
login.appendChild(login.submit);
login.onsubmit = function(event) {
event.preventDefault();
console.log(this.email.value, this.pass.value);
};
document.body.appendChild(login);
The children call produces an array of objects that are appended to the element, but the callback also takes the wrapping element (in this case `login`), and so to be conveniently able to access it later (`login.email.value`) it also assigns them there. A more conventional JavaScript approach would be to assign email, pass and submit as local variables rather than stuffing them inside the form object.As for the other example:
const app = document.createElement('table');
const tbody = document.createElement('tbody');
app.appendChild(tbody);
app.update = function(data) {
tbody.innerHTML = '';
for (let row in data.tbody) {
let tr = document.createElement('tr');
for (let cell in row) {
let td = document.createElement('td');
td.textContent = cell;
tr.appendChild(td);
}
tbody.appendChild(tr);
}
}
document.body.appendChild(app);
app.update({
tbody: [
[1, 2, 3],
],
});
This is rather simpler, frankly. I prefer plain DOM for myself at this level.children() is supposed to take a function as argument and that function is supposed to return the list of children.
So basically:
children( function(el) {
return [
el.email = input(props({ type: 'email' })),
el.pass = input(props({ type: 'pass' })),
el.submit = button(text('Sign in'))
]
} )Also,
[
el.email = input(props({ type: 'email' }))
,
...
]is a neat idea. In one (expressive) line he is assigning the value to the array and also giving the child (in this case, email) a name and reference in its parent, so later he can just call el.email (in the onsubmit function).
It would be much better to use HTML for that and simply toggle the display/visibility of DOM elements via CSS or JS.
- We want to generate HTML from our data (eg. database) - We want an interactive experience (eg. with toggling visibility)
You could argue that we should generate the HTML on the backend, but then you are still generating HTML, and now you have two systems that interact with the HTML instead of one.
Why in the heavens would you ever choose to use a templating library and blur the lines between content (user input) and UI structure? Why reinvent the control-flow wheel?
Templating represents programmers realizing that this newfangled browser thing can already parse HTML, and hey, can't we do something clever with that - sure, if we unnecessarily serialize to a string first, yes! No thank you.
But I can sympathise with where you're coming from, as I have not so fond memories of backbone + [insert templating library]. A lot the problems can be addressed through better tools & a pre compilation stage where the templates are transformed into JS & data input are escaped for security reasons. One example of this is Ember.js's HTMLbars which address basically all of what you just listed there.
edit: That said if for whatever reason I couldn't use Ember, I'd probably choose some flavour of JSX over most other templating libraries, lol
If you toggle visibility with CSS, you still have to put everything in the DOM. Sometimes, putting things in DOM can be very expensive. Consider a date picker, a fairly complicated thing with many sub-elements. If you have to put thousands of date pickers in the dom, that's going to take a lot of time. Especially if the user only sees one if they click on an event to edit it.
Edit: Not sure why I got downvoted, but if you look at the Mithril API (sample code on http://mithril.js.org/), it's very similar to this RE:DOM library with the major difference being that there is a controller function in the Mithril example and that Mithril is more of a functional language.
On the one hand this seems far too clever for it's own good and in the same vein as coffeescript where it's really easy for you to write efficient & compact code which somehow turns into complete garbage when you try to read it two weeks later.
On the other hand it looks super neat, has 0 dependencies and looks like React but without requiring any kind of build system.
I think I might need to try it in a side project.
var form = React.createFactory('form');
form({...}, ...);
or var e = React.createElement;
e('form', {...}, ...);Riot is fantastic, especially in anticipation of web components, but personally I don't see performance as the main issue; I'm willing to trade performance for syntax I like, and the areas where Riot tends to choke are generally on tasks I typically wouldn't ask of client-side JS, no matter how fast it was.
It's the lack of certain critical features that kills it for me. The biggest one is that is has no Vue-style transition system for "if" and "show" -- there are plugins that do it strictly for mount and unmount. It's an outstanding question in #1858, though it might be outside the scope of Riot core, TBH.
In any case, I moved to Vue for that reason, and like it a lot, though I'd still prefer a Riot-with-easy-transitions :)
There is virtual-hyperscript which ports the above to virtual-dom: https://github.com/Matt-Esch/virtual-dom/tree/master/virtual...
I made a similar-ish "library" about an year ago: https://gist.github.com/awalGarg/8a0e18c6fe87456d885f
And there are all sorts of similar DSLs you can find on npm/github for JS. In a bit less time, you can write your own. In even lesser time, you can just do what you used to do prior to all this. This does however seem like a pretty popular idea in the JS community which keeps getting "discovered" every now and then.
e.g.
document.body.appendChild($('form', {action: '/submit', method: 'POST'}, [
$('input', {type: 'text', name: 'username'}),
$('br'),
$('input', {type: 'password', name: 'password'}),
$('br'),
$('input', {type: 'submit'})
]));
RE:DOM looks cool too.Since using Haskell's Blaze, I've wanted something close in other languages.
https://github.com/dropbox/pyxl for python comes to mind as something more enjoyable than manually doing tree-shaped OOP
login = : //"read variable from indented block" symbol of magicness
<form>
<input type=email>
<input type=pass>
<button>{_("Sign in")}<button> //gotta have an excuse to inline code!
</form>
login.events({
onsubmit (whatever, i dunno) {
blap
}
});
seems a lot more fun!What a bold statement !