1. Refactoring form objects and database objects to use inheritance and abstract base class for consistency and reduced redundancy.\n2. Contact us page button links updated to resolve error of missing link causing page refresh instead of expected functionality.
This commit is contained in:
@@ -14,6 +14,4 @@ CREATE TABLE IF NOT EXISTS Shop_Product_Category_Temp (
|
||||
, display_order INT NOT NULL
|
||||
, id_access_level_required INT NOT NULL DEFAULT 1
|
||||
, guid BINARY(36) NOT NULL
|
||||
, created_on TIMESTAMP NOT NULL
|
||||
, created_by INT NOT NULL
|
||||
);
|
||||
|
||||
@@ -16,23 +16,22 @@ DROP PROCEDURE IF EXISTS p_shop_get_many_access_level;
|
||||
|
||||
DELIMITER //
|
||||
CREATE PROCEDURE p_shop_get_many_access_level (
|
||||
IN a_get_inactive_access_level BIT
|
||||
IN a_id_user INT,
|
||||
IN a_get_inactive_access_level BIT
|
||||
)
|
||||
BEGIN
|
||||
IF a_get_inactive_access_level IS NULL THEN
|
||||
SET a_get_inactive_access_level = 0;
|
||||
END IF;
|
||||
SET a_get_inactive_access_level = IFNULL(a_get_inactive_access_level, 0);
|
||||
|
||||
SELECT
|
||||
AL.id_access_level,
|
||||
AL.code,
|
||||
AL.name,
|
||||
AL.active,
|
||||
AL.priority,
|
||||
AL.display_order
|
||||
AL.code,
|
||||
AL.name,
|
||||
AL.active,
|
||||
AL.priority,
|
||||
AL.display_order
|
||||
FROM Shop_Access_Level AL
|
||||
WHERE
|
||||
a_get_inactive_access_level = 1
|
||||
a_get_inactive_access_level = 1
|
||||
OR AL.active = 1
|
||||
ORDER BY AL.display_order
|
||||
;
|
||||
|
||||
@@ -111,7 +111,7 @@ BEGIN
|
||||
, IFNULL(PC_T.code, PC.code) AS code
|
||||
, IFNULL(PC_T.name, PC.code) AS name
|
||||
, IFNULL(PC_T.description, PC.description) AS description
|
||||
, PC_T.id_access_level_required AS id_access_level_required
|
||||
, IFNULL(PC_T.id_access_level_required, PC.id_access_level_required) AS id_access_level_required
|
||||
, IFNULL(PC_T.active, PC.active) AS active
|
||||
, IFNULL(PC_T.display_order, PC.display_order) AS display_order
|
||||
, IFNULL(PC_T.name, IFNULL(PC.name, IFNULL(PC_T.code, IFNULL(PC.code, IFNULL(PC_T.id_category, '(No Product Category)'))))) AS name_error
|
||||
|
||||
@@ -325,14 +325,16 @@ BEGIN
|
||||
, PC.name
|
||||
, PC.description
|
||||
, PC.id_access_level_required
|
||||
, AL.name AS name_access_level_required
|
||||
, PC.display_order
|
||||
, PC.active
|
||||
, MIN(t_P.can_view) AS can_view
|
||||
, MIN(t_P.can_edit) AS can_edit
|
||||
, MIN(t_P.can_admin) AS can_admin
|
||||
FROM tmp_Category t_C
|
||||
INNER JOIN Shop_product_category PC ON t_C.id_category = PC.id_category
|
||||
INNER JOIN Shop_Product_Category PC ON t_C.id_category = PC.id_category
|
||||
LEFT JOIN tmp_Product t_P ON t_C.id_category = t_P.id_product
|
||||
INNER JOIN Shop_Access_Level AL ON PC.id_access_level_required = AL.id_access_level
|
||||
GROUP BY t_C.id_category -- , t_P.id_product
|
||||
ORDER BY PC.display_order
|
||||
;
|
||||
@@ -344,6 +346,7 @@ BEGIN
|
||||
P.name,
|
||||
P.has_variations,
|
||||
P.id_access_level_required,
|
||||
AL.name AS name_access_level_required,
|
||||
P.active,
|
||||
P.display_order,
|
||||
t_P.can_view,
|
||||
@@ -352,6 +355,7 @@ BEGIN
|
||||
FROM tmp_Product t_P
|
||||
INNER JOIN Shop_Product P ON t_P.id_product = P.id_product
|
||||
INNER JOIN tmp_Category t_C ON t_P.id_category = t_C.id_category
|
||||
INNER JOIN Shop_Access_Level AL ON P.id_access_level_required = AL.id_access_level
|
||||
GROUP BY t_P.id_category, t_C.display_order, t_P.id_product, t_P.can_view, t_P.can_edit, t_P.can_admin
|
||||
ORDER BY t_C.display_order, P.display_order
|
||||
;
|
||||
|
||||
25
static/css/pages/core/home.css
Normal file
25
static/css/pages/core/home.css
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
.page-body > * {
|
||||
height: 100%;
|
||||
}
|
||||
#pageBody > * :first-child{
|
||||
margin-top: 25vh;
|
||||
}
|
||||
#pageBody > * :last-child {
|
||||
margin-bottom: 35vh;
|
||||
}
|
||||
|
||||
.img-demo {
|
||||
max-width: 50%;
|
||||
min-width: 500px;
|
||||
}
|
||||
|
||||
.img-featured {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/*
|
||||
img {
|
||||
background-image: url("/static/images/Tag_Molly1.png");
|
||||
}
|
||||
*/
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
|
||||
td.display-order, th.display-order {
|
||||
width: 10% !important;
|
||||
width: 8% !important;
|
||||
}
|
||||
td.code, th.code {
|
||||
width: 15% !important;
|
||||
@@ -10,10 +10,13 @@ td.name, th.name {
|
||||
width: 25% !important;
|
||||
}
|
||||
td.description, th.description {
|
||||
width: 40% !important;
|
||||
width: 35% !important;
|
||||
}
|
||||
td.access_level, th.access_level {
|
||||
width: 10% !important;
|
||||
}
|
||||
td.active, th.active {
|
||||
width: 10% !important;
|
||||
width: 7% !important;
|
||||
}
|
||||
|
||||
/*
|
||||
0
static/css/sections/core.css
Normal file
0
static/css/sections/core.css
Normal file
52
static/css/store_shared.css
Normal file
52
static/css/store_shared.css
Normal file
@@ -0,0 +1,52 @@
|
||||
.img-product {
|
||||
max-width: 20vh;
|
||||
max-height: 20vh;
|
||||
border-radius: 3vh;
|
||||
justify-self: left;
|
||||
}
|
||||
|
||||
.img-thumbnail {
|
||||
max-width: 10vh;
|
||||
max-height: 10vh;
|
||||
border-radius: 3vh;
|
||||
justify-self: left;
|
||||
}
|
||||
|
||||
.buttonAdd2Basket {
|
||||
background-color: var(--c_blue_pastel);
|
||||
color: var(--c_blue_dark);
|
||||
border-color: var(--c_blue_dark);
|
||||
}
|
||||
|
||||
#buttonCheckout, .buttonBuyNow {
|
||||
background-color: var(--c_purple_pastel);
|
||||
color: var(--c_purple_dark);
|
||||
border-color: var(--c_purple_dark);
|
||||
}
|
||||
|
||||
.button-increment, .button-decrement {
|
||||
border: 2px solid darkgrey;
|
||||
background-color: lightgray;
|
||||
margin: 1vh 1vh;
|
||||
width: 2.5vh;
|
||||
height: 2.5vh;
|
||||
border-radius: 1.25vh;
|
||||
font-size: 2vh;
|
||||
}
|
||||
|
||||
.container-input > input {
|
||||
padding: 0vh 1vh;
|
||||
border-radius: 0.5vh;
|
||||
max-width: 7vh;
|
||||
}
|
||||
|
||||
#basket {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Right column */
|
||||
.rightcolumn {
|
||||
min-width: fit-content;
|
||||
}
|
||||
86
static/css/stylesheet.css
Normal file
86
static/css/stylesheet.css
Normal file
@@ -0,0 +1,86 @@
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 10px;
|
||||
display: block;
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
.banner {
|
||||
background-color: black;
|
||||
color: white;
|
||||
width: 100%;
|
||||
position: fixed;
|
||||
padding-top: 5vh;
|
||||
padding-bottom: 10vh;
|
||||
}
|
||||
|
||||
.banner.top {
|
||||
background-color: black;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.banner.bottom {
|
||||
background-color: black;
|
||||
color: white;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.column {
|
||||
float: left;
|
||||
padding: 5vw;
|
||||
}
|
||||
|
||||
.column.side {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.column.middle {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.midbod {
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.panel {
|
||||
float: left;
|
||||
}
|
||||
|
||||
img {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
.panel.labelcontainer {
|
||||
background-color: black;
|
||||
color: white;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.label {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.label.bodytext {
|
||||
background-color: black;
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-style: normal;
|
||||
font-size: 12;
|
||||
}
|
||||
|
||||
.label.title {
|
||||
font-style: bold;
|
||||
font-size: 18;
|
||||
}
|
||||
@@ -27,10 +27,10 @@
|
||||
--nav-hover-text: #bb86fc;
|
||||
|
||||
/* Buttons */
|
||||
--btn-primary-bg: #bb86fc;
|
||||
--btn-primary-text: #121212;
|
||||
--btn-secondary-bg: #03dac6;
|
||||
--btn-secondary-text: #121212;
|
||||
--Button-primary-bg: #bb86fc;
|
||||
--Button-primary-text: #121212;
|
||||
--Button-secondary-bg: #03dac6;
|
||||
--Button-secondary-text: #121212;
|
||||
|
||||
/* Forms */
|
||||
--input-bg: #2c2c2c;
|
||||
|
||||
@@ -27,10 +27,10 @@
|
||||
--nav-hover-text: #007bff;
|
||||
|
||||
/* Buttons */
|
||||
--btn-primary-bg: #007bff;
|
||||
--btn-primary-text: #ffffff;
|
||||
--btn-secondary-bg: #6c757d;
|
||||
--btn-secondary-text: #ffffff;
|
||||
--Button-primary-bg: #007bff;
|
||||
--Button-primary-text: #ffffff;
|
||||
--Button-secondary-bg: #6c757d;
|
||||
--Button-secondary-text: #ffffff;
|
||||
|
||||
/* Forms */
|
||||
--input-bg: #ffffff;
|
||||
|
||||
119
static/docs/naming conventions.txt
Normal file
119
static/docs/naming conventions.txt
Normal file
@@ -0,0 +1,119 @@
|
||||
Precision and Research Technology Systems Limited
|
||||
Naming Conventions
|
||||
|
||||
|
||||
Language: CSS
|
||||
File naming convention:
|
||||
kebab-case
|
||||
lowercase
|
||||
|
||||
|
||||
Language: HTML
|
||||
File naming convention:
|
||||
prefix with underscore for templates
|
||||
snake_case
|
||||
lowercase
|
||||
|
||||
|
||||
Language: JavaScript
|
||||
Variable naming convention:
|
||||
prefix with underscore for private variables
|
||||
camelCase for mutable variables
|
||||
uppercase with underscore spacing for constants
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Function naming convention:
|
||||
camelCase
|
||||
verb is first word
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Class naming convention:
|
||||
PascalCase (UpperCamelCase)
|
||||
singular noun or noun phrase
|
||||
File naming convention:
|
||||
kebab-case
|
||||
lowercase
|
||||
suffix with type for type hinting
|
||||
Folder naming convention:
|
||||
kebab-case
|
||||
lowercase
|
||||
|
||||
|
||||
Language: MySQL
|
||||
Database naming convention:
|
||||
snake_case
|
||||
lowercase
|
||||
Variable naming convention:
|
||||
lowercase and prefix with 'v_' for mutable variables
|
||||
uppercase and prefix with 'C_' for constants
|
||||
snake_case
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Function, Store Procedure, Trigger, and View naming convention:
|
||||
prefix with 'fn_' for functions
|
||||
prefix with 'vw_' for views
|
||||
prefix with 'p_' for stored procedures
|
||||
prefix with 'tri_' for triggers
|
||||
suffix with action then event timing for triggers
|
||||
lowercase
|
||||
snake_case
|
||||
verb is first word
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Table naming convention:
|
||||
prefix with project
|
||||
prefix with 'tmp' for temporary tables
|
||||
singular noun or noun phrase
|
||||
Upper_Snake_Case
|
||||
Column naming convention:
|
||||
prefix with project
|
||||
prefix with 'idx_' for indices
|
||||
singular noun or noun phrase
|
||||
snake_case
|
||||
lowercase
|
||||
Constraint naming convention:
|
||||
prefix with 'pk_' for primary keys
|
||||
prefix with 'fk_' for foreign keys
|
||||
prefix with 'chk_' for check
|
||||
singular noun or noun phrase
|
||||
snake_case
|
||||
lowercase
|
||||
File naming convention:
|
||||
snake_case
|
||||
lowercase
|
||||
suffix with type for type hinting
|
||||
Folder naming convention:
|
||||
kebab-case
|
||||
lowercase
|
||||
|
||||
|
||||
Language: Python
|
||||
Variable naming convention:
|
||||
prefix with underscore for private variables
|
||||
prefix with double underscore for private variables that are not inherited
|
||||
lowercase for mutable variables
|
||||
uppercase for constants
|
||||
snake_case
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Function naming convention:
|
||||
lowercase
|
||||
snake_case
|
||||
verb is first word
|
||||
top-down heirarchy of objects flows left to right
|
||||
suffix with type for type hinting
|
||||
Class naming convention:
|
||||
suffix with 'Base' for base classes
|
||||
prefix with 'Abstract' for abstract classes
|
||||
prefix with 'Abstract' for abstract classes
|
||||
PascalCase (UpperCamelCase)
|
||||
singular noun or noun phrase
|
||||
File naming convention:
|
||||
snake_case
|
||||
lowercase
|
||||
suffix with type for type hinting
|
||||
Folder naming convention:
|
||||
snake_case
|
||||
lowercase
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ def webhook_received():
|
||||
if event_type == 'checkout.session.completed':
|
||||
print('🔔 Payment succeeded!')
|
||||
|
||||
return jsonify({'status': 'success'})
|
||||
return jsonify({Model_View_Base.FLAG_STATUS: Model_View_Base.FLAG_SUCCESS})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(port=4242, debug=True)
|
||||
5
static/js/accessibility_statement.js
Normal file
5
static/js/accessibility_statement.js
Normal file
@@ -0,0 +1,5 @@
|
||||
var _loading = true;
|
||||
|
||||
function hookupPageAccessibilityStatement() {
|
||||
_loading = false;
|
||||
}
|
||||
@@ -8,8 +8,8 @@ export default class API {
|
||||
return document.querySelector(idCSRFToken).getAttribute('content');
|
||||
}
|
||||
|
||||
static async request(hashEndpoint, method = 'GET', data = null) {
|
||||
const url = API.getUrlFromHash(hashEndpoint);
|
||||
static async request(hashEndpoint, method = 'GET', data = null, params = null) {
|
||||
const url = API.getUrlFromHash(hashEndpoint, params);
|
||||
const options = {
|
||||
method,
|
||||
headers: {
|
||||
@@ -36,11 +36,25 @@ export default class API {
|
||||
}
|
||||
}
|
||||
|
||||
static getUrlFromHash(hash) {
|
||||
static getUrlFromHash(hash, params = null) {
|
||||
if (hash == null) hash = hashPageHome;
|
||||
console.log("getUrlFromHash:");
|
||||
console.log("base url: " + _pathHost + "\nhash: " + hash);
|
||||
return _pathHost + hash;
|
||||
console.log("base url: " + _pathHost + "\nhash: " + hash + '\nparams: ' + params);
|
||||
let url = _pathHost + hash;
|
||||
if (params) {
|
||||
url += '?' + new URLSearchParams(params).toString();
|
||||
}
|
||||
console.log("url: " + url);
|
||||
return url;
|
||||
}
|
||||
|
||||
static goToUrl(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
static goToHash(hash, params = null) {
|
||||
const url = API.getUrlFromHash(hash, params);
|
||||
API.goToUrl(url);
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +77,18 @@ export default class API {
|
||||
static async getCategories() {
|
||||
return await API.request(hashGetStoreProductCategory);
|
||||
}
|
||||
static async getCategoriesByFilters(formFilters) {
|
||||
static async getCategoriesByFilters(filtersJson) {
|
||||
/*
|
||||
let dataRequest = {};
|
||||
dataRequest[keyForm] = DOM.convertForm2JSON(formFilters);
|
||||
dataRequest[keyForm] = filtersJson;
|
||||
return await API.request(hashGetStoreProductCategory, 'POST', dataRequest);
|
||||
*/
|
||||
// return await API.request(hashPageStoreProductCategories, 'GET', filtersJson);
|
||||
API.goToHash(hashPageStoreProductCategories, filtersJson);
|
||||
}
|
||||
static async saveCategories(categories, formFilters, comment) {
|
||||
let dataRequest = {};
|
||||
dataRequest[keyForm] = DOM.convertForm2JSON(formFilters);
|
||||
dataRequest[flagFormFilters] = DOM.convertForm2JSON(formFilters);
|
||||
dataRequest[flagCategory] = categories;
|
||||
dataRequest[flagComment] = comment;
|
||||
return await API.request(hashSaveStoreProductCategory, 'POST', dataRequest);
|
||||
|
||||
@@ -38,8 +38,11 @@ class App {
|
||||
|
||||
initPageCurrent() {
|
||||
console.log("initPageCurrent");
|
||||
/*
|
||||
_pageCurrent = Router.getPageCurrent();
|
||||
_pageCurrent.initialize();
|
||||
*/
|
||||
this.router.loadPageCurrent();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,17 +44,22 @@ export default class DOM {
|
||||
pageBody.innerHTML = contentNew;
|
||||
}
|
||||
static getHashPageCurrent() {
|
||||
return document.body.dataset.page;
|
||||
const hashPageCurrent = document.body.dataset.page;
|
||||
console.log("hashPageCurrent: " + hashPageCurrent);
|
||||
return hashPageCurrent;
|
||||
}
|
||||
static isElementDirty(element) {
|
||||
element.setAttribute(attrValueCurrent, DOM.getElementValueCurrent(element));
|
||||
let isDirty = element.getAttribute(attrValuePrevious) != element.getAttribute(attrValueCurrent);
|
||||
DOM.handleDirtyElement(element, isDirty);
|
||||
return isDirty;
|
||||
}
|
||||
static handleDirtyElement(element, isDirty) {
|
||||
if (isDirty) {
|
||||
element.classList.add(flagDirty);
|
||||
} else {
|
||||
element.classList.remove(flagDirty);
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
static getElementValueCurrent(element) {
|
||||
let returnVal = '';
|
||||
@@ -99,5 +104,7 @@ export default class DOM {
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* non-static method on page object to use
|
||||
static handleChangeElement(element) {}
|
||||
*/
|
||||
}
|
||||
|
||||
65
static/js/lib/main.js
Normal file
65
static/js/lib/main.js
Normal file
@@ -0,0 +1,65 @@
|
||||
// main.js
|
||||
|
||||
import { initializeAPI } from './shared/api.js';
|
||||
import { setupEventListeners } from './shared/events.js';
|
||||
import { initializeComponents } from './components/componentInitializer.js';
|
||||
import { router } from './shared/router.js';
|
||||
import { CONFIG } from './config/config.js';
|
||||
|
||||
// DOM ready function
|
||||
function domReady(fn) {
|
||||
if (document.readyState !== 'loading') {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn);
|
||||
}
|
||||
}
|
||||
|
||||
// Main initialization function
|
||||
function initializeApp() {
|
||||
console.log('Initializing application...');
|
||||
|
||||
// Initialize API with base URL
|
||||
initializeAPI(CONFIG.API_BASE_URL);
|
||||
|
||||
// Setup global event listeners
|
||||
setupEventListeners();
|
||||
|
||||
// Initialize reusable components
|
||||
initializeComponents();
|
||||
|
||||
// Initialize router
|
||||
router.init();
|
||||
|
||||
// Page-specific initialization
|
||||
const currentPage = document.body.dataset.page;
|
||||
switch (currentPage) {
|
||||
case 'home':
|
||||
import('./pages/home.js').then(module => module.initHomePage());
|
||||
break;
|
||||
case 'about':
|
||||
import('./pages/about.js').then(module => module.initAboutPage());
|
||||
break;
|
||||
case 'contact':
|
||||
import('./pages/contact.js').then(module => module.initContactPage());
|
||||
break;
|
||||
default:
|
||||
console.log('No specific initialization for this page');
|
||||
}
|
||||
|
||||
console.log('Application initialized');
|
||||
}
|
||||
|
||||
// Run the initialization when the DOM is ready
|
||||
domReady(initializeApp);
|
||||
|
||||
// Expose a global app object if needed
|
||||
window.app = {
|
||||
// Add methods or properties that need to be globally accessible
|
||||
reloadPage: () => {
|
||||
window.location.reload();
|
||||
},
|
||||
navigateTo: (url) => {
|
||||
router.navigateTo(url);
|
||||
}
|
||||
};
|
||||
@@ -126,6 +126,22 @@ function arrayContainsItem(array, itemValue) {
|
||||
function dictHasKey(d, k) {
|
||||
return (k in d);
|
||||
}
|
||||
function areEqualDicts(dict1, dict2) {
|
||||
const keys1 = Object.keys(dict1);
|
||||
const keys2 = Object.keys(dict2);
|
||||
|
||||
if (keys1.length !== keys2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let key of keys1) {
|
||||
if (dict1[key] !== dict2[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function imageExists(url, callback) {
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import API from "../api.js";
|
||||
import DOM from "../dom.js";
|
||||
import { router } from "../router.js";
|
||||
|
||||
export class PageBase {
|
||||
export class BasePage {
|
||||
constructor() {
|
||||
this.title = titlePageCurrent;
|
||||
// this.hash = hashPageCurrent;
|
||||
if (this.constructor === PageBase) {
|
||||
if (this.constructor === BasePage) {
|
||||
throw new Error("Cannot instantiate abstract class");
|
||||
}
|
||||
|
||||
@@ -15,7 +16,7 @@ export class PageBase {
|
||||
}
|
||||
|
||||
initialize() {
|
||||
throw new Error("Method 'init()' must be implemented.");
|
||||
throw new Error("Method 'initialize()' must be implemented.");
|
||||
}
|
||||
|
||||
sharedInitialize() {
|
||||
@@ -237,10 +238,16 @@ export class PageBase {
|
||||
leave() {
|
||||
console.log('Leaving ' + this.title + ' page');
|
||||
_pageCurrent = null;
|
||||
if (this.constructor === PageBase) {
|
||||
if (this.constructor === BasePage) {
|
||||
throw new Error("Must implement leave() method.");
|
||||
}
|
||||
}
|
||||
setLocalStoragePage(dataPage) {
|
||||
setLocalStorage(this.constructor.hash, dataPage);
|
||||
}
|
||||
getLocalStoragePage() {
|
||||
return getLocalStorage(this.constructor.hash);
|
||||
}
|
||||
|
||||
toggleShowButtonsSaveCancel(show, buttonSave = null, buttonCancel = null) {
|
||||
if (buttonSave == null) buttonSave = document.querySelector('form.' + flagFilter + ' button.' + flagSave);
|
||||
@@ -254,14 +261,6 @@ export class PageBase {
|
||||
}
|
||||
}
|
||||
|
||||
refreshDisplayOrders() {
|
||||
let rows = document.querySelectorAll(idTableMain + 'tbody tr.' + flagRow);
|
||||
rows.forEach((row, indexRow) => {
|
||||
sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
sliderDisplayOrder.setAttribute(attrValueCurrent, indexRow);
|
||||
});
|
||||
}
|
||||
|
||||
static isDirtyFilter(filter) {
|
||||
let isDirty = DOM.isElementDirty(filter);
|
||||
if (isDirty) document.querySelectorAll(idTableMain + ' tbody tr').remove();
|
||||
483
static/js/pages/base_table.js
Normal file
483
static/js/pages/base_table.js
Normal file
@@ -0,0 +1,483 @@
|
||||
|
||||
|
||||
import { BasePage } from "./base.js";
|
||||
import API from "../api.js";
|
||||
import DOM from "../dom.js";
|
||||
|
||||
export class TableBasePage extends BasePage {
|
||||
// callFilterTableContent
|
||||
// callSaveTableContent
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
/*
|
||||
if (!this.constructor.callFilterTableContent) {
|
||||
throw new Error(`Class ${this.constructor.name} must have a static callFilterTableContent method attribute that takes a single argument - the filters as json.`);
|
||||
}
|
||||
if (!this.constructor.callSaveTableContent) {
|
||||
throw new Error(`Class ${this.constructor.name} must have a static callSaveTableContent method attribute that takes 3 arguments - a list of records, the filters as json, and a comment for saving.`);
|
||||
}
|
||||
this.initialize();
|
||||
// this.hookupFilters();
|
||||
this.loadRowTable(null);
|
||||
this.getJsonRow(null);
|
||||
// this.hookupTableMain();
|
||||
this.isDirtyRow(null);
|
||||
this.getTableRecords();
|
||||
this.leave();
|
||||
*/
|
||||
// this.cursorXInitial = null;
|
||||
this.cursorYInitial = null;
|
||||
this.rowInitial = null;
|
||||
this.placeholder = null;
|
||||
this.dragSrcEl = null;
|
||||
this.dragSrcRow = null;
|
||||
|
||||
}
|
||||
|
||||
initialize(isPopState = false) {
|
||||
if (this.constructor === TableBasePage) {
|
||||
throw new Error("Must implement initialize() method.");
|
||||
}
|
||||
if (!isPopState) {
|
||||
this.sharedInitialize();
|
||||
this.hookupFilters();
|
||||
this.hookupButtonsAddSaveCancel();
|
||||
this.hookupTableMain();
|
||||
hookupOverlayConfirm(() => {
|
||||
this.leave();
|
||||
this.saveRecordsTableDirty();
|
||||
});
|
||||
} else {
|
||||
let dataPage = this.getLocalStoragePage();
|
||||
let filters = dataPage[flagFormFilters];
|
||||
let formFilters = this.getFormFilters();
|
||||
let filtersDefault = DOM.convertForm2JSON(formFilters);
|
||||
if (!areEqualDicts(filters, filtersDefault)) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
hookupFilters() {
|
||||
if (this.constructor === TableBasePage) {
|
||||
throw new Error("Subclass of TableBasePage must implement method hookupFilters().");
|
||||
}
|
||||
this.hookupButtonApplyFilters();
|
||||
}
|
||||
hookupFilterActive() {
|
||||
initialiseEventHandler(idFormFilters + '.' + flagActive, flagInitialised, (filter) => {
|
||||
filter.addEventListener("change", (event) => {
|
||||
TableBasePage.isDirtyFilter(filter);
|
||||
});
|
||||
});
|
||||
}
|
||||
static isDirtyFilter(filter) {
|
||||
let isDirty = DOM.isElementDirty(filter);
|
||||
if (isDirty) {
|
||||
let tbody = document.querySelector(idTableMain + ' tbody');
|
||||
tbody.querySelectorAll('tr').remove();
|
||||
tbody.appendChild(document.createElement('<div>Press "Apply Filters" to refresh the table.</div>'));
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
hookupButtonApplyFilters() {
|
||||
initialiseEventHandler(idButtonApplyFilters, flagInitialised, (button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
this.getAndLoadFilteredTableContent();
|
||||
});
|
||||
});
|
||||
}
|
||||
getAndLoadFilteredTableContent() {
|
||||
let formFilters = this.getFormFilters();
|
||||
let filtersJson = DOM.convertForm2JSON(formFilters);
|
||||
this.callFilterTableContent(filtersJson)
|
||||
/*
|
||||
.then(data => {
|
||||
console.log('Table data received:', data);
|
||||
this.callbackLoadTableContent(data);
|
||||
})
|
||||
*/
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
getFormFilters() {
|
||||
return document.querySelector(idFormFilters);
|
||||
}
|
||||
callbackLoadTableContent(response) {
|
||||
let table = this.getTableMain();
|
||||
let bodyTable = table.querySelector('tbody');
|
||||
bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); });
|
||||
let rowsJson = response.data[flagRows];
|
||||
if (!isEmpty(rowsJson) && rowsJson.every(row => row.hasOwnProperty('display_order'))) {
|
||||
rowsJson = rowsJson.sort((a, b) => a.display_order - b.display_order);
|
||||
}
|
||||
rowsJson.forEach(this.loadRowTable.bind(this));
|
||||
this.hookupTableMain();
|
||||
}
|
||||
getTableMain() {
|
||||
return document.querySelector(idTableMain);
|
||||
}
|
||||
loadRowTable(rowJson) {
|
||||
throw new Error("Subclass of TableBasePage must implement method loadRowTable().");
|
||||
}
|
||||
hookupButtonsAddSaveCancel() {
|
||||
this.hookupButtonSave();
|
||||
this.hookupButtonCancel();
|
||||
this.hookupButtonAddRowTable();
|
||||
}
|
||||
saveRecordsTableDirty() {
|
||||
let records = this.getTableRecords(true);
|
||||
if (records.length == 0) {
|
||||
showOverlayError('No records to save');
|
||||
return;
|
||||
}
|
||||
let formElement = this.getFormFilters();
|
||||
let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm));
|
||||
this.callSaveTableContent(records, formElement, comment)
|
||||
.then(data => {
|
||||
if (data[flagStatus] == flagSuccess) {
|
||||
console.log('Data received:', data);
|
||||
this.callbackLoadTableContent(data);
|
||||
console.log('Records saved!');
|
||||
}
|
||||
else {
|
||||
showOverlayError(data[flagMessage]);
|
||||
}
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
getTableRecords(dirtyOnly = false) {
|
||||
let table = this.getTableMain();
|
||||
let records = [];
|
||||
let record;
|
||||
table.querySelectorAll('tbody tr').forEach((row) => {
|
||||
if (dirtyOnly && !row.classList.contains(flagDirty)) return;
|
||||
record = this.getJsonRow(row);
|
||||
records.push(record);
|
||||
});
|
||||
return records;
|
||||
}
|
||||
getJsonRow(row) {
|
||||
throw new Error("Subclass of TableBasePage must implement method getJsonRow().");
|
||||
}
|
||||
hookupButtonCancel() {
|
||||
initialiseEventHandler(idFormFilters + ' button.' + flagCancel, flagInitialised, function(button) {
|
||||
button.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
getAndLoadFilteredTableContent();
|
||||
});
|
||||
button.classList.add(flagCollapsed);
|
||||
});
|
||||
}
|
||||
hookupButtonAddRowTable() {
|
||||
initialiseEventHandler(idFormFilters + ' button.' + flagAdd, flagInitialised, (button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
let tbody = document.querySelector(idTableMain + ' tbody');
|
||||
let row = _rowBlank.cloneNode(true);
|
||||
row.classList.remove(flagInitialised);
|
||||
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
|
||||
element.classList.remove(flagInitialised);
|
||||
});
|
||||
let newDisplayOrder = parseInt(tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider).getAttribute(attrValueCurrent)) + 1;
|
||||
tbody.appendChild(row);
|
||||
let slider = tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
if (slider) {
|
||||
slider.setAttribute(attrValueCurrent, newDisplayOrder);
|
||||
slider.setAttribute(attrValuePrevious, newDisplayOrder);
|
||||
}
|
||||
this.hookupTableMain();
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTableMain() {
|
||||
if (this.constructor === TableBasePage) {
|
||||
throw new Error("Must implement hookupTableMain() method.");
|
||||
}
|
||||
if (_rowBlank == null) {
|
||||
this.cacheRowBlank();
|
||||
}
|
||||
}
|
||||
cacheRowBlank() {
|
||||
let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew;
|
||||
let rowBlankTemp = document.querySelector(selectorRowNew);
|
||||
console.log("row blank temp: ", rowBlankTemp);
|
||||
_rowBlank = rowBlankTemp.cloneNode(true);
|
||||
document.querySelectorAll(selectorRowNew).forEach(function(row) {
|
||||
row.remove();
|
||||
});
|
||||
}
|
||||
hookupSlidersDisplayOrderTable() {
|
||||
let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder + ' input.' + flagSlider + '.' + flagDisplayOrder;
|
||||
initialiseEventHandler(selectorDisplayOrder, flagInitialised, (sliderDisplayOrder) => {
|
||||
/*
|
||||
sliderDisplayOrder.setAttribute('draggable', true);
|
||||
sliderDisplayOrder.addEventListener('dragstart', this.handleDragSliderStart.bind(this), false);
|
||||
sliderDisplayOrder.addEventListener('dragenter', this.handleDragSliderEnter.bind(this), false);
|
||||
sliderDisplayOrder.addEventListener('dragover', this.handleDragSliderOver.bind(this), false);
|
||||
sliderDisplayOrder.addEventListener('dragleave', this.handleDragSliderLeave.bind(this), false);
|
||||
sliderDisplayOrder.addEventListener('drop', this.handleDropSlider.bind(this), false);
|
||||
sliderDisplayOrder.addEventListener('dragend', this.handleDragSliderEnd.bind(this), false);
|
||||
*/
|
||||
sliderDisplayOrder.addEventListener('change', (event) => {
|
||||
console.log("slider change event");
|
||||
this.handleChangeElementCellTable(sliderDisplayOrder);
|
||||
});
|
||||
});
|
||||
}
|
||||
/* ToDo: Fix this slider drag and drop functionality
|
||||
handleDragSliderStart(event) {
|
||||
this.dragSrcEl = event.target;
|
||||
event.dataTransfer.effectAllowed = flagMove;
|
||||
/*
|
||||
console.log("setting outer html: ", this.dragSrcEl.outerHTML);
|
||||
event.dataTransfer.setData('text/html', this.dragSrcEl.outerHTML);
|
||||
*
|
||||
this.dragSrcRow = DOM.getRowFromElement(this.dragSrcEl);
|
||||
this.dragSrcEl.classList.add(flagDragging);
|
||||
}
|
||||
handleDragSliderOver(event) {
|
||||
if (event.preventDefault) {
|
||||
event.preventDefault();
|
||||
}
|
||||
event.dataTransfer.dropEffect = flagMove;
|
||||
return false;
|
||||
}
|
||||
handleDragSliderEnter(event) {
|
||||
event.target.closest('tr').classList.add(flagDragOver);
|
||||
}
|
||||
handleDragSliderLeave(event) {
|
||||
event.target.closest('tr').classList.remove(flagDragOver);
|
||||
}
|
||||
handleDropSlider(event) {
|
||||
event.stopPropagation();
|
||||
let targetRow = DOM.getRowFromElement(event.target);
|
||||
if (this.dragSourceRow != targetRow) {
|
||||
targetRow.classList.remove(flagDragOver);
|
||||
this.dragSrcEl.classList.remove(flagDragging);
|
||||
let sourceRowClone = this.dragSrcRow.cloneNode(true);
|
||||
let targetRowClone = targetRow.cloneNode(true);
|
||||
console.log("sourceRowClone: ", sourceRowClone);
|
||||
console.log("targetRowClone: ", targetRowClone);
|
||||
let tbody = targetRow.closest('tbody');
|
||||
tbody.replaceChild(sourceRowClone, targetRow);
|
||||
tbody.replaceChild(targetRowClone, this.dragSrcRow);
|
||||
this.refreshDisplayOrders();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
handleDragSliderEnd(event) {
|
||||
let table = this.getTableMain();
|
||||
let rows = table.querySelectorAll('tr');
|
||||
rows.forEach(row => {
|
||||
row.classList.remove(flagDragOver);
|
||||
row.classList.remove(flagDragging);
|
||||
});
|
||||
}
|
||||
refreshDisplayOrders() {
|
||||
console.log("updating display order values");
|
||||
let rows = document.querySelectorAll(idTableMain + 'tbody tr.' + flagRow);
|
||||
rows.forEach((row, indexRow) => {
|
||||
sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
sliderDisplayOrder.setAttribute(attrValueCurrent, indexRow);
|
||||
});
|
||||
}
|
||||
*/
|
||||
hookupTextareasCodeTable() {
|
||||
let selectorCode = idTableMain + ' tbody tr td.' + flagCode + ' textarea';
|
||||
initialiseEventHandler(selectorCode, flagInitialised, (textareaCode) => {
|
||||
textareaCode.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeElementCellTable(textareaCode);
|
||||
});
|
||||
});
|
||||
}
|
||||
handleChangeElementCellTable(element) {
|
||||
let row = DOM.getRowFromElement(element);
|
||||
let td = DOM.getCellFromElement(element);
|
||||
console.log("td: ", td);
|
||||
let wasDirtyRow = this.isDirtyRow(row);
|
||||
let wasDirtyElement = element.classList.contains(flagDirty);
|
||||
let isDirtyElement = DOM.isElementDirty(element);
|
||||
console.log("isDirtyElement: ", isDirtyElement);
|
||||
console.log("wasDirtyElement: ", wasDirtyElement);
|
||||
if (isDirtyElement != wasDirtyElement) {
|
||||
DOM.handleDirtyElement(td, isDirtyElement);
|
||||
let isNowDirtyRow = this.isDirtyRow(row);
|
||||
console.log("isNowDirtyRow: ", isNowDirtyRow);
|
||||
console.log("wasDirtyRow: ", wasDirtyRow);
|
||||
if (isNowDirtyRow != wasDirtyRow) {
|
||||
DOM.handleDirtyElement(row, isNowDirtyRow);
|
||||
let rows = this.getTableRecords(true);
|
||||
let existsDirtyRecord = rows.length > 0;
|
||||
console.log("dirty records:", rows);
|
||||
console.log("existsDirtyRecord:", existsDirtyRecord);
|
||||
this.toggleShowButtonsSaveCancel(existsDirtyRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
isDirtyRow(row) {
|
||||
throw new Error("Subclass of TableBasePage must implement method isDirtyRow().");
|
||||
}
|
||||
toggleShowButtonsSaveCancel(show, buttonSave = null, buttonCancel = null) {
|
||||
if (buttonSave == null) buttonSave = document.querySelector(idFormFilters + ' button.' + flagSave);
|
||||
if (buttonCancel == null) buttonCancel = document.querySelector(idFormFilters + ' button.' + flagCancel);
|
||||
if (show) {
|
||||
buttonCancel.classList.remove(flagCollapsed);
|
||||
buttonSave.classList.remove(flagCollapsed);
|
||||
} else {
|
||||
buttonCancel.classList.add(flagCollapsed);
|
||||
buttonSave.classList.add(flagCollapsed);
|
||||
}
|
||||
}
|
||||
handleChangeSelectCellTable(element) {
|
||||
let row = DOM.getRowFromElement(element);
|
||||
let td = DOM.getCellFromElement(element);
|
||||
console.log("td: ", td);
|
||||
let wasDirtyRow = this.isDirtyRow(row);
|
||||
let wasDirtyElement = element.classList.contains(flagDirty);
|
||||
let isDirtyElement = DOM.isElementDirty(element);
|
||||
console.log("isDirtyElement: ", isDirtyElement);
|
||||
console.log("wasDirtyElement: ", wasDirtyElement);
|
||||
if (isDirtyElement != wasDirtyElement) {
|
||||
DOM.handleDirtyElement(td, isDirtyElement);
|
||||
let optionSelected = element.options[element.selectedIndex];
|
||||
td.setAttribute(attrIdAccessLevel, optionSelected.value);
|
||||
td.setAttribute(flagAccessLevelRequired, optionSelected.textcontent);
|
||||
let isNowDirtyRow = this.isDirtyRow(row);
|
||||
console.log("isNowDirtyRow: ", isNowDirtyRow);
|
||||
console.log("wasDirtyRow: ", wasDirtyRow);
|
||||
if (isNowDirtyRow != wasDirtyRow) {
|
||||
DOM.handleDirtyElement(row, isNowDirtyRow);
|
||||
let rows = this.getTableRecords(true);
|
||||
let existsDirtyRecord = rows.length > 0;
|
||||
console.log("dirty records:", rows);
|
||||
console.log("existsDirtyRecord:", existsDirtyRecord);
|
||||
this.toggleShowButtonsSaveCancel(existsDirtyRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
hookupTextareasNameTable() {
|
||||
let selectorName = idTableMain + ' tbody tr td.' + flagName + ' textarea';
|
||||
initialiseEventHandler(selectorName, flagInitialised, (textareaName) => {
|
||||
textareaName.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeElementCellTable(textareaName);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTextareasDescriptionTable() {
|
||||
let selectorDescription = idTableMain + ' tbody tr td.' + flagDescription + ' textarea';
|
||||
initialiseEventHandler(selectorDescription, flagInitialised, (textareaDescription) => {
|
||||
textareaDescription.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeElementCellTable(textareaDescription);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupInputsActiveTable() {
|
||||
let selectorActive = idTableMain + ' tbody tr td.' + flagActive + ' input[type="checkbox"]';
|
||||
initialiseEventHandler(selectorActive, flagInitialised, (inputActive) => {
|
||||
inputActive.addEventListener("change", (event) => {
|
||||
console.log("input change event");
|
||||
this.handleChangeElementCellTable(inputActive);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTdsAccessLevel() {
|
||||
initialiseEventHandler(idTableMain + ' tbody td.' + flagAccessLevel, flagInitialised, (tdAccessLevel) => {
|
||||
tdAccessLevel.addEventListener("click", (event) => { this.handleClickTdAccessLevel(event); } );
|
||||
});
|
||||
}
|
||||
handleClickTdAccessLevel(event) {
|
||||
console.log("tdAccessLevel clicked");
|
||||
event.stopPropagation();
|
||||
let tdAccessLevel = DOM.getCellFromElement(event.target);
|
||||
console.log("tdAccessLevel: ", tdAccessLevel);
|
||||
let row = DOM.getRowFromElement(tdAccessLevel);
|
||||
let idAccessLevelSelected = tdAccessLevel.querySelector('div.' + flagAccessLevel).getAttribute(attrIdAccessLevel);
|
||||
let ddlAccessLevel = document.createElement('select');
|
||||
ddlAccessLevel.classList.add(flagAccessLevel);
|
||||
ddlAccessLevel.setAttribute(attrValueCurrent, idAccessLevelSelected);
|
||||
ddlAccessLevel.setAttribute(attrValuePrevious, idAccessLevelSelected);
|
||||
optionsAccessLevel.forEach((accessLevel) => {
|
||||
let option = document.createElement('option');
|
||||
option.value = accessLevel.value;
|
||||
option.textContent = accessLevel.text;
|
||||
if (accessLevel.value == idAccessLevelSelected) option.selected = true;
|
||||
ddlAccessLevel.appendChild(option);
|
||||
});
|
||||
let tdAccessLevelNew = tdAccessLevel.cloneNode(true);
|
||||
tdAccessLevelNew.innerHTML = '';
|
||||
tdAccessLevelNew.appendChild(ddlAccessLevel);
|
||||
row.replaceChild(tdAccessLevelNew, tdAccessLevel);
|
||||
this.hookupDdlsAccessLevelTable();
|
||||
}
|
||||
hookupDdlsAccessLevelTable() {
|
||||
initialiseEventHandler(idTableMain + ' tbody select.' + flagAccessLevel, flagInitialised, (ddlAccessLevel) => {
|
||||
ddlAccessLevel.addEventListener("change", (event) => {
|
||||
event.stopPropagation();
|
||||
this.handleChangeDdlAccessLevelTable(ddlAccessLevel);
|
||||
});
|
||||
});
|
||||
}
|
||||
handleChangeDdlAccessLevelTable(ddlAccessLevel) {
|
||||
let row = DOM.getRowFromElement(ddlAccessLevel);
|
||||
let td = DOM.getCellFromElement(ddlAccessLevel);
|
||||
console.log("td: ", td);
|
||||
let wasDirtyRow = this.isDirtyRow(row);
|
||||
let wasDirtyElement = ddlAccessLevel.classList.contains(flagDirty);
|
||||
let isDirtyElement = DOM.isElementDirty(ddlAccessLevel);
|
||||
console.log("isDirtyElement: ", isDirtyElement);
|
||||
console.log("wasDirtyElement: ", wasDirtyElement);
|
||||
if (isDirtyElement != wasDirtyElement) {
|
||||
DOM.handleDirtyElement(td, isDirtyElement);
|
||||
let optionSelected = ddlAccessLevel.options[ddlAccessLevel.selectedIndex];
|
||||
td.setAttribute(attrIdAccessLevel, optionSelected.value);
|
||||
td.setAttribute(flagAccessLevelRequired, optionSelected.textcontent);
|
||||
let isNowDirtyRow = this.isDirtyRow(row);
|
||||
console.log("isNowDirtyRow: ", isNowDirtyRow);
|
||||
console.log("wasDirtyRow: ", wasDirtyRow);
|
||||
if (isNowDirtyRow != wasDirtyRow) {
|
||||
DOM.handleDirtyElement(row, isNowDirtyRow);
|
||||
let rows = this.getTableRecords(true);
|
||||
let existsDirtyRecord = rows.length > 0;
|
||||
console.log("dirty records:", rows);
|
||||
console.log("existsDirtyRecord:", existsDirtyRecord);
|
||||
this.toggleShowButtonsSaveCancel(existsDirtyRecord);
|
||||
}
|
||||
}
|
||||
}
|
||||
leave() {
|
||||
if (this.constructor === TableBasePage) {
|
||||
throw new Error("Must implement leave() method.");
|
||||
}
|
||||
super.leave();
|
||||
let formFilters = this.getFormFilters();
|
||||
let dataPage = {};
|
||||
dataPage[flagFormFilters] = DOM.convertForm2JSON(formFilters);
|
||||
this.setLocalStoragePage(dataPage);
|
||||
_rowBlank = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Example of a subclass of TableBasePage
|
||||
import { TableBasePage } from "./page_table_base.js";
|
||||
import API from "../api.js";
|
||||
import DOM from "../dom.js";
|
||||
|
||||
export class PageStoreProductCategories extends TableBasePage {
|
||||
static hash = hashPageStoreProductCategories;
|
||||
callFilterTableContent = API.getCategoriesByFilters;
|
||||
|
||||
constructor() {}
|
||||
initialize() {}
|
||||
hookupFilters() {}
|
||||
loadRowTable(rowJson) {}
|
||||
getJsonRow(row) {}
|
||||
hookupTableMain() {}
|
||||
isDirtyRow(row) {}
|
||||
leave() {}
|
||||
}
|
||||
*/
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { router } from "../router.js";
|
||||
import { BasePage } from "../base.js";
|
||||
// import { router } from "../../router.js";
|
||||
|
||||
export class PageAdminHome extends PageBase {
|
||||
export class PageAdminHome extends BasePage {
|
||||
static hash = hashPageAdminHome;
|
||||
|
||||
constructor() {
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageContact extends PageBase {
|
||||
export class PageContact extends BasePage {
|
||||
static hash = hashPageContact;
|
||||
|
||||
constructor() {
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageHome extends PageBase {
|
||||
export class PageHome extends BasePage {
|
||||
static hash = hashPageHome;
|
||||
|
||||
constructor() {
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageServices extends PageBase {
|
||||
export class PageServices extends BasePage {
|
||||
static hash = hashPageServices;
|
||||
|
||||
constructor() {
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageAccessibilityStatement extends PageBase {
|
||||
export class PageAccessibilityStatement extends BasePage {
|
||||
static hash = hashPageAccessibilityStatement;
|
||||
|
||||
constructor() {
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageLicense extends PageBase {
|
||||
export class PageLicense extends BasePage {
|
||||
static hash = hashPageLicense;
|
||||
|
||||
constructor() {
|
||||
@@ -1,174 +0,0 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
|
||||
export class PageStoreHome extends PageBase {
|
||||
static hash = hashPageStoreHome;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
this.hookupFiltersStore();
|
||||
this.hookupStoreHome();
|
||||
}
|
||||
|
||||
|
||||
hookupFiltersStore() {
|
||||
hookupFilterCurrency();
|
||||
hookupFilterDeliveryRegion();
|
||||
hookupFilterIsIncludedVAT();
|
||||
}
|
||||
|
||||
hookupFilterCurrency() {
|
||||
/*
|
||||
let elForm = document.querySelectorAll(idFormCurrency);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormCurrency);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to currency selector controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('select currency', mapHashToController(hashStoreSelectCurrency), ajaxData, function() { window.location.reload() }, false);
|
||||
|
||||
let optionSelected = elSelector.options[elSelector.selectedIndex]
|
||||
let textSelected = optionSelected.attr(attrDataShort)
|
||||
|
||||
});
|
||||
});
|
||||
console.log("form currency initialised")
|
||||
*/
|
||||
|
||||
let dropdownCurrency = document.querySelectorAll(idCurrency)[0];
|
||||
// dropdownCurrency.options.map(function(option) {
|
||||
let option, indexHyphen, textOption;
|
||||
for (let indexOption = 0; indexOption < dropdownCurrency.options.length; indexOption++) {
|
||||
option = document.querySelectorAll(dropdownCurrency.options[indexOption]);
|
||||
textOption = option.text();
|
||||
indexHyphen = textOption.indexOf('-');
|
||||
option.attr(attrTextExpanded, textOption);
|
||||
option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1));
|
||||
option.classList.add(flagCollapsed);
|
||||
}
|
||||
handleSelectCollapse(dropdownCurrency);
|
||||
initialiseEventHandler(dropdownCurrency, flagInitialised, function() {
|
||||
dropdownCurrency = document.querySelectorAll(dropdownCurrency);
|
||||
dropdownCurrency.addEventListener("focus", function() {
|
||||
handleSelectExpand(dropdownCurrency);
|
||||
});
|
||||
dropdownCurrency.addEventListener("blur", function() {
|
||||
handleSelectCollapse(dropdownCurrency);
|
||||
});
|
||||
dropdownCurrency.addEventListener("change", function() {
|
||||
let selectedCurrency = dropdownCurrency.val();
|
||||
console.log("selected currency: ", selectedCurrency);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
basket[keyIdCurrency] = selectedCurrency;
|
||||
// setLocalStorage(keyIdCurrency, selectedCurrency);
|
||||
setLocalStorage(keyBasket, basket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyBasket] = basket;
|
||||
ajaxJSONData('update currency', mapHashToController(hashPageCurrent), ajaxData, loadPageBody, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupFilterDeliveryRegion() {
|
||||
/*
|
||||
let elForm = document.querySelectorAll(idFormDeliveryRegion);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormDeliveryRegion);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to delivery region selector controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('select delivery region', mapHashToController(hashStoreSelectDeliveryRegion), ajaxData, function() { window.location.reload() }, false);
|
||||
});
|
||||
console.log("form delivery region initialised")
|
||||
});
|
||||
*/
|
||||
|
||||
let dropdownRegion = document.querySelectorAll(idRegionDelivery)[0];
|
||||
|
||||
let option, indexHyphen, textOption;
|
||||
for (let indexOption = 0; indexOption < dropdownRegion.options.length; indexOption++) {
|
||||
option = document.querySelectorAll(dropdownRegion.options[indexOption]);
|
||||
textOption = option.text();
|
||||
indexHyphen = textOption.indexOf('-');
|
||||
option.attr(attrTextExpanded, textOption);
|
||||
option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1));
|
||||
option.classList.add(flagCollapsed);
|
||||
}
|
||||
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
|
||||
initialiseEventHandler(dropdownRegion, flagInitialised, function() {
|
||||
dropdownRegion = document.querySelectorAll(dropdownRegion);
|
||||
dropdownRegion.addEventListener("focus", function() {
|
||||
console.log("dropdown region focused");
|
||||
handleSelectExpand(dropdownRegion);
|
||||
});
|
||||
dropdownRegion.addEventListener("blur", function() {
|
||||
console.log("dropdown region blurred");
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
});
|
||||
dropdownRegion.addEventListener("change", function() {
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
let selectedRegion = dropdownRegion.val();
|
||||
console.log("selected region: ", selectedRegion);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
basket[keyIdRegionDelivery] = selectedRegion;
|
||||
// setLocalStorage(keyIdRegionDelivery, selectedRegion);
|
||||
setLocalStorage(keyBasket, basket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyIdRegionDelivery] = selectedRegion;
|
||||
ajaxJSONData('update region', mapHashToController(hashStoreSetRegion), ajaxData, null, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupFilterIsIncludedVAT() {
|
||||
let elForm = document.querySelectorAll(idFormIsIncludedVAT);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('input[type="checkbox"]')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormIsIncludedVAT);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to include VAT controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('set include VAT', mapHashToController(hashStoreSetIsIncludedVAT), ajaxData, function() { window.location.reload() }, false);
|
||||
});
|
||||
console.log("form is included VAT initialised")
|
||||
});
|
||||
}
|
||||
|
||||
hookupStoreCardsProduct() {
|
||||
|
||||
let d; // , lsShared;
|
||||
let selectorCardProduct = '.card.subcard';
|
||||
initialiseEventHandler(selectorCardProduct, flagInitialised, function(cardProduct) {
|
||||
console.log("initialising product card: ", cardProduct);
|
||||
cardProduct.addEventListener("click", function(event) {
|
||||
// d = { keyIdProduct: product.attr(attrIdProduct) }
|
||||
var elemClicked = event.target;
|
||||
if (elemClicked.id != 'submit') { // disable for submit buttons
|
||||
console.log("product click: " + cardProduct.attr(attrIdProduct));
|
||||
console.log("permutation click: " + cardProduct.attr(attrIdPermutation));
|
||||
var d = {}
|
||||
d[keyIdProduct] = cardProduct.attr(attrIdProduct)
|
||||
d[keyIdPermutation] = cardProduct.attr(attrIdPermutation)
|
||||
// send quantity requested
|
||||
goToPage(hashPageStoreProduct, d);
|
||||
}
|
||||
});
|
||||
console.log("click method added for product ID: " + cardProduct.attr(attrIdProduct) + ', permutation ID: ', cardProduct.attr(attrIdPermutation));
|
||||
});
|
||||
}
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
var _rowBlank = null;
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import API from "../api.js";
|
||||
import DOM from "../dom.js";
|
||||
|
||||
export class PageStoreProductCategories extends PageBase {
|
||||
static hash = hashPageStoreProductCategories;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
this.hookupFilters();
|
||||
this.hookupButtonsAddSaveCancel();
|
||||
this.hookupTableMain();
|
||||
hookupOverlayConfirm(() => {
|
||||
this.leave();
|
||||
this.saveCategories();
|
||||
});
|
||||
}
|
||||
|
||||
hookupFilters() {
|
||||
this.hookupFilterIsNotEmpty();
|
||||
this.hookupFilterActive();
|
||||
this.hookupButtonApplyFilters();
|
||||
}
|
||||
|
||||
hookupFilterIsNotEmpty() {
|
||||
initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => {
|
||||
filter.addEventListener("change", (event) => {
|
||||
PageStoreProductCategories.isDirtyFilter(filter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupFilterActive() {
|
||||
initialiseEventHandler('.' + flagActive, flagInitialised, (filter) => {
|
||||
filter.addEventListener("change", (event) => {
|
||||
PageStoreProductCategories.isDirtyFilter(filter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupButtonApplyFilters() {
|
||||
initialiseEventHandler(idButtonApplyFilters, flagInitialised, (button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
this.loadCategories();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadCategories() {
|
||||
|
||||
let elForm = document.querySelector(idFormFiltersProductCategory);
|
||||
API.getCategoriesByFilters(elForm)
|
||||
.then(data => {
|
||||
console.log('Data received:', data);
|
||||
this.callbackLoadCategories(data);
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
|
||||
callbackLoadCategories(response) {
|
||||
|
||||
console.log('ajax:'); console.log(response);
|
||||
|
||||
let table = document.querySelector(idTableMain);
|
||||
let row, sliderDisplayOrder, textareaCode, textareaName, textareaDescription, inputActive;
|
||||
|
||||
// table.querySelector('tr').remove(); // :not(.' + flagRowNew + ')
|
||||
let bodyTable = table.querySelector('tbody');
|
||||
bodyTable.querySelectorAll('tr').forEach(function(row) { row.remove(); });
|
||||
|
||||
let categories = response.data.categories.sort((a, b) => a.display_order - b.display_order);
|
||||
|
||||
categories.forEach((category) => {
|
||||
row = _rowBlank.cloneNode(true);
|
||||
row.classList.remove(flagRowNew);
|
||||
row.classList.remove(flagInitialised);
|
||||
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
|
||||
element.classList.remove(flagInitialised);
|
||||
});
|
||||
console.log("applying data row: ", category);
|
||||
sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
sliderDisplayOrder.setAttribute(attrValueCurrent, category[flagDisplayOrder]);
|
||||
DOM.setElementValuePrevious(sliderDisplayOrder, category[flagDisplayOrder]);
|
||||
DOM.setElementValueCurrent(textareaCode, category[flagCode]);
|
||||
DOM.setElementValuePrevious(textareaCode, category[flagCode]);
|
||||
DOM.setElementValueCurrent(textareaName, category[flagName]);
|
||||
DOM.setElementValuePrevious(textareaName, category[flagName]);
|
||||
DOM.setElementValueCurrent(textareaDescription, category[flagDescription]);
|
||||
DOM.setElementValuePrevious(textareaDescription, category[flagDescription]);
|
||||
DOM.setElementValueCurrent(inputActive, category[flagActive]);
|
||||
DOM.setElementValuePrevious(inputActive, category[flagActive]);
|
||||
row.setAttribute(attrIdCategory, category[attrIdCategory]);
|
||||
bodyTable.appendChild(row);
|
||||
});
|
||||
|
||||
this.hookupTableMain();
|
||||
}
|
||||
|
||||
hookupButtonsAddSaveCancel() {
|
||||
this.hookupButtonSave();
|
||||
|
||||
initialiseEventHandler('form.' + flagFilter + ' button.' + flagCancel, flagInitialised, function(button) {
|
||||
button.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
loadCategories();
|
||||
});
|
||||
button.classList.add(flagCollapsed);
|
||||
});
|
||||
|
||||
initialiseEventHandler('form.' + flagFilter + ' button.' + flagAdd, flagInitialised, (button) => {
|
||||
button.addEventListener("click", (event) => {
|
||||
event.stopPropagation();
|
||||
let tbody = document.querySelector(idTableMain + ' tbody');
|
||||
let row = _rowBlank.cloneNode(true);
|
||||
row.classList.remove(flagInitialised);
|
||||
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
|
||||
element.classList.remove(flagInitialised);
|
||||
});
|
||||
let newDisplayOrder = parseInt(tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider).getAttribute(attrValueCurrent)) + 1;
|
||||
tbody.appendChild(row);
|
||||
let slider = tbody.querySelector('tr:last-child').querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
slider.setAttribute(attrValueCurrent, newDisplayOrder);
|
||||
slider.setAttribute(attrValuePrevious, newDisplayOrder);
|
||||
this.hookupTableMain();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
saveCategories() {
|
||||
|
||||
let categories = this.getCategories(true);
|
||||
|
||||
if (categories.length == 0) {
|
||||
showOverlayError('No categories to save');
|
||||
return;
|
||||
}
|
||||
|
||||
let elForm = document.querySelector(idFormFiltersProductCategory);
|
||||
let comment = DOM.getElementValueCurrent(document.querySelector(idTextareaConfirm)); // idOverlayConfirm + ' ' + textarea
|
||||
API.saveCategories(categories, elForm, comment)
|
||||
.then(data => {
|
||||
console.log('Data received:', data);
|
||||
this.callbackLoadCategories(data);
|
||||
console.log('Categories saved?');
|
||||
})
|
||||
.catch(error => console.error('Error:', error));
|
||||
}
|
||||
|
||||
getCategories(dirtyOnly) {
|
||||
let table = document.querySelector(idTableMain);
|
||||
let categories = [];
|
||||
let category, sliderDisplayOrder, textareaCode, textareaName, textareaDescription, inputActive;
|
||||
table.querySelectorAll('tbody tr').forEach(function(row) {
|
||||
if (dirtyOnly && !row.classList.contains(flagDirty)) return;
|
||||
|
||||
sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
|
||||
category = {};
|
||||
category[attrIdCategory] = row.getAttribute(attrIdCategory);
|
||||
category[flagCode] = DOM.getElementValueCurrent(textareaCode);
|
||||
category[flagName] = DOM.getElementValueCurrent(textareaName);
|
||||
category[flagDescription] = DOM.getElementValueCurrent(textareaDescription);
|
||||
category[flagActive] = DOM.getElementValueCurrent(inputActive);
|
||||
category[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent);
|
||||
categories.push(category);
|
||||
});
|
||||
return categories;
|
||||
}
|
||||
|
||||
hookupTableMain() {
|
||||
this.hookupSlidersDisplayOrder();
|
||||
this.hookupTextareasCode();
|
||||
this.hookupTextareasName();
|
||||
this.hookupTextareasDescription();
|
||||
this.hookupInputsActive();
|
||||
if (_rowBlank == null) {
|
||||
this.cacheRowBlank();
|
||||
}
|
||||
}
|
||||
hookupSlidersDisplayOrder() {
|
||||
let selectorDisplayOrder = idTableMain + ' tbody tr td.' + flagDisplayOrder;
|
||||
initialiseEventHandler(selectorDisplayOrder, flagInitialised, (sliderDisplayOrder) => {
|
||||
sliderDisplayOrder.addEventListener('mousedown', (event) => {
|
||||
this.handleSliderMouseDown(event);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTextareasCode() {
|
||||
let selectorCode = idTableMain + ' tbody tr td.' + flagCode + ' textarea';
|
||||
initialiseEventHandler(selectorCode, flagInitialised, (textareaCode) => {
|
||||
textareaCode.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeInputCategories(textareaCode);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTextareasName() {
|
||||
let selectorName = idTableMain + ' tbody tr td.' + flagName + ' textarea';
|
||||
initialiseEventHandler(selectorName, flagInitialised, (textareaName) => {
|
||||
textareaName.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeInputCategories(textareaName);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupTextareasDescription() {
|
||||
let selectorDescription = idTableMain + ' tbody tr td.' + flagDescription + ' textarea';
|
||||
initialiseEventHandler(selectorDescription, flagInitialised, (textareaDescription) => {
|
||||
textareaDescription.addEventListener("change", (event) => {
|
||||
console.log("textarea change event");
|
||||
this.handleChangeInputCategories(textareaDescription);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupInputsActive() {
|
||||
let selectorActive = idTableMain + ' tbody tr td.' + flagActive + ' input[type="checkbox"]';
|
||||
initialiseEventHandler(selectorActive, flagInitialised, (inputActive) => {
|
||||
inputActive.addEventListener("change", (event) => {
|
||||
console.log("input change event");
|
||||
this.handleChangeInputCategories(inputActive);
|
||||
});
|
||||
});
|
||||
}
|
||||
handleSliderMouseDown(event) {
|
||||
event.stopPropagation();
|
||||
console.log("start drag slider");
|
||||
let slider = event.target;
|
||||
let initialY = event.clientY;
|
||||
let initialRow = DOM.getRowFromElement(slider);
|
||||
let placeholder = document.createElement('tr');
|
||||
placeholder.className = 'placeholder';
|
||||
placeholder.style.height = `${initialRow.offsetHeight}px`;
|
||||
initialRow.parentNode.insertBefore(placeholder, initialRow.nextSibling);
|
||||
initialRow.style.position = 'absolute';
|
||||
initialRow.style.zIndex = '1000';
|
||||
initialRow.style.width = `${initialRow.offsetWidth}px`;
|
||||
|
||||
function onMouseMove(event) {
|
||||
let newY = event.clientY;
|
||||
let deltaY = newY - initialY;
|
||||
initialRow.style.transform = `translateY(${deltaY}px)`;
|
||||
|
||||
let rows = Array.from(initialRow.parentNode.children);
|
||||
let currentIndex = rows.indexOf(initialRow);
|
||||
let placeholderIndex = rows.indexOf(placeholder);
|
||||
|
||||
if (deltaY > 0 && currentIndex < rows.length - 1) {
|
||||
let nextRow = rows[currentIndex + 1];
|
||||
if (newY > nextRow.getBoundingClientRect().top) {
|
||||
initialRow.parentNode.insertBefore(placeholder, nextRow.nextSibling);
|
||||
}
|
||||
} else if (deltaY < 0 && currentIndex > 0) {
|
||||
let prevRow = rows[currentIndex - 1];
|
||||
if (newY < prevRow.getBoundingClientRect().bottom) {
|
||||
initialRow.parentNode.insertBefore(placeholder, prevRow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp() {
|
||||
initialRow.style.position = '';
|
||||
initialRow.style.zIndex = '';
|
||||
initialRow.style.transform = '';
|
||||
placeholder.parentNode.insertBefore(initialRow, placeholder);
|
||||
placeholder.remove();
|
||||
document.removeEventListener('mousemove', onMouseMove);
|
||||
document.removeEventListener('mouseup', onMouseUp);
|
||||
}
|
||||
|
||||
document.addEventListener('mousemove', onMouseMove);
|
||||
document.addEventListener('mouseup', onMouseUp);
|
||||
}
|
||||
cacheRowBlank() {
|
||||
let selectorRowNew = idTableMain + ' tbody tr.' + flagRowNew;
|
||||
let rowBlankTemp = document.querySelector(selectorRowNew);
|
||||
console.log("row blank temp: ", rowBlankTemp);
|
||||
_rowBlank = rowBlankTemp.cloneNode(true);
|
||||
document.querySelectorAll(selectorRowNew).forEach(function(row) {
|
||||
row.remove();
|
||||
});
|
||||
}
|
||||
|
||||
handleChangeInputCategories(element) {
|
||||
console.log("handleChangeInputCategories");
|
||||
console.log("element value:", DOM.getElementValueCurrent(element));
|
||||
let row = DOM.getRowFromElement(element);
|
||||
let wasDirtyRow = this.isRowDirty(row);
|
||||
let wasDirty = element.classList.contains(flagDirty);
|
||||
let isDirty = DOM.isElementDirty(element);
|
||||
if (isDirty != wasDirty) {
|
||||
let isDirtyRow = this.isRowDirty(row);
|
||||
if (isDirtyRow != wasDirtyRow) {
|
||||
let categoriesDirty = this.getCategories(true);
|
||||
let existsDirtyCategory = categoriesDirty.length > 0;
|
||||
console.log("categoriesDirty:", categoriesDirty);
|
||||
console.log("existsDirtyCategory:", existsDirtyCategory);
|
||||
this.toggleShowButtonsSaveCancel(existsDirtyCategory);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
isRowDirty(row) {
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder);
|
||||
let inputCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let inputName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let inputDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) ||
|
||||
inputDescription.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty);
|
||||
if (isDirty) {
|
||||
row.classList.add(flagDirty);
|
||||
} else {
|
||||
row.classList.remove(flagDirty);
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
|
||||
getFiltersDefaults() {
|
||||
return {
|
||||
[flagIsNotEmpty]: true,
|
||||
[flagActive]: true
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,37 +1,146 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
// import { BasePage } from "../base.js";
|
||||
import { DOM } from "../../dom.js";
|
||||
import { isEmpty } from "../../lib/utils.js";
|
||||
|
||||
export class PageStoreHome extends PageBase {
|
||||
export class StoreMixinPage { // extends BasePage {
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
sharedInitialize() {
|
||||
super.sharedInitialize();
|
||||
initialize(thisPage) {
|
||||
console.log('hookup store start for ', DOM.getHashPageCurrent());
|
||||
this.hookupFiltersStore();
|
||||
this.hookupStoreHome();
|
||||
this.hookupLocalStorageStore();
|
||||
this.hookupBasket();
|
||||
this.hookupButtonsAdd2Basket();
|
||||
}
|
||||
|
||||
|
||||
hookupStore() {
|
||||
console.log('hookup store start');
|
||||
console.log(_pathHost);
|
||||
hookupLocalStorageStore();
|
||||
hookupBasket();
|
||||
hookupBtnsAdd2Basket();
|
||||
hookupFiltersStore() {
|
||||
hookupFilterCurrency();
|
||||
hookupFilterDeliveryRegion();
|
||||
hookupFilterIsIncludedVAT();
|
||||
}
|
||||
hookupFilterCurrency() {
|
||||
/*
|
||||
let elForm = document.querySelectorAll(idFormCurrency);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormCurrency);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to currency selector controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('select currency', mapHashToController(hashStoreSelectCurrency), ajaxData, function() { window.location.reload() }, false);
|
||||
|
||||
hookupBasket() {
|
||||
let optionSelected = elSelector.options[elSelector.selectedIndex]
|
||||
let textSelected = optionSelected.attr(attrDataShort)
|
||||
|
||||
});
|
||||
});
|
||||
console.log("form currency initialised")
|
||||
*/
|
||||
|
||||
let dropdownCurrency = document.querySelectorAll(idCurrency)[0];
|
||||
// dropdownCurrency.options.map(function(option) {
|
||||
let option, indexHyphen, textOption;
|
||||
for (let indexOption = 0; indexOption < dropdownCurrency.options.length; indexOption++) {
|
||||
option = document.querySelectorAll(dropdownCurrency.options[indexOption]);
|
||||
textOption = option.text();
|
||||
indexHyphen = textOption.indexOf('-');
|
||||
option.attr(attrTextExpanded, textOption);
|
||||
option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1));
|
||||
option.classList.add(flagCollapsed);
|
||||
}
|
||||
handleSelectCollapse(dropdownCurrency);
|
||||
initialiseEventHandler(dropdownCurrency, flagInitialised, function() {
|
||||
dropdownCurrency = document.querySelectorAll(dropdownCurrency);
|
||||
dropdownCurrency.addEventListener("focus", function() {
|
||||
handleSelectExpand(dropdownCurrency);
|
||||
});
|
||||
dropdownCurrency.addEventListener("blur", function() {
|
||||
handleSelectCollapse(dropdownCurrency);
|
||||
});
|
||||
dropdownCurrency.addEventListener("change", function() {
|
||||
let selectedCurrency = dropdownCurrency.val();
|
||||
console.log("selected currency: ", selectedCurrency);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
basket[keyIdCurrency] = selectedCurrency;
|
||||
// setLocalStorage(keyIdCurrency, selectedCurrency);
|
||||
setLocalStorage(keyBasket, basket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyBasket] = basket;
|
||||
ajaxJSONData('update currency', mapHashToController(hashPageCurrent), ajaxData, loadPageBody, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupFilterDeliveryRegion() {
|
||||
/*
|
||||
let elForm = document.querySelectorAll(idFormDeliveryRegion);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('select')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormDeliveryRegion);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to delivery region selector controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('select delivery region', mapHashToController(hashStoreSelectDeliveryRegion), ajaxData, function() { window.location.reload() }, false);
|
||||
});
|
||||
console.log("form delivery region initialised")
|
||||
});
|
||||
*/
|
||||
|
||||
let dropdownRegion = document.querySelectorAll(idRegionDelivery)[0];
|
||||
|
||||
// const containerBasket = document.querySelectorAll(idContainerBasket);
|
||||
toggleShowBtnCheckout(); // containerBasket
|
||||
hookupBtnCheckout();
|
||||
hookupBtnsPlusMinus();
|
||||
hookupBasketAddInputs();
|
||||
hookupBasketEditInputs();
|
||||
hookupBtnsDelete();
|
||||
}
|
||||
let option, indexHyphen, textOption;
|
||||
for (let indexOption = 0; indexOption < dropdownRegion.options.length; indexOption++) {
|
||||
option = document.querySelectorAll(dropdownRegion.options[indexOption]);
|
||||
textOption = option.text();
|
||||
indexHyphen = textOption.indexOf('-');
|
||||
option.attr(attrTextExpanded, textOption);
|
||||
option.attr(attrTextCollapsed, textOption.substring(0, indexHyphen - 1));
|
||||
option.classList.add(flagCollapsed);
|
||||
}
|
||||
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
|
||||
initialiseEventHandler(dropdownRegion, flagInitialised, function() {
|
||||
dropdownRegion = document.querySelectorAll(dropdownRegion);
|
||||
dropdownRegion.addEventListener("focus", function() {
|
||||
console.log("dropdown region focused");
|
||||
handleSelectExpand(dropdownRegion);
|
||||
});
|
||||
dropdownRegion.addEventListener("blur", function() {
|
||||
console.log("dropdown region blurred");
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
});
|
||||
dropdownRegion.addEventListener("change", function() {
|
||||
handleSelectCollapse(dropdownRegion);
|
||||
let selectedRegion = dropdownRegion.val();
|
||||
console.log("selected region: ", selectedRegion);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
basket[keyIdRegionDelivery] = selectedRegion;
|
||||
// setLocalStorage(keyIdRegionDelivery, selectedRegion);
|
||||
setLocalStorage(keyBasket, basket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyIdRegionDelivery] = selectedRegion;
|
||||
ajaxJSONData('update region', mapHashToController(hashStoreSetRegion), ajaxData, null, false);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupFilterIsIncludedVAT() {
|
||||
let elForm = document.querySelectorAll(idFormIsIncludedVAT);
|
||||
let elSelector = document.querySelectorAll(elForm.querySelector('input[type="checkbox"]')[0]);
|
||||
initialiseEventHandler(elSelector, flagInitialised, function(){
|
||||
elForm = document.querySelectorAll(idFormIsIncludedVAT);
|
||||
elSelector.addEventListener("change", function(event) {
|
||||
ajaxData = {};
|
||||
ajaxData[keyForm] = convertForm2JSON(elForm);
|
||||
console.log('sending data to include VAT controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('set include VAT', mapHashToController(hashStoreSetIsIncludedVAT), ajaxData, function() { window.location.reload() }, false);
|
||||
});
|
||||
console.log("form is included VAT initialised")
|
||||
});
|
||||
}
|
||||
hookupLocalStorageStore() {
|
||||
|
||||
// setupPageLocalStorage(hashPageCurrent);
|
||||
@@ -72,37 +181,21 @@ export class PageStoreHome extends PageBase {
|
||||
console.log('ajax:' + ajaxData);
|
||||
ajaxJSONData(keyBasket, mapHashToController(hashStoreBasketLoad), ajaxData, loadBasket, false);
|
||||
}
|
||||
|
||||
/*
|
||||
setupPageLocalStorageNextStore(pageHashNext) {
|
||||
let lsOld = getPageLocalStorage(hashPageCurrent);
|
||||
hashPageCurrent = pageHashNext;
|
||||
clearPageLocalStorage(hashPageCurrent);
|
||||
setupPageLocalStorage(hashPageCurrent);
|
||||
let lsNew = getPageLocalStorage(hashPageCurrent);
|
||||
lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};
|
||||
setPageLocalStorage(hashPageCurrent, lsNew);
|
||||
}
|
||||
|
||||
goToPageStore(pageHash, parameters_dict) {
|
||||
hookupBasket() {
|
||||
|
||||
let lsOld = getPageLocalStorage(pageHashCurrent);
|
||||
pageHashCurrent = pageHash;
|
||||
clearPageLocalStorage(pageHashCurrent);
|
||||
setupPageLocalStorage(pageHashCurrent);
|
||||
let lsNew = getPageLocalStorage(pageHashCurrent);
|
||||
lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};
|
||||
setPageLocalStorage(pageHashCurrent, lsNew);
|
||||
|
||||
goToPage(pageHash, parameters_dict);
|
||||
// const containerBasket = document.querySelectorAll(idContainerBasket);
|
||||
this.toggleShowButtonCheckout(); // containerBasket
|
||||
this.hookupButtonCheckout();
|
||||
this.hookupBasketItemPlusAndMinusButtons();
|
||||
this.hookupBasketAddInputs();
|
||||
this.hookupBasketEditInputs();
|
||||
this.hookupDeleteBasketItemButtons();
|
||||
}
|
||||
*/
|
||||
|
||||
toggleShowBtnCheckout() { // containerBasket
|
||||
toggleShowButtonCheckout() { // containerBasket
|
||||
|
||||
console.log("toggling checkout button");
|
||||
|
||||
const btnCheckout = document.querySelectorAll(idBtnCheckout);
|
||||
const btnCheckout = document.querySelectorAll(idButtonCheckout);
|
||||
const labelBasketEmpty = document.querySelectorAll(idLabelBasketEmpty);
|
||||
|
||||
// let lsPage = getPageLocalStorage(hashPageCurrent);
|
||||
@@ -118,6 +211,164 @@ export class PageStoreHome extends PageBase {
|
||||
labelBasketEmpty.style.display = "none";
|
||||
}
|
||||
}
|
||||
hookupButtonCheckout() {
|
||||
|
||||
console.log("hooking up checkout button");
|
||||
|
||||
const btnCheckout = document.querySelectorAll(idButtonCheckout);
|
||||
// let lsPage = getPageLocalStorage(hashPageCurrent);
|
||||
initialiseEventHandler(btnCheckout, flagInitialised, function() {
|
||||
btnCheckout.addEventListener("click", function() {
|
||||
/*
|
||||
//setupPageLocalStorageNext(hashPageStoreBasket);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
// goToPage(hashPageStoreBasket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyBasket] = basket;
|
||||
|
||||
ajaxJSONData('checkout', mapHashToController(hashPageStoreBasket), ajaxData, null, false);
|
||||
*/
|
||||
goToPage(hashPageStoreBasket);
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupBasketItemPlusAndMinusButtons() {
|
||||
const minVal = 1;
|
||||
// Basket Add
|
||||
// Increment
|
||||
document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elButton = this;
|
||||
initialiseEventHandler(elButton, flagInitialised, function(){
|
||||
elButton.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elButton)).querySelector('input[type="number"]');
|
||||
// console.log('input selector ='); console.log('form[' + attrFormType + '=' + elButton.attr(attrFormType) + '][' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + ']');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal += 1;
|
||||
elInput.val(newVal);
|
||||
});
|
||||
});
|
||||
});
|
||||
// Decrement
|
||||
document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elButton = this;
|
||||
initialiseEventHandler(elButton, flagInitialised, function(){
|
||||
elButton.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// let product = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elButton.attr(attrIdProduct) + ']');
|
||||
let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elButton)).querySelector('input[type="number"]');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal = Math.max(minVal, newVal - 1);
|
||||
elInput.val(newVal);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basket Edit
|
||||
// Increment
|
||||
document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elButton = this;
|
||||
initialiseEventHandler(elButton, flagInitialised, function(){
|
||||
elButton.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
// basketItem = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elButton.attr(attrIdProduct) + ']');
|
||||
let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elButton)).querySelector('input[type="number"]');
|
||||
// console.log('input selector ='); console.log('form[' + attrFormType + '=' + elButton.attr(attrFormType) + '][' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + ']');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal += 1;
|
||||
elInput.val(newVal);
|
||||
elInput.trigger("change");
|
||||
});
|
||||
});
|
||||
});
|
||||
// Decrement
|
||||
document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elButton = this;
|
||||
initialiseEventHandler(elButton, flagInitialised, function(){
|
||||
elButton.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elButton)).querySelector('input[type="number"]');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal = Math.max(minVal, newVal - 1);
|
||||
elInput.val(newVal);
|
||||
elInput.trigger("change");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupBasketAddInputs() {
|
||||
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elInput = elForm.querySelector('input[type="number"]');
|
||||
initialiseEventHandler(elInput, flagInitialised, function(){
|
||||
elInput.addEventListener("change", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
elInput.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupBasketEditInputs() {
|
||||
|
||||
// let elButton, elInput, newVal, product;
|
||||
const minVal = 1;
|
||||
// Basket Edit
|
||||
// Increment
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elInput = elForm.querySelector('input[type="number"]');
|
||||
initialiseEventHandler(elInput, flagInitialised, function(){
|
||||
elInput.addEventListener("change", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// let lsPage = getPageLocalStorageCurrent();
|
||||
d = {};
|
||||
d[keyBasket]= getLocalStorage(keyBasket); // lsPage[keyBasket]; // JSON.parse(lsPage[keyBasket]);
|
||||
d[keyIdProduct] = elForm.attr(attrIdProduct); // lsPage[keyIdProduct];
|
||||
d[keyIdPermutation] = elForm.attr(attrIdPermutation);
|
||||
// d[keyQuantity] = lsPage[keyQuantity];
|
||||
d[keyForm] = convertForm2JSON(elForm);
|
||||
d[keyForm][keyQuantity] = elInput.val();
|
||||
console.log('sending data to basket edit controller: '); console.log(d);
|
||||
ajaxJSONData('basket update', mapHashToController(hashStoreBasketEdit), d, loadBasket, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
hookupDeleteBasketItemButtons() {
|
||||
|
||||
console.log('hooking up basket item delete buttons');
|
||||
// let elForm, elDelete;
|
||||
// const minVal = 1;
|
||||
// Basket Add
|
||||
// Increment
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elDelete = elForm.querySelector('a.' + flagBasketItemDelete);
|
||||
initialiseEventHandler(elDelete, flagInitialised, function(){
|
||||
elDelete.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
ajaxData = {};
|
||||
ajaxData[keyBasket]= getLocalStorage(keyBasket);
|
||||
ajaxData[keyIdProduct] = elForm.attr(attrIdProduct);
|
||||
ajaxData[keyIdPermutation] = elForm.attr(attrIdPermutation);
|
||||
console.log('sending data to basket delete controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('basket update', mapHashToController(hashStoreBasketDelete), ajaxData, loadBasket, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
getBasket() {
|
||||
@@ -128,10 +379,10 @@ export class PageStoreHome extends PageBase {
|
||||
}
|
||||
*/
|
||||
|
||||
hookupBtnsAdd2Basket() {
|
||||
hookupButtonsAdd2Basket() {
|
||||
|
||||
// let product, btn, lsPage;
|
||||
// [' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']
|
||||
// [' + attrIdProduct + '=' + elButton.attr(attrIdProduct) + ']
|
||||
document.querySelectorAll('form[' + attrFormType + '="' + typeFormBasketAdd +'"]').each(function() {
|
||||
|
||||
var form = this;
|
||||
@@ -159,28 +410,6 @@ export class PageStoreHome extends PageBase {
|
||||
});
|
||||
}
|
||||
|
||||
hookupBtnCheckout() {
|
||||
|
||||
console.log("hooking up checkout button");
|
||||
|
||||
const btnCheckout = document.querySelectorAll(idBtnCheckout);
|
||||
// let lsPage = getPageLocalStorage(hashPageCurrent);
|
||||
initialiseEventHandler(btnCheckout, flagInitialised, function() {
|
||||
btnCheckout.addEventListener("click", function() {
|
||||
/*
|
||||
//setupPageLocalStorageNext(hashPageStoreBasket);
|
||||
let basket = getLocalStorage(keyBasket);
|
||||
// goToPage(hashPageStoreBasket);
|
||||
let ajaxData = {};
|
||||
ajaxData[keyBasket] = basket;
|
||||
|
||||
ajaxJSONData('checkout', mapHashToController(hashPageStoreBasket), ajaxData, null, false);
|
||||
*/
|
||||
goToPage(hashPageStoreBasket);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadBasket(response) {
|
||||
|
||||
let basketContainer = document.querySelectorAll(idBasketContainer);
|
||||
@@ -223,148 +452,7 @@ export class PageStoreHome extends PageBase {
|
||||
return 'form[' + attrFormType + '="' + typeForm + '"][' + attrIdProduct + '=' + elementInForm.attr(attrIdProduct) + ']' + selectorIdPermutation;
|
||||
}
|
||||
|
||||
hookupBtnsPlusMinus() {
|
||||
|
||||
// let elBtn, elInput, newVal, product;
|
||||
const minVal = 1;
|
||||
// Basket Add
|
||||
// Increment
|
||||
document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elBtn = this;
|
||||
initialiseEventHandler(elBtn, flagInitialised, function(){
|
||||
elBtn.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elBtn)).querySelector('input[type="number"]');
|
||||
// console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal += 1;
|
||||
elInput.val(newVal);
|
||||
});
|
||||
});
|
||||
});
|
||||
// Decrement
|
||||
document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elBtn = this;
|
||||
initialiseEventHandler(elBtn, flagInitialised, function(){
|
||||
elBtn.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// let product = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']');
|
||||
let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketAdd, elBtn)).querySelector('input[type="number"]');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal = Math.max(minVal, newVal - 1);
|
||||
elInput.val(newVal);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Basket Edit
|
||||
// Increment
|
||||
document.querySelectorAll('div.btn-increment[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elBtn = this;
|
||||
initialiseEventHandler(elBtn, flagInitialised, function(){
|
||||
elBtn.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
// basketItem = document.querySelectorAll('.card.subcard[' + attrIdProduct +'=' + elBtn.attr(attrIdProduct) + ']');
|
||||
let elInput = document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elBtn)).querySelector('input[type="number"]');
|
||||
// console.log('input selector ='); console.log('form[' + attrFormType + '=' + elBtn.attr(attrFormType) + '][' + attrIdProduct + '=' + elBtn.attr(attrIdProduct) + ']');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal += 1;
|
||||
elInput.val(newVal);
|
||||
elInput.trigger("change");
|
||||
});
|
||||
});
|
||||
});
|
||||
// Decrement
|
||||
document.querySelectorAll('div.btn-decrement[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elBtn = this;
|
||||
initialiseEventHandler(elBtn, flagInitialised, function(){
|
||||
elBtn.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
let elInput= document.querySelectorAll(getFormProductSelector(typeFormBasketEdit, elBtn)).querySelector('input[type="number"]');
|
||||
let newVal = parseInt(getElementCurrentValue(elInput));
|
||||
if (isNaN(newVal)) newVal = minVal;
|
||||
newVal = Math.max(minVal, newVal - 1);
|
||||
elInput.val(newVal);
|
||||
elInput.trigger("change");
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupBasketAddInputs() {
|
||||
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketAdd + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elInput = elForm.querySelector('input[type="number"]');
|
||||
initialiseEventHandler(elInput, flagInitialised, function(){
|
||||
elInput.addEventListener("change", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
elInput.addEventListener("click", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupBasketEditInputs() {
|
||||
|
||||
// let elBtn, elInput, newVal, product;
|
||||
const minVal = 1;
|
||||
// Basket Edit
|
||||
// Increment
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elInput = elForm.querySelector('input[type="number"]');
|
||||
initialiseEventHandler(elInput, flagInitialised, function(){
|
||||
elInput.addEventListener("change", function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
// let lsPage = getPageLocalStorageCurrent();
|
||||
d = {};
|
||||
d[keyBasket]= getLocalStorage(keyBasket); // lsPage[keyBasket]; // JSON.parse(lsPage[keyBasket]);
|
||||
d[keyIdProduct] = elForm.attr(attrIdProduct); // lsPage[keyIdProduct];
|
||||
d[keyIdPermutation] = elForm.attr(attrIdPermutation);
|
||||
// d[keyQuantity] = lsPage[keyQuantity];
|
||||
d[keyForm] = convertForm2JSON(elForm);
|
||||
d[keyForm][keyQuantity] = elInput.val();
|
||||
console.log('sending data to basket edit controller: '); console.log(d);
|
||||
ajaxJSONData('basket update', mapHashToController(hashStoreBasketEdit), d, loadBasket, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hookupBtnsDelete() {
|
||||
|
||||
console.log('hooking up basket item delete buttons');
|
||||
// let elForm, elDelete;
|
||||
// const minVal = 1;
|
||||
// Basket Add
|
||||
// Increment
|
||||
document.querySelectorAll('form[' + attrFormType + '=' + typeFormBasketEdit + ']').each(function() {
|
||||
let elForm = this;
|
||||
let elDelete = elForm.querySelector('a.' + flagBasketItemDelete);
|
||||
initialiseEventHandler(elDelete, flagInitialised, function(){
|
||||
elDelete.addEventListener("click", function(event) {
|
||||
event.stopPropagation();
|
||||
ajaxData = {};
|
||||
ajaxData[keyBasket]= getLocalStorage(keyBasket);
|
||||
ajaxData[keyIdProduct] = elForm.attr(attrIdProduct);
|
||||
ajaxData[keyIdPermutation] = elForm.attr(attrIdPermutation);
|
||||
console.log('sending data to basket delete controller: '); console.log(ajaxData);
|
||||
ajaxJSONData('basket update', mapHashToController(hashStoreBasketDelete), ajaxData, loadBasket, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
getCurrencySelected() {
|
||||
let elementSelectorCurrency = document.querySelectorAll(idSelectorCurrency);
|
||||
@@ -379,4 +467,52 @@ export class PageStoreHome extends PageBase {
|
||||
jsonData[keyIsIncludedVAT] = getLocalStorage(keyIsIncludedVAT);
|
||||
return jsonData;
|
||||
}
|
||||
|
||||
hookupStoreCardsProduct() {
|
||||
|
||||
let d; // , lsShared;
|
||||
let selectorCardProduct = '.card.subcard';
|
||||
initialiseEventHandler(selectorCardProduct, flagInitialised, function(cardProduct) {
|
||||
console.log("initialising product card: ", cardProduct);
|
||||
cardProduct.addEventListener("click", function(event) {
|
||||
// d = { keyIdProduct: product.attr(attrIdProduct) }
|
||||
var elemClicked = event.target;
|
||||
if (elemClicked.id != 'submit') { // disable for submit buttons
|
||||
console.log("product click: " + cardProduct.attr(attrIdProduct));
|
||||
console.log("permutation click: " + cardProduct.attr(attrIdPermutation));
|
||||
var d = {}
|
||||
d[keyIdProduct] = cardProduct.attr(attrIdProduct)
|
||||
d[keyIdPermutation] = cardProduct.attr(attrIdPermutation)
|
||||
// send quantity requested
|
||||
goToPage(hashPageStoreProduct, d);
|
||||
}
|
||||
});
|
||||
console.log("click method added for product ID: " + cardProduct.attr(attrIdProduct) + ', permutation ID: ', cardProduct.attr(attrIdPermutation));
|
||||
});
|
||||
}
|
||||
|
||||
leave() {
|
||||
let lsOld = getPageLocalStorage(hashPageCurrent);
|
||||
hashPageCurrent = pageHashNext;
|
||||
clearPageLocalStorage(hashPageCurrent);
|
||||
setupPageLocalStorage(hashPageCurrent);
|
||||
let lsNew = getPageLocalStorage(hashPageCurrent);
|
||||
lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};
|
||||
setPageLocalStorage(hashPageCurrent, lsNew);
|
||||
}
|
||||
|
||||
/*
|
||||
loadFiltersFromLocalStorage(pageHash, parameters_dict) {
|
||||
|
||||
let lsOld = getPageLocalStorage(pageHashCurrent);
|
||||
pageHashCurrent = pageHash;
|
||||
clearPageLocalStorage(pageHashCurrent);
|
||||
setupPageLocalStorage(pageHashCurrent);
|
||||
let lsNew = getPageLocalStorage(pageHashCurrent);
|
||||
lsNew[keyBasket] = (keyBasket in lsOld) ? lsOld[keyBasket] : {'items': []};
|
||||
setPageLocalStorage(pageHashCurrent, lsNew);
|
||||
|
||||
goToPage(pageHash, parameters_dict);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageStoreBasket extends PageBase {
|
||||
export class PageStoreBasket extends BasePage {
|
||||
static hash = hashPageStoreBasket;
|
||||
|
||||
constructor() {
|
||||
@@ -11,7 +11,7 @@ export class PageStoreBasket extends PageBase {
|
||||
this.sharedInitialize();
|
||||
this.hookupStoreCardsInfo();
|
||||
this.hookupOverlaysStoreBasketInfo();
|
||||
this.hookupBtnCheckoutSession();
|
||||
this.hookupButtonCheckoutSession();
|
||||
}
|
||||
|
||||
|
||||
@@ -134,10 +134,10 @@ export class PageStoreBasket extends PageBase {
|
||||
return ajaxData;
|
||||
}
|
||||
|
||||
hookupBtnCheckoutSession() {
|
||||
let btnCheckout = document.querySelectorAll(idBtnCheckout);
|
||||
hookupButtonCheckoutSession() {
|
||||
let btnCheckout = document.querySelectorAll(idButtonCheckout);
|
||||
btnCheckout.classList.remove(flagInitialised);
|
||||
initialiseEventHandler(idBtnCheckout, flagInitialised, function() {
|
||||
initialiseEventHandler(idButtonCheckout, flagInitialised, function() {
|
||||
|
||||
btnCheckout.removeEventListener("click");
|
||||
btnCheckout.addEventListener("click", function(event) {
|
||||
@@ -165,12 +165,12 @@ export class PageStoreBasket extends PageBase {
|
||||
window.location.href = response.data[keyUrlCheckout]
|
||||
}
|
||||
|
||||
hookupBtnFormBillingCopy() {
|
||||
hookupButtonFormBillingCopy() {
|
||||
|
||||
// let elBtn = document.querySelectorAll(idBtnFormBillingCopy);
|
||||
// let elButton = document.querySelectorAll(idButtonFormBillingCopy);
|
||||
|
||||
initialiseEventHandler(idBtnFormBillingCopy, flagInitialised, function() {
|
||||
document.querySelectorAll(idBtnFormBillingCopy).addEventListener("click", function (event) {
|
||||
initialiseEventHandler(idButtonFormBillingCopy, flagInitialised, function() {
|
||||
document.querySelectorAll(idButtonFormBillingCopy).addEventListener("click", function (event) {
|
||||
|
||||
let keys = [keyNameFull, keyPhoneNumber, keyPostcode, keyAddress1, keyAddress2, keyCity, keyCounty];
|
||||
|
||||
20
static/js/pages/store/home.js
Normal file
20
static/js/pages/store/home.js
Normal file
@@ -0,0 +1,20 @@
|
||||
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageStoreHome extends BasePage {
|
||||
static hash = hashPageStoreHome;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
this.hookupFiltersStore();
|
||||
this.hookupStoreHome();
|
||||
}
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
}
|
||||
129
static/js/pages/store/product_categories.js
Normal file
129
static/js/pages/store/product_categories.js
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
import { TableBasePage } from "../base_table.js";
|
||||
import API from "../../api.js";
|
||||
import DOM from "../../dom.js";
|
||||
|
||||
export class PageStoreProductCategories extends TableBasePage {
|
||||
static hash = hashPageStoreProductCategories;
|
||||
callFilterTableContent = API.getCategoriesByFilters;
|
||||
callSaveTableContent = API.saveCategories;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
hookupFilters() {
|
||||
super.hookupFilters();
|
||||
this.hookupFilterIsNotEmpty();
|
||||
this.hookupFilterActive();
|
||||
}
|
||||
hookupFilterIsNotEmpty() {
|
||||
initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => {
|
||||
filter.addEventListener("change", (event) => {
|
||||
PageStoreProductCategories.isDirtyFilter(filter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadRowTable(rowJson) {
|
||||
if (rowJson == null) return;
|
||||
let row = _rowBlank.cloneNode(true);
|
||||
row.classList.remove(flagRowNew);
|
||||
row.classList.remove(flagInitialised);
|
||||
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
|
||||
element.classList.remove(flagInitialised);
|
||||
});
|
||||
console.log("applying data row: ", rowJson);
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
let textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let tdAccessLevel = row.querySelector('td.' + flagAccessLevel);
|
||||
let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel);
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
|
||||
sliderDisplayOrder.setAttribute(attrValueCurrent, rowJson[flagDisplayOrder]);
|
||||
DOM.setElementValuePrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]);
|
||||
DOM.setElementValueCurrent(textareaCode, rowJson[flagCode]);
|
||||
DOM.setElementValuePrevious(textareaCode, rowJson[flagCode]);
|
||||
DOM.setElementValueCurrent(textareaName, rowJson[flagName]);
|
||||
DOM.setElementValuePrevious(textareaName, rowJson[flagName]);
|
||||
DOM.setElementValueCurrent(textareaDescription, rowJson[flagDescription]);
|
||||
DOM.setElementValuePrevious(textareaDescription, rowJson[flagDescription]);
|
||||
tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]);
|
||||
divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
DOM.setElementValueCurrent(divAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
DOM.setElementValuePrevious(divAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
divAccessLevel.textContent = rowJson[flagAccessLevelRequired];
|
||||
DOM.setElementValueCurrent(inputActive, rowJson[flagActive]);
|
||||
DOM.setElementValuePrevious(inputActive, rowJson[flagActive]);
|
||||
row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]);
|
||||
|
||||
let table = this.getTableMain();
|
||||
let bodyTable = table.querySelector('tbody');
|
||||
bodyTable.appendChild(row);
|
||||
}
|
||||
getJsonRow(row) {
|
||||
if (row == null) return;
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
let textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let tdAccessLevel = row.querySelector('td.' + flagAccessLevel);
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
|
||||
let jsonCategory = {};
|
||||
jsonCategory[attrIdCategory] = row.getAttribute(attrIdCategory);
|
||||
jsonCategory[flagCode] = DOM.getElementValueCurrent(textareaCode);
|
||||
jsonCategory[flagName] = DOM.getElementValueCurrent(textareaName);
|
||||
jsonCategory[flagDescription] = DOM.getElementValueCurrent(textareaDescription);
|
||||
jsonCategory[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired);
|
||||
jsonCategory[attrIdAccessLevel] = tdAccessLevel.getAttribute(attrIdAccessLevel);
|
||||
jsonCategory[flagActive] = DOM.getElementValueCurrent(inputActive);
|
||||
jsonCategory[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent);
|
||||
return jsonCategory;
|
||||
}
|
||||
|
||||
hookupTableMain() {
|
||||
super.hookupTableMain();
|
||||
this.hookupSlidersDisplayOrderTable();
|
||||
this.hookupTextareasCodeTable();
|
||||
this.hookupTextareasNameTable();
|
||||
this.hookupTextareasDescriptionTable();
|
||||
this.hookupTdsAccessLevel();
|
||||
this.hookupInputsActiveTable();
|
||||
}
|
||||
|
||||
isDirtyRow(row) {
|
||||
if (row == null) return false;
|
||||
console.log("Product Category isDirtyRow");
|
||||
console.log("row: ", row);
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder);
|
||||
let inputCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let inputName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let inputDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let tdAccessLevel = row.querySelector('td.' + flagAccessLevel);
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
let isDirty = sliderDisplayOrder.classList.contains(flagDirty) || inputCode.classList.contains(flagDirty) || inputName.classList.contains(flagDirty) ||
|
||||
inputDescription.classList.contains(flagDirty) || tdAccessLevel.classList.contains(flagDirty) || inputActive.classList.contains(flagDirty);
|
||||
DOM.handleDirtyElement(row, isDirty);
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
|
||||
getFiltersDefaults() {
|
||||
filters = {};
|
||||
filters.flagIsNotEmpty = true;
|
||||
filters.flagActive = true;
|
||||
return filters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
var _rowBlank = null;
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageStoreProductPermutations extends PageBase {
|
||||
export class PageStoreProductPermutations extends BasePage {
|
||||
static hash = hashPageStoreProductPermutations;
|
||||
|
||||
constructor() {
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
var _rowBlank = null;
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
|
||||
export class PageStoreStockItems extends PageBase {
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageStoreStockItems extends BasePage {
|
||||
static hash = hashPageStoreStockItems;
|
||||
|
||||
constructor() {
|
||||
@@ -12,8 +12,8 @@ export class PageStoreStockItems extends PageBase {
|
||||
|
||||
initialize() {
|
||||
this.sharedInitialize();
|
||||
hookupFilters();
|
||||
hookupButtonsSaveCancel();
|
||||
this.hookupFilters();
|
||||
this.hookupButtonsSaveCancel();
|
||||
hookupTableMain();
|
||||
hookupOverlayConfirm(savePermutations);
|
||||
}
|
||||
@@ -213,7 +213,7 @@ export class PageStoreStockItems extends PageBase {
|
||||
let table = document.querySelectorAll(idTableMain);
|
||||
let rowBlankTemp = table.querySelector('tr.' + flagRowNew);
|
||||
console.log("row blank temp: ", rowBlankTemp);
|
||||
_rowBlank = rowBlankTemp[0].cloneNode(true);
|
||||
_rowBlank = rowBlankTemp.cloneNode(true);
|
||||
table.querySelector('tr.' + flagRowNew).remove();
|
||||
|
||||
/*
|
||||
@@ -370,8 +370,138 @@ export class PageStoreStockItems extends PageBase {
|
||||
});
|
||||
return variations.join(',');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
import { TableBasePage } from "../base_table.js";
|
||||
import API from "../../api.js";
|
||||
import DOM from "../../dom.js";
|
||||
|
||||
export class PageStoreProductCategories extends TableBasePage {
|
||||
static hash = hashPageStoreProductCategories;
|
||||
callFilterTableContent = API.getCategoriesByFilters;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
}
|
||||
|
||||
initialize() {
|
||||
super.initialize();
|
||||
}
|
||||
|
||||
hookupFilters() {
|
||||
super.hookupFilters();
|
||||
this.hookupFilterIsNotEmpty();
|
||||
this.hookupFilterActive();
|
||||
}
|
||||
hookupFilterIsNotEmpty() {
|
||||
initialiseEventHandler('.' + flagIsNotEmpty, flagInitialised, (filter) => {
|
||||
filter.addEventListener("change", (event) => {
|
||||
PageStoreProductCategories.isDirtyFilter(filter);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
loadRowTable(rowJson) {
|
||||
if (rowJson == null) return;
|
||||
let row = _rowBlank.cloneNode(true);
|
||||
row.classList.remove(flagRowNew);
|
||||
row.classList.remove(flagInitialised);
|
||||
row.querySelectorAll('.' + flagInitialised).forEach(function(element) {
|
||||
element.classList.remove(flagInitialised);
|
||||
});
|
||||
console.log("applying data row: ", rowJson);
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
let textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let tdAccessLevel = row.querySelector('td.' + flagAccessLevel);
|
||||
let divAccessLevel = tdAccessLevel.querySelector('div.' + flagAccessLevel);
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
|
||||
sliderDisplayOrder.setAttribute(attrValueCurrent, rowJson[flagDisplayOrder]);
|
||||
DOM.setElementValuePrevious(sliderDisplayOrder, rowJson[flagDisplayOrder]);
|
||||
DOM.setElementValueCurrent(textareaCode, rowJson[flagCode]);
|
||||
DOM.setElementValuePrevious(textareaCode, rowJson[flagCode]);
|
||||
DOM.setElementValueCurrent(textareaName, rowJson[flagName]);
|
||||
DOM.setElementValuePrevious(textareaName, rowJson[flagName]);
|
||||
DOM.setElementValueCurrent(textareaDescription, rowJson[flagDescription]);
|
||||
DOM.setElementValuePrevious(textareaDescription, rowJson[flagDescription]);
|
||||
tdAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
tdAccessLevel.setAttribute(flagAccessLevelRequired, rowJson[flagAccessLevelRequired]);
|
||||
divAccessLevel.setAttribute(attrIdAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
DOM.setElementValueCurrent(divAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
DOM.setElementValuePrevious(divAccessLevel, rowJson[attrIdAccessLevel]);
|
||||
divAccessLevel.textContent = rowJson[flagAccessLevelRequired];
|
||||
DOM.setElementValueCurrent(inputActive, rowJson[flagActive]);
|
||||
DOM.setElementValuePrevious(inputActive, rowJson[flagActive]);
|
||||
row.setAttribute(rowJson[flagKeyPrimary], rowJson[rowJson[flagKeyPrimary]]);
|
||||
|
||||
let table = this.getTableMain();
|
||||
let bodyTable = table.querySelector('tbody');
|
||||
bodyTable.appendChild(row);
|
||||
}
|
||||
getJsonRow(row) {
|
||||
if (row == null) return;
|
||||
let sliderDisplayOrder = row.querySelector('td.' + flagDisplayOrder + ' .' + flagSlider);
|
||||
let textareaCode = row.querySelector('td.' + flagCode + ' textarea');
|
||||
let textareaName = row.querySelector('td.' + flagName + ' textarea');
|
||||
let textareaDescription = row.querySelector('td.' + flagDescription + ' textarea');
|
||||
let tdAccessLevel = row.querySelector('td.' + flagAccessLevel);
|
||||
let inputActive = row.querySelector('td.' + flagActive + ' input[type="checkbox"]');
|
||||
|
||||
let jsonCategory = {};
|
||||
jsonCategory[attrIdCategory] = row.getAttribute(attrIdCategory);
|
||||
jsonCategory[flagCode] = DOM.getElementValueCurrent(textareaCode);
|
||||
jsonCategory[flagName] = DOM.getElementValueCurrent(textareaName);
|
||||
jsonCategory[flagDescription] = DOM.getElementValueCurrent(textareaDescription);
|
||||
jsonCategory[flagAccessLevelRequired] = tdAccessLevel.getAttribute(flagAccessLevelRequired);
|
||||
jsonCategory[attrIdAccessLevel] = tdAccessLevel.getAttribute(attrIdAccessLevel);
|
||||
jsonCategory[flagActive] = DOM.getElementValueCurrent(inputActive);
|
||||
jsonCategory[flagDisplayOrder] = sliderDisplayOrder.getAttribute(attrValueCurrent);
|
||||
return jsonCategory;
|
||||
}
|
||||
|
||||
hookupTableMain() {
|
||||
super.hookupTableMain();
|
||||
this.hookupSlidersDisplayOrderTable();
|
||||
this.hookupTextareasCodeTable();
|
||||
this.hookupTextareasNameTable();
|
||||
this.hookupTextareasDescriptionTable();
|
||||
this.hookupTdsAccessLevel();
|
||||
this.hookupInputsActiveTable();
|
||||
}
|
||||
|
||||
isRowDirty(row) {
|
||||
if (row == null) return;
|
||||
let ddlCategory = row.querySelector('td.' + flagCategory + ' select');
|
||||
let ddlProduct = row.querySelector('td.' + flagProduct + ' select');
|
||||
let variations = row.querySelector('td.' + flagVariations + ' textarea');
|
||||
let quantityStock = row.querySelector('td.' + flagQuantityStock + ' input');
|
||||
let quantityMin = row.querySelector('td.' + flagQuantityMin + ' input');
|
||||
let quantityMax = row.querySelector('td.' + flagQuantityMax + ' input');
|
||||
|
||||
// return isElementDirty(ddlCategory) || isElementDirty(ddlProduct) || isElementDirty(variations) || isElementDirty(quantityStock) || isElementDirty(quantityMin) || isElementDirty(quantityMax);
|
||||
let isDirty = ddlCategory.classList.contains(flagDirty) || ddlProduct.classList.contains(flagDirty) || variations.classList.contains(flagDirty) ||
|
||||
quantityStock.classList.contains(flagDirty) || quantityMin.classList.contains(flagDirty) || quantityMax.classList.contains(flagDirty);
|
||||
if (isDirty) {
|
||||
row.classList.add(flagDirty);
|
||||
} else {
|
||||
row.classList.remove(flagDirty);
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
|
||||
leave() {
|
||||
super.leave();
|
||||
}
|
||||
}
|
||||
|
||||
getFiltersDefaults() {
|
||||
filters = {};
|
||||
filters.flagIsNotEmpty = true;
|
||||
filters.flagActive = true;
|
||||
return filters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
import { PageBase } from "./page_base.js";
|
||||
import { BasePage } from "../base.js";
|
||||
|
||||
export class PageUser extends PageBase {
|
||||
export class PageUser extends BasePage {
|
||||
static hash = hashPageUser;
|
||||
|
||||
constructor() {
|
||||
@@ -1,36 +1,117 @@
|
||||
|
||||
import { PageAdminHome } from './pages/page_admin_home.js';
|
||||
import { PageHome } from './pages/page_home.js';
|
||||
import { PageContact } from './pages/page_contact.js';
|
||||
import { PageAccessibilityStatement } from './pages/page_accessibility_statement.js';
|
||||
import { PageLicense } from './pages/page_license.js';
|
||||
import { PageServices } from './pages/page_services.js';
|
||||
import { PageStoreBasket } from './pages/page_store_basket.js';
|
||||
import { PageStoreHome } from './pages/page_store_home.js';
|
||||
import { PageStoreProductCategories } from './pages/page_store_product_categories.js';
|
||||
import { PageStoreProductPermutations } from './pages/page_store_product_permutations.js';
|
||||
// import { PageStoreProductPrices } from './pages/page_store_product_prices.js';
|
||||
// import { PageStoreProducts } from './pages/page_store_products.js';
|
||||
// import { PageStoreProductVariations } from './pages/page_store_product_variations.js';
|
||||
import { PageStoreStockItems } from './pages/page_store_stock_items.js';
|
||||
/*
|
||||
import { PageAdminHome } from './pages/core/admin_home.js';
|
||||
import { PageHome } from './pages/core/home.js';
|
||||
import { PageContact } from './pages/core/contact.js';
|
||||
import { PageAccessibilityStatement } from './pages/legal/accessibility_statement.js';
|
||||
import { PageLicense } from './pages/legal/license.js';
|
||||
import { PageServices } from './pages/core/services.js';
|
||||
import { PageStoreBasket } from './pages/store/basket.js';
|
||||
import { PageStoreHome } from './pages/store/home.js';
|
||||
import { PageStoreProductCategories } from './pages/store/product_categories.js';
|
||||
import { PageStoreProductPermutations } from './pages/store/product_permutations.js';
|
||||
// import { PageStoreProductPrices } from './pages/store/product_prices.js';
|
||||
// import { PageStoreProducts } from './pages/store/products.js';
|
||||
// import { PageStoreProductVariations } from './pages/store/product_variations.js';
|
||||
import { PageStoreStockItems } from './pages/store/stock_items.js';
|
||||
*/
|
||||
import API from './api.js';
|
||||
import DOM from './dom.js';
|
||||
|
||||
export default class Router {
|
||||
constructor() {
|
||||
// Pages
|
||||
this.pages = {};
|
||||
// Core
|
||||
this.pages[hashPageHome] = { name: 'PageHome', pathModule: './pages/core/home.js' };
|
||||
this.pages[hashPageContact] = { name: 'PageContact', pathModule: './pages/core/contact.js' };
|
||||
this.pages[hashPageServices] = { name: 'PageServices', pathModule: './pages/core/services.js' };
|
||||
this.pages[hashPageAdminHome] = { name: 'PageAdminHome', pathModule: './pages/core/admin_home.js' };
|
||||
// Legal
|
||||
this.pages[hashPageAccessibilityStatement] = { name: 'PageAccessibilityStatement', pathModule: './pages/legal/accessibility_statement.js' };
|
||||
this.pages[hashPageLicense] = { name: 'PageLicense', pathModule: './pages/legal/license.js' };
|
||||
// Store
|
||||
this.pages[hashPageStoreProductCategories] = { name: 'PageStoreProductCategories', pathModule: './pages/store/product_categories.js' };
|
||||
this.pages[hashPageStoreProductPermutations] = { name: 'PageStoreProductPermutations', pathModule: './pages/store/product_permutations.js' };
|
||||
// this.pages[hashPageStoreProductPrices] = { name: 'PageStoreProductPrices', pathModule: './pages/store/product_prices.js' };
|
||||
this.pages[hashPageStoreProducts] = { name: 'PageStoreProducts', pathModule: './pages/store/products.js' };
|
||||
// this.pages[hashPageStoreProductVariations] = { name: 'PageStoreProductVariations', pathModule: './pages/store/product_variations.js' };
|
||||
// User
|
||||
// this.pages[hashPageUserLogin] = { name: 'PageUserLogin', pathModule: './pages/user/login.js' };
|
||||
// this.pages[hashPageUserLogout] = { name: 'PageUserLogout', pathModule: './pages/user/logout.js' };
|
||||
// this.pages[hashPageUserAccount] = { name: 'PageUserAccount', pathModule: './pages/user/account.js' };
|
||||
|
||||
// Routes
|
||||
this.routes = {};
|
||||
// Core
|
||||
this.routes[hashPageHome] = (isPopState = false) => this.navigateToHash(hashPageHome, isPopState);
|
||||
this.routes[hashPageContact] = (isPopState = false) => this.navigateToHash(hashPageContact, isPopState);
|
||||
this.routes[hashPageServices] = (isPopState = false) => this.navigateToHash(hashPageServices, isPopState);
|
||||
this.routes[hashPageAdminHome] = (isPopState = false) => this.navigateToHash(hashPageAdminHome, isPopState);
|
||||
// Legal
|
||||
this.routes[hashPageAccessibilityStatement] = (isPopState = false) => this.navigateToHash(hashPageAccessibilityStatement, isPopState);
|
||||
this.routes[hashPageLicense] = (isPopState = false) => this.navigateToHash(hashPageLicense, isPopState);
|
||||
// Store
|
||||
this.routes[hashPageStoreProductCategories] = (isPopState = false) => this.navigateToHash(hashPageStoreProductCategories, isPopState);
|
||||
this.routes[hashPageStoreProductPermutations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPermutations, isPopState);
|
||||
// this.routes[hashPageStoreProductPrices] = (isPopState = false) => this.navigateToHash(hashPageStoreProductPrices, isPopState);
|
||||
this.routes[hashPageStoreProducts] = (isPopState = false) => this.navigateToHash(hashPageStoreProducts, isPopState);
|
||||
// this.routes[hashPageStoreProductVariations] = (isPopState = false) => this.navigateToHash(hashPageStoreProductVariations, isPopState);
|
||||
// User
|
||||
// this.routes[hashPageUserLogin] = (isPopState = false) => this.navigateToHash(hashPageUserLogin, isPopState);
|
||||
// this.routes[hashPageUserLogout] = (isPopState = false) => this.navigateToHash(hashPageUserLogout, isPopState);
|
||||
// this.routes[hashPageUserAccount] = (isPopState = false) => this.navigateToHash(hashPageUserAccount, isPopState);
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
async loadPage(hashPage, isPopState = false) {
|
||||
const PageClass = await this.getClassPageFromHash(hashPage);
|
||||
this.currentPage = new PageClass();
|
||||
this.currentPage.initialize(isPopState);
|
||||
}
|
||||
async getClassPageFromHash(hashPage) {
|
||||
let pageJson = this.pages[hashPage];
|
||||
const module = await import(pageJson.pathModule);
|
||||
return module[pageJson.name];
|
||||
}
|
||||
initialize() {
|
||||
/*
|
||||
let pages = Router.getPages();
|
||||
for (const key of Object.keys(pages)) {
|
||||
let page = pages[key];
|
||||
this.addRoute(page.hash, page.initialize);
|
||||
}
|
||||
*/
|
||||
window.addEventListener('popstate', this.handlePopState.bind(this)); // page accessed by history navigation
|
||||
}
|
||||
handlePopState(event) {
|
||||
this.loadPageCurrent();
|
||||
}
|
||||
loadPageCurrent() {
|
||||
const hashPageCurrent = DOM.getHashPageCurrent();
|
||||
this.loadPage(hashPageCurrent);
|
||||
}
|
||||
navigateToHash(hash, data = null, params = null, isPopState = false) {
|
||||
this.beforeLeave();
|
||||
/*
|
||||
if (this.routes[hash]) {
|
||||
console.log("navigating to hash: " + hash);
|
||||
this.routes[hash](isPopState);
|
||||
} else {
|
||||
console.error(`Hash ${hash} not found`);
|
||||
}
|
||||
*/
|
||||
let url = API.getUrlFromHash(hash, params);
|
||||
// if (!isPopState)
|
||||
history.pushState(data, '', url);
|
||||
API.goToUrl(url, data);
|
||||
}
|
||||
async beforeLeave() {
|
||||
const ClassPageCurrent = await this.getClassPageFromHash(DOM.getHashPageCurrent());
|
||||
const pageCurrent = new ClassPageCurrent();
|
||||
pageCurrent.leave();
|
||||
}
|
||||
|
||||
/*
|
||||
static getPages() {
|
||||
let pages = {};
|
||||
pages[hashPageAccessibilityStatement] = PageAccessibilityStatement;
|
||||
@@ -56,15 +137,19 @@ export default class Router {
|
||||
}
|
||||
|
||||
handlePopState(event) {
|
||||
/*
|
||||
let url = window.location.pathname;
|
||||
url = url.split('?')[0];
|
||||
let hash = url.replace(_pathHost, '');
|
||||
console.log("handlePopState: " + hash);
|
||||
this.handleRouteHash(hash);
|
||||
*
|
||||
let pageCurrent = Router.getPageCurrent();
|
||||
pageCurrent.initialize(true);
|
||||
}
|
||||
|
||||
navigateToHash(hash, data = null) {
|
||||
const url = Router.getUrlFromHash(hash);
|
||||
const url = API.getUrlFromHash(hash);
|
||||
this.navigateToUrl(url, data);
|
||||
}
|
||||
|
||||
@@ -109,11 +194,8 @@ export default class Router {
|
||||
}
|
||||
return url;
|
||||
}
|
||||
*/
|
||||
|
||||
static #goToUrl(url) {
|
||||
window.location.href = url;
|
||||
}
|
||||
|
||||
/*
|
||||
handleRouteUrl(url) {
|
||||
const path = url.split('?')[0]; // Remove query parameters
|
||||
|
||||
0
static/js/sections/core.js
Normal file
0
static/js/sections/core.js
Normal file
0
static/js/sections/store.js
Normal file
0
static/js/sections/store.js
Normal file
Reference in New Issue
Block a user