MachinaJs - Hierarchical

Hierarchical FSM learning with MachinaJs

by Jeancarlo Fontalvo

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/machina.js/2.0.0/machina.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootswatch/3.3.7/paper/bootstrap.min.css">
<div class="container">
    <form action="#" class="form">
        <div class="row">
            <div class="col-sm-6">
                <div class="form-group">
                    <label for="">Nombre</label>
                    <input data-fsm="visibles" type="text" class="form-control">
                </div>
                <div class="form-group">
                    <label for="">Descripcion</label>
                    <input data-fsm="visibles" data-fsm type="text" class="form-control" name="descripcion" id="descripcion">
                </div>
                <div class="form-group">
                    <label for="">Valor ponderado</label>
                    <input data-fsm="visibles" type="text" class="form-control" name="valor-ponderado" id="valor-ponderado">
                </div>
            </div>
            <div class="col-sm-6">
                <div class="form-group">
                    <label for="">Tipo</label>
                    <select data-fsm="visibles" name="" id="" class="form-control">
                      <option value="1"> Tipo 1</option>
                      <option value="2"> Tipo 2</option>
                      <option value="3"> Tipo 3</option>
                      <option value="4"> Tipo 4</option>
                    </select>
                </div>
                <div class="form-group">
                    <label for="">Resultado</label>
                    <input data-fsm="visibles" type="text" class="form-control">
                </div>
                <div class="form-group">
                    <label for="" class="control-label">Descripcion indicador</label>
                    <input data-fsm="visibles" type="text"...

CSS

input, textarea, select {
    color: lightblue;
    border: 1px dashed  lightblue !important;
    box-shadow: 0px 0px 1px lightblue !important;
}

[readonly], [disabled] {
    color: red;
    border: 1px dashed  red !important;
    box-shadow: 0px 0px 5px red !important;
}

JavaScript

const stages = {
	Inicio              : 1,
    SeguimientoEditable : 2,
    SeguimientoNormal   : 3,
    CierreEvaluacion    : 4
};


function config() {
	var config = {
        initialState: "_init",
        initialize: function() {
        	if( _.isEmpty( this.target ) )
            	throw "Must provide machina targets";
                
        	this.clients = $(this.target);
        },
        states: {},
        clients: [],
        target: "",
        startWith: function( stage ) {
        	this.transition( stage );
        },
        show: show,
        hide: hide,
        block: block,
        unblock: unblock
    };
    
    config.states[ "_init" ] = {
    	"*": function() {
        	console.log("Nothing to do!");
        }
    };
    config.states[ stages.Inicio ] 					= initState();
    config.states[ stages.SeguimientoEditable ]   	= config.states[ stages.Inicio ];
    config.states[ stages.SeguimientoNormal ] 		= config.states[ stages.Inicio ];
    config.states[ stages.CierreEvaluacion ] 		= config.states[ stages.Inicio ];
    
    function show( ) {
    	_.each(this.clients, function( o ) {
        	$(o).parents("[class*='form-group']")["show"]();
        });
        
        return this;
    }
    
    function hide() {
    	_.each(this.clients, function( o ) {
        	$(o).parents("[class*='form-group']")["hide"]();
        });
        
        return this;
    }
    
    function block() {
    	_.each(this.clients, function( o ) {
        	$(o).attr("disabled", true);
        });
        
        return this;
    }
    
    function unblock() {
    	_.each(this.clients, function( o ) {
        	$(o).removeAttr("disabled", true);
        });
        
        return this;
    }
    
    function initState() {
    	return {
            _onEnter: function() {
            	this.show().unblock();
            }
        };
    }
    
    return config;
}

var baseStagesFSM = machina.Fsm.extend( config() );

var visibles = new baseStagesFSM(...