LoginView.js 7.42 KB
/*
 *
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2014 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */
/* globals Screens */
define('ux/views/LoginView', [
    'underscore',
    'jquery',
    'context',
    'util/Util',
    'views/BaseView'
], function(_, $, Context, Util, BaseView) {
    'use strict';

    var DEFAULT_OPTIONS = {
        defaultUser: '',
        defaultPassword: ''
    };

    var LoginView = BaseView.extend(/** @lends LoginView.prototype */{

        templateLoginForm: function(width, height) {
            var tmpl = _.template('<div class="screens-Login-screen" style="width:<%- width %>px; height:<%- height %>px">' +
            '<div class="u-screens-alignHorizontal">' +
            '<div class="u-screens-alignVertical">' +
            '<div class="screens-Login-wrapper">' +
            '<div class="screens-Login-title"/>' +
            '<form id="login-form" autocomplete="off">' +
            '<input disabled type="text" name="username" placeholder="username" spellcheck="false" value="">' +
            '<input disabled type="password" name="password" placeholder="password" value="">' +
            '<button type="submit" class="screens-Login-button" value="" />' +
            '</form>' +
            '</div>' +
            '</div>' +
            '</div>' +
            '</div>');

            return tmpl({
                width: width,
                height: height
            });
        },

        template: function(width, height) {
            var tmpl = _.template('<div class="screens-Login-screen" style="width:<%- width %>px; height:<%- height %>px"/>');

            return tmpl({
                width: width,
                height: height
            });
        },

        className: 'screens-Login',

        events: {
            'submit #login-form': '_handleLogin'
        },

        sistineOptions: {
            events: {
                'press .screens-Login-button': '_handleLoginButtonUI',
                'tap .screens-Login-button': '_handleLogin'
            },
            recognizers: [
                'press', 'tap'
            ]
        },

        /**
         * @classdesc View that renders the login screen
         * @class LoginView
         * @extends BaseView
         *
         * @param {Object} [options] An object of configurable options.
         * @param {String} [options.defaultUser] Default user name for prefilled inputs
         * @param {String} [options.defaultPassword] Default password name for prefilled inputs
         */
        constructor: function(options) {
            this._initOptions(options, DEFAULT_OPTIONS);
            LoginView.__super__.constructor.apply(this, arguments);
        },


        /**
         * Set focus on the input
         */
        focus: function() {
            this.$el.find('#login-form input[name="username"]').focus();
        },

        render: function() {
            // get tile that spans the position of the event. assume only horizontal tiles.
            // based on the number of tiles, we figure out where to place the login form
            // so that they don't end up in the middle of 2 screens
            var tiles = Context.appView.getTiles();
            var idx = 0;
            if (tiles.length % 2 === 0) {
                idx = (tiles.length * 0.5) - 1;
            } else {
                idx = Math.floor(tiles.length * 0.5);
            }

            for (var i = 0; i < tiles.length; i++) {
                if (i !== idx) {
                    this.$el.append(this.template(tiles[i].width, tiles[i].height));
                } else {
                    this.$el.append(this.templateLoginForm(tiles[i].width, tiles[i].height));
                }
            }
            return this;
        },

        /**
         * Resets the login form.
         *
         * @returns {LoginView} The login view
         */
        reset: function() {
            this._showErrorMode(false);
            this.$el.find('#login-form').get(0).reset();
            this.$el.find('#login-form input[name="username"]').val(this.options.defaultUser);
            this.$el.find('#login-form input[name="password"]').val(this.options.defaultPassword);
            return this;
        },

        enable: function() {
            $('INPUT', this.$el).prop('disabled', false);
            return this;
        },

        disable: function() {
            $('INPUT', this.$el).prop('disabled', true);
            return this;
        },

        /**
         * hide this view
         * @returns {LoginView} this
         */
        hide: function() {
            this.$el.hide();
            return this.disable();
        },

        /**
         * show this view
         * @returns {LoginView} this
         */
        show: function() {
            // also enable inputs for iOS safari
            this.$el.show();
            return this.enable();
        },

        handleLoginFailed: function() {
            this._showErrorMode(true);
        },

        /**
         * reposition the login elements so that they are placed right in
         * the middle of the screen vertically
         */
        _centerElements: function() {
            var wrapper = this.$el.find('.ctx-Login-wrapper');
            var loginButton = this.$el.find('.ctx-Login-button');

            var midButton = loginButton.position().top + loginButton.innerHeight() * 0.5;
            var marginTop = (window.innerHeight * 0.5) - midButton - 8;

            wrapper.css({marginTop: marginTop + 'px'});
        },

        _handleLogin: function(ev) {
            var user = this.$el.find('#login-form input[name="username"]').val();
            var pass = this.$el.find('#login-form input[name="password"]').val();
            if (user && pass) {
                // todo: maybe handle login-response with callback
                Screens.ws.emit('login', {
                    user: user,
                    pass: pass
                });
            }
            return false;
        },

        _handleLoginButtonUI: function(ev) {
            Util.buttonPressedUIHandler(ev);
        },

        /**
         * show error or normal mode
         * @param {Boolean} isError is true, we are showing the error mode, otherwise, show normal mode
         */
        _showErrorMode: function(isError) {
            var loginTitleEl = this.$el.find('.ctx-Login-title');
            var user = this.$el.find('#login-form input[name="username"]');
            var pass = this.$el.find('#login-form input[name="password"]');

            if (isError) {
                loginTitleEl.addClass('error');
                user.addClass('error');
                pass.addClass('error');
                loginTitleEl.text('Invalid username or password');
            } else {
                loginTitleEl.removeClass('error');
                user.removeClass('error');
                pass.removeClass('error');
                loginTitleEl.text('sign in to aem');
            }
        }

    });

    // return module exports
    return LoginView;
});