Compare commits
7 Commits
v3.2.1
...
c772a39156
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c772a39156 | ||
|
|
7907d1d507 | ||
|
|
01c4a35026 | ||
|
|
4b08a4d856 | ||
|
|
23d2483855 | ||
|
|
729541f280 | ||
|
|
d47f525480 |
0
www/admin/edit_groups_test.php
Normal file
0
www/admin/edit_groups_test.php
Normal file
@@ -193,6 +193,12 @@ $CONTENT_DATA = array_merge($HEADER, $DATA, $DEBUG_DATA);
|
|||||||
foreach ($CONTENT_DATA as $key => $value) {
|
foreach ($CONTENT_DATA as $key => $value) {
|
||||||
$smarty->assign($key, $value);
|
$smarty->assign($key, $value);
|
||||||
}
|
}
|
||||||
|
if (is_dir(BASE.TEMPLATES_C)) {
|
||||||
|
$smarty->setCompileDir(BASE.TEMPLATES_C);
|
||||||
|
}
|
||||||
|
if (is_dir(BASE.CACHE)) {
|
||||||
|
$smarty->setCacheDir(BASE.CACHE);
|
||||||
|
}
|
||||||
$smarty->display('edit_order.tpl');
|
$smarty->display('edit_order.tpl');
|
||||||
|
|
||||||
echo $login->printErrorMsg();
|
echo $login->printErrorMsg();
|
||||||
|
|||||||
@@ -12,7 +12,17 @@ require 'config.php';
|
|||||||
require BASE.INCLUDES.'admin_header.inc';
|
require BASE.INCLUDES.'admin_header.inc';
|
||||||
$MASTER_TEMPLATE_NAME = 'main_body.tpl';
|
$MASTER_TEMPLATE_NAME = 'main_body.tpl';
|
||||||
$TEMPLATE_NAME = 'smarty_test.tpl';
|
$TEMPLATE_NAME = 'smarty_test.tpl';
|
||||||
$PAGE_WIDTH = 750;
|
$CSS_NAME = 'smart_test.css';
|
||||||
|
$USE_PROTOTYPE = false;
|
||||||
|
$USE_JQUERY = true;
|
||||||
|
if ($USE_PROTOTYPE) {
|
||||||
|
$EDIT_JAVASCRIPT = 'edit.pt.js';
|
||||||
|
$JS_NAME = 'prototype.test.js';
|
||||||
|
} else if ($USE_JQUERY) {
|
||||||
|
$EDIT_JAVASCRIPT = 'edit.jq.js';
|
||||||
|
$JS_NAME = 'jquery.test.js';
|
||||||
|
}
|
||||||
|
$PAGE_WIDTH = "100%";
|
||||||
require BASE.INCLUDES.'admin_set_paths.inc';
|
require BASE.INCLUDES.'admin_set_paths.inc';
|
||||||
|
|
||||||
// smarty test
|
// smarty test
|
||||||
|
|||||||
@@ -1,25 +1,12 @@
|
|||||||
<?
|
<?php
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* AUTHOR: Clemens Schwaighofer
|
* AUTHOR: Clemens Schwaighofer
|
||||||
* CREATED: 2003/06/10
|
* CREATED: 2003/06/10
|
||||||
* SHORT DESCRIPTION:
|
* SHORT DESCRIPTION:
|
||||||
* configuration file
|
* configuration file
|
||||||
* HISTORY:
|
* HISTORY:
|
||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
/************* SESSION NAMES *************/
|
|
||||||
// backend
|
|
||||||
DEFINE('EDIT_SESSION_NAME', '<ADMIN SESSION NAME>');
|
|
||||||
// frontend
|
|
||||||
DEFINE('SESSION_NAME', '<SESSION NAME>');
|
|
||||||
// set the session name
|
|
||||||
define('SET_SESSION_NAME', EDIT_SESSION_NAME);
|
|
||||||
|
|
||||||
/************* LANGUAGE / ENCODING *******/
|
|
||||||
DEFINE('DEFAULT_LANG', 'en_utf8');
|
|
||||||
// default web page encoding setting
|
|
||||||
DEFINE('DEFAULT_ENCODING', 'UTF-8');
|
|
||||||
|
|
||||||
/************* PATHS *********************/
|
/************* PATHS *********************/
|
||||||
// directory seperator
|
// directory seperator
|
||||||
DEFINE('DS', DIRECTORY_SEPARATOR);
|
DEFINE('DS', DIRECTORY_SEPARATOR);
|
||||||
@@ -27,7 +14,7 @@ DEFINE('DS', DIRECTORY_SEPARATOR);
|
|||||||
// path to original file (if symlink)
|
// path to original file (if symlink)
|
||||||
DEFINE('DIR', __DIR__.DS);
|
DEFINE('DIR', __DIR__.DS);
|
||||||
// base dir root folder level
|
// base dir root folder level
|
||||||
DEFINE('BASE', str_replace('configs', '', __DIR__));
|
DEFINE('BASE', str_replace('/configs', '', __DIR__).DS);
|
||||||
|
|
||||||
// ** OLD DIR DECLARATIONS **
|
// ** OLD DIR DECLARATIONS **
|
||||||
// path to document root of file called
|
// path to document root of file called
|
||||||
@@ -35,6 +22,8 @@ DEFINE('ROOT', getcwd().DS);
|
|||||||
// libs path
|
// libs path
|
||||||
DEFINE('LIB', 'lib'.DS);
|
DEFINE('LIB', 'lib'.DS);
|
||||||
DEFINE('LIBS', 'lib'.DS);
|
DEFINE('LIBS', 'lib'.DS);
|
||||||
|
// configs folder
|
||||||
|
DEFINE('CONFIGS', 'configs'.DS);
|
||||||
// includes (strings, arrays for static, etc)
|
// includes (strings, arrays for static, etc)
|
||||||
DEFINE('INCLUDES', 'includes'.DS);
|
DEFINE('INCLUDES', 'includes'.DS);
|
||||||
// layout base path
|
// layout base path
|
||||||
@@ -83,6 +72,14 @@ DEFINE('TEMPLATES_C', 'templates_c'.DS);
|
|||||||
DEFINE('TEMPLATES', 'templates'.DS);
|
DEFINE('TEMPLATES', 'templates'.DS);
|
||||||
// frontend template dir', only for admin
|
// frontend template dir', only for admin
|
||||||
DEFINE('TEMPLATES_FRONTEND', 'templates_frontend'.DS);
|
DEFINE('TEMPLATES_FRONTEND', 'templates_frontend'.DS);
|
||||||
|
|
||||||
|
// if below is turned to true then the old folder format is ued
|
||||||
|
// www/layout/<admin|frontend>/<template name>/...
|
||||||
|
// in the new layout the "<template name>" is dropped and only frontend
|
||||||
|
// data is visible there: js, css, images
|
||||||
|
// language files are moved into www/includes/lang/<admin/frontend>/*.mo
|
||||||
|
// the language .po files are in 4dev/lang/<admin/frontend>/*.po
|
||||||
|
DEFINE('USE_DEPRECATED_TEMPLATE_FOLDERS', false);
|
||||||
// default template
|
// default template
|
||||||
DEFINE('DEFAULT_TEMPLATE', 'default'.DS);
|
DEFINE('DEFAULT_TEMPLATE', 'default'.DS);
|
||||||
// default template file
|
// default template file
|
||||||
@@ -111,7 +108,7 @@ DEFINE('DEFAULT_ACL_ADMIN', 100); */
|
|||||||
// DEFINE('ERROR_STRICT', 3);
|
// DEFINE('ERROR_STRICT', 3);
|
||||||
// allow page caching in general, set to 'FALSE' if you do debugging or development!
|
// allow page caching in general, set to 'FALSE' if you do debugging or development!
|
||||||
// DEFINE('ALLOW_SMARTY_CACHE', FALSE);
|
// DEFINE('ALLOW_SMARTY_CACHE', FALSE);
|
||||||
// cache life time, in seconds, default here is 2 days (172800s)
|
// cache life time, in second', default here is 2 days (172800s)
|
||||||
// -1 is never expire cache
|
// -1 is never expire cache
|
||||||
// DEFINE('SMARTY_CACHE_LIFETIME', -1);
|
// DEFINE('SMARTY_CACHE_LIFETIME', -1);
|
||||||
|
|
||||||
@@ -120,6 +117,9 @@ DEFINE('DEFAULT_ACL_ADMIN', 100); */
|
|||||||
DEFINE('LOGOUT_TARGET', '');
|
DEFINE('LOGOUT_TARGET', '');
|
||||||
// password change allowed
|
// password change allowed
|
||||||
DEFINE('PASSWORD_CHANGE', false);
|
DEFINE('PASSWORD_CHANGE', false);
|
||||||
|
// min/max password length
|
||||||
|
DEFINE('PASSWORD_MIN_LENGTH', 8);
|
||||||
|
DEFINE('PASSWORD_MAX_LENGTH', 255);
|
||||||
|
|
||||||
/************* AJAX / ACCESS *************/
|
/************* AJAX / ACCESS *************/
|
||||||
// ajax request type
|
// ajax request type
|
||||||
@@ -134,6 +134,21 @@ DEFINE('PAGE_WIDTH', 800);
|
|||||||
// the default template name
|
// the default template name
|
||||||
DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl');
|
DEFINE('MASTER_TEMPLATE_NAME', 'main_body.tpl');
|
||||||
|
|
||||||
|
/************* SESSION NAMES *************/
|
||||||
|
// server name HASH
|
||||||
|
DEFINE('SERVER_NAME_HASH', hash('crc32b', $_SERVER['HTTP_HOST']));
|
||||||
|
// backend
|
||||||
|
DEFINE('EDIT_SESSION_NAME', 'ADMIN_SESSION_NAME'.SERVER_NAME_HASH);
|
||||||
|
// frontend
|
||||||
|
DEFINE('SESSION_NAME', 'SESSION_NAME'.SERVER_NAME_HASH);
|
||||||
|
// SET_SESSION_NAME should be set in the header if a special session name is needed
|
||||||
|
// DEFINE('SET_SESSION_NAME', SESSION_NAME);
|
||||||
|
|
||||||
|
/************* LANGUAGE / ENCODING *******/
|
||||||
|
DEFINE('DEFAULT_LANG', 'en_utf8');
|
||||||
|
// default web page encoding setting
|
||||||
|
DEFINE('DEFAULT_ENCODING', 'UTF-8');
|
||||||
|
|
||||||
// below two can be defined here, but they should be
|
// below two can be defined here, but they should be
|
||||||
// defined in either the header file or the file itself
|
// defined in either the header file or the file itself
|
||||||
/************* LOGGING *******************/
|
/************* LOGGING *******************/
|
||||||
@@ -152,44 +167,21 @@ DEFINE('DEV_SCHEMA', 'public');
|
|||||||
DEFINE('TEST_SCHEMA', 'public');
|
DEFINE('TEST_SCHEMA', 'public');
|
||||||
DEFINE('LIVE_SCHEMA', 'public');
|
DEFINE('LIVE_SCHEMA', 'public');
|
||||||
|
|
||||||
// non constant part
|
/************* OTHER PATHS *****************/
|
||||||
/************* DB ACCESS *****************/
|
|
||||||
// please be VERY carefull only to change the right side
|
|
||||||
$DB_CONFIG = array (
|
|
||||||
'<db id>' => array (
|
|
||||||
'db_name' => '<database>',
|
|
||||||
'db_user' => '<user>',
|
|
||||||
'db_pass' => '<password>',
|
|
||||||
'db_host' => '<host>',
|
|
||||||
'db_port' => '5432',
|
|
||||||
'db_schema' => 'public', // if not set, uses public
|
|
||||||
'db_type' => 'pgsql',
|
|
||||||
'db_encoding' => '',
|
|
||||||
'db_ssl' => 'disable' // allow, disable, require, prefer
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
// File and Folder paths
|
// File and Folder paths
|
||||||
// ID is TARGET (first array element)
|
// ID is TARGET (first array element)
|
||||||
// $PATHS['test']['csv_path'] = '';
|
// $PATHS['test']['csv_path'] = '';
|
||||||
// $PATHS['test']['perl_bin'] = '';
|
// $PATHS['test']['perl_bin'] = '';
|
||||||
// $PATHS['test']['redirect_url'] = '';
|
// $PATHS['test']['redirect_url'] = '';
|
||||||
|
|
||||||
// each host has a different db_host
|
/************* DB ACCESS *****************/
|
||||||
// development host
|
if (file_exists(BASE.CONFIGS.'config.db.inc')) {
|
||||||
$DB_HOST['<host>'] = '<db id>';
|
require BASE.CONFIGS.'config.db.inc';
|
||||||
// target host (live)
|
}
|
||||||
// $DB_TARGET_HOST['<host>'] = '<DB ID>';
|
/************* CORE HOST SETTINGS *****************/
|
||||||
// url redirect database
|
if (file_exists(BASE.CONFIGS.'config.host.inc')) {
|
||||||
// $DB_URL_REDIRECT_HOST['<host>'] = '<DB ID>';
|
require BASE.CONFIGS.'config.host.inc';
|
||||||
// location flagging
|
}
|
||||||
// test/dev/live
|
|
||||||
$LOCATION['<host>'] = '<test|live|remote|etc>';
|
|
||||||
// show DEBUG override
|
|
||||||
// true/false
|
|
||||||
$DEBUG_FLAG['<host>'] = true;
|
|
||||||
// set postgresql paths (schemas)
|
|
||||||
$DB_PATH['<host>'] = PUBLIC_SCHEMA;
|
|
||||||
|
|
||||||
// set the USE_DATABASE var, if there is nothing set, we assume TRUE
|
// set the USE_DATABASE var, if there is nothing set, we assume TRUE
|
||||||
$USE_DATABASE = defined('USE_DATABASE') ? USE_DATABASE : true;
|
$USE_DATABASE = defined('USE_DATABASE') ? USE_DATABASE : true;
|
||||||
@@ -198,29 +190,41 @@ $USE_DATABASE = defined('USE_DATABASE') ? USE_DATABASE : true;
|
|||||||
// ** missing live domains **
|
// ** missing live domains **
|
||||||
// get the name without the port
|
// get the name without the port
|
||||||
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
|
list($HOST_NAME) = array_pad(explode(':', $_SERVER['HTTP_HOST'], 2), 2, null);
|
||||||
if (!$DB_HOST[$HOST_NAME] && $USE_DATABASE) {
|
if (!isset($DB_HOST[$HOST_NAME]) && $USE_DATABASE) {
|
||||||
echo 'No matching DB config found. Contact Admin<br>';
|
echo 'No matching DB config found. Contact Admin<br>';
|
||||||
exit -1;
|
exit -1;
|
||||||
}
|
}
|
||||||
|
// set HOST name
|
||||||
|
DEFINE('HOST_NAME', $HOST_NAME);
|
||||||
|
// set SSL on
|
||||||
|
if ((array_key_exists('HTTPS', $_SERVER) && !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ||
|
||||||
|
$_SERVER['SERVER_PORT'] == 443) {
|
||||||
|
DEFINE('HOST_SSL', true);
|
||||||
|
DEFINE('HOST_PROTOCOL', 'https://');
|
||||||
|
} else {
|
||||||
|
DEFINE('HOST_SSL', false);
|
||||||
|
DEFINE('HOST_PROTOCOL', 'http://');
|
||||||
|
}
|
||||||
// define the static names
|
// define the static names
|
||||||
DEFINE('LOGIN_DB', $DB_HOST[$HOST_NAME]);
|
DEFINE('LOGIN_DB', $DB_HOST[$HOST_NAME]);
|
||||||
DEFINE('MAIN_DB', $DB_HOST[$HOST_NAME]);
|
DEFINE('MAIN_DB', $DB_HOST[$HOST_NAME]);
|
||||||
DEFINE('DB_SCHEMA', $DB_PATH[$HOST_NAME]);
|
DEFINE('DB_SCHEMA', $DB_PATH[$HOST_NAME]);
|
||||||
// DEFINE('TARGET_DB', $DB_TARGET_HOST[$HOST_NAME]);
|
// DEFINE('TARGET_DB', $DB_TARGET_HOST[$HOST_NAME]);
|
||||||
// DEFINE('URL_REDIRECT_DB', $DB_URL_REDIRECT_HOST[$HOST_NAME]);
|
// DEFINE('URL_REDIRECT_DB', $DB_URL_REDIRECT_HOST[$HOST_NAME]);
|
||||||
// next three if top is not set
|
// next three if top is not set
|
||||||
// DEFINE('DEV_SCHEMA', $DB_CONFIG[MAIN_DB]['db_schema']);
|
// DEFINE('TEST_SCHEMA', $DB_CONFIG[MAIN_DB]['db_schema']);
|
||||||
// DEFINE('TEST_SCHEMA', $DB_CONFIG[MAIN_DB]['db_schema']);
|
// DEFINE('DEV_SCHEMA', $DB_CONFIG[MAIN_DB]['db_schema']);
|
||||||
// DEFINE('PUBLIC_SCHEMA', $DB_CONFIG[TARGET_DB]['db_schema']);
|
// DEFINE('PUBLIC_SCHEMA', $DB_CONFIG[TARGET_DB]['db_schema']);
|
||||||
DEFINE('LOGIN_DB_SCHEMA', 'public'); // where the edit* tables are
|
DEFINE('LOGIN_DB_SCHEMA', PUBLIC_SCHEMA); // where the edit* tables are
|
||||||
DEFINE('GLOBAL_DB_SCHEMA', 'public'); // where global tables are that are used by all schemas (eg queue tables for online, etc)
|
DEFINE('GLOBAL_DB_SCHEMA', PUBLIC_SCHEMA); // where global tables are that are used by all schemas (eg queue tables for online, etc)
|
||||||
DEFINE('TARGET', $LOCATION[$HOST_NAME]);
|
DEFINE('TARGET', $LOCATION[$HOST_NAME]);
|
||||||
// DEFINE('CSV_PATH', $PATHS[TARGET]['csv_path']);
|
// DEFINE('CSV_PATH', $PATHS[TARGET]['csv_path']);
|
||||||
// DEFINE('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin']);
|
// DEFINE('EXPORT_SCRIPT', $PATHS[TARGET]['perl_bin']);
|
||||||
// DEFINE('REDIRECT_URL', $PATHS[TARGET]['redirect_url']);
|
// DEFINE('REDIRECT_URL', $PATHS[TARGET]['redirect_url']);
|
||||||
DEFINE('DEBUG', $DEBUG_FLAG[$HOST_NAME]);
|
DEFINE('DEBUG', $DEBUG_FLAG[$HOST_NAME]);
|
||||||
DEFINE('SHOW_ALL_ERRORS', false); // show all errors if debug_all & show_error_handling are enabled
|
DEFINE('SITE_LANG', $SITE_LANG[$HOST_NAME]);
|
||||||
|
|
||||||
|
DEFINE('SHOW_ALL_ERRORS', true); // show all errors if debug_all & show_error_handling are enabled
|
||||||
|
|
||||||
/************* GENERAL PAGE TITLE ********/
|
/************* GENERAL PAGE TITLE ********/
|
||||||
$G_TITLE = '<OVERALL PAGE TITLE>';
|
$G_TITLE = '<OVERALL PAGE TITLE>';
|
||||||
@@ -232,6 +236,11 @@ $EDIT_JAVASCRIPT = 'edit.js';
|
|||||||
$STYLESHEET = 'frontend.css';
|
$STYLESHEET = 'frontend.css';
|
||||||
$JAVASCRIPT = 'frontend.js';
|
$JAVASCRIPT = 'frontend.js';
|
||||||
|
|
||||||
|
// anything optional
|
||||||
|
/************* INTERNAL ******************/
|
||||||
|
// any other global definitons here
|
||||||
|
// DEFINE('SOME_ID', <SOME VALUE>);
|
||||||
|
|
||||||
/************* CONVERT *******************/
|
/************* CONVERT *******************/
|
||||||
$paths = array (
|
$paths = array (
|
||||||
'/bin',
|
'/bin',
|
||||||
@@ -253,12 +262,14 @@ if (defined('DEBUG') && DEBUG == false) {
|
|||||||
$PRINT_ALL = 0;
|
$PRINT_ALL = 0;
|
||||||
$DB_DEBUG = 0;
|
$DB_DEBUG = 0;
|
||||||
$ENABLE_ERROR_HANDLING = 0;
|
$ENABLE_ERROR_HANDLING = 0;
|
||||||
|
} else {
|
||||||
|
$ECHO_ALL = 0;
|
||||||
|
$DEBUG_ALL = 1;
|
||||||
|
$PRINT_ALL = 1;
|
||||||
|
$DB_DEBUG = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// any other global definitons here
|
|
||||||
// DEFINE('SOME_ID', <SOME VALUE>);
|
|
||||||
|
|
||||||
// read auto loader
|
// read auto loader
|
||||||
require BASE.LIB.'autoloader.php';
|
require BASE.LIB.'autoloader.php';
|
||||||
|
|
||||||
# __END__
|
// __END__
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
//------------------------------ variable init start
|
//------------------------------ variable init start
|
||||||
// for dev test we set full error reporting; writes everything, except E_ERROR into logs/php_error-<day>.log
|
// for dev test we set full error reporting; writes everything, except E_ERROR into logs/php_error-<day>.log
|
||||||
if ($DEBUG_ALL && $ENABLE_ERROR_HANDLING) {
|
if ($DEBUG_ALL && $ENABLE_ERROR_HANDLING) {
|
||||||
include(BASE.LIBS."Error.Handling.inc");
|
include BASE.LIBS."Error.Handling.inc";
|
||||||
}
|
}
|
||||||
// predefine vars
|
// predefine vars
|
||||||
$lang = '';
|
$lang = '';
|
||||||
|
|||||||
@@ -122,8 +122,8 @@ if (false === strstr(LAYOUT.DEFAULT_TEMPLATE.LANG, $cms->lang_dir) ||
|
|||||||
|
|
||||||
// javascrip translate data as template for auto translate
|
// javascrip translate data as template for auto translate
|
||||||
if (!$TEMPLATE_TRANSLATE) {
|
if (!$TEMPLATE_TRANSLATE) {
|
||||||
$cms->debug('LANG', 'Load lang: '.$lang.', for page file jsTranslate_'.$lang.'.tpl');
|
|
||||||
$TEMPLATE_TRANSLATE = 'jsTranslate_'.$lang.'.tpl';
|
$TEMPLATE_TRANSLATE = 'jsTranslate_'.$lang.'.tpl';
|
||||||
|
$cms->debug('LANG', 'Load lang: '.$lang.', for page file '.$TEMPLATE_TRANSLATE);
|
||||||
} else {
|
} else {
|
||||||
// we assume we have some fixed set
|
// we assume we have some fixed set
|
||||||
// we must add _<$lang>
|
// we must add _<$lang>
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
*********************************************************************/
|
*********************************************************************/
|
||||||
|
|
||||||
// trigger flags
|
// trigger flags
|
||||||
$cms->HEADER['USE_PROTOTYPE'] = USE_PROTOTYPE;
|
$cms->HEADER['USE_PROTOTYPE'] = isset($USE_PROTOTYPE) ? $USE_PROTOTYPE : USE_PROTOTYPE;
|
||||||
// scriptacolous, can only be used with prototype
|
// scriptacolous, can only be used with prototype
|
||||||
if (USE_PROTOTYPE) {
|
if ($cms->HEADER['USE_PROTOTYPE']) {
|
||||||
$cms->HEADER['USE_SCRIPTACULOUS'] = USE_SCRIPTACULOUS;
|
$cms->HEADER['USE_SCRIPTACULOUS'] = isset($USE_SCRIPTACULOUS) ? $USE_SCRIPTACULOUS : USE_SCRIPTACULOUS;
|
||||||
}
|
}
|
||||||
// jquery and prototype should not be used together
|
// jquery and prototype should not be used together
|
||||||
$cms->HEADER['USE_JQUERY'] = USE_JQUERY; // don't use either of those two toger
|
$cms->HEADER['USE_JQUERY'] = isset($USE_JQUERY) ? $USE_JQUERY : USE_JQUERY; // don't use either of those two toger
|
||||||
|
|
||||||
// set basic template path (tmp)
|
// set basic template path (tmp)
|
||||||
// paths are set in the 'set_paths.inc' file
|
// paths are set in the 'set_paths.inc' file
|
||||||
|
|||||||
83
www/layout/admin/default/css/smarty_test.css
Executable file
83
www/layout/admin/default/css/smarty_test.css
Executable file
@@ -0,0 +1,83 @@
|
|||||||
|
/* smart test CSS */
|
||||||
|
|
||||||
|
.jp-test {
|
||||||
|
width: 100%;
|
||||||
|
margin: 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.test-div {
|
||||||
|
margin: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* CORE overlay, progress elements */
|
||||||
|
.actionBoxElement {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10px;
|
||||||
|
border: 2px solid black;
|
||||||
|
box-shadow: #333333 10px 10px 25px;
|
||||||
|
color: black;
|
||||||
|
/*font-size: 20px;*/
|
||||||
|
left: 45px;
|
||||||
|
min-height: 200px;
|
||||||
|
position: fixed;
|
||||||
|
text-align: center;
|
||||||
|
top: 45px;
|
||||||
|
width: 70%;
|
||||||
|
z-index: 99;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionBoxTitle {
|
||||||
|
background-color: #c2c5cf;
|
||||||
|
border-radius: 7px 7px 0 0;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionBoxText {
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.actionBoxButtons {
|
||||||
|
bottom: 0;
|
||||||
|
font-size: 20px;
|
||||||
|
padding: 20px 20px 10px 20px;
|
||||||
|
position: absolute;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the overlay background black cover */
|
||||||
|
.overlayBoxElement {
|
||||||
|
background-color: rgba(0, 0, 0, 0.3);
|
||||||
|
height: 100%;
|
||||||
|
left: 0;
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 98;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* the progress guruguru */
|
||||||
|
/* NEW VERSION with CSS key frame animation */
|
||||||
|
.progress {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
background: rgba(255, 255, 255, 0.6);
|
||||||
|
border: 20px solid rgba(255, 255, 255, 0.25);
|
||||||
|
border-left-color: rgba(3, 155, 229 ,1);
|
||||||
|
border-top-color: rgba(3, 155, 229 ,1);
|
||||||
|
border-radius: 50%;
|
||||||
|
display: inline-block;
|
||||||
|
animation: rotate 600ms infinite linear;
|
||||||
|
/* align */
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 120;
|
||||||
|
}
|
||||||
|
/* Animation for above progress */
|
||||||
|
@keyframes rotate {
|
||||||
|
to {
|
||||||
|
transform: rotate(1turn)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
// if debug is set to true, console log messages are printed
|
// if debug is set to true, console log messages are printed
|
||||||
if (!DEBUG) {
|
if (!DEBUG) {
|
||||||
$($H(window.console)).each(function(w) {
|
for (var prop in window.console) {
|
||||||
window.console[w.key] = function() {};
|
window.console[prop] = function () {};
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
676
www/layout/admin/default/javascript/edit.jq.js
Normal file
676
www/layout/admin/default/javascript/edit.jq.js
Normal file
@@ -0,0 +1,676 @@
|
|||||||
|
/* general edit javascript */
|
||||||
|
|
||||||
|
/* jshint esversion: 6 */
|
||||||
|
|
||||||
|
// debug set
|
||||||
|
/*var FRONTEND_DEBUG = false;
|
||||||
|
var DEBUG = true;
|
||||||
|
if (!DEBUG) {
|
||||||
|
$($H(window.console)).each(function(w) {
|
||||||
|
window.console[w.key] = function() {};
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// METHOD: pop
|
||||||
|
// PARAMS: url, window name, features
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : opens a popup window with winNAme and given features (string)
|
||||||
|
function pop(theURL, winName, features) {
|
||||||
|
winName = window.open(theURL, winName, features);
|
||||||
|
winName.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: expandTA
|
||||||
|
// PARAMS: id
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : automatically resize a text area based on the amount of lines in it
|
||||||
|
function expandTA(ta_id) {
|
||||||
|
var ta;
|
||||||
|
// if a string comes, its a get by id, else use it as an element pass on
|
||||||
|
if (!ta_id.length) {
|
||||||
|
ta = ta_id;
|
||||||
|
} else {
|
||||||
|
ta = document.getElementById(ta_id);
|
||||||
|
}
|
||||||
|
var maxChars = ta.cols;
|
||||||
|
var theRows = ta.value.split("\n");
|
||||||
|
var numNewRows = 0;
|
||||||
|
|
||||||
|
for ( var i = 0; i < theRows.length; i++ ) {
|
||||||
|
if ((theRows[i].length+2) > maxChars) {
|
||||||
|
numNewRows += Math.ceil( (theRows[i].length+2) / maxChars ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ta.rows = numNewRows + theRows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getWindowSize
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: array with width/height
|
||||||
|
// DESC : wrapper to get the real window size for the current browser window
|
||||||
|
function getWindowSize()
|
||||||
|
{
|
||||||
|
var width, height;
|
||||||
|
width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
|
||||||
|
height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
|
||||||
|
return {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getScrollOffset
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: array with x/y px
|
||||||
|
// DESC : wrapper to get the correct scroll offset
|
||||||
|
function getScrollOffset()
|
||||||
|
{
|
||||||
|
var left, top;
|
||||||
|
left = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
|
||||||
|
top = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
|
||||||
|
return {
|
||||||
|
left: left,
|
||||||
|
top: top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: setCenter
|
||||||
|
// PARAMS: id to set center
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : centers div to current window size middle
|
||||||
|
function setCenter(id, left, top)
|
||||||
|
{
|
||||||
|
// get size of id
|
||||||
|
var dimensions = {};
|
||||||
|
dimensions.height = $('#' + id).height();
|
||||||
|
dimensions.width = $('#' + id).width();
|
||||||
|
var type = $('#' + id).css('position');
|
||||||
|
var viewport = getWindowSize();
|
||||||
|
var offset = getScrollOffset();
|
||||||
|
|
||||||
|
// console.log('Id %s, type: %s, dimensions %s x %s, viewport %s x %s', id, type, dimensions.width, dimensions.height, viewport.width, viewport.height);
|
||||||
|
// console.log('Scrolloffset left: %s, top: %s', offset.left, offset.top);
|
||||||
|
// console.log('Left: %s, Top: %s (%s)', parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left), parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top), parseInt((viewport.height / 2) - (dimensions.height / 2)));
|
||||||
|
if (left) {
|
||||||
|
$('#' + id).css({
|
||||||
|
left: parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (top) {
|
||||||
|
// if we have fixed, we do not add the offset, else it moves out of the screen
|
||||||
|
var top_pos = type == 'fixed' ?
|
||||||
|
parseInt((viewport.height / 2) - (dimensions.height / 2)) :
|
||||||
|
parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top);
|
||||||
|
$('#' + id).css({
|
||||||
|
top: top_pos + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: goToPos()
|
||||||
|
// PARAMS: element, offset (default 0)
|
||||||
|
// RETURN: none
|
||||||
|
// DESC: goes to an element id position
|
||||||
|
function goToPos(element, offset = 0)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($('#' + element).length)
|
||||||
|
{
|
||||||
|
$('body,html').animate({
|
||||||
|
scrollTop: $('#' + element).offset().top - offset
|
||||||
|
}, 500);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
errorCatch(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: __
|
||||||
|
// PARAMS: text
|
||||||
|
// RETURN: translated text (based on PHP selected language)
|
||||||
|
// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty)
|
||||||
|
function __(string)
|
||||||
|
{
|
||||||
|
if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) {
|
||||||
|
return i18n[string];
|
||||||
|
} else {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: string.format
|
||||||
|
// PARAMS: any, for string format
|
||||||
|
// RETURN: formatted string
|
||||||
|
// DESC : simple sprintf formater for replace
|
||||||
|
// "{0} is cool, {1} is not".format("Alpha", "Beta");
|
||||||
|
// First, checks if it isn't implemented yet.
|
||||||
|
if (!String.prototype.format) {
|
||||||
|
String.prototype.format = function()
|
||||||
|
{
|
||||||
|
var args = arguments;
|
||||||
|
return this.replace(/{(\d+)}/g, function(match, number)
|
||||||
|
{
|
||||||
|
return typeof args[number] != 'undefined' ?
|
||||||
|
args[number] :
|
||||||
|
match
|
||||||
|
;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: numberWithCommas
|
||||||
|
// PARAMS: number
|
||||||
|
// RETURN: formatted with , in thousands
|
||||||
|
// DESC : formats flat number 123456 to 123,456
|
||||||
|
const numberWithCommas = (x) => {
|
||||||
|
var parts = x.toString().split(".");
|
||||||
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
return parts.join(".");
|
||||||
|
};
|
||||||
|
|
||||||
|
// METHOD:
|
||||||
|
// PARAMS: string
|
||||||
|
// RETURN: string with <br>
|
||||||
|
// DESC : converts line breaks to br
|
||||||
|
function convertLBtoBR(string)
|
||||||
|
{
|
||||||
|
return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.prototype.escapeHTML) {
|
||||||
|
String.prototype.escapeHTML = function() {
|
||||||
|
return this.replace(/[&<>"'\/]/g, function (s) {
|
||||||
|
var entityMap = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': '"',
|
||||||
|
"'": ''',
|
||||||
|
"/": '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
return entityMap[s];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.prototype.unescapeHTML) {
|
||||||
|
String.prototype.unescapeHTML = function() {
|
||||||
|
return this.replace(/&[#\w]+;/g, function (s) {
|
||||||
|
var entityMap = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': '"',
|
||||||
|
''': "'",
|
||||||
|
'/': "/"
|
||||||
|
};
|
||||||
|
|
||||||
|
return entityMap[s];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getTimestamp
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: timestamp (in milliseconds)
|
||||||
|
// DESC : returns current timestamp (unix timestamp)
|
||||||
|
function getTimestamp()
|
||||||
|
{
|
||||||
|
let date = new Date();
|
||||||
|
return date.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: isObject
|
||||||
|
// PARAMS: possible object
|
||||||
|
// RETURN: true/false if it is an object or not
|
||||||
|
function isObject(val) {
|
||||||
|
if (val === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ((typeof val === 'function') || (typeof val === 'object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: exists
|
||||||
|
// PARAMS: uid
|
||||||
|
// RETURN: true/false
|
||||||
|
// DESC : checks if a DOM element actually exists
|
||||||
|
const exists = (id) => $('#' + id) ? true : false;
|
||||||
|
|
||||||
|
// METHOD: formatBytes
|
||||||
|
// PARAMS: bytes in int
|
||||||
|
// RETURN: string in GB/MB/KB
|
||||||
|
// DESC : converts a int number into bytes with prefix in two decimals precision
|
||||||
|
// currently precision is fixed, if dynamic needs check for max/min precision
|
||||||
|
function formatBytes(bytes)
|
||||||
|
{
|
||||||
|
var i = -1;
|
||||||
|
do {
|
||||||
|
bytes = bytes / 1024;
|
||||||
|
i++;
|
||||||
|
} while (bytes > 99);
|
||||||
|
|
||||||
|
return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: errorCatch
|
||||||
|
// PARAMS: err (error from try/catch
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : prints out error messages based on data available from the browser
|
||||||
|
function errorCatch(err)
|
||||||
|
{
|
||||||
|
// for FF & Chrome
|
||||||
|
if (err.stack) {
|
||||||
|
// only FF
|
||||||
|
if (err.lineNumber) {
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.lineNumber, err.message);
|
||||||
|
} else if (err.line) {
|
||||||
|
// only Safari
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.line, err.message);
|
||||||
|
} else {
|
||||||
|
console.log('ERROR[%s] %s', err.name, err.message);
|
||||||
|
}
|
||||||
|
// stack trace
|
||||||
|
console.log('ERROR[stack] %s', err.stack);
|
||||||
|
} else if (err.number) {
|
||||||
|
// IE
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.number, err.message);
|
||||||
|
console.log('ERROR[description] %s', err.description);
|
||||||
|
} else {
|
||||||
|
// the rest
|
||||||
|
console.log('ERROR[%s] %s', err.name, err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: actionIndicator
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : show or hide the "do" overlay
|
||||||
|
function actionIndicator(loc = '')
|
||||||
|
{
|
||||||
|
if ($('#overlayBox').is(':visible')) {
|
||||||
|
actionIndicatorHide(loc);
|
||||||
|
} else {
|
||||||
|
actionIndicatorShow(loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: actionIndicatorShow/actionIndicatorHide
|
||||||
|
// PARAMS: loc for console log info
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : explicit show/hide for action Indicator
|
||||||
|
// instead of automatically show or hide, do
|
||||||
|
// on command
|
||||||
|
function actionIndicatorShow(loc = '')
|
||||||
|
{
|
||||||
|
console.log('Indicator: SHOW [%s]', loc);
|
||||||
|
$('#indicator').addClass('progress');
|
||||||
|
setCenter('indicator', true, true);
|
||||||
|
$('#indicator').show();
|
||||||
|
overlayBoxShow();
|
||||||
|
}
|
||||||
|
function actionIndicatorHide(loc = '')
|
||||||
|
{
|
||||||
|
console.log('Indicator: HIDE [%s]', loc);
|
||||||
|
$('#indicator').hide();
|
||||||
|
$('#indicator').removeClass('progress');
|
||||||
|
overlayBoxHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: overlayBoxView
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : shows or hides the overlay box
|
||||||
|
function overlayBoxShow()
|
||||||
|
{
|
||||||
|
// check if overlay box exists and if yes set the z-index to 100
|
||||||
|
if ($('#overlayBox').is(':visible')) {
|
||||||
|
$('#overlayBox').css('zIndex', '100');
|
||||||
|
} else {
|
||||||
|
$('#overlayBox').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function overlayBoxHide()
|
||||||
|
{
|
||||||
|
// if the overlay box z-index is 100, do no hide, but set to 98
|
||||||
|
if ($('#overlayBox').css('zIndex') == 100) {
|
||||||
|
$('#overlayBox').css('zIndex', '98');
|
||||||
|
} else {
|
||||||
|
$('#overlayBox').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: setOverlayBox
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : position the overlay block box and shows it
|
||||||
|
function setOverlayBox()
|
||||||
|
{
|
||||||
|
var viewport = document.viewport.getDimensions();
|
||||||
|
$('#overlayBox').setStyle ({
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
});
|
||||||
|
$('#overlayBox').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: ClearCall
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : the abort call, clears the action box and hides it and the overlay box
|
||||||
|
function ClearCall()
|
||||||
|
{
|
||||||
|
$('#actionBox').innerHTML = '';
|
||||||
|
$('#actionBox').hide();
|
||||||
|
$('#overlayBox').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** DOM MANAGEMENT FUNCTIONS
|
||||||
|
// METHOD: cel [create element]
|
||||||
|
// PARAMS: tag: must set tag (div, span, etc)
|
||||||
|
// id: optional set for id, if input, select will be used for name
|
||||||
|
// content: text content inside, is skipped if sub elements exist
|
||||||
|
// css: array for css tags
|
||||||
|
// options: anything else (value, placeholder, OnClick, style)
|
||||||
|
// RETURN: object
|
||||||
|
// DESC : creates object for DOM element creation flow
|
||||||
|
const cel = (tag, id = '', content = '', css = [], options = {}) =>
|
||||||
|
_element = {
|
||||||
|
tag: tag,
|
||||||
|
id: id,
|
||||||
|
name: options.name, // override name if set [name gets ignored in tree build anyway]
|
||||||
|
content: content,
|
||||||
|
css: css,
|
||||||
|
options: options,
|
||||||
|
sub: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// METHOD: ael [attach element]
|
||||||
|
// PARAMS: base: object where to attach/search
|
||||||
|
// attach: the object to be attached
|
||||||
|
// id: optional id, if given search in base for this id and attach there
|
||||||
|
// RETURN: "none", technically there is no return needed
|
||||||
|
// DESC : attach a cel created object to another to create a basic DOM tree
|
||||||
|
function ael(base, attach, id = '')
|
||||||
|
{
|
||||||
|
if (id) {
|
||||||
|
// base id match already
|
||||||
|
if (base.id == id) {
|
||||||
|
base.sub.push(Object.assign({}, attach));
|
||||||
|
} else {
|
||||||
|
// sub check
|
||||||
|
if (isObject(base.sub) && base.sub.length > 0) {
|
||||||
|
for (var i = 0; i < base.sub.length; i ++) {
|
||||||
|
// recursive call to sub element
|
||||||
|
ael(base.sub[i], attach, id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base.sub.push(Object.assign({}, attach));
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: aelx [attach n elements]
|
||||||
|
// PARAMS: base: object to where we attach the elements
|
||||||
|
// attach 1..n: attach directly to the base element those attachments
|
||||||
|
// RETURN: "none", technically there is no return needed
|
||||||
|
// DESC : directly attach n elements to one master base element
|
||||||
|
// this type does not support attach with optional id
|
||||||
|
function aelx(base, ...attach)
|
||||||
|
{
|
||||||
|
for (var i = 0; i < attach.length; i ++) {
|
||||||
|
base.sub.push(Object.assign({}, attach[i]));
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: rel [reset element]
|
||||||
|
// PARAMS: cel created element
|
||||||
|
// RETURN: "none", is self change, but returns base.sub
|
||||||
|
// DESC : resets the sub elements of the base element given
|
||||||
|
const rel = (base) => base.sub = [];
|
||||||
|
|
||||||
|
// METHOD: rcssel [remove a css from the element]
|
||||||
|
// PARAMS: element, style sheet to remove
|
||||||
|
// RETURN: "none", in place because of reference
|
||||||
|
// DESC : searches and removes style from css array
|
||||||
|
function rcssel(_element, css)
|
||||||
|
{
|
||||||
|
let css_index = _element.css.indexOf(css);
|
||||||
|
if (css_index > -1) {
|
||||||
|
_element.css.splice(css_index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: acssel [add css element]
|
||||||
|
// PARAMS: element, style sheet to add
|
||||||
|
// RETURN: "none", in place add because of reference
|
||||||
|
// DESC : adds a new style sheet to the element given
|
||||||
|
function acssel(_element, css)
|
||||||
|
{
|
||||||
|
let css_index = _element.css.indexOf(css);
|
||||||
|
if (css_index == -1) {
|
||||||
|
_element.css.push(css);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: scssel
|
||||||
|
// PARAMS: element, style to remove, style to add
|
||||||
|
// RETURN: "none", in place add because of reference
|
||||||
|
// DESC : removes one css and adds another
|
||||||
|
// is a wrapper around rcssel/acssel
|
||||||
|
function scssel(_element, rcss, acss)
|
||||||
|
{
|
||||||
|
rcssel(_element, rcss);
|
||||||
|
acssel(_element, acss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: phfo [produce html from object]
|
||||||
|
// PARAMS: object tree with dom element declarations
|
||||||
|
// RETURN: HTML string that can be used as innerHTML
|
||||||
|
// DESC : parses the object tree created with cel/ael
|
||||||
|
// and converts it into an HTML string that can
|
||||||
|
// be inserted into the page
|
||||||
|
function phfo(tree)
|
||||||
|
{
|
||||||
|
// holds the elements
|
||||||
|
let content = [];
|
||||||
|
// main part line
|
||||||
|
let line = '<' + tree.tag;
|
||||||
|
let i;
|
||||||
|
// first id, if set
|
||||||
|
if (tree.id) {
|
||||||
|
line += ' id="' + tree.id + '"';
|
||||||
|
// if anything input (input, textarea, select then add name too)
|
||||||
|
if (['input', 'textarea', 'select'].includes(tree.tag)) {
|
||||||
|
line += ' name="' + (tree.name ? tree.name : tree.id) + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// second CSS
|
||||||
|
if (isObject(tree.css) && tree.css.length > 0) {
|
||||||
|
line += ' class="';
|
||||||
|
for (i = 0; i < tree.css.length; i ++) {
|
||||||
|
line += tree.css[i] + ' ';
|
||||||
|
}
|
||||||
|
// strip last space
|
||||||
|
line = line.slice(0, -1);
|
||||||
|
line += '"';
|
||||||
|
}
|
||||||
|
// options is anything key = "data"
|
||||||
|
if (isObject(tree.options)) {
|
||||||
|
// ignores id, name, class as key
|
||||||
|
for (const [key, item] of Object.entries(tree.options)) {
|
||||||
|
if (!['id', 'name', 'class'].includes(key)) {
|
||||||
|
line += ' ' + key + '="' + item + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finish open tag
|
||||||
|
line += '>';
|
||||||
|
// push finished line
|
||||||
|
content.push(line);
|
||||||
|
// dive into sub tree to attach sub nodes
|
||||||
|
// NOTES: we can have content (text) AND sub nodes at the same level
|
||||||
|
// CONTENT (TEXT) takes preference over SUB NODE in order
|
||||||
|
if (isObject(tree.sub) && tree.sub.length > 0) {
|
||||||
|
if (tree.content) {
|
||||||
|
content.push(tree.content);
|
||||||
|
}
|
||||||
|
for (i = 0; i < tree.sub.length; i ++) {
|
||||||
|
content.push(phfo(tree.sub[i]));
|
||||||
|
}
|
||||||
|
} else if (tree.content) {
|
||||||
|
content.push(tree.content);
|
||||||
|
}
|
||||||
|
// if not input close
|
||||||
|
if (tree.tag != 'input') {
|
||||||
|
content.push('</' + tree.tag + '>');
|
||||||
|
}
|
||||||
|
// combine to string
|
||||||
|
return content.join('');
|
||||||
|
}
|
||||||
|
// *** DOM MANAGEMENT FUNCTIONS
|
||||||
|
|
||||||
|
// BLOCK: html wrappers for quickly creating html data blocks
|
||||||
|
// METHOD: html_options
|
||||||
|
// PARAMS: name/id, array for the options, selected item uid
|
||||||
|
// options_only [def false] if this is true, it will not print the select part
|
||||||
|
// return_string [def false]: return as string and not as element
|
||||||
|
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
||||||
|
// RETURN: html with build options block
|
||||||
|
// DESC : creates an select/options drop down block.
|
||||||
|
// the array needs to be key -> value format. key is for the option id and value is for the data output
|
||||||
|
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')
|
||||||
|
{
|
||||||
|
let content = [];
|
||||||
|
let element_select;
|
||||||
|
let element_option;
|
||||||
|
let data_list = []; // for sorted output
|
||||||
|
// set outside select, gets stripped on return if options only is true
|
||||||
|
element_select = cel('select', name);
|
||||||
|
// console.log('Call for %s, options: %s', name, options_only);
|
||||||
|
if (sort == 'keys') {
|
||||||
|
data_list = Object.keys(data).sort();
|
||||||
|
} else if (sort == 'values') {
|
||||||
|
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
||||||
|
} else {
|
||||||
|
data_list = Object.keys(data);
|
||||||
|
}
|
||||||
|
// console.log('ORDER: %s', data_list);
|
||||||
|
// use the previously sorted list
|
||||||
|
// for (const [key, value] of Object.entries(data)) {
|
||||||
|
for (const key of data_list) {
|
||||||
|
let value = data[key];
|
||||||
|
console.log('create [%s] options: key: %s, value: %s', name, key, value);
|
||||||
|
// basic options init
|
||||||
|
let options = {
|
||||||
|
'label': value,
|
||||||
|
'value': key
|
||||||
|
};
|
||||||
|
// add selected if matching
|
||||||
|
if (selected == key) {
|
||||||
|
options.selected = '';
|
||||||
|
}
|
||||||
|
// create the element option
|
||||||
|
element_option = cel('option', '', value, '', options);
|
||||||
|
// attach it to the select element
|
||||||
|
ael(element_select, element_option);
|
||||||
|
}
|
||||||
|
// if with select part, convert to text
|
||||||
|
if (!options_only) {
|
||||||
|
if (return_string) {
|
||||||
|
content.push(phfo(element_select));
|
||||||
|
return content.join('');
|
||||||
|
} else {
|
||||||
|
return element_select;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// strip select part
|
||||||
|
if (return_string) {
|
||||||
|
for (var i = 0; i < element_select.sub.length; i ++) {
|
||||||
|
content.push(phfo(element_select.sub[i]));
|
||||||
|
}
|
||||||
|
return content.join('');
|
||||||
|
} else {
|
||||||
|
return element_select.sub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: html_options_refill
|
||||||
|
// PARAMS: name/id, array of options, sort = ''
|
||||||
|
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : refills a select box with options and keeps the selected
|
||||||
|
function html_options_refill(name, data, sort = '')
|
||||||
|
{
|
||||||
|
let element_option;
|
||||||
|
let option_selected;
|
||||||
|
let data_list = []; // for sorted output
|
||||||
|
// skip if not exists
|
||||||
|
if (document.getElementById(name)) {
|
||||||
|
// console.log('Call for %s, options: %s', name, options_only);
|
||||||
|
if (sort == 'keys') {
|
||||||
|
data_list = Object.keys(data).sort();
|
||||||
|
} else if (sort == 'values') {
|
||||||
|
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
||||||
|
} else {
|
||||||
|
data_list = Object.keys(data);
|
||||||
|
}
|
||||||
|
// first read in existing ones from the options and get the selected one
|
||||||
|
[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {
|
||||||
|
option_selected = elm.value;
|
||||||
|
});
|
||||||
|
document.getElementById(name).innerHTML = '';
|
||||||
|
for (const key of data_list) {
|
||||||
|
let value = data[key];
|
||||||
|
// console.log('add [%s] options: key: %s, value: %s', name, key, value);
|
||||||
|
element_option = document.createElement('option');
|
||||||
|
element_option.label = value;
|
||||||
|
element_option.value = key;
|
||||||
|
element_option.innerHTML = value;
|
||||||
|
document.getElementById(name).appendChild(element_option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: initDatepickr
|
||||||
|
// PARAMS: initial date ID (#)
|
||||||
|
// RETURN: true on ok, false on failure
|
||||||
|
// DESC : inits date pickr which translations for dates (week/month)
|
||||||
|
function initDatepickr(init_date)
|
||||||
|
{
|
||||||
|
if (document.getElementById(init_date)) {
|
||||||
|
datepickr('#' + init_date); // we need to add this so we have it initialized before we can actually change the definitions
|
||||||
|
// dates in japanese
|
||||||
|
datepickr.prototype.l10n.months.shorthand = [__('Jan'), __('Feb'), __('Mar'), __('Apr'), __('May'), __('Jun'), __('Jul'), __('Aug'), __('Sep'), __('Oct'), __('Nov'), __('Dec')];
|
||||||
|
datepickr.prototype.l10n.months.longhand = [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December')];
|
||||||
|
datepickr.prototype.l10n.weekdays.shorthand = [__('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat'), __('Sun')];
|
||||||
|
datepickr.prototype.l10n.weekdays.longhand = [__('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday'), __('Sunday')];
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** MASTER logout call
|
||||||
|
// METHOD: loginLogout
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : submits basic data for form logout
|
||||||
|
function loginLogout()
|
||||||
|
{
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'post';
|
||||||
|
const hiddenField = document.createElement('input');
|
||||||
|
hiddenField.type = 'hidden';
|
||||||
|
hiddenField.name = 'login_logout';
|
||||||
|
hiddenField.value = 'Logout';
|
||||||
|
form.appendChild(hiddenField);
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END */
|
||||||
@@ -1,785 +0,0 @@
|
|||||||
/*
|
|
||||||
code is taken and adapted from dokuwiki
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* jshint esversion: 6 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Some browser detection
|
|
||||||
*/
|
|
||||||
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
|
|
||||||
var is_gecko = ((clientPC.indexOf('gecko') != -1) && (clientPC.indexOf('spoofer') == -1) &&
|
|
||||||
(clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0') == -1));
|
|
||||||
var is_safari = ((clientPC.indexOf('AppleWebKit') != -1) && (clientPC.indexOf('spoofer') == -1));
|
|
||||||
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
|
|
||||||
if (clientPC.indexOf('opera') != -1) {
|
|
||||||
var is_opera = true;
|
|
||||||
var is_opera_preseven = (window.opera && !document.childNodes);
|
|
||||||
var is_opera_seven = (window.opera && document.childNodes);
|
|
||||||
}
|
|
||||||
// debug set
|
|
||||||
var FRONTEND_DEBUG = false;
|
|
||||||
var DEBUG = true;
|
|
||||||
if (!DEBUG) {
|
|
||||||
$($H(window.console)).each(function(w) {
|
|
||||||
window.console[w.key] = function() {};
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: pop
|
|
||||||
// PARAMS: url, window name, features
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : opens a popup window with winNAme and given features (string)
|
|
||||||
function pop(theURL, winName, features) {
|
|
||||||
winName = window.open(theURL, winName, features);
|
|
||||||
winName.focus();
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: expandTA
|
|
||||||
// PARAMS: id
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : automatically resize a text area based on the amount of lines in it
|
|
||||||
function expandTA(ta_id) {
|
|
||||||
var ta;
|
|
||||||
// if a string comes, its a get by id, else use it as an element pass on
|
|
||||||
if (!ta_id.length) {
|
|
||||||
ta = ta_id;
|
|
||||||
} else {
|
|
||||||
ta = document.getElementById(ta_id);
|
|
||||||
}
|
|
||||||
var maxChars = ta.cols;
|
|
||||||
var theRows = ta.value.split("\n");
|
|
||||||
var numNewRows = 0;
|
|
||||||
|
|
||||||
for ( var i = 0; i < theRows.length; i++ ) {
|
|
||||||
if ((theRows[i].length+2) > maxChars) {
|
|
||||||
numNewRows += Math.ceil( (theRows[i].length+2) / maxChars ) ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ta.rows = numNewRows + theRows.length;
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: ShowHideMenu
|
|
||||||
// PARAMS: status -> show or hide
|
|
||||||
// id -> id to work on
|
|
||||||
// RETURN: none
|
|
||||||
// DESC: shows or hides the menu
|
|
||||||
// this is used in some old menu templates
|
|
||||||
function ShowHideMenu(status, id)
|
|
||||||
{
|
|
||||||
if (status == 'show') {
|
|
||||||
document.getElementById(id).style.visibility = 'visible';
|
|
||||||
if (document.getElementById('search_results').innerHTML) {
|
|
||||||
document.getElementById('search_results').style.visibility = 'visible';
|
|
||||||
}
|
|
||||||
} else if (status == 'hide') {
|
|
||||||
document.getElementById(id).style.visibility = 'hidden';
|
|
||||||
if (document.getElementById('search_results').style.visibility == 'visible') {
|
|
||||||
document.getElementById('search_results').style.visibility = 'hidden';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// used in old templates
|
|
||||||
// move element action
|
|
||||||
function mv(id, direction)
|
|
||||||
{
|
|
||||||
document.forms[form_name].action.value = 'move';
|
|
||||||
document.forms[form_name].action_flag.value = direction;
|
|
||||||
document.forms[form_name].action_id.value = id;
|
|
||||||
document.forms[form_name].submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// load element action
|
|
||||||
function le(id)
|
|
||||||
{
|
|
||||||
document.forms[form_name].action.value = 'load';
|
|
||||||
if (load_id) {
|
|
||||||
document.forms[form_name].action_yes.value = confirm('Do you want to load this data?');
|
|
||||||
} else {
|
|
||||||
document.forms[form_name].action_yes.value = 'true';
|
|
||||||
}
|
|
||||||
document.forms[form_name].action_id.value = id;
|
|
||||||
document.forms[form_name].action_menu.value = id;
|
|
||||||
if (document.forms[form_name].action_yes.value == 'true') {
|
|
||||||
document.forms[form_name].submit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: sh
|
|
||||||
// PARAMS: id -> element to hide
|
|
||||||
// showText -> text for the element if shown
|
|
||||||
// hideText -> text for the element if hidden
|
|
||||||
// RETURN: returns true if hidden, or false if not
|
|
||||||
// DESC : hides an element, additional writes 1 (show) or 0 (hide) into <id>Flag field
|
|
||||||
// this needs scriptacolous installed for BlindUp/BlindDown
|
|
||||||
function sh(id, showText, hideText)
|
|
||||||
{
|
|
||||||
flag = id + 'Flag';
|
|
||||||
btn = id + 'Btn';
|
|
||||||
// get status from element (hidden or visible)
|
|
||||||
divStatus = $(id).visible();
|
|
||||||
//console.log('Set flag %s for element %s', divStatus, id);
|
|
||||||
if (divStatus) {
|
|
||||||
// hide the element
|
|
||||||
Effect.BlindUp(id, {duration:0.3});
|
|
||||||
$(flag).value = 0;
|
|
||||||
$(btn).innerHTML = showText;
|
|
||||||
} else if (!divStatus) {
|
|
||||||
// show the element
|
|
||||||
Effect.BlindDown(id, {duration:0.3});
|
|
||||||
$(flag).value = 1;
|
|
||||||
$(btn).innerHTML = hideText;
|
|
||||||
}
|
|
||||||
// return current button status
|
|
||||||
return divStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: getWindowSize
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: array with width/height
|
|
||||||
// DESC : wrapper to get the real window size for the current browser window
|
|
||||||
function getWindowSize()
|
|
||||||
{
|
|
||||||
var width, height;
|
|
||||||
width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
|
|
||||||
height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
|
|
||||||
return {
|
|
||||||
width: width,
|
|
||||||
height: height
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: getScrollOffset
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: array with x/y px
|
|
||||||
// DESC : wrapper to get the correct scroll offset
|
|
||||||
function getScrollOffset()
|
|
||||||
{
|
|
||||||
var left, top;
|
|
||||||
left = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
|
|
||||||
top = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
|
|
||||||
return {
|
|
||||||
left: left,
|
|
||||||
top: top
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: setCenter
|
|
||||||
// PARAMS: id to set center
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : centers div to current window size middle
|
|
||||||
function setCenter(id, left, top)
|
|
||||||
{
|
|
||||||
// get size of id
|
|
||||||
var dimensions = $(id).getDimensions();
|
|
||||||
var type = $(id).getStyle('position');
|
|
||||||
var viewport = getWindowSize();
|
|
||||||
var offset = getScrollOffset();
|
|
||||||
|
|
||||||
// console.log('Id %s, type: %s, dimensions %s x %s, viewport %s x %s', id, $(id).getStyle('position'), dimensions.width, dimensions.height, viewport.width, viewport.height);
|
|
||||||
// console.log('Scrolloffset left: %s, top: %s', offset.left, offset.top);
|
|
||||||
// console.log('Left: %s, Top: %s (%s)', parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left), parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top), parseInt((viewport.height / 2) - (dimensions.height / 2)));
|
|
||||||
if (left) {
|
|
||||||
$(id).setStyle ({
|
|
||||||
left: parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left) + 'px'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (top) {
|
|
||||||
// if we have fixed, we do not add the offset, else it moves out of the screen
|
|
||||||
var top_pos = type == 'fixed' ? parseInt((viewport.height / 2) - (dimensions.height / 2)) : parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top);
|
|
||||||
$(id).setStyle ({
|
|
||||||
top: top_pos + 'px'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: goToPos()
|
|
||||||
// PARAMS: element, offset (default 0)
|
|
||||||
// RETURN: none
|
|
||||||
// DESC: goes to an element id position
|
|
||||||
function goToPos(element, offset = 0)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if ($(element))
|
|
||||||
{
|
|
||||||
// get the element pos
|
|
||||||
var pos = $(element).cumulativeOffset();
|
|
||||||
// if not top element and no offset given, set auto offset for top element
|
|
||||||
// also compensate by -40 for some offset calc issue and not have it too much to the header
|
|
||||||
if (pos.top != 0 && offset == 0) {
|
|
||||||
offset = ($(GL_main_content_div).style.paddingTop.replace('px', '') * -1) - 40;
|
|
||||||
}
|
|
||||||
//console.log('Scroll to: %s, Offset: %s [%s], PT: %s', element, offset, $('pbsMainContent').style.paddingTop.replace('px', ''), pos.top);
|
|
||||||
window.scrollTo(pos.left, pos.top + offset);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
errorCatch(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: __
|
|
||||||
// PARAMS: text
|
|
||||||
// RETURN: translated text (based on PHP selected language)
|
|
||||||
// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty)
|
|
||||||
function __(string)
|
|
||||||
{
|
|
||||||
if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) {
|
|
||||||
return i18n[string];
|
|
||||||
} else {
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: string.format
|
|
||||||
// PARAMS: any, for string format
|
|
||||||
// RETURN: formatted string
|
|
||||||
// DESC : simple sprintf formater for replace
|
|
||||||
// "{0} is cool, {1} is not".format("Alpha", "Beta");
|
|
||||||
// First, checks if it isn't implemented yet.
|
|
||||||
if (!String.prototype.format) {
|
|
||||||
String.prototype.format = function()
|
|
||||||
{
|
|
||||||
var args = arguments;
|
|
||||||
return this.replace(/{(\d+)}/g, function(match, number)
|
|
||||||
{
|
|
||||||
return typeof args[number] != 'undefined' ?
|
|
||||||
args[number] :
|
|
||||||
match
|
|
||||||
;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: numberWithCommas
|
|
||||||
// PARAMS: number
|
|
||||||
// RETURN: formatted with , in thousands
|
|
||||||
// DESC : formats flat number 123456 to 123,456
|
|
||||||
const numberWithCommas = (x) => {
|
|
||||||
var parts = x.toString().split(".");
|
|
||||||
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
||||||
return parts.join(".");
|
|
||||||
};
|
|
||||||
|
|
||||||
// METHOD:
|
|
||||||
// PARAMS: string
|
|
||||||
// RETURN: string with <br>
|
|
||||||
// DESC : converts line breaks to br
|
|
||||||
function convertLBtoBR(string)
|
|
||||||
{
|
|
||||||
return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.escapeHTML) {
|
|
||||||
String.prototype.escapeHTML = function() {
|
|
||||||
return this.replace(/[&<>"'\/]/g, function (s) {
|
|
||||||
var entityMap = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': '"',
|
|
||||||
"'": ''',
|
|
||||||
"/": '/'
|
|
||||||
};
|
|
||||||
|
|
||||||
return entityMap[s];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!String.prototype.unescapeHTML) {
|
|
||||||
String.prototype.unescapeHTML = function() {
|
|
||||||
return this.replace(/&[#\w]+;/g, function (s) {
|
|
||||||
var entityMap = {
|
|
||||||
"&": "&",
|
|
||||||
"<": "<",
|
|
||||||
">": ">",
|
|
||||||
'"': '"',
|
|
||||||
''': "'",
|
|
||||||
'/': "/"
|
|
||||||
};
|
|
||||||
|
|
||||||
return entityMap[s];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: getTimestamp
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: timestamp (in milliseconds)
|
|
||||||
// DESC : returns current timestamp (unix timestamp)
|
|
||||||
function getTimestamp()
|
|
||||||
{
|
|
||||||
let date = new Date();
|
|
||||||
return date.getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: isObject
|
|
||||||
// PARAMS: possible object
|
|
||||||
// RETURN: true/false if it is an object or not
|
|
||||||
function isObject(val) {
|
|
||||||
if (val === null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return ((typeof val === 'function') || (typeof val === 'object'));
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: exists
|
|
||||||
// PARAMS: uid
|
|
||||||
// RETURN: true/false
|
|
||||||
// DESC : checks if a DOM element actually exists
|
|
||||||
const exists = (id) => $(id) ? true : false;
|
|
||||||
|
|
||||||
// METHOD: formatBytes
|
|
||||||
// PARAMS: bytes in int
|
|
||||||
// RETURN: string in GB/MB/KB
|
|
||||||
// DESC : converts a int number into bytes with prefix in two decimals precision
|
|
||||||
// currently precision is fixed, if dynamic needs check for max/min precision
|
|
||||||
function formatBytes(bytes)
|
|
||||||
{
|
|
||||||
var i = -1;
|
|
||||||
do {
|
|
||||||
bytes = bytes / 1024;
|
|
||||||
i++;
|
|
||||||
} while (bytes > 99);
|
|
||||||
|
|
||||||
return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: goToPos()
|
|
||||||
// PARAMS: element, offset (default 0)
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : goes to an element id position
|
|
||||||
function goToPos(element, offset = 0)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
if ($(element))
|
|
||||||
{
|
|
||||||
// get the element pos
|
|
||||||
var pos = $(element).cumulativeOffset();
|
|
||||||
// if not top element and no offset given, set auto offset for top element
|
|
||||||
// also compensate by -40 for some offset calc issue and not have it too much to the header
|
|
||||||
if (pos.top != 0 && offset == 0) {
|
|
||||||
offset = ($(GL_main_content_div).style.paddingTop.replace('px', '') * -1) - 40;
|
|
||||||
}
|
|
||||||
//console.log('Scroll to: %s, Offset: %s [%s], PT: %s', element, offset, $('pbsMainContent').style.paddingTop.replace('px', ''), pos.top);
|
|
||||||
window.scrollTo(pos.left, pos.top + offset);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
errorCatch(err);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: errorCatch
|
|
||||||
// PARAMS: err (error from try/catch
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : prints out error messages based on data available from the browser
|
|
||||||
function errorCatch(err)
|
|
||||||
{
|
|
||||||
// for FF & Chrome
|
|
||||||
if (err.stack) {
|
|
||||||
// only FF
|
|
||||||
if (err.lineNumber) {
|
|
||||||
console.log('ERROR[%s:%s] %s', err.name, err.lineNumber, err.message);
|
|
||||||
} else if (err.line) {
|
|
||||||
// only Safari
|
|
||||||
console.log('ERROR[%s:%s] %s', err.name, err.line, err.message);
|
|
||||||
} else {
|
|
||||||
console.log('ERROR[%s] %s', err.name, err.message);
|
|
||||||
}
|
|
||||||
// stack trace
|
|
||||||
console.log('ERROR[stack] %s', err.stack);
|
|
||||||
} else if (err.number) {
|
|
||||||
// IE
|
|
||||||
console.log('ERROR[%s:%s] %s', err.name, err.number, err.message);
|
|
||||||
console.log('ERROR[description] %s', err.description);
|
|
||||||
} else {
|
|
||||||
// the rest
|
|
||||||
console.log('ERROR[%s] %s', err.name, err.message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: actionIndicator
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : show or hide the "do" overlay
|
|
||||||
function actionIndicator(loc = '')
|
|
||||||
{
|
|
||||||
if ($('overlayBox').visible()) {
|
|
||||||
actionIndicatorHide(loc);
|
|
||||||
} else {
|
|
||||||
actionIndicatorShow(loc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: actionIndicatorShow/actionIndicatorHide
|
|
||||||
// PARAMS: loc for console log info
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : explicit show/hide for action Indicator
|
|
||||||
// instead of automatically show or hide, do
|
|
||||||
// on command
|
|
||||||
function actionIndicatorShow(loc = '')
|
|
||||||
{
|
|
||||||
console.log('Indicator: SHOW [%s]', loc);
|
|
||||||
$('indicator').addClassName('progress');
|
|
||||||
setCenter('indicator', true, true);
|
|
||||||
$('indicator').show();
|
|
||||||
overlayBoxShow();
|
|
||||||
}
|
|
||||||
function actionIndicatorHide(loc = '')
|
|
||||||
{
|
|
||||||
console.log('Indicator: HIDE [%s]', loc);
|
|
||||||
$('indicator').hide();
|
|
||||||
$('indicator').removeClassName('progress');
|
|
||||||
overlayBoxHide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: overlayBoxView
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : shows or hides the overlay box
|
|
||||||
function overlayBoxShow()
|
|
||||||
{
|
|
||||||
// check if overlay box exists and if yes set the z-index to 100
|
|
||||||
if ($('overlayBox').visible()) {
|
|
||||||
$('overlayBox').style.zIndex = "100";
|
|
||||||
} else {
|
|
||||||
$('overlayBox').show();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function overlayBoxHide()
|
|
||||||
{
|
|
||||||
// if the overlay box z-index is 100, do no hide, but set to 98
|
|
||||||
if ($('overlayBox').style.zIndex == 100) {
|
|
||||||
$('overlayBox').style.zIndex = "98";
|
|
||||||
} else {
|
|
||||||
$('overlayBox').hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: setOverlayBox
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : position the overlay block box and shows it
|
|
||||||
function setOverlayBox()
|
|
||||||
{
|
|
||||||
var viewport = document.viewport.getDimensions();
|
|
||||||
$('overlayBox').setStyle ({
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
});
|
|
||||||
$('overlayBox').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: ClearCall
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : the abort call, clears the action box and hides it and the overlay box
|
|
||||||
function ClearCall()
|
|
||||||
{
|
|
||||||
$('actionBox').innerHTML = '';
|
|
||||||
$('actionBox').hide();
|
|
||||||
$('overlayBox').hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** DOM MANAGEMENT FUNCTIONS
|
|
||||||
// METHOD: cel [create element]
|
|
||||||
// PARAMS: tag: must set tag (div, span, etc)
|
|
||||||
// id: optional set for id, if input, select will be used for name
|
|
||||||
// content: text content inside, is skipped if sub elements exist
|
|
||||||
// css: array for css tags
|
|
||||||
// options: anything else (value, placeholder, OnClick, style)
|
|
||||||
// RETURN: object
|
|
||||||
// DESC : creates object for DOM element creation flow
|
|
||||||
const cel = (tag, id = '', content = '', css = [], options = {}) =>
|
|
||||||
_element = {
|
|
||||||
tag: tag,
|
|
||||||
id: id,
|
|
||||||
name: options.name, // override name if set [name gets ignored in tree build anyway]
|
|
||||||
content: content,
|
|
||||||
css: css,
|
|
||||||
options: options,
|
|
||||||
sub: []
|
|
||||||
};
|
|
||||||
|
|
||||||
// METHOD: ael [attach element]
|
|
||||||
// PARAMS: base: object where to attach/search
|
|
||||||
// attach: the object to be attached
|
|
||||||
// id: optional id, if given search in base for this id and attach there
|
|
||||||
// RETURN: "none", technically there is no return needed
|
|
||||||
// DESC : attach a cel created object to another to create a basic DOM tree
|
|
||||||
function ael(base, attach, id = '')
|
|
||||||
{
|
|
||||||
if (id) {
|
|
||||||
// base id match already
|
|
||||||
if (base.id == id) {
|
|
||||||
base.sub.push(Object.assign({}, attach));
|
|
||||||
} else {
|
|
||||||
// sub check
|
|
||||||
if (base.sub.length > 0) {
|
|
||||||
base.sub.each(function(t) {
|
|
||||||
// recursive call to sub element
|
|
||||||
ael(t, attach, id);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
base.sub.push(Object.assign({}, attach));
|
|
||||||
}
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: aelx [attach n elements]
|
|
||||||
// PARAMS: base: object to where we attach the elements
|
|
||||||
// attach 1..n: attach directly to the base element those attachments
|
|
||||||
// RETURN: "none", technically there is no return needed
|
|
||||||
// DESC : directly attach n elements to one master base element
|
|
||||||
// this type does not support attach with optional id
|
|
||||||
function aelx(base, ...attach)
|
|
||||||
{
|
|
||||||
attach.each(function(t) {
|
|
||||||
base.sub.push(Object.assign({}, t));
|
|
||||||
});
|
|
||||||
return base;
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: rel [reset element]
|
|
||||||
// PARAMS: cel created element
|
|
||||||
// RETURN: "none", is self change, but returns base.sub
|
|
||||||
// DESC : resets the sub elements of the base element given
|
|
||||||
const rel = (base) => base.sub = [];
|
|
||||||
|
|
||||||
// METHOD: rcssel [remove a css from the element]
|
|
||||||
// PARAMS: element, style sheet to remove
|
|
||||||
// RETURN: "none", in place because of reference
|
|
||||||
// DESC : searches and removes style from css array
|
|
||||||
function rcssel(_element, css)
|
|
||||||
{
|
|
||||||
let css_index = _element.css.indexOf(css);
|
|
||||||
if (css_index > -1) {
|
|
||||||
_element.css.splice(css_index, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: acssel [add css element]
|
|
||||||
// PARAMS: element, style sheet to add
|
|
||||||
// RETURN: "none", in place add because of reference
|
|
||||||
// DESC : adds a new style sheet to the element given
|
|
||||||
function acssel(_element, css)
|
|
||||||
{
|
|
||||||
let css_index = _element.css.indexOf(css);
|
|
||||||
if (css_index == -1) {
|
|
||||||
_element.css.push(css);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: scssel
|
|
||||||
// PARAMS: element, style to remove, style to add
|
|
||||||
// RETURN: "none", in place add because of reference
|
|
||||||
// DESC : removes one css and adds another
|
|
||||||
// is a wrapper around rcssel/acssel
|
|
||||||
function scssel(_element, rcss, acss)
|
|
||||||
{
|
|
||||||
rcssel(_element, rcss);
|
|
||||||
acssel(_element, acss);
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: phfo [produce html from object]
|
|
||||||
// PARAMS: object tree with dom element declarations
|
|
||||||
// RETURN: HTML string that can be used as innerHTML
|
|
||||||
// DESC : parses the object tree created with cel/ael
|
|
||||||
// and converts it into an HTML string that can
|
|
||||||
// be inserted into the page
|
|
||||||
function phfo(tree)
|
|
||||||
{
|
|
||||||
// holds the elements
|
|
||||||
let content = [];
|
|
||||||
// main part line
|
|
||||||
let line = '<' + tree.tag;
|
|
||||||
// first id, if set
|
|
||||||
if (tree.id) {
|
|
||||||
line += ' id="' + tree.id + '"';
|
|
||||||
// if anything input (input, textarea, select then add name too)
|
|
||||||
if (['input', 'textarea', 'select'].includes(tree.tag)) {
|
|
||||||
line += ' name="' + (tree.name ? tree.name : tree.id) + '"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// second CSS
|
|
||||||
if (tree.css.length > 0) {
|
|
||||||
line += ' class="';
|
|
||||||
tree.css.each(function(t) {
|
|
||||||
line += t + ' ';
|
|
||||||
});
|
|
||||||
// strip last space
|
|
||||||
line = line.slice(0, -1);
|
|
||||||
line += '"';
|
|
||||||
}
|
|
||||||
// options is anything key = "data"
|
|
||||||
if (tree.options) {
|
|
||||||
// ignores id, name, class as key
|
|
||||||
for (const [key, item] of Object.entries(tree.options)) {
|
|
||||||
if (!['id', 'name', 'class'].includes(key)) {
|
|
||||||
line += ' ' + key + '="' + item + '"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// finish open tag
|
|
||||||
line += '>';
|
|
||||||
// push finished line
|
|
||||||
content.push(line);
|
|
||||||
// dive into sub tree to attach sub nodes
|
|
||||||
// NOTES: we can have content (text) AND sub nodes at the same level
|
|
||||||
// CONTENT (TEXT) takes preference over SUB NODE in order
|
|
||||||
if (tree.sub.length > 0) {
|
|
||||||
if (tree.content) {
|
|
||||||
content.push(tree.content);
|
|
||||||
}
|
|
||||||
tree.sub.each(function(t) {
|
|
||||||
content.push(phfo(t));
|
|
||||||
});
|
|
||||||
} else if (tree.content) {
|
|
||||||
content.push(tree.content);
|
|
||||||
}
|
|
||||||
// if not input close
|
|
||||||
if (tree.tag != 'input') {
|
|
||||||
content.push('</' + tree.tag + '>');
|
|
||||||
}
|
|
||||||
// combine to string
|
|
||||||
return content.join('');
|
|
||||||
}
|
|
||||||
// *** DOM MANAGEMENT FUNCTIONS
|
|
||||||
|
|
||||||
// BLOCK: html wrappers for quickly creating html data blocks
|
|
||||||
// METHOD: html_options
|
|
||||||
// PARAMS: name/id, array for the options, selected item uid
|
|
||||||
// options_only [def false] if this is true, it will not print the select part
|
|
||||||
// return_string [def false]: return as string and not as element
|
|
||||||
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
|
||||||
// RETURN: html with build options block
|
|
||||||
// DESC : creates an select/options drop down block.
|
|
||||||
// the array needs to be key -> value format. key is for the option id and value is for the data output
|
|
||||||
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')
|
|
||||||
{
|
|
||||||
let content = [];
|
|
||||||
let element_select;
|
|
||||||
let element_option;
|
|
||||||
let data_list = []; // for sorted output
|
|
||||||
// set outside select, gets stripped on return if options only is true
|
|
||||||
element_select = cel('select', name);
|
|
||||||
// console.log('Call for %s, options: %s', name, options_only);
|
|
||||||
if (sort == 'keys') {
|
|
||||||
data_list = Object.keys(data).sort();
|
|
||||||
} else if (sort == 'values') {
|
|
||||||
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
|
||||||
} else {
|
|
||||||
data_list = Object.keys(data);
|
|
||||||
}
|
|
||||||
// console.log('ORDER: %s', data_list);
|
|
||||||
// use the previously sorted list
|
|
||||||
// for (const [key, value] of Object.entries(data)) {
|
|
||||||
for (const key of data_list) {
|
|
||||||
let value = data[key];
|
|
||||||
console.log('create [%s] options: key: %s, value: %s', name, key, value);
|
|
||||||
// basic options init
|
|
||||||
let options = {
|
|
||||||
'label': value,
|
|
||||||
'value': key
|
|
||||||
};
|
|
||||||
// add selected if matching
|
|
||||||
if (selected == key) {
|
|
||||||
options.selected = '';
|
|
||||||
}
|
|
||||||
// create the element option
|
|
||||||
element_option = cel('option', '', value, '', options);
|
|
||||||
// attach it to the select element
|
|
||||||
ael(element_select, element_option);
|
|
||||||
}
|
|
||||||
// if with select part, convert to text
|
|
||||||
if (!options_only) {
|
|
||||||
if (return_string) {
|
|
||||||
content.push(phfo(element_select));
|
|
||||||
return content.join('');
|
|
||||||
} else {
|
|
||||||
return element_select;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// strip select part
|
|
||||||
if (return_string) {
|
|
||||||
element_select.sub.each(function(t) {
|
|
||||||
content.push(phfo(t));
|
|
||||||
});
|
|
||||||
return content.join('');
|
|
||||||
} else {
|
|
||||||
return element_select.sub;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: html_options_refill
|
|
||||||
// PARAMS: name/id, array of options, sort = ''
|
|
||||||
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : refills a select box with options and keeps the selected
|
|
||||||
function html_options_refill(name, data, sort = '')
|
|
||||||
{
|
|
||||||
let element_option;
|
|
||||||
let option_selected;
|
|
||||||
let data_list = []; // for sorted output
|
|
||||||
// skip if not exists
|
|
||||||
if ($(name)) {
|
|
||||||
// console.log('Call for %s, options: %s', name, options_only);
|
|
||||||
if (sort == 'keys') {
|
|
||||||
data_list = Object.keys(data).sort();
|
|
||||||
} else if (sort == 'values') {
|
|
||||||
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
|
||||||
} else {
|
|
||||||
data_list = Object.keys(data);
|
|
||||||
}
|
|
||||||
// first read in existing ones from the options and get the selected one
|
|
||||||
[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {
|
|
||||||
option_selected = elm.value;
|
|
||||||
});
|
|
||||||
$(name).innerHTML = '';
|
|
||||||
for (const key of data_list) {
|
|
||||||
let value = data[key];
|
|
||||||
// console.log('add [%s] options: key: %s, value: %s', name, key, value);
|
|
||||||
element_option = document.createElement('option');
|
|
||||||
element_option.label = value;
|
|
||||||
element_option.value = key;
|
|
||||||
element_option.innerHTML = value;
|
|
||||||
$(name).appendChild(element_option);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// METHOD: initDatepickr
|
|
||||||
// PARAMS: initial date ID (#)
|
|
||||||
// RETURN: true on ok, false on failure
|
|
||||||
// DESC : inits date pickr which translations for dates (week/month)
|
|
||||||
function initDatepickr(init_date)
|
|
||||||
{
|
|
||||||
if ($(init_date)) {
|
|
||||||
datepickr('#' + init_date); // we need to add this so we have it initialized before we can actually change the definitions
|
|
||||||
// dates in japanese
|
|
||||||
datepickr.prototype.l10n.months.shorthand = [__('Jan'), __('Feb'), __('Mar'), __('Apr'), __('May'), __('Jun'), __('Jul'), __('Aug'), __('Sep'), __('Oct'), __('Nov'), __('Dec')];
|
|
||||||
datepickr.prototype.l10n.months.longhand = [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December')];
|
|
||||||
datepickr.prototype.l10n.weekdays.shorthand = [__('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat'), __('Sun')];
|
|
||||||
datepickr.prototype.l10n.weekdays.longhand = [__('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday'), __('Sunday')];
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// *** MASTER logout call
|
|
||||||
// METHOD: loginLogout
|
|
||||||
// PARAMS: none
|
|
||||||
// RETURN: none
|
|
||||||
// DESC : submits basic data for form logout
|
|
||||||
function loginLogout()
|
|
||||||
{
|
|
||||||
$('login_logout').value = 'Logout';
|
|
||||||
$(form_name).submit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* END */
|
|
||||||
1
www/layout/admin/default/javascript/edit.js
Symbolic link
1
www/layout/admin/default/javascript/edit.js
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
edit.pt.js
|
||||||
753
www/layout/admin/default/javascript/edit.pt.js
Normal file
753
www/layout/admin/default/javascript/edit.pt.js
Normal file
@@ -0,0 +1,753 @@
|
|||||||
|
/* general edit javascript */
|
||||||
|
|
||||||
|
/* jshint esversion: 6 */
|
||||||
|
|
||||||
|
// debug set
|
||||||
|
/*var FRONTEND_DEBUG = false;
|
||||||
|
var DEBUG = true;
|
||||||
|
if (!DEBUG) {
|
||||||
|
$($H(window.console)).each(function(w) {
|
||||||
|
window.console[w.key] = function() {};
|
||||||
|
});
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// METHOD: pop
|
||||||
|
// PARAMS: url, window name, features
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : opens a popup window with winNAme and given features (string)
|
||||||
|
function pop(theURL, winName, features) {
|
||||||
|
winName = window.open(theURL, winName, features);
|
||||||
|
winName.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: expandTA
|
||||||
|
// PARAMS: id
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : automatically resize a text area based on the amount of lines in it
|
||||||
|
function expandTA(ta_id) {
|
||||||
|
var ta;
|
||||||
|
// if a string comes, its a get by id, else use it as an element pass on
|
||||||
|
if (!ta_id.length) {
|
||||||
|
ta = ta_id;
|
||||||
|
} else {
|
||||||
|
ta = document.getElementById(ta_id);
|
||||||
|
}
|
||||||
|
var maxChars = ta.cols;
|
||||||
|
var theRows = ta.value.split("\n");
|
||||||
|
var numNewRows = 0;
|
||||||
|
|
||||||
|
for ( var i = 0; i < theRows.length; i++ ) {
|
||||||
|
if ((theRows[i].length+2) > maxChars) {
|
||||||
|
numNewRows += Math.ceil( (theRows[i].length+2) / maxChars ) ;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ta.rows = numNewRows + theRows.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: ShowHideMenu
|
||||||
|
// PARAMS: status -> show or hide
|
||||||
|
// id -> id to work on
|
||||||
|
// RETURN: none
|
||||||
|
// DESC: shows or hides the menu
|
||||||
|
// this is used in some old menu templates
|
||||||
|
function ShowHideMenu(status, id)
|
||||||
|
{
|
||||||
|
if (status == 'show') {
|
||||||
|
document.getElementById(id).style.visibility = 'visible';
|
||||||
|
if (document.getElementById('search_results').innerHTML) {
|
||||||
|
document.getElementById('search_results').style.visibility = 'visible';
|
||||||
|
}
|
||||||
|
} else if (status == 'hide') {
|
||||||
|
document.getElementById(id).style.visibility = 'hidden';
|
||||||
|
if (document.getElementById('search_results').style.visibility == 'visible') {
|
||||||
|
document.getElementById('search_results').style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// used in old templates
|
||||||
|
// move element action
|
||||||
|
function mv(id, direction)
|
||||||
|
{
|
||||||
|
document.forms[form_name].action.value = 'move';
|
||||||
|
document.forms[form_name].action_flag.value = direction;
|
||||||
|
document.forms[form_name].action_id.value = id;
|
||||||
|
document.forms[form_name].submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// load element action
|
||||||
|
function le(id)
|
||||||
|
{
|
||||||
|
document.forms[form_name].action.value = 'load';
|
||||||
|
if (load_id) {
|
||||||
|
document.forms[form_name].action_yes.value = confirm('Do you want to load this data?');
|
||||||
|
} else {
|
||||||
|
document.forms[form_name].action_yes.value = 'true';
|
||||||
|
}
|
||||||
|
document.forms[form_name].action_id.value = id;
|
||||||
|
document.forms[form_name].action_menu.value = id;
|
||||||
|
if (document.forms[form_name].action_yes.value == 'true') {
|
||||||
|
document.forms[form_name].submit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: sh
|
||||||
|
// PARAMS: id -> element to hide
|
||||||
|
// showText -> text for the element if shown
|
||||||
|
// hideText -> text for the element if hidden
|
||||||
|
// RETURN: returns true if hidden, or false if not
|
||||||
|
// DESC : hides an element, additional writes 1 (show) or 0 (hide) into <id>Flag field
|
||||||
|
// this needs scriptacolous installed for BlindUp/BlindDown
|
||||||
|
function sh(id, showText, hideText)
|
||||||
|
{
|
||||||
|
flag = id + 'Flag';
|
||||||
|
btn = id + 'Btn';
|
||||||
|
// get status from element (hidden or visible)
|
||||||
|
divStatus = $(id).visible();
|
||||||
|
//console.log('Set flag %s for element %s', divStatus, id);
|
||||||
|
if (divStatus) {
|
||||||
|
// hide the element
|
||||||
|
Effect.BlindUp(id, {duration:0.3});
|
||||||
|
$(flag).value = 0;
|
||||||
|
$(btn).innerHTML = showText;
|
||||||
|
} else if (!divStatus) {
|
||||||
|
// show the element
|
||||||
|
Effect.BlindDown(id, {duration:0.3});
|
||||||
|
$(flag).value = 1;
|
||||||
|
$(btn).innerHTML = hideText;
|
||||||
|
}
|
||||||
|
// return current button status
|
||||||
|
return divStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getWindowSize
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: array with width/height
|
||||||
|
// DESC : wrapper to get the real window size for the current browser window
|
||||||
|
function getWindowSize()
|
||||||
|
{
|
||||||
|
var width, height;
|
||||||
|
width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
|
||||||
|
height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
|
||||||
|
return {
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getScrollOffset
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: array with x/y px
|
||||||
|
// DESC : wrapper to get the correct scroll offset
|
||||||
|
function getScrollOffset()
|
||||||
|
{
|
||||||
|
var left, top;
|
||||||
|
left = window.pageXOffset || (window.document.documentElement.scrollLeft || window.document.body.scrollLeft);
|
||||||
|
top = window.pageYOffset || (window.document.documentElement.scrollTop || window.document.body.scrollTop);
|
||||||
|
return {
|
||||||
|
left: left,
|
||||||
|
top: top
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: setCenter
|
||||||
|
// PARAMS: id to set center
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : centers div to current window size middle
|
||||||
|
function setCenter(id, left, top)
|
||||||
|
{
|
||||||
|
// get size of id
|
||||||
|
var dimensions = $(id).getDimensions();
|
||||||
|
var type = $(id).getStyle('position');
|
||||||
|
var viewport = getWindowSize();
|
||||||
|
var offset = getScrollOffset();
|
||||||
|
|
||||||
|
console.log('Id %s, type: %s, dimensions %s x %s, viewport %s x %s', id, type, dimensions.width, dimensions.height, viewport.width, viewport.height);
|
||||||
|
// console.log('Scrolloffset left: %s, top: %s', offset.left, offset.top);
|
||||||
|
// console.log('Left: %s, Top: %s (%s)', parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left), parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top), parseInt((viewport.height / 2) - (dimensions.height / 2)));
|
||||||
|
if (left) {
|
||||||
|
$(id).setStyle ({
|
||||||
|
left: parseInt((viewport.width / 2) - (dimensions.width / 2) + offset.left) + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (top) {
|
||||||
|
// if we have fixed, we do not add the offset, else it moves out of the screen
|
||||||
|
var top_pos = type == 'fixed' ? parseInt((viewport.height / 2) - (dimensions.height / 2)) : parseInt((viewport.height / 2) - (dimensions.height / 2) + offset.top);
|
||||||
|
$(id).setStyle ({
|
||||||
|
top: top_pos + 'px'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: goToPos()
|
||||||
|
// PARAMS: element, offset (default 0)
|
||||||
|
// RETURN: none
|
||||||
|
// DESC: goes to an element id position
|
||||||
|
function goToPos(element, offset = 0)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
if ($(element))
|
||||||
|
{
|
||||||
|
// get the element pos
|
||||||
|
var pos = $(element).cumulativeOffset();
|
||||||
|
// if not top element and no offset given, set auto offset for top element
|
||||||
|
// also compensate by -40 for some offset calc issue and not have it too much to the header
|
||||||
|
if (pos.top != 0 && offset == 0) {
|
||||||
|
offset = ($(GL_main_content_div).style.paddingTop.replace('px', '') * -1) - 40;
|
||||||
|
}
|
||||||
|
//console.log('Scroll to: %s, Offset: %s [%s], PT: %s', element, offset, $('pbsMainContent').style.paddingTop.replace('px', ''), pos.top);
|
||||||
|
window.scrollTo(pos.left, pos.top + offset);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
errorCatch(err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: __
|
||||||
|
// PARAMS: text
|
||||||
|
// RETURN: translated text (based on PHP selected language)
|
||||||
|
// DESC : uses the i18n array created in the translation template, that is filled from gettext in PHP (Smarty)
|
||||||
|
function __(string)
|
||||||
|
{
|
||||||
|
if (typeof i18n !== 'undefined' && isObject(i18n) && i18n[string]) {
|
||||||
|
return i18n[string];
|
||||||
|
} else {
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: string.format
|
||||||
|
// PARAMS: any, for string format
|
||||||
|
// RETURN: formatted string
|
||||||
|
// DESC : simple sprintf formater for replace
|
||||||
|
// "{0} is cool, {1} is not".format("Alpha", "Beta");
|
||||||
|
// First, checks if it isn't implemented yet.
|
||||||
|
if (!String.prototype.format) {
|
||||||
|
String.prototype.format = function()
|
||||||
|
{
|
||||||
|
var args = arguments;
|
||||||
|
return this.replace(/{(\d+)}/g, function(match, number)
|
||||||
|
{
|
||||||
|
return typeof args[number] != 'undefined' ?
|
||||||
|
args[number] :
|
||||||
|
match
|
||||||
|
;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: numberWithCommas
|
||||||
|
// PARAMS: number
|
||||||
|
// RETURN: formatted with , in thousands
|
||||||
|
// DESC : formats flat number 123456 to 123,456
|
||||||
|
const numberWithCommas = (x) => {
|
||||||
|
var parts = x.toString().split(".");
|
||||||
|
parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
||||||
|
return parts.join(".");
|
||||||
|
};
|
||||||
|
|
||||||
|
// METHOD:
|
||||||
|
// PARAMS: string
|
||||||
|
// RETURN: string with <br>
|
||||||
|
// DESC : converts line breaks to br
|
||||||
|
function convertLBtoBR(string)
|
||||||
|
{
|
||||||
|
return string.replace(/(?:\r\n|\r|\n)/g, '<br>');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.prototype.escapeHTML) {
|
||||||
|
String.prototype.escapeHTML = function() {
|
||||||
|
return this.replace(/[&<>"'\/]/g, function (s) {
|
||||||
|
var entityMap = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': '"',
|
||||||
|
"'": ''',
|
||||||
|
"/": '/'
|
||||||
|
};
|
||||||
|
|
||||||
|
return entityMap[s];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!String.prototype.unescapeHTML) {
|
||||||
|
String.prototype.unescapeHTML = function() {
|
||||||
|
return this.replace(/&[#\w]+;/g, function (s) {
|
||||||
|
var entityMap = {
|
||||||
|
"&": "&",
|
||||||
|
"<": "<",
|
||||||
|
">": ">",
|
||||||
|
'"': '"',
|
||||||
|
''': "'",
|
||||||
|
'/': "/"
|
||||||
|
};
|
||||||
|
|
||||||
|
return entityMap[s];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: getTimestamp
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: timestamp (in milliseconds)
|
||||||
|
// DESC : returns current timestamp (unix timestamp)
|
||||||
|
function getTimestamp()
|
||||||
|
{
|
||||||
|
let date = new Date();
|
||||||
|
return date.getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: isObject
|
||||||
|
// PARAMS: possible object
|
||||||
|
// RETURN: true/false if it is an object or not
|
||||||
|
function isObject(val) {
|
||||||
|
if (val === null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return ((typeof val === 'function') || (typeof val === 'object'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: exists
|
||||||
|
// PARAMS: uid
|
||||||
|
// RETURN: true/false
|
||||||
|
// DESC : checks if a DOM element actually exists
|
||||||
|
const exists = (id) => $(id) ? true : false;
|
||||||
|
|
||||||
|
// METHOD: formatBytes
|
||||||
|
// PARAMS: bytes in int
|
||||||
|
// RETURN: string in GB/MB/KB
|
||||||
|
// DESC : converts a int number into bytes with prefix in two decimals precision
|
||||||
|
// currently precision is fixed, if dynamic needs check for max/min precision
|
||||||
|
function formatBytes(bytes)
|
||||||
|
{
|
||||||
|
var i = -1;
|
||||||
|
do {
|
||||||
|
bytes = bytes / 1024;
|
||||||
|
i++;
|
||||||
|
} while (bytes > 99);
|
||||||
|
|
||||||
|
return parseFloat(Math.round(bytes * Math.pow(10, 2)) / Math.pow(10, 2)) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: errorCatch
|
||||||
|
// PARAMS: err (error from try/catch
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : prints out error messages based on data available from the browser
|
||||||
|
function errorCatch(err)
|
||||||
|
{
|
||||||
|
// for FF & Chrome
|
||||||
|
if (err.stack) {
|
||||||
|
// only FF
|
||||||
|
if (err.lineNumber) {
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.lineNumber, err.message);
|
||||||
|
} else if (err.line) {
|
||||||
|
// only Safari
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.line, err.message);
|
||||||
|
} else {
|
||||||
|
console.log('ERROR[%s] %s', err.name, err.message);
|
||||||
|
}
|
||||||
|
// stack trace
|
||||||
|
console.log('ERROR[stack] %s', err.stack);
|
||||||
|
} else if (err.number) {
|
||||||
|
// IE
|
||||||
|
console.log('ERROR[%s:%s] %s', err.name, err.number, err.message);
|
||||||
|
console.log('ERROR[description] %s', err.description);
|
||||||
|
} else {
|
||||||
|
// the rest
|
||||||
|
console.log('ERROR[%s] %s', err.name, err.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: actionIndicator
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : show or hide the "do" overlay
|
||||||
|
function actionIndicator(loc = '')
|
||||||
|
{
|
||||||
|
if ($('overlayBox').visible()) {
|
||||||
|
actionIndicatorHide(loc);
|
||||||
|
} else {
|
||||||
|
actionIndicatorShow(loc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: actionIndicatorShow/actionIndicatorHide
|
||||||
|
// PARAMS: loc for console log info
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : explicit show/hide for action Indicator
|
||||||
|
// instead of automatically show or hide, do
|
||||||
|
// on command
|
||||||
|
function actionIndicatorShow(loc = '')
|
||||||
|
{
|
||||||
|
console.log('Indicator: SHOW [%s]', loc);
|
||||||
|
$('indicator').addClassName('progress');
|
||||||
|
setCenter('indicator', true, true);
|
||||||
|
$('indicator').show();
|
||||||
|
overlayBoxShow();
|
||||||
|
}
|
||||||
|
function actionIndicatorHide(loc = '')
|
||||||
|
{
|
||||||
|
console.log('Indicator: HIDE [%s]', loc);
|
||||||
|
$('indicator').hide();
|
||||||
|
$('indicator').removeClassName('progress');
|
||||||
|
overlayBoxHide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: overlayBoxView
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : shows or hides the overlay box
|
||||||
|
function overlayBoxShow()
|
||||||
|
{
|
||||||
|
// check if overlay box exists and if yes set the z-index to 100
|
||||||
|
if ($('overlayBox').visible()) {
|
||||||
|
$('overlayBox').style.zIndex = "100";
|
||||||
|
} else {
|
||||||
|
$('overlayBox').show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function overlayBoxHide()
|
||||||
|
{
|
||||||
|
// if the overlay box z-index is 100, do no hide, but set to 98
|
||||||
|
if ($('overlayBox').style.zIndex == 100) {
|
||||||
|
$('overlayBox').style.zIndex = "98";
|
||||||
|
} else {
|
||||||
|
$('overlayBox').hide();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: setOverlayBox
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : position the overlay block box and shows it
|
||||||
|
function setOverlayBox()
|
||||||
|
{
|
||||||
|
var viewport = document.viewport.getDimensions();
|
||||||
|
$('overlayBox').setStyle ({
|
||||||
|
width: '100%',
|
||||||
|
height: '100%'
|
||||||
|
});
|
||||||
|
$('overlayBox').show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: ClearCall
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : the abort call, clears the action box and hides it and the overlay box
|
||||||
|
function ClearCall()
|
||||||
|
{
|
||||||
|
$('actionBox').innerHTML = '';
|
||||||
|
$('actionBox').hide();
|
||||||
|
$('overlayBox').hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** DOM MANAGEMENT FUNCTIONS
|
||||||
|
// METHOD: cel [create element]
|
||||||
|
// PARAMS: tag: must set tag (div, span, etc)
|
||||||
|
// id: optional set for id, if input, select will be used for name
|
||||||
|
// content: text content inside, is skipped if sub elements exist
|
||||||
|
// css: array for css tags
|
||||||
|
// options: anything else (value, placeholder, OnClick, style)
|
||||||
|
// RETURN: object
|
||||||
|
// DESC : creates object for DOM element creation flow
|
||||||
|
const cel = (tag, id = '', content = '', css = [], options = {}) =>
|
||||||
|
_element = {
|
||||||
|
tag: tag,
|
||||||
|
id: id,
|
||||||
|
name: options.name, // override name if set [name gets ignored in tree build anyway]
|
||||||
|
content: content,
|
||||||
|
css: css,
|
||||||
|
options: options,
|
||||||
|
sub: []
|
||||||
|
};
|
||||||
|
|
||||||
|
// METHOD: ael [attach element]
|
||||||
|
// PARAMS: base: object where to attach/search
|
||||||
|
// attach: the object to be attached
|
||||||
|
// id: optional id, if given search in base for this id and attach there
|
||||||
|
// RETURN: "none", technically there is no return needed
|
||||||
|
// DESC : attach a cel created object to another to create a basic DOM tree
|
||||||
|
function ael(base, attach, id = '')
|
||||||
|
{
|
||||||
|
if (id) {
|
||||||
|
// base id match already
|
||||||
|
if (base.id == id) {
|
||||||
|
base.sub.push(Object.assign({}, attach));
|
||||||
|
} else {
|
||||||
|
// sub check
|
||||||
|
if (base.sub.length > 0) {
|
||||||
|
base.sub.each(function(t) {
|
||||||
|
// recursive call to sub element
|
||||||
|
ael(t, attach, id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base.sub.push(Object.assign({}, attach));
|
||||||
|
}
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: aelx [attach n elements]
|
||||||
|
// PARAMS: base: object to where we attach the elements
|
||||||
|
// attach 1..n: attach directly to the base element those attachments
|
||||||
|
// RETURN: "none", technically there is no return needed
|
||||||
|
// DESC : directly attach n elements to one master base element
|
||||||
|
// this type does not support attach with optional id
|
||||||
|
function aelx(base, ...attach)
|
||||||
|
{
|
||||||
|
attach.each(function(t) {
|
||||||
|
base.sub.push(Object.assign({}, t));
|
||||||
|
});
|
||||||
|
return base;
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: rel [reset element]
|
||||||
|
// PARAMS: cel created element
|
||||||
|
// RETURN: "none", is self change, but returns base.sub
|
||||||
|
// DESC : resets the sub elements of the base element given
|
||||||
|
const rel = (base) => base.sub = [];
|
||||||
|
|
||||||
|
// METHOD: rcssel [remove a css from the element]
|
||||||
|
// PARAMS: element, style sheet to remove
|
||||||
|
// RETURN: "none", in place because of reference
|
||||||
|
// DESC : searches and removes style from css array
|
||||||
|
function rcssel(_element, css)
|
||||||
|
{
|
||||||
|
let css_index = _element.css.indexOf(css);
|
||||||
|
if (css_index > -1) {
|
||||||
|
_element.css.splice(css_index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: acssel [add css element]
|
||||||
|
// PARAMS: element, style sheet to add
|
||||||
|
// RETURN: "none", in place add because of reference
|
||||||
|
// DESC : adds a new style sheet to the element given
|
||||||
|
function acssel(_element, css)
|
||||||
|
{
|
||||||
|
let css_index = _element.css.indexOf(css);
|
||||||
|
if (css_index == -1) {
|
||||||
|
_element.css.push(css);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: scssel
|
||||||
|
// PARAMS: element, style to remove, style to add
|
||||||
|
// RETURN: "none", in place add because of reference
|
||||||
|
// DESC : removes one css and adds another
|
||||||
|
// is a wrapper around rcssel/acssel
|
||||||
|
function scssel(_element, rcss, acss)
|
||||||
|
{
|
||||||
|
rcssel(_element, rcss);
|
||||||
|
acssel(_element, acss);
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: phfo [produce html from object]
|
||||||
|
// PARAMS: object tree with dom element declarations
|
||||||
|
// RETURN: HTML string that can be used as innerHTML
|
||||||
|
// DESC : parses the object tree created with cel/ael
|
||||||
|
// and converts it into an HTML string that can
|
||||||
|
// be inserted into the page
|
||||||
|
function phfo(tree)
|
||||||
|
{
|
||||||
|
// holds the elements
|
||||||
|
let content = [];
|
||||||
|
// main part line
|
||||||
|
let line = '<' + tree.tag;
|
||||||
|
// first id, if set
|
||||||
|
if (tree.id) {
|
||||||
|
line += ' id="' + tree.id + '"';
|
||||||
|
// if anything input (input, textarea, select then add name too)
|
||||||
|
if (['input', 'textarea', 'select'].includes(tree.tag)) {
|
||||||
|
line += ' name="' + (tree.name ? tree.name : tree.id) + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// second CSS
|
||||||
|
if (tree.css.length > 0) {
|
||||||
|
line += ' class="';
|
||||||
|
tree.css.each(function(t) {
|
||||||
|
line += t + ' ';
|
||||||
|
});
|
||||||
|
// strip last space
|
||||||
|
line = line.slice(0, -1);
|
||||||
|
line += '"';
|
||||||
|
}
|
||||||
|
// options is anything key = "data"
|
||||||
|
if (tree.options) {
|
||||||
|
// ignores id, name, class as key
|
||||||
|
for (const [key, item] of Object.entries(tree.options)) {
|
||||||
|
if (!['id', 'name', 'class'].includes(key)) {
|
||||||
|
line += ' ' + key + '="' + item + '"';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// finish open tag
|
||||||
|
line += '>';
|
||||||
|
// push finished line
|
||||||
|
content.push(line);
|
||||||
|
// dive into sub tree to attach sub nodes
|
||||||
|
// NOTES: we can have content (text) AND sub nodes at the same level
|
||||||
|
// CONTENT (TEXT) takes preference over SUB NODE in order
|
||||||
|
if (tree.sub.length > 0) {
|
||||||
|
if (tree.content) {
|
||||||
|
content.push(tree.content);
|
||||||
|
}
|
||||||
|
tree.sub.each(function(t) {
|
||||||
|
content.push(phfo(t));
|
||||||
|
});
|
||||||
|
} else if (tree.content) {
|
||||||
|
content.push(tree.content);
|
||||||
|
}
|
||||||
|
// if not input close
|
||||||
|
if (tree.tag != 'input') {
|
||||||
|
content.push('</' + tree.tag + '>');
|
||||||
|
}
|
||||||
|
// combine to string
|
||||||
|
return content.join('');
|
||||||
|
}
|
||||||
|
// *** DOM MANAGEMENT FUNCTIONS
|
||||||
|
|
||||||
|
// BLOCK: html wrappers for quickly creating html data blocks
|
||||||
|
// METHOD: html_options
|
||||||
|
// PARAMS: name/id, array for the options, selected item uid
|
||||||
|
// options_only [def false] if this is true, it will not print the select part
|
||||||
|
// return_string [def false]: return as string and not as element
|
||||||
|
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
||||||
|
// RETURN: html with build options block
|
||||||
|
// DESC : creates an select/options drop down block.
|
||||||
|
// the array needs to be key -> value format. key is for the option id and value is for the data output
|
||||||
|
function html_options(name, data, selected = '', options_only = false, return_string = false, sort = '')
|
||||||
|
{
|
||||||
|
let content = [];
|
||||||
|
let element_select;
|
||||||
|
let element_option;
|
||||||
|
let data_list = []; // for sorted output
|
||||||
|
// set outside select, gets stripped on return if options only is true
|
||||||
|
element_select = cel('select', name);
|
||||||
|
// console.log('Call for %s, options: %s', name, options_only);
|
||||||
|
if (sort == 'keys') {
|
||||||
|
data_list = Object.keys(data).sort();
|
||||||
|
} else if (sort == 'values') {
|
||||||
|
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
||||||
|
} else {
|
||||||
|
data_list = Object.keys(data);
|
||||||
|
}
|
||||||
|
// console.log('ORDER: %s', data_list);
|
||||||
|
// use the previously sorted list
|
||||||
|
// for (const [key, value] of Object.entries(data)) {
|
||||||
|
for (const key of data_list) {
|
||||||
|
let value = data[key];
|
||||||
|
console.log('create [%s] options: key: %s, value: %s', name, key, value);
|
||||||
|
// basic options init
|
||||||
|
let options = {
|
||||||
|
'label': value,
|
||||||
|
'value': key
|
||||||
|
};
|
||||||
|
// add selected if matching
|
||||||
|
if (selected == key) {
|
||||||
|
options.selected = '';
|
||||||
|
}
|
||||||
|
// create the element option
|
||||||
|
element_option = cel('option', '', value, '', options);
|
||||||
|
// attach it to the select element
|
||||||
|
ael(element_select, element_option);
|
||||||
|
}
|
||||||
|
// if with select part, convert to text
|
||||||
|
if (!options_only) {
|
||||||
|
if (return_string) {
|
||||||
|
content.push(phfo(element_select));
|
||||||
|
return content.join('');
|
||||||
|
} else {
|
||||||
|
return element_select;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// strip select part
|
||||||
|
if (return_string) {
|
||||||
|
element_select.sub.each(function(t) {
|
||||||
|
content.push(phfo(t));
|
||||||
|
});
|
||||||
|
return content.join('');
|
||||||
|
} else {
|
||||||
|
return element_select.sub;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: html_options_refill
|
||||||
|
// PARAMS: name/id, array of options, sort = ''
|
||||||
|
// sort [def '']: if empty as is, else allowed 'keys', 'values' all others are ignored
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : refills a select box with options and keeps the selected
|
||||||
|
function html_options_refill(name, data, sort = '')
|
||||||
|
{
|
||||||
|
let element_option;
|
||||||
|
let option_selected;
|
||||||
|
let data_list = []; // for sorted output
|
||||||
|
// skip if not exists
|
||||||
|
if ($(name)) {
|
||||||
|
// console.log('Call for %s, options: %s', name, options_only);
|
||||||
|
if (sort == 'keys') {
|
||||||
|
data_list = Object.keys(data).sort();
|
||||||
|
} else if (sort == 'values') {
|
||||||
|
data_list = Object.keys(data).sort((a, b) => ('' + data[a]).localeCompare(data[b]));
|
||||||
|
} else {
|
||||||
|
data_list = Object.keys(data);
|
||||||
|
}
|
||||||
|
// first read in existing ones from the options and get the selected one
|
||||||
|
[].forEach.call(document.querySelectorAll('#' + name + ' :checked'), function(elm) {
|
||||||
|
option_selected = elm.value;
|
||||||
|
});
|
||||||
|
$(name).innerHTML = '';
|
||||||
|
for (const key of data_list) {
|
||||||
|
let value = data[key];
|
||||||
|
// console.log('add [%s] options: key: %s, value: %s', name, key, value);
|
||||||
|
element_option = document.createElement('option');
|
||||||
|
element_option.label = value;
|
||||||
|
element_option.value = key;
|
||||||
|
element_option.innerHTML = value;
|
||||||
|
$(name).appendChild(element_option);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// METHOD: initDatepickr
|
||||||
|
// PARAMS: initial date ID (#)
|
||||||
|
// RETURN: true on ok, false on failure
|
||||||
|
// DESC : inits date pickr which translations for dates (week/month)
|
||||||
|
function initDatepickr(init_date)
|
||||||
|
{
|
||||||
|
if ($(init_date)) {
|
||||||
|
datepickr('#' + init_date); // we need to add this so we have it initialized before we can actually change the definitions
|
||||||
|
// dates in japanese
|
||||||
|
datepickr.prototype.l10n.months.shorthand = [__('Jan'), __('Feb'), __('Mar'), __('Apr'), __('May'), __('Jun'), __('Jul'), __('Aug'), __('Sep'), __('Oct'), __('Nov'), __('Dec')];
|
||||||
|
datepickr.prototype.l10n.months.longhand = [__('January'), __('February'), __('March'), __('April'), __('May'), __('June'), __('July'), __('August'), __('September'), __('October'), __('November'), __('December')];
|
||||||
|
datepickr.prototype.l10n.weekdays.shorthand = [__('Mon'), __('Tue'), __('Wed'), __('Thu'), __('Fri'), __('Sat'), __('Sun')];
|
||||||
|
datepickr.prototype.l10n.weekdays.longhand = [__('Monday'), __('Tuesday'), __('Wednesday'), __('Thursday'), __('Friday'), __('Saturday'), __('Sunday')];
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// *** MASTER logout call
|
||||||
|
// METHOD: loginLogout
|
||||||
|
// PARAMS: none
|
||||||
|
// RETURN: none
|
||||||
|
// DESC : submits basic data for form logout
|
||||||
|
function loginLogout()
|
||||||
|
{
|
||||||
|
const form = document.createElement('form');
|
||||||
|
form.method = 'post';
|
||||||
|
const hiddenField = document.createElement('input');
|
||||||
|
hiddenField.type = 'hidden';
|
||||||
|
hiddenField.name = 'login_logout';
|
||||||
|
hiddenField.value = 'Logout';
|
||||||
|
form.appendChild(hiddenField);
|
||||||
|
document.body.appendChild(form);
|
||||||
|
form.submit();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* END */
|
||||||
@@ -3,14 +3,14 @@
|
|||||||
* firebug 1.2+ and the webkit console */
|
* firebug 1.2+ and the webkit console */
|
||||||
|
|
||||||
var ConsoleSetup = function() {
|
var ConsoleSetup = function() {
|
||||||
if (!window.console)
|
if (!window.console)
|
||||||
window.console = {};
|
window.console = {};
|
||||||
|
|
||||||
var names = ["log", "debug", "info", "warn", "error", "assert", "dir", "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", "profile", "profileEnd"];
|
var names = ['log', 'debug', 'info', 'warn', 'error', 'assert', 'dir', 'dirxml', 'group', 'groupEnd', 'time', 'timeEnd', 'count', 'trace', 'profile', 'profileEnd'];
|
||||||
|
|
||||||
for (var i = 0; i < names.length; ++i) {
|
for (var i = 0; i < names.length; ++i) {
|
||||||
if (!window.console[names[i]]) {
|
if (!window.console[names[i]]) {
|
||||||
window.console[names[i]] = function() {};
|
window.console[names[i]] = function() {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
|
|||||||
16
www/layout/admin/default/javascript/jquery.test.js
Executable file
16
www/layout/admin/default/javascript/jquery.test.js
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
/* jquery tests */
|
||||||
|
|
||||||
|
/* global setCenter ClearCall overlayBoxShow actionIndicatorShow actionIndicatorHide */
|
||||||
|
/* eslint no-undef: "error" */
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
setCenter('test-div', true, true);
|
||||||
|
ClearCall();
|
||||||
|
overlayBoxShow();
|
||||||
|
actionIndicatorShow('testSmarty');
|
||||||
|
setTimeout(function() {
|
||||||
|
console.log('Waiting dummy ...');
|
||||||
|
actionIndicatorHide('testSmarty');
|
||||||
|
ClearCall();
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<script language="JavaScript" src="{$js}/debug.js"></script>
|
<script language="JavaScript" src="{$js}/debug.js"></script>
|
||||||
{if $USE_JQUERY}
|
{if $USE_JQUERY}
|
||||||
<!-- JQuery -->
|
<!-- JQuery -->
|
||||||
<script type="text/javascript" src="{$js}/jquery.js"></script>
|
<script type="text/javascript" src="{$js}/jquery.min.js"></script>
|
||||||
{/if}
|
{/if}
|
||||||
{if $USE_PROTOTYPE}
|
{if $USE_PROTOTYPE}
|
||||||
<script src="{$js}/scriptaculous/prototype.js" type="text/javascript"></script>
|
<script src="{$js}/scriptaculous/prototype.js" type="text/javascript"></script>
|
||||||
@@ -96,10 +96,7 @@
|
|||||||
<div style="position: relative; height: 20px;" class="menu">
|
<div style="position: relative; height: 20px;" class="menu">
|
||||||
<div style="position: absolute; width: 200px;">{t 1=$USER_NAME|upper}Hello %1{/t}</div>
|
<div style="position: absolute; width: 200px;">{t 1=$USER_NAME|upper}Hello %1{/t}</div>
|
||||||
<div style="position: absolute; text-align: right; right: 0px; width: 120px;">
|
<div style="position: absolute; text-align: right; right: 0px; width: 120px;">
|
||||||
<form method="post" name="loginlogout">
|
<a href="#" OnClick="loginLogout(); return false;">{t}Logout{/t}</a>
|
||||||
<a href="javascript:document.loginlogout.login_logout.value='Logout';document.loginlogout.submit();">{t}Logout{/t}</a>
|
|
||||||
<input type="hidden" name="login_logout" value="">
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin-bottom: 5px;" class="menu">
|
<div style="margin-bottom: 5px;" class="menu">
|
||||||
|
|||||||
@@ -6,3 +6,14 @@
|
|||||||
{html_options options=$drop_down_test selected=$drop_down_test_selected}
|
{html_options options=$drop_down_test selected=$drop_down_test_selected}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="jq-test" class="jp-test">
|
||||||
|
<div id="test-div" class="test-div">
|
||||||
|
Some content ehre or asdfasdfasf
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{* progresss indicator *}
|
||||||
|
<div id="indicator"></div>
|
||||||
|
{* the action confirm box *}
|
||||||
|
<div id="actionBox" class="actionBoxElement"></div>
|
||||||
|
{* The Overlay box *}
|
||||||
|
<div id="overlayBox" class="overlayBoxElement"></div>
|
||||||
|
|||||||
@@ -276,7 +276,7 @@ class Basic
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set the regex for checking emails
|
// set the regex for checking emails
|
||||||
$this->email_regex = "^[A-Za-z0-9!#$%&'*+-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+-\/=?^_`{|}~\.]{0,63}@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]{1,})*\.([a-zA-Z]{2,}){1}$";
|
$this->email_regex = "^[A-Za-z0-9!#$%&'*+\-\/=?^_`{|}~][A-Za-z0-9!#$%:\(\)&'*+\-\/=?^_`{|}~\.]{0,63}@[a-zA-Z0-9\-]+(\.[a-zA-Z0-9\-]{1,})*\.([a-zA-Z]{2,}){1}$";
|
||||||
// this is for error check parts in where the email regex failed
|
// this is for error check parts in where the email regex failed
|
||||||
$this->email_regex_check = array (
|
$this->email_regex_check = array (
|
||||||
1 => "@(.*)@(.*)", // double @
|
1 => "@(.*)@(.*)", // double @
|
||||||
@@ -1374,7 +1374,10 @@ class Basic
|
|||||||
if (!$hour || !$min) {
|
if (!$hour || !$min) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (($hour < 0 && $hour > 24) || ($min < 0 && $hour > 60) || ($sec && $sec < 0 && $sec > 60)) {
|
if (($hour < 0 || $hour > 24) ||
|
||||||
|
($min < 0 || $min > 60) ||
|
||||||
|
($sec && ($sec < 0 || $sec > 60))
|
||||||
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -1446,6 +1449,40 @@ class Basic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// METHOD: calcDaysInterval
|
||||||
|
// PARAMS: start date, end date
|
||||||
|
// RETURN: overall days, week days, weekend days as array 0...2 or named
|
||||||
|
// DESC : calculates the days between two dates
|
||||||
|
private function calcDaysInterval($start_date, $end_date, $return_named = false)
|
||||||
|
{
|
||||||
|
// pos 0 all, pos 1 weekday, pos 2 weekend
|
||||||
|
$days = array ();
|
||||||
|
$start = new \DateTime($start_date);
|
||||||
|
$end = new \DateTime($end_date);
|
||||||
|
|
||||||
|
$days[0] = $end->diff($start)->days;
|
||||||
|
|
||||||
|
$period = new \DatePeriod($start, new \DateInterval('P1D'), $end);
|
||||||
|
|
||||||
|
foreach ($period as $dt) {
|
||||||
|
$curr = $dt->format('D');
|
||||||
|
if ($curr == 'Sat' || $curr == 'Sun') {
|
||||||
|
$days[2] ++;
|
||||||
|
} else {
|
||||||
|
$days[1] ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($return_named === true) {
|
||||||
|
return array (
|
||||||
|
'overall' => $days[0],
|
||||||
|
'weekday' => $days[1],
|
||||||
|
'weekend' => $days[2]
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return $days;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// METHOD: createThumbnail
|
// METHOD: createThumbnail
|
||||||
// WAS : CreateThumbnail
|
// WAS : CreateThumbnail
|
||||||
// PARAMS: pic -> picture where from we create a thumbnail
|
// PARAMS: pic -> picture where from we create a thumbnail
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class L10n extends \CoreLibs\Basic
|
|||||||
// reloads the mofile, if the location of the lang file changes
|
// reloads the mofile, if the location of the lang file changes
|
||||||
public function l10nReloadMOfile($lang, $path = DEFAULT_TEMPLATE)
|
public function l10nReloadMOfile($lang, $path = DEFAULT_TEMPLATE)
|
||||||
{
|
{
|
||||||
|
$success = false;
|
||||||
$old_mofile = $this->mofile;
|
$old_mofile = $this->mofile;
|
||||||
$old_lang = $this->lang;
|
$old_lang = $this->lang;
|
||||||
|
|
||||||
@@ -80,11 +81,14 @@ class L10n extends \CoreLibs\Basic
|
|||||||
if (is_readable($this->mofile)) {
|
if (is_readable($this->mofile)) {
|
||||||
$this->input = new FileReader($this->mofile);
|
$this->input = new FileReader($this->mofile);
|
||||||
$this->l10n = new GetTextReader($this->input);
|
$this->l10n = new GetTextReader($this->input);
|
||||||
|
// we successfully loaded
|
||||||
|
$success = true;
|
||||||
} else {
|
} else {
|
||||||
// else fall back to the old ones
|
// else fall back to the old ones
|
||||||
$this->mofile = $old_mofile;
|
$this->mofile = $old_mofile;
|
||||||
$this->lang = $old_lang;
|
$this->lang = $old_lang;
|
||||||
}
|
}
|
||||||
|
return $success;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function __($text)
|
public function __($text)
|
||||||
|
|||||||
@@ -1294,6 +1294,10 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
|
|||||||
}
|
}
|
||||||
reset($this->element_list);
|
reset($this->element_list);
|
||||||
foreach ($this->element_list as $table_name => $reference_array) {
|
foreach ($this->element_list as $table_name => $reference_array) {
|
||||||
|
// init arrays
|
||||||
|
$q_names = array ();
|
||||||
|
$q_data = array ();
|
||||||
|
$q_values = array ();
|
||||||
// get the number of keys from the elements array
|
// get the number of keys from the elements array
|
||||||
$keys = array_keys($reference_array["elements"]);
|
$keys = array_keys($reference_array["elements"]);
|
||||||
// element prefix name
|
// element prefix name
|
||||||
@@ -1314,9 +1318,6 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
|
|||||||
// go through all submitted data
|
// go through all submitted data
|
||||||
// for ($i = 0; $i < count($_POST[$el_name]); $i ++)
|
// for ($i = 0; $i < count($_POST[$el_name]); $i ++)
|
||||||
for ($i = 0; $i < $max; $i ++) {
|
for ($i = 0; $i < $max; $i ++) {
|
||||||
$q_data[$i] = '';
|
|
||||||
$q_names[$i] = '';
|
|
||||||
$q_values[$i] = '';
|
|
||||||
// if we have enable name & delete set, then only insert/update those which are flagged as active
|
// if we have enable name & delete set, then only insert/update those which are flagged as active
|
||||||
// check if mandatory field is set, if not set "do not write flag"
|
// check if mandatory field is set, if not set "do not write flag"
|
||||||
if ($data_array["mandatory"] && !$_POST[$prfx.$el_name][$i]) {
|
if ($data_array["mandatory"] && !$_POST[$prfx.$el_name][$i]) {
|
||||||
@@ -1355,7 +1356,7 @@ class Generate extends \CoreLibs\DB\Extended\ArrayIO
|
|||||||
$q_data[$i] .= ", ";
|
$q_data[$i] .= ", ";
|
||||||
}
|
}
|
||||||
// insert name part list
|
// insert name part list
|
||||||
if ($q_names[$i]) {
|
if (strlen($q_names[$i])) {
|
||||||
$q_names[$i] .= ", ";
|
$q_names[$i] .= ", ";
|
||||||
}
|
}
|
||||||
// insert value part list
|
// insert value part list
|
||||||
|
|||||||
Reference in New Issue
Block a user