Merge pull request #13427 from calixteman/xfa_storage
XFA - Add a storage to save fields values
This commit is contained in:
commit
a6484c9861
@ -941,11 +941,14 @@ class CheckButton extends XFAObject {
|
|||||||
style.height = size;
|
style.height = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fieldId = this[$getParent]()[$getParent]()[$uid];
|
||||||
const input = {
|
const input = {
|
||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaCheckbox",
|
class: "xfaCheckbox",
|
||||||
|
fieldId,
|
||||||
type: "radio",
|
type: "radio",
|
||||||
|
id: `${fieldId}-radio`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1023,6 +1026,7 @@ class ChoiceList extends XFAObject {
|
|||||||
|
|
||||||
const selectAttributes = {
|
const selectAttributes = {
|
||||||
class: "xfaSelect",
|
class: "xfaSelect",
|
||||||
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
style,
|
style,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1249,6 +1253,7 @@ class DateTimeEdit extends XFAObject {
|
|||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: "xfaTextfield",
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
@ -3012,6 +3017,7 @@ class NumericEdit extends XFAObject {
|
|||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: "xfaTextfield",
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
@ -4550,6 +4556,7 @@ class TextEdit extends XFAObject {
|
|||||||
html = {
|
html = {
|
||||||
name: "textarea",
|
name: "textarea",
|
||||||
attributes: {
|
attributes: {
|
||||||
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: "xfaTextfield",
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
@ -4559,6 +4566,7 @@ class TextEdit extends XFAObject {
|
|||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
type: "text",
|
type: "text",
|
||||||
|
fieldId: this[$getParent]()[$getParent]()[$uid],
|
||||||
class: "xfaTextfield",
|
class: "xfaTextfield",
|
||||||
style,
|
style,
|
||||||
},
|
},
|
||||||
|
@ -14,9 +14,60 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class XfaLayer {
|
class XfaLayer {
|
||||||
static setAttributes(html, attrs) {
|
static setupStorage(html, fieldId, element, storage) {
|
||||||
for (const [key, value] of Object.entries(attrs)) {
|
const storedData = storage.getValue(fieldId, { value: null });
|
||||||
if (value === null || value === undefined) {
|
switch (element.name) {
|
||||||
|
case "textarea":
|
||||||
|
html.textContent = storedData.value !== null ? storedData.value : "";
|
||||||
|
html.addEventListener("input", event => {
|
||||||
|
storage.setValue(fieldId, { value: event.target.value });
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "input":
|
||||||
|
if (storedData.value !== null) {
|
||||||
|
html.setAttribute("value", storedData.value);
|
||||||
|
}
|
||||||
|
if (element.attributes.type === "radio") {
|
||||||
|
html.addEventListener("change", event => {
|
||||||
|
const { target } = event;
|
||||||
|
for (const radio of document.getElementsByName(target.name)) {
|
||||||
|
if (radio !== target) {
|
||||||
|
const id = radio.id;
|
||||||
|
storage.setValue(id.split("-")[0], { value: false });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
storage.setValue(fieldId, { value: target.checked });
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
html.addEventListener("input", event => {
|
||||||
|
storage.setValue(fieldId, { value: event.target.value });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "select":
|
||||||
|
if (storedData.value !== null) {
|
||||||
|
for (const option of element.children) {
|
||||||
|
if (option.attributes.value === storedData.value) {
|
||||||
|
option.attributes.selected = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
html.addEventListener("input", event => {
|
||||||
|
const options = event.target.options;
|
||||||
|
const value =
|
||||||
|
options.selectedIndex === -1
|
||||||
|
? null
|
||||||
|
: options[options.selectedIndex].value;
|
||||||
|
storage.setValue(fieldId, { value });
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static setAttributes(html, element, storage) {
|
||||||
|
const { attributes } = element;
|
||||||
|
for (const [key, value] of Object.entries(attributes)) {
|
||||||
|
if (value === null || value === undefined || key === "fieldId") {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,13 +81,20 @@ class XfaLayer {
|
|||||||
Object.assign(html.style, value);
|
Object.assign(html.style, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set the value after the others to be sure overwrite
|
||||||
|
// any other values.
|
||||||
|
if (storage && attributes.fieldId !== undefined) {
|
||||||
|
this.setupStorage(html, attributes.fieldId, element, storage);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static render(parameters) {
|
static render(parameters) {
|
||||||
|
const storage = parameters.annotationStorage;
|
||||||
const root = parameters.xfa;
|
const root = parameters.xfa;
|
||||||
const rootHtml = document.createElement(root.name);
|
const rootHtml = document.createElement(root.name);
|
||||||
if (root.attributes) {
|
if (root.attributes) {
|
||||||
XfaLayer.setAttributes(rootHtml, root.attributes);
|
this.setAttributes(rootHtml, root);
|
||||||
}
|
}
|
||||||
const stack = [[root, -1, rootHtml]];
|
const stack = [[root, -1, rootHtml]];
|
||||||
|
|
||||||
@ -69,7 +127,7 @@ class XfaLayer {
|
|||||||
const childHtml = document.createElement(name);
|
const childHtml = document.createElement(name);
|
||||||
html.appendChild(childHtml);
|
html.appendChild(childHtml);
|
||||||
if (child.attributes) {
|
if (child.attributes) {
|
||||||
XfaLayer.setAttributes(childHtml, child.attributes);
|
this.setAttributes(childHtml, child, storage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child.children && child.children.length > 0) {
|
if (child.children && child.children.length > 0) {
|
||||||
|
@ -1317,12 +1317,16 @@ class BaseViewer {
|
|||||||
/**
|
/**
|
||||||
* @param {HTMLDivElement} pageDiv
|
* @param {HTMLDivElement} pageDiv
|
||||||
* @param {PDFPage} pdfPage
|
* @param {PDFPage} pdfPage
|
||||||
|
* @param {AnnotationStorage} [annotationStorage] - Storage for annotation
|
||||||
|
* data in forms.
|
||||||
* @returns {XfaLayerBuilder}
|
* @returns {XfaLayerBuilder}
|
||||||
*/
|
*/
|
||||||
createXfaLayerBuilder(pageDiv, pdfPage) {
|
createXfaLayerBuilder(pageDiv, pdfPage, annotationStorage = null) {
|
||||||
return new XfaLayerBuilder({
|
return new XfaLayerBuilder({
|
||||||
pageDiv,
|
pageDiv,
|
||||||
pdfPage,
|
pdfPage,
|
||||||
|
annotationStorage:
|
||||||
|
annotationStorage || this.pdfDocument?.annotationStorage,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -603,7 +603,8 @@ class PDFPageView {
|
|||||||
if (!this.xfaLayer) {
|
if (!this.xfaLayer) {
|
||||||
this.xfaLayer = this.xfaLayerFactory.createXfaLayerBuilder(
|
this.xfaLayer = this.xfaLayerFactory.createXfaLayerBuilder(
|
||||||
div,
|
div,
|
||||||
pdfPage
|
pdfPage,
|
||||||
|
/* annotationStorage = */ null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
this._renderXfaLayer();
|
this._renderXfaLayer();
|
||||||
|
@ -19,15 +19,17 @@ import { XfaLayer } from "pdfjs-lib";
|
|||||||
* @typedef {Object} XfaLayerBuilderOptions
|
* @typedef {Object} XfaLayerBuilderOptions
|
||||||
* @property {HTMLDivElement} pageDiv
|
* @property {HTMLDivElement} pageDiv
|
||||||
* @property {PDFPage} pdfPage
|
* @property {PDFPage} pdfPage
|
||||||
|
* @property {AnnotationStorage} [annotationStorage]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class XfaLayerBuilder {
|
class XfaLayerBuilder {
|
||||||
/**
|
/**
|
||||||
* @param {XfaLayerBuilderOptions} options
|
* @param {XfaLayerBuilderOptions} options
|
||||||
*/
|
*/
|
||||||
constructor({ pageDiv, pdfPage }) {
|
constructor({ pageDiv, pdfPage, annotationStorage }) {
|
||||||
this.pageDiv = pageDiv;
|
this.pageDiv = pageDiv;
|
||||||
this.pdfPage = pdfPage;
|
this.pdfPage = pdfPage;
|
||||||
|
this.annotationStorage = annotationStorage;
|
||||||
|
|
||||||
this.div = null;
|
this.div = null;
|
||||||
this._cancelled = false;
|
this._cancelled = false;
|
||||||
@ -40,29 +42,34 @@ class XfaLayerBuilder {
|
|||||||
* annotations is complete.
|
* annotations is complete.
|
||||||
*/
|
*/
|
||||||
render(viewport, intent = "display") {
|
render(viewport, intent = "display") {
|
||||||
return this.pdfPage.getXfa().then(xfa => {
|
return this.pdfPage
|
||||||
if (this._cancelled) {
|
.getXfa()
|
||||||
return;
|
.then(xfa => {
|
||||||
}
|
if (this._cancelled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const parameters = {
|
||||||
|
viewport: viewport.clone({ dontFlip: true }),
|
||||||
|
div: this.div,
|
||||||
|
xfa,
|
||||||
|
page: this.pdfPage,
|
||||||
|
annotationStorage: this.annotationStorage,
|
||||||
|
};
|
||||||
|
|
||||||
const parameters = {
|
if (this.div) {
|
||||||
viewport: viewport.clone({ dontFlip: true }),
|
XfaLayer.update(parameters);
|
||||||
div: this.div,
|
} else {
|
||||||
xfa,
|
// Create an xfa layer div and render the form
|
||||||
page: this.pdfPage,
|
this.div = document.createElement("div");
|
||||||
};
|
this.pageDiv.appendChild(this.div);
|
||||||
|
parameters.div = this.div;
|
||||||
|
|
||||||
if (this.div) {
|
XfaLayer.render(parameters);
|
||||||
XfaLayer.update(parameters);
|
}
|
||||||
} else {
|
})
|
||||||
// Create an xfa layer div and render the form
|
.catch(error => {
|
||||||
this.div = document.createElement("div");
|
console.error(error);
|
||||||
this.pageDiv.appendChild(this.div);
|
});
|
||||||
parameters.div = this.div;
|
|
||||||
|
|
||||||
XfaLayer.render(parameters);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
@ -84,11 +91,13 @@ class DefaultXfaLayerFactory {
|
|||||||
/**
|
/**
|
||||||
* @param {HTMLDivElement} pageDiv
|
* @param {HTMLDivElement} pageDiv
|
||||||
* @param {PDFPage} pdfPage
|
* @param {PDFPage} pdfPage
|
||||||
|
* @param {AnnotationStorage} [annotationStorage]
|
||||||
*/
|
*/
|
||||||
createXfaLayerBuilder(pageDiv, pdfPage) {
|
createXfaLayerBuilder(pageDiv, pdfPage, annotationStorage = null) {
|
||||||
return new XfaLayerBuilder({
|
return new XfaLayerBuilder({
|
||||||
pageDiv,
|
pageDiv,
|
||||||
pdfPage,
|
pdfPage,
|
||||||
|
annotationStorage,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user