LnkWcb Framework

LnkWcb  2.5.0

LnkWcb Framework > LnkWcb > bouton-basique.js (source view)
Search:
 
Filters
/*!
 * LNK WCB Framework v2.5
 * (c) 2010 Linkeo.com
 * Use and redistribution are permitted. No warranty.
 * 
 * Basic Bouton
 */

// LnkWcb.BoutonBasique
//  - tel/date basic validation, with customizable error messages
//  - limited internationalization (frontal msg not translated)
//  - basic call status display (incl. frontal msg), with limited customization
//  - basic raw error display (incl. frontal msg), not customizable
//  - standard fallbacks (incl. back-office cfg msg)

var LnkLog, LnkWcb; // if already defined, log won't get clobbered just defining it
LnkLog = LnkLog || {};
LnkLog.log = LnkLog.log || function () {}; // if not defined, use a safe default value instead
LnkWcb = LnkWcb || {};

/**
 * @module LnkWcb
 */
/**
 * Basic Bouton.
 * @class BoutonBasique
 * @extends LnkWcb.Bouton
 * @namespace LnkWcb
 * @constructor
 * @param cfg {Object} the initial configuration settings
 * @private
 * @deprecated Superseded by <code>LnkWcb.BoutonJquery</code> use this latter class instead.
 */
(function () {
	var U = LnkWcb.util,
		B = LnkWcb.Bouton, BB, BBPROTO,
		INTL = LnkWcb.intl,
		defaultSettings = LnkWcb.util.putAll(B.prototype.getDefaultSettings(), {
			userStatusElemId: 'LnkWcbUserStatus',
			userErrorsElemId: 'LnkWcbUserErrors',
			calleeElemId: 'LnkWcbCallee',
			dateDiffElemId: 'LnkWcbDateDiff',
			forceFallbacks: false // override to get back to compatibility mode (not recommended)
		}),
		defaultRsc = { // French locale by default
			err: {
				blankTel: "Précisez le numéro de téléphone.",
				invalidTel: "Ce numéro de téléphone [{tel}] n'est pas correct.",
				blankDate: "La date [{date}] est incorrecte. Elle doit respecter le format 'JJ/MM/AAAA hh:mm'."
			},
			msg: {
				helloChannelState: "Bonjour, le canal est {etat}.",
				callStatus: "Votre téléphone : {usr}, votre correspondant : {agt}.",
				delayedCallAccepted: "Votre demande a bien été prise en compte.",
				okThanks: "Nous vous remercions de votre appel.",
				koPleaseCallAgain: "Votre téléphone n'est pas joignable. Renouveler votre demande et répondez à l'appel téléphonique.",
				koPleaseCallLater: "Tous nos conseillers sont en ligne. Merci de rappeler ultérieurement."
			}
		};

	BB = LnkWcb.BoutonBasique = function (cfg) {
		var that = this;

		B.call(that);
		LnkWcb.util.putAll(that.cfg, defaultSettings); // force our default settings over LnkWcb.Bouton ones
		LnkWcb.util.putAll(that.cfg, cfg);

		that.rsc = INTL.getRsc('bouton-basique', INTL.getLang()) || defaultRsc;
		INTL.onLangChanged(function (lang) {
			that.rsc = INTL.getRsc('bouton-basique', lang) || defaultRsc;
		});

		that.fieldsInError = {};

		LnkWcb.BoutonBasique.onCreate.fire(that);
	};
	BBPROTO = BB.prototype = LnkWcb.util.object(B.prototype);
	BBPROTO.constructor = BB;
	BB.superclass = B.prototype;
	// class event
	BB.onCreate = new LnkWcb.Event(BB);

	// public class methods
	U.putAll(BBPROTO, {
		showUserStatus: function (msg) {
			var DOC = this.document || document,
				elem;
			elem = this.cfg.userStatusElemId && DOC.getElementById(this.cfg.userStatusElemId);
			if (!elem) {
				return;
			}
			if (elem.value !== undefined) {
				elem.value = msg;
			}
			else if (elem.innerHTML !== undefined) {
				elem.innerHTML = msg;
			}
		},
		resetUserErrors: function () {
			var DOC = this.document || document,
				errorsElem, field;
			errorsElem = this.cfg.userErrorsElemId && DOC.getElementById(this.cfg.userErrorsElemId);
			if (errorsElem) {
				while (errorsElem.hasChildNodes()) {
					errorsElem.removeChild(errorsElem.firstChild);
				}
			}
			for (field in this.fieldsInError) {
				if (this.fieldsInError[field] !== undefined) {
					DOC.getElementById(field).className = this.fieldsInError[field];
					delete this.fieldsInError[field];
				}
			}
		},
		showUserErrors: function (errors) {
			var DOC = this.document || document,
				errorsElem, errorsList, field, i, line, fieldElem;
			errorsElem = this.cfg.userErrorsElemId && DOC.getElementById(this.cfg.userErrorsElemId);
			if (!errorsElem) {
				return;
			}
			errorsList = DOC.createElement('ul');
			for (field in errors) {
				for (i = 0; i < errors[field].length; ++i) {
					line = DOC.createElement('li');
					line.appendChild(DOC.createTextNode(errors[field][i]));
					errorsList.appendChild(line);
				}
				fieldElem = DOC.getElementById(field);
				if (fieldElem) {
					if (!this.fieldsInError[field]) {
						this.fieldsInError[field] = fieldElem.className;
					}
					fieldElem.className = fieldElem.className + ' error';
				}
			}
			if (errorsList.hasChildNodes()) {
				errorsElem.appendChild(errorsList);
			}
		},

		// class events handlers
		/*
		onSendCallAction: function (args, attrs) {
			var planedDate, date;
			planedDate = attrs.planedDate;
			if (typeof planedDate === 'object' && planedDate !== null) { // fixup date from { date: .., hours: .., minutes: .. } object to "DD/MM/YYYY hh:mm" string
				date = planedDate.date;
				date.setHours(planedDate.hours);
				date.setMinutes(planedDate.minutes);
				attrs.planedDate = U.formatDateTime(date);
			}
		},
		*/
		onChannelStateAction: function (etat) {
			this.showUserStatus(INTL.fmt(this.rsc.msg.helloChannelState, { etat: etat.etatOuverture }));
		},
		onStatusAction: function (status, params) {
			var msg = INTL.fmt(this.rsc.msg.callStatus, { usr: status.u, agt: status.a });
			this.showUserStatus(msg);
		},
		onEndedAction: function (status, params) {
			var msg, usrErr;
			if (String(params.t) === 'delay') { // errors directly go to the error handler, not here
				msg = this.rsc.msg.delayedCallAccepted;
			}
			else if (status.status === 'OK') {
				msg = this.rsc.msg.okThanks;
			}
			// status.status === 'KO'
			else if (U.indexOf([ 'RACCROCHE_INTERNAUTE_AVANT_AGENT', 'INVERSE_INABOUTI_INTERNAUTE', 'INABOUTI_INTERNAUTE', 'MACHINE' ], status.cause) >= 0) {
				msg = "";
				usrErr = this.rsc.msg.koPleaseCallAgain;
			}
			else {
				msg = this.rsc.msg.koPleaseCallLater;
			}
			this.showUserStatus(msg);
			if (usrErr) {
				this.resetUserErrors();
				this.showUserErrors({ msg: [ usrErr ] });
			}
		},
		onFallbackAction: function (status, params) { // strictly follows server-side hints about what to do upon fallback
			var type = status.debordementType,
				valeur = status.debordementValue;
			if (type === "URL" && valeur) {
				document.location = valeur;
			}
			else if (type === "SIMPLE" && valeur) {
				this.showUserStatus(valeur);
			}
		},
		onErrorAction: function (msg, exc, status, params) {
			this.resetUserErrors();
			this.showUserErrors({ msg: [ msg ] });
		}
	});

	// custom instance validation
	defaultSettings.validator = function (tel, date) {
		var BLANK = /^\s+$/,
			TEL = /^(?:\+[1-9]|0)\d{9,}$/,
			DATE = /^[0-3]\d\/[01]\d\/\d{4} [0-2]\d:[0-5]\d$/,
			errors = {};
		this.resetUserErrors();
		if (!tel || BLANK.test(tel)) {
			U.accu(errors, this.cfg.calleeElemId, this.rsc.err.blankTel);
		}
		else if (!TEL.test(tel)) {
			U.accu(errors, this.cfg.calleeElemId, INTL.fmt(this.rsc.err.invalidTel, { tel: tel }));
		}
		if (date !== undefined && !BLANK.test(date) && !DATE.test(date)) {
			U.accu(errors, this.cfg.dateDiffElemId, INTL.fmt(this.rsc.err.blankDate, { date: date }));
		}
		this.showUserErrors(errors);
		return U.countDefined(errors) === 0;
	};

	// customize instance behavior with class events handlers
	(function () {
		function PROXY(method) {
			return function () {
				this[method].apply(this, arguments);
			};
		}
		BB.onCreate.register(function (that) {
			// that.onSendCall(PROXY('onSendCallAction'));
			that.onChannelState(PROXY('onChannelStateAction'));
			that.onStatus(PROXY('onStatusAction'));
			that.onEnded(PROXY('onEndedAction'));
			that.onFallback(PROXY('onFallbackAction'));
			that.onError(PROXY('onErrorAction'));
		});
	})();
})();

Copyright © 2010 Linkeo.com All rights reserved.