PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.2.11
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.2.11
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / includes / Extensions / Elementor / FormWidget.php

FormWidget.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.2.11, at includes/Extensions/Elementor/FormWidget.php

685 lines 29.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * NotificationX Elementor Form Widget
4 *
5 * A simple Name / Email / Message form whose submissions are saved into
6 * the NotificationX `nx_entries` table via the existing
7 * `notificationx/v1/popup-submit` REST endpoint. The widget must be bound
8 * to an existing NotificationX campaign of source `popup_notification`
9 * or `exit_intent_custom`.
10 *
11 * @package NotificationX\Extensions\Elementor
12 */
13
14 namespace NotificationX\Extensions\Elementor;
15
16 use Elementor\Controls_Manager;
17 use Elementor\Group_Control_Border;
18 use Elementor\Group_Control_Box_Shadow;
19 use Elementor\Group_Control_Typography;
20 use Elementor\Widget_Base;
21 use NotificationX\Core\PostType;
22
23 if ( ! defined( 'ABSPATH' ) ) {
24 exit;
25 }
26
27 /**
28 * Column-width options shared across all field controls.
29 * Keys are the CSS percentage values rendered into `flex-basis`.
30 */
31 if ( ! function_exists( __NAMESPACE__ . '\\nx_form_widths' ) ) {
32 function nx_form_widths() {
33 return [
34 '100' => '100%',
35 '75' => '75%',
36 '66' => '66%',
37 '50' => '50%',
38 '33' => '33%',
39 '25' => '25%',
40 ];
41 }
42 }
43
44 class FormWidget extends Widget_Base {
45
46 public function get_name() {
47 return 'nx-form';
48 }
49
50 public function get_title() {
51 return esc_html__( 'NotificationX Form', 'notificationx' );
52 }
53
54 public function get_icon() {
55 return 'eicon-form-horizontal';
56 }
57
58 public function get_categories() {
59 return [ 'notificationx' ];
60 }
61
62 public function get_keywords() {
63 return [ 'form', 'contact', 'lead', 'notificationx', 'nx', 'entries', 'subscribe' ];
64 }
65
66 public function get_script_depends() {
67 return [ 'nx-elementor-form' ];
68 }
69
70 public function get_style_depends() {
71 return [ 'nx-elementor-form' ];
72 }
73
74 /**
75 * Existing NX Popup / Exit-Intent campaigns to bind submissions to.
76 *
77 * @return array<int|string,string>
78 */
79 private function get_nx_campaigns() {
80 $options = [ '' => esc_html__( '— Select a Campaign —', 'notificationx' ) ];
81
82 if ( ! class_exists( PostType::class ) ) {
83 return $options;
84 }
85
86 $posts = PostType::get_instance()->get_posts(
87 [], // can't AND two source values via a simple where; filter below.
88 'nx_id, title, source'
89 );
90
91 if ( is_array( $posts ) ) {
92 foreach ( $posts as $post ) {
93 if ( empty( $post['source'] ) ) {
94 continue;
95 }
96 if ( ! in_array( $post['source'], [ 'popup_notification', 'exit_intent_custom' ], true ) ) {
97 continue;
98 }
99 $label = $post['title'] ?: sprintf( __( '#%d', 'notificationx' ), $post['nx_id'] );
100 $options[ (string) $post['nx_id'] ] = sprintf(
101 '%s (%s)',
102 $label,
103 $post['source'] === 'exit_intent_custom' ? __( 'Exit Intent', 'notificationx' ) : __( 'Popup', 'notificationx' )
104 );
105 }
106 }
107
108 return $options;
109 }
110
111 /**
112 * Whether NotificationX Pro is active. Pro unlocks the Email field and the
113 * per-field Column Width controls; the free version forces a single-column
114 * (100%) layout and does not collect email.
115 *
116 * @return bool
117 */
118 private function is_pro() {
119 return class_exists( '\\NotificationXPro\\NotificationX' );
120 }
121
122 protected function register_controls() {
123
124 $is_pro = $this->is_pro();
125
126 // ── Form Settings ─────────────────────────────────────────────────
127 $this->start_controls_section(
128 'section_form_settings',
129 [ 'label' => esc_html__( 'Form Settings', 'notificationx' ) ]
130 );
131
132 $this->add_control(
133 'nx_campaign_id',
134 [
135 'label' => esc_html__( 'Select Notification ID', 'notificationx' ),
136 'type' => Controls_Manager::SELECT,
137 'options' => $this->get_nx_campaigns(),
138 'default' => '',
139 'description' => esc_html__( 'Submissions are saved as entries against the selected Popup or Exit-Intent campaign.', 'notificationx' ),
140 ]
141 );
142
143 $this->add_control(
144 'nx_form_title',
145 [
146 'label' => esc_html__( 'Form Title', 'notificationx' ),
147 'type' => Controls_Manager::TEXT,
148 'default' => esc_html__( 'Get in touch', 'notificationx' ),
149 'dynamic' => [ 'active' => true ],
150 ]
151 );
152
153 // Name field
154 $this->add_control(
155 'nx_name_heading',
156 [ 'label' => esc_html__( 'Name Field', 'notificationx' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before' ]
157 );
158
159 if ( $is_pro ) {
160 $this->add_control(
161 'nx_show_name',
162 [ 'label' => esc_html__( 'Show Name', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes' ]
163 );
164 $this->add_responsive_control(
165 'nx_name_width',
166 [
167 'label' => esc_html__( 'Column Width', 'notificationx' ),
168 'type' => Controls_Manager::SELECT,
169 'options' => nx_form_widths(),
170 'default' => '100',
171 'condition' => [ 'nx_show_name' => 'yes' ],
172 ]
173 );
174 $this->add_control(
175 'nx_name_label',
176 [ 'label' => esc_html__( 'Label', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Name', 'notificationx' ), 'condition' => [ 'nx_show_name' => 'yes' ] ]
177 );
178 $this->add_control(
179 'nx_name_placeholder',
180 [ 'label' => esc_html__( 'Placeholder', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Your name', 'notificationx' ), 'condition' => [ 'nx_show_name' => 'yes' ] ]
181 );
182 $this->add_control(
183 'nx_name_required',
184 [ 'label' => esc_html__( 'Required', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'condition' => [ 'nx_show_name' => 'yes' ] ]
185 );
186 } else {
187 // Free version: the Name field is a Pro-only feature. Show a notice
188 // instead of the controls so the field can't be enabled.
189 $this->add_control(
190 'nx_name_pro_notice',
191 [
192 'type' => Controls_Manager::RAW_HTML,
193 'raw' => esc_html__( 'The Name field is available in NotificationX Pro.', 'notificationx' ),
194 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
195 ]
196 );
197 }
198
199 // Email field
200 $this->add_control(
201 'nx_email_heading',
202 [ 'label' => esc_html__( 'Email Field', 'notificationx' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before' ]
203 );
204
205 if ( $is_pro ) {
206 $this->add_control(
207 'nx_show_email',
208 [ 'label' => esc_html__( 'Show Email', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes' ]
209 );
210 $this->add_responsive_control(
211 'nx_email_width',
212 [
213 'label' => esc_html__( 'Column Width', 'notificationx' ),
214 'type' => Controls_Manager::SELECT,
215 'options' => nx_form_widths(),
216 'default' => '100',
217 'condition' => [ 'nx_show_email' => 'yes' ],
218 ]
219 );
220 $this->add_control(
221 'nx_email_label',
222 [ 'label' => esc_html__( 'Label', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Email', 'notificationx' ), 'condition' => [ 'nx_show_email' => 'yes' ] ]
223 );
224 $this->add_control(
225 'nx_email_placeholder',
226 [ 'label' => esc_html__( 'Placeholder', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'you@example.com', 'notificationx' ), 'condition' => [ 'nx_show_email' => 'yes' ] ]
227 );
228 $this->add_control(
229 'nx_email_required',
230 [ 'label' => esc_html__( 'Required', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes', 'condition' => [ 'nx_show_email' => 'yes' ] ]
231 );
232 } else {
233 // Free version: the Email field is a Pro-only feature. Show a notice
234 // instead of the controls so the field can't be enabled.
235 $this->add_control(
236 'nx_email_pro_notice',
237 [
238 'type' => Controls_Manager::RAW_HTML,
239 'raw' => esc_html__( 'The Email field is available in NotificationX Pro.', 'notificationx' ),
240 'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
241 ]
242 );
243 }
244
245 // Message field
246 $this->add_control(
247 'nx_message_heading',
248 [ 'label' => esc_html__( 'Message Field', 'notificationx' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before' ]
249 );
250 $this->add_control(
251 'nx_show_message',
252 [ 'label' => esc_html__( 'Show Message', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => 'yes' ]
253 );
254 $this->add_responsive_control(
255 'nx_message_width',
256 [
257 'label' => esc_html__( 'Column Width', 'notificationx' ),
258 'type' => Controls_Manager::SELECT,
259 'options' => nx_form_widths(),
260 'default' => '100',
261 'condition' => [ 'nx_show_message' => 'yes' ],
262 ]
263 );
264 $this->add_control(
265 'nx_message_label',
266 [ 'label' => esc_html__( 'Label', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Message', 'notificationx' ), 'condition' => [ 'nx_show_message' => 'yes' ] ]
267 );
268 $this->add_control(
269 'nx_message_placeholder',
270 [ 'label' => esc_html__( 'Placeholder', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Write your message…', 'notificationx' ), 'condition' => [ 'nx_show_message' => 'yes' ] ]
271 );
272 $this->add_control(
273 'nx_message_rows',
274 [ 'label' => esc_html__( 'Rows', 'notificationx' ), 'type' => Controls_Manager::NUMBER, 'default' => 3, 'min' => 1, 'max' => 20, 'condition' => [ 'nx_show_message' => 'yes' ] ]
275 );
276 $this->add_control(
277 'nx_message_required',
278 [ 'label' => esc_html__( 'Required', 'notificationx' ), 'type' => Controls_Manager::SWITCHER, 'return_value' => 'yes', 'default' => '', 'condition' => [ 'nx_show_message' => 'yes' ] ]
279 );
280
281 // Submit
282 $this->add_control(
283 'nx_submit_heading',
284 [ 'label' => esc_html__( 'Submit', 'notificationx' ), 'type' => Controls_Manager::HEADING, 'separator' => 'before' ]
285 );
286 $this->add_responsive_control(
287 'nx_submit_width',
288 [
289 'label' => esc_html__( 'Column Width', 'notificationx' ),
290 'type' => Controls_Manager::SELECT,
291 'options' => nx_form_widths(),
292 'default' => '100',
293 ]
294 );
295 $this->add_control(
296 'nx_submit_text',
297 [ 'label' => esc_html__( 'Button Text', 'notificationx' ), 'type' => Controls_Manager::TEXT, 'default' => esc_html__( 'Submit', 'notificationx' ) ]
298 );
299 $this->add_control(
300 'nx_success_message',
301 [ 'label' => esc_html__( 'Success Message', 'notificationx' ), 'type' => Controls_Manager::TEXTAREA, 'default' => esc_html__( 'Thanks! Your submission has been received.', 'notificationx' ) ]
302 );
303 $this->add_control(
304 'nx_error_message',
305 [ 'label' => esc_html__( 'Error Message', 'notificationx' ), 'type' => Controls_Manager::TEXTAREA, 'default' => esc_html__( 'Something went wrong. Please try again.', 'notificationx' ) ]
306 );
307
308 $this->end_controls_section();
309
310 // ── Style: Form ──────────────────────────────────────────────────
311 $this->start_controls_section(
312 'section_style_form',
313 [ 'label' => esc_html__( 'Form', 'notificationx' ), 'tab' => Controls_Manager::TAB_STYLE ]
314 );
315
316 $this->add_responsive_control(
317 'nx_form_align',
318 [
319 'label' => esc_html__( 'Alignment', 'notificationx' ),
320 'type' => Controls_Manager::CHOOSE,
321 'options' => [
322 'left' => [ 'title' => esc_html__( 'Left', 'notificationx' ), 'icon' => 'eicon-text-align-left' ],
323 'center' => [ 'title' => esc_html__( 'Center', 'notificationx' ), 'icon' => 'eicon-text-align-center' ],
324 'right' => [ 'title' => esc_html__( 'Right', 'notificationx' ), 'icon' => 'eicon-text-align-right' ],
325 ],
326 'default' => 'left',
327 'selectors' => [ '{{WRAPPER}} .nx-form-title' => 'text-align: {{VALUE}};' ],
328 ]
329 );
330
331 $this->add_group_control(
332 Group_Control_Typography::get_type(),
333 [ 'name' => 'nx_title_typography', 'selector' => '{{WRAPPER}} .nx-form-title' ]
334 );
335
336 $this->add_control(
337 'nx_title_color',
338 [
339 'label' => esc_html__( 'Title Color', 'notificationx' ),
340 'type' => Controls_Manager::COLOR,
341 'selectors' => [ '{{WRAPPER}} .nx-form-title' => 'color: {{VALUE}};' ],
342 ]
343 );
344
345 $this->end_controls_section();
346
347 // ── Style: Fields ────────────────────────────────────────────────
348 $this->start_controls_section(
349 'section_style_fields',
350 [ 'label' => esc_html__( 'Fields', 'notificationx' ), 'tab' => Controls_Manager::TAB_STYLE ]
351 );
352
353 $this->add_control(
354 'nx_label_color',
355 [
356 'label' => esc_html__( 'Label Color', 'notificationx' ),
357 'type' => Controls_Manager::COLOR,
358 'selectors' => [ '{{WRAPPER}} .nx-form-label' => 'color: {{VALUE}};' ],
359 ]
360 );
361
362 $this->add_group_control(
363 Group_Control_Typography::get_type(),
364 [ 'name' => 'nx_label_typography', 'selector' => '{{WRAPPER}} .nx-form-label' ]
365 );
366
367 $this->add_control(
368 'nx_input_text_color',
369 [
370 'label' => esc_html__( 'Input Text Color', 'notificationx' ),
371 'type' => Controls_Manager::COLOR,
372 'selectors' => [ '{{WRAPPER}} .nx-form-input' => 'color: {{VALUE}};' ],
373 ]
374 );
375
376 $this->add_control(
377 'nx_input_bg_color',
378 [
379 'label' => esc_html__( 'Input Background', 'notificationx' ),
380 'type' => Controls_Manager::COLOR,
381 'selectors' => [ '{{WRAPPER}} .nx-form-input' => 'background-color: {{VALUE}};' ],
382 ]
383 );
384
385 $this->add_control(
386 'nx_placeholder_color',
387 [
388 'label' => esc_html__( 'Placeholder Color', 'notificationx' ),
389 'type' => Controls_Manager::COLOR,
390 'selectors' => [
391 '{{WRAPPER}} .nx-form-input::-webkit-input-placeholder' => 'color: {{VALUE}};',
392 '{{WRAPPER}} .nx-form-input::-moz-placeholder' => 'color: {{VALUE}};',
393 '{{WRAPPER}} .nx-form-input:-ms-input-placeholder' => 'color: {{VALUE}};',
394 '{{WRAPPER}} .nx-form-input::placeholder' => 'color: {{VALUE}};',
395 ],
396 ]
397 );
398
399 $this->add_group_control(
400 Group_Control_Typography::get_type(),
401 [
402 'name' => 'nx_placeholder_typography',
403 'label' => esc_html__( 'Placeholder Typography', 'notificationx' ),
404 'selector' => '{{WRAPPER}} .nx-form-input::placeholder',
405 ]
406 );
407
408 $this->add_group_control(
409 Group_Control_Border::get_type(),
410 [
411 'name' => 'nx_input_border',
412 'selector' => '{{WRAPPER}} .nx-form-input',
413 ]
414 );
415
416 $this->add_control(
417 'nx_input_radius',
418 [
419 'label' => esc_html__( 'Border Radius', 'notificationx' ),
420 'type' => Controls_Manager::DIMENSIONS,
421 'size_units' => [ 'px', '%' ],
422 'selectors' => [ '{{WRAPPER}} .nx-form-input' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
423 ]
424 );
425
426 $this->add_control(
427 'nx_input_padding',
428 [
429 'label' => esc_html__( 'Padding', 'notificationx' ),
430 'type' => Controls_Manager::DIMENSIONS,
431 'size_units' => [ 'px', 'em' ],
432 'selectors' => [ '{{WRAPPER}} .nx-form-input' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
433 ]
434 );
435
436 $this->add_control(
437 'nx_field_spacing',
438 [
439 'label' => esc_html__( 'Row Gap (Vertical)', 'notificationx' ),
440 'type' => Controls_Manager::SLIDER,
441 'size_units' => [ 'px' ],
442 'range' => [ 'px' => [ 'min' => 0, 'max' => 60 ] ],
443 'default' => [ 'unit' => 'px', 'size' => 14 ],
444 'selectors' => [ '{{WRAPPER}} .nx-form-rows' => 'row-gap: {{SIZE}}{{UNIT}};' ],
445 ]
446 );
447
448 $this->add_control(
449 'nx_column_gap',
450 [
451 'label' => esc_html__( 'Column Gap (Horizontal)', 'notificationx' ),
452 'type' => Controls_Manager::SLIDER,
453 'size_units' => [ 'px' ],
454 'range' => [ 'px' => [ 'min' => 0, 'max' => 60 ] ],
455 'default' => [ 'unit' => 'px', 'size' => 14 ],
456 'selectors' => [ '{{WRAPPER}} .nx-form-rows' => 'column-gap: {{SIZE}}{{UNIT}}; --nx-gap: {{SIZE}}{{UNIT}};' ],
457 ]
458 );
459
460 $this->end_controls_section();
461
462 // ── Style: Button ────────────────────────────────────────────────
463 $this->start_controls_section(
464 'section_style_button',
465 [ 'label' => esc_html__( 'Button', 'notificationx' ), 'tab' => Controls_Manager::TAB_STYLE ]
466 );
467
468 $this->add_group_control(
469 Group_Control_Typography::get_type(),
470 [ 'name' => 'nx_button_typography', 'selector' => '{{WRAPPER}} .nx-form-submit' ]
471 );
472
473 $this->start_controls_tabs( 'nx_button_tabs' );
474
475 $this->start_controls_tab( 'nx_button_tab_normal', [ 'label' => esc_html__( 'Normal', 'notificationx' ) ] );
476 $this->add_control(
477 'nx_button_color',
478 [ 'label' => esc_html__( 'Text Color', 'notificationx' ), 'type' => Controls_Manager::COLOR, 'default' => '#ffffff', 'selectors' => [ '{{WRAPPER}} .nx-form-submit' => 'color: {{VALUE}};' ] ]
479 );
480 $this->add_control(
481 'nx_button_bg',
482 [ 'label' => esc_html__( 'Background', 'notificationx' ), 'type' => Controls_Manager::COLOR, 'default' => '#2271b1', 'selectors' => [ '{{WRAPPER}} .nx-form-submit' => 'background-color: {{VALUE}};' ] ]
483 );
484 $this->end_controls_tab();
485
486 $this->start_controls_tab( 'nx_button_tab_hover', [ 'label' => esc_html__( 'Hover', 'notificationx' ) ] );
487 $this->add_control(
488 'nx_button_color_h',
489 [ 'label' => esc_html__( 'Text Color', 'notificationx' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .nx-form-submit:hover' => 'color: {{VALUE}};' ] ]
490 );
491 $this->add_control(
492 'nx_button_bg_h',
493 [ 'label' => esc_html__( 'Background', 'notificationx' ), 'type' => Controls_Manager::COLOR, 'selectors' => [ '{{WRAPPER}} .nx-form-submit:hover' => 'background-color: {{VALUE}};' ] ]
494 );
495 $this->end_controls_tab();
496
497 $this->end_controls_tabs();
498
499 $this->add_group_control(
500 Group_Control_Border::get_type(),
501 [ 'name' => 'nx_button_border', 'selector' => '{{WRAPPER}} .nx-form-submit' ]
502 );
503
504 $this->add_control(
505 'nx_button_radius',
506 [
507 'label' => esc_html__( 'Border Radius', 'notificationx' ),
508 'type' => Controls_Manager::DIMENSIONS,
509 'size_units' => [ 'px', '%' ],
510 'selectors' => [ '{{WRAPPER}} .nx-form-submit' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
511 ]
512 );
513
514 $this->add_control(
515 'nx_button_padding',
516 [
517 'label' => esc_html__( 'Padding', 'notificationx' ),
518 'type' => Controls_Manager::DIMENSIONS,
519 'size_units' => [ 'px', 'em' ],
520 'default' => [ 'top' => '12', 'right' => '20', 'bottom' => '12', 'left' => '20', 'unit' => 'px', 'isLinked' => false ],
521 'selectors' => [ '{{WRAPPER}} .nx-form-submit' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};' ],
522 ]
523 );
524
525 $this->add_responsive_control(
526 'nx_button_align',
527 [
528 'label' => esc_html__( 'Alignment', 'notificationx' ),
529 'type' => Controls_Manager::CHOOSE,
530 'options' => [
531 'flex-start' => [ 'title' => esc_html__( 'Left', 'notificationx' ), 'icon' => 'eicon-text-align-left' ],
532 'center' => [ 'title' => esc_html__( 'Center', 'notificationx' ), 'icon' => 'eicon-text-align-center' ],
533 'flex-end' => [ 'title' => esc_html__( 'Right', 'notificationx' ), 'icon' => 'eicon-text-align-right' ],
534 'stretch' => [ 'title' => esc_html__( 'Justified', 'notificationx' ), 'icon' => 'eicon-text-align-justify' ],
535 ],
536 'default' => 'stretch',
537 'selectors' => [ '{{WRAPPER}} .nx-form-actions' => 'justify-content: {{VALUE}};' ],
538 ]
539 );
540
541 $this->end_controls_section();
542 }
543
544 /**
545 * Build the class string for a row given per-breakpoint width settings.
546 *
547 * @param array $s Settings array.
548 * @param string $base_key The control base name (e.g. `nx_name_width`).
549 * @return string
550 */
551 private function row_width_classes( $s, $base_key ) {
552 $classes = [ 'nx-form-row' ];
553 $map = [
554 '' => $s[ $base_key ] ?? '100',
555 'tablet-' => $s[ $base_key . '_tablet' ] ?? '',
556 'mobile-' => $s[ $base_key . '_mobile' ] ?? '',
557 ];
558 foreach ( $map as $prefix => $val ) {
559 if ( $val !== '' && $val !== null ) {
560 $classes[] = 'nx-w-' . $prefix . $val;
561 }
562 }
563 return implode( ' ', array_map( 'sanitize_html_class', $classes ) );
564 }
565
566 protected function render() {
567 $s = $this->get_settings_for_display();
568
569 $campaign_id = absint( $s['nx_campaign_id'] ?? 0 );
570 $rest_url = esc_url_raw( rest_url( 'notificationx/v1/popup-submit' ) );
571
572 $form_id = 'nx-form-' . esc_attr( $this->get_id() );
573 $show_name = ! empty( $s['nx_show_name'] );
574 $show_email = ! empty( $s['nx_show_email'] );
575 $show_message = ! empty( $s['nx_show_message'] );
576
577 // Free version: Name and Email are Pro-only fields, so only the Message
578 // field is collected. Enforce this at render time too, so settings saved
579 // while Pro was active don't leak through after Pro is deactivated.
580 if ( ! $this->is_pro() ) {
581 $show_name = false;
582 $show_email = false;
583 }
584
585 // Don't render the form at all if no campaign is selected — show a
586 // friendly editor-only notice.
587 if ( ! $campaign_id ) {
588 if ( \Elementor\Plugin::$instance->editor->is_edit_mode() ) {
589 printf(
590 '<div class="nx-form-notice">%s</div>',
591 esc_html__( 'Select a NotificationX campaign in the Form Settings to start collecting entries.', 'notificationx' )
592 );
593 }
594 return;
595 }
596 ?>
597 <div class="nx-form-wrapper">
598
599 <?php if ( ! empty( $s['nx_form_title'] ) ) : ?>
600 <h3 class="nx-form-title"><?php echo esc_html( $s['nx_form_title'] ); ?></h3>
601 <?php endif; ?>
602
603 <form
604 id="<?php echo esc_attr( $form_id ); ?>"
605 class="nx-form"
606 data-nx-id="<?php echo esc_attr( $campaign_id ); ?>"
607 data-rest-url="<?php echo esc_attr( $rest_url ); ?>"
608 data-success="<?php echo esc_attr( $s['nx_success_message'] ?? '' ); ?>"
609 data-error="<?php echo esc_attr( $s['nx_error_message'] ?? '' ); ?>"
610 novalidate
611 >
612 <div class="nx-form-rows">
613
614 <?php if ( $show_name ) : ?>
615 <div class="<?php echo esc_attr( $this->row_width_classes( $s, 'nx_name_width' ) ); ?>">
616 <?php if ( ! empty( $s['nx_name_label'] ) ) : ?>
617 <label class="nx-form-label" for="<?php echo esc_attr( $form_id ); ?>-name">
618 <?php echo esc_html( $s['nx_name_label'] ); ?>
619 <?php if ( ! empty( $s['nx_name_required'] ) ) echo ' <span class="nx-form-required">*</span>'; ?>
620 </label>
621 <?php endif; ?>
622 <input
623 type="text"
624 id="<?php echo esc_attr( $form_id ); ?>-name"
625 name="name"
626 class="nx-form-input"
627 placeholder="<?php echo esc_attr( $s['nx_name_placeholder'] ?? '' ); ?>"
628 <?php if ( ! empty( $s['nx_name_required'] ) ) echo 'required'; ?>
629 >
630 </div>
631 <?php endif; ?>
632
633 <?php if ( $show_email ) : ?>
634 <div class="<?php echo esc_attr( $this->row_width_classes( $s, 'nx_email_width' ) ); ?>">
635 <?php if ( ! empty( $s['nx_email_label'] ) ) : ?>
636 <label class="nx-form-label" for="<?php echo esc_attr( $form_id ); ?>-email">
637 <?php echo esc_html( $s['nx_email_label'] ); ?>
638 <?php if ( ! empty( $s['nx_email_required'] ) ) echo ' <span class="nx-form-required">*</span>'; ?>
639 </label>
640 <?php endif; ?>
641 <input
642 type="email"
643 id="<?php echo esc_attr( $form_id ); ?>-email"
644 name="email"
645 class="nx-form-input"
646 placeholder="<?php echo esc_attr( $s['nx_email_placeholder'] ?? '' ); ?>"
647 <?php if ( ! empty( $s['nx_email_required'] ) ) echo 'required'; ?>
648 >
649 </div>
650 <?php endif; ?>
651
652 <?php if ( $show_message ) : ?>
653 <div class="<?php echo esc_attr( $this->row_width_classes( $s, 'nx_message_width' ) ); ?>">
654 <?php if ( ! empty( $s['nx_message_label'] ) ) : ?>
655 <label class="nx-form-label" for="<?php echo esc_attr( $form_id ); ?>-message">
656 <?php echo esc_html( $s['nx_message_label'] ); ?>
657 <?php if ( ! empty( $s['nx_message_required'] ) ) echo ' <span class="nx-form-required">*</span>'; ?>
658 </label>
659 <?php endif; ?>
660 <textarea
661 id="<?php echo esc_attr( $form_id ); ?>-message"
662 name="message"
663 class="nx-form-input nx-form-textarea"
664 rows="<?php echo absint( $s['nx_message_rows'] ?? 4 ); ?>"
665 placeholder="<?php echo esc_attr( $s['nx_message_placeholder'] ?? '' ); ?>"
666 <?php if ( ! empty( $s['nx_message_required'] ) ) echo 'required'; ?>
667 ></textarea>
668 </div>
669 <?php endif; ?>
670
671 <div class="<?php echo esc_attr( $this->row_width_classes( $s, 'nx_submit_width' ) ); ?> nx-form-actions">
672 <button type="submit" class="nx-form-submit">
673 <?php echo esc_html( $s['nx_submit_text'] ?? __( 'Submit', 'notificationx' ) ); ?>
674 </button>
675 </div>
676
677 </div>
678
679 <div class="nx-form-message" role="status" aria-live="polite"></div>
680 </form>
681 </div>
682 <?php
683 }
684 }
685