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: { when: "worldValue", hasValue: false } }
        }
    }
);
                                            
                                        

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: { when: "clickCount", "<": 3 } }
        },
        tooManyClicksMessage:
        {
            bind:   { display: { when: "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: { when: "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 group:
Checkbox group:
Buttons:
Readonly:
Link:
Link Panel: [ ]
Images:
Audio:

Time lapsed:
Volume:
Video:

Time lapsed:
Volume:
Details:

What's in the model?

Text value:
Url value:
Password:
Bool value:
Selected option (single select and radio group):
Multi-selected options (multi select and checkbox group):
Image path value:
Audio path value:
Video path value:
Summary:
Details Toggled:

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();} },
        imagePathValueReadout:          { bind: "imageUrl" },
        audioPathValueReadout:          { bind: "audioUrl" },
        videoPathValueReadout:          { bind: "videoUrl" },
        summaryReadout:                 { bind: "summary" },
        detailsToggledReadout:          { bind: "$shadow.detailsToggled" },
        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: "selectedValue",           items: "items" } },
        checkboxGroupControl:           { bind: { value: "multipleSelectedValues",  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" } } },
        audioControl:
        {
            bind:
            {
                value:          "audioUrl",
                currentTime:    "$shadow.audioTimeLapsed",
                volume:         "audioVolume"
            },
            nativeControls: true,
            preload:        true
        },
        audioTimeLapsed:                { bind: function(){return this.data("$shadow.audioTimeLapsed")||0;} },
        audioVolume:                    { bind: { value: { get: function(){return (this.data("audioVolume")||0)*100;}, set: function(data, value){this.data("audioVolume", value/100);} } } },
        audioPathControl:               { bind: { value: "audioUrl",                items: { to: "sounds", text: "title", value: "url" } } },
        videoControl:
        {
            bind:
            {
                value:          "videoUrl",
                currentTime:    "$shadow.videoTimeLapsed",
                volume:         "videoVolume"
            },
            nativeControls: true,
            preload:        true
        },
        videoTimeLapsed:                { bind: function(){return this.data("$shadow.videoTimeLapsed")||0;} },
        videoVolume:                    { bind: { value: { get: function(){return (this.data("videoVolume")||0)*100;}, set: function(data, value){this.data("videoVolume", value/100);} } } },
        videoPathControl:               { bind: { value: "videoUrl",                items: { to: "videos", text: "title", value: "url" } } },
        detailsControl:
        {
            bind:
            {
                open:       "$shadow.detailsToggled",
                summary:    "summary"
            },
            controls:
            {
                detailsNestedInput: { bind: "stringValue" }
            }
        },
        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"], 
            imageUrl:               "images/hammock_cat.jpg",
            audioUrl:               "audio/birds_after_rain.mp3",
            videoUrl:               "video/Countdown.mov",
            audioVolume:            1,
            videoVolume:            1,
            summary:                "This is the summary",
            details:                "These are the details.",
            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"
                }
            ],
            sounds:
            [
                {
                    title:  "Birds",
                    type:   "audio/mpeg",
                    url:    "audio/birds_after_rain.mp3"
                },
                {
                    title:  "Clock",
                    type:   "audio/mpeg",
                    url:    "audio/clock_chimes.mp3"
                },
                {
                    title:  "Ocean",
                    type:   "audio/mpeg",
                    url:    "audio/crisp_ocean_waves.mp3"
                },
                {
                    title:  "Sunny Day",
                    type:   "audio/mpeg",
                    url:    "audio/sunny_day.mp3"
                },
                {
                    title:  "Wind",
                    type:   "audio/mpeg",
                    url:    "audio/wind.mp3"
                }
            ],
            videos:
            [
                {
                    title:  "Background",
                    type:   "video/mov",
                    url:    "video/Background.mov"
                },
                {
                    title:  "Countdown",
                    type:   "video/mov",
                    url:    "video/Countdown.mov"
                },
                {
                    title:  "Earth",
                    type:   "video/mov",
                    url:    "video/Earth.mov"
                },
                {
                    title:  "Milky Way",
                    type:   "video/mp4",
                    url:    "video/Milky_Way.mp4"
                }
            ]
        });
    }
);
                                            
                                        

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">Checkbox group:</td>
                            <td class="table-cell">
                                <checkboxgroup id="checkboxGroupControl">
                                    <checkboxgroupitem class="checkbox-inline"><input type="checkbox" /><label></label></checkboxgroupitem>
                                </checkboxgroup>
                            </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>
                        <tr>
                            <td class="table-cell">Audio:</td>
                            <td class="table-cell">
                                <audio id="audioControl"></audio><br/>
                                <radiogroup id="audioPathControl">
                                    <radiogroupitem class="radio-inline"><input type="radio" /><label></label></radiogroupitem>
                                </radiogroup>
                                <br/>
                                Time lapsed: <span id="audioTimeLapsed"></span><br/>
                                Volume: <input type="number" id="audioVolume" />
                            </td>
                        </tr>
                        <tr>
                            <td class="table-cell">Video:</td>
                            <td class="table-cell">
                                <video id="videoControl" class="videoPlayer"></video><br/>
                                <radiogroup id="videoPathControl">
                                    <radiogroupitem class="radio-inline"><input type="radio" /><label></label></radiogroupitem>
                                </radiogroup>
                                <br/>
                                Time lapsed: <span id="videoTimeLapsed"></span><br/>
                                Volume: <input type="number" id="videoVolume" />
                            </td>
                        </tr>
                        <tr>
                            <td class="table-cell">Details:</td>
                            <td class="table-cell">
                                <details id="detailsControl">
                                    <input type="text" id="detailsNestedInput" />
                                </details>
                            </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 (single select and radio group):</td>
                            <td class="table-cell" id="selectedValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Multi-selected options (multi select and checkbox group):</td>
                            <td class="table-cell" id="multipleSelectedValuesReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Image path value:</td>
                            <td class="table-cell" id="imagePathValueReadout"></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Audio path value:</td>
                            <td class="table-cell" id="audioPathValueReadout"></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){data("name"); 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){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","Bee-bop","Brianna","Barbie"]},
                {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",
                            classes:    ["form-control"],
                            bind:       { value: { to: "newItem", updateon: ["keydown", "keyup", "change"] } },
                            onenter:    function(){this.parent.controls.betterAddNewItemButton10.click();}
                        },
                        betterAddNewItemButton10:
                        {
                            type:       "button",
                            classes:    ["btn"],
                            value:      "Add",
                            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", "well", "form-group"],
                    controls:
                    {
                        betterItemsList10:
                        {
                            type:       "multiselect",
                            classes:    ["form-control"],
                            bind:       { value: "selected", items: "items" }
                        },
                        listButtons:
                        {
                            selector:   ".listButtons",
                            type:       "panel",
                            controls:
                            {
                                removeItemButton10:
                                {
                                    type:       "button",
                                    classes:    ["btn"],
                                    value:      "Remove",
                                    bind:       {enabled: "items.length"},
                                    onclick:    function(){this.data("items").removeAll(this.parent.parent.controls.betterItemsList10.value());}
                                },
                                sortItemsButton:
                                {
                                    type:       "button",
                                    classes:    ["btn"],
                                    value:      "Sort",
                                    bind:       { enabled: { when: "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>
                                            
                                        

Control bindings

Readonly with attributes: This control has attributes
Text control (reacts to disabled):
Text control (reacts to display):
Text control (reacts to enabled):
Label control (reacts to for):
Panel control (reacts to id):
The id of this panel changes dynamically
Panel control (reacts to tooltip):
The tooltip of this panel changes dynamically.
Try hovering the mouse over it.
Textarea control (reacts to value):
Panel control (reacts to classes):
The classes applied to this panel changes dynamically.
Image control (reacts to alt):

Settings

Disabled:
Display:
Enabled:
For:
Id:
Tooltip:
Value:
Add Border:
Add Bold:
Add Italics:
Add Padding:
Custom Class:
Alt:

What's in the view?

Readonly with attributes:
Text control (reacts to disabled):
Text control (reacts to display):
Text control (reacts to enabled):
Label control (reacts to for):
Panel control (reacts to id):
Panel control (reacts to tooltip):
Textarea control (reacts to value):
Panel control (reacts to classes):
Image control (reacts to alt):

Model


                                        

View Adapter

                                            
root.atomic.launch
(
    "#example13",
    {
        readonlyWithAttributesControl:          { bind: { attributes: { to: "settings", root: "settings" } } },
        disabledExampleControl:                 { bind: { disabled: "settings.disabled" } },
        displayExampleControl:                  { bind: { display: "settings.display" } },
        enabledExampleControl:                  { bind: { enabled: "settings.enabled" } },
        labelForControl:                        { bind: { for: "settings.for" } },
        dynamicIdControl:                       { bind: { id: "settings.id" } },
        tooltipControl:                         { bind: { tooltip: "settings.tooltip" } },
        valueControl:                           { bind: { value: "settings.value" } },
        classesControl:
        {
            bind:
            {
                classes:
                {
                    addBorder:  { when: "classBindings.classes.addBorder" },                        // default operation is a bool check (customClass can affect this value)
                    addItalics: { when: "classBindings.classes.addItalics" },                       // default operation is a bool check (customClass can affect this value)
                    addBold:    { when: "classBindings.classes.addBold",      equals: true },       // alternative operation equals
                    addPadding: { when: "classBindings.classes.addPadding",   notequals: false }    // alternative operation notequals
                }
            }
        },
        altControl:                             { bind: { alt: "settings.alt" } },




        disabledCheckbox:                       { bind: "settings.disabled" },
        displayCheckbox:                        { bind: "settings.display" },
        enabledCheckbox:                        { bind: "settings.enabled" },
        forList:                                { bind: { value: "settings.for",    items: "controls" } },
        idTextbox:                              { bind: { value: { to: "settings.id",        updateon: ["keydown", "keyup", "change"] } } },
        tooltipTextbox:                         { bind: { value: { to: "settings.tooltip",   updateon: ["keydown", "keyup", "change"] } } },
        valueTextbox:                           { bind: { value: { to: "settings.value",     updateon: ["keydown", "keyup", "change"] } } },
        addBorderCheckbox:                      { bind: "classes.addBorder" },
        addBoldCheckbox:                        { bind: "classes.addBold" },
        addItalicsCheckbox:                     { bind: "classes.addItalics" },
        addPaddingCheckbox:                     { bind: "classes.addPadding" },
        altTextbox:                             { bind: { value: { to: "settings.alt",   updateon: ["keydown", "keyup", "change"] } } },




        /* BEGIN: these controls are here to display the contents of the view */

        readonlyWithAttributesControlWrapper:   {},
        disabledExampleControlWrapper:          {},
        displayExampleControlWrapper:           {},
        enabledExampleControlWrapper:           {},
        labelForControlWrapper:                 {},
        dynamicIdControlWrapper:                {},
        tooltipControlWrapper:                  {},
        valueControlWrapper:                    {},
        classesControlWrapper:                  {},
        altControlWrapper:                      {},
        readonlyWithAttibutesControlReadout:    { bind: { value: { to: function(item){item("settings"); return this.parent.controls.readonlyWithAttributesControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");}, root: "settings" } } },
        disabledExampleControlReadout:          { bind: { value: { to: function(item){item("settings.disabled"); return this.parent.controls.disabledExampleControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        displayExampleControlReadout:           { bind: { value: { to: function(item){item("settings.display"); return this.parent.controls.displayExampleControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        enabledExampleControlReadout:           { bind: { value: { to: function(item){item("settings.enabled"); return this.parent.controls.enabledExampleControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        labelForControlReadout:                 { bind: { value: { to: function(item){item("settings.for"); return this.parent.controls.labelForControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        dynamicIdControlReadout:                { bind: { value: { to: function(item){item("settings.id"); return this.parent.controls.dynamicIdControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        tooltipControlReadout:                  { bind: { value: { to: function(item){item("settings.tooltip"); return this.parent.controls.tooltipControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        valueControlReadout:                    { bind: { value: { to: function(item){item("settings.value"); return this.parent.controls.valueControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },
        classesControlReadout:                  { bind: { value: { to: function(item){item("classBindings"); return this.parent.controls.classesControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");}, root: "classBindings" } } },
        altControlReadout:                      { bind: { value: { to: function(item){item("settings.alt"); return this.parent.controls.altControlWrapper.value().replace(/\</g, "<").replace(/\>/g, ">");} } } },

        /* END: these controls are here to display the contents of the view */

        example13model:                         { bind: { value: { to: function(){return JSON.stringify(this.data(), null, '    ');}, root: "" } } }
    },
    function(adapter)
    {
        adapter.data("", 
        {
            settings:
            {
                disabled:       false,
                display:        true,
                enabled:        true,
                for:            "disabledExampleControl",
                id:             "someUniqueId",
                tooltip:        "This is a tooltip!",
                value:          "A value fit for a control",
                alt:            "Depending on your browser this text might appear when the value property of the image has not been set or bound or is non existent."
            },
            classBindings:
            {
                classes:
                {
                    addBorder:      false,
                    addBold:        false,
                    addItalics:     false,
                    addPadding:     false
                },
                customClass:    "customClass"
            },
            controls:   ["disabledExampleControl", "displayExampleControl", "enabledExampleControl"]
        });
    }
);
                                            
                                        

View

                                            
<div id="example13">
    <div class="example">
        <div class="well">
            <div class="row">
                <div class="col-md-8">
                    <h3>Control bindings</h3>
                    <style>
                        .addBorder  { border: solid 2px black; }
                        .addBold    { font-weight: bold; }
                        .addItalics { font-style: italic; }
                        .addPadding { padding: 20px; }
                    </style>
                    <table class="table table-bordered">
                        <tr>
                            <td class="table-cell">Readonly with attributes:</td>
                            <td class="table-cell" id="readonlyWithAttributesControlWrapper"><span id="readonlyWithAttributesControl">This control has attributes</span></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to disabled):</td>
                            <td class="table-cell" id="disabledExampleControlWrapper"><input id="disabledExampleControl" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to display):</td>
                            <td class="table-cell" id="displayExampleControlWrapper"><input id="displayExampleControl" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to enabled):</td>
                            <td class="table-cell" id="enabledExampleControlWrapper"><input id="enabledExampleControl" /></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Label control (reacts to for):</td>
                            <td class="table-cell" id="labelForControlWrapper"><label id="labelForControl">This label can be set for another element.<br/>Clicking on this label will set focus to that control.</label></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Panel control (reacts to id):</td>
                            <td class="table-cell" id="dynamicIdControlWrapper"><div id="dynamicIdControl">The id of this panel changes dynamically</div></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Panel control (reacts to tooltip):</td>
                            <td class="table-cell" id="tooltipControlWrapper"><div id="tooltipControl">The tooltip of this panel changes dynamically.<br/>Try hovering the mouse over it.</div></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Textarea control (reacts to value):</td>
                            <td class="table-cell" id="valueControlWrapper"><textarea id="valueControl"></textarea></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Panel control (reacts to classes):</td>
                            <td class="table-cell" id="classesControlWrapper"><div id="classesControl">The classes applied to this panel changes dynamically.</div></td>
                        </tr>
                        <tr>
                            <td class="table-cell">Image control (reacts to alt):</td>
                            <td class="table-cell" id="altControlWrapper"><img id="altControl" src="nonexistent.png" width="150" height="60" /></td>
                        </tr>
                    </table>
                </div>
                <div class="col-md-4">
                    <h3>Settings</h3>
                    <table class="table table-bordered">
                        <tr class="table-row">
                            <td class="table-cell">Disabled:</td>
                            <td class="table-cell"><input id="disabledCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Display:</td>
                            <td class="table-cell"><input id="displayCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Enabled:</td>
                            <td class="table-cell"><input id="enabledCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">For:</td>
                            <td class="table-cell"><select id="forList"></select></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Id:</td>
                            <td class="table-cell"><input id="idTextbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Tooltip:</td>
                            <td class="table-cell"><input id="tooltipTextbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Value:</td>
                            <td class="table-cell"><input id="valueTextbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Add Border:</td>
                            <td class="table-cell"><input id="addBorderCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Add Bold:</td>
                            <td class="table-cell"><input id="addBoldCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Add Italics:</td>
                            <td class="table-cell"><input id="addItalicsCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Add Padding:</td>
                            <td class="table-cell"><input id="addPaddingCheckbox" type="checkbox" class="checkbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Custom Class:</td>
                            <td class="table-cell"><input id="customClassTextbox" /></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Alt:</td>
                            <td class="table-cell"><input id="altTextbox" /></td>
                        </tr>
                    </table>
                </div>
                <div class="col-md-12">
                    <h3>What's in the view?</h3>
                    <table class="table table-bordered">
                        <tr class="table-row">
                            <td class="table-cell">Readonly with attributes:</td>
                            <td class="table-cell" id="readonlyWithAttibutesControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to disabled):</td>
                            <td class="table-cell" id="disabledExampleControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to display):</td>
                            <td class="table-cell" id="displayExampleControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Text control (reacts to enabled):</td>
                            <td class="table-cell" id="enabledExampleControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Label control (reacts to for):</td>
                            <td class="table-cell" id="labelForControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Panel control (reacts to id):</td>
                            <td class="table-cell" id="dynamicIdControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Panel control (reacts to tooltip):</td>
                            <td class="table-cell" id="tooltipControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Textarea control (reacts to value):</td>
                            <td class="table-cell" id="valueControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Panel control (reacts to classes):</td>
                            <td class="table-cell" id="classesControlReadout"></td>
                        </tr>
                        <tr class="table-row">
                            <td class="table-cell">Image control (reacts to alt):</td>
                            <td class="table-cell" id="altControlReadout"></td>
                        </tr>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
                                            
                                        

View Adapter is dynamically loaded

                                            
                                            // No Local Code
                                            
                                        

View

                                            
<div id="example14">
    <div class="example" id="exampleViewHost">
    </div>
</div>