Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 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
namespace core\output\local\dropdown;
18
 
19
use core\output\named_templatable;
20
use renderable;
21
 
22
/**
23
 * Class to render a dropdown dialog element.
24
 *
25
 * A dropdown dialog allows to render any arbitrary HTML into a dropdown elements triggered
26
 * by a button.
27
 *
28
 * @package    core
29
 * @category   output
30
 * @copyright  2023 Ferran Recio <ferran@moodle.com>
31
 * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
32
 */
33
class dialog implements named_templatable, renderable {
34
    /** Dropdown dialog positions. */
35
    public const POSITION = [
36
        'start' => 'dropdown-menu-left',
37
        'end' => 'dropdown-menu-right',
38
    ];
39
 
40
    /** Dropdown dialog positions. */
41
    public const WIDTH = [
42
        'default' => '',
43
        'big' => 'dialog-big',
44
        'small' => 'dialog-small',
45
    ];
46
 
47
    /**
48
     * @var string content of dialog.
49
     */
50
    protected $dialogcontent = '';
51
 
52
    /**
53
     * @var bool if the footer should auto enable or not.
54
     */
55
    protected $buttoncontent = true;
56
 
57
    /**
58
     * @var string trigger button CSS classes.
59
     */
60
    protected $buttonclasses = '';
61
 
62
    /**
63
     * @var string component CSS classes.
64
     */
65
    protected $classes = '';
66
 
67
    /**
68
     * @var string the dropdown position.
69
     */
70
    protected $dropdownposition = self::POSITION['start'];
71
 
72
    /**
73
     * @var string dropdown preferred width.
74
     */
75
    protected $dropdownwidth = self::WIDTH['default'];
76
 
77
 
78
    /**
79
     * @var array extra HTML attributes (attribute => value).
80
     */
81
    protected $extras = [];
82
 
83
    /**
84
     * @var bool if the element is disabled.
85
     */
86
    protected $disabled = false;
87
 
88
    /**
89
     * Constructor.
90
     *
91
     * The definition object could contain the following keys:
92
     * - classes: component CSS classes.
93
     * - buttonclasses: the button CSS classes.
94
     * - dialogwidth: the dropdown width.
95
     * - dropdownposition: the dropdown position.
96
     * - extras: extra HTML attributes (attribute => value).
97
     *
98
     * @param string $buttoncontent the button content
99
     * @param string $dialogcontent the footer content
100
     * @param array $definition an optional array of the element definition
101
     */
102
    public function __construct(string $buttoncontent, string $dialogcontent, array $definition = []) {
103
        $this->buttoncontent = $buttoncontent;
104
        $this->dialogcontent = $dialogcontent;
105
        if (isset($definition['classes'])) {
106
            $this->classes = $definition['classes'];
107
        }
108
        if (isset($definition['buttonclasses'])) {
109
            $this->buttonclasses = $definition['buttonclasses'];
110
        }
111
        if (isset($definition['extras'])) {
112
            $this->extras = $definition['extras'];
113
        }
114
        if (isset($definition['dialogwidth'])) {
115
            $this->dropdownwidth = $definition['dialogwidth'];
116
        }
117
        if (isset($definition['dropdownposition'])) {
118
            $this->dropdownposition = $definition['dropdownposition'];
119
        }
120
    }
121
 
122
    /**
123
     * Set the dialog contents.
124
     *
125
     * @param string $dialogcontent
126
     */
127
    public function set_content(string $dialogcontent) {
128
        $this->dialogcontent = $dialogcontent;
129
    }
130
 
131
    /**
132
     * Set the button contents.
133
     *
134
     * @param string $buttoncontent
135
     * @param string|null $buttonclasses the button classes
136
     */
137
    public function set_button(string $buttoncontent, ?string $buttonclasses = null) {
138
        $this->buttoncontent = $buttoncontent;
139
        if ($buttonclasses !== null) {
140
            $this->buttonclasses = $buttonclasses;
141
        }
142
    }
143
 
144
    /**
145
     * Set the dialog width.
146
     *
147
     * @param string $width
148
     */
149
    public function set_dialog_width(string $width) {
150
        $this->dropdownwidth = $width;
151
    }
152
 
153
    /**
154
     * Add extra classes to trigger butotn.
155
     *
156
     * @param string $buttonclasses the extra classes
157
     */
158
    public function set_button_classes(string $buttonclasses) {
159
        $this->buttonclasses = $buttonclasses;
160
    }
161
 
162
    /**
163
     * Add extra classes to the component.
164
     *
165
     * @param string $classes the extra classes
166
     */
167
    public function set_classes(string $classes) {
168
        $this->classes = $classes;
169
    }
170
 
171
    /**
172
     * Add extra extras to the sticky footer element.
173
     *
174
     * @param string $attribute the extra attribute
175
     * @param string $value the value
176
     */
177
    public function add_extra(string $attribute, string $value) {
178
        $this->extras[$attribute] = $value;
179
    }
180
 
181
    /**
182
     * Set the button element id.
183
     *
184
     * @param string $value the value
185
     */
186
    public function add_button_id(string $value) {
187
        $this->extras['buttonid'] = $value;
188
    }
189
 
190
    /**
191
     * Set the dropdown position.
192
     * @param string $position the position
193
     */
194
    public function set_position(string $position) {
195
        $this->dropdownposition = $position;
196
    }
197
 
198
    /**
199
     * Set the dropdown disabled attribute.
200
     * @param bool $disabled the disabled value
201
     */
202
    public function set_disabled(bool $disabled) {
203
        $this->disabled = $disabled;
204
    }
205
 
206
    /**
207
     * Export this data so it can be used as the context for a mustache template (core/inplace_editable).
208
     *
209
     * @param \renderer_base $output typically, the renderer that's calling this function
210
     * @return array data context for a mustache template
211
     */
212
    public function export_for_template(\renderer_base $output): array {
213
        $extras = [];
214
        // Id is required to add JS controls to the dropdown.
215
        $dropdownid = $this->extras['id'] ?? \html_writer::random_id('dropdownDialog_');
216
        if (isset($this->extras['id'])) {
217
            unset($this->extras['id']);
218
        }
219
        foreach ($this->extras as $attribute => $value) {
220
            $extras[] = [
221
                'attribute' => $attribute,
222
                'value' => $value,
223
            ];
224
        }
225
        $data = [
226
            // Id is required for the correct HTML labelling.
227
            'dropdownid' => $dropdownid,
228
            'buttonid' => $this->extras['buttonid'] ?? \html_writer::random_id('dropwdownbutton_'),
229
            'buttoncontent' => (string) $this->buttoncontent,
230
            'dialogcontent' => (string) $this->dialogcontent,
231
            'classes' => $this->classes,
232
            'buttonclasses' => $this->buttonclasses,
233
            'dialogclasses' => $this->dropdownwidth,
234
            'extras' => $extras,
235
        ];
236
        if ($this->disabled) {
237
            $data['disabledbutton'] = true;
238
        }
239
        // Bootstrap 4 dropdown position still uses left and right literals.
240
        $data["position"] = $this->dropdownposition;
241
        if (right_to_left()) {
242
            $rltposition = [
243
                self::POSITION['start'] => self::POSITION['end'],
244
                self::POSITION['end'] => self::POSITION['end'],
245
            ];
246
            $data["position"] = $rltposition[$this->dropdownposition];
247
        }
248
        return $data;
249
    }
250
 
251
    /**
252
     * Get the name of the template to use for this templatable.
253
     *
254
     * @param \renderer_base $renderer The renderer requesting the template name
255
     * @return string the template name
256
     */
257
    public function get_template_name(\renderer_base $renderer): string {
258
        return 'core/local/dropdown/dialog';
259
    }
260
}