Skip to content
Snippets Groups Projects
Verified Commit b355ac89 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

chore: update doc, small issues, etc #274

parent 660b649e
No related branches found
No related tags found
No related merge requests found
Showing
with 2469 additions and 2036 deletions
......@@ -4,7 +4,7 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>check and update data save button #272</title>
<script src="./272.mjs" type="module"></script>
<script src="272.mjs" type="module"></script>
</head>
<body>
<h1>check and update pagination and dataset #272</h1>
......
File moved
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>update and check form, button and datasources #274</title>
<script src="./274.mjs" type="module"></script>
</head>
<body>
<h1>update and check form, button and datasources #274</h1>
<p></p>
<ul>
<li><a href="https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/274">Issue #274</a></li>
<li><a href="/">Back to overview</a></li>
</ul>
<main>
<h2>Control with DOM datasource</h2>
<monster-datasource-rest id="ds274-r"
data-monster-option-features-autoInit="true"
data-monster-option-write-url="/issue-274.json"
data-monster-option-read-url="/issue-274.json?limit=1&page=${page}"
></monster-datasource-rest>
<monster-pagination
data-monster-option-datasource-selector="#ds274-r"
data-monster-option-objectsperpage="1"
></monster-pagination>
<hr>
<monster-form
id="ds-274"
data-monster-option-datasource-selector="#ds274-r">
<div style="display: grid; grid-template-columns: 1fr 1fr;gap: 0.1rem;width: 600px">
<div>ID</div>
<input data-monster-attributes="value path:data.id | tostring" data-monster-bind="path:data.id">
<div>Username</div>
<input data-monster-attributes="value path:data.username" data-monster-bind="path:data.username">
<div>Full Name</div>
<input data-monster-attributes="value path:data.full_name" data-monster-bind="path:data.full_name">
<div>Email</div>
<input data-monster-attributes="value path:data.email" data-monster-bind="path:data.email">
<div>Age</div>
<input data-monster-attributes="value path:data.age" data-monster-bind="path:data.age">
<div>Registered Date</div>
<input data-monster-attributes="value path:data.registered_date" data-monster-bind="path:data.registered_date">
<div>Country</div>
<monster-select data-monster-attributes="value path:data.country" data-monster-bind="path:data.country">
<div data-monster-value="de">de</div>
<div data-monster-value="en">en</div>
<div data-monster-value="fr">fr</div>
</monster-select>
<div>Status</div>
<monster-toggle-switch data-monster-attributes="value path:data.status" data-monster-bind="path:data.status"
data-monster-option-values-on="active" data-monster-option-values-off="inactive"></monster-toggle-switch>
<!-- monster-toggle-switch data-monster-attributes="value path:data.status" data-monster-bind="path:data.status"></monster-toggle-switch -->
</div>
</monster-form>
<monster-pagination
data-monster-option-datasource-selector="#ds274-r"
data-monster-option-objectsperpage="1"
></monster-pagination>
<hr>
<hr>
<hr>
<hr>
<h3>Check output</h3>
<monster-dataset
data-monster-option-datasource-selector="#ds274-r">
<div style="display: grid; grid-template-columns: 1fr 1fr;gap: 0.1rem;width: 600px">
<div>ID</div>
<input data-monster-attributes="value path:data.id">
<div>Username</div>
<input data-monster-attributes="value path:data.username">
<div>Full Name</div>
<input data-monster-attributes="value path:data.full_name">
<div>Email</div>
<input data-monster-attributes="value path:data.email">
<div>Age</div>
<input data-monster-attributes="value path:data.age">
<div>Country</div>
<input data-monster-attributes="value path:data.country">
<div>Registered Date</div>
<input data-monster-attributes="value path:data.registered_date">
<div>Status</div>
<input data-monster-attributes="value path:data.status">
<monster-toggle-switch data-monster-attributes="value path:data.status"
data-monster-option-values-on="active" data-monster-option-values-off="inactive"></monster-toggle-switch>
</div>
</monster-dataset>
</main>
</body>
</html>
\ No newline at end of file
/**
* @file development/issues/open/274.mjs
* @url https://gitlab.schukai.com/oss/libraries/javascript/monster/-/issues/274
* @description update and check form, button and datasources
* @issue 274
*/
import "../../../source/components/style/property.pcss";
import "../../../source/components/style/link.pcss";
import "../../../source/components/style/color.pcss";
import "../../../source/components/style/theme.pcss";
import "../../../source/components/style/normalize.pcss";
import "../../../source/components/style/typography.pcss";
import "../../../source/components/datatable/datasource/rest.mjs";
import "../../../source/components/datatable/datasource/dom.mjs";
import "../../../source/components/datatable/dataset.mjs";
import "../../../source/components/datatable/pagination.mjs";
import "../../../source/components/form/button.mjs";
import "../../../source/components/form/form.mjs";
import "../../../source/components/form/button-bar.mjs";
import "../../../source/components/form/toggle-switch.mjs";
// DOM-Elemente für die Seiten-Datensätze
const pageData1 = document.getElementById("ds274-d");
const pageData2 = document.getElementById("ds274-r");
const json =
`[{
"id": 1,
"username": "wernerjennifer",
"email": "smithchristina@clark.biz",
"full_name": "Joshua Smith",
"age": 28,
"country": "Central African Republic",
"registered_date": "2020-01-17",
"status": "active"
},
{
"id": 2,
"username": "elizabethmurphy",
"email": "beverlywarren@gmail.com",
"full_name": "Sarah Snyder",
"age": 18,
"country": "Tajikistan",
"registered_date": "2023-05-10",
"status": "banned"
},
{
"id": 3,
"username": "ftaylor",
"email": "deckercassandra@conrad.com",
"full_name": "Rhonda Carroll",
"age": 34,
"country": "Australia",
"registered_date": "2022-07-31",
"status": "inactive"
},
{
"id": 4,
"username": "antoniocastillo",
"email": "tevans@hotmail.com",
"full_name": "Brad Brown",
"age": 39,
"country": "Nepal",
"registered_date": "2023-01-09",
"status": "banned"
},
{
"id": 5,
"username": "dylan46",
"email": "audreywalter@watts-conley.com",
"full_name": "Jacqueline Turner",
"age": 26,
"country": "United States Minor Outlying Islands",
"registered_date": "2024-10-14",
"status": "inactive"
},
{
"id": 6,
"username": "michael27",
"email": "thompsonsydney@gmail.com",
"full_name": "Stephanie Walls",
"age": 25,
"country": "Switzerland",
"registered_date": "2020-05-20",
"status": "inactive"
},
{
"id": 7,
"username": "vickie92",
"email": "mary35@jackson.com",
"full_name": "Colin Cohen",
"age": 23,
"country": "Saint Martin",
"registered_date": "2022-12-31",
"status": "active"
},
{
"id": 8,
"username": "fordomar",
"email": "hernandezbrian@gmail.com",
"full_name": "Christopher Garza",
"age": 65,
"country": "Antigua and Barbuda",
"registered_date": "2022-08-15",
"status": "banned"
},
{
"id": 9,
"username": "jerry82",
"email": "nwhite@yahoo.com",
"full_name": "Gabrielle Garza",
"age": 46,
"country": "Mauritania",
"registered_date": "2023-03-08",
"status": "inactive"
},
{
"id": 10,
"username": "alyssa54",
"email": "kevin11@hotmail.com",
"full_name": "Andrea Williams",
"age": 43,
"country": "Western Sahara",
"registered_date": "2023-04-19",
"status": "active"
},
{
"id": 11,
"username": "jacob30",
"email": "scottmary@yahoo.com",
"full_name": "Nicole Cunningham",
"age": 29,
"country": "French Polynesia",
"registered_date": "2022-02-21",
"status": "banned"
},
{
"id": 12,
"username": "ftucker",
"email": "simmonsrichard@jones.com",
"full_name": "Daniel Shelton",
"age": 42,
"country": "Cameroon",
"registered_date": "2024-04-20",
"status": "active"
},
{
"id": 13,
"username": "alvarezpaul",
"email": "ucannon@ortega.biz",
"full_name": "Matthew Poole",
"age": 44,
"country": "Chad",
"registered_date": "2021-09-22",
"status": "inactive"
},
{
"id": 14,
"username": "sarahunter",
"email": "allisoncharles@phillips-graves.com",
"full_name": "Nathan Fernandez",
"age": 40,
"country": "French Polynesia",
"registered_date": "2023-04-11",
"status": "inactive"
},
{
"id": 15,
"username": "sierra65",
"email": "hnicholson@gmail.com",
"full_name": "Michael Taylor",
"age": 27,
"country": "Indonesia",
"registered_date": "2021-08-15",
"status": "active"
},
{
"id": 16,
"username": "benjamin84",
"email": "zgallegos@hale-johnson.com",
"full_name": "Molly Santana",
"age": 32,
"country": "Holy See (Vatican City State)",
"registered_date": "2023-06-09",
"status": "inactive"
},
{
"id": 17,
"username": "peckpaul",
"email": "james03@hotmail.com",
"full_name": "Kelly Allen",
"age": 42,
"country": "Austria",
"registered_date": "2021-04-26",
"status": "active"
},
{
"id": 18,
"username": "jill42",
"email": "williamstephenson@hotmail.com",
"full_name": "Samuel Adkins",
"age": 22,
"country": "American Samoa",
"registered_date": "2024-10-04",
"status": "active"
},
{
"id": 19,
"username": "pottssavannah",
"email": "emily76@mckinney.com",
"full_name": "Jeremy Pearson",
"age": 42,
"country": "Lesotho",
"registered_date": "2020-06-15",
"status": "inactive"
},
{
"id": 20,
"username": "robertsdaniel",
"email": "robinsontodd@pineda.org",
"full_name": "Francis Castaneda",
"age": 58,
"country": "British Indian Ocean Territory (Chagos Archipelago)",
"registered_date": "2020-03-01",
"status": "inactive"
}
]
`;
// check if JSON is valid
const objects = JSON.parse(json)
if (!Array.isArray(objects)) {
throw new Error('Invalid JSON')
}
const requestDelay = 10
function wrapJsonWithPagination(data, page, limit) {
return JSON.stringify({
dataset: data,
sys: {
pagination: {
objectsPerPage: limit,
pages: Math.ceil(objects.length / limit),
currentPage: page
}
}
})
}
export default [
{
url: '/issue-274.json',
method: 'get',
rawResponse: async (req, res) => {
res.setHeader('Content-Type', 'application/json')
res.statusCode = 200
const url = new URL(req.url, `http://${req.headers.host}`)
const q = Object.fromEntries(url.searchParams)
let filtered = objects
if (q) {
let limit = 20
if (q.limit) {
limit = parseInt(q.limit)
}
if (q.page) {
const page = parseInt(q.page)
const start = (page - 1) * limit
const end = start + limit
filtered = objects.slice(start, end)
} else {
filtered = objects.slice(0, limit)
}
if (q.q) {
const query = q.q.toLowerCase()
filtered = objects.filter(item => item.name.toLowerCase().includes(query))
}
setTimeout(function () {
res.end(wrapJsonWithPagination(filtered, q.page || 1, limit))
}, requestDelay);
return
}
setTimeout(function () {
res.end(wrapJsonWithPagination(filtered, 1, 20))
}, requestDelay);
},
},
{
url: '/issue-274.json',
method: 'post',
rawResponse: async (req, res) => {
res.setHeader('Content-Type', 'application/json')
res.statusCode = 200
const jsonRespond = JSON.stringify({message: "Data has been successfully saved"})
res.end(jsonRespond)
}
}
];
\ No newline at end of file
......@@ -84,7 +84,7 @@ const resizeObserverSymbol = Symbol("resizeObserver");
*
* @fragments /fragments/components/content/copy/
*
* @example /examples/components/content/copy-simple
* @example /examples/components/content/copy-simple Copy
*
* @since 3.77.0
* @copyright schukai GmbH
......
......@@ -20,7 +20,7 @@ import {
attributeObserverSymbol,
registerCustomElement,
} from "../../dom/customelement.mjs";
import {findElementWithSelectorUpwards} from "../../dom/util.mjs";
import {findElementWithSelectorUpwards, getDocument, getWindow} from "../../dom/util.mjs";
import {isString} from "../../types/is.mjs";
import {Observer} from "../../types/observer.mjs";
import {
......@@ -42,8 +42,8 @@ export {DataSet};
*
* @fragments /fragments/components/datatable/dataset
*
* @example /examples/components/datatable/dataset-dom
* @example /examples/components/datatable/dataset-rest
* @example /examples/components/datatable/dataset-dom Dom dataset
* @example /examples/components/datatable/dataset-rest Rest dataset
*
* @issue https://localhost.alvine.dev:8443/development/issues/closed/272.html
*
......@@ -56,7 +56,7 @@ class DataSet extends CustomElement {
* @return {symbol}
*/
static get [instanceSymbol]() {
return Symbol.for("@schukai/monster/components/dataset@@instance");
return Symbol.for("@schukai/monster/components/datatable/dataset@@instance");
}
/**
......@@ -118,7 +118,7 @@ class DataSet extends CustomElement {
* @type {boolean}
*/
refreshOnMutation: {
selector: "input, select, textarea",
selector: "input, select, textarea, monster-select, monster-toggle-switch",
},
data: {},
......@@ -139,12 +139,12 @@ class DataSet extends CustomElement {
/**
* This method is called when the component is created.
* @since 3.70.0
* @return {DataSet}
* @return {Promise}
*/
refresh() {
// makes sure that handleDataSourceChanges is called
this.setOption("data", {});
return this;
return Promise.resolve(this);
}
/**
......
......@@ -68,9 +68,9 @@ const filterObserverSymbol = Symbol("filterObserver");
*
* @fragments /fragments/components/datatable/datasource/rest
*
* @example /examples/components/datatable/datasource-rest-simple
* @example /examples/components/datatable/datasource-rest-auto-init
* @example /examples/components/datatable/datasource-rest-do-fetch
* @example /examples/components/datatable/datasource-rest-simple Simple Rest datasource
* @example /examples/components/datatable/datasource-rest-auto-init Auto init
* @example /examples/components/datatable/datasource-rest-do-fetch Rest datasource with fetch
*
* @issue https://localhost.alvine.dev:8443/development/issues/closed/272.html
*
......
......@@ -75,7 +75,7 @@ const debounceSizeSymbol = Symbol("debounceSize");
*
* @fragments /fragments/components/datatable/pagination
*
* @example /examples/components/datatable/pagination-simple
* @example /examples/components/datatable/pagination-simple Pagination
*
* @copyright schukai GmbH
* @summary The Pagination component is used to show the current page and the total number of pages.
......
......@@ -51,7 +51,7 @@ export { ApiBar };
*
* @fragments /fragments/components/form/api-bar/
*
* @example /examples/components/form/api-bar-simple
* @example /examples/components/form/api-bar-simple API Bar
*
* @since 3.90.0
* @copyright schukai GmbH
......
......@@ -56,7 +56,7 @@ const containerElementSymbol = Symbol("containerElement");
*
* @fragments /fragments/components/form/api-button/
*
* @example /examples/components/form/api-button-simple
* @example /examples/components/form/api-button-simple API Button
*
* @since 3.32.0
* @copyright schukai GmbH
......
......@@ -129,7 +129,7 @@ const ATTRIBUTE_POPPER_POSITION = "data-monster-popper-position";
*
* @fragments /fragments/components/form/button-bar/
*
* @example /examples/components/form/button-bar-simple
* @example /examples/components/form/button-bar-simple Button bar
*
* @copyright schukai GmbH
* @summary This is a button bar control that can be used to display a set of buttons.
......
......@@ -44,8 +44,8 @@ export const buttonElementSymbol = Symbol("buttonElement");
*
* @fragments /fragments/components/form/button/
*
* @example /examples/components/form/button-simple
* @example /examples/components/form/button-with-click-event
* @example /examples/components/form/button-simple Simple Button
* @example /examples/components/form/button-with-click-event Button with event
*
* @copyright schukai GmbH
* @summary A beautiful button that can make your life easier and also looks good.
......
......@@ -93,7 +93,7 @@ const cancelButtonElementSymbol = Symbol("cancelButtonElement");
*
* @fragments /fragments/components/form/confirm-button/
*
* @example /examples/components/form/confirm-button-simple
* @example /examples/components/form/confirm-button-simple confirm button
*
* @since 1.5.0
* @copyright schukai GmbH
......
......@@ -83,7 +83,7 @@ class Form extends DataSet {
},
reportValidity: {
selector: "input,select,textarea",
selector: "input,select,textarea,monster-select,monster-toggle-switch",
},
eventProcessing: true,
......@@ -130,12 +130,13 @@ class Form extends DataSet {
/**
* This method is called when the component is created.
* @since 3.70.0
* @return {DataSet}
* @return {Promise}
*/
refresh() {
this.write();
return this.write().then(() => {
super.refresh();
return this;
})
}
/**
......@@ -175,6 +176,7 @@ function initEventHandler() {
const events = this.getOption("writeBack.events");
for (const event of events) {
this.addEventListener(event, (e) => {
if (!this.reportValidity()) {
this.classList.add("invalid");
setTimeout(() => {
......
......@@ -38,7 +38,7 @@ import {
fireCustomEvent,
fireEvent,
} from "../../dom/events.mjs";
import { getDocument } from "../../dom/util.mjs";
import {getDocument, getWindow} from "../../dom/util.mjs";
import {Formatter} from "../../text/formatter.mjs";
import {getGlobal} from "../../types/global.mjs";
import {ID} from "../../types/id.mjs";
......@@ -281,6 +281,7 @@ const FILTER_POSITION_INLINE = "inline";
* @fragments /fragments/components/form/select/
*
* @example /examples/components/form/select-with-options Select with options
* @example /examples/components/form/select-with-html-options Select with HTML options
* @example /examples/components/form/select-multiple Multiple selection
* @example /examples/components/form/select-filter Filter
* @example /examples/components/form/select-fetch Fetch options
......@@ -349,7 +350,8 @@ class Select extends CustomControl {
const result = convertValueToSelection.call(this, value);
setSelection
.call(this, result.selection)
.then(() => {})
.then(() => {
})
.catch((e) => {
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
});
......@@ -561,7 +563,8 @@ class Select extends CustomControl {
lastValue = n;
setSelection
.call(self, n)
.then(() => {})
.then(() => {
})
.catch((e) => {
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
});
......@@ -1011,12 +1014,12 @@ function parseSlotsToOptions() {
value = node.getAttribute("data-monster-value");
}
let label = node.outerHTML;
if (node.style.display === "none") {
visibility = "hidden";
}
const label = node.outerHTML;
options.push({
value,
label,
......@@ -1171,7 +1174,7 @@ function initOptionObserver() {
try {
self.updateI18n();
} catch (e) {
console.error(e);
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message);
requestAnimationFrame(() => {
setStatusOrRemoveBadges.call(self, "error");
});
......@@ -1179,7 +1182,7 @@ function initOptionObserver() {
try {
areOptionsAvailableAndInit.call(self);
} catch (e) {
console.error(e);
addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message);
requestAnimationFrame(() => {
setStatusOrRemoveBadges.call(self, "error");
});
......@@ -1199,7 +1202,8 @@ function getDefaultTranslation() {
try {
const doc = getDocumentTranslations();
translation.locale = doc.locale;
} catch (e) {}
} catch (e) {
}
return translation;
}
......@@ -1233,7 +1237,7 @@ function setSummaryAndControlText() {
current === msg ||
current === null
) {
if (selections === undefined || selections.length === 0) {
if (selections.length === 0) {
this.setOption("messages.control", msg);
} else {
this.setOption("messages.control", "");
......@@ -1827,7 +1831,8 @@ function gatherState() {
setSelection
.call(this, selection)
.then(() => {})
.then(() => {
})
.catch((e) => {
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
});
......@@ -1856,7 +1861,8 @@ function clearSelection() {
setSelection
.call(this, [])
.then(() => {})
.then(() => {
})
.catch((e) => {
addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
});
......@@ -2079,7 +2085,7 @@ function setSelection(selection) {
validateArray(selection);
for (let i = 0; i < selection.length; i++) {
var l = getSelectionLabel.call(this, selection[i].value);
let l = getSelectionLabel.call(this, selection[i].value);
if (l === selection[i].value) {
l = selection[i].label;
}
......@@ -2092,6 +2098,7 @@ function setSelection(selection) {
this.setOption("selection", selection);
checkOptionState.call(this);
setSummaryAndControlText.call(this);
try {
this?.setFormValue(this.value);
......@@ -2124,6 +2131,7 @@ function setSelection(selection) {
}
const selected = this.shadowRoot.querySelectorAll(":checked");
if (selected) {
selected.forEach((node) => {
const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
......
......@@ -145,9 +145,9 @@ const resizeObserverSymbol = Symbol("resizeObserver");
*
* @fragments /fragments/components/layout/tabs/
*
* @example /examples/components/layout/tabs-simple
* @example /examples/components/layout/tabs-active
* @example /examples/components/layout/tabs-removable
* @example /examples/components/layout/tabs-simple Simple Tabs
* @example /examples/components/layout/tabs-active Active Tabs
* @example /examples/components/layout/tabs-removable Removable Tabs
*
* @issue https://localhost.alvine.dev:8443/development/issues/closed/268.html
* @issue https://localhost.alvine.dev:8443/development/issues/closed/271.html
......
......@@ -59,7 +59,7 @@ const MODE_WIDE = "wide";
*
* @fragments /fragments/components/layout/width-toggle/
*
* @example /examples/components/layout/width-toggle-simple
* @example /examples/components/layout/width-toggle-simple Toggle Width
*
* @since 3.57.0
* @copyright schukai GmbH
......
......@@ -73,7 +73,7 @@ const scrollableEventHandlerSymbol = Symbol("scrollableEventHandler");
*
* @fragments /fragments/components/form/table-of-content
*
* @example /examples/components/form/table-of-content-simple
* @example /examples/components/form/table-of-content-simple Table of content
*
* @since 3.65.0
* @copyright schukai GmbH
......
......@@ -70,7 +70,7 @@ const removeEventHandlerSymbol = Symbol("removeEventHandler");
*
* @fragments /fragments/components/notify/message
*
* @example /examples/components/notify/message-simple
* @example /examples/components/notify/message-simple Message
*
* @issue https://localhost.alvine.dev:8443/development/issues/closed/269.html
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment