Files
jsl/README.md
Christopher Vagnetoft bd7b7ac498 Bugfixes, dialog improvements
* It is now possible to pass an element as the dialog message to have it inserted as the body.
2025-09-21 00:45:34 +02:00

166 lines
4.0 KiB
Markdown

# NoccyLabs JSL
This is a collection of libraries that make working with JavaScript and data.
Each component is available in it's own file, and example/default stylesheets are available in separate files.
## Installing
For now, clone this somewhere and copy the files to your project. Hopefully [Symfony Issue #53999](https://github.com/symfony/symfony/issues/53999) will be completed soon, in which case you will hopefully be able to import JSL using the AssetMapper CLI commands.
## Components
### date.js
> [!WARNING]
> **WORK IN PROGRESS! MOSTLY NOT WORKING!**
This component makes working with dates less of a pain.
```javascript
import { date, Timestamp } from "./date.js";
// now
const now = date();
// nothing below here in this example works, to be implemented!
// tomorrow
const tomorrow = date().add({days:1});
// yesterday
const yesterday = now.sub({ days:1 });
// sometime
const custom = date("2025-09-01 15:00:42 +02:00");
// format dates, php style
let ts = now.format("Y-m-d H:i:s P");
```
### dialog.js
This component creates dialogs on the fly, and resolves a promise when the dialog is accepted.
```javascript
import { dialog } from "./dialog.js";
// show a message box
dialog.msgbox("Something");
// show a message box and do something when dismissed
dialog.msgbox("Ready!").then(
function (result) {
// do something!
}
);
// show a confirmation in an async callback
... async () => {
const result = await dialog.confirm("Are you sure about that?");
if (result === "ok") {
// do it
}
}
// show custom actions in a custom select style dialog
dialog.select("Put in warehouse", "Select", { "none":"None", "1":"WH1", "2":"WH2" }).then(...)
```
* `dialog.TYPE(body, ?title, ?actions, ?options)``Promise`
Options:
- `showClose` - true to show close button in top left corner
- `width` - valid CSS width definition
### dom.js
This component offers `dom` and `el` that can be used to manipulate the DOM.
```javascript
import { dom, el } from "./dom.js";
// build DOM
const myDiv = el.div({ class: "form-row" }, [
el.label({ class:"form-label", for:"myInput" }, "Label"),
el.input({ class:"form-control", id:"myInput", type:"text" })
]);
// update element attributes
dom.apply(myDiv, { style:"font-weight:bold;" });
// append children
dom.append(myDiv, [
"Some text",
el.span()
]);
```
### json.js
This component contains tools to query and update data structures using simplified JSON paths.
```javascript
import { jsonQuery, jsonPatch } from './json.js';
let model = {
name: "Bob",
info: {
age: 42
}
};
jsonQuery(model, ".name") // → "Bob"
jsonPatch(model, ".name", "Bobby"); // → { name:"Bobby", info:{ age:42 }}
let items = [
{ "name": "cheese", "price": "5.99" },
{ "name": "wine", "price": "2.99" }
];
jsonQuery(items, "[].name") // → [ "cheese", "wine" ]
```
### jsonform.js
This component not only builds forms and allow you to map it against paths in a model dataset, but it also allows you to do inline editing of your data, with type mapping.
```javascript
import { JsonForm, TextField } from "./jsonform.js";
const productForm = new JsonForm();
productForm.layout.addRow()
.append(new TextField({ label:"Product name", path:".product.name", width:70 }))
.append(new TextField({ label:"Price", path:".price" }));
myTargetEl.appendChild(productForm.dom());
productForm.model = {
product: {
name: "Swedish Fish"
},
price: "9.99"
};
// make it possible to edit the form
productForm.editable = true;
// when the user is done editing set editable = false and access the updated model
productForm.editable = false;
const newModel = productForm.model; // → { product:{ name:"Swedish Fish" }, price:"8.99" }
// You can even put a form inside a dialog!
dialog.dialog(productForm.dom(), "Title", {"ok":"Update"}, { showClose:true, width:'400px' }).then(
(result) => {
productForm.editable = false;
if (result == 'ok') {
// productForm.model is updated
}
}
)
productForm.editable = true;
```