PluginProbe
WPZOOM Forms – Drag & Drop Contact Form Builder for WordPress / trunk
WPZOOM Forms – Drag & Drop Contact Form Builder for WordPress vtrunk
2.0.9 2.0.8 2.0.7 2.0.6 2.0.5 2.0.4 2.0.3 2.0.2 2.0.1 2.0.0 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.2.0 1.2.1 1.2.10 All 43 releases
wpzoom-forms / src / fields / select / edit.js

edit.js in WPZOOM Forms – Drag & Drop Contact Form Builder for WordPress trunk, at src/fields/select/edit.js

302 lines 8.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import isEmpty from 'lodash/isEmpty';
2 import { useState, useEffect } from '@wordpress/element';
3 import { useBlockProps, InspectorControls, RichText } from '@wordpress/block-editor';
4 import { Fragment } from '@wordpress/element';
5 import { __, sprintf } from '@wordpress/i18n';
6 import {
7 PanelBody,
8 TextControl,
9 TextareaControl,
10 ToggleControl,
11 SelectControl,
12 Card,
13 CardBody,
14 CardHeader,
15 Button,
16 Flex,
17 FlexBlock,
18 FlexItem,
19 Modal,
20 } from '@wordpress/components';
21
22 import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
23 import { arrayMoveImmutable } from 'array-move';
24
25 // Import the lists from the lists.js file
26 import { countries, states } from './lists';
27
28 const DragHandle = SortableHandle( () => <Button
29 icon="move"
30 label={ __( 'Re-arrange Item', 'wpzoom-forms' ) }
31 className="wpzoom-forms-move-button"
32 /> );
33
34 const SortableItem = SortableElement( ( { value, optsId, options, changeCallback, removeCallback } ) => <Fragment>
35 <Flex>
36 <FlexBlock>
37 <TextControl
38 value={ value }
39 onChange={ val => changeCallback( val, optsId ) }
40 __next40pxDefaultSize
41 __nextHasNoMarginBottom
42 />
43 </FlexBlock>
44
45 { options.length > 1 && <FlexItem>
46 <DragHandle />
47
48 <Button
49 icon="no-alt"
50 label={ __( 'Delete Item', 'wpzoom-forms' ) }
51 onClick={ () => removeCallback( optsId ) }
52 __next40pxDefaultSize
53 __nextHasNoMarginBottom
54 />
55 </FlexItem> }
56 </Flex>
57 </Fragment> );
58
59 const SortableList = SortableContainer( ( { items, changeCallback, removeCallback } ) => <div>
60 { items.map( ( value, index ) => <SortableItem
61 index={ index }
62 optsId={ index }
63 value={ value }
64 options={ items }
65 changeCallback={ changeCallback }
66 removeCallback={ removeCallback }
67 /> ) }
68 </div> );
69
70 const Edit = props => {
71 const blockProps = useBlockProps();
72 const { attributes, setAttributes, clientId } = props;
73 const { id, name, options, defaultValue, label, showLabel, multiple, required } = attributes;
74
75 const [isOpen, setOpen] = useState(false);
76 const [bulkOptions, setBulkOptions] = useState('');
77
78 const openModal = () => setOpen(true);
79 const closeModal = () => setOpen(false);
80
81 const optionAdd = () => {
82 const opts = [...options];
83 opts.push(sprintf(__('Item #%s', 'wpzoom-forms'), options.length + 1));
84 setAttributes({ options: opts });
85 };
86
87 const optionRemove = (index) => {
88 const opts = [...options];
89 opts.splice(index, 1);
90 setAttributes({ options: opts });
91 };
92
93 const optionChange = (name, index) => {
94 const opts = [...options];
95 opts[index] = name;
96 setAttributes({ options: opts });
97 };
98
99 const optionsSort = (oldIndex, newIndex) => {
100 const sorted = arrayMoveImmutable(options, oldIndex, newIndex);
101 setAttributes({ options: sorted });
102 };
103
104 useEffect(() => {
105 if (!id) {
106 setAttributes({ id: 'input_' + clientId.substr(0, 8) });
107 }
108 }, []);
109
110 useEffect(() => {
111 if (options) {
112 let _items = '';
113 options.forEach((item) => {
114 _items += item + '\n';
115 });
116 setBulkOptions(_items);
117 }
118 }, [options]);
119
120 const onBulkAddItems = () => {
121 const _options = bulkOptions.split('\n').filter(Boolean);
122 setAttributes({ options: _options });
123 setOpen(false);
124 };
125
126 const [ uniqueId ] = useState( id );
127
128 const handleNameChange = newValue => {
129 const newId = newValue.replace(/\s/g, '_').toLowerCase();
130 setAttributes( { name: newValue, id: 'input_' + clientId.substr( 0, 8 ) } );
131 };
132
133 return (
134 <>
135 <InspectorControls>
136 <PanelBody title={__('Options', 'wpzoom-forms')}>
137 <TextControl
138 label={__('Name', 'wpzoom-forms')}
139 value={name}
140 placeholder={__('e.g. My Dropdown Select Field', 'wpzoom-forms')}
141 onChange={ handleNameChange }
142 __next40pxDefaultSize
143 __nextHasNoMarginBottom
144 />
145
146 <Card size="small">
147 <CardHeader>
148 {__('Items', 'wpzoom-forms')}
149 <Button
150 icon="insert"
151 label={__('Add Item', 'wpzoom-forms')}
152 onClick={optionAdd}
153 __next40pxDefaultSize
154 __nextHasNoMarginBottom
155 />
156 </CardHeader>
157 <CardBody>
158 <SortableList
159 items={options}
160 changeCallback={optionChange}
161 removeCallback={optionRemove}
162 lockAxis="y"
163 useDragHandle={true}
164 onSortEnd={({ oldIndex, newIndex }) => optionsSort(oldIndex, newIndex)}
165 />
166 </CardBody>
167 </Card>
168
169 <Button
170 icon="admin-settings"
171 label={__('Add Bulk Options', 'wpzoom-forms')}
172 onClick={openModal}
173 __next40pxDefaultSize
174 __nextHasNoMarginBottom
175 >
176 {__('Add Bulk Options', 'wpzoom-forms')}
177 </Button>
178
179 { isOpen && (
180 <Modal
181 title={__('Add Bulk Options', 'wpzoom-forms')}
182 onRequestClose={closeModal}
183 shouldCloseOnClickOutside={true}
184 >
185 <div className="wpzoom-forms-extra-options" style={{ maxWidth: 720 + 'px', maxHeight: 525 + 'px' } } >
186 <div className="form-group">
187 <div className="wrap-content">
188 <TextareaControl
189 label={__('Bulk Options', 'wpzoom-forms')}
190 help={__('Each line break is a new option.', 'wpzoom-forms')}
191 className="bulk-add-enter-options"
192 rows="5"
193 value={ bulkOptions }
194 onChange={value => setBulkOptions(value)}
195 __next40pxDefaultSize
196 __nextHasNoMarginBottom
197 />
198 </div>
199 </div>
200 <div className="form-group">
201 <div class="predefined-lists">
202 <p>{ __('Predefined Lists', 'wpzoom-forms') }
203 <br />
204 <Button isLink onClick={ () => setBulkOptions( countries.join('\n') ) }>{ __( 'Countries', 'wpzoom-forms' ) }</Button>
205 <Button isLink onClick={ () => setBulkOptions( states.join('\n') ) }>{ __( 'US States', 'wpzoom-forms' ) }</Button>
206 </p>
207 </div>
208 <div class="action-buttons">
209 <Button variant="secondary" onClick={() => setOpen(false)} __next40pxDefaultSize __nextHasNoMarginBottom>
210 { __('Cancel', 'wpzoom-forms')}
211 </Button>
212 { ! isEmpty( bulkOptions ) && (
213 <Button variant="primary" onClick={ () => { onBulkAddItems(); } } __next40pxDefaultSize __nextHasNoMarginBottom>
214 {__('Bulk Add', 'wpzoom-forms')}
215 </Button>
216 )}
217 </div>
218 </div>
219 </div>
220 </Modal>
221 )}
222
223 <SelectControl
224 label={__('Default Value', 'wpzoom-forms')}
225 value={defaultValue}
226 options={options.map((option, index) => ({ label: option, value: option }))}
227 onChange={value => setAttributes({ defaultValue: value })}
228 __next40pxDefaultSize
229 __nextHasNoMarginBottom
230 />
231
232 <ToggleControl
233 label={__('Show Label', 'wpzoom-forms')}
234 checked={!!showLabel}
235 onChange={value => setAttributes({ showLabel: !!value })}
236 __next40pxDefaultSize
237 __nextHasNoMarginBottom
238 />
239
240 {showLabel && (
241 <TextControl
242 label={__('Label', 'wpzoom-forms')}
243 value={label}
244 onChange={value => setAttributes({ label: value })}
245 __next40pxDefaultSize
246 __nextHasNoMarginBottom
247 />
248 )}
249
250 <ToggleControl
251 label={__('Allow Multiple Selections', 'wpzoom-forms')}
252 checked={!!multiple}
253 onChange={value => setAttributes({ multiple: !!value })}
254 __next40pxDefaultSize
255 __nextHasNoMarginBottom
256 />
257
258 <ToggleControl
259 label={__('Required', 'wpzoom-forms')}
260 checked={!!required}
261 onChange={value => setAttributes({ required: !!value })}
262 __next40pxDefaultSize
263 __nextHasNoMarginBottom
264 />
265 </PanelBody>
266 </InspectorControls>
267
268 <Fragment>
269 {showLabel && (
270 <>
271 <RichText
272 tagName="label"
273 placeholder={__('Label', 'wpzoom-forms')}
274 value={label}
275 htmlFor={ uniqueId }
276 onChange={value => setAttributes({ label: value })}
277 />
278 {required && <sup className="wp-block-wpzoom-forms-required">{__('*', 'wpzoom-forms')}</sup>}
279 </>
280 )}
281
282 <select
283 name={ uniqueId }
284 id={ uniqueId }
285 required={!!required}
286 multiple={!!multiple}
287 defaultValue={defaultValue}
288 {...blockProps}
289 >
290 {options.map((option, index) => (
291 <option key={index} value={option}>
292 {option}
293 </option>
294 ))}
295 </select>
296 </Fragment>
297 </>
298 );
299 };
300
301 export default Edit;
302