wrjs.state = wrjs.state || {};
// ***********************************************************
// MODAL
// ***********************************************************
wrjs.state.modalcount = 1;
wrjs.View.Modal = function(options) {
// **********************************************************************************
// CHECK FOR DUPLICATES
// IF MODAL ALREADY EXISTS, BLOCK CREATION
// **********************************************************************************
if(options && options.id) {
var modal = $('#wrjs_modal_' + options.id);
if(modal.length > 0) {
return false;
}
};
// **********************************************************************************
// PRIVATE VARS
// **********************************************************************************
var _defaults = {
animate: true, // WHETHER TO SLIDE THE MODAL IN FROM THE TOP - NOW DEFAULTED TO TRUE
body: 'Body content', // Description goes here...
bodyAlign: 'center', // Description goes here...
buttoncolor: 'green', // Description goes here...
buttons: false, // Description goes here...
canceltext: ls.text_cancel, // Description goes here...
cancelCallback: false, // Description goes here...
cls: '', // Description goes here...
confirmtext: ls.text_confirm, // Description goes here...
confirmCallback: false, // Description goes here...
dontshowagain: false, // Description goes here...
helpFunction: false, // Description goes here...
id: wrjs.state.modalcount, // Description goes here...
listeners: false, // Description goes here...
maskCls: '', // Description goes here...
preRenderer: false, // PRE RENDERERS ARE FOR THE SITUATION WHERE YOU MIGHT WANT TO RUN SOME FUNCTIONALITY AFTER BEING ADDED TO THE DOM, BUT BEFORE BEING MADE VISIBLE (e.g. set form defaults / show hide certain tabs, etc)
renderTo: 'body', // Description goes here...
speed: 500, // Description goes here...
style: '', // Description goes here...
title: 'Title', // Description goes here...
width: false, // Description goes here...
padding: 12
};
options = options || {};
// TEMPORARY FIX WHILST "additionalClasses" IS BEING DEPRECATED
if(options.additionalClasses) {
options.cls = options.additionalClasses;
delete options.additionalClasses;
};
var _config = $.extend(_defaults, options);
// **********************************************************************************
// PRIVATE FUNCTIONS
// **********************************************************************************
var _registerListeners = function() {
if (_config.listeners != false) {
wrjs.Event.eventManager.registerListeners(_config);
}
$('body').on('keyup', _keypress);
$('body').on('click', '#wrjs_modal_' + _config.id + ' .tabs:not(.disabled) li:not(.selected) a', _pixelFix);
};
var _buildView = function() {
//console.log('_buildView - GRID')
var html = '';
var textalign = '';
switch (_config.bodyAlign) {
case 'left':
textalign = 'textalign_left';
break;
case 'right':
textalign = 'textalign_right';
break;
default:
// DO NOTHING - ALREADY CENTERED
}
_config.cls += ' ' + textalign;
// APPEND WIDTH INTO STYLE
if(_config.width) {
var widthunit = _config.width.toString().indexOf('%') > -1 ? '%' : 'px';
var wid = _config.width.toString().split('%')[0];
_config.style += ' width:' + wid + widthunit + ';'
};
if (_config.cls.indexOf('red') != -1) {
_config.buttoncolor = 'red';
};
if (_config.cls.indexOf('blue') != -1) {
_config.buttoncolor = 'blue';
};
// ALLOW FOR GREY BUTTON BY PASSING 'none'
if(_config.buttoncolor != 'none') {
_config.buttoncolor += ' inverse'
};
var dontshow = _config.dontshowagain ? ' ' : '';
var confirmbutton = '' + _config.confirmtext + '';
var cancelbutton = _config.canceltext != false ? '' + _config.canceltext + '' : '';
var helpbutton = _config.helpFunction != false ? '' : '';
var footerbuttons = confirmbutton + cancelbutton;
if (_config.buttons != false) {
var b = '';
$.each(_config.buttons, function (i, but) {
// CREATE BUTTON
var butid = but.id || 'button_text' + i;
var style = but.style || '';
var buttoncls = but.cls || '';
b += '' + but.text + '';
// BIND HANDLER
$(document).off('click', '#' + butid + ':not(.disabled)');
$(document).on('click', '#' + butid + ':not(.disabled)', function (e) {
if (but.handler) {
but.handler(this, modal, e);
} else {
modal.remove();
};
});
})
footerbuttons = b;
}
// ***********************************************************************************
// BUILD POPUP
// ***********************************************************************************
if(_config.animate) {
_config.cls += ' animate';
_config.maskCls += ' animate';
}
var padding = 'style="padding:' + _config.padding + 'px;"';
var html = '
' +
'
' + _config.title +
'' +
'' +
helpbutton +
'' +
'
' +
'
' +
_config.body +
'
' +
'' +
'
';
// ***********************************************************************************
// BUILD MASK
// ***********************************************************************************
var maskCls = _config.maskCls ? _config.maskCls : '';
var m = '';
// ***********************************************************************************
// APPEND MASK AND POPUP
// ***********************************************************************************
$(_config.renderTo).append(m + html);
$('html,body').addClass('has-modal');
var p = $('#wrjs_modal_' + _config.id);
var msk = $('#wrjs_mask_' + _config.id);
// ADD ON PIXEL IF HEIGHT IS ODD, DUE TO SUB-PIXEL RENDERING ISSUES
_pixelFix()
// Click the active tab to trigger the height check listener
$('#usertabs .selected a', p).trigger('click');
// ***********************************************************************************
// RUN ANY PRE-RENDER FUNCTION
// ***********************************************************************************
if (_config.preRenderer !== false) {
_config.preRenderer(modal);
}
// ***********************************************************************************
// POSITION AND DISPLAY POPUP
// ***********************************************************************************
if(_config.rapid) {
p.show().css('opacity',1);
msk.show().css('opacity',0.7);
} else {
if (_config.animate) {
p.addClass('slideIn');
setTimeout(function(){
p.addClass('animated');
p.removeClass('slideIn animate');
}, 500);
} else {
setTimeout(function(){
p.addClass('fadeIn');
setTimeout(function(){
p.addClass('animated');
p.removeClass('fadeIn animated');
}, 500);
}, 10);
};
setTimeout(function(){
msk.addClass('fadeIn');
}, 10);
};
// Focus the modal. But if there's an achor button then focus that, otherwise focus the first visible text field
p.focus();
$('a.button:visible:first', p).focus();
$('input:visible:first', p).focus();
// ***********************************************************************************
// CONFIRMCLICK
// ***********************************************************************************
$('body').on('click', '#wrjs_modal_' + _config.id + ' .confirmclick:not(.disabled)', function(e) {
if (_config.confirmCallback) {
_config.confirmCallback(this, modal, e)
} else {
modal.remove();
}
});
// ***********************************************************************************
// CANCELCLICK
// ***********************************************************************************
$('.cancelclick:not(.disabled)', p).bind('click', function (e) {
if (_config.cancelCallback) {
_config.cancelCallback(this, modal, e)
} else {
modal.remove();
}
});
// ***********************************************************************************
// HELP CLICK
// ***********************************************************************************
if (_config.helpFunction) {
$('.helpclick', p).bind('click', function (e) {
_config.helpFunction(this, modal, e);
});
}
// ***********************************************************************************
// INCNREMENT ID
// ***********************************************************************************
//wrjs.state.modalcount++
return html
};
// ***********************************************************************************
// REMOVEMODAL FROM DOM AND VIEW AMANGER
// ***********************************************************************************
var _removeModal = function(fn) {
var callback = typeof fn == 'function'; // A FUNCTION HAS BEEN PASSED INSTEAD OF EL
var p = _config.id == false ? $('.wrjs_modal') : $('#wrjs_modal_' + _config.id);
var mask = _config.id == false ? $('.wrjs_mask') : $('#wrjs_mask_' + _config.id);
function performDestroy() {
p.remove();
mask.remove();
if(_config.removeCallback) {
_config.removeCallback();
}
if(callback) {
fn();
}
};
if(_config.animate) {
p.addClass('slideOut');
mask.removeClass('fadeIn').addClass('fadeOut');
// WAIT FOR ANIMATION TO COMPLETE BEFORE REMOVING FROM DOM
setTimeout(function() {
performDestroy()
},1000)
} else {
performDestroy();
};
// REMOVE FROM VIEWMANAGER
delete wrjs.View.viewManager[_config.id];
};
var _keypress = function(e) {
if (e.keyCode === 27) {
if (_config.cancelCallback) {
_config.cancelCallback(this, modal, e)
} else {
modal.remove();
}
}
};
var _pixelFix = function() {
setTimeout(function() {
// DIRTY FIX FOR SUB PIXEL RENDERING
// IF MODAL IS AN ODD NUMBER IN HEIGHT, THEN BLURRY BORDERS ARE RENDERED IN BROWSER
// THEREFORE ALWAYS ENSURE MODAL IS AN EVEN NUMBER AND THIS IS RESOLVED
var parent = $('#wrjs_modal_' + _config.id);
var h1 = $('h1', parent);
// RESET
h1.css({
'paddingBottom': '13px'
});
var h = parent.outerHeight();
var even = h % 2 == 0;
if(!even) {
h1.css('paddingBottom', '14px');
};
//var w = parent.outerWidth();
//parent.width(w + 1);
},10);
return modal;
};
var _displayMessage = function(options) {
$('.modalmessage').remove();
$('#wrjs_modal_' + _config.id + ' .inner').prepend(wrjs.Message({cls: options.cls + ' modalmessage', msg: options.msg, icon: options.icon}));
return modal;
};
// **********************************************************************************
// PUBLIC FUNCTIONS
// **********************************************************************************
var publicFunctions = {
loadMask: _config.loadMask,
renderTo: _config.renderTo,
rendered: false,
remove: function(el, e) {
// TRIGGER CLOSE
var hash = '#wrjs_modal_' + _config.id;
$(hash).trigger('close');
if (_config.listeners != false) {
wrjs.Event.eventManager.unregisterListeners(_config);
}
$('body').off('keyup', _keypress);
$('body').off('click', '#wrjs_modal_' + _config.id + ' .tabs:not(.disabled) li:not(.selected) a', _pixelFix);
$('body').off('click', '#wrjs_modal_' + _config.id + ' .confirmclick:not(.disabled)');
$('html,body').removeClass('has-modal');
//console.log('WRJS REMOVE MODAL', el ,e);
_removeModal(el, e);
},
update: function(records) {
//console.log('GRID UPDATE', grid, records)
// mondal.render();
// UNMASK
if(_config.loadMask) {
if(_config.renderTo) {
$(_config.renderTo).unmask()
}
}
},
setHeader: function(val) {
_config.header = val;
},
render: function(options) {
//console.log('MODAL RENDER')
// CALL RENDER FUNCTION
function callRender() {
if(typeof _config.listeners.render == 'function') {
var modal = $('#' + _config.id);
modal.trigger('render');
}
}
// ONLY REGISTER LISTENERS ON INITIAL RENDER
if(!_config.rendered) {
//console.log('REGISTER LISTENERS')
_registerListeners();
}
// BEFORERENDER - CALL THIS FIRST
if(typeof _config.listeners.beforerender == 'function') {
//console.log('CALL BEFORERENDER', _config)
_config.listeners.beforerender(_config);
}
// BUILD MODAL VIEW
var html = _buildView();
// IF NO RENDERTO CONFIG IS PROVIDED, SIMPLY RETURN THE BUILD HTML STRING
// ELSE, APPEND THE CREATED HTML TO THE PASSED RENDERTO ELEMENT
if(html) {
if(!_config.renderTo) {
return html
} else {
if(!_config.rendered) {
// RENDERING IS CURRENTLY HAPPENING IN BUILDVIEW
//var renderto = $(_config.renderTo);
//var parent = renderto.parent().parent();
//renderto.prepend(html);
callRender();
}
}
}
_config.rendered = true;
this.rendered = true;
},
mask: function(str, maskstyle) {
str = str || false;
maskstyle = maskstyle || '';
$('#wrjs_modal_' + _config.id).mask(str, maskstyle);
},
unmask: function() {
$('#wrjs_modal_' + _config.id).unmask();
},
pixelFix: _pixelFix,
displayMessage: _displayMessage,
setRapid: function(bool) {
var flag = typeof bool != undefined ? bool : false;
_config.rapid = flag;
},
updateBody: function(str) {
str = str || '';
$('#wrjs_modal_' + _config.id + ' .inner').html(str);
}
}
// **********************************************************************************
// CONSTRUCTOR
// **********************************************************************************
var modal = {
id: _config.id
};
$.extend(modal, publicFunctions)
modal.render();
wrjs.View.viewManager = wrjs.View.viewManager || {};
wrjs.View.viewManager[_config.id] = modal;
wrjs.state.modalcount++;
//console.log('WRJS MODAL CREATE');
return modal;
// **********************************************************************************
// END
// **********************************************************************************
};
wrjs.View.removeAllModals = function(callback) {
var modals = $('.wrjs_modal');
$.each(modals, function(i, modal) {
var id = modal.id.split('wrjs_modal_')[1];
var wrjsmodal = wrjs.get(id);
if(wrjsmodal) {
wrjsmodal.remove();
};
});
if(callback) {
//setTimeout(function() {
callback();
//},100)
};
}