* Optimized js code for the backend pages.
This commit is contained in:
parent
3450bd93b1
commit
148258385c
17 changed files with 1596 additions and 1409 deletions
|
@ -474,8 +474,11 @@ class Backend_api extends CI_Controller {
|
|||
try {
|
||||
$this->load->model('customers_model');
|
||||
$customer = json_decode($_POST['customer'], true);
|
||||
$this->customers_model->add($customer);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$customer_id = $this->customers_model->add($customer);
|
||||
echo json_encode(array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $customer_id
|
||||
));
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
@ -509,8 +512,11 @@ class Backend_api extends CI_Controller {
|
|||
try {
|
||||
$this->load->model('services_model');
|
||||
$service = json_decode($_POST['service'], true);
|
||||
$this->services_model->add($service);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$service_id =$this->services_model->add($service);
|
||||
echo json_encode(array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $service_id
|
||||
));
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
@ -568,8 +574,11 @@ class Backend_api extends CI_Controller {
|
|||
try {
|
||||
$this->load->model('services_model');
|
||||
$category = json_decode($_POST['category'], true);
|
||||
$this->services_model->add_category($category);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$category_id = $this->services_model->add_category($category);
|
||||
echo json_encode(array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $category_id
|
||||
));
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
@ -644,15 +653,21 @@ class Backend_api extends CI_Controller {
|
|||
*
|
||||
* @param array $_POST['admin'] A json encoded array that contains the admin data. If an 'id'
|
||||
* value is provided then the record is going to be updated.
|
||||
* @return string Returns the success contant 'AJAX_SUCCESS' so javascript knows that
|
||||
* everything completed successfully.
|
||||
* @return array Returns an array with the operation status and the record id that was
|
||||
* saved into the database.
|
||||
*/
|
||||
public function ajax_save_admin() {
|
||||
try {
|
||||
$this->load->model('admins_model');
|
||||
$admin = json_decode($_POST['admin'], true);
|
||||
$this->admins_model->add($admin);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$admin_id = $this->admins_model->add($admin);
|
||||
|
||||
$response = array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $admin_id
|
||||
);
|
||||
|
||||
echo json_encode($response);
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
@ -722,8 +737,13 @@ class Backend_api extends CI_Controller {
|
|||
->get_setting('company_working_plan');
|
||||
}
|
||||
|
||||
$this->providers_model->add($provider);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$provider_id = $this->providers_model->add($provider);
|
||||
|
||||
echo json_encode(array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $provider_id
|
||||
));
|
||||
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
@ -786,8 +806,12 @@ class Backend_api extends CI_Controller {
|
|||
try {
|
||||
$this->load->model('secretaries_model');
|
||||
$secretary = json_decode($_POST['secretary'], true);
|
||||
$this->secretaries_model->add($secretary);
|
||||
echo json_encode(AJAX_SUCCESS);
|
||||
$secretary_id = $this->secretaries_model->add($secretary);
|
||||
|
||||
echo json_encode(array(
|
||||
'status' => AJAX_SUCCESS,
|
||||
'id' => $secretary_id
|
||||
));
|
||||
} catch(Exception $exc) {
|
||||
echo json_encode(array(
|
||||
'exceptions' => array(exceptionToJavaScript($exc))
|
||||
|
|
|
@ -204,16 +204,6 @@ class Secretaries_Model extends CI_Model {
|
|||
throw new Exception('Invalid email address provided : ' . $secretary['email']);
|
||||
}
|
||||
|
||||
// Validate admin username
|
||||
if (isset($secretary['settings']['username'])) {
|
||||
$num_rows = $this->db->get_where('ea_user_settings',
|
||||
array('username' => $secretary['settings']['username']))->num_rows();
|
||||
if ($num_rows > 0) {
|
||||
throw new Exception('Username already exists, please select another '
|
||||
. 'and try again (username: ' . $secretary['settings']['username'] . ')');
|
||||
}
|
||||
}
|
||||
|
||||
// Validate admin password
|
||||
if (isset($secretary['settings']['password'])) {
|
||||
if (strlen($secretary['settings']['password']) < MIN_PASSWORD_LENGTH) {
|
||||
|
|
|
@ -18,14 +18,21 @@
|
|||
</script>
|
||||
|
||||
<div id="customers-page" class="row-fluid">
|
||||
<div id="filter" class="span4">
|
||||
<div class="input-append">
|
||||
<input class="span12" type="text" id="filter-key" />
|
||||
<button type="button" class="btn" id="filter-customers">Filter</button>
|
||||
</div>
|
||||
<div id="filter-customers" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Customers</h2>
|
||||
<div id="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div id="details" class="span7 row-fluid">
|
||||
|
|
|
@ -28,16 +28,24 @@
|
|||
?>
|
||||
<div id="services" class="tab-content">
|
||||
<?php // FILTER SERVICES ?>
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" />
|
||||
<button class="filter-services btn" type="button">Filter</button>
|
||||
</div>
|
||||
<div id="filter-services" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Services</h2>
|
||||
<div class="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="details column span7">
|
||||
<div class="btn-toolbar">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-service" class="btn">
|
||||
|
@ -97,14 +105,21 @@
|
|||
// --------------------------------------------------------------
|
||||
?>
|
||||
<div id="categories" class="tab-content" style="display:none;">
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" class="" />
|
||||
<button class="filter-categories btn" type="button">Filter</button>
|
||||
</div>
|
||||
<div id="filter-categories" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" class="" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Categories</h2>
|
||||
<div class="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/backend_settings.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/working_plan.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery-ui-timepicker-addon.js"></script>
|
||||
<script type="text/javascript"
|
||||
|
@ -65,7 +67,7 @@
|
|||
|
||||
<a href="<?php echo $this->config->base_url(); ?>" class="btn btn-primary btn-large">
|
||||
<i class="icon-calendar icon-white"></i>
|
||||
Visit Book Appointment Page
|
||||
Book Appointment Page
|
||||
</a>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
@ -174,7 +176,7 @@
|
|||
|
||||
<br>
|
||||
|
||||
<table id="breaks" class="table table-striped">
|
||||
<table class="breaks table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Day</th>
|
||||
|
@ -255,8 +257,8 @@
|
|||
<br>
|
||||
|
||||
<button type="button" id="user-notifications" class="btn" data-toggle="button">
|
||||
<i class="icon-asterisk"></i>
|
||||
Receive Email Notifications
|
||||
<i class="icon-envelope"></i>
|
||||
Receive Notifications
|
||||
</button>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
|
|
@ -7,6 +7,9 @@
|
|||
src="<?php echo $base_url; ?>assets/js/backend_users_providers.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/backend_users_secretaries.js"></script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/working_plan.js"></script>
|
||||
|
||||
<script type="text/javascript"
|
||||
src="<?php echo $base_url; ?>assets/js/libs/jquery/jquery-ui-timepicker-addon.js"></script>
|
||||
|
@ -30,25 +33,45 @@
|
|||
|
||||
<div id="users-page" class="row-fluid">
|
||||
|
||||
<?php // Page Tabs ?>
|
||||
<?php
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Page Navigation
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
?>
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="admins-tab tab active"><a>Admins</a></li>
|
||||
<li class="providers-tab tab"><a>Providers</a></li>
|
||||
<li class="secretaries-tab tab"><a>Secretaries</a></li>
|
||||
</ul>
|
||||
|
||||
<?php // Admin Tab ?>
|
||||
<?php
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Admins Tab
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
?>
|
||||
<div id="admins" class="tab-content">
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" />
|
||||
<button class="filter-admins btn" type="button">Filter</button>
|
||||
</div>
|
||||
<div id="filter-admins" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Admins</h2>
|
||||
<div class="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="details column span7">
|
||||
<div class="btn-toolbar">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-admin" class="btn">
|
||||
|
@ -123,26 +146,40 @@
|
|||
<br>
|
||||
|
||||
<button type="button" id="admin-notifications" class="btn" data-toggle="button">
|
||||
<i class="icon-asterisk"></i>
|
||||
<span>Receive Email Notifications</span>
|
||||
<i class="icon-envelope"></i>
|
||||
<span>Receive Notifications</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<?php // Providers Tab ?>
|
||||
<?php
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Providers Tab
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
?>
|
||||
<div id="providers" class="tab-content" style="display:none;">
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" />
|
||||
<button class="filter-providers btn" type="button">Filter</button>
|
||||
</div>
|
||||
<div id="filter-providers" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Providers</h2>
|
||||
<div class="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="details column span7">
|
||||
<div class="btn-toolbar span5">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-provider" class="btn">
|
||||
|
@ -167,13 +204,16 @@
|
|||
</div>
|
||||
|
||||
<div class="switch-view pull-right">
|
||||
<strong>Current View</strong>
|
||||
<div class="display-details current">Details</div>
|
||||
<div class="display-working-plan">Working Plan</div>
|
||||
</div>
|
||||
|
||||
<?php // This form message is outside the details view, so that it can be
|
||||
// visible when the user has working plan view active. ?>
|
||||
<div class="form-message alert" style="display:none;"></div>
|
||||
|
||||
<div class="details-view">
|
||||
<div class="details-view provider-view">
|
||||
<h2>Details</h2>
|
||||
|
||||
<input type="hidden" id="provider-id" class="record-id" />
|
||||
|
@ -223,8 +263,8 @@
|
|||
<br>
|
||||
|
||||
<button type="button" id="provider-notifications" class="btn" data-toggle="button">
|
||||
<i class="icon-asterisk"></i>
|
||||
<span>Receive Email Notifications</span>
|
||||
<i class="icon-envelope"></i>
|
||||
<span>Receive Notifications</span>
|
||||
</button>
|
||||
|
||||
<br><br>
|
||||
|
@ -235,7 +275,7 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<div class="working-plan-view" style="display: none;">
|
||||
<div class="working-plan-view provider-view" style="display: none;">
|
||||
<h2>Working Plan</h2>
|
||||
<table class="working-plan table table-striped">
|
||||
<thead>
|
||||
|
@ -302,7 +342,7 @@
|
|||
|
||||
<br>
|
||||
|
||||
<table id="breaks" class="table table-striped">
|
||||
<table class="breaks table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Day</th>
|
||||
|
@ -318,18 +358,32 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<?php // Secretaries Tab ?>
|
||||
<?php
|
||||
// ---------------------------------------------------------------------
|
||||
//
|
||||
// Secretaries Tab
|
||||
//
|
||||
// ---------------------------------------------------------------------
|
||||
?>
|
||||
<div id="secretaries" class="tab-content" style="display:none;">
|
||||
<div class="filter span4">
|
||||
<div class="input-append">
|
||||
<input class="filter-key span12" type="text" />
|
||||
<button class="filter-secretaries btn" type="button">Filter</button>
|
||||
</div>
|
||||
<div id="filter-secretaries" class="filter-records column span4">
|
||||
<form class="input-append">
|
||||
<input class="key span8" type="text" />
|
||||
<button class="filter btn" type="submit">
|
||||
<i class="icon-filter"></i>
|
||||
Filter
|
||||
</button>
|
||||
<button class="clear btn" type="button">
|
||||
<i class="icon-remove-circle"></i>
|
||||
Clear
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<h2>Secretaries</h2>
|
||||
<div class="filter-results"></div>
|
||||
<div class="results"></div>
|
||||
</div>
|
||||
|
||||
<div class="details span7">
|
||||
<div class="details column span7">
|
||||
<div class="btn-toolbar">
|
||||
<div class="add-edit-delete-group btn-group">
|
||||
<button id="add-secretary" class="btn">
|
||||
|
@ -404,7 +458,7 @@
|
|||
<br>
|
||||
|
||||
<button type="button" id="secretary-notifications" class="btn" data-toggle="button">
|
||||
<i class="icon-asterisk"></i>
|
||||
<i class="icon-envelope"></i>
|
||||
<span>Receive Notifications</span>
|
||||
</button>
|
||||
|
||||
|
|
|
@ -194,24 +194,25 @@ body .modal-header h3 {
|
|||
|
||||
/* BACKEND CUSTOMERS PAGE
|
||||
-------------------------------------------------------------------- */
|
||||
#customers-page #filter {
|
||||
#customers-page #filter-customers {
|
||||
margin: 15px 0px 15px 15px;
|
||||
}
|
||||
|
||||
#customers-page #filter-results {
|
||||
#customers-page .filter-records .results {
|
||||
overflow-y: auto;
|
||||
max-height: 650px;
|
||||
}
|
||||
|
||||
#customers-page #filter-results .customer-row {
|
||||
#customers-page #filter-customers .results .customer-row {
|
||||
padding: 10px 7px; border-radius: 3px;
|
||||
}
|
||||
|
||||
#customers-page #filter-results .customer-row:hover {
|
||||
#customers-page #filter-customers .results .customer-row:hover {
|
||||
background-color: #C6E7D5;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#customers-page #filter-results hr {
|
||||
#customers-page #filter-customers .results hr {
|
||||
margin: 5px 0;
|
||||
}
|
||||
|
||||
|
@ -270,6 +271,11 @@ body .modal-header h3 {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#services-page .filter-records .results {
|
||||
overflow-y: auto;
|
||||
max-height: 650px;
|
||||
}
|
||||
|
||||
#services-page .service-row {
|
||||
padding: 10px 7px;
|
||||
border-radius: 3px;
|
||||
|
@ -330,6 +336,11 @@ body .modal-header h3 {
|
|||
cursor: pointer;
|
||||
}
|
||||
|
||||
#users-page .filter-records .results {
|
||||
overflow-y: auto;
|
||||
max-height: 650px;
|
||||
}
|
||||
|
||||
#users-page .secretary-row,
|
||||
#users-page .provider-row,
|
||||
#users-page .admin-row {
|
||||
|
@ -358,7 +369,8 @@ body .modal-header h3 {
|
|||
#users-page #secretary-notifications.active,
|
||||
#users-page #provider-notifications.active,
|
||||
#users-page #admin-notifications.active {
|
||||
background: #FFFF91;
|
||||
background: #B6DCFF;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
#users-page #secretary-providers,
|
||||
|
@ -377,11 +389,11 @@ body .modal-header h3 {
|
|||
|
||||
#users-page #providers .switch-view div {
|
||||
display: inline-block;
|
||||
padding: 10px 15px;
|
||||
padding: 6px 13px;
|
||||
border-radius: 4px;
|
||||
color: #333;
|
||||
float: left;
|
||||
margin-right: 5px;
|
||||
margin-right: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
@ -389,6 +401,13 @@ body .modal-header h3 {
|
|||
background: #F5F5F5;
|
||||
}
|
||||
|
||||
#users-page #providers .switch-view strong {
|
||||
display: inline-block;
|
||||
float: left;
|
||||
margin: 8px 20px;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
#users-page #providers .switch-view .current {
|
||||
color: #FFF;
|
||||
background: #95E4A8;
|
||||
|
@ -408,7 +427,7 @@ background: #95E4A8;
|
|||
clear: both;
|
||||
}
|
||||
|
||||
#users-page #providers #breaks .btn {
|
||||
#users-page #providers .breaks .btn {
|
||||
margin-right: 5px;
|
||||
padding: 4px 7px;
|
||||
}
|
||||
|
@ -437,21 +456,21 @@ padding: 4px 7px;
|
|||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#business-logic #breaks .btn {
|
||||
#business-logic .breaks .btn {
|
||||
margin-right: 5px;
|
||||
padding: 4px 7px;
|
||||
}
|
||||
|
||||
#business-logic #breaks input {
|
||||
#business-logic .breaks input {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
#business-logic #breaks .editable form {
|
||||
#business-logic .breaks .editable form {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#business-logic #breaks .editable select,
|
||||
#business-logic #breaks .editable input {
|
||||
#business-logic .breaks .editable select,
|
||||
#business-logic .breaks .editable input {
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
@ -462,4 +481,9 @@ padding: 4px 7px;
|
|||
|
||||
#business-logic .ui-spinner {
|
||||
border: none;
|
||||
}
|
||||
|
||||
#settings-page #user-notifications.active {
|
||||
background: #B6DCFF;
|
||||
box-shadow: none;
|
||||
}
|
|
@ -640,7 +640,7 @@ var BackendCalendar = {
|
|||
$('#enable-sync span').text('Enable Sync');
|
||||
$('#google-sync').prop('disabled', true);
|
||||
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1477,7 +1477,7 @@ var BackendCalendar = {
|
|||
$.each(provider['services'], function(index, serviceId) {
|
||||
if (serviceId == $dialog.find('#select-service').val()) {
|
||||
canProvideService = true;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -1495,7 +1495,7 @@ var BackendCalendar = {
|
|||
$.each(GlobalVariables.availableServices, function(index, service) {
|
||||
if (service['id'] == $dialog.find('#select-service').val()) {
|
||||
serviceDuration = service['duration'];
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -6,26 +6,29 @@
|
|||
* @namespace BackendCustomers
|
||||
*/
|
||||
var BackendCustomers = {
|
||||
filterResults: {},
|
||||
selectedCustomer: {},
|
||||
selectedAppointment: {},
|
||||
|
||||
/**
|
||||
* The page helper contains methods that implement each record type functionality
|
||||
* (for now there is only the CustomersHelper).
|
||||
*
|
||||
* @type {object{
|
||||
*/
|
||||
helper: {},
|
||||
|
||||
/**
|
||||
* This method initializes the backend customers page. If you use this namespace
|
||||
* in a different page do not use this method.
|
||||
*
|
||||
* @param {bool} bindDefaultEventHandlers Whether to bind the default event handlers
|
||||
* or not.
|
||||
* @param {bool} defaultEventHandlers (OPTIONAL = false) Whether to bind the default
|
||||
* event handlers or not.
|
||||
*/
|
||||
initialize: function(bindDefaultEventHandlers) {
|
||||
if (bindDefaultEventHandlers === undefined) {
|
||||
bindDefaultEventHandlers = false; // default value
|
||||
}
|
||||
initialize: function(defaultEventHandlers) {
|
||||
if (defaultEventHandlers == undefined) defaultEventHandlers = false;
|
||||
|
||||
BackendCustomers.helper = new CustomersHelper();
|
||||
BackendCustomers.helper.resetForm();
|
||||
BackendCustomers.helper.filter('');
|
||||
|
||||
BackendCustomers.filterCustomers('');
|
||||
$('#details').find('input, textarea').prop('readonly', true);
|
||||
|
||||
if (bindDefaultEventHandlers) {
|
||||
if (defaultEventHandlers) {
|
||||
BackendCustomers.bindEventHandlers();
|
||||
}
|
||||
},
|
||||
|
@ -34,376 +37,413 @@ var BackendCustomers = {
|
|||
* Default event handlers declaration for backend customers page.
|
||||
*/
|
||||
bindEventHandlers: function() {
|
||||
/**
|
||||
* Event: Customer Row "Click"
|
||||
*
|
||||
* Display the customer data of the selected row.
|
||||
*/
|
||||
$(document).on('click', '.customer-row', function() {
|
||||
if ($('#filter-customers').prop('disabled')) {
|
||||
return; // Do nothing when user edits a customer record.
|
||||
}
|
||||
|
||||
$('#filter-results .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
|
||||
var customerId = $(this).attr('data-id');
|
||||
var customer;
|
||||
|
||||
$.each(BackendCustomers.filterResults, function(index, item) {
|
||||
if (item.id === customerId) {
|
||||
customer = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
BackendCustomers.selectedCustomer = customer;
|
||||
BackendCustomers.displayCustomer(customer);
|
||||
$('#edit-customer, #delete-customer').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Appointment Row "Click"
|
||||
*
|
||||
* Display appointment data of the selected row.
|
||||
*/
|
||||
$(document).on('click', '.appointment-row', function() {
|
||||
$('#customer-appointments .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
|
||||
var appointmentId = $(this).attr('data-id');
|
||||
var appointment;
|
||||
|
||||
$.each(BackendCustomers.selectedCustomer.appointments, function(index, item) {
|
||||
if (item.id === appointmentId) {
|
||||
appointment = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
BackendCustomers.selectedAppointment = appointment;
|
||||
BackendCustomers.displayAppointment(appointment);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Customers Button "Click"
|
||||
*
|
||||
* Filter customer rows with given string.
|
||||
*/
|
||||
$('#filter-customers').click(function() {
|
||||
BackendCustomers.filterCustomers($('#filter-key').val());
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Customer Button "Click"
|
||||
*/
|
||||
$('#add-customer').click(function() {
|
||||
BackendCustomers.resetForm();
|
||||
$('#add-edit-delete-group').hide();
|
||||
$('#save-cancel-group').show();
|
||||
$('#details').find('input, textarea').prop('readonly', false);
|
||||
$('#filter-customers').prop('disabled', true);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Customer Button "Click"
|
||||
*/
|
||||
$('#edit-customer').click(function() {
|
||||
$('#details').find('input, textarea').prop('readonly', false);
|
||||
$('#add-edit-delete-group').hide();
|
||||
$('#save-cancel-group').show();
|
||||
$('#filter-customers').prop('disabled', true);
|
||||
$('#filter-results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Customer Add/Edit Operation Button "Click"
|
||||
*/
|
||||
$('#cancel-customer').click(function() {
|
||||
$('#details').find('input, textarea').prop('readonly', true);
|
||||
$('#save-cancel-group').hide();
|
||||
$('#add-edit-delete-group').show();
|
||||
$('#filter-customers').prop('disabled', false);
|
||||
$('#filter-results').css('color', '');
|
||||
// Reset the selected appointments data.
|
||||
$('#filter-results .selected-row').trigger('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Add/Edit Customer Operation "Click"
|
||||
*/
|
||||
$('#save-customer').click(function() {
|
||||
$('#filter-results').css('color', '');
|
||||
|
||||
var customer = {
|
||||
'first_name': $('#first-name').val(),
|
||||
'last_name': $('#last-name').val(),
|
||||
'email': $('#email').val(),
|
||||
'phone_number': $('#phone-number').val(),
|
||||
'address': $('#address').val(),
|
||||
'city': $('#city').val(),
|
||||
'zip_code': $('#zip-code').val(),
|
||||
'notes': $('#notes').val()
|
||||
};
|
||||
|
||||
if ($('#customer-id').val() != '') {
|
||||
customer.id = $('#customer-id').val();
|
||||
}
|
||||
|
||||
BackendCustomers.saveCustomer(customer);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Customer Button "Click"
|
||||
*/
|
||||
$('#delete-customer').click(function() {
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
var customerId = BackendCustomers.selectedCustomer.id;
|
||||
BackendCustomers.deleteCustomer(customerId);
|
||||
},
|
||||
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Customer', 'Are you sure that you want '
|
||||
+ 'to delete this customer? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* This method displays the customer data on the right part of the page.
|
||||
* When a customer is selected the user can make changes and update the
|
||||
* customer record.
|
||||
*
|
||||
* @param {int} customerId Selected customer's record id.
|
||||
*/
|
||||
displayCustomer: function(customer) {
|
||||
if (customer === undefined) {
|
||||
throw 'DisplayCustomer: customer is undefined';
|
||||
CustomersHelper.prototype.bindEventHandlers();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class contains the methods that are used in the backend customers page.
|
||||
*
|
||||
* @class CustomersHelper
|
||||
*/
|
||||
var CustomersHelper = function() {
|
||||
this.filterResults = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Binds the default event handlers of the backend customers page.
|
||||
*/
|
||||
CustomersHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Customers Form "Submit"
|
||||
*/
|
||||
$('#filter-customers form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-customers .key').val();
|
||||
$('#filter-customers .selected-row').removeClass('selected-row');
|
||||
BackendCustomers.helper.resetForm();
|
||||
BackendCustomers.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Customers Clear Button "Click"
|
||||
*/
|
||||
$('#filter-customers .clear').click(function() {
|
||||
$('#filter-customers .key').val('');
|
||||
BackendCustomers.helper.filter('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Customer Row "Click"
|
||||
*
|
||||
* Display the customer data of the selected row.
|
||||
*/
|
||||
$(document).on('click', '.customer-row', function() {
|
||||
if ($('#filter-customers .filter').prop('disabled')) {
|
||||
return; // Do nothing when user edits a customer record.
|
||||
}
|
||||
|
||||
BackendCustomers.resetForm();
|
||||
|
||||
$('#customer-id').val(customer.id);
|
||||
$('#first-name').val(customer.first_name);
|
||||
$('#last-name').val(customer.last_name);
|
||||
$('#email').val(customer.email);
|
||||
$('#phone-number').val(customer.phone_number);
|
||||
$('#address').val(customer.address);
|
||||
$('#city').val(customer.city);
|
||||
$('#zip-code').val(customer.zip_code);
|
||||
$('#notes').val(customer.notes);
|
||||
|
||||
$.each(customer.appointments, function(index, appointment) {
|
||||
var start = Date.parse(appointment.start_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
var end = Date.parse(appointment.end_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
var html =
|
||||
'<div class="appointment-row" data-id="' + appointment.id + '">' +
|
||||
start + ' - ' + end + '<br>' +
|
||||
appointment.service.name + ', ' +
|
||||
appointment.provider.first_name + ' ' + appointment.provider.last_name +
|
||||
'</div>';
|
||||
$('#customer-appointments').append(html);
|
||||
var customerId = $(this).attr('data-id');
|
||||
var customer = {};
|
||||
$.each(BackendCustomers.helper.filterResults, function(index, item) {
|
||||
if (item.id == customerId) {
|
||||
customer = item;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* This method makes an ajax call to the server and save the changes of
|
||||
* an existing customer record, or inserts a new customer row when on insert
|
||||
* mode.
|
||||
*
|
||||
* NOTICE: User the "deleteCustomer" method to delete a customer record.
|
||||
*
|
||||
* @param {object} customer Contains the customer data. If "id" is not
|
||||
* provided then the record is going to be inserted.
|
||||
*/
|
||||
saveCustomer: function(customer) {
|
||||
if (!BackendCustomers.validateForm()) return;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_customer';
|
||||
var postData = { 'customer': JSON.stringify(customer) };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox(Backend.EXCEPTIONS_TITLE, Backend.EXCEPTIONS_MESSAGE);
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.warnings) {
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox(Backend.WARNINGS_TITLE, Backend.WARNINGS_MESSAGE);
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
$('#add-edit-delete-group').show();
|
||||
$('#save-cancel-group').hide();
|
||||
$('#filter-customers').prop('disabled', false);
|
||||
$('#details').find('input, textarea').prop('readonly', true);
|
||||
|
||||
BackendCustomers.filterCustomers($('#filter-key').val());
|
||||
|
||||
// On edit mode keep the customer data on form.
|
||||
if (customer.id) {
|
||||
$.each(BackendCustomers.filterResults, function(index, item) {
|
||||
if (item.id == customer.id) {
|
||||
customer.appointments = item.appointments; // w/ appointments
|
||||
return;
|
||||
BackendCustomers.helper.display(customer);
|
||||
$('#filter-customers .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-customer, #delete-customer').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Appointment Row "Click"
|
||||
*
|
||||
* Display appointment data of the selected row.
|
||||
*/
|
||||
$(document).on('click', '.appointment-row', function() {
|
||||
$('#customer-appointments .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
|
||||
var customerId = $('#filter-customers .selected-row').attr('data-id');
|
||||
var appointmentId = $(this).attr('data-id');
|
||||
var appointment = {};
|
||||
|
||||
$.each(BackendCustomers.helper.filterResults, function(index, c) {
|
||||
if (c.id === customerId) {
|
||||
$.each(c.appointments, function(index, a) {
|
||||
if (a.id == appointmentId) {
|
||||
appointment = a;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
BackendCustomers.displayCustomer(customer);
|
||||
$('#edit-customer, #delete-customer').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
}, 'json');
|
||||
},
|
||||
|
||||
/**
|
||||
* This method makes an ajax call to the server and deletes the selected
|
||||
* customer record.
|
||||
*
|
||||
* @param {int} customerId The customer record id to be deleted.
|
||||
*/
|
||||
deleteCustomer: function(customerId) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_delete_customer';
|
||||
var postData = { 'customer_id': BackendCustomers.selectedCustomer.id };
|
||||
});
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately the '
|
||||
+ 'filter operation could not complete successfully. The following '
|
||||
+ 'issues occured.');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
BackendCustomers.helper.displayAppointment(appointment);
|
||||
});
|
||||
|
||||
if (response.warnings) {
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The filter operation '
|
||||
+ 'complete with the following warnings.');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
/**
|
||||
* Event: Add Customer Button "Click"
|
||||
*/
|
||||
$('#add-customer').click(function() {
|
||||
BackendCustomers.helper.resetForm();
|
||||
$('#add-edit-delete-group').hide();
|
||||
$('#save-cancel-group').show();
|
||||
$('#details').find('input, textarea').prop('readonly', false);
|
||||
|
||||
$('#message_box').dialog('close');
|
||||
BackendCustomers.filterCustomers($('#filter-key').val());
|
||||
}, 'json');
|
||||
},
|
||||
|
||||
/**
|
||||
* This method filters the system registered customers. Pass an empty string
|
||||
* to display all customers.
|
||||
*
|
||||
* @param {string} key The filter key string.
|
||||
*/
|
||||
filterCustomers: function(key) {
|
||||
$('#filter-results').html('');
|
||||
BackendCustomers.resetForm();
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_customers';
|
||||
var postData = { 'key': key };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
if (response.exceptions) {
|
||||
response.exceptions = GeneralFunctions.parseExceptions(response.exceptions);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Issues', 'Unfortunately the '
|
||||
+ 'filter operation could not complete successfully. The following '
|
||||
+ 'issues occured.');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.exceptions));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.warnings) {
|
||||
response.warnings = GeneralFunctions.parseExceptions(response.warnings);
|
||||
GeneralFunctions.displayMessageBox('Unexpected Warnings', 'The filter operation '
|
||||
+ 'complete with the following warnings.');
|
||||
$('#message_box').append(GeneralFunctions.exceptionsToHtml(response.warnings));
|
||||
}
|
||||
|
||||
BackendCustomers.filterResults = response;
|
||||
|
||||
$.each(response, function(index, customer) {
|
||||
var html =
|
||||
'<div class="customer-row" data-id="' + customer.id + '">' +
|
||||
'<strong>' +
|
||||
customer.first_name + ' ' + customer.last_name +
|
||||
'</strong><br>' +
|
||||
'<span>' + customer.email + '</span> | ' +
|
||||
'<span>' + customer.phone_number + '</span>' +
|
||||
'</div><hr>';
|
||||
$('#filter-results').append(html);
|
||||
});
|
||||
}, 'json');
|
||||
},
|
||||
|
||||
/**
|
||||
* This method validates the main customer form of the page. There are certain
|
||||
* rules that the record must fullfil before getting into the system database.
|
||||
*
|
||||
* @return {bool} Returns the validation result.
|
||||
*/
|
||||
validateForm: function() {
|
||||
try {
|
||||
$('#form-message').hide();
|
||||
$('.required').css('border', '');
|
||||
|
||||
// :: CHECK REQUIRED FIELDS
|
||||
var missingRequiredField = false;
|
||||
$('.required').each(function() {
|
||||
if ($(this).val() == '') {
|
||||
$(this).css('border', '2px solid red');
|
||||
missingRequiredField = true;
|
||||
}
|
||||
});
|
||||
if (missingRequiredField) {
|
||||
throw 'Fields with * are required!';
|
||||
}
|
||||
|
||||
// :: CHECK EMAIL ADDRESS
|
||||
if (!GeneralFunctions.validateEmail($('#email').val())) {
|
||||
$('#email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch(exc) {
|
||||
$('#form-message').text(exc).show();
|
||||
return false;
|
||||
$('#filter-customers button').prop('disabled', true);
|
||||
$('#filter-customers .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Customer Button "Click"
|
||||
*/
|
||||
$('#edit-customer').click(function() {
|
||||
$('#details').find('input, textarea').prop('readonly', false);
|
||||
$('#add-edit-delete-group').hide();
|
||||
$('#save-cancel-group').show();
|
||||
|
||||
$('#filter-customers button').prop('disabled', true);
|
||||
$('#filter-customers .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Customer Add/Edit Operation Button "Click"
|
||||
*/
|
||||
$('#cancel-customer').click(function() {
|
||||
var id = $('#customer-id').val();
|
||||
BackendCustomers.helper.resetForm();
|
||||
if (id != '') {
|
||||
BackendCustomers.helper.select(id, true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Bring the customer data form back to its initial state.
|
||||
*/
|
||||
resetForm: function() {
|
||||
$('#details').find('input, textarea').val('');
|
||||
$('#customer-appointments').html('');
|
||||
$('#appointment-details').html('');
|
||||
$('#edit-customer, #delete-customer').prop('disabled', true);
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Display appointment details on customers backend page.
|
||||
*
|
||||
* @param {object} appointment Appointment data
|
||||
* Event: Save Add/Edit Customer Operation "Click"
|
||||
*/
|
||||
displayAppointment: function(appointment) {
|
||||
$('#save-customer').click(function() {
|
||||
var customer = {
|
||||
'first_name': $('#first-name').val(),
|
||||
'last_name': $('#last-name').val(),
|
||||
'email': $('#email').val(),
|
||||
'phone_number': $('#phone-number').val(),
|
||||
'address': $('#address').val(),
|
||||
'city': $('#city').val(),
|
||||
'zip_code': $('#zip-code').val(),
|
||||
'notes': $('#notes').val()
|
||||
};
|
||||
|
||||
if ($('#customer-id').val() != '') {
|
||||
customer.id = $('#customer-id').val();
|
||||
}
|
||||
|
||||
if (!BackendCustomers.helper.validate(customer)) return;
|
||||
|
||||
BackendCustomers.helper.save(customer);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Customer Button "Click"
|
||||
*/
|
||||
$('#delete-customer').click(function() {
|
||||
var customerId = $('#customer-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendCustomers.helper.delete(customerId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Customer', 'Are you sure that you want '
|
||||
+ 'to delete this customer? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Save a customer record to the database (via ajax post).
|
||||
*
|
||||
* @param {object} customer Contains the customer data.
|
||||
*/
|
||||
CustomersHelper.prototype.save = function(customer) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_customer';
|
||||
var postData = { 'customer': JSON.stringify(customer) };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
///////////////////////////////////////////////////////////
|
||||
console.log('Save Customer Response:', response);
|
||||
///////////////////////////////////////////////////////////
|
||||
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
Backend.displayNotification('Customer saved successfully!');
|
||||
BackendCustomers.helper.resetForm();
|
||||
$('#filter-customers .key').val('');
|
||||
BackendCustomers.helper.filter('', response.id, true);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a customer record from database.
|
||||
*
|
||||
* @param {numeric} id Record id to be deleted.
|
||||
*/
|
||||
CustomersHelper.prototype.delete = function(id) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_delete_customer';
|
||||
var postData = { 'customer_id': id };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
////////////////////////////////////////////////////
|
||||
//console.log('Delete customer response:', response);
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
Backend.displayNotification('Customer deleted successfully!');
|
||||
BackendCustomers.helper.resetForm();
|
||||
BackendCustomers.helper.filter($('#filter-customers .key').val());
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Validate customer data before save (insert or update).
|
||||
*
|
||||
* @param {object} customer Contains the customer data.
|
||||
*/
|
||||
CustomersHelper.prototype.validate = function(customer) {
|
||||
$('#form-message').hide();
|
||||
$('.required').css('border', '');
|
||||
|
||||
try {
|
||||
// Validate required fields.
|
||||
var missingRequired = false;
|
||||
$('.required').each(function() {
|
||||
if ($(this).val() == '') {
|
||||
$(this).css('border', '2px solid red');
|
||||
missingRequired = true;
|
||||
}
|
||||
});
|
||||
if (missingRequired) {
|
||||
throw 'Fields with * are required!';
|
||||
}
|
||||
|
||||
// Validate email address.
|
||||
if (!GeneralFunctions.validateEmail($('#email').val())) {
|
||||
$('#email').css('border', '2px solid red');
|
||||
throw 'Invalid email address!';
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
} catch(exc) {
|
||||
$('#form-message').text(exc).show();
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Bring the customer form back to its initial state.
|
||||
*/
|
||||
CustomersHelper.prototype.resetForm = function() {
|
||||
$('#details').find('input, textarea').val('');
|
||||
$('#customer-appointments').html('');
|
||||
$('#appointment-details').html('');
|
||||
$('#edit-customer, #delete-customer').prop('disabled', true);
|
||||
$('#add-edit-delete-group').show();
|
||||
$('#save-cancel-group').hide();
|
||||
|
||||
$('#filter-customers button').prop('disabled', false);
|
||||
$('#filter-customers .selected-row').removeClass('selected-row');
|
||||
$('#filter-customers .results').css('color', '');
|
||||
};
|
||||
|
||||
/**
|
||||
* Display a customer record into the form.
|
||||
*
|
||||
* @param {object} customer Contains the customer record data.
|
||||
*/
|
||||
CustomersHelper.prototype.display = function(customer) {
|
||||
$('#customer-id').val(customer.id);
|
||||
$('#first-name').val(customer.first_name);
|
||||
$('#last-name').val(customer.last_name);
|
||||
$('#email').val(customer.email);
|
||||
$('#phone-number').val(customer.phone_number);
|
||||
$('#address').val(customer.address);
|
||||
$('#city').val(customer.city);
|
||||
$('#zip-code').val(customer.zip_code);
|
||||
$('#notes').val(customer.notes);
|
||||
|
||||
$('#customer-appointments').empty();
|
||||
$.each(customer.appointments, function(index, appointment) {
|
||||
var start = Date.parse(appointment.start_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
var end = Date.parse(appointment.end_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
|
||||
var html =
|
||||
'<div>' +
|
||||
'<strong>' + appointment.service.name + '</strong><br>' +
|
||||
appointment.provider.first_name + ' ' + appointment.provider.last_name + '<br>' +
|
||||
'<div class="appointment-row" data-id="' + appointment.id + '">' +
|
||||
start + ' - ' + end + '<br>' +
|
||||
'</div>';
|
||||
appointment.service.name + ', ' +
|
||||
appointment.provider.first_name + ' ' + appointment.provider.last_name +
|
||||
'</div>';
|
||||
$('#customer-appointments').append(html);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter customer records.
|
||||
*
|
||||
* @param {string} key This key string is used to filter the customer records.
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter
|
||||
* operation the record with the given id will be selected (but not displayed).
|
||||
* @param {bool} display (OPTIONAL = false) If true then the selected record will
|
||||
* be displayed on the form.
|
||||
*/
|
||||
CustomersHelper.prototype.filter = function(key, selectId, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_customers';
|
||||
var postData = { 'key': key };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
///////////////////////////////////////////////////////
|
||||
console.log('Filter Customers Response:', response);
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
$('#appointment-details').html(html);
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
BackendCustomers.helper.filterResults = response;
|
||||
|
||||
$('#filter-customers .results').html('');
|
||||
$.each(response, function(index, customer) {
|
||||
var html = BackendCustomers.helper.getFilterHtml(customer);
|
||||
$('#filter-customers .results').append(html);
|
||||
});
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-customers .results').html('<em>No records found...</em>');
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendCustomers.helper.select(selectId, display);
|
||||
}
|
||||
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the filter results row html code.
|
||||
*
|
||||
* @param {object} customer Contains the customer data.
|
||||
* @return {string} Returns the record html code.
|
||||
*/
|
||||
CustomersHelper.prototype.getFilterHtml = function(customer) {
|
||||
var html =
|
||||
'<div class="customer-row" data-id="' + customer.id + '">' +
|
||||
'<strong>' +
|
||||
customer.first_name + ' ' + customer.last_name +
|
||||
'</strong><br>' +
|
||||
'<span>' + customer.email + '</span> | ' +
|
||||
'<span>' + customer.phone_number + '</span>' +
|
||||
'</div><hr>';
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a specific record from the current filter results. If the customer id does not exist
|
||||
* in the list then no record will be selected.
|
||||
*
|
||||
* @param {numeric} id The record id to be selected from the filter results.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the method will display the record
|
||||
* on the form.
|
||||
*
|
||||
* @task The selected row must always be visible (even if a vertical scroll bar is used to
|
||||
* navigate through the filter results).
|
||||
*/
|
||||
CustomersHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
$('#filter-customers .selected-row').removeClass('selected-row');
|
||||
|
||||
$('#filter-customers .customer-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (display) {
|
||||
$.each(BackendCustomers.helper.filterResults, function(index, customer) {
|
||||
if (customer.id == id) {
|
||||
BackendCustomers.helper.display(customer);
|
||||
$('#edit-customer, #delete-customer').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display appointment details on customers backend page.
|
||||
*
|
||||
* @param {object} appointment Appointment data
|
||||
*/
|
||||
CustomersHelper.prototype.displayAppointment = function(appointment) {
|
||||
var start = Date.parse(appointment.start_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
var end = Date.parse(appointment.end_datetime).toString('dd/MM/yyyy HH:mm');
|
||||
|
||||
var html =
|
||||
'<div>' +
|
||||
'<strong>' + appointment.service.name + '</strong><br>' +
|
||||
appointment.provider.first_name + ' ' + appointment.provider.last_name + '<br>' +
|
||||
start + ' - ' + end + '<br>' +
|
||||
'</div>';
|
||||
|
||||
$('#appointment-details').html(html);
|
||||
};
|
|
@ -69,227 +69,14 @@ var BackendServices = {
|
|||
$('.filter-key').val('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Services Button "Click"
|
||||
*/
|
||||
$('.filter-services').click(function() {
|
||||
var key = $('#services .filter-key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter(key);
|
||||
});
|
||||
ServicesHelper.prototype.bindEventHandlers();
|
||||
CategoriesHelper.prototype.bindEventHandlers();
|
||||
|
||||
/**
|
||||
* Event: Filter Categories Button "Click"
|
||||
*/
|
||||
$('.filter-categories').click(function() {
|
||||
var key = $('#categories .filter-key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Service Row "Click"
|
||||
*
|
||||
* Display the selected service data to the user.
|
||||
*/
|
||||
$(document).on('click', '.service-row', function() {
|
||||
if ($('#services .filter-services').prop('disabled')) {
|
||||
$('#services .filter-results').css('color', '#AAA');
|
||||
return; // exit because we are on edit mode
|
||||
}
|
||||
|
||||
var service = { 'id': $(this).attr('data-id') };
|
||||
$.each(BackendServices.helper.filterResults, function(index, item) {
|
||||
if (item.id === service.id) {
|
||||
service = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
BackendServices.helper.display(service);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-service, #delete-service').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Categories Row "Click"
|
||||
*
|
||||
* Displays the selected row data on the right side of the page.
|
||||
*/
|
||||
$(document).on('click', '.category-row', function() {
|
||||
if ($('#categories .filter-categories').prop('disabled')) {
|
||||
$('#categories .filter-results').css('color', '#AAA');
|
||||
return; // exit because we are on edit mode
|
||||
}
|
||||
var category = { 'id': $(this).attr('data-id') };
|
||||
$.each(BackendServices.helper.filterResults, function(index, item) {
|
||||
if (item.id === category.id) {
|
||||
category = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
BackendServices.helper.display(category);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-category, #delete-category').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add New Service Button "Click"
|
||||
*/
|
||||
$('#add-service').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
$('#services .add-edit-delete-group').hide();
|
||||
$('#services .save-cancel-group').show();
|
||||
$('#services .details').find('input, textarea').prop('readonly', false);
|
||||
$('#services .details').find('select').prop('disabled', false);
|
||||
$('#service-duration').spinner('enable');
|
||||
$('#services .filter-services').prop('disabled', true);
|
||||
$('#services .filter-results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Category Button "Click"
|
||||
*/
|
||||
$('#add-category').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
$('#categories .add-edit-delete-group').hide();
|
||||
$('#categories .save-cancel-group').show();
|
||||
$('#categories .details').find('input, textarea').prop('readonly', false);
|
||||
$('#categories .filter-categories').prop('disabled', true);
|
||||
$('#categories .filter-results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Service Button "Click"
|
||||
*
|
||||
* Cancel add or edit of a service record.
|
||||
*/
|
||||
$('#cancel-service').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Category Button "Click"
|
||||
*/
|
||||
$('#cancel-category').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Service Button "Click"
|
||||
*/
|
||||
$('#save-service').click(function() {
|
||||
var service = {
|
||||
'name': $('#service-name').val(),
|
||||
'duration': $('#service-duration').val(),
|
||||
'price': $('#service-price').val(),
|
||||
'currency': $('#service-currency').val(),
|
||||
'description': $('#service-description').val()
|
||||
};
|
||||
|
||||
if ($('#service-category').val() !== 'null') {
|
||||
service.id_service_categories = $('#service-category').val();
|
||||
} else {
|
||||
service.id_service_categories = null;
|
||||
}
|
||||
|
||||
if ($('#service-id').val() !== '') {
|
||||
service.id = $('#service-id').val();
|
||||
}
|
||||
|
||||
if (!BackendServices.helper.validate(service)) return;
|
||||
|
||||
BackendServices.helper.save(service);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Categories Save Button "Click"
|
||||
*/
|
||||
$('#save-category').click(function() {
|
||||
var category = {
|
||||
'name': $('#category-name').val(),
|
||||
'description': $('#category-description').val()
|
||||
};
|
||||
|
||||
if ($('#category-id').val() !== '') {
|
||||
category.id = $('#category-id').val();
|
||||
}
|
||||
|
||||
if (!BackendServices.helper.validate(category)) return;
|
||||
|
||||
BackendServices.helper.save(category);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Service Button "Click"
|
||||
*/
|
||||
$('#edit-service').click(function() {
|
||||
$('#services .add-edit-delete-group').hide();
|
||||
$('#services .save-cancel-group').show();
|
||||
$('.filter-services').prop('disabled', true);
|
||||
$('#services .filter-results').css('color', '#AAA');
|
||||
$('#services .details').find('input, textarea').prop('readonly', false);
|
||||
$('#services .details select').prop('disabled', false);
|
||||
$('#service-duration').spinner('enable');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Category Button "Click"
|
||||
*/
|
||||
$('#edit-category').click(function() {
|
||||
$('#categories .add-edit-delete-group').hide();
|
||||
$('#categories .save-cancel-group').show();
|
||||
$('.filter-categories').prop('disabled', true);
|
||||
$('#categories .filter-results').css('color', '#AAA');
|
||||
$('#categories .details').find('input, textarea').prop('readonly', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Service Button "Click"
|
||||
*/
|
||||
$('#delete-service').click(function() {
|
||||
var serviceId = $('#service-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendServices.helper.delete(serviceId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Service', 'Are you sure that you want '
|
||||
+ 'to delete this record? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
|
||||
$('#delete-category').click(function() {
|
||||
var categoryId = $('#category-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendServices.helper.delete(categoryId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Category', 'Are you sure that you want '
|
||||
+ 'to delete this record? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the service category listbox. Use this method every time a change is made
|
||||
* to the service categories db table.
|
||||
*
|
||||
* @param {array} categories Contains the available category objects.
|
||||
*/
|
||||
updateAvailableCategories: function() {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_service_categories';
|
||||
|
@ -322,6 +109,142 @@ var ServicesHelper = function() {
|
|||
this.filterResults = {};
|
||||
};
|
||||
|
||||
ServicesHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Services Form "Submit"
|
||||
*/
|
||||
$('#filter-services form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-services .key').val();
|
||||
$('#filter-services .selected-row').removeClass('selected-row');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Service Cancel Button "Click"
|
||||
*/
|
||||
$('#filter-services .clear').click(function() {
|
||||
$('#filter-services .key').val('');
|
||||
BackendServices.helper.filter('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Service Row "Click"
|
||||
*
|
||||
* Display the selected service data to the user.
|
||||
*/
|
||||
$(document).on('click', '.service-row', function() {
|
||||
if ($('#filter-services .filter').prop('disabled')) {
|
||||
$('#filter-services .results').css('color', '#AAA');
|
||||
return; // exit because we are on edit mode
|
||||
}
|
||||
|
||||
var serviceId = $(this).attr('data-id');
|
||||
var service = {};
|
||||
$.each(BackendServices.helper.filterResults, function(index, item) {
|
||||
if (item.id === serviceId) {
|
||||
service = item;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
BackendServices.helper.display(service);
|
||||
$('#filter-services .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-service, #delete-service').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add New Service Button "Click"
|
||||
*/
|
||||
$('#add-service').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
$('#services .add-edit-delete-group').hide();
|
||||
$('#services .save-cancel-group').show();
|
||||
$('#services .details').find('input, textarea').prop('readonly', false);
|
||||
$('#services .details').find('select').prop('disabled', false);
|
||||
$('#service-duration').spinner('enable');
|
||||
|
||||
$('#filter-services button').prop('disabled', true);
|
||||
$('#filter-services .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Service Button "Click"
|
||||
*
|
||||
* Cancel add or edit of a service record.
|
||||
*/
|
||||
$('#cancel-service').click(function() {
|
||||
var id = $('#service-id').val();
|
||||
BackendServices.helper.resetForm();
|
||||
if (id != '') {
|
||||
BackendServices.helper.select(id, true);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Service Button "Click"
|
||||
*/
|
||||
$('#save-service').click(function() {
|
||||
var service = {
|
||||
'name': $('#service-name').val(),
|
||||
'duration': $('#service-duration').val(),
|
||||
'price': $('#service-price').val(),
|
||||
'currency': $('#service-currency').val(),
|
||||
'description': $('#service-description').val()
|
||||
};
|
||||
|
||||
if ($('#service-category').val() !== 'null') {
|
||||
service.id_service_categories = $('#service-category').val();
|
||||
} else {
|
||||
service.id_service_categories = null;
|
||||
}
|
||||
|
||||
if ($('#service-id').val() !== '') {
|
||||
service.id = $('#service-id').val();
|
||||
}
|
||||
|
||||
if (!BackendServices.helper.validate(service)) return;
|
||||
|
||||
BackendServices.helper.save(service);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Service Button "Click"
|
||||
*/
|
||||
$('#edit-service').click(function() {
|
||||
$('#services .add-edit-delete-group').hide();
|
||||
$('#services .save-cancel-group').show();
|
||||
$('#services .details').find('input, textarea').prop('readonly', false);
|
||||
$('#services .details select').prop('disabled', false);
|
||||
$('#service-duration').spinner('enable');
|
||||
|
||||
$('#filter-services button').prop('disabled', true);
|
||||
$('#filter-services .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Service Button "Click"
|
||||
*/
|
||||
$('#delete-service').click(function() {
|
||||
var serviceId = $('#service-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendServices.helper.delete(serviceId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Service', 'Are you sure that you want '
|
||||
+ 'to delete this record? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Save service record to database.
|
||||
*
|
||||
|
@ -329,23 +252,30 @@ var ServicesHelper = function() {
|
|||
* then the update operation is going to be executed.
|
||||
*/
|
||||
ServicesHelper.prototype.save = function(service) {
|
||||
////////////////////////////////////////////////
|
||||
//console.log('Service data to save:', service);
|
||||
////////////////////////////////////////////////
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_save_service';
|
||||
var postData = { 'service': JSON.stringify(service) };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
console.log('Save Service Response:', response);
|
||||
//////////////////////////////////////////////////
|
||||
//console.log('Save Service Response:', response);
|
||||
//////////////////////////////////////////////////
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
Backend.displayNotification('Service saved successfully!');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter($('#services .filter-key').val());
|
||||
$('#filter-services .key').val('');
|
||||
BackendServices.helper.filter('', response.id, true);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a service records from database.
|
||||
* Delete a service record from database.
|
||||
*
|
||||
* @param {int} id Record id to be deleted.
|
||||
* @param {numeric} id Record id to be deleted.
|
||||
*/
|
||||
ServicesHelper.prototype.delete = function(id) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_delete_service';
|
||||
|
@ -353,7 +283,7 @@ ServicesHelper.prototype.delete = function(id) {
|
|||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
////////////////////////////////////////////////////
|
||||
console.log('Delete service response:', response);
|
||||
//console.log('Delete service response:', response);
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
@ -361,7 +291,7 @@ ServicesHelper.prototype.delete = function(id) {
|
|||
Backend.displayNotification('Service deleted successfully!');
|
||||
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter($('#services .filter-key').val());
|
||||
BackendServices.helper.filter($('#filter-services .key').val());
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -404,8 +334,10 @@ ServicesHelper.prototype.resetForm = function() {
|
|||
$('#edit-service, #delete-service').prop('disabled', true);
|
||||
$('#services .details').find('input, textarea').prop('readonly', true);
|
||||
$('#service-category').prop('disabled', true);
|
||||
$('.filter-services').prop('disabled', false);
|
||||
$('#services .filter-results').css('color', '');
|
||||
|
||||
$('#filter-services .selected-row').removeClass('selected-row');
|
||||
$('#filter-services button').prop('disabled', false);
|
||||
$('#filter-services .results').css('color', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -429,25 +361,39 @@ ServicesHelper.prototype.display = function(service) {
|
|||
* Filters service records depending a string key.
|
||||
*
|
||||
* @param {string} key This is used to filter the service records of the database.
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter
|
||||
* operation the record with this id will be selected (but not displayed).
|
||||
* @param {bool} display (OPTIONAL = false) If true then the selected record will
|
||||
* be displayed on the form.
|
||||
*/
|
||||
ServicesHelper.prototype.filter = function(key) {
|
||||
ServicesHelper.prototype.filter = function(key, selectId, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_services';
|
||||
var postData = { 'key': key };
|
||||
|
||||
$.post(postUrl, postData, function(response) {
|
||||
/////////////////////////////////////////////////////
|
||||
console.log('Filter services response:', response);
|
||||
//console.log('Filter services response:', response);
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
BackendServices.helper.filterResults = response;
|
||||
$('#services .filter-results').html('');
|
||||
|
||||
$('#filter-services .results').html('');
|
||||
$.each(response, function(index, service) {
|
||||
var html = ServicesHelper.prototype.getFilterHtml(service);
|
||||
$('#services .filter-results').append(html);
|
||||
$('#filter-services .results').append(html);
|
||||
});
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-services .result').html('<em>No results found ...</em>');
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendServices.helper.select(selectId, display);
|
||||
}
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
|
@ -468,6 +414,40 @@ ServicesHelper.prototype.getFilterHtml = function(service) {
|
|||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a specific record from the current filter results. If the service id does not exist
|
||||
* in the list then no record will be selected.
|
||||
*
|
||||
* @param {numeric} id The record id to be selected from the filter results.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the method will display the record
|
||||
* on the form.
|
||||
*
|
||||
* @task The selected row must always be visible (even if a vertical scroll bar is used to
|
||||
* navigate through the filter results).
|
||||
*/
|
||||
ServicesHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
$('#filter-services .selected-row').removeClass('selected-row');
|
||||
|
||||
$('#filter-services .service-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (display) {
|
||||
$.each(BackendServices.helper.filterResults, function(index, service) {
|
||||
if (service.id == id) {
|
||||
BackendServices.helper.display(service);
|
||||
$('#edit-service, #delete-service').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This class contains the core method implementations that belong to the categories tab
|
||||
* of the backend services page.
|
||||
|
@ -478,12 +458,139 @@ var CategoriesHelper = function() {
|
|||
this.filterResults = {};
|
||||
};
|
||||
|
||||
/**
|
||||
* Binds the default event handlers of the categories tab.
|
||||
*/
|
||||
CategoriesHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Categories Cancel Button "Click"
|
||||
*/
|
||||
$('#filter-categories .clear').click(function() {
|
||||
$('#filter-categories .key').val('');
|
||||
BackendServices.helper.filter('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Categories Form "Submit"
|
||||
*/
|
||||
$('#filter-categories form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-categories .key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Categories Row "Click"
|
||||
*
|
||||
* Displays the selected row data on the right side of the page.
|
||||
*/
|
||||
$(document).on('click', '.category-row', function() {
|
||||
if ($('#filter-categories .filter').prop('disabled')) {
|
||||
$('#filter-categories .results').css('color', '#AAA');
|
||||
return; // exit because we are on edit mode
|
||||
}
|
||||
|
||||
var categoryId = $(this).attr('data-id');
|
||||
var category = {};
|
||||
$.each(BackendServices.helper.filterResults, function(index, item) {
|
||||
if (item.id === categoryId) {
|
||||
category = item;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
BackendServices.helper.display(category);
|
||||
$('#filter-categories .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-category, #delete-category').prop('disabled', false);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Category Button "Click"
|
||||
*/
|
||||
$('#add-category').click(function() {
|
||||
BackendServices.helper.resetForm();
|
||||
$('#categories .add-edit-delete-group').hide();
|
||||
$('#categories .save-cancel-group').show();
|
||||
$('#categories .details').find('input, textarea').prop('readonly', false);
|
||||
$('#filter-categories button').prop('disabled', true);
|
||||
$('#filter-categories .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Category Button "Click"
|
||||
*/
|
||||
$('#edit-category').click(function() {
|
||||
$('#categories .add-edit-delete-group').hide();
|
||||
$('#categories .save-cancel-group').show();
|
||||
$('#categories .details').find('input, textarea').prop('readonly', false);
|
||||
|
||||
$('#filter-categories button').prop('disabled', true);
|
||||
$('#filter-categories .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Category Button "Click"
|
||||
*/
|
||||
$('#delete-category').click(function() {
|
||||
var categoryId = $('#category-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendServices.helper.delete(categoryId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
'Cancel': function() {
|
||||
$('#message_box').dialog('close');
|
||||
}
|
||||
};
|
||||
|
||||
GeneralFunctions.displayMessageBox('Delete Category', 'Are you sure that you want '
|
||||
+ 'to delete this record? This action cannot be undone.', messageBtns);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Categories Save Button "Click"
|
||||
*/
|
||||
$('#save-category').click(function() {
|
||||
var category = {
|
||||
'name': $('#category-name').val(),
|
||||
'description': $('#category-description').val()
|
||||
};
|
||||
|
||||
if ($('#category-id').val() !== '') {
|
||||
category.id = $('#category-id').val();
|
||||
}
|
||||
|
||||
if (!BackendServices.helper.validate(category)) return;
|
||||
|
||||
BackendServices.helper.save(category);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Category Button "Click"
|
||||
*/
|
||||
$('#cancel-category').click(function() {
|
||||
var id = $('#category-id').val();
|
||||
BackendServices.helper.resetForm();
|
||||
if (id != '') {
|
||||
BackendServices.helper.select(id, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Filter service categories records.
|
||||
*
|
||||
* @param {string} key This key string is used to filter the category records.
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) If set then after the filter
|
||||
* operation the record with the given id will be selected (but not displayed).
|
||||
* @param {bool} display (OPTIONAL = false) If true then the selected record will
|
||||
* be displayed on the form.
|
||||
*/
|
||||
CategoriesHelper.prototype.filter = function(key) {
|
||||
CategoriesHelper.prototype.filter = function(key, selectId, display) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_service_categories';
|
||||
var postData = { 'key': key };
|
||||
|
||||
|
@ -495,12 +602,21 @@ CategoriesHelper.prototype.filter = function(key) {
|
|||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
|
||||
BackendServices.helper.filterResults = response;
|
||||
$('#categories .filter-results').html('');
|
||||
|
||||
$('#filter-categories .results').html('');
|
||||
$.each(response, function(index, category) {
|
||||
var html = BackendServices.helper.getFilterHtml(category);
|
||||
$('#categories .filter-results').append(html);
|
||||
$('#filter-categories .results').append(html);
|
||||
});
|
||||
|
||||
if (response.length == 0) {
|
||||
$('#filter-categories .results').html('<em>No records found...</em>');
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendServices.helper.select(selectId, display);
|
||||
}
|
||||
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
|
@ -522,7 +638,8 @@ CategoriesHelper.prototype.save = function(category) {
|
|||
|
||||
Backend.displayNotification('Service saved successfully!');
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter($('#categories .filter-key').val());
|
||||
$('#filter-categories .key').val('');
|
||||
BackendServices.helper.filter('', response.id, true);
|
||||
BackendServices.updateAvailableCategories();
|
||||
});
|
||||
};
|
||||
|
@ -546,7 +663,7 @@ CategoriesHelper.prototype.delete = function(id) {
|
|||
Backend.displayNotification('Category deleted successfully!');
|
||||
|
||||
BackendServices.helper.resetForm();
|
||||
BackendServices.helper.filter($('#categories .filter-key').val());
|
||||
BackendServices.helper.filter($('#filter-categories .key').val());
|
||||
BackendServices.updateAvailableCategories();
|
||||
});
|
||||
};
|
||||
|
@ -597,8 +714,10 @@ CategoriesHelper.prototype.resetForm = function() {
|
|||
$('#categories .details').find('input, textarea').val('');
|
||||
$('#categories .details').find('input, textarea').prop('readonly', true);
|
||||
$('#edit-category, #delete-category').prop('disabled', true);
|
||||
$('#categories .filter-results').css('color', '');
|
||||
$('#categories .filter-categories').prop('disabled', false);
|
||||
|
||||
$('#filter-categories .selected-row').removeClass('selected-row');
|
||||
$('#filter-categories .results').css('color', '');
|
||||
$('#filter-categories button').prop('disabled', false);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -616,3 +735,36 @@ CategoriesHelper.prototype.getFilterHtml = function(category) {
|
|||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a specific record from the current filter results. If the category id does not exist
|
||||
* in the list then no record will be selected.
|
||||
*
|
||||
* @param {numeric} id The record id to be selected from the filter results.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the method will display the record
|
||||
* on the form.
|
||||
*
|
||||
* @task The selected row must always be visible (even if a vertical scroll bar is used to
|
||||
* navigate through the filter results).
|
||||
*/
|
||||
CategoriesHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
$('#filter-categories .selected-row').removeClass('selected-row');
|
||||
|
||||
$('#filter-categories .category-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (display) {
|
||||
$.each(BackendServices.helper.filterResults, function(index, category) {
|
||||
if (category.id == id) {
|
||||
BackendServices.helper.display(category);
|
||||
$('#edit-category, #delete-category').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -10,20 +10,10 @@ var BackendSettings = {
|
|||
SETTINGS_USER: 'SETTINGS_USER',
|
||||
|
||||
/**
|
||||
* This flag is used when trying to cancel row editing. It is
|
||||
* true only whenever the user presses the cancel button.
|
||||
*
|
||||
* @type {bool}
|
||||
* Use this WorkingPlan class instance to perform actions on the page's working plan
|
||||
* tables.
|
||||
*/
|
||||
enableCancel: false,
|
||||
|
||||
/**
|
||||
* This flag determines whether the jeditables are allowed to submit. It is
|
||||
* true only whenever the user presses the save button.
|
||||
*
|
||||
* @type {bool}
|
||||
*/
|
||||
enableSubmit: false,
|
||||
wp: {},
|
||||
|
||||
/**
|
||||
* Tab settings object.
|
||||
|
@ -55,60 +45,9 @@ var BackendSettings = {
|
|||
}
|
||||
});
|
||||
|
||||
$.each(workingPlan, function(index, workingDay) {
|
||||
if (workingDay != null) {
|
||||
$('#' + index).prop('checked', true);
|
||||
$('#' + index + '-start').val(workingDay.start);
|
||||
$('#' + index + '-end').val(workingDay.end);
|
||||
|
||||
// Add the day's breaks on the breaks table.
|
||||
$.each(workingDay.breaks, function(i, brk) {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
|
||||
'<td class="break-start editable">' + brk.start + '</td>' +
|
||||
'<td class="break-end editable">' + brk.end + '</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('#breaks').append(tr);
|
||||
});
|
||||
} else {
|
||||
$('#' + index).prop('checked', false);
|
||||
$('#' + index + '-start').prop('disabled', true);
|
||||
$('#' + index + '-end').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
// Make break cells editable.
|
||||
BackendSettings.editableBreakDay($('#breaks .break-day'));
|
||||
BackendSettings.editableBreakTime($('#breaks').find('.break-start, .break-end'));
|
||||
|
||||
// Set timepickers where needed.
|
||||
$('.working-plan input').timepicker({
|
||||
'timeFormat': 'HH:mm',
|
||||
'onSelect': function(datetime, inst) {
|
||||
// Start time must be earlier than end time.
|
||||
var start = Date.parse($(this).parent().parent().find('.work-start').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.work-end').val());
|
||||
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
}
|
||||
});
|
||||
BackendSettings.wp = new WorkingPlan();
|
||||
BackendSettings.wp.setup(workingPlan);
|
||||
BackendSettings.wp.timepickers(false);
|
||||
|
||||
// Book Advance Timeout Spinner
|
||||
$('#book-advance-timeout').spinner({
|
||||
|
@ -150,6 +89,8 @@ var BackendSettings = {
|
|||
* backend/settings html, so do not use this method on a different page.
|
||||
*/
|
||||
bindEventHandlers: function() {
|
||||
BackendSettings.wp.bindEventHandlers();
|
||||
|
||||
/**
|
||||
* Event: Tab "Click"
|
||||
*
|
||||
|
@ -196,177 +137,6 @@ var BackendSettings = {
|
|||
console.log('Settings To Save: ', settings);
|
||||
//////////////////////////////////////////////
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Day Checkbox "Click"
|
||||
*
|
||||
* Enable or disable the time selection for each day.
|
||||
*/
|
||||
$('.working-plan input[type="checkbox"]').click(function() {
|
||||
var id = $(this).attr('id');
|
||||
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#' + id + '-start').prop('disabled', false).val('09:00');
|
||||
$('#' + id + '-end').prop('disabled', false).val('18:00');
|
||||
} else {
|
||||
$('#' + id + '-start').prop('disabled', true).val('');
|
||||
$('#' + id + '-end').prop('disabled', true).val('');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Break Button "Click"
|
||||
*
|
||||
* A new row is added on the table and the user can enter the new break
|
||||
* data. After that he can either press the save or cancel button.
|
||||
*/
|
||||
$('.add-break').click(function() {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">Monday</td>' +
|
||||
'<td class="break-start editable">09:00</td>' +
|
||||
'<td class="break-end editable">10:00</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('#breaks').prepend(tr);
|
||||
|
||||
// Bind editable and event handlers.
|
||||
tr = $('#breaks tr').get()[1];
|
||||
BackendSettings.editableBreakDay($(tr).find('.break-day'));
|
||||
BackendSettings.editableBreakTime($(tr).find('.break-start, .break-end'));
|
||||
$(tr).find('.edit-break').trigger('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Break Button "Click"
|
||||
*
|
||||
* Enables the row editing for the "Breaks" table rows.
|
||||
*/
|
||||
$(document).on('click', '.edit-break', function() {
|
||||
// Reset previous editable tds
|
||||
var $previousEdt = $(this).closest('table').find('.editable').get();
|
||||
$.each($previousEdt, function(index, edt) {
|
||||
edt.reset();
|
||||
});
|
||||
|
||||
// Make all cells in current row editable.
|
||||
$(this).parent().parent().children().trigger('edit');
|
||||
$(this).parent().parent().find('.break-start input, .break-end input').timepicker();
|
||||
$(this).parent().parent().find('.break-day select').focus();
|
||||
|
||||
// Show save - cancel buttons.
|
||||
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Break Button "Click"
|
||||
*
|
||||
* Removes the current line from the "Breaks" table.
|
||||
*/
|
||||
$(document).on('click', '.delete-break', function() {
|
||||
$(this).parent().parent().remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Break Button "Click"
|
||||
*
|
||||
* Bring the "#breaks" table back to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.cancel-break', function() {
|
||||
BackendSettings.enableCancel = true;
|
||||
$(this).parent().parent().find('.cancel-editable').trigger('click');
|
||||
BackendSettings.enableCancel = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Break Button "Click"
|
||||
*
|
||||
* Save the editable values and restore the table to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.save-break', function() {
|
||||
// Break's start time must always be prior to break's end.
|
||||
var start = Date.parse($(this).parent().parent().find('.break-start input').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.break-end input').val());
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
|
||||
BackendSettings.enableSubmit = true;
|
||||
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
|
||||
BackendSettings.enableSubmit = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the editable functionality to the break day table cells.
|
||||
*
|
||||
* @param {object} $selector The cells to be initialized.
|
||||
*/
|
||||
editableBreakDay: function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
return value;
|
||||
}, {
|
||||
'type': 'select',
|
||||
'data': '{ "Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", '
|
||||
+ '"Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", '
|
||||
+ '"Sunday": "Sunday", "selected": "Monday"}',
|
||||
'event': 'edit',
|
||||
'height': '30px',
|
||||
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
|
||||
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
|
||||
'onblur': 'ignore',
|
||||
'onreset': function(settings, td) {
|
||||
if (!BackendSettings.enableCancel) return false; // disable ESC button
|
||||
},
|
||||
'onsubmit': function(settings, td) {
|
||||
if (!BackendSettings.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the editable functionality to the break time table cells.
|
||||
*
|
||||
* @param {object} $selector The cells to be initialized.
|
||||
*/
|
||||
editableBreakTime: function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
// Do not return the value because the user needs to press the "Save" button.
|
||||
return value;
|
||||
}, {
|
||||
'event': 'edit',
|
||||
'height': '25px',
|
||||
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
|
||||
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
|
||||
'onblur': 'ignore',
|
||||
'onreset': function(settings, td) {
|
||||
if (!BackendSettings.enableCancel) return false; // disable ESC button
|
||||
},
|
||||
'onsubmit': function(settings, td) {
|
||||
if (!BackendSettings.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -418,37 +188,9 @@ SystemSettings.prototype.get = function() {
|
|||
});
|
||||
|
||||
// Business Logic Tab
|
||||
var workingPlan = {};
|
||||
$('.working-plan input[type="checkbox"').each(function() {
|
||||
var id = $(this).attr('id');
|
||||
if ($(this).prop('checked') == true) {
|
||||
workingPlan[id] = {}
|
||||
workingPlan[id].start = $('#' + id + '-start').val();
|
||||
workingPlan[id].end = $('#' + id + '-end').val();
|
||||
workingPlan[id].breaks = [];
|
||||
|
||||
$('#breaks tr').each(function(index, tr) {
|
||||
var day = $(tr).find('.break-day').text().toLowerCase();
|
||||
if (day == id) {
|
||||
var start = $(tr).find('.break-start').text();
|
||||
var end = $(tr).find('.break-end').text();
|
||||
|
||||
workingPlan[id].breaks.push({
|
||||
'start': start,
|
||||
'end': end
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
workingPlan[id] = null;
|
||||
}
|
||||
});
|
||||
|
||||
settings.push({
|
||||
'name': 'company_working_plan',
|
||||
'value': JSON.stringify(workingPlan)
|
||||
'value': JSON.stringify(BackendSettings.wp.get())
|
||||
});
|
||||
|
||||
settings.push({
|
||||
|
|
|
@ -13,22 +13,13 @@ var BackendUsers = {
|
|||
* @type AdminsHelper|ProvidersHelper|SecretariesHelper
|
||||
*/
|
||||
helper: {},
|
||||
|
||||
/**
|
||||
* This flag is used when trying to cancel row editing. It is
|
||||
* true only whenever the user presses the cancel button.
|
||||
*
|
||||
* @type {bool}
|
||||
*/
|
||||
enableCancel: false,
|
||||
|
||||
/**
|
||||
* This flag determines whether the jeditables are allowed to submit. It is
|
||||
* true only whenever the user presses the save button.
|
||||
* Use this class instance for performing actions on the working plan.
|
||||
*
|
||||
* @type {bool}
|
||||
* @type {object}
|
||||
*/
|
||||
enableSubmit: false,
|
||||
wp: {},
|
||||
|
||||
/**
|
||||
* Initialize the backend users page.
|
||||
|
@ -44,6 +35,9 @@ var BackendUsers = {
|
|||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter('');
|
||||
|
||||
BackendUsers.wp = new WorkingPlan();
|
||||
BackendUsers.wp.bindEventHandlers();
|
||||
|
||||
// Fill the services and providers list boxes.
|
||||
$.each(GlobalVariables.services, function(index, service) {
|
||||
var html = '<label class="checkbox"><input type="checkbox" data-id="' + service.id + '" />'
|
||||
|
@ -150,7 +144,7 @@ var BackendUsers = {
|
|||
}, 'json');
|
||||
});
|
||||
|
||||
// -----------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
AdminsHelper.prototype.bindEventHandlers();
|
||||
|
||||
|
@ -161,5 +155,7 @@ var BackendUsers = {
|
|||
// ------------------------------------------------------------------------
|
||||
|
||||
SecretariesHelper.prototype.bindEventHandlers();
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
}
|
||||
};
|
|
@ -14,16 +14,25 @@ var AdminsHelper = function() {
|
|||
*/
|
||||
AdminsHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Admins Button "Click"
|
||||
* Event: Filter Admins Form "Sumbit"
|
||||
*
|
||||
* Filter the admin records with the given key string.
|
||||
*/
|
||||
$('.filter-admins').click(function() {
|
||||
var key = $('#admins .filter-key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-admins form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-admins .key').val();
|
||||
$('#filter-admins .selected-row').removeClass('selected-row');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Clear Filter Results Button "Click"
|
||||
*/
|
||||
$('#filter-admins .clear').click(function() {
|
||||
BackendUsers.helper.filter('');
|
||||
$('#filter-admins .key').val('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Admin Row "Click"
|
||||
|
@ -31,20 +40,22 @@ AdminsHelper.prototype.bindEventHandlers = function() {
|
|||
* Display the selected admin data to the user.
|
||||
*/
|
||||
$(document).on('click', '.admin-row', function() {
|
||||
if ($('#admins .filter-admins').prop('disabled')) {
|
||||
$('#admins .filter-results').css('color', '#AAA');
|
||||
if ($('#filter-admins .filter').prop('disabled')) {
|
||||
$('#filter-admins .results').css('color', '#AAA');
|
||||
return; // exit because we are currently on edit mode
|
||||
}
|
||||
|
||||
var admin = { 'id': $(this).attr('data-id') };
|
||||
var adminId = $(this).attr('data-id');
|
||||
var admin = {};
|
||||
$.each(BackendUsers.helper.filterResults, function(index, item) {
|
||||
if (item.id === admin.id) {
|
||||
if (item.id === adminId) {
|
||||
admin = item;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
BackendUsers.helper.display(admin);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-admins .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-admin, #delete-admin').prop('disabled', false);
|
||||
});
|
||||
|
@ -57,10 +68,10 @@ AdminsHelper.prototype.bindEventHandlers = function() {
|
|||
$('#admins .add-edit-delete-group').hide();
|
||||
$('#admins .save-cancel-group').show();
|
||||
$('#admins .details').find('input, textarea').prop('readonly', false);
|
||||
$('#admins .filter-admins').prop('disabled', true);
|
||||
$('#admins .filter-results').css('color', '#AAA');
|
||||
$('#admin-password, #admin-password-confirm').addClass('required');
|
||||
$('#admin-notifications').prop('disabled', false);
|
||||
$('#filter-admins button').prop('disabled', true);
|
||||
$('#filter-admins .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -69,11 +80,12 @@ AdminsHelper.prototype.bindEventHandlers = function() {
|
|||
$('#edit-admin').click(function() {
|
||||
$('#admins .add-edit-delete-group').hide();
|
||||
$('#admins .save-cancel-group').show();
|
||||
$('.filter-admins').prop('disabled', true);
|
||||
$('#admins .filter-results').css('color', '#AAA');
|
||||
$('#admins .details').find('input, textarea').prop('readonly', false);
|
||||
$('#admin-password, #admin-password-confirm').removeClass('required');
|
||||
$('#admin-notifications').prop('disabled', false);
|
||||
|
||||
$('#filter-admins .filter').prop('disabled', true);
|
||||
$('#filter-admins .results').css('color', '#AAA');
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -138,10 +150,11 @@ AdminsHelper.prototype.bindEventHandlers = function() {
|
|||
* Cancel add or edit of an admin record.
|
||||
*/
|
||||
$('#cancel-admin').click(function() {
|
||||
var id = $('#admin-id').val();
|
||||
BackendUsers.helper.resetForm();
|
||||
if ($('admins .selected-row').length == 0) return;
|
||||
var id = $('#admins .selected-row').attr('data-id');
|
||||
BackendUsers.helper.selectRecord(id);
|
||||
if (id != '') {
|
||||
BackendUsers.helper.select(id, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -165,11 +178,9 @@ AdminsHelper.prototype.save = function(admin) {
|
|||
////////////////////////////////////////////////
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Admin saved successfully!');
|
||||
BackendUsers.helper.resetForm(true);
|
||||
// When adding a new record the "admin.id" will be undefined. In this situation
|
||||
// no record will be selected because we do not yet know the id of the new record,
|
||||
// but no error will occur either.
|
||||
BackendUsers.helper.filter($('#admins .filter-key').val(), admin.id);
|
||||
BackendUsers.helper.resetForm();
|
||||
$('#filter-admins .key').val('');
|
||||
BackendUsers.helper.filter('', response.id, true);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
|
@ -189,7 +200,7 @@ AdminsHelper.prototype.delete = function(id) {
|
|||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Admin deleted successfully!');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter($('#admins .filter-key').val());
|
||||
BackendUsers.helper.filter($('#filter-admins .key').val());
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -244,29 +255,23 @@ AdminsHelper.prototype.validate = function(admin) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Resets the admin tab form back to its initial state.
|
||||
*
|
||||
* @param {bool} keepRecordData (OPTIONAL = false) If false then the current record data
|
||||
* will remain on the form.
|
||||
* Resets the admin form back to its initial state.
|
||||
*/
|
||||
AdminsHelper.prototype.resetForm = function(keepRecordData) {
|
||||
if (keepRecordData == undefined) keepRecordData = false;
|
||||
|
||||
AdminsHelper.prototype.resetForm = function() {
|
||||
$('#admins .add-edit-delete-group').show();
|
||||
$('#admins .save-cancel-group').hide();
|
||||
$('#admins .details').find('input, textarea').prop('readonly', true);
|
||||
$('.filter-admins').prop('disabled', false);
|
||||
$('#admins .filter-results').css('color', '');
|
||||
$('#admins .form-message').hide();
|
||||
$('#admin-notifications').prop('disabled', true);
|
||||
$('#admins .required').css('border', '');
|
||||
$('#admin-password, #admin-password-confirm').css('border', '');
|
||||
$('#admins .details').find('input, textarea').val('');
|
||||
$('#admin-notifications').removeClass('active');
|
||||
$('#edit-admin, #delete-admin').prop('disabled', true);
|
||||
|
||||
if (!keepRecordData) {
|
||||
$('#admins .details').find('input, textarea').val('');
|
||||
$('#admin-notifications').removeClass('active');
|
||||
$('#edit-admin, #delete-admin').prop('disabled', true);
|
||||
}
|
||||
$('#filter-admins .selected-row').removeClass('selected-row');
|
||||
$('#filter-admins button').prop('disabled', false);
|
||||
$('#filter-admins .results').css('color', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -296,11 +301,17 @@ AdminsHelper.prototype.display = function(admin) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Filters admin records depending a string key.
|
||||
* Filters admin records depending a key string.
|
||||
*
|
||||
* @param {string} key This is used to filter the admin records of the database.
|
||||
* @param {string} key This string is used to filter the admin records of the database.
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) This record id will be selected when
|
||||
* the filter operation is finished.
|
||||
* @param {bool} display (OPTIONAL = false) If true the selected record data are going
|
||||
* to be displayed on the details column (requires a selected record though).
|
||||
*/
|
||||
AdminsHelper.prototype.filter = function(key, selectRecordId) {
|
||||
AdminsHelper.prototype.filter = function(key, selectId, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_admins';
|
||||
var postData = { 'key': key };
|
||||
|
||||
|
@ -313,19 +324,18 @@ AdminsHelper.prototype.filter = function(key, selectRecordId) {
|
|||
|
||||
BackendUsers.helper.filterResults = response;
|
||||
|
||||
$('#admins .filter-results').html('');
|
||||
$('#filter-admins .results').html('');
|
||||
$.each(response, function(index, admin) {
|
||||
var html = AdminsHelper.prototype.getFilterHtml(admin);
|
||||
$('#admins .filter-results').append(html);
|
||||
$('#filter-admins .results').append(html);
|
||||
});
|
||||
|
||||
if (selectRecordId != undefined) {
|
||||
$('.admin-row').each(function() {
|
||||
if ($(this).attr('data-id') == selectRecordId) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (response.length == 0) {
|
||||
$('#filter-admins .results').html('<em>No results found ...</em>')
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendUsers.helper.select(selectId, display);
|
||||
}
|
||||
}, 'json');
|
||||
};
|
||||
|
@ -347,33 +357,34 @@ AdminsHelper.prototype.getFilterHtml = function(admin) {
|
|||
};
|
||||
|
||||
/**
|
||||
* Select a specific record from the current filter results. If the admin does not exist in
|
||||
* the list then no record will be selected.
|
||||
* Select a specific record from the current filter results. If the admin id does not exist
|
||||
* in the list then no record will be selected.
|
||||
*
|
||||
* @param {numeric} id The record id to be selected.
|
||||
* @param {numeric} id The record id to be selected from the filter results.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the method will display the record
|
||||
* on the form.
|
||||
*
|
||||
* @task The selected row must always be visible (even if a vertical scroll bar is used to
|
||||
* navigate through the filter results).
|
||||
*/
|
||||
AdminsHelper.prototype.selectRecord = function(id, display) {
|
||||
AdminsHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
$('#admins .selected-row').removeClass('selected-row');
|
||||
$('#filter-admins .selected-row').removeClass('selected-row');
|
||||
|
||||
$('.admin-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (display) {
|
||||
var admin;
|
||||
$.each(BackendUsers.helper.filterResults, function(index, item) {
|
||||
if (item.id === id) {
|
||||
admin = item;
|
||||
$.each(BackendUsers.helper.filterResults, function(index, admin) {
|
||||
if (admin.id == id) {
|
||||
BackendUsers.helper.display(admin);
|
||||
$('#edit-admin, #delete-admin').prop('disabled', false);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -14,37 +14,48 @@ var ProvidersHelper = function() {
|
|||
*/
|
||||
ProvidersHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Providers Button "Click"
|
||||
* Event: Filter Providers Form "Submit"
|
||||
*
|
||||
* Filter the provider records with the given key string.
|
||||
*/
|
||||
$('.filter-providers').click(function() {
|
||||
var key = $('#providers .filter-key').val();
|
||||
$('#filter-providers form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-providers .key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Clear Filter Button "Click"
|
||||
*/
|
||||
$('#filter-providers .clear').click(function() {
|
||||
BackendUsers.helper.filter('');
|
||||
$('#filter-providers .key').val('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Provider Row "Click"
|
||||
*
|
||||
* Display the selected provider data to the user.
|
||||
*/
|
||||
$(document).on('click', '.provider-row', function() {
|
||||
if ($('#providers .filter-providers').prop('disabled')) {
|
||||
$('#providers .filter-results').css('color', '#AAA');
|
||||
return; // exit because we are currently on edit mode
|
||||
if ($('#filter-providers .filter').prop('disabled')) {
|
||||
$('#filter-providers .results').css('color', '#AAA');
|
||||
return; // Exit because we are currently on edit mode.
|
||||
}
|
||||
|
||||
var provider = { 'id': $(this).attr('data-id') };
|
||||
|
||||
var providerId = $(this).attr('data-id');
|
||||
var provider = {};
|
||||
$.each(BackendUsers.helper.filterResults, function(index, item) {
|
||||
if (item.id === provider.id) {
|
||||
if (item.id === providerId) {
|
||||
provider = item;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
BackendUsers.helper.display(provider);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-providers .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-provider, #delete-provider').prop('disabled', false);
|
||||
});
|
||||
|
@ -54,194 +65,19 @@ ProvidersHelper.prototype.bindEventHandlers = function() {
|
|||
*/
|
||||
$('#add-provider').click(function() {
|
||||
BackendUsers.helper.resetForm();
|
||||
$('#filter-providers button').prop('disabled', true);
|
||||
$('#filter-providers .results').css('color', '#AAA');
|
||||
$('#providers .add-edit-delete-group').hide();
|
||||
$('#providers .save-cancel-group').show();
|
||||
$('#providers .details').find('input, textarea').prop('readonly', false);
|
||||
$('#providers .filter-providers').prop('disabled', true);
|
||||
$('#providers .filter-results').css('color', '#AAA');
|
||||
$('#provider-password, #provider-password-confirm').addClass('required');
|
||||
$('#provider-notifications').prop('disabled', false);
|
||||
$('#provider-services input[type="checkbox"]').prop('disabled', false);
|
||||
|
||||
$('#providers .add-break').prop('disabled', false);
|
||||
$('.edit-break, .delete-break').prop('disabled', false);
|
||||
$('#providers input[type="checkbox"]').prop('disabled', false);
|
||||
|
||||
// Apply default working plan
|
||||
$.each(GlobalVariables.workingPlan, function(index, workingDay) {
|
||||
if (workingDay != null) {
|
||||
$('#' + index).prop('checked', true);
|
||||
$('#' + index + '-start').val(workingDay.start);
|
||||
$('#' + index + '-end').val(workingDay.end);
|
||||
|
||||
// Add the day's breaks on the breaks table.
|
||||
$.each(workingDay.breaks, function(i, brk) {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
|
||||
'<td class="break-start editable">' + brk.start + '</td>' +
|
||||
'<td class="break-end editable">' + brk.end + '</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('#breaks').append(tr);
|
||||
});
|
||||
} else {
|
||||
$('#' + index).prop('checked', false);
|
||||
$('#' + index + '-start').prop('disabled', true);
|
||||
$('#' + index + '-end').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
// Make break cells editable.
|
||||
BackendUsers.helper.editableBreakDay($('#breaks .break-day'));
|
||||
BackendUsers.helper.editableBreakTime($('#breaks').find('.break-start, .break-end'));
|
||||
|
||||
// Set timepickers where needed.
|
||||
$('.working-plan input').timepicker({
|
||||
'timeFormat': 'HH:mm',
|
||||
'onSelect': function(datetime, inst) {
|
||||
// Start time must be earlier than end time.
|
||||
var start = Date.parse($(this).parent().parent().find('.work-start').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.work-end').val());
|
||||
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Day Checkbox "Click"
|
||||
*
|
||||
* Enable or disable the time selection for each day.
|
||||
*/
|
||||
$('.working-plan input[type="checkbox"]').click(function() {
|
||||
var id = $(this).attr('id');
|
||||
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#' + id + '-start').prop('disabled', false).val('09:00');
|
||||
$('#' + id + '-end').prop('disabled', false).val('18:00');
|
||||
} else {
|
||||
$('#' + id + '-start').prop('disabled', true).val('');
|
||||
$('#' + id + '-end').prop('disabled', true).val('');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Break Button "Click"
|
||||
*
|
||||
* A new row is added on the table and the user can enter the new break
|
||||
* data. After that he can either press the save or cancel button.
|
||||
*/
|
||||
$('.add-break').click(function() {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">Monday</td>' +
|
||||
'<td class="break-start editable">09:00</td>' +
|
||||
'<td class="break-end editable">10:00</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('#breaks').prepend(tr);
|
||||
|
||||
// Bind editable and event handlers.
|
||||
tr = $('#breaks tr').get()[1];
|
||||
BackendUsers.helper.editableBreakDay($(tr).find('.break-day'));
|
||||
BackendUsers.helper.editableBreakTime($(tr).find('.break-start, .break-end'));
|
||||
$(tr).find('.edit-break').trigger('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Break Button "Click"
|
||||
*
|
||||
* Enables the row editing for the "Breaks" table rows.
|
||||
*/
|
||||
$(document).on('click', '.edit-break', function() {
|
||||
// Reset previous editable tds
|
||||
var $previousEdt = $(this).closest('table').find('.editable').get();
|
||||
$.each($previousEdt, function(index, edt) {
|
||||
edt.reset();
|
||||
});
|
||||
|
||||
// Make all cells in current row editable.
|
||||
$(this).parent().parent().children().trigger('edit');
|
||||
$(this).parent().parent().find('.break-start input, .break-end input').timepicker();
|
||||
$(this).parent().parent().find('.break-day select').focus();
|
||||
|
||||
// Show save - cancel buttons.
|
||||
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Break Button "Click"
|
||||
*
|
||||
* Removes the current line from the "Breaks" table.
|
||||
*/
|
||||
$(document).on('click', '.delete-break', function() {
|
||||
$(this).parent().parent().remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Break Button "Click"
|
||||
*
|
||||
* Bring the "#breaks" table back to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.cancel-break', function() {
|
||||
BackendUsers.enableCancel = true;
|
||||
$(this).parent().parent().find('.cancel-editable').trigger('click');
|
||||
BackendUsers.enableCancel = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Break Button "Click"
|
||||
*
|
||||
* Save the editable values and restore the table to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.save-break', function() {
|
||||
// Break's start time must always be prior to break's end.
|
||||
var start = Date.parse($(this).parent().parent().find('.break-start input').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.break-end input').val());
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
|
||||
BackendUsers.enableSubmit = true;
|
||||
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
|
||||
BackendUsers.enableSubmit = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
BackendUsers.wp.setup(GlobalVariables.workingPlan);
|
||||
BackendUsers.wp.timepickers(false);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -250,16 +86,15 @@ ProvidersHelper.prototype.bindEventHandlers = function() {
|
|||
$('#edit-provider').click(function() {
|
||||
$('#providers .add-edit-delete-group').hide();
|
||||
$('#providers .save-cancel-group').show();
|
||||
$('.filter-providers').prop('disabled', true);
|
||||
$('#providers .filter-results').css('color', '#AAA');
|
||||
$('#filter-providers button').prop('disabled', true);
|
||||
$('#filter-providers .results').css('color', '#AAA');
|
||||
$('#providers .details').find('input, textarea').prop('readonly', false);
|
||||
$('#provider-password, #provider-password-confirm').removeClass('required');
|
||||
$('#provider-notifications').prop('disabled', false);
|
||||
$('#provider-services input[type="checkbox"]').prop('disabled', false);
|
||||
|
||||
$('#providers .add-break').prop('disabled', false);
|
||||
$('.edit-break, .delete-break').prop('disabled', false);
|
||||
$('#providers').find('.add-break, .edit-break, .delete-break').prop('disabled', false);
|
||||
$('#providers input[type="checkbox"]').prop('disabled', false);
|
||||
BackendUsers.wp.timepickers(false);
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -299,7 +134,7 @@ ProvidersHelper.prototype.bindEventHandlers = function() {
|
|||
'notes': $('#provider-notes').val(),
|
||||
'settings': {
|
||||
'username': $('#provider-username').val(),
|
||||
'working_plan': BackendUsers.helper.getWorkingPlan(),
|
||||
'working_plan': JSON.stringify(BackendUsers.wp.get()),
|
||||
'notifications': $('#provider-notifications').hasClass('active')
|
||||
}
|
||||
};
|
||||
|
@ -333,20 +168,11 @@ ProvidersHelper.prototype.bindEventHandlers = function() {
|
|||
* Cancel add or edit of an provider record.
|
||||
*/
|
||||
$('#cancel-provider').click(function() {
|
||||
var id = $('#filter-providers .selected-row').attr('data-id');
|
||||
BackendUsers.helper.resetForm();
|
||||
|
||||
var provider = { 'id': $('#providers .selected-row').attr('data-id') };
|
||||
|
||||
$.each(BackendUsers.helper.filterResults, function(index, item) {
|
||||
if (item.id === provider.id) {
|
||||
provider = item;
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
BackendUsers.helper.display(provider);
|
||||
|
||||
$('#edit-provider, #delete-provider').prop('disabled', false);
|
||||
if (id != '') {
|
||||
BackendUsers.helper.select(id, true);
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
|
@ -393,17 +219,16 @@ ProvidersHelper.prototype.save = function(provider) {
|
|||
///////////////////////////////////////////////////
|
||||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Provider saved successfully!');
|
||||
BackendUsers.helper.resetForm(true);
|
||||
// If "id" is not defined then no record will be selected (applies when adding
|
||||
// a new provider record).
|
||||
BackendUsers.helper.filter($('#providers .filter-key').val(), provider.id);
|
||||
BackendUsers.helper.resetForm();
|
||||
$('#filter-providers .key').val('');
|
||||
BackendUsers.helper.filter('', response.id, true);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete a provider record from database.
|
||||
*
|
||||
* @param {int} id Record id to be deleted.
|
||||
* @param {numeric} id Record id to be deleted.
|
||||
*/
|
||||
ProvidersHelper.prototype.delete = function(id) {
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_delete_provider';
|
||||
|
@ -416,7 +241,7 @@ ProvidersHelper.prototype.delete = function(id) {
|
|||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Provider deleted successfully!');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter($('#providers .filter-key').val());
|
||||
BackendUsers.helper.filter($('#filter-providers .key').val());
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -472,18 +297,15 @@ ProvidersHelper.prototype.validate = function(provider) {
|
|||
|
||||
/**
|
||||
* Resets the admin tab form back to its initial state.
|
||||
*
|
||||
* @param {bool} keepRecordData (OPTIONAL = false) If true then the current record data will
|
||||
* remain on the form.
|
||||
*/
|
||||
ProvidersHelper.prototype.resetForm = function(keepRecordData) {
|
||||
if (keepRecordData == undefined) keepRecordData = false;
|
||||
ProvidersHelper.prototype.resetForm = function() {
|
||||
$('#filter-providers .selected-row').removeClass('selected-row');
|
||||
$('#filter-providers button').prop('disabled', false);
|
||||
$('#filter-providers .results').css('color', '');
|
||||
|
||||
$('#providers .add-edit-delete-group').show();
|
||||
$('#providers .save-cancel-group').hide();
|
||||
$('#providers .details').find('input, textarea').prop('readonly', true);
|
||||
$('.filter-providers').prop('disabled', false);
|
||||
$('#providers .filter-results').css('color', '');
|
||||
$('#providers .form-message').hide();
|
||||
$('#provider-notifications').removeClass('active');
|
||||
$('#provider-notifications').prop('disabled', true);
|
||||
|
@ -491,17 +313,16 @@ ProvidersHelper.prototype.resetForm = function(keepRecordData) {
|
|||
$('#providers .required').css('border', '');
|
||||
$('#provider-password, #provider-password-confirm').css('border', '');
|
||||
$('#providers .add-break').prop('disabled', true);
|
||||
$('#providers input[type="checkbox"]').prop('disabled', true);
|
||||
BackendUsers.wp.timepickers(true);
|
||||
$('#providers .working-plan input[type="text"]').timepicker('destroy');
|
||||
$('#breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
||||
|
||||
if (!keepRecordData) {
|
||||
$('#edit-provider, #delete-provider').prop('disabled', true);
|
||||
$('#providers .details').find('input, textarea').val('');
|
||||
$('#providers input[type="checkbox"]').prop('checked', false);
|
||||
$('#provider-services input[type="checkbox"]').prop('checked', false);
|
||||
$('#providers #breaks tbody').empty();
|
||||
}
|
||||
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
||||
|
||||
$('#edit-provider, #delete-provider').prop('disabled', true);
|
||||
$('#providers .details').find('input, textarea').val('');
|
||||
$('#providers input[type="checkbox"]').prop('checked', false);
|
||||
$('#provider-services input[type="checkbox"]').prop('checked', false);
|
||||
$('#providers .breaks tbody').empty();
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -539,74 +360,24 @@ ProvidersHelper.prototype.display = function(provider) {
|
|||
});
|
||||
|
||||
// Display working plan
|
||||
$('#providers #breaks tbody').empty();
|
||||
$('#providers .breaks tbody').empty();
|
||||
var workingPlan = $.parseJSON(provider.settings.working_plan);
|
||||
$.each(workingPlan, function(index, workingDay) {
|
||||
if (workingDay != null) {
|
||||
$('#' + index).prop('checked', true);
|
||||
$('#' + index + '-start').val(workingDay.start);
|
||||
$('#' + index + '-end').val(workingDay.end);
|
||||
|
||||
// Add the day's breaks on the breaks table.
|
||||
$.each(workingDay.breaks, function(i, brk) {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
|
||||
'<td class="break-start editable">' + brk.start + '</td>' +
|
||||
'<td class="break-end editable">' + brk.end + '</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('#breaks').append(tr);
|
||||
});
|
||||
} else {
|
||||
$('#' + index).prop('checked', false);
|
||||
$('#' + index + '-start').prop('disabled', true);
|
||||
$('#' + index + '-end').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
$('.edit-break, .delete-break').prop('disabled', true);
|
||||
|
||||
// Make break cells editable.
|
||||
BackendUsers.helper.editableBreakDay($('#breaks .break-day'));
|
||||
BackendUsers.helper.editableBreakTime($('#breaks').find('.break-start, .break-end'));
|
||||
|
||||
// Set timepickers where needed.
|
||||
$('.working-plan input').timepicker({
|
||||
'timeFormat': 'HH:mm',
|
||||
'onSelect': function(datetime, inst) {
|
||||
// Start time must be earlier than end time.
|
||||
var start = Date.parse($(this).parent().parent().find('.work-start').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.work-end').val());
|
||||
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
}
|
||||
});
|
||||
BackendUsers.wp.setup(workingPlan);
|
||||
$('.breaks').find('.edit-break, .delete-break').prop('disabled', true);
|
||||
};
|
||||
|
||||
/**
|
||||
* Filters provider records depending a string key.
|
||||
*
|
||||
* @param {string} key This is used to filter the provider records of the database.
|
||||
* @param {numeric} selectRecordId (OPTIONAL) If set, when the function is complete
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) If set, when the function is complete
|
||||
* a result row can be set as selected.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the selected record will be also
|
||||
* displayed.
|
||||
*/
|
||||
ProvidersHelper.prototype.filter = function(key, selectRecordId) {
|
||||
ProvidersHelper.prototype.filter = function(key, selectId, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_providers';
|
||||
var postData = { 'key': key };
|
||||
|
||||
|
@ -619,19 +390,18 @@ ProvidersHelper.prototype.filter = function(key, selectRecordId) {
|
|||
|
||||
BackendUsers.helper.filterResults = response;
|
||||
|
||||
$('#providers .filter-results').html('');
|
||||
$('#filter-providers .results').html('');
|
||||
$.each(response, function(index, provider) {
|
||||
var html = ProvidersHelper.prototype.getFilterHtml(provider);
|
||||
$('#providers .filter-results').append(html);
|
||||
$('#filter-providers .results').append(html);
|
||||
});
|
||||
|
||||
if (selectRecordId != undefined) {
|
||||
$('.provider-row').each(function() {
|
||||
if ($(this).attr('data-id') == selectRecordId) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (response.length == 0) {
|
||||
$('#filter-providers .results').html('<em>No results found ...</em>')
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendUsers.helper.select(selectId, display);
|
||||
}
|
||||
}, 'json');
|
||||
};
|
||||
|
@ -652,44 +422,6 @@ ProvidersHelper.prototype.getFilterHtml = function(provider) {
|
|||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the current working plan.
|
||||
*
|
||||
* @return {string} Returns the working plan (already stringified).
|
||||
*/
|
||||
ProvidersHelper.prototype.getWorkingPlan = function() {
|
||||
var workingPlan = {};
|
||||
$('.working-plan input[type="checkbox"').each(function() {
|
||||
var id = $(this).attr('id');
|
||||
if ($(this).prop('checked') == true) {
|
||||
workingPlan[id] = {}
|
||||
workingPlan[id].start = $('#' + id + '-start').val();
|
||||
workingPlan[id].end = $('#' + id + '-end').val();
|
||||
workingPlan[id].breaks = [];
|
||||
|
||||
$('#breaks tr').each(function(index, tr) {
|
||||
var day = $(tr).find('.break-day').text().toLowerCase();
|
||||
if (day == id) {
|
||||
var start = $(tr).find('.break-start').text();
|
||||
var end = $(tr).find('.break-end').text();
|
||||
|
||||
workingPlan[id].breaks.push({
|
||||
'start': start,
|
||||
'end': end
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
workingPlan[id] = null;
|
||||
}
|
||||
});
|
||||
|
||||
return JSON.stringify(workingPlan);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the editable functionality to the break day table cells.
|
||||
*
|
||||
|
@ -715,7 +447,7 @@ ProvidersHelper.prototype.editableBreakDay = function($selector) {
|
|||
if (!BackendUsers.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the editable functionality to the break time table cells.
|
||||
|
@ -739,4 +471,33 @@ ProvidersHelper.prototype.editableBreakTime = function($selector) {
|
|||
if (!BackendUsers.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Select and display a providers filter result on the form.
|
||||
*
|
||||
* @param {numeric} id Record id to be selected.
|
||||
* @param {bool} display (OPTIONAL = false) If true the record will be displayed on the form.
|
||||
*/
|
||||
ProvidersHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
// Select record in filter results.
|
||||
$('#filter-providers .provider-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
// Display record in form (if display = true).
|
||||
if (display) {
|
||||
$.each(BackendUsers.helper.filterResults, function(index, provider) {
|
||||
if (provider.id == id) {
|
||||
BackendUsers.helper.display(provider);
|
||||
$('#edit-provider, #delete-provider').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -14,37 +14,48 @@ var SecretariesHelper = function() {
|
|||
*/
|
||||
SecretariesHelper.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Filter Secretaries Button "Click"
|
||||
* Event: Filter Secretaries Form "Submit"
|
||||
*
|
||||
* Filter the secretary records with the given key string.
|
||||
*/
|
||||
$('.filter-secretaries').click(function() {
|
||||
var key = $('#secretaries .filter-key').val();
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-secretaries form').submit(function() {
|
||||
event.preventDefault();
|
||||
var key = $('#filter-secretaries .key').val();
|
||||
$('#filter-secretaries .selected-row').removeClass('selected-row');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter(key);
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Clear Filter Results Button "Click"
|
||||
*/
|
||||
$('#filter-secretaries .clear').click(function() {
|
||||
BackendUsers.helper.filter('');
|
||||
$('#filter-secretaries .key').val('');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Filter Secretary Row "Click"
|
||||
*
|
||||
* Display the selected secretary data to the user.
|
||||
*/
|
||||
$(document).on('click', '.secretary-row', function() {
|
||||
if ($('#secretaries .filter-secretaries').prop('disabled')) {
|
||||
$('#secretaries .filter-results').css('color', '#AAA');
|
||||
if ($('#filter-secretaries .filter').prop('disabled')) {
|
||||
$('#filter-secretaries .results').css('color', '#AAA');
|
||||
return; // exit because we are currently on edit mode
|
||||
}
|
||||
|
||||
var secretary = { 'id': $(this).attr('data-id') };
|
||||
var secretaryId = $(this).attr('data-id');
|
||||
var secretary = {};
|
||||
$.each(BackendUsers.helper.filterResults, function(index, item) {
|
||||
if (item.id === secretary.id) {
|
||||
if (item.id === secretaryId) {
|
||||
secretary = item;
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
BackendUsers.helper.display(secretary);
|
||||
$('.selected-row').removeClass('selected-row');
|
||||
$('#filter-secretaries .selected-row').removeClass('selected-row');
|
||||
$(this).addClass('selected-row');
|
||||
$('#edit-secretary, #delete-secretary').prop('disabled', false);
|
||||
});
|
||||
|
@ -54,11 +65,12 @@ SecretariesHelper.prototype.bindEventHandlers = function() {
|
|||
*/
|
||||
$('#add-secretary').click(function() {
|
||||
BackendUsers.helper.resetForm();
|
||||
$('#filter-secretaries button').prop('disabled', true);
|
||||
$('#filter-secretaries .results').css('color', '#AAA');
|
||||
|
||||
$('#secretaries .add-edit-delete-group').hide();
|
||||
$('#secretaries .save-cancel-group').show();
|
||||
$('#secretaries .details').find('input, textarea').prop('readonly', false);
|
||||
$('#secretaries .filter-secretaries').prop('disabled', true);
|
||||
$('#secretaries .filter-results').css('color', '#AAA');
|
||||
$('#secretary-password, #secretary-password-confirm').addClass('required');
|
||||
$('#secretary-notifications').prop('disabled', false);
|
||||
$('#secretary-providers input[type="checkbox"]').prop('disabled', false);
|
||||
|
@ -68,10 +80,11 @@ SecretariesHelper.prototype.bindEventHandlers = function() {
|
|||
* Event: Edit Secretary Button "Click"
|
||||
*/
|
||||
$('#edit-secretary').click(function() {
|
||||
$('#filter-secretaries button').prop('disabled', true);
|
||||
$('#filter-secretaries .results').css('color', '#AAA');
|
||||
|
||||
$('#secretaries .add-edit-delete-group').hide();
|
||||
$('#secretaries .save-cancel-group').show();
|
||||
$('.filter-secretaries').prop('disabled', true);
|
||||
$('#secretaries .filter-results').css('color', '#AAA');
|
||||
$('#secretaries .details').find('input, textarea').prop('readonly', false);
|
||||
$('#secretary-password, #secretary-password-confirm').removeClass('required');
|
||||
$('#secretary-notifications').prop('disabled', false);
|
||||
|
@ -82,11 +95,11 @@ SecretariesHelper.prototype.bindEventHandlers = function() {
|
|||
* Event: Delete Secretary Button "Click"
|
||||
*/
|
||||
$('#delete-secretary').click(function() {
|
||||
var providerId = $('#secretary-id').val();
|
||||
var secretaryId = $('#secretary-id').val();
|
||||
|
||||
var messageBtns = {
|
||||
'Delete': function() {
|
||||
BackendUsers.helper.delete(providerId);
|
||||
BackendUsers.helper.delete(secretaryId);
|
||||
$('#message_box').dialog('close');
|
||||
},
|
||||
'Cancel': function() {
|
||||
|
@ -148,7 +161,11 @@ SecretariesHelper.prototype.bindEventHandlers = function() {
|
|||
* Cancel add or edit of an secretary record.
|
||||
*/
|
||||
$('#cancel-secretary').click(function() {
|
||||
var id = $('#secretary-id').val();
|
||||
BackendUsers.helper.resetForm();
|
||||
if (id != '') {
|
||||
BackendUsers.helper.select(id, true);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -173,7 +190,8 @@ SecretariesHelper.prototype.save = function(secretary) {
|
|||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Secretary saved successfully!');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter($('#secretaries .filter-key').val());
|
||||
$('#filter-secretaries .key').val('');
|
||||
BackendUsers.helper.filter('', response.id, true);
|
||||
}, 'json');
|
||||
};
|
||||
|
||||
|
@ -193,7 +211,7 @@ SecretariesHelper.prototype.delete = function(id) {
|
|||
if (!GeneralFunctions.handleAjaxExceptions(response)) return;
|
||||
Backend.displayNotification('Secretary deleted successfully!');
|
||||
BackendUsers.helper.resetForm();
|
||||
BackendUsers.helper.filter($('#secretaries .filter-key').val());
|
||||
BackendUsers.helper.filter($('#filter-secretaries .key').val());
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -256,8 +274,6 @@ SecretariesHelper.prototype.resetForm = function() {
|
|||
$('#secretaries .save-cancel-group').hide();
|
||||
$('#edit-secretary, #delete-secretary').prop('disabled', true);
|
||||
$('#secretaries .details').find('input, textarea').prop('readonly', true);
|
||||
$('.filter-secretaries').prop('disabled', false);
|
||||
$('#secretaries .filter-results').css('color', '');
|
||||
$('#secretaries .form-message').hide();
|
||||
$('#secretary-notifications').removeClass('active');
|
||||
$('#secretary-notifications').prop('disabled', true);
|
||||
|
@ -265,6 +281,10 @@ SecretariesHelper.prototype.resetForm = function() {
|
|||
$('#secretary-providers input[type="checkbox"]').prop('disabled', true);
|
||||
$('#secretaries .required').css('border', '');
|
||||
$('#secretary-password, #secretary-password-confirm').css('border', '');
|
||||
|
||||
$('#filter-secretaries .selected-row').removeClass('selected-row');
|
||||
$('#filter-secretaries button').prop('disabled', false);
|
||||
$('#filter-secretaries .results').css('color', '');
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -306,10 +326,13 @@ SecretariesHelper.prototype.display = function(secretary) {
|
|||
* Filters secretary records depending a string key.
|
||||
*
|
||||
* @param {string} key This is used to filter the secretary records of the database.
|
||||
* @param {numeric} selectRecordId (OPTIONAL) If provided then the given id will be
|
||||
* @param {numeric} selectId (OPTIONAL = undefined) If provided then the given id will be
|
||||
* selected in the filter results (only selected, not displayed).
|
||||
* @param {bool} display (OPTIONAL = false)
|
||||
*/
|
||||
SecretariesHelper.prototype.filter = function(key, selectRecordId) {
|
||||
SecretariesHelper.prototype.filter = function(key, selectId, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
var postUrl = GlobalVariables.baseUrl + 'backend_api/ajax_filter_secretaries';
|
||||
var postData = { 'key': key };
|
||||
|
||||
|
@ -322,19 +345,18 @@ SecretariesHelper.prototype.filter = function(key, selectRecordId) {
|
|||
|
||||
BackendUsers.helper.filterResults = response;
|
||||
|
||||
$('#secretaries .filter-results').html('');
|
||||
$('#filter-secretaries .results').html('');
|
||||
$.each(response, function(index, secretary) {
|
||||
var html = SecretariesHelper.prototype.getFilterHtml(secretary);
|
||||
$('#secretaries .filter-results').append(html);
|
||||
$('#filter-secretaries .results').append(html);
|
||||
});
|
||||
|
||||
if (selectRecordId != undefined) {
|
||||
$('.secretary-row').each(function() {
|
||||
if ($(this).attr('data-id') == selectRecordId) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
if (response.length == 0) {
|
||||
$('#filter-secretaries .results').html('<em>No results found ...</em>')
|
||||
}
|
||||
|
||||
if (selectId != undefined) {
|
||||
BackendUsers.helper.select(selectId, display);
|
||||
}
|
||||
}, 'json');
|
||||
};
|
||||
|
@ -353,4 +375,38 @@ SecretariesHelper.prototype.getFilterHtml = function(secretary) {
|
|||
'</div>';
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
/**
|
||||
* Select a specific record from the current filter results. If the secretary id does not exist
|
||||
* in the list then no record will be selected.
|
||||
*
|
||||
* @param {numeric} id The record id to be selected from the filter results.
|
||||
* @param {bool} display (OPTIONAL = false) If true then the method will display the record
|
||||
* on the form.
|
||||
*
|
||||
* @task The selected row must always be visible (even if a vertical scroll bar is used to
|
||||
* navigate through the filter results).
|
||||
*/
|
||||
SecretariesHelper.prototype.select = function(id, display) {
|
||||
if (display == undefined) display = false;
|
||||
|
||||
$('#filter-secretaries .selected-row').removeClass('selected-row');
|
||||
|
||||
$('#filter-secretaries .secretary-row').each(function() {
|
||||
if ($(this).attr('data-id') == id) {
|
||||
$(this).addClass('selected-row');
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if (display) {
|
||||
$.each(BackendUsers.helper.filterResults, function(index, admin) {
|
||||
if (admin.id == id) {
|
||||
BackendUsers.helper.display(admin);
|
||||
$('#edit-secretary, #delete-secretary').prop('disabled', false);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
|
@ -483,7 +483,7 @@ var FrontendBook = {
|
|||
$.each(GlobalVariables.availableServices, function(index, service) {
|
||||
if (service.id == $('#select-service').val()) {
|
||||
selServiceDuration = service.duration;
|
||||
return; // Stop searching ...
|
||||
return false; // Stop searching ...
|
||||
}
|
||||
});
|
||||
|
||||
|
|
313
src/assets/js/working_plan.js
Normal file
313
src/assets/js/working_plan.js
Normal file
|
@ -0,0 +1,313 @@
|
|||
/**
|
||||
* Contains the working plan functionality. The working plan DOM elements must be same
|
||||
* in every page this class is used.
|
||||
*
|
||||
* @class WorkingPlan
|
||||
*/
|
||||
var WorkingPlan = function() {
|
||||
/**
|
||||
* This flag is used when trying to cancel row editing. It is
|
||||
* true only whenever the user presses the cancel button.
|
||||
*
|
||||
* @type {bool}
|
||||
*/
|
||||
this.enableCancel = false;
|
||||
|
||||
/**
|
||||
* This flag determines whether the jeditables are allowed to submit. It is
|
||||
* true only whenever the user presses the save button.
|
||||
*
|
||||
* @type {bool}
|
||||
*/
|
||||
this.enableSubmit = false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Setup the dom elements of a given working plan.
|
||||
*
|
||||
* @param {object} workingPlan Contains the working hours and breaks for each day of the week.
|
||||
*/
|
||||
WorkingPlan.prototype.setup = function(workingPlan) {
|
||||
$.each(workingPlan, function(index, workingDay) {
|
||||
if (workingDay != null) {
|
||||
$('#' + index).prop('checked', true);
|
||||
$('#' + index + '-start').val(workingDay.start);
|
||||
$('#' + index + '-end').val(workingDay.end);
|
||||
|
||||
// Add the day's breaks on the breaks table.
|
||||
$.each(workingDay.breaks, function(i, brk) {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">' + GeneralFunctions.ucaseFirstLetter(index) + '</td>' +
|
||||
'<td class="break-start editable">' + brk.start + '</td>' +
|
||||
'<td class="break-end editable">' + brk.end + '</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('.breaks').append(tr);
|
||||
});
|
||||
} else {
|
||||
$('#' + index).prop('checked', false);
|
||||
$('#' + index + '-start').prop('disabled', true);
|
||||
$('#' + index + '-end').prop('disabled', true);
|
||||
}
|
||||
});
|
||||
|
||||
// Make break cells editable.
|
||||
WorkingPlan.prototype.editableBreakDay($('.breaks .break-day'));
|
||||
WorkingPlan.prototype.editableBreakTime($('.breaks').find('.break-start, .break-end'));
|
||||
};
|
||||
|
||||
/**
|
||||
* This method makes editable the break day cells.
|
||||
*
|
||||
* @param {object} $selector The jquery selector ready for use.
|
||||
*/
|
||||
WorkingPlan.prototype.editableBreakDay = function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
return value;
|
||||
}, {
|
||||
'type': 'select',
|
||||
'data': '{ "Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", '
|
||||
+ '"Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", '
|
||||
+ '"Sunday": "Sunday", "selected": "Monday"}',
|
||||
'event': 'edit',
|
||||
'height': '30px',
|
||||
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
|
||||
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
|
||||
'onblur': 'ignore',
|
||||
'onreset': function(settings, td) {
|
||||
if (!WorkingPlan.prototype.enableCancel) return false; // disable ESC button
|
||||
},
|
||||
'onsubmit': function(settings, td) {
|
||||
if (!WorkingPlan.prototype.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* This method makes editable the break time cells.
|
||||
*
|
||||
* @param {object} $selector The jquery selector ready for use.
|
||||
*/
|
||||
WorkingPlan.prototype.editableBreakTime = function($selector) {
|
||||
$selector.editable(function(value, settings) {
|
||||
// Do not return the value because the user needs to press the "Save" button.
|
||||
return value;
|
||||
}, {
|
||||
'event': 'edit',
|
||||
'height': '25px',
|
||||
'submit': '<button type="button" class="hidden submit-editable">Submit</button>',
|
||||
'cancel': '<button type="button" class="hidden cancel-editable">Cancel</button>',
|
||||
'onblur': 'ignore',
|
||||
'onreset': function(settings, td) {
|
||||
if (!WorkingPlan.prototype.enableCancel) return false; // disable ESC button
|
||||
},
|
||||
'onsubmit': function(settings, td) {
|
||||
if (!WorkingPlan.prototype.enableSubmit) return false; // disable Enter button
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Binds the event handlers for the working plan dom elements.
|
||||
*/
|
||||
WorkingPlan.prototype.bindEventHandlers = function() {
|
||||
/**
|
||||
* Event: Day Checkbox "Click"
|
||||
*
|
||||
* Enable or disable the time selection for each day.
|
||||
*/
|
||||
$('.working-plan input[type="checkbox"]').click(function() {
|
||||
var id = $(this).attr('id');
|
||||
|
||||
if ($(this).prop('checked') == true) {
|
||||
$('#' + id + '-start').prop('disabled', false).val('09:00');
|
||||
$('#' + id + '-end').prop('disabled', false).val('18:00');
|
||||
} else {
|
||||
$('#' + id + '-start').prop('disabled', true).val('');
|
||||
$('#' + id + '-end').prop('disabled', true).val('');
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Add Break Button "Click"
|
||||
*
|
||||
* A new row is added on the table and the user can enter the new break
|
||||
* data. After that he can either press the save or cancel button.
|
||||
*/
|
||||
$('.add-break').click(function() {
|
||||
var tr =
|
||||
'<tr>' +
|
||||
'<td class="break-day editable">Monday</td>' +
|
||||
'<td class="break-start editable">09:00</td>' +
|
||||
'<td class="break-end editable">10:00</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn edit-break" title="Edit Break">' +
|
||||
'<i class="icon-pencil"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn delete-break" title="Delete Break">' +
|
||||
'<i class="icon-remove"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn save-break hidden" title="Save Break">' +
|
||||
'<i class="icon-ok"></i>' +
|
||||
'</button>' +
|
||||
'<button type="button" class="btn cancel-break hidden" title="Cancel Break">' +
|
||||
'<i class="icon-ban-circle"></i>' +
|
||||
'</button>' +
|
||||
'</td>' +
|
||||
'</tr>';
|
||||
$('.breaks').prepend(tr);
|
||||
|
||||
// Bind editable and event handlers.
|
||||
tr = $('.breaks tr').get()[1];
|
||||
BackendSettings.editableBreakDay($(tr).find('.break-day'));
|
||||
BackendSettings.editableBreakTime($(tr).find('.break-start, .break-end'));
|
||||
$(tr).find('.edit-break').trigger('click');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Edit Break Button "Click"
|
||||
*
|
||||
* Enables the row editing for the "Breaks" table rows.
|
||||
*/
|
||||
$(document).on('click', '.edit-break', function() {
|
||||
// Reset previous editable tds
|
||||
var $previousEdt = $(this).closest('table').find('.editable').get();
|
||||
$.each($previousEdt, function(index, edt) {
|
||||
edt.reset();
|
||||
});
|
||||
|
||||
// Make all cells in current row editable.
|
||||
$(this).parent().parent().children().trigger('edit');
|
||||
$(this).parent().parent().find('.break-start input, .break-end input').timepicker();
|
||||
$(this).parent().parent().find('.break-day select').focus();
|
||||
|
||||
// Show save - cancel buttons.
|
||||
$(this).closest('table').find('.edit-break, .delete-break').addClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').removeClass('hidden');
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Delete Break Button "Click"
|
||||
*
|
||||
* Removes the current line from the "Breaks" table.
|
||||
*/
|
||||
$(document).on('click', '.delete-break', function() {
|
||||
$(this).parent().parent().remove();
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Cancel Break Button "Click"
|
||||
*
|
||||
* Bring the ".breaks" table back to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.cancel-break', function() {
|
||||
WorkingPlan.prototype.enableCancel = true;
|
||||
$(this).parent().parent().find('.cancel-editable').trigger('click');
|
||||
WorkingPlan.prototype.enableCancel = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
});
|
||||
|
||||
/**
|
||||
* Event: Save Break Button "Click"
|
||||
*
|
||||
* Save the editable values and restore the table to its initial state.
|
||||
*/
|
||||
$(document).on('click', '.save-break', function() {
|
||||
// Break's start time must always be prior to break's end.
|
||||
var start = Date.parse($(this).parent().parent().find('.break-start input').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.break-end input').val());
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.break-end input').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
|
||||
WorkingPlan.prototype.enableSubmit = true;
|
||||
$(this).parent().parent().find('.editable .submit-editable').trigger('click');
|
||||
WorkingPlan.prototype.enableSubmit = false;
|
||||
|
||||
$(this).closest('table').find('.edit-break, .delete-break').removeClass('hidden');
|
||||
$(this).parent().find('.save-break, .cancel-break').addClass('hidden');
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get the working plan settings.
|
||||
*
|
||||
* @returns {object} Returns the working plan settings object.
|
||||
*/
|
||||
WorkingPlan.prototype.get = function() {
|
||||
var workingPlan = {};
|
||||
$('.working-plan input[type="checkbox"').each(function() {
|
||||
var id = $(this).attr('id');
|
||||
if ($(this).prop('checked') == true) {
|
||||
workingPlan[id] = {}
|
||||
workingPlan[id].start = $('#' + id + '-start').val();
|
||||
workingPlan[id].end = $('#' + id + '-end').val();
|
||||
workingPlan[id].breaks = [];
|
||||
|
||||
$('.breaks tr').each(function(index, tr) {
|
||||
var day = $(tr).find('.break-day').text().toLowerCase();
|
||||
if (day == id) {
|
||||
var start = $(tr).find('.break-start').text();
|
||||
var end = $(tr).find('.break-end').text();
|
||||
|
||||
workingPlan[id].breaks.push({
|
||||
'start': start,
|
||||
'end': end
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
workingPlan[id] = null;
|
||||
}
|
||||
});
|
||||
|
||||
return workingPlan;
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disabled the timepicker functionality from the working plan input
|
||||
* text fields.
|
||||
*
|
||||
* @param {bool} disabled (OPTIONAL = false) If true then the timepickers will be
|
||||
* disabled.
|
||||
*/
|
||||
WorkingPlan.prototype.timepickers = function(disabled) {
|
||||
if (disabled == undefined) disabled == false;
|
||||
|
||||
if (disabled == false) {
|
||||
// Set timepickers where needed.
|
||||
$('.working-plan input').timepicker({
|
||||
'timeFormat': 'HH:mm',
|
||||
'onSelect': function(datetime, inst) {
|
||||
// Start time must be earlier than end time.
|
||||
var start = Date.parse($(this).parent().parent().find('.work-start').val());
|
||||
var end = Date.parse($(this).parent().parent().find('.work-end').val());
|
||||
|
||||
if (start > end) {
|
||||
$(this).parent().parent().find('.work-end').val(start.addHours(1).toString('HH:mm'));
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
$('.working-plan input').timepicker('destroy');
|
||||
}
|
||||
};
|
Loading…
Reference in a new issue