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:
2024-09-10 12:09:50 +01:00
parent b3e801e1ec
commit 2d55fe6239
709 changed files with 5158 additions and 1512 deletions

View File

@@ -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
);

View File

@@ -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
;

View File

@@ -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

View File

@@ -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
;

View 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");
}
*/

View File

@@ -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;
}
/*

View File

View 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
View 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;
}

View File

@@ -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;

View File

@@ -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;

View 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

View File

@@ -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)

View File

@@ -0,0 +1,5 @@
var _loading = true;
function hookupPageAccessibilityStatement() {
_loading = false;
}

View File

@@ -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);

View File

@@ -38,8 +38,11 @@ class App {
initPageCurrent() {
console.log("initPageCurrent");
/*
_pageCurrent = Router.getPageCurrent();
_pageCurrent.initialize();
*/
this.router.loadPageCurrent();
}
}

View File

@@ -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
View 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);
}
};

View File

@@ -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) {

View File

@@ -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();

View 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() {}
}
*/

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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();
}
}

View File

@@ -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
};
}
}

View File

@@ -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);
}
*/
}

View File

@@ -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];

View 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();
}
}

View 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;
}
}

View File

@@ -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() {

View File

@@ -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;
}
}

View File

@@ -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() {

View File

@@ -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

View File

View File