dynamic form for json definition

by Paweł Niemczyk

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/handlebars.js/2.0.0-alpha.4/handlebars.min.js"></script>
<div id="efect"> </div>
<script id="template" type="template/text">
    <div>
    {{#each elems}}
    {{#if this.group}}
        <h2>{{this.group}}</h2>
        <hr>
        <ul>
        {{#each this.items}}
        <li>
            <label for="{{this.name}}">{{this.title}}</label>
            {{#if this.ui.is_textarea}}
            <textarea id="{{this.name}}">{{this.value}}</textarea>
            {{/if}}
            {{#if this.ui.is_text}}
            <input id="{{this.name}}" type="text" value="{{this.value}}" />
            {{/if}}
            {{#if this.ui.is_label}}
            {{this.value}}
            {{/if}}
        </li>
        {{/each}}
        </ul>
    {{else}}
            <p>
            <label for="{{this.name}}">{{this.title}}</label>
            {{#if this.ui.is_textarea}}
            <textarea id="{{this.name}}">{{this.value}}</textarea>
            {{/if}}
            {{#if this.ui.is_text}}
            <input id="{{this.name}}" type="text" value="{{this.value}}" />
            {{/if}}
            {{#if this.ui.is_label}}
            {{this.value}}
            {{/if}}              
            {{#if this.ui.is_select}}
                <select id="{{this.name}}">
                {{#each this.options}}
                    <option value="{{this.value}}" {{#if this.selected}}selected{{/if}}>{{this.name}}</option>
                {{/each}}
                </select>
            {{/if}}
            </p>
    {{/if}}
    {{/each}}
    </div>
</script>
<div id="haml" style="display:none">
{{#each elems}}
{{#if this.group}}
%h2 {{this.group}}
%hr
%ul
	{{#each this.items}}
	%li
		%label{for:"{{this.name}}"} {{this.title}}
		{{#if this.ui.is_textarea}}
		%textarea{id:"{{this.name}}"} {{this.value}}
		{{/if}}
		{{#if this.ui.is_text}}
		%input{id:"{{this.name}}", type:"text", value:"{{this.value}}"}
		{{/if}}
		{{#if...

CoffeeScript

l = (d) -> console.log(d)

json =
    from: '2014-04-02'
    to:   '2014-04-10'
    kind: 'zabiegi_agrotechniczne'
    name: 'podorywka'
    deep: '10 cm'
    width: '5m'
    state_of_sol: 'sucha'
    warnings: ''
    alerts: ''
    worker: 'pawel niemczyk'
    human_cost: 10
    machine_cost: 30
    area:  10
    costs: null
    type_of_work: 10

jsonDefinition = 
    from:
        name: 'od'
        group: 'daty'
        type: 'date'
    to:
        name: 'do'
        group: 'daty'
        type: 'date'
    kind:
        name: 'rodzaj'
        ui:
            is_label: true
    deep:
        name: 'glebokosc'
        group: 'parametry pracy'    
    width:
        name: 'szerokosc'
        group: 'parametry pracy'
    state_of_sol:
        name: 'stan gleby'
    warnings:
        name: 'uwagi'
        ui: 
            is_textarea: true
    alerts:
        name: 'alerty'
        ui: 
            is_textarea: true
    type_of_work:
        name: 'typ pracy'
        type: 'float'
        options: [{name: 'manualna', value:20}, {name:'grabki', value: 10},{name: 'motyka', value: 5}]
        ui:
            is_select: true     
    human_cost:
        name: 'pracownik'
        group: 'koszta'
        type: 'float'
    machine_cost:
        name: 'maszyny'
        group: 'koszta'    
        type: 'float'
    area:
        name: 'powieszchnia'
        group: 'koszta'    
        type: 'float'
    costs:
        name: 'calkowity koszt'
        group: 'koszta'
        type: 'float'
        calc: '( o.human_cost + o.machine_cost ) * o.area'      
   
class JsonFormBuilder
    calc: (o, algorithm) -> eval(algorithm)        
    buildItem: (def, field, json) -> 
        value   = if def[field]['calc'] then @calc(json, def[field]['calc']) else json[field]
        options = def[field]['options']
        if options
            options = $.map options, (o) -> 
                o.selected = o.value is value
                o
        name:    field
        title:  ...