Introduction

The "Regoch Web" is framework for developing single page, dynamic web applications. Created in modern Javascript with recent version of ECMAScript it's extraordinary simple and intuitive.
Together with the Cordova it can be used for mobile app development.
Learn this framework in just a few hours.

 The website regoch.org is completely made in the Regoch WEB framework.

Features

  • no slow compilation as in Angular, Vue or React (no such compilation at all)
  • lightweight application - small app file size (~50kB only)
  • JS files builded with the gulp and browserify (very fast)
  • use CommonJS and write the code just like you are doing that in NodeJS by using require()
  • no typescript, no heavy compiling, no bullshit
  • Model-View-Controller (MVC), intuitive app structure
  • easy to learn and to use
  • due to its small size you can build very fast and reactive mobile apps
  • steep learning curve (you'll reach high programming skills rapidly fast)

Installation & Development

To start a new project clone the regoch-web-skel repository. It's the web app skeleton with the basic routes and controllers.


  $ git clone https://github.com/smikodanic/regoch-web-skel.git projectName
  $ cd projectName
  $ rm -rf .git
  $ git init
  $ npm run inst
  

Now edit regoch.json, package.json, README.md and files in the client and server directories.
Notice: Instead of using the git clone the skel can be downloaded from https://github.com/smikodanic/regoch-web-skel/archive/refs/heads/master.zip

Build & Server Deployment

Build and deploy your application on the server. The SSR (Server Side Render) is achieved with the ProxyServer.


  $ sudo npm install -g pm2
  $ git clone <projectName>
  $ cd projectName
  $ npm run build   (or $ gulp build)
  $ pm2 start server --name projectName
  

Quick Start

After cloning the regoch-web-skel edit client/src/app.js file and create new controllers.

const { App } = require('regoch-web');

// route definitions
const routesCnf = [
  ['when', '/', 'HomeCtrl'],
  ['when', '/contact', 'ContactCtrl'],
  ['when', '/product/:id', 'ProductCtrl'],
  ['notfound', 'NotfoundCtrl'],
];

// inject controllers and define routes
app
  .controllers([HomeCtrl, ContactCtrl, ProductCtrl, NotfoundCtrl])
  .routes(routesCnf);


Playground

To learn more quickly visit our playground examples. The controller code is here and HTML views are here.
  • Controller Lifecycle Hooks - shows in which order will be executed constructor, prerender, postrender, init, destroy
  • Model - modelling with the Proxy Object
  • View::rgInc() - test the rgInc() method with nested data-rg-inc elements
  • View::loadViews() - test the loadViews() method with isAsync argument
  • View::lazyJS() - load/unload JS file lazily
  • DataRg - test the data-rg- elements related to DataRg methods
  • DataRgListeners - test the data-rg- elements related to DataRgListeners methods
  • Cookie - test all Cookie methods: put, putObject, getAll, ...
  • Form - test all Form methods: setControl, getControl, delControl ...
  • Auth - test login, logout, ... i.e. Auth methods
  • navig - test Navig methods

License

The software is published under MIT License.
The MIT License

Copyright (C) 2021  Saša Mikodanić http://www.regoch.org

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to
whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

App

class App

Properties

PropertyDescriptionTypeDefault
ctrlsA collection of all controllers. This makes possible to use a controller's methods inside another controller.object{}
$debugOptsDebugger options.object

client/src/conf/$debugOpts.js
=================================
{
// general
warnings: false,

// Router
router: false,
regochRouter: false,

// Controller.js
render: false,
navig: false,

// View.js
rgInc: false,
loadView: false,
emptyView: false,
loadHead: false,
rgLazyjs: false,

// DataRg.js
rgFor: false,
rgRepeat: false,
rgPrint: false,

rgIf: false,
rgSpinner: false,
rgSwitch: false,
rgDisabled: false,
rgValue: false,
rgChecked: false,
rgClass: false,
rgStyle: false,
rgSrc: false,
rgAttr: false,
rgElem: false,
rgEcho: false,
rgFlicker: false,

// DataRgListeners.js
rgKILL: false,
rgHref: false,
rgClick: false,
rgKeyup: false,
rgChange: false,
rgEvt: false,
rgSet: false,
rgModel: false
};
      


Beside these properties the global window.regochGlob = {} variable is initialised and can be used in controllers whenever it's needed.

Methods

  • controllers (Ctrls :Class[]) :App - create controller instances and inject into the app.ctrls

    Ctrls - array of controller classes, for example: [HomeCtrl, LoginCtrl]

  • fridge (name, val) :App - Set the subproperty of the controller's $fridge property in all controllers. The $fridge object will be preserved during controller processing execution. Other controller's properties will be deleted. This method is useful to define values shared among the all controllers.

    name - $fridge property name val - the fridge property value

  • auth (auth :Auth) :App - Inject the auth library into the all controllers and use it as this.$auth. Useful in apps where authentication guards are required in all routes, for example when building a web panel.

    auth - instance of the Auth class

  • preflight (funcs :Function) :App - Define preflight functions which will be executed on every route, before the controller processing() i.e. before loader(). The function argument is trx, regoch router transitional variable. Never define $model in the preflight function because it will triger render() before loader().

    funcs - the comma separated functions, preflight(func1, async (trx) => {console.log(trx)})

  • postflight (funcs :Function) :App - Define postflight functions which will be executed on every route, after the controller processing(), i.e. after the postrend(). Here the $model can be defined (what will trigger the render()).

    funcs - the comma separated functions, postflight(func1, async (trx) => {console.log(trx)})

  • routes (routesCnf :any[][]): App - define the app routes

    routesCnf - route configuration, for example:
    [['when', '/login', 'LoginCtrl'], {autoLogin:true}], ['when', '/customer/product/:id', 'CustomerProductCtrl'], {isLogged:true, hasRole:true}]]

  • viewsCached (viewsCached :object) :App - Inject the content of the client/_cache/views.json. Useful to speed up the HTML view load, especially in data-rg-inc elements. The cached views are set in the window.regochGlob.viewsCached

    viewsCcached - the content of the client/_cache/views.json file. In the regoch.json is defined what files will be cached.

  • debugger ($debugOpts :object) :App - Define the debugging options. Set the controller's $debugOpts property.

    funcs - the comma separated functions, postflight(func1, async (trx) => {console.log(trx)})



  • EVENT LISTENERS

  • onReady (cb :Function): void - Fired when HTML doc with the all resources is loaded. https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onload
  • onDOMLoaded (cb :Function): void - Fired when HTML doc is loaded without CSS, IMG and other resources. https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event
  • createDOMObserver (cb :Function): void - Listen for the DOM changes. Creates app.DOMobserver. https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
    
    app.createDOMObserver((mutationsList, observer) => { ... });
    const targetNode = document.querySelector('p#my-id);
    const config = { attributes: true, childList: true, subtree: true };
    app.DOMObserver.observe(targetNode, config);
    
    To stop observing the DOM changes use: app.DOMObserver.disconnect();
          

Example


const { App, syslib } = require('regoch-web');
const viewsCached = require('../_cache/views.json');
const routes = require('./routes');

// conf
const { $debugOpts, authOpts } = require('./conf');

// controllers
const HomeCtrl = require('./controllers/HomeCtrl');
const WebsocketServerCtrl = require('./controllers/WebsocketServerCtrl');
const WebsocketClientsCtrl = require('./controllers/WebsocketClientsCtrl');
const WebsocketClientsNodejsCtrl = require('./controllers/WebsocketClientsNodejsCtrl');
const WebsocketClientsBrowserCtrl = require('./controllers/WebsocketClientsBrowserCtrl');
const WebCtrl = require('./controllers/WebCtrl');
const MobCtrl = require('./controllers/MobCtrl');
const DatabaseCtrl = require('./controllers/DatabaseCtrl');
const RouterCtrl = require('./controllers/RouterCtrl');
const ContactCtrl = require('./controllers/ContactCtrl');
const NotfoundCtrl = require('./controllers/NotfoundCtrl');

// controllers - playground
const Controller_hooksCtrl = require('./controllers/playground/Controller_hooksCtrl');
const ModelCtrl = require('./controllers/playground/ModelCtrl');
const View_rgIncCtrl = require('./controllers/playground/View_rgIncCtrl');
const View_loadViewsCtrl = require('./controllers/playground/View_loadViewsCtrl');
const View_lazyJSCtrl = require('./controllers/playground/View_lazyJSCtrl');
const DataRgCtrl = require('./controllers/playground/DataRgCtrl');
const DataRgListenersCtrl = require('./controllers/playground/DataRgListenersCtrl');
const CookieCtrl = require('./controllers/playground/CookieCtrl');
const FormCtrl = require('./controllers/playground/FormCtrl');
const LoginCtrl = require('./controllers/playground/LoginCtrl');
const LoginokCtrl = require('./controllers/playground/LoginokCtrl');
const Navig1Ctrl = require('./controllers/playground/Navig1Ctrl');
const Navig2Ctrl = require('./controllers/playground/Navig2Ctrl');

// auth
const auth = new syslib.Auth(authOpts);

// preflight/postflight
const pref1 = async (trx) => { console.log('PREFLIGHT 1 - trx::', trx); };
const pref2 = async (trx) => { console.log('PREFLIGHT 2 - trx::', trx); };
const postf1 = async (trx) => { console.log('POSTFLIGHT 1 - trx::', trx); };
const postf2 = async (trx) => { console.log('POSTFLIGHT 2 - trx::', trx); };

// app
const app = new App();
app
.controllers([
// docs
HomeCtrl,
WebsocketServerCtrl,
WebsocketClientsCtrl,
WebsocketClientsNodejsCtrl,
WebsocketClientsBrowserCtrl,
WebCtrl,
MobCtrl,
DatabaseCtrl,
RouterCtrl,
ContactCtrl,

// playground
Controller_hooksCtrl,
ModelCtrl,
View_rgIncCtrl,
View_loadViewsCtrl,
View_lazyJSCtrl,
DataRgCtrl,
DataRgListenersCtrl,
CookieCtrl,
FormCtrl,
LoginCtrl,
LoginokCtrl,
Navig1Ctrl,
Navig2Ctrl,

// not found
NotfoundCtrl
])
.auth(auth) // needed for route authGuards
.preflight(pref1, pref2)
.postflight(postf1, postf2)
.routes(routes)
.viewsCached(viewsCached)
.debugger($debugOpts);