1 <?php 2 // This file is part of Moodle - http://moodle.org/ 3 // 4 // Moodle is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // Moodle is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>. 16 17 /** 18 * Test page for dropdown dialog output component. 19 * 20 * @copyright 2023 Ferran Recio <ferran@moodle.com> 21 * @package core 22 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 23 */ 24 25 require_once(__DIR__ . '/../../../../config.php'); 26 27 defined('BEHAT_SITE_RUNNING') || die(); 28 29 global $CFG, $PAGE, $OUTPUT; 30 $PAGE->set_url('/lib/tests/behat/fixtures/dropdown_dialog_testpage.php'); 31 $PAGE->add_body_class('limitedwidth'); 32 require_login(); 33 $PAGE->set_context(core\context\system::instance()); 34 35 echo $OUTPUT->header(); 36 37 echo "<h2>Dropdown dialog test page</h2>"; 38 39 echo '<div id="regularscenario" class="mb-4">'; 40 echo "<h3>Basic example</h3>"; 41 $dialog = new core\output\local\dropdown\dialog('Open dialog', 'Dialog content'); 42 echo $OUTPUT->render($dialog); 43 echo '</div>'; 44 45 echo '<div id="richcontent" class="mb-4">'; 46 echo "<h3>Rich content example</h3>"; 47 $content = ' 48 <p>Some rich content <b>element</b>.</p> 49 <ul> 50 <li>Item 1 <a href="#">Link 1</a></li> 51 <li>Item 2 <a href="#">Link 2</a></li> 52 </ul> 53 '; 54 $dialog = new core\output\local\dropdown\dialog('Open dialog', $content); 55 echo $OUTPUT->render($dialog); 56 echo '</div>'; 57 58 echo '<div id="richbutton" class="mb-4">'; 59 echo "<h3>Rich button example</h3>"; 60 $button = $OUTPUT->pix_icon('t/hide', 'Eye icon') . ' Click to <b>open</b></a>'; 61 $dialog = new core\output\local\dropdown\dialog($button, 'Dialog content'); 62 echo $OUTPUT->render($dialog); 63 echo '</div>'; 64 65 echo '<div id="cssoverride" class="mb-4">'; 66 echo "<h3>CSS override example</h3>"; 67 $dialog = new core\output\local\dropdown\dialog( 68 'Open dialog', 69 'Dialog content', 70 [ 71 'buttonclasses' => 'btn btn-primary extraclass', 72 ] 73 ); 74 echo $OUTPUT->render($dialog); 75 echo '</div>'; 76 77 echo '<div id="extraattributes" class="mb-4">'; 78 echo "<h3>Extra data attributes example</h3>"; 79 $dialog = new core\output\local\dropdown\dialog('Open dialog', 'Dialog content', [ 80 'extras' => ['data-foo' => 'bar'], 81 ]); 82 echo $OUTPUT->render($dialog); 83 echo '</div>'; 84 85 echo '<div id="customid" class="mb-4">'; 86 echo "<h3>Custom element id</h3>"; 87 $dialog = new core\output\local\dropdown\dialog('Open dialog', 'Dialog content', [ 88 'extras' => ['id' => 'CustomDropdownButtonId'], 89 ]); 90 echo $OUTPUT->render($dialog); 91 echo '</div>'; 92 93 $inlinejs = "document.querySelector('#CustomDropdownButtonId button').innerHTML = 'Custom ID button found';"; 94 $PAGE->requires->js_amd_inline($inlinejs); 95 96 echo '<div id="position" class="mb-4">'; 97 echo "<h3>Dropdown position example</h3>"; 98 $dialog = new core\output\local\dropdown\dialog('Open dialog', 'Dialog content'); 99 $dialog->set_position(core\output\local\dropdown\dialog::POSITION['end']); 100 echo $OUTPUT->render($dialog); 101 echo '</div>'; 102 103 echo '<div id="widths" class="mb-4">'; 104 echo "<h3>Dropdown max width values example</h3>"; 105 $content = ' 106 Some long long content. Some long long content. Some long long content. Some long long content. 107 Some long long content. Some long long content. Some long long content. Some long long content. 108 Some long long content. Some long long content. Some long long content. Some long long content. 109 '; 110 111 $dialog = new core\output\local\dropdown\dialog('Default dialog (adaptative)', $content); 112 $dialog->set_classes('mb-3'); 113 echo $OUTPUT->render($dialog); 114 115 $dialog = new core\output\local\dropdown\dialog('Big dialog', $content); 116 $dialog->set_dialog_width(core\output\local\dropdown\dialog::WIDTH['big']); 117 $dialog->set_classes('mb-3'); 118 echo $OUTPUT->render($dialog); 119 120 $dialog = new core\output\local\dropdown\dialog('Small dialog', $content); 121 $dialog->set_dialog_width(core\output\local\dropdown\dialog::WIDTH['small']); 122 $dialog->set_classes('mb-3'); 123 echo $OUTPUT->render($dialog); 124 echo '</div>'; 125 126 echo '<div id="dialogjscontrolssection" class="mb-4">'; 127 echo "<h3>Dropdown JS module controls</h3>"; 128 echo '<div class="mb-2"> 129 <button class="btn btn-secondary" id="buttontext">Change button text</button> 130 <button class="btn btn-secondary" id="opendropdown">Open</button> 131 <button class="btn btn-secondary" id="closedropdown">Close</button> 132 <span id="dialogvisibility"></span> 133 </div>'; 134 $dialog = new core\output\local\dropdown\dialog('Open dialog', 'Dialog content', [ 135 'extras' => ['id' => 'dialogjscontrols'], 136 ]); 137 echo $OUTPUT->render($dialog); 138 echo '</div>'; 139 140 $inlinejs = <<<EOF 141 require( 142 ['core/local/dropdown/dialog', 'jquery'], 143 (Module, jQuery) => { 144 const dialog = Module.getDropdownDialog('#dialogjscontrols'); 145 146 document.querySelector('#buttontext').addEventListener('click', () => { 147 dialog.setButtonContent('New button text'); 148 }); 149 150 document.querySelector('#opendropdown').addEventListener('click', (e) => { 151 e.stopPropagation(); 152 dialog.setVisible(true); 153 }); 154 155 document.querySelector('#closedropdown').addEventListener('click', (e) => { 156 e.stopPropagation(); 157 dialog.setVisible(false); 158 }); 159 160 const visibility = () => { 161 const text = 'The dropdown is ' + (dialog.isVisible() ? 'visible' : 'hidden') + '.'; 162 document.querySelector('#dialogvisibility').innerHTML = text; 163 } 164 visibility(); 165 166 167 // Bootstrap 4 events are still jQuery. 168 jQuery(dialog.getElement()).on('shown.bs.dropdown', (e) => { 169 visibility(); 170 }); 171 jQuery(dialog.getElement()).on('hidden.bs.dropdown', (e) => { 172 visibility(); 173 }); 174 } 175 ); 176 EOF; 177 $PAGE->requires->js_amd_inline($inlinejs); 178 179 echo "<h2>Dropdown status test page</h2>"; 180 181 echo '<div id="statusregularscenario" class="mb-4">'; 182 echo "<h3>Basic example</h3>"; 183 $choice = new core\output\choicelist('Dialog content'); 184 $choice->add_option('option1', 'Option 1', [ 185 'description' => 'Option 1 description' 186 ]); 187 $choice->add_option('option2', 'Option 2', [ 188 'description' => 'Option 2 description', 189 'icon' => new pix_icon('t/hide', 'Eye icon 1') 190 ]); 191 $choice->add_option('option3', 'Option 3', [ 192 'icon' => new pix_icon('t/show', 'Eye icon 2') 193 ]); 194 $dialog = new core\output\local\dropdown\status('Open dialog', $choice); 195 echo $OUTPUT->render($dialog); 196 echo '</div>'; 197 198 echo '<div id="statusselectedscenario" class="mb-4">'; 199 echo "<h3>Selected element example</h3>"; 200 $choice = new core\output\choicelist('Dialog content'); 201 $choice->add_option('option1', 'Option 1', [ 202 'description' => 'Option 1 description', 203 'icon' => new pix_icon('t/show', 'Eye icon 1') 204 ]); 205 $choice->add_option('option2', 'Option 2', [ 206 'description' => 'Option 2 description', 207 'icon' => new pix_icon('t/hide', 'Eye icon 2') 208 ]); 209 $choice->add_option('option3', 'Option 3', [ 210 'description' => 'Option 3 description', 211 'icon' => new pix_icon('t/stealth', 'Eye icon 3') 212 ]); 213 $choice->set_selected_value('option2'); 214 $dialog = new core\output\local\dropdown\status('Open dialog', $choice); 215 echo $OUTPUT->render($dialog); 216 echo '</div>'; 217 218 echo '<div id="statusdisablescenario" class="mb-4">'; 219 echo "<h3>Disable option example</h3>"; 220 $choice = new core\output\choicelist('Dialog content'); 221 $choice->add_option('option1', 'Option 1'); 222 $choice->add_option('option2', 'Option 2', [ 223 'description' => 'Option 2 description', 224 'icon' => new pix_icon('t/hide', 'Eye icon') 225 ]); 226 $choice->add_option('option3', 'Option 3'); 227 $choice->set_option_disabled('option2', true); 228 $dialog = new core\output\local\dropdown\status('Open dialog', $choice); 229 echo $OUTPUT->render($dialog); 230 echo '</div>'; 231 232 echo '<div id="statusoptionextrasscenario" class="mb-4">'; 233 echo "<h3>Set option extra attributes example</h3>"; 234 $choice = new core\output\choicelist('Dialog content'); 235 $choice->add_option('option1', 'Option 1'); 236 $choice->add_option('option2', 'Option 2', [ 237 'description' => 'Option 2 description', 238 'icon' => new pix_icon('t/hide', 'Eye icon') 239 ]); 240 $choice->add_option('option3', 'Option 3'); 241 $choice->set_option_extras('option2', ['data-foo' => 'bar']); 242 $dialog = new core\output\local\dropdown\status('Open dialog', $choice); 243 echo $OUTPUT->render($dialog); 244 echo '</div>'; 245 246 echo '<div id="statusoptionurl" class="mb-4">'; 247 echo "<h3>Set option url example</h3>"; 248 $choice = new core\output\choicelist('Dialog content'); 249 $choice->add_option('option1', 'Option 1'); 250 $choice->add_option('option2', 'Option 2', [ 251 'url' => new moodle_url('/lib/tests/behat/fixtures/dropdown_output_testpage.php', ['foo' => 'bar']), 252 ]); 253 $choice->add_option('option3', 'Option 3'); 254 $choice->set_option_extras('option2', ['data-foo' => 'bar']); 255 $dialog = new core\output\local\dropdown\status('Open dialog', $choice); 256 echo $OUTPUT->render($dialog); 257 $foo = optional_param('foo', 'none', PARAM_TEXT); 258 echo "<p>Foo param value: $foo</p>"; 259 echo '</div>'; 260 261 echo '<div id="statussyncbutton" class="mb-4">'; 262 echo "<h3>Sync button text</h3>"; 263 $choice = new core\output\choicelist('Dialog content'); 264 $choice->add_option('option1', 'Option 1', [ 265 'description' => 'Option 1 description', 266 'icon' => new pix_icon('t/show', 'Eye icon 1') 267 ]); 268 $choice->add_option('option2', 'Option 2', [ 269 'description' => 'Option 2 description', 270 'icon' => new pix_icon('t/hide', 'Eye icon 2') 271 ]); 272 $choice->add_option('option3', 'Option 3', [ 273 'description' => 'Option 3 description', 274 'icon' => new pix_icon('t/stealth', 'Eye icon 3') 275 ]); 276 $choice->set_selected_value('option2'); 277 $dialog = new core\output\local\dropdown\status( 278 'Open dialog', 279 $choice, 280 ['buttonsync' => true, 'updatestatus' => true] 281 ); 282 echo '<button class="btn">Focus helper</button>'; 283 echo $OUTPUT->render($dialog); 284 echo '</div>'; 285 286 echo '<div id="statusjscontrolsection" class="mb-4">'; 287 echo "<h3>Status JS controls</h3>"; 288 echo '<div class="mb-2"> 289 <button class="btn btn-secondary" id="setselected">Change selected value</button> 290 <button class="btn btn-secondary" id="syncbutton">Enable sync</button> 291 <button class="btn btn-secondary" id="updatestatus">Disable update</button> 292 <span id="statusvalue"></span> 293 </div>'; 294 $choice = new core\output\choicelist('Dialog content'); 295 $choice->add_option('option1', 'Option 1', [ 296 'description' => 'Option 1 description', 297 'icon' => new pix_icon('t/show', 'Eye icon 1') 298 ]); 299 $choice->add_option('option2', 'Option 2', [ 300 'description' => 'Option 2 description', 301 'icon' => new pix_icon('t/hide', 'Eye icon 2') 302 ]); 303 $choice->add_option('option3', 'Option 3', [ 304 'description' => 'Option 3 description', 305 'icon' => new pix_icon('t/stealth', 'Eye icon 3') 306 ]); 307 $choice->set_selected_value('option2'); 308 $dialog = new core\output\local\dropdown\status( 309 'Open dialog', 310 $choice, 311 [ 312 'extras' => ['id' => 'statusjscontrols'], 313 'updatestatus' => true 314 ], 315 ); 316 echo $OUTPUT->render($dialog); 317 echo '</div>'; 318 319 $inlinejs = <<<EOF 320 require( 321 ['core/local/dropdown/status', 'jquery'], 322 (Module, jQuery) => { 323 const status = Module.getDropdownStatus('#statusjscontrols'); 324 325 const printValue = () => { 326 const text = 'The status value is ' + status.getSelectedValue() + '.'; 327 document.querySelector('#statusvalue').innerHTML = text; 328 } 329 printValue(); 330 331 document.querySelector('#setselected').addEventListener('click', () => { 332 if (status.getSelectedValue() == 'option2') { 333 status.setSelectedValue('option3'); 334 } else { 335 status.setSelectedValue('option2'); 336 } 337 }); 338 339 document.querySelector('#syncbutton').addEventListener('click', (e) => { 340 if (status.isButtonSyncEnabled()) { 341 status.setButtonSyncEnabled(false); 342 } else { 343 status.setButtonSyncEnabled(true); 344 } 345 e.target.innerHTML = (status.isButtonSyncEnabled()) ? 'Disable sync': 'Enable sync'; 346 }); 347 348 document.querySelector('#updatestatus').addEventListener('click', (e) => { 349 if (status.isUpdateStatusEnabled()) { 350 status.setUpdateStatusEnabled(false); 351 } else { 352 status.setUpdateStatusEnabled(true); 353 } 354 e.target.innerHTML = (status.isUpdateStatusEnabled()) ? 'Disable update': 'Enable update'; 355 }); 356 357 status.getElement().addEventListener('change', () => { 358 printValue(); 359 }); 360 361 } 362 ); 363 EOF; 364 $PAGE->requires->js_amd_inline($inlinejs); 365 366 echo $OUTPUT->footer();
title
Description
Body
title
Description
Body
title
Description
Body
title
Body