Wiki source code of Attachment Picker Module

Last modified by Eleni Cojocariu on 2026/10/01 09:49

Show last authors
1 The RequireJS module ##xwiki-attachment-picker##, one of the two modules of the [[Attachment Picker WebJar>>doc:documentation.xs.dev.attachments.attachment-picker-webjar.WebHome]], turns markup into a working picker: it builds the search field, fills the grid of results, and reports what the reader picks.
2
3 == Markup of a Picker ==
4
5 A picker is an element carrying the class ##attachmentGalleryPicker##, holding four blocks that the JavaScript looks up inside it by class:
6
7 |=Block class|=Holds
8 |##attachmentPickerSearch##|The search field, which the JavaScript builds into it, and the class ##xform##, which it adds. The field is a Bootstrap ##input-group##: a text input and a pair of radio buttons named ##scope##, of values ##local## and ##global##, with ##local## checked.
9 |##attachmentPickerResults##|The grid of results, filled and emptied at every search.
10 |##attachmentPickerNoResults##|The message shown when a search returns nothing. Rendered with the class ##hidden##, which the JavaScript removes and adds back.
11 |##attachmentPickerGlobalSelection##|The warning shown while the selected attachment belongs to another Page. Rendered ##hidden## too.
12
13 Three optional attributes on the root element configure it. The JavaScript only reads them, and they are the three parameters of the ##attachmentGalleryPicker## macro:
14
15 |=Attribute|=Passed to ##SolrSearch## as|=Default
16 |##data-xwiki-attachment-picker-limit##|##limit##, parsed as an integer|##20##, both for an absent attribute and for a value that does not parse
17 |##data-xwiki-attachment-picker-target##|##target##|The Page the picker is displayed on
18 |##data-xwiki-attachment-picker-filter##|##filter## of the Solr options, where it becomes a media type clause of every query|No filter
19
20 The macro writes exactly that markup, but any markup carrying those classes works, once the module is loaded on the Page as described below:
21
22 {{code language="html"}}
23 <div class="attachmentGalleryPicker"
24 data-xwiki-attachment-picker-filter="image/*"
25 data-xwiki-attachment-picker-limit="10"
26 data-xwiki-attachment-picker-target="Sandbox.WebHome">
27 <div class="attachmentPickerSearch"></div>
28 <div class="attachmentPickerResults"></div>
29 <div class="attachmentPickerNoResults hidden">No attachment matches your search.</div>
30 <div class="attachmentPickerGlobalSelection hidden">The attachment you picked belongs to another
31 page.</div>
32 </div>
33 {{/code}}
34
35 == Initialisation ==
36
37 The module registers the jQuery plugin ##$.fn.attachmentGalleryPicker()##:
38
39 {{code language="javascript"}}
40 require(['jquery', 'xwiki-attachment-picker'], function ($) {
41 // The module exports nothing: requiring it is what registers the plugin.
42 $('#my-picker').attachmentGalleryPicker();
43 });
44 {{/code}}
45
46 |=Trigger|=What happens
47 |A call of the plugin|One picker is built and initialised per matched element.
48 |The document being ready, then every ##xwiki:dom:updated## event|The module initialises every element of class ##attachmentGalleryPicker## by itself, among the elements the event carries or in the whole document, so a picker inserted by an asynchronous request needs no call of your own.
49 |Initialising a picker|It is marked with the class ##initialized##, and a first search runs with an empty query, so the grid is filled before the reader types anything.
50 |Initialising a picker that already carries ##initialized##|Nothing, which is what makes the automatic initialisation safe.
51 |Typing in the search field, or switching scope|A new search, debounced by 500 milliseconds on both.
52
53 == Results ==
54
55 Every result of a search is one ##attachmentGroup## element:
56
57 {{code language="html"}}
58 <span class="attachmentGroup localAttachment"> <!-- jQuery data "id": the attachment reference -->
59 <a title="logo.png" href="/xwiki/bin/download/Sandbox/WebHome/logo.png">
60 <span class="previewWrapper">
61 <img loading="lazy" alt="logo.png"
62 src="/xwiki/bin/download/Sandbox/WebHome/logo.png?width=150&height=150&keepAspectRatio=true">
63 </span>
64 <span class="attachmentTitle" title="logo.png">logo.png</span>
65 </a>
66 </span>
67 {{/code}}
68
69 |=Carried by a result|=Value
70 |The class ##localAttachment## or ##globalAttachment##|Whether the attachment comes from the Page being searched or from another one
71 |The class ##selected##|Set on the selected result
72 |The jQuery data ##id##, on the group|The reference of the attachment, held as data rather than as an attribute
73 |The jQuery data ##index##, on the link|The rank of the result in the grid, held the same way
74 |The ##attachmentTitle## span, and the ##title## of both the span and the link|The file name
75
76 |=Preview|=Shown for
77 |The attachment itself, in an ##img## whose address carries ##?width=150&height=150&keepAspectRatio=true##, so the wiki resizes it into a 150 by 150 box while preserving its aspect ratio|A media type starting with ##image/##
78 |A span carrying the class of the media type's icon, taken from ##xwiki-attachments-icon##, plus the class ##attachmentIcon##|Any other media type, with a font icon theme
79 |An image element pointing at the address of that icon|Any other media type, with a theme that is not a font one
80
81 While a search runs, the results block is emptied and carries the class ##loading##. A search that fails is logged to the browser console and reported to the reader as an error notification.
82
83 == Selection ==
84
85 A picker reports what the reader picks through two events fired on its root element, documented with an example on the [[attachmentGalleryPicker macro>>doc:documentation.xs.dev.attachments.attachmentgallerypicker-macro.WebHome]] page.
86
87 |=Rule|=Behaviour
88 |Selection is single|Selecting a result unselects every other.
89 |Clicking the selected result|Clears the selection.
90 |Double click|Only the first click of a chain selects, so the second click does not undo the selection the first one made.
91 |A new search|Keeps the selection while the attachment is still among the results, and clears it otherwise.
92 |The ##attachmentPickerGlobalSelection## block|Shown exactly while the selected result carries ##globalAttachment##, and hidden again when the selection is cleared or a new search runs.
93
94 == Messages ==
95
96 The four messages of the picker are loaded through ##xwiki-l10n!##, under the prefix ##attachment.picker.##, and none of them is defined in this WebJar:
97
98 |=Key|=Labels|=Defined by
99 |##solrSearch.query.errorMessage##|The notification shown when a search fails|The ##attachmentGalleryPicker## macro module
100 |##searchField.placeholder##|The search field|The ##Attachment.Picker.Code.Translations## page of the Attachment Picker Application
101 |##searchField.scope.currentPage##|The scope button of the current Page|The same page
102 |##searchField.scope.allPages##|The scope button of every Page|The same page
103
104 The texts of the two blocks the JavaScript only shows and hides, ##attachment.picker.macro.notResult.message## and ##attachment.picker.macro.globalSelection.message##, belong to the macro module as well.

Get Connected