dolibarr 24.0.0-beta
intuitive-table-row-select.php
1<?php
2/*
3 * Copyright (C) 2024 Anthony Damhet <a.damhet@progiseize.fr>
4 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20// Load Dolibarr environment
21require '../../../../main.inc.php';
22
30// Protection if external user
31if ($user->socid > 0) {
33}
34
35// Includes
36require_once DOL_DOCUMENT_ROOT . '/admin/tools/ui/class/documentation.class.php';
37
38// Load documentation translations
39$langs->load('uxdocumentation');
40
41//
42$documentation = new Documentation($db);
43$group = 'Content';
44$experimentName = 'TableRowIntuitiveSelect';
45
46
47$js = [
48 '/includes/ace/src/ace.js',
49 '/includes/ace/src/ext-statusbar.js',
50 '/includes/ace/src/ext-language_tools.js',
51];
52$css = [
53
54];
55
56// Output html head + body - Param is Title
57$documentation->docHeader($langs->trans($experimentName, $group), $js, $css);
58
59// Set view for menu and breadcrumb
60$documentation->view = [$group, $experimentName];
61
62// Output sidebar
63$documentation->showSidebar();
64$form = new Form($db);
65
66?>
67
68<div class="doc-wrapper">
69
70 <?php $documentation->showBreadCrumb(); ?>
71
72 <div class="doc-content-wrapper">
73
74 <h1 class="documentation-title"><?php echo $langs->trans($experimentName); ?></h1>
75
76 <?php $documentation->showSummary(); ?>
77
78 <div class="documentation-section" >
79 <h2 class="documentation-title" >Select table lines by <kbd>Ctrl</kbd> + <kbd>Click</kbd></h2>
80
81
82 <h2>Description</h2>
83 <p>
84 This feature allows users to <strong>select</strong> or <strong>deselect</strong> table rows (<code>&lt;tr&gt;</code>) in an HTML table:
85 </p>
86 <ul>
87 <li>Holding down <strong>Ctrl</strong> (or <strong>Cmd</strong> on Mac) allows users to add or remove individual rows from the selection.</li>
88 <li>Holding down <strong>Shift</strong> allows users to <strong>select a range</strong> of rows between the last selected row and the clicked row.</li>
89 </ul>
90
91 <h2>Detailed Behavior</h2>
92 <table border="1" cellpadding="6" cellspacing="0">
93 <thead>
94 <tr>
95 <th>User Action</th>
96 <th>Expected Result</th>
97 </tr>
98 </thead>
99 <tbody>
100 <tr>
101 <td>Ctrl + Click on a row</td>
102 <td>Toggles selection of the clicked row (add/remove).</td>
103 </tr>
104 <tr>
105 <td>Shift + Click on a row</td>
106 <td>Selects all rows between the last selected and clicked row.</td>
107 </tr>
108 </tbody>
109 </table>
110
111 <h2>HTML Requirements</h2>
112 <p>
113 The table should follow a standard structure with <code>&lt;thead&gt;</code> and <code>&lt;tbody&gt;</code> elements,
114 and each <code>&lt;tr&gt;</code> must be selectable by applying <code>.row-with-select</code> CSS class and have checkbox with <code>.checkforselect</code> class
115 </p>
116
117 <h2>Key Notes</h2>
118 <ul>
119 <li>The script supports <strong>Cmd</strong> key (for Mac users) as an alternative to <strong>Ctrl</strong>.</li>
120 <li>When Shift-clicking without a previously selected row, selection will not start.</li>
121 <li>When user start selection, the css rules will remove text selection possibility.</li>
122 <li>When the user double-clicks, the selection functionality is reactivated, but the reference to the last selected row is cleared, thus disabling the <code>Shift + Click</code> range selection behavior.</li>
123 </ul>
124
125
126 <div class="documentation-example">
127 <div class="div-table-responsive">
128 <table class="tagtable liste listwithfilterbefore table-with-select" id="try-line-ctrl-click-feature">
129 <thead>
130 <tr class="liste_titre_filter">
131 <td class="liste_titre center maxwidthsearch">
132 <div class="nowraponall">
133 <button type="submit" class="liste_titre button_search reposition" name="button_search_x" value="x">
134 <span class="fas fa-search"></span>
135 </button>
136 <button type="submit" class="liste_titre button_removefilter reposition" name="button_removefilter_x" value="x">
137 <span class="fas fa-times"></span>
138 </button>
139 </div>
140 </td>
141 <td><input class="flat" type="text" name="search_firstname" value=""></td>
142 <td><input class="flat" type="text" name="search_lasttname" value=""></td>
143 <td class="center"><input class="maxwidth50 flat" type="text" name="search_age" value=""></td>
144 <td class="right"><input class="flat" type="text" name="search_country" value=""></td>
145 </tr>
146 <tr class="liste_titre">
147 <th>
148 <dl class="dropdown" style="opacity: 0.5;">
149 <dt><span class="fas fa-list" style=""></span></dt>
150 <dd class="dropdowndd">
151 <div class="multiselectcheckboxselectedfields">
152 <ul class="selectedfieldsleft"></ul>
153 </div>
154 </dd>
155 </dl>
156 <div class="inline-block checkallactions">
157 <input type="checkbox" id="checkforselects" name="checkforselects" class="checkallactions" >
158 <script nonce="<?php echo getNonce(); ?>" >
159 // TODO : Dolibarr use this kind of script inclusion for toggle checkboxes : we need to add a more global js method
160 $(document).ready(function() {
161 $("#checkforselects").click(function() {
162 if($(this).is(':checked')){
163 console.log("We check all checkforselect and trigger the change method");
164 $(".checkforselect").prop('checked', true).trigger('change');
165 }
166 else
167 {
168 console.log("We uncheck all");
169 $(".checkforselect").prop('checked', false).trigger('change');
170 }
171 if (typeof initCheckForSelect == 'function') { initCheckForSelect(0, "massaction", "checkforselect"); } else { console.log("No function initCheckForSelect found. Call won't be done."); } });
172 $(".checkforselect").change(function() {
173 // TODO : change this by a simple css rule
174 $(this).closest("tr").toggleClass("highlight", this.checked);
175 });
176 });
177 </script>
178 </div>
179 </th>
180 <th class="wrapcolumntitle left" title="First Name">First Name</th>
181 <th class="wrapcolumntitle left" title="Last Name">Last Name</th>
182 <th class="wrapcolumntitle center" title="Age">Age</th>
183 <th class="wrapcolumntitle right" title="Country">Country</th>
184 </tr>
185 </thead>
186 <tbody>
187 <tr class="oddeven row-with-select" >
188 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
189 <td class="left">John</td>
190 <td class="left">Doe</td>
191 <td class="center">37</td>
192 <td class="right">U.S.A</td>
193 </tr>
194 <tr class="oddeven row-with-select">
195 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
196 <td class="left">Jack</td>
197 <td class="left">Sparrow</td>
198 <td class="center">29</td>
199 <td class="right">Caribbean</td>
200 </tr>
201 <tr class="oddeven row-with-select">
202 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
203 <td class="left">Sacha</td>
204 <td class="left">Ketchum</td>
205 <td class="center">16</td>
206 <td class="right">Kanto</td>
207 </tr>
208 <tr class="oddeven row-with-select">
209 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
210 <td class="left">Albert</td>
211 <td class="left">Einstein</td>
212 <td class="center">72</td>
213 <td class="right">Germany</td>
214 </tr>
215 <tr class="oddeven row-with-select" >
216 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
217 <td class="left">John</td>
218 <td class="left">Doe</td>
219 <td class="center">37</td>
220 <td class="right">U.S.A</td>
221 </tr>
222 <tr class="oddeven row-with-select">
223 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
224 <td class="left">Jack</td>
225 <td class="left">Sparrow</td>
226 <td class="center">29</td>
227 <td class="right">Caribbean</td>
228 </tr>
229 <tr class="oddeven row-with-select">
230 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
231 <td class="left">Sacha</td>
232 <td class="left">Ketchum</td>
233 <td class="center">16</td>
234 <td class="right">Kanto</td>
235 </tr>
236 <tr class="oddeven row-with-select">
237 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
238 <td class="left">Albert</td>
239 <td class="left">Einstein</td>
240 <td class="center">72</td>
241 <td class="right">Germany</td>
242 </tr>
243 <tr class="oddeven row-with-select" >
244 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
245 <td class="left">John</td>
246 <td class="left">Doe</td>
247 <td class="center">37</td>
248 <td class="right">U.S.A</td>
249 </tr>
250 <tr class="oddeven row-with-select">
251 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
252 <td class="left">Jack</td>
253 <td class="left">Sparrow</td>
254 <td class="center">29</td>
255 <td class="right">Caribbean</td>
256 </tr>
257 <tr class="oddeven row-with-select">
258 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
259 <td class="left">Sacha</td>
260 <td class="left">Ketchum</td>
261 <td class="center">16</td>
262 <td class="right">Kanto</td>
263 </tr>
264 <tr class="oddeven row-with-select">
265 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
266 <td class="left">Albert</td>
267 <td class="left">Einstein</td>
268 <td class="center">72</td>
269 <td class="right">Germany</td>
270 </tr>
271 <tr class="oddeven row-with-select" >
272 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
273 <td class="left">John</td>
274 <td class="left">Doe</td>
275 <td class="center">37</td>
276 <td class="right">U.S.A</td>
277 </tr>
278 <tr class="oddeven row-with-select">
279 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
280 <td class="left">Jack</td>
281 <td class="left">Sparrow</td>
282 <td class="center">29</td>
283 <td class="right">Caribbean</td>
284 </tr>
285 <tr class="oddeven row-with-select">
286 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
287 <td class="left">Sacha</td>
288 <td class="left">Ketchum</td>
289 <td class="center">16</td>
290 <td class="right">Kanto</td>
291 </tr>
292 <tr class="oddeven row-with-select">
293 <td><input class="checkforselect" type="checkbox" name="" value="" ></td>
294 <td class="left">Albert</td>
295 <td class="left">Einstein</td>
296 <td class="center">72</td>
297 <td class="right">Germany</td>
298 </tr>
299 </tbody>
300 </table>
301
302 </div>
303
304
305 </div>
306 </div>
307
308
309 </div>
310
311</div>
312<?php
313// Output close body + html
314$documentation->docFooter();
315?>
Class to manage UI documentation.
Class to manage generation of HTML components Only common components must be here.
Class to manage Dolibarr users.
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
multi select button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
treeview li table
No Email.
$conf db user
Active Directory does not allow anonymous connections.
Definition repair.php:134
if(preg_match('/(crypted|dolcrypt):/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
'integer', 'integer:ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter[:Sortfield]]]',...
Definition repair.php:130
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition repair.php:133
accessforbidden($message='', $printheader=1, $printfooter=1, $showonlymessage=0, $params=null)
Show a message to say access is forbidden and stop program.