neobiz v4.7.2
Documentation Neobiz.js 4.7.x
A simple view engine that has 100% JS features
Neobiz.js is pure in JS lang, transform Object into HTML
fix error outFIle
Updates:
- fix event bugs
- Boolean attributes / non-value attribute (example: disabled, readonly)
prev update:
- rendermethod change to- **\_render**to avoid conflict with another library and add safety check
- render option props improve
- fix bug on child order
features:
- eventHandler
- Reusable & editable style/css
- Altering object
- Registering component
- Explicit tag name supported
read /example dir to better understanding
for browser usage use browser.js file.
Example with vue in browser
page.js
import "neobiz";
({
  div: {
    script: [
      { src: "https://unpkg.com/vue@3/dist/vue.global.js" },
      { src: "https://unpkg.com/neobiz@3.1.0/browser.js" },
      { src: "./my-component.js" },
    ],
    id: "app",
  },
  script: {
    html() {
      const { createApp } = Vue;
      createApp(myComponent).mount("#app");
    },
  },
}.outFile("./welcome.html"));my-component.js
const myComponent = {
  data() {
    return { msg: "hi, this is example" };
  },
  template: { h1: { text: "{{msg}}" } }._render,
};| properties | caller | return-type | description | 
|---|---|---|---|
| _render | Object | string | rendering to HTML | 
| outFile | Object @params destinationstring | void | generate static HTML file | 
| range | Array @params lengthint, startint | Array | shortcut for looping in a range | 
| repulse | String | Object | generate object from HTML string | 
| css | Object | Object | generate css from object | 
| cssText | Object | Object | inline css | 
| alter trials | Object @params cbfunction | Object | altering object before rendering | 
| reg | Object | void | registring an object | 
| regm | Object | void | updating the existing registered object | 
| load | Object | Object | read an existing registered object | 
| unred | Object | void | removing an existing registered object | 
| renderOption | Object @params optionObject | void | set the option for rendering | 
Why use this?
- Easy maintance innerHTML rather than literal string
- Generate static html file
- Full control of view. Such as filtering, encrypting the data before serve, or just like conditional and loop case
- Almost no need to learn anything. Just need to learn how to render
- Limitless potential, because it's just js. Almost all library should be compatible
Basic syntax
How to use? just import this:
import "neobiz";It's just an Object! wrap in () to create a statement or just assign to a var
{
  // text property is same as innerText
  h1: {
    text: "Hello World!",
  },
}._render;
// <h1>Hello World!</h1>or use call method
_render.call({
  // text property is same as innerText
  h1: {
    text: "Hello World!",
  },
});Comments:
{
  // this is comment
  /*
  this is multi line
  */
  h1: {
    text: "This is heading";
  }
}properties dom
{
  h1: {
    class:"heading",
    text: "Hello World!",
    style:"color: #DC1E1E",
  }
}
// <h1 class="heading" style="color: #DC1E1E">Hello World!</h1>boolean attributes
use Null to indicate non-value attributes, do not confuse Null to null
{
    button: { text: "Hello World!", disabled: Null },
  }._renderinnerText & innerHTML:
  {
    h1: { text: "<b>this is a text</b>" },
    ul: { html: "<li>this will be render as html</li>" },
  }nested dom:
{
  body: {
    h1: {
      text: "Hello World!",
    }
  }
}expression & operator
{
  span: [
    { text: 24 + 12 / 6 },
    { text: !false },
  ],
}siblings dom:
There is a case like this:
<li>orange</li>
<li>banana</li>Object can not use 2 keys with the same name
// Don't do this
{
  li:{text:"orange"},
  li:{text:"banana"},
}
// Do this
{
  li:[
    {text:"orange"},
    {text:"banana"},
  ]
}Render Option
renderOption({
  camelCase: false,
  once: false,
  nodoctype: false,
  ignoreTag: false,
  prefixTag: false,
  prefixAttr: false,
});set once to true to use option only for once,
set nodoctype to true to remove <!doctype html> in the beninging,
set ignoreTag to true to unused tag properties,
set prefixTag to something to add text before tag,
use noprefix:true to skip on specific object
set prefixAttr to something to add text before attribute,
use nopAttr:true to skip in specific object
set camelCase true to convert camelCase properties to kebab-case
make sure to set the option before rendering
renderOption({
  camelCase: true,
});
render.call({
  ionRouter: {},
});result
<ion-router></ion-router>Explicit tag name
What if there is somethings in the middle of list?
<li>orange</li>
<p>
  <span>This is in the middle</span>
</p>
<li>banana</li>if we use an array there will share the tag name right? just use this:
use string as key could distinc an element with just a space no need to worry, it will render without space
{
  li:{text:"orange"},
  p:{span:{text:"This is in the middle"}},
  "li ":{text:"banana"},
}or write the tag name:
{
  li: [
    { text: "orange" },
    { tag: "p", span: { text: "This is in the middle" } },
    { text: "banana" },
  ],
}also with specifying tag name, we can name it differently:
  {
    PersonList: ["Arthur", "Zoro"].map((person) => ({
      tag: "li",
      text: person,
    })),
  }Modify an Object
use alter properties, with function as params. no need to return a value
const y = {
  h1: { text: "Hello World!" },
  p: { text: "this is a p" }.alter((e) => (e.class = "lorem")),
}.alter((e) => {
  e.h1.text = "thi is altered text";
  e.h1.style = { color: "red", fontSize: "150%" }.cssText;
});
console.log(y.render);Components / Partials
import header from "./header.v.js"; //function type
import footer from "./footer.v.js"; //object type
{
  div: header({ user: "dim24" }),
  p: { text: "this is text" },
  div: footer,
}.render;header.v.js
export default ({ user }) => ({ h1: { text: `Hi, ${user}` } });footer.v.js
export default {
  script: { src: "/assets/js/main.js" },
  span: { text: "this is footer" },
};reg, regm, load & unreg Components
The idea is to make object has resuability
reg & load
this function need a single argument to set a name of registering object,
there is 2 ways to registering an component:
- through properties method:
{ name:"viewport"}.reg("viewport")- via call method:
reg.call({ name: "viewport" }, "viewport");now we can load it's value whenever we want
{
  meta:load("viewport"),
  body: {
  }
}regm
this function will replace an existing registered object with a new value:
const newValue = load("viewport");
newValue.content = "width=device-width, initial-scale=1.0";
newValue.regm("viewport");unreg
when we the object doesn't needed anymore, just unreg it:
unreg("viewport");Style
use camel case to css properties
inline CSS:
{
  h1:{
    text:"Hello World",
    style:{
      color:"#1B73F8",
      fontSize:"150%"
    }.cssText
  }
}use style :
global-style.js:
export default {
  h1: {
    color: "red",
  },
  body: {
    margin: "0px",
    textAlign: "center",
  },
};why should use object css rather than direct css?
we can easily modify the style
main-page.js:
import style from "./global-style.js";
style.body.margin = "12px";
{
  style:style.css,
  div:{
    h1:{text:"Hello World!"}
  }
}.renderreusable style / mixin
const flex = (justify, align, direction = "row") => ({
  display: "flex",
  justifyContent: justify,
  alignItems: align,
  flexDirection: direction,
});
const space = {
  padding: "6px 8px",
  margin: "6px 10px",
};
console.log({
  style: { div: flex("center", "center"), button: { border: "none", ...space } }
    .css,
});Interacting with DOM
use script to interact with browser with html property
wrap the script with a function, or use string
{
  button:{onclick:"sayHi(this)",id:"hi-button"},
  script:{
    html(){
      document.getElementById("hi-button").innerText="Click me!";
      function sayHi(el){
        el.innerText="Hi!";
      }
    }
  }
}Event
you can add an event this keyword always refered to the node itseft
{
  input:{type:"password",onkeypress(){
    if(event.keyCode==13)
    alert(this.value)
  }},
  button:{text:"Click me!",onclick(){
    this.innerText = this.innerText=="clicked"?"Click me!":"clicked";
  }}
}Repulse
If you already have an html file and want to modify it, or make it as a template, just use this
this function is still has a lot issues, use only in a simple case
- need to wrap all tag into a single parent
- recommended to use external script and css
- repetitive / nested could caused weird behavior (help me, please!)
I still try to improve this feature. if you can provide some help just tell me please... :)
const { div } = `
<div>
    <h1>Hello dims!</h1>
</div>
`.repulse;
div.id = "main";
div.h1.class = "heading";
div.p = { text: "this is a whole text" };
console.log({ div }.render);result
<div id="main">
  <h1 class="heading">Hello dims!</h1>
  <p>this is a whole text</p>
</div>Pass Value
use shorthand anonym function
console.log(((user) => ({ h1: { text: `Hello, ${user}` } }))("Vins").render);or
const greeting = (user) => ({ h1: `Hello, ${user}` });
console.log(greeting("Vins").render);Control Flow
ternary:
{
    h1: status
      ? { text: "Hello World!" }
      : {
          a: { href: "#", text: "You are offline!" },
        },
}IIFE if-else
{
    h1: (() => {
      let result;
      if (status) result = { text: "Hello World!" };
      else
        result = {
          a: { href: "#", text: "You are offline!" },
        };
      return result;
    })(),
}normal if else
let result;
if (status) result = { text: "Hello World!" };
else
  result = {
    a: { href: "#", text: "You are offline!" },
  };
//use
{
  h1: result,
}IIFE switch-case
{
    h1: (() => {
      let result;
      switch (status) {
        case true:
          result = { text: "Hello World!" };
          break;
        case false:
          result = {
            a: { href: "#", text: "You are offline!" },
          };
      }
      return result;
    })(),
}Loop & array manipulation
range & map:
  {
    ul: {
      li: [].range(8, 1).map((item) => ({ text: "data-" + item })),
    },
  }map
  {
    ul: {
      li: ["grape", "banana", "apple"].map((text) => ({ text })),
    },
  }filter
{
  ul: {
    li: [].range(8, 1).filter( num => num % 2 == 0 ).map((item) => ({ text: "data-" + item })),
  },
}for
  {
    ul: {
      li: (() => {
        const result = [];
        for (let i = 1; i < 9; i++) result.push({ text: "data-" + i });
        return result;
      })(),
    },
  }while
  {
    ul: {
      li: (() => {
        const result = [];
        let i = 0;
        while (++i < 9) result.push({ text: "data-" + i });
        return result;
      })(),
    },
  }templating
this example use single file usage. for modular usage leave to you, or just read the example dir
//template file
const template = (content) => ({
  div: {
    class: "main wrapper",
    div: content,
  },
});
//content file
template({
  h1: { text: "Hello World!" },
});Thank you for read until here.
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago