O.js : an easy front-end framework

Hello everyone !

I write this topic to share a front-end framework I’ve been working on for almost a year : O.js.
O.js allows you to make in no time simple apps through an easy data-binding, with no need to write HTML nor set classes and ids to access the objects. Everything (aside from the CSS) is done with JS factory functions.

O.js source code on GitHub : https://github.com/MagicMixer/O.js/tree/master

Here is a link to a simple demo, followed by its explanations :

About the code :

  • Lines 1 to 6 : create references of functions contains in the O and B (BootStrap extension) libraries, as shortcuts to save time and for a better readability.

  • Line 8 : we initialize an object that will contain the data of the app. Any change to this object properties will automatically and immediately cause changes to every DOM element they are bound with.

  • Line 17 : we create a O object through DIV( … ). A O object is an object which contain a DOM object, and methods to interact with it. DIV(…) is equivalent to <div> ... </div> This function can take as parameters : configuration objects {}, text content, or other O objects…

  • Lines 21 and 23 : we use TEXT(…), which call O.text(…). O.text(…) takes 3 entry arguments : (source, prop, setter(optional)). “source” is the object which contains the data, “prop” name of the data to print, and “setter” is a function which can process the data if necessary (for exemple set to upper case). From now, every change of source[prop] will change the textContent of TEXT(…) on the screen.

  • Line 25 : we use a function IF( [source, prop], [condition1, content1], … , [conditionN, contentN] ) which shows content according to conditions. [source, prop] defines the data to use in the conditions, every change will update the IF. Then the objects are defined in an array format, which contains the condition and the content to hsow if true. There, we show “old” if age >= 25, “an adult” if 25 > age >= 18, “a child” otherwise.

  • Line 35 : we do some data-binding on the style. For this we use the style function of O objects. We can set a const value with style({width:“0px”}), or a dynamic value with style({width: [source, prop, (setter)] }). Here we use the setter defined on line 14, which transform the property “timer” in an angle between 0 and 360. We also use the c function, which is the short form of class to set the DOM class.

  • Line 37 : we create an Input of type Range. Inputs have 4 usefull properties : source(source, prop), value(source, prop, setter), target(source, prop, (setter)) and combo(source, prop, (setter)). Source and value are equivalent, excepted the fact that value can take a setter. They define the source of the data displayed in the input. Target defines where we want to put the input, with an optional setter to format or validate the data. Combo simply call source and target with the same arguments to do a two way data-binding. In this example, we only set a value in the Input.

  • Line 41 and 43 : we create buttons, and we use the function “click” to give them an action. Here we change the age.

  • Line 42 : we create an Input of type Number to set the age. As you can see, every change is immediatly shown on the view.

  • Line 45 : we create an Input of type Text to set the name.

  • Finally line 51, we render the app to the DOM.


Firstly, thank you for your interest in my work. I am not (yet?) an expert in JS, just a student having fun with coding, so any comment is welcomed.

Secondly, I have to say that what I showed you today is only a small part of O.js :

  • The framework can deal with data in an array, where every change or new value will be automatically build as a view through a setter and displayed, in the same order as in the array.
  • The Bootstrap addon help to make the responsive, for example : O.sm(4, 2).lg(3, 3) will add to the classes : “col-sm-4” and “offset-sm-4” and “col-lg-3” and “offset-lg-3”.
  • Every DOM attribute and style property can be bound to the app data.
  • The “close” function deletes all data-binding of an O object and its children, to avoid memory leak.
  • And many other functionalities will come in the following months, with an official documentation, a source code with comments, and a better english.

For now to use O.js, you can set the following link in your pen settings in codepen.

Source code : https://codepen.io/MagicMixer/pen/QgjJVV

Other examples :

TicTacToe : https://codepen.io/MagicMixer/pen/weMpvj

Game of Life : https://codepen.io/MagicMixer/pen/RgJQxW

Paint : https://codepen.io/MagicMixer/pen/JJYxGv

Todo List : https://codepen.io/MagicMixer/pen/OOKOzz (example od data-binding with an array)

3 Likes

This is way cool. Thanks for sharing! Do you have a Github repo? It’d be neat to see other campers contribute features and bug fixes.

One comment on the syntax: when binding an element to an object property, I’d rather pass a reference to the object (ie. I(obj.age)) rather than the object and a string reference to the property (ie. I(obj, "age")) as static analyzers for JS will pick up on misspelled properties but not strings.

Thank for the comment. I will put it on github in the next days.

Yes, I agree with you, but the way the data-binding works, it’s not possible.
The mechanism behind it is the following : O creates a pair of setter/getter for “age” on the object “source”, and the setter updates all depencies at each change. For this, we need both the object and the property name.

I’m working on a template function, that will transform a syntax like that :
template ( obj, “I am $name and I am $age years old.” )
in :
"I am ", TEXT(obj, “name”), " and I am “, TEXT(obj, “name”), " years old.”

It will be better for readability, at the cost of performance. But you still can’t detect mispelled properties. The only way to do it would be to put every variable in an object, like that :
obj = { age : { value : 17 } };
Then we can use a reference, but I think it will be a pain in the ass to set the value, i.e. : obj.age.value = 18.
Or I could create a preprocessor, that transform obj.age in obj, “age”, but just for this it’s a bit too much ^^

1 Like

Now on GitHub : https://github.com/MagicMixer/O.js/tree/master