Examples

It is the goal of this tutorial to show you how to build web applications using AtomicJS. Each page contains a new example.

Hello !

View Adapter

                                            
root.atomic.launch ( "#example1", {worldLabel: {value: "World"}} );
                                            
                                        

View

                                            
<div id="example1">
    <div class="example">
        <div class="well">
            <h1 id="greeting">Hello <span id="worldLabel"></span>!</h1>
        </div>
    </div>
</div>
                                            
                                        

Hello !

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example2",
    {
        greeting2:      {bind: { display: "worldValue.length" }},
        worldLabel2:    {bind: "worldValue"},
        sayHelloButton:
        {
            onclick:    function(){this.data("worldValue","World");}, 
            bind:       { display: function(){return !this.data("worldValue.length");} }
        }
    }
);
                                            
                                        

View

                                            
<div id="example2">
    <div class="example">
        <div class="well">
            <h1 id="greeting2">Hello <span id="worldLabel2"></span>!</h1>
            <button id="sayHelloButton">Say Hello</button>
        </div>
    </div>
</div>
                                            
                                        

Hello !

Have a great day !

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example3",
    {
        firstNameTextbox:
        {
            focused:    true,
            bind:       { value: { to: "firstName", updateon: ["keydown", "keyup", "change"] } },
            onescape:   function(){ this.value(""); }
        },
        lastNameTextbox:
        {
            bind:       { value: { to: "lastName", updateon: ["keydown", "keyup", "change"] } },
            onescape:   function(){this.value("");}
        },
        helloMessage:
        {
            bind:   { display: function(){return this.data.hasValue("firstName") || this.data.hasValue("lastName");} }
        },
        nameLabels:
        {
            selector:   ".name",
            bind:       function(data){return (this.data("firstName")||"") + (this.data("firstName") && this.data("lastName")?" ":"") + (this.data("lastName")||"");}
        }
    }
);
                                            
                                        

View

                                            
<div id="example3">
    <div class="example">
        <div class="well form-group">
            <div><input id="firstNameTextbox" autocomplete="off" class="form-control" placeholder="Enter your first name:" /></div>
            <div><input id="lastNameTextbox" autocomplete="off" class="form-control" placeholder="Enter your last name:" /></div>
            <div id="helloMessage">
                <p>Hello <span class="name"></span>!</p>
                <p>Pardon me <span class="name"></span>, but do you have any grey poupon?</p>
            </div>
        </div>
    </div>
</div>
                                            
                                        
You've clicked   times
That's too many clicks! Please stop before you wear out your fingers.

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example4",
    {
        numberOfClicks:         { bind: "clickCount" },
        countClickButton:
        {
            onclick:
            function()
            {
                this.data("clickCount", this.data("clickCount")+1);
            },
            bind:       {enabled: function(){return this.data("clickCount")<3;}}
        },
        tooManyClicksMessage:
        {
            bind:   { display: function(data){return data("clickCount")>=3;} }
        },
        resetClickCountButton:
        {
            onclick:
            function()
            {
                this.data("clickCount",0);
            }
        }
    },
    function(adapter) { adapter.data("", {clickCount:0}); }
);
                                            
                                        

View

                                            
<div id="example4">
    <div class="example">
        <div class="well form-group">
            <div>You've clicked <span id="numberOfClicks"> </span> times</div>

            <button id="incrementClickCounterButton" class="btn">Click me</button>

            <div id="tooManyClicksMessage">
                That's too many clicks! Please stop before you wear out your fingers.
                <button id="resetClickCounterButton" class="btn">Reset clicks</button>
            </div>
        </div>
    </div>
</div>
                                            
                                        

Your items:

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example5",
    {
        newItem:
        {
            bind:       { value: { to: "newItem", updateon:   ["keydown", "keyup", "change"] } },
            onenter:    function(){this.parent.controls.addNewItemButton.click();}
        },
        addNewItemButton:
        {
            bind:       { enabled: "newItem.length" },
            onclick:
            function()
            {
                if (this.data("newItem.length")>0 && this.data("items").indexOf(this.data("newItem"))==-1)
                this.data("items").push(this.data("newItem"));
                this.data("newItem","");
            }
        },
        itemsList:
        {
            bind: "items"
        }
    },
    function(adapter) { adapter.data("", {newItem:"", items: ["Alpha","Beta","Gamma"]}); }
);
                                            
                                        

View

                                            
<div id="example5">
    <div class="example">
        <div class="well form-group">
            <div>
                <div class="form-group"><input id="newItem" class="form-control" /></div>
                <button id="addNewItemButton" type="button" class="btn">Add</button>
                <p>Your items:</p>
                <div class="form-group">
                    <select id="itemsList" multiple="multiple" class="form-control"> </select>
                </div>
            </div>
        </div>
    </div>
</div>
                                            
                                        

Your items:

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example6",
    {
        betterNewItem:
        {
            bind:       { value: { to: "newItem", updateon: ["keydown", "keyup", "change"] } },
            onenter:    function(){this.parent.controls.betterAddNewItemButton.click();}
        },
        betterAddNewItemButton:
        {
            bind:       { enabled: "newItem.length" },
            onclick:
            function()
            {
                if (this.data("newItem.length")>0 && this.data("items").indexOf(this.data("newItem"))==-1)
                this.data("items").push(this.data("newItem"));
                this.data("newItem","");
            }
        },
        betterItemsList:
        {
            bind: {value: "selected", items: "items"}
        },
        removeItemButton:
        {
            bind:       {enabled: "items.length"},
            onclick:    function(){this.data("items").removeAll(this.parent.controls.betterItemsList.value());}
        },
        sortItemsButton:
        {
            bind:       {enabled: function(){return this.data("items.length")>1}},
            onclick:    function(){this.data("items").sort();}
        }
    },
    function(adapter) { adapter.data("", {newItem:"", items: ["Fries","Eggs Benedict","Ham","Cheese"]}); }
);
                                            
                                        

View

                                            
<div id="example4">
    <div class="example">
        <div class="well form-group">
            <div>
                <div class="form-group"><input id="newItem" class="form-control" /></div>
                <button id="addNewItemButton" type="button" class="btn">Add</button>
                <p>Your items:</p>
                <div class="form-group">
                    <select id="itemsList" multiple="multiple" class="form-control"> </select>
                </div>
            </div>
            <div>
                <button id="removeItemButton" class="btn">Remove</button>
                <button id="sortItemsButton" class="btn">Sort</button>
            </div>
        </div>
    </div>
</div>
                                            
                                        

HTML controls

Text value (updates on change):
Text value (updates on keystroke):
Text value (multi-line):
Password:
Checkbox:
Drop-down list:
Multi-select drop-down list:
Radio buttons:
Buttons:
Readonly:
Link:
Link Panel: [ ]
Images:

What's in the model?

Text value:
Url value:
Password:
Bool value:
Selected option:
Multi-selected options:
Radio button selection:
Image path value:

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example7",
    {
        stringValueReadout:             { bind: "stringValue" },
        urlValueReadout:                { bind: "urlValue" },
        passwordValueReadout:           { bind: "passwordValue" },
        booleanValueReadout:            { bind: "booleanValue" },
        selectedValueReadout:           { bind: "selectedValue" },
        multipleSelectedValuesReadout:  { bind: function(data){ return data("multipleSelectedValues")&&data("multipleSelectedValues").join();} },
        radioSelectedOptionReadout:     { bind: "radioSelectedValue" },
        imagePathValueReadout:          { bind: "imageUrl" },
        onChangeTextboxControl:         { bind: "stringValue" },
        onKeyStrokeTextboxControl:      { bind: { value: { to: "stringValue", updateon: ["keydown","keyup","change"] } } },
        textAreaControl:                { bind: "stringValue" },
        passwordControl:                { bind: "passwordValue" },
        checkboxControl:                { bind: "booleanValue" },
        singleDropdownListControl:      { bind: { value: "selectedValue",           items: "items" } },
        multipleListControl:            { bind: { value: "multipleSelectedValues",  items: "items" } },
        radioGroupControl:              { bind: { value: "radioSelectedValue",      items: "items" } },
        buttonControl:                  { bind: "stringValue" },
        readonlyControl:                { bind: "stringValue" },
        linkControl:                    { bind: {value: "stringValue", href: "urlValue" }},
        urlTextboxControl:              { bind: "urlValue" },
        linkPanelControl:
        {
            bind: {href: "urlValue"},
            controls:
            {
                panelReadonly:  { bind: "stringValue" },
                panelUrl:       { bind: "urlValue" }
            }
        },
        imageControl:                   { bind: "imageUrl" },
        imagePathControl:               { bind: { value: "imageUrl",                items: { to: "images", text: "title", value: "url" } } },
        example7model:                  { bind: { value: { to: function(){return JSON.stringify(this.data(), null, '    ');}, root: "" } } }
    },
    function(adapter)
    {
        adapter.data("", 
        {
            stringValue:            "Hello", 
            urlValue:               "https://atomicstack.com",
            passwordValue:          "mypass", 
            booleanValue:           true, 
            selectedValue:          "Gamma", 
            multipleSelectedValues: ["Beta"], 
            radioSelectedValue:     "Alpha",
            imageUrl:               "images/hammock_cat.jpg",
            items:                  ["Alpha","Beta","Gamma"],
            images:
            [
                {
                    title:  "Hammock Cat",
                    url:    "images/hammock_cat.jpg"
                },
                {
                    title:  "Headphones",
                    url:    "images/headphones.jpg"
                },
                {
                    title:  "Nature Scene",
                    url:    "images/nature_scene.png"
                }
            ]
        });
    }
);
                                            
                                        

View

                                            
<div id="example1">
    <div class="example">
        <div class="well">
            <div class="row">
                <div class="col-md-8">
                    <h3>HTML controls</h3>
                    <table class="table table-bordered">
                        <tr class="table-row">
                            <td class="table-cell">Text value (updates on change):</td>
                            <td class="table-cell"><input id="onChangeTextboxControl" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Text value (updates on keystroke):</td>
                            <td class="table-cell"><input id="onKeyStrokeTextboxControl" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Text value (multi-line):</td>
                            <td class="table-cell"><textarea id="textAreaControl"> </textarea></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Password:</td>
                            <td class="table-cell"><input id="passwordControl" type="password" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Checkbox:</td>
                            <td class="table-cell"><input id="checkboxControl" type="checkbox" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Drop-down list:</td>
                            <td class="table-cell"><select id="singleDropdownListControl"></select></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Multi-select drop-down list:</td>
                            <td class="table-cell"><select id="multipleListControl" multiple="multiple"></select></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Radio buttons:</td>
                            <td class="table-cell">
                                <radiogroup id="radioGroupControl">
                                    <radiogroupitem class="radio-inline">
                                        <input type="radio" /><label></label>
                                    </radiogroupitem>
                                </radiogroup>
                            </td>
                        </tr>
                        <tr>
                            <td class="table-cell">Buttons:</td>
                            <td class="table-cell">
                                <button id="buttonControl"></button>
                            </td>
                        </tr>
                        <tr>
                            <td class="table-cell">Readonly:</td>
                            <td class="table-cell"><span id="readonlyControl"></a></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Link:</td>
                            <td class="table-cell"><a id="linkControl"></a><br/><input id="urlTextboxControl" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Link Panel:</td>
                            <td class="table-cell"><a id="linkPanelControl"><span id="panelReadonly"></span> [ <span id="panelUrl"></span> ]</a></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Images:</td>
                            <td class="table-cell">
                                <img id="imageControl"></img><br/>
                                <radiogroup id="imagePathControl">
                                    <radiogroupitem class="radio-inline"><input type="radio" /><label></label></radiogroupitem>
                                </radiogroup>
                            </td>
                        </tr>
                    </table>
                </div>
                <div class="col-md-4">
                    <h3>What's in the model?</h3>
                    <table class="table table-bordered">
                        <tr>
                            <td class="table-cell">Text value:</td>
                            <td class="table-cell" id="stringValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Url value:</td>
                            <td class="table-cell" id="urlValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Password:</td>
                            <td class="table-cell" id="passwordValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Bool value:</td>
                            <td class="table-cell" id="booleanValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Selected option:</td>
                            <td class="table-cell" id="selectedValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Multi-selected options:</td>
                            <td class="table-cell" id="multipleSelectedValuesReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Radio button selection:</td>
                            <td class="table-cell" id="radioSelectedOptionReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Image path value:</td>
                            <td class="table-cell" id="imagePathValueReadout"></td>
                        </tr>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
                                            
                                        

People

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example8",
    {
        peopleList:
        {
            bind:   "people",
            repeat:
            {
                peopleListItemTemplate:
                {
                    getKey:     function(data){return "person-"+this.index;},
                    controls:
                    {
                        personNameLabel:    { bind:     "name" },
                        childCountLabel:    { bind:     "children.length" },
                        addChildLink:       { onclick:  function(){this.data("children").push({name:"New Child"});} },
                        renderTimeSection:  { bind:     { display: "::showRenderTimes" } },
                        renderTimeLabel:    { bind:     function(data){return new Date().getSeconds();} },
                        childList:
                        {
                            bind:   "children",
                            repeat:
                            {
                                childListItemTemplate:
                                {
                                    getKey:     function(data){return "person-"+this.parent.parent.data("name")+"-child-"+this.index;},
                                    controls:
                                    {
                                        childNameLabel:         { bind: "name" },
                                        childRenderTimeSection: { bind: { display: "::showRenderTimes" } },
                                        childRenderTimeLabel:   { bind: function(data){return new Date().getSeconds();} },
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        showRenderTimesCheckbox:    { bind: "showRenderTimes" }
    },
    function(adapter)
    {
        adapter.data
        ("",
        {
            showRenderTimes:    false,
            people:
            [
                {name:"Anabelle",   children: ["Arnie","Anders","Apple"]},
                {name:"Bertie",     children: ["Boutros-Boutros","Brianna","Barbie","Bee-bop"]},
                {name:"Charles",    children: ["Cayenne","Cleopatra"]}
            ]
        });
    }
);
                                            
                                        

View

                                            
<div id="example1">
    <div class="example">
        <div class="well">
            <h2>People</h2>
            <ul id="peopleList">
                <li id="peopleListItemTemplate">
                    <div>
                        <span id="personNameLabel"> </span> has <span id="childCountLabel"> </span> children:
                        <a id="addChildLink" class="clickable">Add child</a>
                        <span id="renderTimeSection" class="renderTime">
                            (person rendered at <span id="renderTimeLabel"> </span>)
                        </span>
                    </div>
                    <ul id="childList">
                        <li id="childListItemTemplate">
                            <span id="childNameLabel"> </span>
                            <span id="childRenderTimeSection" class="renderTime">
                                (child rendered at <span id="childRenderTimeLabel"> </span>)
                            </span>
                        </li>
                    </ul>
                </li>
            </ul>
            <label><input id="showRenderTimesCheckbox" type='checkbox' /> Show render times</label> 
        </div>
    </div>
</div>
                                            
                                        

Hello !

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example9",
    {
        inputPanel:
        {
            bind:       "input",
            controls:
            {
                firstNameTextbox9:
                {
                    focused:    true,
                    bind:       { value: { to: "firstName", updateon: ["keydown", "keyup", "change"] } },
                    onescape:   function(){ this.value(""); }
                },
                lastNameTextbox9:
                {
                    bind:       { value: { to: "lastName", updateon: ["keydown", "keyup", "change"] } },
                    onescape:   function(){this.value("");}
                }
            }
        },
        helloMessage9:
        {
            bind:       { value: "input", display: function(){return this.data.hasValue("input.firstName") || this.data.hasValue("input.lastName");} },
            controls:
            {
                nameLabels:
                {
                    selector:   ".name",
                    bind:       function(data){return (this.data("firstName")||"") + (this.data("firstName") && this.data("lastName")?" ":"") + (this.data("lastName")||"");}
                }
            }
        }
    }
);
                                            
                                        

View

                                            
<div id="example3">
    <div class="example">
        <div class="well form-group">
            <div id="inputPanel">
                <div><input id="firstNameTextbox9" autocomplete="off" class="form-control" placeholder="Enter your first name:" /></div>
                <div><input id="lastNameTextbox9" autocomplete="off" class="form-control" placeholder="Enter your last name:" /></div>
            </div>
            <div id="helloMessage9">
                <p>Hello <span class="name"></span>!</p>
                <p>Pardon me <span class="name"></span>, but do you have any grey poupon?</p>
            </div>
        </div>
    </div>
</div>
                                            
                                        

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example10",
    {
        example10container:
        {
            type:       "panel",
            classes:    "example",
            controls:
            {
                well:
                {
                    selector:   ".well",
                    type:       "panel",
                    classes:    "well form-group",
                    controls:
                    {
                        betterNewItem10:
                        {
                            type:       "input",
                            bind:       { value: { to: "newItem", updateon: ["keydown", "keyup", "change"] } },
                            onenter:    function(){this.parent.controls.betterAddNewItemButton10.click();}
                        },
                        betterAddNewItemButton10:
                        {
                            type:       "button",
                            bind:       { enabled: "newItem.length" },
                            onclick:
                            function()
                            {
                                if (this.data("newItem.length")>0 && this.data("items").indexOf(this.data("newItem"))==-1)
                                this.data("items").push(this.data("newItem"));
                                this.data("newItem","");
                            }
                        }
                    }
                },
                itemsTitle:
                {
                    type:   "readonly",
                    value:  "Your items:"
                },
                formgroup:
                {
                    selector:   ".listContainer",
                    type:       "panel",
                    classes:    "listContainer form-group",
                    controls:
                    {
                        betterItemsList10:
                        {
                            type:   "multiselect",
                            bind:   {value: "selected", items: "items"}
                        },
                        removeItemButton10:
                        {
                            type:       "button",
                            bind:       {enabled: "items.length"},
                            onclick:    function(){this.data("items").removeAll(this.parent.controls.betterItemsList10.value());}
                        },
                        sortItemsButton:
                        {
                            type:       "button",
                            bind:       {enabled: function(){return this.data("items.length")>1}},
                            onclick:    function(){this.data("items").sort();}
                        }
                    }
                }
            }
        },
        example10model:  { bind: { value: { to: function(){return JSON.stringify(this.data(), null, '    ');}, root: "" } } }
    },
    function(adapter) { adapter.data("", {newItem:"", items: ["Fries","Eggs Benedict","Ham","Cheese"]}); }
);
                                            
                                        

View

                                            
<div id="example10">
    <div id="example10container" class="example">
    </div>
</div>
                                            
                                        

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example11",
    {
        newTodo:
        {
            bind:       {value: {to: "newTodo", updateon:["keyup", "change"]}}, 
            onenter:    function(){this.parent.controls.addTodo.click();}
        },
        addTodo:        {onclick: function()
        {
            this.data("todos").push({description: this.data("newTodo"), done: false});
            this.data("newTodo", "");
        }},
        todoList:
        {
            bind:   "todos",
            repeat:
            {
                todoListItem:
                {
                    controls:
                    {
                        todoDone:           {bind: "done"},
                        todoDescription:    {bind: {value: "description", classes: {strikethrough: "done"}}},
                        removeTodo:         {onclick: function()
                        {
                            this.data("...todos").remove(this.data());
                        }}
                    }
                }
            }
        },
        example11model:  { bind: { value: { to: function(){return JSON.stringify(this.data(), null, '    ');}, root: "" } } }
    },
    function(adapter) { adapter.data("todos", []); }
);
                                            
                                        

View

                                            
<div id="example2">
    <div class="example">
        <style>.strikethrough{text-decoration: line-through;}</style>
        <div class="well form-group">
            <h1 id="example11title"></h1>
            <fieldset>
                <input id="newTodo" type="text">
                <button id="addTodo">Add Todo</button>
            </fieldset>
            <ul id="todoList">
                <li id="todoListItem">
                    <input id="todoDone" type="checkbox">
                    <span id="todoDescription"></span>
                    <button id="removeTodo">Remove</button>
                </li>
            </ul>
        </div>
    </div>
</div>
                                            
                                        

Model


                                        

View Adapter

                                            
root.atomic.ready(function(atomic)
{
    var textboxControl  = atomic.viewAdapterFactory.createFactory
    (
        {
            controls:
            {
                label:
                {
                    selector:   ".textbox-label"
                },
                input:
                {
                    selector:   ".textbox-input"
                }
            },
            properties:
            {
                label:
                {
                    get: function(){return this.controls.label.value();},
                    set: function(value){this.controls.label.value(value);}
                },
                value:  function(){return this.controls.input.value}
            },
            extensions:
            [{
                initializers:
                {
                    label:  function(adapter, value){adapter.label = value;}
                }
            }]

        },
        "#example12 .textbox-field-control"
    );
    var readonlyControl = atomic.viewAdapterFactory.createFactory
    (
        {
            controls:
            {
                label:
                {
                    selector:   ".readonly-label"
                },
                readout:
                {
                    selector:   ".readonly-readout"
                }
            },
            properties:
            {
                label:
                {
                    get: function(){return this.controls.label.value();}, 
                    set: function(value){this.controls.label.value(value);}
                },
                value:  function(){return this.controls.readout.value}
            },
            extensions:
            [{
                initializers:
                {
                    label:  function(adapter, value){adapter.label = value;}
                }
            }]

        },
        "#example12 .readonly-field-control"
    );
    atomic.viewAdapterFactory.launch
    (
        "#example12",
        {
            example12container:
            {
                controls:
                {
                    firstName:
                    {
                        factory:    textboxControl, 
                        label:      "First Name:", 
                        bind:       {value: {to: "firstName", updateon: ["keyup", "change"] } }
                    },
                    lastName:
                    {
                        factory:    textboxControl, 
                        label:      "Last Name:", 
                        bind:       {value: {to: "lastName", updateon: ["keyup", "change"] } }
                    },
                    fullName:
                    {
                        factory:    readonlyControl, 
                        label:      "Full Name:", 
                        bind: 
                        {
                            value:      function()
                            {
                                return (this.data("firstName")||"") + " " + (this.data("lastName")||"");
                            }, 
                            display:    function()
                            {
                                return (this.data("firstName")||"").length > 0
                                ||
                                (this.data("lastName")||"").length > 0;
                            } 
                        }
                    }
                }
            }
        }
    );
});
                                            
                                        

View

                                            
<div id="example2">
    <div class="example">
        <div id="example12container" class="well form-group">
            <div class="textbox-field-control">
                <label class="textbox-label"></label>
                <input class="textbox-input">
            </div>
            <div class="readonly-field-control">
                <label class="readonly-label"></label>
                <span class="readonly-readout"></span>
            </div>
        </div>
    </div>
</div>