* Create a new list box field. * * @param name - Field name (must be unique) * @param options - Listbox options (options array is required) * @returns The created listbox field * @throws {Error} If a field with the same name already exists * @throws {Error} If options array is empt
(name: string, options: ListboxOptions)
| 889 | * ``` |
| 890 | */ |
| 891 | createListbox(name: string, options: ListboxOptions): ListBoxField { |
| 892 | this.validateUniqueName(name); |
| 893 | |
| 894 | if (!options.options || options.options.length === 0) { |
| 895 | throw new Error("Listbox must have at least one option"); |
| 896 | } |
| 897 | |
| 898 | // Choice field type without Combo flag = list box |
| 899 | let flags = 0; |
| 900 | |
| 901 | if (options.multiSelect) { |
| 902 | flags |= FieldFlags.MULTI_SELECT; |
| 903 | } |
| 904 | |
| 905 | // Build default appearance string |
| 906 | const da = this.buildDefaultAppearance(options.font, options.fontSize, options.color); |
| 907 | |
| 908 | // Create field dictionary with /Kids array (separate widget model) |
| 909 | const fieldDict = PdfDict.of({ |
| 910 | FT: PdfName.of("Ch"), |
| 911 | T: PdfString.fromString(name), |
| 912 | Kids: new PdfArray([]), |
| 913 | Opt: PdfArray.of(...options.options.map(o => PdfString.fromString(o))), |
| 914 | }); |
| 915 | |
| 916 | if (flags !== 0) { |
| 917 | fieldDict.set("Ff", PdfNumber.of(flags)); |
| 918 | } |
| 919 | |
| 920 | if (da) { |
| 921 | fieldDict.set("DA", PdfString.fromString(da)); |
| 922 | } |
| 923 | |
| 924 | // Handle default value(s) |
| 925 | if (options.defaultValue && options.defaultValue.length > 0) { |
| 926 | const validDefaults = options.defaultValue.filter(v => options.options.includes(v)); |
| 927 | |
| 928 | if (validDefaults.length === 1) { |
| 929 | fieldDict.set("V", PdfString.fromString(validDefaults[0])); |
| 930 | fieldDict.set("DV", PdfString.fromString(validDefaults[0])); |
| 931 | } else if (validDefaults.length > 1) { |
| 932 | fieldDict.set("V", PdfArray.of(...validDefaults.map(v => PdfString.fromString(v)))); |
| 933 | fieldDict.set("DV", PdfArray.of(...validDefaults.map(v => PdfString.fromString(v)))); |
| 934 | |
| 935 | // Set /I (selection indices) |
| 936 | const indices = validDefaults |
| 937 | .map(v => options.options.indexOf(v)) |
| 938 | .filter(i => i >= 0) |
| 939 | .sort((a, b) => a - b); |
| 940 | fieldDict.set("I", PdfArray.of(...indices.map(i => PdfNumber.of(i)))); |
| 941 | } |
| 942 | } |
| 943 | |
| 944 | // Register font in form resources if embedded font provided |
| 945 | if (options.font) { |
| 946 | this.registerFontInFormResources(options.font); |
| 947 | } |
| 948 |
no test coverage detected