Änderungen von Dokument Icon Picker

Zuletzt geändert von MACH ProForms GmbH am 30.01.2025

Von Version 1.1
bearbeitet von MACH ProForms GmbH
am 18.07.2019
Änderungskommentar: Copied from fswikitemplate:IconThemesCode.IconPicker
Auf Version 3.1
bearbeitet von MACH ProForms GmbH
am 30.01.2025
Änderungskommentar: Install extension [org.xwiki.platform:xwiki-platform-icon-ui/16.10.3]

Zusammenfassung

Details

Seiteneigenschaften
Inhalt
... ... @@ -1,29 +1,30 @@
1 1  {{velocity}}
2 2  ###########################
3 -## GLOBALS
4 -###########################
5 -#set($xwikiIcons = ['home', 'wiki', 'space', 'page', 'check', 'add', 'anchor', 'terminal', 'list', 'branch', 'down', 'up', 'left', 'right', 'arrows', 'repeat', 'undo', 'refresh', 'rotate-left', 'rotate-right', 'switch', 'random', 'attach', 'shopping-cart', 'bell', 'trash', 'bomb', 'book', 'cube', 'cubes', 'briefcase', 'bug', 'building', 'caret-down', 'caret-up', 'caret-right', 'calculator', 'calendar', 'camera', 'remove', 'cross', 'car', 'truck', 'chart-bar', 'chart-organisation', 'cloud', 'clock', 'cog', 'comment', 'comments', 'desktop', 'contrast', 'eject', 'step-forward', 'step-backward', 'fast-forward', 'backward', 'play', 'pause', 'stop', 'gamepad', 'credit-card', 'coffee', 'cut', 'database', 'delete', 'floppy-disk', 'glass', 'drive', 'envelope', 'warning', 'error', 'info', 'eye', 'rss', 'female', 'male', 'film', 'flag', 'search', 'search-plus', 'search-minus', 'folder', 'user', 'group', 'heart', 'question', 'image', 'key', 'keyboard', 'lightbulb', 'link', 'unlink', 'lock', 'unlock', 'money', 'dollar', 'euro', 'gbp', 'yen', 'music', 'file', 'file-white', 'file-pdf', 'file-code', 'file-archive', 'file-word', 'file-excel', 'file-powerpoint', 'file-text', 'paste', 'pencil', 'print', 'shield', 'certificate', 'volume-up', 'volume-down', 'volume-off', 'soccer', 'star', 'table', 'phone', 'font', 'bold', 'italic', 'strikethrough', 'subscript', 'superscript', 'underline', 'align-center', 'align-justify', 'align-left', 'align-right', 'columns', 'indent-left', 'indent-right', 'list-bullets', 'list-numbers', 'sun', 'world', 'wrench'])
6 -###########################
7 7  ## DATA: ICON THEMES
8 8  ###########################
9 -#if($request.action == 'data_iconthemes')
10 - #set($map = {})
11 - #set($discard = $map.put('iconThemes', $services.icon.iconSetNames))
12 - #set($discard = $map.put('currentIconTheme', $services.icon.currentIconSetName))
13 - $jsontool.serialize($map)
5 +#if ($request.action == 'data_iconthemes')
6 + #set ($map = {})
7 + #set ($discard = $map.put('iconThemes', $services.icon.iconSetNames))
8 + #set ($discard = $map.put('currentIconTheme', $services.icon.currentIconSetName))
9 + #jsonResponse($map)
14 14  ###########################
15 15  ## DATA: ICONS
16 16  ###########################
17 -#elseif($request.action == 'data_icons')
18 - #set($icons = [])
19 - #set($iconTheme = $request.iconTheme)
20 - #foreach($xwikiIcon in $xwikiIcons)
21 - #set($icon = {})
22 - #set($discard = $icon.put('name', $xwikiIcon))
23 - #set($discard = $icon.put('render', $services.icon.renderHTML($xwikiIcon, $iconTheme)))
24 - #set($discard = $icons.add($icon))
13 +#elseif ($request.action == 'data_icons')
14 + #set ($icons = [])
15 + #set ($iconTheme = $request.iconTheme)
16 + #set ($xwikiIcons = $collectiontool.sort($services.icon.getIconNames($iconTheme)))
17 + #set ($iconNamePrefix = $request.query.toLowerCase())
18 + #foreach ($xwikiIcon in $xwikiIcons)
19 + #if ("$!iconNamePrefix" == '' || $xwikiIcon.startsWith($iconNamePrefix))
20 + #set ($discard = $icons.add({
21 + 'name': $xwikiIcon,
22 + 'render': $services.icon.renderHTML($xwikiIcon, $iconTheme),
23 + 'metadata': $services.icon.getMetaData($xwikiIcon, $iconTheme)
24 + }))
25 + #end
25 25   #end
26 - $jsontool.serialize($icons)
27 + #jsonResponse($icons)
27 27  #else
28 28  = Presentation =
29 29  The Icon Picker is a jQuery plugin written by XWiki to help user selecting an icon. See [[IconPickerMacro]] for using this picker easily. If you want to use it manually, read the following.
... ... @@ -36,7 +36,7 @@
36 36  \#set(\$discard = \$xwiki.ssx.use('IconThemesCode.IconPicker'))
37 37  
38 38  // JavaScript code:
39 -<script language="javascript">
40 +<script>
40 40  
41 41  // Configure requirejs to load the picker code
42 42  require.config({
XWiki.JavaScriptExtension[0]
Code
... ... @@ -55,23 +55,37 @@
55 55   * Display the list of icons
56 56   */
57 57   var displayList = function(iconTheme) {
58 + // Filter the icons we display based on the value of the input field.
59 + let selectedIconName = '';
60 + if (currentInput.data('xwikiIconPickerSettings') !== '') {
61 + selectedIconName = currentInput[0].value.replace(currentInput.data('xwikiIconPickerSettings').prefix, '');
62 + }
58 58   // For each icon
59 59   for (var i=0; i < iconTheme.length; ++i) {
60 60   // Display the icon
61 - var displayer = $(document.createElement('div'));
62 - iconListSection.append(displayer);
63 - displayer.addClass('xwikiIconPickerIcon');
64 - var imageDiv = $(document.createElement('div'));
65 - imageDiv.addClass('xwikiIconPickerIconImage').html(iconTheme[i].render);
66 - displayer.append(imageDiv);
67 - var iconNameDiv = $(document.createElement('div'));
68 - iconNameDiv.addClass('xwikiIconPickerIconName').text(iconTheme[i].name);
69 - displayer.append(iconNameDiv);
70 - // Change the input value when the icon is clicked
71 - displayer.click(function(event) {
72 - currentInput.val(currentInput.data('xwikiIconPickerSettings').prefix + $(event.currentTarget).children('.xwikiIconPickerIconName').text() );
73 - closePicker();
74 - });
66 + if (selectedIconName === '' || iconTheme[i].name.includes(selectedIconName)) {
67 + var displayer = $(document.createElement('button'));
68 + displayer.addClass('btn');
69 + iconListSection.append(displayer);
70 + displayer.addClass('xwikiIconPickerIcon');
71 + var imageDiv = $(document.createElement('p'));
72 + imageDiv.addClass('xwikiIconPickerIconImage').html(iconTheme[i].render);
73 + displayer.append(imageDiv);
74 + var iconNameSpan = $(document.createElement('p'));
75 + // Usually, the icon name is just one "word" in snakecase. e.g. arrow_refresh_small
76 + // We add Line Break Opportunity elements in the middle of this word so that it's cut into nice to read
77 + // substrings.
78 + let iconNameWithLineBreakOpportunities = iconTheme[i].name
79 + .replaceAll("-","<wbr/>-")
80 + .replaceAll("_","<wbr/>_");
81 + iconNameSpan.addClass('xwikiIconPickerIconName').html(iconNameWithLineBreakOpportunities);
82 + displayer.append(iconNameSpan);
83 + // Change the input value when the icon is clicked
84 + displayer.on('click', function(event) {
85 + currentInput.val(currentInput.data('xwikiIconPickerSettings').prefix + $(event.currentTarget).children('.xwikiIconPickerIconName').text());
86 + closePicker();
87 + });
88 + }
75 75   }
76 76   }
77 77  
... ... @@ -79,7 +79,7 @@
79 79   * Load the icon list (get the JSON from the server) and display it afterwards
80 80   */
81 81   var loadIconList = function(iconTheme) {
82 - $.getJSON(getResourceURL('data_icons', 'iconTheme='+iconTheme), function(dataIcons) {
96 + $.getJSON(getResourceURL('data_icons', 'iconTheme=' + iconTheme), function(dataIcons) {
83 83   // Put the result in the icons map
84 84   icons[iconTheme] = dataIcons;
85 85   // Display the list
... ... @@ -130,7 +130,7 @@
130 130   var createIconThemeSelector = function() {
131 131   iconThemeSelector = $(document.createElement('select'));
132 132   // Change the current icon theme where the selector is used
133 - iconThemeSelector.change(function() {
147 + iconThemeSelector.on('change', function() {
134 134   currentIconTheme = iconThemeSelector.val();
135 135   // Remove all the displayed icons
136 136   $('.xwikiIconPickerIcon').remove();
... ... @@ -187,7 +187,7 @@
187 187   }
188 188  
189 189   /**
190 - * Create the piccker
204 + * Create the picker
191 191   */
192 192   var createPicker = function (input) {
193 193   // If the picker already exists
... ... @@ -206,7 +206,7 @@
206 206   xwikiCurrentIconsPicker = $(document.createElement('div'));
207 207   xwikiCurrentIconsPicker.addClass('xwikiIconPickerContainer');
208 208   // Insert the picker in the DOM
209 - $(body).append(xwikiCurrentIconsPicker);
223 + xwikiCurrentIconsPicker.insertAfter(currentInput);
210 210   // Set the position
211 211   setPickerPosition();
212 212   // Add the icon list section
... ... @@ -242,15 +242,34 @@
242 242   loadIconList(currentIconTheme);
243 243   }
244 244   }
245 - // Close the picker when the user press 'escape'.
246 - currentInput.keyup(function (event) {
259 + var lastTimeout = 0;
260 + var reloadIconList = function () {
261 + // Remove all the displayed icons
262 + $('.xwikiIconPickerIcon').remove();
263 + // Display the new ones. We always reload because the filter results are unrelated.
264 + displayList(icons[currentIconTheme]);
265 + };
266 + currentInput.on('keyup', function(event) {
267 + // Close the picker when the user press 'escape'.
247 247   // See: http://stackoverflow.com/questions/1160008/which-keycode-for-escape-key-with-jquery
248 248   if (event.which == 27) {
249 249   closePicker();
271 + } else {
272 + if (lastTimeout!==0) {
273 + clearTimeout(lastTimeout);
274 + }
275 + lastTimeout = setTimeout(reloadIconList, 500);
250 250   }
251 251   });
278 + iconThemeSelector.on('keyup', function(event) {
279 + // Close the picker when the user press 'escape'.
280 + // See: http://stackoverflow.com/questions/1160008/which-keycode-for-escape-key-with-jquery
281 + if (event.which == 27) {
282 + closePicker();
283 + }
284 + });
252 252   }
253 -
286 +
254 254   /**
255 255   * Create the jQuery plugin
256 256   */
... ... @@ -259,7 +259,7 @@
259 259   var settings = $.extend({
260 260   prefix: 'icon:image:'
261 261   }, options);
262 -
295 +
263 263   // Enable the picker on focus
264 264   this.each(function() {
265 265   var elem = $(this);
... ... @@ -270,25 +270,25 @@
270 270   // Attach the settings to the input
271 271   $(this).data('xwikiIconPickerSettings', settings);
272 272   // Create the picker on focus
273 - $(this).focusin(function(event) {
306 + $(this).on('focusin', function(event) {
274 274   createPicker($(event.currentTarget));
275 275   });
276 276   });
277 -
310 +
278 278   // Because the picker uses the 'fixed' position, we must recompute its position everytime the user scrolls the page
279 279   // Otherwise, the picker would stay in the same position *on the screen* without staying close to the input.
280 - $(window).scroll(function() {
313 + $(window).on('scroll', function() {
281 281   setPickerPosition();
282 282   });
283 -
316 +
284 284   // Close the picker if the input and the picker itself have lost the focus
285 - $(window).click(function(event) {
318 + $(window).on('click', function(event) {
286 286   if (xwikiCurrentIconsPicker && document.activeElement != currentInput[0] &&
287 287   !$.contains(xwikiCurrentIconsPicker[0], document.activeElement)) {
288 288   closePicker();
289 289   }
290 290   });
291 -
324 +
292 292   // Return this object to enable the jQuery chaining
293 293   return this;
294 294   }
XWiki.StyleSheetExtension[0]
Code
... ... @@ -12,18 +12,26 @@
12 12  .xwikiIconPickerList {
13 13   overflow-y: scroll;
14 14   height: 240px;
15 + display: flex;
16 + flex-wrap: wrap;
17 + gap: .3em;
15 15  }
16 16  
20 +/* Avoid stretching on the Loader element. */
21 +.xwikiIconPickerList > img {
22 + object-fit: contain;
23 +}
24 +
17 17  .xwikiIconPickerIcon {
18 - float: left;
19 19   height: 80px;
20 20   width: 100px;
21 21   text-align: center;
22 - border-radius: 4px;
29 + border-radius: 7px;
23 23   vertical-align: middle;
24 24   overflow: hidden;
25 25   padding: 10px;
26 26   cursor: pointer;
34 + background-color: transparent;
27 27  }
28 28  
29 29  .xwikiIconPickerIcon:hover {
... ... @@ -32,6 +32,7 @@
32 32  
33 33  .xwikiIconPickerIconImage {
34 34   font-size: 24px;
43 + line-height: 1;
35 35   margin: 0;
36 36  }
37 37  
... ... @@ -39,6 +39,18 @@
39 39   width: 24px;
40 40  }
41 41  
51 +.xwikiIconPickerIcon .xwikiIconPickerIconName {
52 + /* We want to limit the number of lines in the name so that it always fit inside the standard button size.
53 + The value below is just about twice the line-height. */
54 + max-height: 2.9em;
55 + /* For the few names that need three lines, we make sure the user can scroll to read the whole name. */
56 + overflow-y: scroll;
57 + overflow-x: hidden;
58 + /* Make sure the name wraps onto multiple lines instead of overflowing. */
59 + white-space: pre-wrap;
60 + word-break: break-word;
61 +}
62 +
42 42  .xwikiIconPickerIconThemeSelector {
43 43   width: 100%;
44 44   background-color: $theme.menuBackgroundColor;