A better MVVM example

1 posts, 0 answers
  1. Daniel
    Daniel avatar
    21 posts
    Member since:
    Nov 2011

    Posted 16 Jul 2012 Link to this post

    I revised the MVVM example index.html that ships with Kendo UI Web.  The form element is host to the kendo controls instead of the browser's controls.  This example also includes sample validation logic.  Hope this helps someone:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Basic usage</title>
        <script src="../../../js/jquery.min.js"></script>
        <script src="../../../js/kendo.web.min.js"></script>
        <script src="../../content/shared/js/console.js"></script>
        <link href="../../../styles/kendo.common.min.css" rel="stylesheet" />
        <link href="../../../styles/kendo.default.min.css" rel="stylesheet" />
    </head>
    <body>
        <a href="../index.html">Back</a>
        <div id="example" class="k-content">
        <div class="current-state">
            <h4>Current view model state:</h4>
            <pre>
        {
            firstName: <span data-bind="text: ds.firstName"></span>,
            lastName: <span data-bind="text: ds.lastName"></span>,
            gender: <span data-bind="text: ds.gender.value"></span>,
            agreed: <span data-bind="text: ds.agreed"></span>
        }
            </pre>
        </div>
        <div class="registration">
            <form>
                <ul>
                    <li><label for="fname">First Name:</label><input id="fname" name="fname" data-bind="value: ds.firstName" /></li>
                    <!-- working example of a custom message in markup -->
                    <li><label for="lname">Last Name:</label><input type="text" id="lname" name="lname" required="required" pattern="^[S|s][A-Za-z].*$" validationmessage="Last name must begin with 'S'." data-bind="value: ds.lastName" /><span class="k-invalid-msg" data-for="lname"></span></li>
                    <li>
                        <label for="gender">Gender:</label>
                        <input id="gender" name="gender" type="text" required="required" data-bind="source: genders, value: ds.gender" validationmessage="Gender is required."></select><span class="k-invalid-msg" data-for="gender"></span>
                    </li>
                </ul>
                
                <div style="padding-top: 11px; margin: 0 auto;">
                    <input type="checkbox" id="agree" data-bind="checked: ds.agreed" /> <label for="agree">I have read the license agreement.</label><br />
                    <div style="padding-top: 4px; float: left;" >
                        <button id="btnRegister" data-bind="click: register, enabled: enableBasedOnAgree" class="k-button">Register</button>
                    </div>
                </div>
            </form>
        </div>
        <div class="confirmation" data-bind="visible: ds.confirmed">
            Thank you for your registration, <span data-bind="text: ds.firstName"></span> <span data-bind="text: ds.lastName"></span>
            <br />
            <button data-bind="click: startOver">Start Over</button>
        </div>
        <script>
            $(document).ready(function () {
                var genderCollection = [{ description: "Guy", value: "Male" }, { description: "Girl", value: "Female"}];
                var genderElement = ('input[id*="gender"]');


                $(genderElement).width(($("#fname").width() + 2));
                $(genderElement).css("margin-left", "-2px");
                $(genderElement).kendoComboBox({ dataValueField: "value", dataTextField: "description" });


                var viewModel = kendo.observable({
                    genders: genderCollection,
                    enableBasedOnAgree: function (e) {
                        if (this.get("ds.agreed") == true) {
                            $("#btnRegister").attr('class', 'k-button');
                            return true;
                        } else {
                            $("#btnRegister").attr('class', 'k-button k-state-disabled');
                            return false;
                        }
                    },
                    register: function (e) {
                        e.preventDefault();
                        this.set("ds.confirmed", true);
                    },
                    startOver: function () {
                        this.set("ds.confirmed", false);
                        this.set("ds.agreed", false);
                        this.set("ds.gender", { description: "Girl", value: "Female" });
                        this.set("ds.firstName", "Cyndi");
                        this.set("ds.lastName", "Watson");
                    },
                    ds: new kendo.data.DataSource({
                        schema: {
                            model: {
                                fields: {
                                    firstName: {
                                        type: "String",
                                        defaultValue: "John"
                                    },
                                    lastName: {
                                        defaultValue: "Doe",
                                        type: "String"
                                    },
                                    gender: {
                                        type: "String",
                                        defaultValue: "Male"
                                    },
                                    agreed: {
                                        defaultValue: false,
                                        type: "Boolean"
                                    },
                                    confirmed: {
                                        type: "Boolean",
                                        defaultValue: false
                                    }
                                }
                            }
                        }
                    })
                });


                kendo.bind($("#example"), viewModel);
                viewModel.startOver();


                // working example of how to get a viewModel value 
                //
                // alert(viewModel.get("ds.firstName"));
                var formValidator = $("#example").kendoValidator().data("kendoValidator");


                // working custom validation rule inside of kendoValidator //
                /*
                var formValidator = $("#example").kendoValidator({
                    rules: {
                        lastName: function (input) {
                            var isValidated = true;
                            var lNameValue = input.val();


                            if ($(input).attr('name') == 'lname') {
                                if ((lNameValue != undefined) && (lNameValue.length > 0)) {
                                    if (lNameValue.toLowerCase().indexOf("s") != 0) {
                                        isValidated = false;
                                    }
                                }
                            }


                            return isValidated;
                        }
                    }
                }).data("kendoValidator");
                */


                // working code required for validating kendoComboBox object input //
                //
                $("span.k-dropdown-wrap").focusout(function () {
                    console.log('Going to validate now upon focusout event ...');
                    formValidator.validate();
                });
                
            });
        </script>


        <div class="source code-sample">
            <h4 class="code-title">View (old) source code:</h4>
            <pre class="prettyprint">
    &lt;form&gt;
        &lt;label&gt;First Name: &lt;input data-bind=&quot;value: firstName&quot; /&gt;&lt;/label&gt;
        &lt;label&gt;Last Name: &lt;input data-bind=&quot;value: lastName&quot; /&gt;&lt;/label&gt;
        &lt;label&gt;Gender:
            &lt;select data-bind=&quot;source: genders, value: gender&quot;&gt;&lt;/select&gt;
        &lt;/label&gt;
        &lt;label&gt;&lt;input type=&quot;checkbox&quot; data-bind=&quot;checked: agreed&quot; /&gt; I have read the licence agreement&lt;/label&gt;
        &lt;button data-bind=&quot;enabled: agreed, click: register&quot;&gt;Register&lt;/button&gt;
        &lt;div data-bind=&quot;visible: confirmed&quot;&gt;
            &lt;h4&gt;Confirmation&lt;/h4&gt;
            &lt;div&gt;
                Thank you for your registration, &lt;span data-bind=&quot;text: firstName&quot;&gt;&lt;/span&gt; &lt;span data-bind=&quot;text: lastName&quot;&gt;&lt;/span&gt;
                &lt;br /&gt;&lt;br /&gt;
                &lt;button data-bind=&quot;click: startOver&quot;&gt;Start Over&lt;/button&gt;
            &lt;/div&gt;
        &lt;/div&gt;
    &lt;/form&gt;
            </pre>
        </div>
        <div class="source code-sample">
            <h4 class="code-title">View model source code:</h4>
            <pre class="prettyprint">
        var viewModel = kendo.observable({
            firstName: &quot;John&quot;,
            lastName: &quot;Doe&quot;,
            genders: [&quot;Male&quot;, &quot;Female&quot;],
            gender: &quot;Male&quot;,
            agreed: false,
            confirmed: false,
            register: function(e) {
                e.preventDefault();


                this.set(&quot;confirmed&quot;, true);
            },
            startOver: function() {
                this.set(&quot;confirmed&quot;, false);
                this.set(&quot;agreed&quot;, false);
                this.set(&quot;gender&quot;, &quot;Male&quot;);
                this.set(&quot;firstName&quot;, &quot;John&quot;);
                this.set(&quot;lastName&quot;, &quot;Doe&quot;);
            }
        });


        kendo.bind($(&quot;form&quot;), viewModel);
            </pre>
        </div>


        <style scoped>
            .current-state {
                float: right;
                width: 200px;
                margin: 60px 85px 0 0
            }
            
            .current-state pre {
                font-size: 12px;
            }
            
            .registration h3 {
                font-size: 2.5em;
                color: #787878;
                border-bottom: 1px solid #ccc;
            }
            
            .registration {
                float: left;
                clear: left;
                width: 500px;
                height: 131px;
                margin: 30px 0 30px 30px;
                padding: 60px 0 30px 30px;
                background: url('../../content/web/mvvm/regForm.png') transparent no-repeat 0 0;
            }
            
            .registration ul {
            list-style: none;
                margin: 0;
                padding: 0;
            }
            
            .registration li {
            height: 28px;
            vertical-align: middle;
            color: #000;
            }
            
            .registration ul label {
            display: inline-block;
            width: 100px;
            text-align: right;
            padding-right: 5px;
            color: #000;
            }
            
            .registration label {
            color: #000;
            }
            
            .registration ul input {
            border: 1px solid #ddd;
            }
            
            .registration button {
            float: right;
            margin-right: 85px;
            }
            
            .confirmation {
                float: left;
                clear: left;
                width: 274px;
                height: 65px;
                margin: 30px 0 30px 30px;
                padding: 20px 30px;
                background: url('../../content/web/mvvm/confirm.png') transparent no-repeat 0 0;
                text-align: center;
            }
            
            .code-details > ul {
                list-style: none;
                margin: 0;
                padding: 0;
            }


            .code-details li
            {
                height: 26px;
                line-height: 22px;
                vertical-align: middle;
            }


            .code-details {
                padding: 1em;
            }
            
            .source {
                clear: both;
            }
        </style>
    </div>
    </body>
    </html>


    Dan
Back to Top