Added language selection functionality to backend pages.

This commit is contained in:
alextselegidis@gmail.com 2013-12-23 16:55:42 +00:00
parent 4767dc36f9
commit 6b03dcff90
26 changed files with 218 additions and 49 deletions

View file

@ -96,7 +96,7 @@ $autoload['config'] = array();
| |
*/ */
$autoload['language'] = array('translations'); $autoload['language'] = array();
/* /*

View file

@ -86,7 +86,8 @@ $config['url_suffix'] = '';
| than english. | than english.
| |
*/ */
$config['language'] = 'greek';//'english'; $config['language'] = 'english'; // default language
$config['available_languages'] = array('english', 'german', 'greek');
/* /*
|-------------------------------------------------------------------------- |--------------------------------------------------------------------------

View file

@ -1,6 +1,18 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Appointments extends CI_Controller { class Appointments extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('session');
// Set user's selected language.
if ($this->session->userdata('language')) {
$this->config->set_item('language', $this->session->userdata('language'));
$this->lang->load('translations', $this->session->userdata('language'));
} else {
$this->lang->load('translations', $this->config->item('language')); // default
}
}
/** /**
* Default callback method of the application. * Default callback method of the application.
* *

View file

@ -4,6 +4,14 @@ class Backend extends CI_Controller {
public function __construct() { public function __construct() {
parent::__construct(); parent::__construct();
$this->load->library('session'); $this->load->library('session');
// Set user's selected language.
if ($this->session->userdata('language')) {
$this->config->set_item('language', $this->session->userdata('language'));
$this->lang->load('translations', $this->session->userdata('language'));
} else {
$this->lang->load('translations', $this->config->item('language')); // default
}
} }
/** /**

View file

@ -1038,6 +1038,40 @@ class Backend_api extends CI_Controller {
)); ));
} }
} }
/**
* [AJAX] Change system language for current user.
*
* The language setting is stored in session data and retrieved every time the user
* visits any of the system pages.
*
* @param string $_POST['language'] Selected language name.
*/
public function ajax_change_language() {
try {
// Check if language exists in the available languages.
$found = false;
foreach($this->config->item('available_languages') as $lang) {
if ($lang == $_POST['language']) {
$found = true;
break;
}
}
if (!$found)
throw new Exception('Translations for the given language does not exist (' . $_POST['language'] . ').');
$this->session->set_userdata('language', $_POST['language']);
$this->config->set_item('language', $_POST['language']);
echo json_encode(AJAX_SUCCESS);
} catch(Exception $exc) {
echo json_encode(array(
'exceptions' => array(exceptionToJavaScript($exc))
));
}
}
} }
/* End of file backend_api.php */ /* End of file backend_api.php */

View file

@ -1,6 +1,18 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Errors extends CI_Controller { class Errors extends CI_Controller {
public function __construct() {
parent::__construct();
$this->load->library('session');
// Set user's selected language.
if ($this->session->userdata('language')) {
$this->config->set_item('language', $this->session->userdata('language'));
$this->lang->load('translations', $this->session->userdata('language'));
} else {
$this->lang->load('translations', $this->config->item('language')); // default
}
}
public function index() { public function index() {
$this->e404(); $this->e404();
} }

View file

@ -1,6 +1,10 @@
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Google extends CI_Controller { class Google extends CI_Controller {
public function __construct() {
parent::__construct();
}
/** /**
* Authorize Google Calendar API usage for a specific provider. * Authorize Google Calendar API usage for a specific provider.
* *

View file

@ -4,6 +4,14 @@ class User extends CI_Controller {
public function __construct() { public function __construct() {
parent::__construct(); parent::__construct();
$this->load->library('session'); $this->load->library('session');
// Set user's selected language.
if ($this->session->userdata('language')) {
$this->config->set_item('language', $this->session->userdata('language'));
$this->lang->load('translations', $this->session->userdata('language'));
} else {
$this->lang->load('translations', $this->config->item('language')); // default
}
} }
public function index() { public function index() {

View file

@ -143,7 +143,7 @@ $lang['secretary_deleted'] = 'Secretary deleted successfully!';
$lang['service_saved'] = 'Service saved successfully!'; $lang['service_saved'] = 'Service saved successfully!';
$lang['service_category_saved'] = 'Service category saved successfully!'; $lang['service_category_saved'] = 'Service category saved successfully!';
$lang['service_deleted'] = 'Service deleted successfully!'; $lang['service_deleted'] = 'Service deleted successfully!';
$lang['servce_category_deleted'] = 'Service category deleted successfully!'; $lang['service_category_deleted'] = 'Service category deleted successfully!';
$lang['customer_saved'] = 'Customer saved successfully!'; $lang['customer_saved'] = 'Customer saved successfully!';
$lang['customer_deleted'] = 'Customer deleted successfully!'; $lang['customer_deleted'] = 'Customer deleted successfully!';
$lang['current_view'] = 'Current View'; $lang['current_view'] = 'Current View';

View file

@ -143,7 +143,7 @@ $lang['secretary_deleted'] = 'Bearbeiter erfolgreich gelöscht!';
$lang['service_saved'] = 'Dienstleistung erfolgreich gesichert!'; $lang['service_saved'] = 'Dienstleistung erfolgreich gesichert!';
$lang['service_category_saved'] = 'Dienstleistungskategorie erfolgreich gesichert!'; $lang['service_category_saved'] = 'Dienstleistungskategorie erfolgreich gesichert!';
$lang['service_deleted'] = 'Dienstleistung erfolgreich gelöscht!'; $lang['service_deleted'] = 'Dienstleistung erfolgreich gelöscht!';
$lang['servce_category_deleted'] = 'Dienstleistungskategorie erfolgreicht gelöscht!'; $lang['service_category_deleted'] = 'Dienstleistungskategorie erfolgreicht gelöscht!';
$lang['customer_saved'] = 'Kunde erfolgreich gesichert!'; $lang['customer_saved'] = 'Kunde erfolgreich gesichert!';
$lang['customer_deleted'] = 'Kunde erfolgreich gelöscht!'; $lang['customer_deleted'] = 'Kunde erfolgreich gelöscht!';
$lang['current_view'] = 'Laufende Ansicht'; $lang['current_view'] = 'Laufende Ansicht';

View file

@ -143,7 +143,7 @@ $lang['secretary_deleted'] = 'Ο γραμματέας διαγράφηκε επ
$lang['service_saved'] = 'Η υπηρεσία αποθηκεύτηκε επιτυχώς!'; $lang['service_saved'] = 'Η υπηρεσία αποθηκεύτηκε επιτυχώς!';
$lang['service_category_saved'] = 'Η κατηγορία υπηρεσιών αποθηκεύτηκε επιτυχώς!'; $lang['service_category_saved'] = 'Η κατηγορία υπηρεσιών αποθηκεύτηκε επιτυχώς!';
$lang['service_deleted'] = 'Η υπηρεσία διαγράφηκε επιτυχώς!'; $lang['service_deleted'] = 'Η υπηρεσία διαγράφηκε επιτυχώς!';
$lang['servce_category_deleted'] = 'Η κατηγορία υπηρεσιών διαγράφηκε επιτυχώς!'; $lang['service_category_deleted'] = 'Η κατηγορία υπηρεσιών διαγράφηκε επιτυχώς!';
$lang['customer_saved'] = 'Ο πελάτης αποθηκεύτηκε επιτυχώς!'; $lang['customer_saved'] = 'Ο πελάτης αποθηκεύτηκε επιτυχώς!';
$lang['customer_deleted'] = 'Ο πελάτης διαγράφηκε επιτυχώς!'; $lang['customer_deleted'] = 'Ο πελάτης διαγράφηκε επιτυχώς!';
$lang['current_view'] = 'Τρέχων Προβολή'; $lang['current_view'] = 'Τρέχων Προβολή';

View file

@ -27,8 +27,6 @@
} }
}; };
var EALang = <?php echo json_encode($this->lang->language); ?>;
$(document).ready(function() { $(document).ready(function() {
BackendCalendar.initialize(true); BackendCalendar.initialize(true);
}); });

View file

@ -18,8 +18,6 @@
} }
}; };
var EALang = <?php echo json_encode($this->lang->language); ?>
$(document).ready(function() { $(document).ready(function() {
BackendCustomers.initialize(true); BackendCustomers.initialize(true);
}); });

View file

@ -12,7 +12,10 @@
} }
?> ?>
</a> | </a> |
<?php echo $this->lang->line('licensed_under'); ?> GPLv3 <?php echo $this->lang->line('licensed_under'); ?> GPLv3 |
<span id="select-language" class="badge badge-inverse">
<?php echo ucfirst($this->config->item('language')); ?>
</span>
</div> </div>
<div id="footer-user-display-name"> <div id="footer-user-display-name">

View file

@ -64,6 +64,12 @@
<script <script
type="text/javascript" type="text/javascript"
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery.mousewheel.js"></script> src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery.mousewheel.js"></script>
<script type="text/javascript">
// Global JavaScript Variables - Used in all backend pages.
var availableLanguages = <?php echo json_encode($this->config->item('available_languages')); ?>;
var EALang = <?php echo json_encode($this->lang->language); ?>;
</script>
</head> </head>
<body> <body>

View file

@ -14,8 +14,6 @@
} }
}; };
var EALang = <?php echo json_encode($this->lang->language); ?>;
$(document).ready(function() { $(document).ready(function() {
BackendServices.initialize(true); BackendServices.initialize(true);
}); });

View file

@ -23,8 +23,6 @@
} }
}; };
var EALang = <?php echo json_encode($this->lang->language); ?>;
$(document).ready(function() { $(document).ready(function() {
BackendSettings.initialize(true); BackendSettings.initialize(true);
}); });

View file

@ -31,8 +31,6 @@
'privileges': <?php echo json_encode($privileges); ?> 'privileges': <?php echo json_encode($privileges); ?>
} }
}; };
var EALang = <?php echo json_encode($this->lang->language); ?>;
$(document).ready(function() { $(document).ready(function() {
BackendUsers.initialize(true); BackendUsers.initialize(true);

View file

@ -2,9 +2,9 @@
<html> <html>
<head> <head>
<?php // PAGE META ?> <?php // PAGE META ?>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Easy!Appointments - Installation</title> <title>Easy!Appointments - Installation</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<?php // INCLUDE CSS ?> <?php // INCLUDE CSS ?>
<link <link
rel="stylesheet" rel="stylesheet"
@ -31,16 +31,15 @@
<script <script
type="text/javascript" type="text/javascript"
src="<?php echo $base_url; ?>assets/js/libs/date.js"></script> src="<?php echo $base_url; ?>assets/js/libs/date.js"></script>
<script
type="text/javascript"
src="<?php echo $base_url; ?>assets/js/general_functions.js"></script>
<script type="text/javascript"> <script type="text/javascript">
$(document).ready(function() { var GlobalVariables = {
var GlobalVariables = { 'baseUrl': <?php echo '"' . $base_url . '"'; ?>
'baseUrl': <?php echo '"' . $base_url . '"'; ?> };
};
var EALang = <?php echo json_encode($this->lang->language); ?>;
$(document).ready(function() {
var MIN_PASSWORD_LENGTH = 7; var MIN_PASSWORD_LENGTH = 7;
var AJAX_SUCCESS = 'SUCCESS'; var AJAX_SUCCESS = 'SUCCESS';
var AJAX_FAILURE = 'FAILURE'; var AJAX_FAILURE = 'FAILURE';
@ -59,7 +58,7 @@
$('#install').click(function() { $('#install').click(function() {
if (!validate()) return; if (!validate()) return;
var postUrl = GlobalVariables.baseUrl + 'appointments/ajax_install'; var postUrl = GlobalVariables.baseUrl + 'index.php/appointments/ajax_install';
var postData = { var postData = {
'admin': JSON.stringify(getAdminData()), 'admin': JSON.stringify(getAdminData()),
'company': JSON.stringify(getCompanyData()) 'company': JSON.stringify(getCompanyData())
@ -310,5 +309,9 @@
<footer> <footer>
Powered by <a href="http://easyappointments.org">Easy!Appointments</a> Powered by <a href="http://easyappointments.org">Easy!Appointments</a>
</footer> </footer>
<script
type="text/javascript"
src="<?php echo $base_url; ?>assets/js/general_functions.js"></script>
</body> </body>
</html> </html>

View file

@ -571,6 +571,12 @@ padding: 4px 7px;
margin-bottom: 0px; margin-bottom: 0px;
} }
#users-page .editable form,
#users-page .editable select,
#users-page .editable input {
margin: 0px;
}
/* BACKEND SETTINGS PAGE /* BACKEND SETTINGS PAGE
-------------------------------------------------------------------- */ -------------------------------------------------------------------- */
#settings-page h2 { #settings-page h2 {

View file

@ -45,6 +45,15 @@ body .ui-icon, .ui-widget-content .ui-icon {
background-image: url(libs/jquery/images/ui-icons_52b799_256x240.png); background-image: url(libs/jquery/images/ui-icons_52b799_256x240.png);
} }
li.language:hover {
cursor: pointer;
color: #005580;
}
#select-language {
cursor: pointer;
}
/* JQUERY UI DATETIME PICKER ADDON /* JQUERY UI DATETIME PICKER ADDON
------------------------------------------------------------------------- */ ------------------------------------------------------------------------- */
.ui-timepicker-div .ui-widget-header { margin-bottom: 8px; } .ui-timepicker-div .ui-widget-header { margin-bottom: 8px; }

View file

@ -23,6 +23,8 @@ $(document).ready(function() {
classes: 'qtip-green qtip-shadow custom-qtip' classes: 'qtip-green qtip-shadow custom-qtip'
} }
}); });
GeneralFunctions.enableLanguageSelection($('#select-language'));
}); });
/** /**

View file

@ -41,13 +41,42 @@ var BackendCalendar = {
'titleFormat': { 'titleFormat': {
'month': 'MMMM yyyy', 'month': 'MMMM yyyy',
'week': "MMMM d[ yyyy]{ '&#8212;'[ MMM] d, yyyy}", 'week': "MMMM d[ yyyy]{ '&#8212;'[ MMM] d, yyyy}",
'day': 'dddd, MMM d, yyyy' 'day': 'dddd, MMMM d, yyyy'
}, },
'header': { 'header': {
'left': 'prev,next today', 'left': 'prev,next today',
'center': 'title', 'center': 'title',
'right': 'agendaDay,agendaWeek,month' 'right': 'agendaDay,agendaWeek,month'
}, },
// Translations
'monthNames': [EALang['january'], EALang['february'], EALang['march'], EALang['april'],
EALang['may'], EALang['june'], EALang['july'], EALang['august'],
EALang['september'],EALang['october'], EALang['november'],
EALang['december']],
'monthNamesShort': [EALang['january'].substr(0,3), EALang['february'].substr(0,3),
EALang['march'].substr(0,3), EALang['april'].substr(0,3),
EALang['may'].substr(0,3), EALang['june'].substr(0,3),
EALang['july'].substr(0,3), EALang['august'].substr(0,3),
EALang['september'].substr(0,3),EALang['october'].substr(0,3),
EALang['november'].substr(0,3), EALang['december'].substr(0,3)],
'dayNames': [EALang['sunday'], EALang['monday'], EALang['tuesday'], EALang['wednesday'],
EALang['thursday'], EALang['friday'], EALang['saturday']],
'dayNamesShort': [EALang['sunday'].substr(0,3), EALang['monday'].substr(0,3),
EALang['tuesday'].substr(0,3), EALang['wednesday'].substr(0,3),
EALang['thursday'].substr(0,3), EALang['friday'].substr(0,3),
EALang['saturday'].substr(0,3)],
'dayNamesMin': [EALang['sunday'].substr(0,2), EALang['monday'].substr(0,2),
EALang['tuesday'].substr(0,2), EALang['wednesday'].substr(0,2),
EALang['thursday'].substr(0,2), EALang['friday'].substr(0,2),
EALang['saturday'].substr(0,2)],
'buttonText': {
'today': EALang['today'],
'day': EALang['day'],
'week': EALang['week'],
'month': EALang['month']
},
// Calendar events need to be declared on initialization. // Calendar events need to be declared on initialization.
'windowResize': BackendCalendar.calendarWindowResize, 'windowResize': BackendCalendar.calendarWindowResize,
'viewDisplay': BackendCalendar.calendarViewDisplay, 'viewDisplay': BackendCalendar.calendarViewDisplay,
@ -60,13 +89,6 @@ var BackendCalendar = {
} }
}); });
// Temporary fix: make the first letter capital in all the lowercase strings
// of the calendar.
$('#calendar .fc-button-today').text('Today');
$('#calendar .fc-button-agendaDay').text('Day');
$('#calendar .fc-button-agendaWeek').text('Week');
$('#calendar .fc-button-month').text('Month');
// Trigger once to set the proper footer position after calendar // Trigger once to set the proper footer position after calendar
// initialization. // initialization.
BackendCalendar.calendarWindowResize(); BackendCalendar.calendarWindowResize();
@ -1488,7 +1510,7 @@ var BackendCalendar = {
}); });
BackendCalendar.lastFocusedEventData = event; BackendCalendar.lastFocusedEventData = event;
$(jsEvent.target).popover('show'); $(jsEvent.target).popover('toggle');
// Fix popover position // Fix popover position
if ($('.popover').position().top < 200) $('.popover').css('top', '200px'); if ($('.popover').position().top < 200) $('.popover').css('top', '200px');

View file

@ -316,9 +316,10 @@ ServicesHelper.prototype.validate = function(service) {
missingRequired = true; missingRequired = true;
} }
}); });
if (missingRequired) {
if (missingRequired)
throw EALang['fields_are_required']; throw EALang['fields_are_required'];
}
return true; return true;
} catch(exc) { } catch(exc) {
@ -541,14 +542,13 @@ CategoriesHelper.prototype.bindEventHandlers = function() {
$('#delete-category').click(function() { $('#delete-category').click(function() {
var categoryId = $('#category-id').val(); var categoryId = $('#category-id').val();
var messageBtns = { var messageBtns = {};
'Delete': function() { messageBtns[EALang['delete']] = function() {
BackendServices.helper.delete(categoryId); BackendServices.helper.delete(categoryId);
$('#message_box').dialog('close'); $('#message_box').dialog('close');
}, };
'Cancel': function() { messageBtns[EALang['cancel']] = function() {
$('#message_box').dialog('close'); $('#message_box').dialog('close');
}
}; };
GeneralFunctions.displayMessageBox(EALang['delete_category'], GeneralFunctions.displayMessageBox(EALang['delete_category'],
@ -642,7 +642,7 @@ CategoriesHelper.prototype.save = function(category) {
if (!GeneralFunctions.handleAjaxExceptions(response)) return; if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification(EALang['category_saved']); Backend.displayNotification(EALang['service_category_saved']);
BackendServices.helper.resetForm(); BackendServices.helper.resetForm();
$('#filter-categories .key').val(''); $('#filter-categories .key').val('');
BackendServices.helper.filter('', response.id, true); BackendServices.helper.filter('', response.id, true);
@ -666,7 +666,7 @@ CategoriesHelper.prototype.delete = function(id) {
if (!GeneralFunctions.handleAjaxExceptions(response)) return; if (!GeneralFunctions.handleAjaxExceptions(response)) return;
Backend.displayNotification(EALang['category_deleted']); Backend.displayNotification(EALang['service_category_deleted']);
BackendServices.helper.resetForm(); BackendServices.helper.resetForm();
BackendServices.helper.filter($('#filter-categories .key').val()); BackendServices.helper.filter($('#filter-categories .key').val());

View file

@ -268,5 +268,54 @@ var GeneralFunctions = {
} }
return true; return true;
},
/**
* Enables the language selection functionality. Must be called on every page has a
* language selection button. This method requires the global variable 'availableLanguages'
* to be initialized before the execution.
*
* @param {object} $element Selected element button for the language selection.
*/
enableLanguageSelection: function($element) {
// Select Language
var html = '<ul id="language-list">';
$.each(availableLanguages, function() {
html += '<li class="language" data-language="' + this + '">'
+ GeneralFunctions.ucaseFirstLetter(this) + '</li>';
});
html += '</ul>';
$element.popover({
'placement': 'top',
'title': 'Select Language',
'content': html,
'html': true,
'container': 'body',
'trigger': 'manual'
});
$element.click(function() {
if ($('#language-list').length == 0) {
$(this).popover('show');
} else {
$(this).popover('hide');
}
});
$(document).on('click', 'li.language', function() {
// Change language with ajax call and refresh page.
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_change_language';
var postData = { 'language': $(this).attr('data-language') };
$.post(postUrl, postData, function(response) {
////////////////////////////////////////////////////
console.log('Change Language Response', response);
////////////////////////////////////////////////////
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
document.location.reload(true);
}, 'json');
});
} }
}; };

View file

@ -276,7 +276,7 @@ WorkingPlan.prototype.bindEventHandlers = function() {
*/ */
WorkingPlan.prototype.get = function() { WorkingPlan.prototype.get = function() {
var workingPlan = {}; var workingPlan = {};
$('.working-plan input[type="checkbox"').each(function() { $('.working-plan input[type="checkbox"]').each(function() {
var id = $(this).attr('id'); var id = $(this).attr('id');
if ($(this).prop('checked') == true) { if ($(this).prop('checked') == true) {
workingPlan[id] = {}; workingPlan[id] = {};