XFA - Use native radio and checkbox buttons
- Remove current stuff which relies on some system fonts to avoid bad rendering.
This commit is contained in:
parent
f2ade671ec
commit
f61f80a5a3
@ -890,71 +890,45 @@ class CheckButton extends XFAObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
[$toHTML](availableSpace) {
|
[$toHTML](availableSpace) {
|
||||||
// TODO: shape and mark == default.
|
// TODO: border, shape and mark.
|
||||||
const style = toStyle(this, "border", "margin");
|
|
||||||
|
const style = toStyle("margin");
|
||||||
const size = measureToString(this.size);
|
const size = measureToString(this.size);
|
||||||
|
|
||||||
style.width = style.height = size;
|
style.width = style.height = size;
|
||||||
|
|
||||||
let mark, radius;
|
let type;
|
||||||
if (this.shape === "square") {
|
let className;
|
||||||
mark = "▪";
|
let groupId;
|
||||||
radius = "10%";
|
let id;
|
||||||
} else {
|
|
||||||
mark = "●";
|
|
||||||
radius = "50%";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!style.borderRadius) {
|
|
||||||
style.borderRadius = radius;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.mark !== "default") {
|
|
||||||
// TODO: To avoid some rendering issues we should use svg
|
|
||||||
// to draw marks.
|
|
||||||
switch (this.mark) {
|
|
||||||
case "check":
|
|
||||||
mark = "✓";
|
|
||||||
break;
|
|
||||||
case "circle":
|
|
||||||
mark = "●";
|
|
||||||
break;
|
|
||||||
case "cross":
|
|
||||||
mark = "✕";
|
|
||||||
break;
|
|
||||||
case "diamond":
|
|
||||||
mark = "♦";
|
|
||||||
break;
|
|
||||||
case "square":
|
|
||||||
mark = "▪";
|
|
||||||
break;
|
|
||||||
case "star":
|
|
||||||
mark = "★";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (size !== "10px") {
|
|
||||||
style.fontSize = size;
|
|
||||||
style.lineHeight = size;
|
|
||||||
style.width = size;
|
|
||||||
style.height = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
const fieldId = this[$getParent]()[$getParent]()[$uid];
|
const fieldId = this[$getParent]()[$getParent]()[$uid];
|
||||||
|
const container = this[$getParent]()[$getParent]()[$getParent]();
|
||||||
|
if (container instanceof ExclGroup) {
|
||||||
|
groupId = container[$uid];
|
||||||
|
type = "radio";
|
||||||
|
className = "xfaRadio";
|
||||||
|
id = `${fieldId}-radio`;
|
||||||
|
} else {
|
||||||
|
type = "checkbox";
|
||||||
|
className = "xfaCheckbox";
|
||||||
|
}
|
||||||
|
|
||||||
const input = {
|
const input = {
|
||||||
name: "input",
|
name: "input",
|
||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaCheckbox",
|
class: className,
|
||||||
|
style,
|
||||||
fieldId,
|
fieldId,
|
||||||
type: "radio",
|
type,
|
||||||
id: `${fieldId}-radio`,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const container = this[$getParent]()[$getParent]()[$getParent]();
|
if (id) {
|
||||||
if (container instanceof ExclGroup) {
|
input.attributes.id = id;
|
||||||
input.attributes.name = container[$uid];
|
}
|
||||||
|
|
||||||
|
if (groupId) {
|
||||||
|
input.attributes.name = groupId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return HTMLResult.success({
|
return HTMLResult.success({
|
||||||
@ -962,17 +936,7 @@ class CheckButton extends XFAObject {
|
|||||||
attributes: {
|
attributes: {
|
||||||
class: "xfaLabel",
|
class: "xfaLabel",
|
||||||
},
|
},
|
||||||
children: [
|
children: [input],
|
||||||
input,
|
|
||||||
{
|
|
||||||
name: "span",
|
|
||||||
attributes: {
|
|
||||||
class: "xfaCheckboxMark",
|
|
||||||
mark,
|
|
||||||
style,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,20 +16,26 @@
|
|||||||
import { PageViewport } from "./display_utils.js";
|
import { PageViewport } from "./display_utils.js";
|
||||||
|
|
||||||
class XfaLayer {
|
class XfaLayer {
|
||||||
static setupStorage(html, fieldId, element, storage) {
|
static setupStorage(html, fieldId, element, storage, intent) {
|
||||||
const storedData = storage.getValue(fieldId, { value: null });
|
const storedData = storage.getValue(fieldId, { value: null });
|
||||||
switch (element.name) {
|
switch (element.name) {
|
||||||
case "textarea":
|
case "textarea":
|
||||||
html.textContent = storedData.value !== null ? storedData.value : "";
|
html.textContent = storedData.value !== null ? storedData.value : "";
|
||||||
|
if (intent === "print") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
html.addEventListener("input", event => {
|
html.addEventListener("input", event => {
|
||||||
storage.setValue(fieldId, { value: event.target.value });
|
storage.setValue(fieldId, { value: event.target.value });
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "input":
|
case "input":
|
||||||
if (storedData.value !== null) {
|
|
||||||
html.setAttribute("value", storedData.value);
|
|
||||||
}
|
|
||||||
if (element.attributes.type === "radio") {
|
if (element.attributes.type === "radio") {
|
||||||
|
if (storedData.value) {
|
||||||
|
html.setAttribute("checked", true);
|
||||||
|
}
|
||||||
|
if (intent === "print") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
html.addEventListener("change", event => {
|
html.addEventListener("change", event => {
|
||||||
const { target } = event;
|
const { target } = event;
|
||||||
for (const radio of document.getElementsByName(target.name)) {
|
for (const radio of document.getElementsByName(target.name)) {
|
||||||
@ -40,7 +46,23 @@ class XfaLayer {
|
|||||||
}
|
}
|
||||||
storage.setValue(fieldId, { value: target.checked });
|
storage.setValue(fieldId, { value: target.checked });
|
||||||
});
|
});
|
||||||
|
} else if (element.attributes.type === "checkbox") {
|
||||||
|
if (storedData.value) {
|
||||||
|
html.setAttribute("checked", true);
|
||||||
|
}
|
||||||
|
if (intent === "print") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
html.addEventListener("input", event => {
|
||||||
|
storage.setValue(fieldId, { value: event.target.checked });
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
|
if (storedData.value !== null) {
|
||||||
|
html.setAttribute("value", storedData.value);
|
||||||
|
}
|
||||||
|
if (intent === "print") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
html.addEventListener("input", event => {
|
html.addEventListener("input", event => {
|
||||||
storage.setValue(fieldId, { value: event.target.value });
|
storage.setValue(fieldId, { value: event.target.value });
|
||||||
});
|
});
|
||||||
@ -66,8 +88,13 @@ class XfaLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static setAttributes(html, element, storage) {
|
static setAttributes(html, element, storage, intent) {
|
||||||
const { attributes } = element;
|
const { attributes } = element;
|
||||||
|
if (attributes.type === "radio") {
|
||||||
|
// Avoid to have a radio group when printing with the same as one
|
||||||
|
// already displayed.
|
||||||
|
attributes.name = `${attributes.name}-${intent}`;
|
||||||
|
}
|
||||||
for (const [key, value] of Object.entries(attributes)) {
|
for (const [key, value] of Object.entries(attributes)) {
|
||||||
if (value === null || value === undefined || key === "fieldId") {
|
if (value === null || value === undefined || key === "fieldId") {
|
||||||
continue;
|
continue;
|
||||||
@ -94,6 +121,7 @@ class XfaLayer {
|
|||||||
static render(parameters) {
|
static render(parameters) {
|
||||||
const storage = parameters.annotationStorage;
|
const storage = parameters.annotationStorage;
|
||||||
const root = parameters.xfa;
|
const root = parameters.xfa;
|
||||||
|
const intent = parameters.intent;
|
||||||
const rootHtml = document.createElement(root.name);
|
const rootHtml = document.createElement(root.name);
|
||||||
if (root.attributes) {
|
if (root.attributes) {
|
||||||
this.setAttributes(rootHtml, root);
|
this.setAttributes(rootHtml, root);
|
||||||
@ -134,7 +162,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) {
|
||||||
this.setAttributes(childHtml, child, storage);
|
this.setAttributes(childHtml, child, storage, intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (child.children && child.children.length > 0) {
|
if (child.children && child.children.length > 0) {
|
||||||
|
@ -125,38 +125,6 @@
|
|||||||
resize: none;
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.xfaLabel > input[type="radio"] {
|
|
||||||
/* Use this trick to make the checkbox invisible but
|
|
||||||
but still focusable. */
|
|
||||||
position: absolute;
|
|
||||||
left: -99999px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaLabel > input[type="radio"]:focus + .xfaCheckboxMark {
|
|
||||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.7);
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaCheckboxMark {
|
|
||||||
cursor: pointer;
|
|
||||||
flex: 0 0 auto;
|
|
||||||
border-style: solid;
|
|
||||||
border-width: 2px;
|
|
||||||
border-color: #8f8f9d;
|
|
||||||
font-size: 10px;
|
|
||||||
line-height: 10px;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
text-align: center;
|
|
||||||
vertical-align: middle;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaCheckbox:checked + .xfaCheckboxMark::after {
|
|
||||||
content: attr(mark);
|
|
||||||
}
|
|
||||||
|
|
||||||
.xfaButton {
|
.xfaButton {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -169,6 +137,13 @@
|
|||||||
background: Highlight;
|
background: Highlight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.xfaCheckbox,
|
||||||
|
.xfaRadio {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
.xfaRich {
|
.xfaRich {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
@ -82,6 +82,7 @@ class XfaLayerBuilder {
|
|||||||
xfa: this.xfaHtml,
|
xfa: this.xfaHtml,
|
||||||
page: null,
|
page: null,
|
||||||
annotationStorage: this.annotationStorage,
|
annotationStorage: this.annotationStorage,
|
||||||
|
intent,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create an xfa layer div and render the form
|
// Create an xfa layer div and render the form
|
||||||
|
Loading…
Reference in New Issue
Block a user