Coding Test

by craigcav

HTML

<script src=" http://github.com/downloads/SteveSanderson/knockout/knockout-2.1.0.js"></script>
<script src="https://dl.dropbox.com/u/16870890/knockout.validation.js"></script>
<div class="home-signup">
    <form class="home-signup__body" data-bind="visible: !success()">
        <div class="control-group" data-bind="css: { error: !firstName.isValid() && firstName.isModified() }">
            <label for="first-name" class="control-label">First Name:</label>
            <div class="controls">
                <input class="input-field" autofocus="autofocus" id="first-name" name="first-name" tabindex="1" type="text" required="required" data-bind="value: firstName" />
                <div class="callout-placeholder" data-bind="visible: !firstName.isValid() && firstName.isModified()">
                    <div class="callout callout--error" style="width: 120px; top: -10px;">
                        <div class="callout__arrow"></div>
                        <div class="callout__content">
                            Required Input.
                        </div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="control-group">
            <label for="last-name" class="control-label">Last Name:</label>
            <input class="input-field" id="last-name" name="last-name" tabindex="2" type="text" data-bind="value: lastName"  />
        </div>
        
        <div class="control-group">
            <label for="username" class="control-label">Username:</label>
            <input class="input-field" autocorrect="off" id="username" name="username" tabindex="3" type="text" data-bind="value: username"  />
        </div>
        
        <div class="control-group" data-bind="css: { error: !password.isValid() && password.isModified() }">
            <label for="password" class="control-label">Password:</label>
            <div class="controls">
                <input class="input-field" autocomplete="disabled"...

CSS

body {
  font: 13px Helvetica, arial, freesans, clean, sans-serif;
}

.control-label {
  font-weight: bold;
  display: inline-block;
  width: 75px;
  padding: 10px;
  text-align: right;
}

.control-group {
  text-align: right;
  padding-right: 25px;
}

.controls { 
  text-align: left;
  display: inline;
}
.controls--submit {
  margin-top: 20px;
}

.btn {
  border-style: solid;
  border-width: 1px;
  padding: 5px 10px;
  color: white;
  cursor: pointer;
  text-shadow: 1px 1px 1px #005800;

  -webkit-border-radius: 3px;
     -moz-border-radius: 3px;
          border-radius: 3px;
}
.btn--primary {
  background-color: #009900;
  /* provide multiple border-like effect*/
  box-shadow:0 0 0 1px #005800;
}
.btn--disabled {
  background-color: #999999;
}

.input-field {
  border: 1px solid #686868;
  padding: 3px;
  -webkit-border-radius: 5px;
     -moz-border-radius: 5px;
          border-radius: 5px;

  -webkit-box-shadow: 0px 0px 6px 3px #ccc;
     -moz-box-shadow: 0px 0px 6px 3px #ccc;
          box-shadow: 0px 0px 6px 3px #ccc;
}

.error .control-label {
    color: #993300;    
}

.error .input-field {
    border-color: #c70202;
}


/* module - home screen */
.signup-complete {
    color: #009900;
}

.home-signup {
  width: 330px;
  margin: 20px;
}
  .home-signup__body {
    padding: 20px;
    border: 1px solid #676767;
    -webkit-border-radius: 5px;
       -moz-border-radius: 5px;
            border-radius: 5px;

    -webkit-box-shadow: 0px 0px 12px 6px #ccc;
       -moz-box-shadow: 0px 0px 12px 6px #ccc;
            box-shadow: 0px 0px 12px 6px #ccc;

    /* fallback */
    background-color: #ffffff;
    background: -webkit-gradient(linear, 0% 0%, 0% 30%, from(#cccccc), to(#ffffff));
    background: -webkit-linear-gradient(bottom, #ffffff 70%, #cccccc);
    background:    -moz-linear-gradient(bottom, #ffffff 70%, #cccccc);
    background:     -ms-linear-gradient(bottom, #ffffff 70%, #cccccc);
    background:      -o-linear-gradient(bottom, #ffffff 70%, #cccccc);
 ...

JavaScript

ko.validation.configure({
    messagesOnModified: true,
    insertMessages: false
});

var SignUpModel = function(contacts) {    
    this.firstName = ko.observable().extend({ required: true });
    this.lastName = ko.observable();
    this.username = ko.observable();
    this.password = ko.observable().extend({ required: true, pattern: "^(?=.*[a-z])(?=.*[A-Z])(?=.*([^a-zA-Z]|[\\d])).+$" });
    this.showHint = ko.observable(false);
    this.success = ko.observable(false);
    
    this.toggleHint = function() {
        this.showHint(!this.showHint());
    };

    this.signUp = function() {
        if (this.errors().length !== 0) {
            this.errors.showAllMessages();
            return;
        }
        $.ajax({
            url: "/echo/json/",
            type: "POST",
            data: ko.toJSON(this),
            dataType: "json",
            context: this,
            contentType: "application/json; charset=utf-8",
            success: function(data) {
                this.success(true);
            }
        });
    };
    
    this.errors = ko.validation.group(this);
};
 
ko.applyBindings(new SignUpModel());