Last active
January 28, 2025 16:26
-
-
Save mahircoding/9ca8519a4d418eeb48de46add1b3e2f6 to your computer and use it in GitHub Desktop.
jet engine custom form lokasi file di builder.php & frontend-forms.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Form builder class | |
| */ | |
| // If this file is called directly, abort. | |
| if ( ! defined( 'WPINC' ) ) { | |
| die; | |
| } | |
| if ( ! class_exists( 'Jet_Engine_Booking_Forms_Builder' ) ) { | |
| /** | |
| * Define Jet_Engine_Booking_Forms_Builder class | |
| */ | |
| class Jet_Engine_Booking_Forms_Builder { | |
| public $form_id = null; | |
| public $post = null; | |
| public $fields = array(); | |
| public $fields_settings = array(); | |
| public $args = array(); | |
| public $settings = array(); | |
| public $attrs = array(); | |
| public $rows = array(); | |
| public $captcha = false; | |
| public $preset = false; | |
| public $is_hidden_row = true; | |
| public $is_submit_row = false; | |
| public $is_page_break_row = false; | |
| public $rendered_rows = 0; | |
| public $pages = 0; | |
| public $page = 0; | |
| public $has_prev = false; | |
| public $start_new_page = true; | |
| public $manager = null; | |
| public $current_repeater = false; | |
| public $current_repeater_i = false; | |
| /** | |
| * Constructor for the class | |
| */ | |
| function __construct( $form_id = null, $fields = false, $args = array(), $captcha = false ) { | |
| if ( ! $form_id ) { | |
| return; | |
| } | |
| $this->form_id = $form_id; | |
| $this->setup_fields( $fields ); | |
| $this->args = wp_parse_args( $args, array( | |
| 'fields_layout' => 'column', | |
| 'label_tag' => 'div', | |
| 'rows_divider' => false, | |
| 'required_mark' => '*', | |
| 'submit_type' => 'reload', | |
| ) ); | |
| if ( empty( $post ) ) { | |
| global $post; | |
| } | |
| $this->post = $post; | |
| $this->captcha = $captcha; | |
| $this->preset = new Jet_Engine_Booking_Forms_Preset( $this->form_id ); | |
| } | |
| /** | |
| * Set manager instance | |
| * | |
| * @param [type] $manager [description] | |
| */ | |
| public function set_manager( $manager ) { | |
| $this->manager = $manager; | |
| } | |
| /** | |
| * Setup fields prop | |
| */ | |
| public function setup_fields( $fields = false ) { | |
| $raw_fields = ''; | |
| if ( $fields ) { | |
| $raw_fields = $fields; | |
| } else { | |
| $raw_fields = get_post_meta( $this->form_id, '_form_data', true ); | |
| $raw_fields = json_decode( wp_unslash( $raw_fields ), true ); | |
| } | |
| if ( empty( $raw_fields ) ) { | |
| return; | |
| } | |
| // Ensure fields sorted by rows | |
| usort( $raw_fields, function( $a, $b ) { | |
| if ( $a['y'] == $b['y'] ) { | |
| return 0; | |
| } | |
| return ( $a['y'] < $b['y'] ) ? -1 : 1; | |
| } ); | |
| $repeater_index = false; | |
| foreach ( $raw_fields as $index => $field ) { | |
| if ( $this->is_repeater_start( $field['settings'] ) ) { | |
| $repeater_index = $index; | |
| continue; | |
| } | |
| if ( $this->is_repeater_end( $field['settings'] ) ) { | |
| $repeater_index = false; | |
| unset( $raw_fields[ $index ] ); | |
| continue; | |
| } | |
| if ( false !== $repeater_index ) { | |
| if ( empty( $raw_fields[ $repeater_index ]['settings']['repeater_fields'] ) ) { | |
| $raw_fields[ $repeater_index ]['settings']['repeater_fields'] = array(); | |
| } | |
| $raw_fields[ $repeater_index ]['settings']['repeater_fields'][] = $field; | |
| unset( $raw_fields[ $index ] ); | |
| } | |
| } | |
| $this->fields = $raw_fields; | |
| $this->fields_settings = wp_list_pluck( $raw_fields, 'settings' ); | |
| $this->rows = $this->get_sorted_fields( $raw_fields ); | |
| } | |
| /** | |
| * Public function get sorted form fields | |
| */ | |
| public function get_sorted_fields( $raw_fields = array() ) { | |
| $sorted = array(); | |
| $y = false; | |
| foreach ( $raw_fields as $field ) { | |
| $is_page_break = ! empty( $field['settings']['is_page_break'] ) ? true : false; | |
| if ( $is_page_break ) { | |
| $this->pages++; | |
| } | |
| if ( false === $y ) { | |
| $y = $field['y']; | |
| } | |
| if ( $field['y'] === $y ) { | |
| if ( empty( $sorted[ $y ] ) ) { | |
| $sorted[ $y ] = array(); | |
| } | |
| $sorted[ $y ][] = $field; | |
| } else { | |
| usort( $sorted[ $y ], function( $a, $b ) { | |
| if ( $a['x'] == $b['x'] ) { | |
| return 0; | |
| } | |
| return ( $a['x'] < $b['x'] ) ? -1 : 1; | |
| } ); | |
| $y = $field['y']; | |
| $sorted[ $y ][] = $field; | |
| } | |
| } | |
| // Ensure last row is sorted | |
| usort( $sorted[ $y ], function( $a, $b ) { | |
| if ( $a['x'] == $b['x'] ) { | |
| return 0; | |
| } | |
| return ( $a['x'] < $b['x'] ) ? -1 : 1; | |
| } ); | |
| return $sorted; | |
| } | |
| public function get_author_meta( $key ) { | |
| $post_id = get_the_ID(); | |
| if ( ! $post_id ) { | |
| return null; | |
| } | |
| global $authordata; | |
| if ( $authordata ) { | |
| return get_the_author_meta( $key ); | |
| } | |
| $post = get_post( $post_id ); | |
| if ( ! $post ) { | |
| return null; | |
| } | |
| return get_the_author_meta( $key, $post->post_author ); | |
| } | |
| /** | |
| * Get hidden value | |
| * | |
| * @return string | |
| */ | |
| public function get_hidden_val( $args = array() ) { | |
| $from = isset( $args['hidden_value'] ) ? $args['hidden_value'] : ''; | |
| switch ( $from ) { | |
| case 'post_id': | |
| if ( ! $this->post ) { | |
| return null; | |
| } else { | |
| return $this->post->ID; | |
| } | |
| case 'post_title': | |
| if ( ! $this->post ) { | |
| return null; | |
| } else { | |
| return get_the_title( $this->post->ID ); | |
| } | |
| case 'post_url': | |
| if ( ! $this->post ) { | |
| return null; | |
| } else { | |
| return get_permalink( $this->post->ID ); | |
| } | |
| case 'post_meta': | |
| if ( ! $this->post ) { | |
| return null; | |
| } | |
| $key = ! empty( $args['hidden_value_field'] ) ? $args['hidden_value_field'] : ''; | |
| if ( ! $key ) { | |
| return null; | |
| } else { | |
| return get_post_meta( $this->post->ID, $key, true ); | |
| } | |
| case 'query_var': | |
| $key = ! empty( $args['query_var_key'] ) ? $args['query_var_key'] : ''; | |
| if ( ! $key ) { | |
| return null; | |
| } else { | |
| return isset( $_GET[ $key ] ) ? esc_attr( $_GET[ $key ] ) : null; | |
| } | |
| case 'user_id': | |
| if ( ! is_user_logged_in() ) { | |
| return null; | |
| } else { | |
| return get_current_user_id(); | |
| } | |
| case 'user_email': | |
| if ( ! is_user_logged_in() ) { | |
| return null; | |
| } else { | |
| $user = wp_get_current_user(); | |
| return $user->user_email; | |
| } | |
| case 'user_name': | |
| if ( ! is_user_logged_in() ) { | |
| return null; | |
| } else { | |
| $user = wp_get_current_user(); | |
| return $user->display_name; | |
| } | |
| case 'user_meta': | |
| $key = ! empty( $args['hidden_value_field'] ) ? $args['hidden_value_field'] : ''; | |
| if ( ! $key ) { | |
| return null; | |
| } | |
| if ( ! is_user_logged_in() ) { | |
| return null; | |
| } else { | |
| return get_user_meta( get_current_user_id(), $key, true ); | |
| } | |
| case 'author_id': | |
| return $this->get_author_meta( 'ID' ); | |
| case 'author_email': | |
| return $this->get_author_meta( 'user_email' ); | |
| case 'author_name': | |
| return $this->get_author_meta( 'display_name' ); | |
| case 'current_date': | |
| $format = ! empty( $args['date_format'] ) ? $args['date_format'] : get_option( 'date_format' ); | |
| return date_i18n( $format ); | |
| case 'manual_input': | |
| return ! empty( $args['default'] ) ? $args['default'] : 0; | |
| default: | |
| $value = ! empty( $args['default'] ) ? $args['default'] : ''; | |
| return apply_filters( 'jet-engine/forms/hidden-value/' . $from, $value ); | |
| } | |
| } | |
| /** | |
| * Render custom form item template | |
| * | |
| * @param int|string $object_id Object ID | |
| * @param array $args Field arguments | |
| * @param bool|string $checked | |
| * @return string | |
| */ | |
| public function get_custom_template( $object_id = null, $args = array(), $checked = false ) { | |
| $listing_id = ! empty( $args['custom_item_template_id'] ) ? $args['custom_item_template_id'] : false; | |
| $listing_id = absint( $listing_id ); | |
| if ( ! $listing_id ) { | |
| return __( 'Please select template', 'jet-engine' ) . '<br>'; | |
| } | |
| global $wp_query; | |
| $default_object = $wp_query->queried_object; | |
| $options_from = ! empty( $args['field_options_from'] ) ? $args['field_options_from'] : 'posts'; | |
| if ( 'terms' === $options_from ) { | |
| $object = get_term( $object_id ); | |
| } else { | |
| $object = get_post( $object_id ); | |
| } | |
| $classes = array( | |
| 'jet-form__field-template', | |
| 'jet-listing-dynamic-post-' . $object_id, | |
| ); | |
| if ( $checked ) { | |
| $classes[] = 'jet-form__field-template--checked'; | |
| } | |
| $wp_query->queried_object = $object; | |
| jet_engine()->listings->data->set_current_object( $object ); | |
| jet_engine()->frontend->set_listing( $listing_id ); | |
| $content = jet_engine()->frontend->get_listing_item( $object ); | |
| $result = sprintf( | |
| '<div class="%3$s" data-value="%1$d">%2$s</div>', | |
| $object_id, | |
| apply_filters( 'jet-engine/forms/custom-template-content', $content, $object_id, $listing_id ), | |
| join( ' ', $classes ) | |
| ); | |
| $wp_query->queried_object = $default_object; | |
| jet_engine()->listings->data->set_current_object( $wp_query->queried_object ); | |
| return $result; | |
| } | |
| /** | |
| * Get required attribute value | |
| * | |
| * @param [type] $args [description] | |
| * @return [type] [description] | |
| */ | |
| public function get_required_val( $args ) { | |
| if ( ! empty( $args['required'] ) && ( 'required' === $args['required'] || true === $args['required'] ) ) { | |
| return 'required'; | |
| } | |
| return ''; | |
| } | |
| /** | |
| * Get calulation formula for calculated field | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_calculated_data( $args ) { | |
| if ( empty( $args['calc_formula'] ) ) { | |
| return ''; | |
| } | |
| $listen_fields = array(); | |
| $formula = preg_replace_callback( | |
| '/%([a-zA-Z-_]+)::([a-zA-Z0-9-_]+)%/', | |
| function( $matches ) use ( &$listen_fields ) { | |
| switch ( strtolower( $matches[1] ) ) { | |
| case 'field': | |
| $listen_fields[] = $matches[2]; | |
| return '%' . $matches[2] . '%'; | |
| case 'meta': | |
| return get_post_meta( $this->post->ID, $matches[2], true ); | |
| default: | |
| $macros_name = $matches[1]; | |
| $field_key = isset( $matches[2] ) ? $matches[2] : '' ; | |
| if( $field_key ){ | |
| $listen_fields[] = $field_key; | |
| } | |
| return apply_filters( "jet-engine/calculated-data/$macros_name", $matches[0], $matches ); | |
| } | |
| }, | |
| $args['calc_formula'] | |
| ); | |
| return array( | |
| 'formula' => $formula, | |
| 'listen_fields' => $listen_fields, | |
| 'listen_to' => $listen_fields, | |
| ); | |
| } | |
| /** | |
| * Add attribute | |
| */ | |
| public function add_attribute( $attr = null, $value = null ) { | |
| if ( '' === $value ) { | |
| return; | |
| } | |
| if ( in_array( $attr, array( 'value', 'placeholder' ) ) ) { | |
| $value = esc_attr( $value ); | |
| } | |
| if ( ! isset( $this->attrs[ $attr ] ) ) { | |
| $this->attrs[ $attr ] = $value; | |
| } else { | |
| $this->attrs[ $attr ] .= ' ' . $value; | |
| } | |
| } | |
| /** | |
| * Returns field name with repeater prefix if needed | |
| */ | |
| public function get_field_name( $name ) { | |
| if ( $this->current_repeater ) { | |
| $repeater_name = ! empty( $this->current_repeater['name'] ) ? $this->current_repeater['name'] : 'repeater'; | |
| $index = ( false !== $this->current_repeater_i ) ? $this->current_repeater_i : '__i__'; | |
| $name = sprintf( '%1$s[%2$s][%3$s]', $repeater_name, $index, $name ); | |
| } | |
| return $name; | |
| } | |
| /** | |
| * Returns field ID with repeater prefix if needed | |
| */ | |
| public function get_field_id( $name ) { | |
| if ( is_array( $name ) ) { | |
| $name = $name['name']; | |
| } | |
| if ( $this->current_repeater ) { | |
| $repeater_name = ! empty( $this->current_repeater['name'] ) ? $this->current_repeater['name'] : 'repeater'; | |
| $index = ( false !== $this->current_repeater_i ) ? $this->current_repeater_i : '__i__'; | |
| $name = sprintf( '%1$s_%2$s_%3$s', $repeater_name, $index, $name ); | |
| } | |
| return $name; | |
| } | |
| /** | |
| * Reset attributes array | |
| */ | |
| public function reset_attributes() { | |
| $this->attrs = array(); | |
| } | |
| /** | |
| * Render current attributes string | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function render_attributes_string() { | |
| foreach ( $this->attrs as $attr => $value ) { | |
| printf( ' %1$s="%2$s"', $attr, $value ); | |
| } | |
| $this->attrs = array(); | |
| } | |
| /** | |
| * Render current repeater row | |
| */ | |
| public function render_repeater_row( $children = array(), $index = false, $manage_items = 'manually', $calc_dataset = '' ) { | |
| if ( false !== $index ) { | |
| $this->current_repeater_i = $index; | |
| } else { | |
| $index = 0; | |
| $this->current_repeater_i = false; | |
| } | |
| echo '<div class="jet-form-repeater__row" data-repeater-row="1" data-index="' . $index . '"' . $calc_dataset . '>'; | |
| echo '<div class="jet-form-repeater__row-fields">'; | |
| foreach ( $children as $row ) { | |
| $this->is_hidden_row = true; | |
| $this->is_submit_row = false; | |
| $this->is_page_break_row = false; | |
| ob_start(); | |
| $this->render_row( $row ); | |
| $rendered_row = ob_get_clean(); | |
| //$this->maybe_start_page(); | |
| $this->start_form_row( $row ); | |
| echo $rendered_row; | |
| $this->end_form_row( $row ); | |
| //$this->maybe_end_page(); | |
| } | |
| echo '</div>'; | |
| if ( 'manually' === $manage_items ) { | |
| echo '<div class="jet-form-repeater__row-remove">'; | |
| echo '<button type="button" class="jet-form-repeater__remove">Hapus</button>'; | |
| echo '</div>'; | |
| } | |
| echo '</div>'; | |
| // File custom mulai disini | |
| ?> | |
| <script> | |
| jQuery(document).ready(function($) { | |
| function autoSetCurrentDate(row) { | |
| const rtlInput2 = row.querySelector('input[data-field-name="rtl_date"]'); | |
| const currentDate = new Date().toISOString().split('T')[0]; | |
| if (rtlInput2) { | |
| rtlInput2.value = currentDate; | |
| } | |
| } | |
| function checkRepeaterRow(row) { | |
| const hasRtl = row.find('[data-field-name="rtl"]').length > 0; | |
| const hasSelesaiButton = row.find('.jet-form-repeater__selesai').length > 0; | |
| const pageBreak = row.find('.field-type-group_break'); | |
| if (hasRtl && !hasSelesaiButton && pageBreak.length > 0) { | |
| const buttonHtml = ` | |
| <div class="jet-form-repeater__row-selesai" style="padding-top:0px;"> | |
| <button type="button" class="jet-form-repeater__selesai">Selesai</button> | |
| </div> | |
| <div class="" style="margin-bottom:14px"></div> | |
| `; | |
| pageBreak.after(buttonHtml); | |
| } | |
| } | |
| $('.jet-form-repeater__row').each(function() { | |
| checkRepeaterRow($(this)); | |
| autoSetCurrentDate(this); | |
| }); | |
| $(document).on('jet-form-builder/repeater/row-added', function(event, row) { | |
| checkRepeaterRow($(row)); | |
| autoSetCurrentDate(row); | |
| }); | |
| }); | |
| </script> | |
| <style> | |
| .pilihan_hidden { | |
| display: none!important; | |
| } | |
| .jet-form-repeater__actions { | |
| margin-top: 30px; | |
| } | |
| .jet-form-repeater__row-selesai { | |
| display: flex; | |
| position: absolute; | |
| left: 0px; | |
| padding-top: 20px; | |
| } | |
| .jet-form-repeater__selesai { | |
| background-color: #4CAF50; | |
| color: white; | |
| padding: 10px 20px; | |
| border: none; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| } | |
| .jet-form-repeater__selesai:hover { | |
| background-color: #45a049; | |
| } | |
| </style> | |
| <?php | |
| // File custom berakhir disini | |
| } | |
| /** | |
| * Render repeater fields group | |
| */ | |
| public function render_repeater_fields( $args = array() ) { | |
| ob_start(); | |
| $children = ! empty( $args['repeater_fields'] ) ? $args['repeater_fields'] : array(); | |
| $manage_items = ! empty( $args['manage_items_count'] ) ? $args['manage_items_count'] : 'manually'; | |
| $items_field = ! empty( $args['manage_items_count_field'] ) ? $args['manage_items_count_field'] : false; | |
| if ( empty( $children ) ) { | |
| return; | |
| } | |
| /* | |
| Disabled because getting preset value moved before rendering fields in render_filed method | |
| $preset_value = $this->preset->get_field_value( $args['name'], $args ); | |
| if ( $preset_value['rewrite'] ) { | |
| $args['default'] = $preset_value['value']; | |
| } else { | |
| $args['default'] = $this->maybe_adjust_value( $args ); | |
| }*/ | |
| $this->current_repeater = $args; | |
| $children = $this->get_sorted_fields( $children ); | |
| $repeater_calc_type = ! empty( $args['repeater_calc_type'] ) ? $args['repeater_calc_type'] : 'default'; | |
| $calc_data = false; | |
| if ( 'custom' === $repeater_calc_type ) { | |
| $calc_data = $this->get_calculated_data( $args ); | |
| } | |
| $settings = htmlspecialchars( json_encode( array( | |
| 'manageItems' => $manage_items, | |
| 'itemsField' => $items_field, | |
| 'calcType' => $repeater_calc_type, | |
| ) ) ); | |
| $calc_dataset = ''; | |
| if ( $calc_data ) { | |
| foreach ( $calc_data as $data_key => $data_value ) { | |
| if ( is_array( $data_value ) ) { | |
| $data_value = json_encode( $data_value ); | |
| } | |
| $calc_dataset .= sprintf( ' data-%1$s="%2$s"', $data_key, htmlspecialchars( $data_value ) ); | |
| } | |
| } | |
| echo '<div class="jet-form-repeater" data-repeater="1" data-field-name="' . $args['name'] . '" name="' . $args['name'] . '" data-settings="' . $settings . '"' . $calc_dataset . '>'; | |
| echo '<template class="jet-form-repeater__initial">'; | |
| $this->render_repeater_row( $children, false, $manage_items, $calc_dataset ); | |
| echo '</template>'; | |
| echo '<div class="jet-form-repeater__items">'; | |
| if ( ! empty( $args['default'] ) && is_array( $args['default'] ) ) { | |
| $i = 0; | |
| foreach ( $args['default'] as $item ) { | |
| $this->current_repeater['values'] = $item; | |
| $this->render_repeater_row( $children, $i, $manage_items, $calc_dataset ); | |
| $i++; | |
| } | |
| $this->current_repeater['values'] = false; | |
| } | |
| echo '</div>'; | |
| if ( 'manually' === $manage_items ) { | |
| echo '<div class="jet-form-repeater__actions">'; | |
| $new_item_label = ! empty( $args['new_item_label'] ) ? $args['new_item_label'] : __( 'Add new', 'jet-engine' ); | |
| printf( '<button type="button" class="jet-form-repeater__new">%1$s</button>', $new_item_label ); | |
| echo '</div>'; | |
| } | |
| echo '</div>'; | |
| $this->current_repeater = false; | |
| return ob_get_clean(); | |
| } | |
| /** | |
| * Render form field by passed arguments. | |
| * | |
| * @param array $args [description] | |
| * @return [type] [description] | |
| */ | |
| public function render_field( $args = array() ) { | |
| if ( empty( $args['type'] ) ) { | |
| return; | |
| } | |
| $defaults = array( | |
| 'default' => '', | |
| 'name' => '', | |
| 'placeholder' => '', | |
| 'required' => false, | |
| ); | |
| $template = null; | |
| $name = ! empty( $args['name'] ) ? $args['name'] : ''; | |
| $preset_value = $this->preset->get_field_value( $name, $args ); | |
| if ( ! empty( $preset_value ) && $preset_value['rewrite'] ) { | |
| $args['default'] = $preset_value['value']; | |
| } else { | |
| $args['default'] = $this->maybe_adjust_value( $args ); | |
| } | |
| // Repeater defaults prsed inside repeater field so here we need to get the data from repeater | |
| if ( $this->current_repeater && ! empty( $this->current_repeater['values'] ) && isset( $this->current_repeater['values'][ $args['name'] ] ) ) { | |
| $args['default'] = $this->current_repeater['values'][ $args['name'] ]; | |
| } | |
| // Prepare defaults | |
| switch ( $args['type'] ) { | |
| case 'repeater_start': | |
| $template = $this->render_repeater_fields( $args ); | |
| break; | |
| case 'hidden': | |
| $val = $this->get_hidden_val( $args ); | |
| $defaults['default'] = $val; | |
| $args['default'] = $val; | |
| break; | |
| case 'number': | |
| case 'range': | |
| $defaults['min'] = ''; | |
| $defaults['max'] = ''; | |
| $defaults['step'] = 1; | |
| break; | |
| case 'text': | |
| $defaults['field_type'] = 'text'; | |
| if ( ! empty( $args['enable_input_mask'] ) && ! empty( $args['input_mask'] ) ) { | |
| wp_enqueue_script( 'jet-engine-inputmask' ); | |
| add_filter( | |
| 'jet-engine/compatibility/popup-package/the_content', | |
| array( $this, 'ensure_mask_js' ), 10, 2 | |
| ); | |
| } | |
| break; | |
| case 'calculated': | |
| $defaults['formula'] = ''; | |
| $args['required'] = false; | |
| break; | |
| case 'submit': | |
| $defaults['label'] = __( 'Submit', 'jet-engine' ); | |
| $defaults['class_name'] = ''; | |
| $this->is_submit_row = true; | |
| break; | |
| case 'page_break': | |
| $defaults['label'] = __( 'Submit', 'jet-engine' ); | |
| $defaults['class_name'] = ''; | |
| $this->is_page_break_row = true; | |
| break; | |
| case 'media': | |
| Jet_Engine_Forms_File_Upload::instance()->set_custom_messages( $this->form_id ); | |
| Jet_Engine_Forms_File_Upload::instance()->enqueue_upload_script(); | |
| add_filter( | |
| 'jet-engine/compatibility/popup-package/the_content', | |
| array( Jet_Engine_Forms_File_Upload::instance(), 'ensure_media_js' ), 10, 2 | |
| ); | |
| break; | |
| case 'wysiwyg': | |
| wp_enqueue_editor(); | |
| wp_localize_script( | |
| 'jet-engine-frontend-forms', | |
| 'JetEngineFormsEditor', | |
| array( | |
| 'hasEditor' => true, | |
| ) | |
| ); | |
| add_filter( | |
| 'jet-engine/compatibility/popup-package/the_content', | |
| array( $this, 'ensure_wysiwyg_js' ), 10, 2 | |
| ); | |
| // Ensure template not rewritten | |
| $template = false; | |
| break; | |
| case 'textarea': | |
| case 'select': | |
| case 'checkboxes': | |
| case 'radio': | |
| case 'date': | |
| case 'time': | |
| case 'datetime-local': | |
| case 'heading': | |
| case 'group_break': | |
| // Ensure template not rewritten | |
| $template = false; | |
| break; | |
| default: | |
| if ( 'hidden' !== $args['type'] ) { | |
| $this->is_hidden_row = false; | |
| } | |
| /** | |
| * Render custom field | |
| */ | |
| do_action( 'jet-engine/forms/booking/render-field/' . $args['type'], $args, $this ); | |
| /** | |
| * Or just get custom template for field | |
| */ | |
| $template = apply_filters( | |
| 'jet-engine/forms/booking/field-template/' . $args['type'], | |
| $template, | |
| $args, | |
| $this | |
| ); | |
| if ( ! $template ) { | |
| return; | |
| } else { | |
| break; | |
| } | |
| } | |
| $sanitized_args = array(); | |
| foreach ( $args as $key => $value ) { | |
| $sanitized_args[ $key ] = $value; | |
| } | |
| $args = wp_parse_args( $sanitized_args, $defaults ); | |
| if ( ! $template ) { | |
| $template_name = str_replace( '_', '-', $args['type'] ); | |
| $template = jet_engine()->get_template( 'forms/fields/' . $template_name . '.php' ); | |
| } | |
| // Ensure args | |
| switch ( $args['type'] ) { | |
| case 'select': | |
| case 'checkboxes': | |
| case 'radio': | |
| $args['field_options'] = $this->get_field_options( $args ); | |
| break; | |
| } | |
| $label = $this->get_field_label( $args ); | |
| $desc = $this->get_field_desc( $args ); | |
| $layout = $this->args['fields_layout']; | |
| $args = apply_filters( "jet-engine/forms/render/{$args['type']}", $args, $this ); | |
| if ( 'column' === $layout ) { | |
| include jet_engine()->get_template( 'forms/common/field-column.php' ); | |
| } else { | |
| include jet_engine()->get_template( 'forms/common/field-row.php' ); | |
| } | |
| if ( 'hidden' !== $args['type'] && ! $this->is_hidden_calc_field( $args ) ) { | |
| $this->is_hidden_row = false; | |
| } | |
| } | |
| /** | |
| * Ensure mask JS is enqueued | |
| * | |
| * @param [type] $content [description] | |
| * @return [type] [description] | |
| */ | |
| public function ensure_mask_js( $content = null, $popup_data = array() ) { | |
| ob_start(); | |
| wp_register_script( | |
| 'jet-engine-inputmask', | |
| jet_engine()->plugin_url( 'assets/lib/inputmask/jquery.inputmask.min.js' ), | |
| array(), | |
| jet_engine()->get_version(), | |
| true | |
| ); | |
| wp_scripts()->print_scripts( 'jet-engine-inputmask' ); | |
| return $content . ob_get_clean(); | |
| } | |
| /** | |
| * Ensure wysiwyg JS is enqueued | |
| * | |
| * @param [type] $content [description] | |
| * @return [type] [description] | |
| */ | |
| public function ensure_wysiwyg_js( $content = null, $popup_data = array() ) { | |
| if ( ! empty( $popup_data['hasEditor'] ) ) { | |
| return $content; | |
| } | |
| ob_start(); | |
| _WP_Editors::editor_js(); | |
| _WP_Editors::force_uncompressed_tinymce(); | |
| _WP_Editors::enqueue_scripts(); | |
| wp_enqueue_editor(); | |
| wp_scripts()->done[] = 'jquery-core'; | |
| wp_scripts()->done[] = 'jquery-migrate'; | |
| wp_scripts()->done[] = 'jquery'; | |
| print_footer_scripts(); | |
| return $content . ob_get_clean(); | |
| } | |
| /** | |
| * Try to get values from request if passed | |
| * @param [type] $args [description] | |
| * @return [type] [description] | |
| */ | |
| public function maybe_adjust_value( $args ) { | |
| if ( 'hidden' === $args['type'] ) { | |
| return isset( $args['default'] ) ? $args['default'] : ''; | |
| } | |
| $value = isset( $args['default'] ) ? $args['default'] : false; | |
| $request_val = ! empty( $_REQUEST['values'] ) ? $_REQUEST['values'] : array(); | |
| if ( ! empty( $request_val[ $args['name'] ] ) ) { | |
| $value = $request_val[ $args['name'] ]; | |
| } | |
| return $value; | |
| } | |
| /** | |
| * Returns field label | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_field_label( $args ) { | |
| $no_labels = $this->get_no_labels_types(); | |
| ob_start(); | |
| if ( ! empty( $args['label'] ) && ! in_array( $args['type'], $no_labels ) && ! $this->is_hidden_calc_field( $args ) ) { | |
| include jet_engine()->get_template( 'forms/common/field-label.php' ); | |
| } | |
| return ob_get_clean(); | |
| } | |
| /** | |
| * Returns field description | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_field_desc( $args ) { | |
| $no_labels = $this->get_no_labels_types(); | |
| ob_start(); | |
| if ( ! empty( $args['desc'] ) && ! in_array( $args['type'], $no_labels ) && ! $this->is_hidden_calc_field( $args ) ) { | |
| include jet_engine()->get_template( 'forms/common/field-description.php' ); | |
| } | |
| return ob_get_clean(); | |
| } | |
| /** | |
| * Return field types without labels | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_no_labels_types() { | |
| return array( 'submit', 'hidden', 'page_break', 'group_break' ); | |
| } | |
| /** | |
| * Is hidden calculated field | |
| * | |
| * @param $args | |
| * | |
| * @return bool | |
| */ | |
| public function is_hidden_calc_field( $args ) { | |
| $is_hidden = false; | |
| if ( 'calculated' !== $args['type'] ) { | |
| return $is_hidden; | |
| } | |
| $is_hidden = isset( $args['calc_hidden'] ) ? filter_var( $args['calc_hidden'], FILTER_VALIDATE_BOOLEAN ) : false; | |
| return $is_hidden; | |
| } | |
| /** | |
| * Returns field options list | |
| * | |
| * @return array | |
| */ | |
| public function get_field_options( $args ) { | |
| $options_from = ! empty( $args['field_options_from'] ) ? $args['field_options_from'] : 'manual_input'; | |
| $options = array(); | |
| $value_from = ! empty( $args['value_from_key'] ) ? $args['value_from_key'] : false; | |
| $calc_from = ! empty( $args['calculated_value_from_key'] ) ? $args['calculated_value_from_key'] : false; | |
| if ( 'manual_input' === $options_from ) { | |
| if ( ! empty( $args['field_options'] ) ) { | |
| foreach ( $args['field_options'] as $option ) { | |
| $item = array( | |
| 'value' => $option['value'], | |
| 'label' => $option['label'], | |
| ); | |
| if ( isset( $option['calculate'] ) && '' !== $option['calculate'] ) { | |
| $item['calculate'] = $option['calculate']; | |
| } | |
| $options[] = $item; | |
| } | |
| } | |
| } elseif ( 'posts' === $options_from ) { | |
| $post_type = ! empty( $args['field_options_post_type'] ) ? $args['field_options_post_type'] : false; | |
| if ( ! $post_type ) { | |
| return $options; | |
| } | |
| $posts = get_posts( apply_filters( 'jet-engine/compatibility/get-posts/args', array( | |
| 'post_status' => 'publish', | |
| 'posts_per_page' => -1, | |
| 'post_type' => $post_type, | |
| ) ) ); | |
| if ( empty( $posts ) ) { | |
| return $options; | |
| } | |
| $result = array(); | |
| $post_props = array( 'post_title', 'post_content', 'post_name', 'post_excerpt' ); | |
| foreach ( $posts as $post ) { | |
| $item = array( | |
| 'value' => $post->ID, | |
| 'label' => $post->post_title, | |
| ); | |
| if ( ! empty( $value_from ) ) { | |
| if ( in_array( $value_from, $post_props ) ) { | |
| $item['value'] = $post->$value_from; | |
| } else { | |
| $item['value'] = get_post_meta( $post->ID, $value_from, true ); | |
| } | |
| } | |
| if ( ! empty( $calc_from ) ) { | |
| if ( in_array( $calc_from, $post_props ) ) { | |
| $item['calculate'] = $post->$calc_from; | |
| } else { | |
| $item['calculate'] = get_post_meta( $post->ID, $calc_from, true ); | |
| } | |
| } | |
| $result[] = $item; | |
| } | |
| $options = $result; | |
| } elseif ( 'terms' === $options_from ) { | |
| $tax = ! empty( $args['field_options_tax'] ) ? $args['field_options_tax'] : false; | |
| if ( ! $tax ) { | |
| return $options; | |
| } | |
| $terms = get_terms( array( | |
| 'taxonomy' => $tax, | |
| 'hide_empty' => false, | |
| ) ); | |
| if ( empty( $terms ) || is_wp_error( $terms ) ) { | |
| return $options; | |
| } | |
| $result = array(); | |
| foreach ( $terms as $term ) { | |
| $item = array( | |
| 'value' => $term->term_id, | |
| 'label' => $term->name, | |
| ); | |
| if ( ! empty( $value_from ) ) { | |
| $item['value'] = get_term_meta( $term->term_id, $value_from, true ); | |
| } | |
| if ( ! empty( $calc_from ) ) { | |
| $item['calculate'] = get_term_meta( $term->term_id, $calc_from, true ); | |
| } | |
| $result[] = $item; | |
| } | |
| $options = $result; | |
| } elseif ( 'generate' === $options_from ) { | |
| $generator = ! empty( $args['generator_function'] ) ? $args['generator_function'] : false; | |
| $field = ! empty( $args['generator_field'] ) ? $args['generator_field'] : false; | |
| if ( ! $generator ) { | |
| return $options; | |
| } | |
| if ( ! $this->manager ) { | |
| return $options; | |
| } | |
| $generators = $this->manager->get_options_generators(); | |
| $generator_instance = isset( $generators[ $generator ] ) ? $generators[ $generator ] : false; | |
| if ( ! $generator_instance ) { | |
| return $options; | |
| } | |
| $generated = $generator_instance->generate( $field ); | |
| $result = array(); | |
| if ( ! empty( $value_from || ! empty( $calc_from ) ) ) { | |
| foreach ( $generated as $key => $data ) { | |
| if ( is_array( $data ) ) { | |
| $item = $data; | |
| } else { | |
| $item = array( | |
| 'value' => $key, | |
| 'label' => $data, | |
| ); | |
| } | |
| $post_id = $item['value']; | |
| if ( ! empty( $value_from ) ) { | |
| $item['value'] = get_post_meta( $post_id, $value_from, true ); | |
| } | |
| if ( ! empty( $calc_from ) ) { | |
| $item['calculate'] = get_post_meta( $post_id, $calc_from, true ); | |
| } | |
| $result[] = $item; | |
| } | |
| $options = $result; | |
| } else { | |
| $options = $generated; | |
| } | |
| } else { | |
| $key = ! empty( $args['field_options_key'] ) ? $args['field_options_key'] : ''; | |
| if ( $key ) { | |
| $options = get_post_meta( $this->post->ID, $key, true ); | |
| $options = $this->maybe_parse_repeater_options( $options ); | |
| } | |
| } | |
| return apply_filters( 'jet-engine/forms/field-options', $options, $args, $this ); | |
| } | |
| /** | |
| * Returns form action url | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_form_action_url() { | |
| if ( ! wp_doing_ajax() ) { | |
| $action = add_query_arg( array( | |
| 'jet_engine_action' => 'book', | |
| 'nocache' => time(), | |
| ) ); | |
| } else { | |
| $action = add_query_arg( | |
| array( | |
| 'jet_engine_action' => 'book', | |
| '_jet_form_is_ajax' => true, | |
| ), | |
| home_url( '/' ) | |
| ); | |
| } | |
| return apply_filters( 'jet-engine/forms/booking/form-action-url', esc_url( $action ), $this ); | |
| } | |
| /** | |
| * Returns form refer url | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function get_form_refer_url() { | |
| global $wp; | |
| $refer = home_url( $wp->request ); | |
| if ( ! empty( $_SERVER['QUERY_STRING'] ) ) { | |
| $refer = trailingslashit( $refer ) . '?' . $_SERVER['QUERY_STRING']; | |
| } | |
| return apply_filters( 'jet-engine/forms/booking/form-refer-url', $refer, $this ); | |
| } | |
| /** | |
| * Open form wrapper | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function start_form() { | |
| do_action( 'jet-engine/forms/booking/before-start-form', $this ); | |
| $this->add_attribute( 'class', 'jet-form' ); | |
| $this->add_attribute( 'class', 'layout-' . $this->args['fields_layout'] ); | |
| $this->add_attribute( 'class', 'submit-type-' . $this->args['submit_type'] ); | |
| $this->add_attribute( 'action', $this->get_form_action_url() ); | |
| $this->add_attribute( 'method', 'POST' ); | |
| $this->add_attribute( 'data-form-id', $this->form_id ); | |
| $this->rendered_rows = 0; | |
| $this->page = 0; | |
| $this->has_prev = false; | |
| include jet_engine()->get_template( 'forms/common/start-form.php' ); | |
| do_action( 'jet-engine/forms/booking/after-start-form', $this ); | |
| } | |
| /** | |
| * Open form wrapper | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function start_form_row() { | |
| if ( ! $this->is_hidden_row ) { | |
| $this->rendered_rows++; | |
| } | |
| if ( true === $this->args['rows_divider'] && 1 < $this->rendered_rows && ! $this->is_hidden_row ) { | |
| echo '<div class="jet-form__divider"></div>'; | |
| } | |
| do_action( 'jet-engine/forms/booking/before-start-form-row', $this ); | |
| $this->add_attribute( 'class', 'jet-form-row' ); | |
| if ( $this->is_hidden_row ) { | |
| $this->add_attribute( 'class', 'jet-form-row--hidden' ); | |
| } | |
| if ( $this->is_submit_row ) { | |
| $this->add_attribute( 'class', 'jet-form-row--submit' ); | |
| } | |
| if ( $this->is_page_break_row ) { | |
| $this->add_attribute( 'class', 'jet-form-row--page-break' ); | |
| } | |
| if ( 1 === $this->rendered_rows ) { | |
| $this->add_attribute( 'class', 'jet-form-row--first-visible' ); | |
| } | |
| include jet_engine()->get_template( 'forms/common/start-form-row.php' ); | |
| do_action( 'jet-engine/forms/booking/after-start-form-row', $this ); | |
| } | |
| /** | |
| * Close form wrapper | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function end_form() { | |
| do_action( 'jet-engine/forms/booking/before-end-form', $this ); | |
| include jet_engine()->get_template( 'forms/common/end-form.php' ); | |
| do_action( 'jet-engine/forms/booking/after-end-form', $this ); | |
| } | |
| /** | |
| * Close form wrapper | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function end_form_row() { | |
| do_action( 'jet-engine/forms/booking/before-end-form-row', $this ); | |
| include jet_engine()->get_template( 'forms/common/end-form-row.php' ); | |
| do_action( 'jet-engine/forms/booking/after-end-form-row', $this ); | |
| } | |
| /** | |
| * Render passed form row | |
| * | |
| * @param [type] $row [description] | |
| * @return [type] [description] | |
| */ | |
| public function render_row( $row ) { | |
| $filled = 0; | |
| foreach ( $row as $field ) { | |
| $push = ''; | |
| $col = 'jet-form-col jet-form-col-' . $field['w']; | |
| if ( 0 < $filled ) { | |
| if ( $filled < $field['x'] ) { | |
| $push = $field['x'] - $filled; | |
| $filled = $filled + $push; | |
| $push = 'jet-form-push-' . $push; | |
| } | |
| } else { | |
| if ( 0 < $field['x'] ) { | |
| $push = 'jet-form-push-' . $field['x']; | |
| $filled = $filled + $field['x']; | |
| } | |
| } | |
| if ( $this->is_field_visible( $field['settings'] ) ) { | |
| $type = ! empty( $field['settings']['type'] ) ? $field['settings']['type'] : 'text'; | |
| $class_name = ! empty( $field['settings']['class_name'] ) ? $field['settings']['class_name'] : ''; | |
| $classes = array( | |
| $col, | |
| $push, | |
| 'field-type-' . $type, | |
| $class_name, | |
| 'jet-form-field-container' | |
| ); | |
| $conditional = ! empty( $field['conditionals'] ) ? $field['conditionals'] : false; | |
| if ( $conditional && is_array( $conditional ) ) { | |
| foreach ( $conditional as $index => $condition ) { | |
| if ( empty( $condition['operator'] ) ) { | |
| $condition['operator'] = 'equal'; | |
| } | |
| if ( empty( $condition['type'] ) ) { | |
| $condition['type'] = 'show'; | |
| } | |
| if ( false !== strpos( $condition['value'], 'jet_preset' ) && ! empty( $condition['field'] ) ) { | |
| $_field_key = array_search( $condition['field'], wp_list_pluck( $this->fields_settings, 'name' ) ); | |
| $_field_args = $this->fields_settings[ $_field_key ]; | |
| $_field_args['array_allowed'] = 'one_of' === $condition['operator']; | |
| $preset_value = $this->preset->get_condition_value( $condition, $_field_args ); | |
| if ( $preset_value['rewrite'] ) { | |
| $condition['value'] = $preset_value['value']; | |
| } | |
| } | |
| if ( in_array( $condition['operator'], array( 'between', 'one_of' ) ) && ! is_array( $condition['value'] ) ) { | |
| if ( ! empty( $condition['value'] ) ) { | |
| $value = explode( ',', $condition['value'] ); | |
| $value = array_map( 'trim', $value ); | |
| } else { | |
| $value = array(); | |
| } | |
| $condition['value'] = $value; | |
| } | |
| if ( $this->current_repeater && false !== strpos( $condition['field'], '::' ) ) { | |
| $parse_field_name = explode( '::', $condition['field'] ); | |
| $repeater_name = ! empty( $parse_field_name[0] ) ? $parse_field_name[0] : 'repeater'; | |
| $cond_field_name = ! empty( $parse_field_name[1] ) ? $parse_field_name[1] : ''; | |
| $repeater_index = ( false !== $this->current_repeater_i ) ? $this->current_repeater_i : '__i__'; | |
| $condition['field'] = sprintf( '%1$s\\[%2$s\\]\\[%3$s\\]', $repeater_name, $repeater_index, $cond_field_name ); | |
| } | |
| $conditional[ $index ] = $condition; | |
| } | |
| } | |
| $conditional = htmlspecialchars( json_encode( $conditional ) ); | |
| echo '<div class="' . implode( ' ', $classes ) . '" data-field="' . $field['settings']['name'] . '" data-conditional="' . $conditional . '">'; | |
| $this->render_field( $field['settings'] ); | |
| echo '</div>'; | |
| } | |
| $filled = $filled + $field['w']; | |
| } | |
| } | |
| /** | |
| * Check if is repeater start now | |
| * | |
| * @param array $args [description] | |
| * @return boolean [description] | |
| */ | |
| public function is_repeater_start( $args = array() ) { | |
| return ( ! empty( $args['type'] ) && 'repeater_start' === $args['type'] ); | |
| } | |
| /** | |
| * Check if is repeater end now | |
| * | |
| * @param array $args [description] | |
| * @return boolean [description] | |
| */ | |
| public function is_repeater_end( $args = array() ) { | |
| return ( ! empty( $args['type'] ) && 'repeater_end' === $args['type'] ); | |
| } | |
| /** | |
| * Returns true if field is visible | |
| * | |
| * @param array $field [description] | |
| * @return boolean [description] | |
| */ | |
| public function is_field_visible( $field = array() ) { | |
| // For backward compatibility and hidden fields | |
| if ( empty( $field['visibility'] ) ) { | |
| return true; | |
| } | |
| // If is visible for all - show field | |
| if ( 'all' === $field['visibility'] ) { | |
| return true; | |
| } | |
| // If is visible for logged in users and user is logged in - show field | |
| if ( 'logged_id' === $field['visibility'] && is_user_logged_in() ) { | |
| return true; | |
| } | |
| // If is visible for not logged in users and user is not logged in - show field | |
| if ( 'not_logged_in' === $field['visibility'] && ! is_user_logged_in() ) { | |
| return true; | |
| } | |
| return false; | |
| } | |
| /** | |
| * Render from HTML | |
| * @return [type] [description] | |
| */ | |
| public function render_form( $force_update = false ) { | |
| $pre_render = apply_filters( 'jet-engine/forms/pre-render/' . $this->form_id, false ); | |
| if ( $pre_render ) { | |
| return; | |
| } | |
| if ( ! $this->preset->sanitize_source() ) { | |
| echo 'You are not permitted to submit this form!'; | |
| return; | |
| } | |
| if ( ! $force_update ) { | |
| $cached = $this->get_form_cache(); | |
| if ( $cached ) { | |
| echo $this->add_nonce_field( $cached ); | |
| return; | |
| } | |
| } | |
| ob_start(); | |
| $this->start_form(); | |
| $this->render_field( array( | |
| 'type' => 'hidden', | |
| 'default' => $this->form_id, | |
| 'name' => '_jet_engine_booking_form_id', | |
| ) ); | |
| $this->render_field( array( | |
| 'type' => 'hidden', | |
| 'default' => $this->get_form_refer_url(), | |
| 'name' => '_jet_engine_refer', | |
| ) ); | |
| $token = jet_engine()->forms->handler->get_session_token( $this->form_id ); | |
| if ( $token ) { | |
| $this->render_field( array( | |
| 'type' => 'hidden', | |
| 'default' => $token, | |
| 'name' => '_jet_engine_form_token', | |
| ) ); | |
| } | |
| foreach ( $this->rows as $row ) { | |
| $this->is_hidden_row = true; | |
| $this->is_submit_row = false; | |
| $this->is_page_break_row = false; | |
| ob_start(); | |
| $this->render_row( $row ); | |
| $rendered_row = ob_get_clean(); | |
| $this->maybe_start_page(); | |
| $this->start_form_row( $row ); | |
| echo $rendered_row; | |
| $this->end_form_row( $row ); | |
| $this->maybe_end_page(); | |
| } | |
| if ( $this->captcha ) { | |
| $this->captcha->render( $this->form_id ); | |
| } | |
| $this->maybe_end_page( true ); | |
| $this->end_form(); | |
| $form = ob_get_clean(); | |
| $this->set_form_cache( $form ); | |
| echo $this->add_nonce_field( $form ); | |
| } | |
| public function add_nonce_field( $form_html ) { | |
| ob_start(); | |
| $this->render_field( array( | |
| 'type' => 'hidden', | |
| 'default' => wp_create_nonce( '_jet_engine_booking_form' ), | |
| 'name' => '_jet_engine_nonce', | |
| ) ); | |
| $nonce_field = ob_get_clean(); | |
| return str_replace( '</form>', $nonce_field . '</form>', $form_html ); | |
| } | |
| /** | |
| * Maybe start new page | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function maybe_start_page() { | |
| if ( 0 >= $this->pages ) { | |
| return; | |
| } | |
| if ( false === $this->start_new_page ) { | |
| return; | |
| } | |
| $this->start_new_page = false; | |
| $this->page++; | |
| do_action( 'jet-engine/forms/before-page-start', $this ); | |
| $hidden_class = ''; | |
| if ( 1 < $this->page ) { | |
| $hidden_class = 'jet-form-page--hidden'; | |
| } | |
| include jet_engine()->get_template( 'forms/common/start-page.php' ); | |
| do_action( 'jet-engine/forms/after-page-start', $this ); | |
| } | |
| /** | |
| * Maybe start new page | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function maybe_end_page( $is_last = false ) { | |
| if ( 0 >= $this->pages ) { | |
| return; | |
| } | |
| if ( ! $is_last && ! $this->is_page_break_row ) { | |
| return; | |
| } | |
| $this->start_new_page = true; | |
| $this->has_prev = true; | |
| do_action( 'jet-engine/forms/before-page-end', $this ); | |
| include jet_engine()->get_template( 'forms/common/end-page.php' ); | |
| do_action( 'jet-engine/forms/after-page-end', $this ); | |
| } | |
| /** | |
| * Get rendered form | |
| * @return [type] [description] | |
| */ | |
| public function get_form_cache() { | |
| return apply_filters( | |
| 'jet-engine/forms/booking/form-cache', | |
| get_post_meta( $this->form_id, '_rendered_form', true ), | |
| $this->form_id | |
| ); | |
| } | |
| /** | |
| * Store rendered form | |
| * @param [type] $content [description] | |
| */ | |
| public function set_form_cache( $content = null ) { | |
| update_post_meta( $this->form_id, '_rendered_form', $content ); | |
| } | |
| /** | |
| * Prepare repeater options fields | |
| * | |
| * @param [type] $options [description] | |
| * @return [type] [description] | |
| */ | |
| public function maybe_parse_repeater_options( $options ) { | |
| $result = array(); | |
| if ( empty( $options ) ) { | |
| return $result; | |
| } | |
| if ( ! is_array( $options ) ) { | |
| $options = array( $options ); | |
| } | |
| if ( in_array( 'true', $options ) || in_array( 'false', $options ) ) { | |
| return $this->get_checked_options( $options ); | |
| } | |
| $option_values = array_values( $options ); | |
| if ( ! is_array( $option_values[0] ) ) { | |
| foreach ( $options as $key => $value ) { | |
| $result[] = array( | |
| 'value' => is_string( $key ) ? $key : $value, | |
| 'label' => $value, | |
| ); | |
| } | |
| return $result; | |
| } | |
| foreach ( $options as $option ) { | |
| $values = array_values( $option ); | |
| if ( ! isset( $values[0] ) ) { | |
| continue; | |
| } | |
| $result[] = array( | |
| 'value' => $values[0], | |
| 'label' => isset( $values[1] ) ? $values[1] : $values[0], | |
| ); | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Returns checked options | |
| */ | |
| public function get_checked_options( $options ) { | |
| $result = array(); | |
| foreach ( $options as $label => $checked ) { | |
| $checked = filter_var( $checked, FILTER_VALIDATE_BOOLEAN ); | |
| if ( $checked ) { | |
| $result[] = array( | |
| 'value' => $label, | |
| 'label' => $label, | |
| ); | |
| } | |
| } | |
| return $result; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Custom mulai disini | |
| /** | |
| * Render field content | |
| * | |
| * @return [type] [description] | |
| */ | |
| public function render_repeater_items( $settings ) { | |
| global $post; | |
| $fields = $this->get_saved_fields( $settings ); | |
| $format = isset( $settings['dynamic_field_format'] ) ? wp_kses_post( $settings['dynamic_field_format'] ) : false; | |
| $delimiter = isset( $settings['items_delimiter'] ) ? wp_kses_post( $settings['items_delimiter'] ) : false; | |
| $item_tag = isset( $settings['item_tag'] ) ? $settings['item_tag'] : 'div'; | |
| $item_tag = Jet_Engine_Tools::sanitize_html_tag( $item_tag ); | |
| $items_before = isset( $settings['dynamic_field_before'] ) ? wp_kses_post( $settings['dynamic_field_before'] ) : ''; | |
| $items_after = isset( $settings['dynamic_field_after'] ) ? wp_kses_post( $settings['dynamic_field_after'] ) : ''; | |
| $is_first = true; | |
| $counter = ! empty( $settings['dynamic_field_counter'] ) ? $settings['dynamic_field_counter'] : false; | |
| $counter_after = ! empty( $settings['dynamic_field_counter_after'] ) ? wp_kses_post( $settings['dynamic_field_counter_after'] ) : false; | |
| $leading_zero = ! empty( $settings['dynamic_field_leading_zero'] ) ? $settings['dynamic_field_leading_zero'] : false; | |
| $counter_pos = ! empty( $settings['dynamic_field_counter_position'] ) ? esc_attr( $settings['dynamic_field_counter_position'] ) : 'at-left'; | |
| if ( empty( $fields ) ) { | |
| if ( ! empty( $settings['hide_if_empty'] ) ) { | |
| $this->show_field = false; | |
| } | |
| return; | |
| } | |
| $base_class = $this->get_name(); | |
| printf( | |
| '<div class="%1$s__items %2$s">', | |
| $base_class, | |
| ( $counter ? 'has-counter counter--' . $counter_pos : '' ) | |
| ); | |
| if ( $items_before ) { | |
| echo $items_before; | |
| } | |
| $index = 1; | |
| if ( ! is_array( $fields ) ) { | |
| $unserialized = maybe_unserialize( $fields ); | |
| if ( is_array( $unserialized ) ) { | |
| $fields = $unserialized; | |
| } | |
| } | |
| if ( ! is_array( $fields ) ) { | |
| $decoded = json_decode( $fields, true ); | |
| if ( is_array( $decoded ) ) { | |
| $fields = $decoded; | |
| } | |
| } | |
| if ( ! is_array( $fields ) ) { | |
| $fields = array( $fields ); | |
| } | |
| foreach ( $fields as $field ) { | |
| $item_content = preg_replace_callback( | |
| '/\%(([a-zA-Z0-9_-]+)(\|([a-zA-Z0-9\(\)\.\,\:\/\s_-]+))*)\%/', | |
| function( $matches ) use ( $field ) { | |
| if ( ! isset( $matches[2] ) ) { | |
| return $matches[0]; | |
| } | |
| if ( ! isset( $field[ $matches[2] ] ) ) { | |
| return $matches[0]; | |
| } else { | |
| if ( isset( $matches[4] ) ) { | |
| return jet_engine()->listings->filters->apply_filters( | |
| $field[ $matches[2] ], $matches[4] | |
| ); | |
| } else { | |
| return $field[ $matches[2] ]; | |
| } | |
| } | |
| }, | |
| $format | |
| ); | |
| $item_content = wp_kses_post( $item_content ); | |
| // Skip rendering if content is empty | |
| if ( empty( $item_content ) ) { | |
| continue; | |
| } | |
| if ( $delimiter && ! $is_first ) { | |
| printf( | |
| '<div class="%1$s__delimiter">%2$s</div>', | |
| $base_class, | |
| $delimiter | |
| ); | |
| } | |
| if ( apply_filters( 'jet-engine/listings/dynamic-repeater/allow-shorcodes', false ) ) { | |
| $item_content = do_shortcode( $item_content ); | |
| } | |
| if ( false === strpos( $item_content, '<' ) ) { | |
| $item_content = '<div>' . $item_content . '</div>'; | |
| } | |
| if ( $counter ) { | |
| $counter_html = $index; | |
| if ( $leading_zero ) { | |
| $counter_html = zeroise( $counter_html, 2 ); | |
| } | |
| if ( $counter_after ) { | |
| $counter_html = $counter_html . $counter_after; | |
| } | |
| $item_content = sprintf( | |
| '<div class="%2$s__counter">%3$s</div><div class="%2$s__body">%1$s</div>', | |
| $item_content, | |
| $base_class, | |
| $counter_html | |
| ); | |
| } | |
| printf( | |
| '<%3$s class="%1$s__item">%2$s</%3$s>', | |
| $base_class, | |
| $item_content, | |
| $item_tag | |
| ); | |
| $is_first = false; | |
| $index++; | |
| } | |
| if ( $items_after ) { | |
| echo $items_after; | |
| } | |
| echo '</div>'; | |
| } | |
| // Custom berakhir disini |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (function ($) { | |
| 'use strict'; | |
| $.fn.jetFormConditional = function (options) { | |
| var settings = $.extend( | |
| { | |
| hideJS: true, | |
| }, | |
| options | |
| ); | |
| var checkValue = function ($listenTo, listenFor, operator) { | |
| var val = ''; | |
| var checkResult = false; | |
| var controlType = 'plain'; | |
| operator = operator || 'equal'; | |
| if ($listenTo.is('input[type=checkbox]')) { | |
| controlType = 'checkbox'; | |
| } else if ($listenTo.is('input[type=radio]')) { | |
| controlType = 'radio'; | |
| } | |
| if ('checkbox' === controlType) { | |
| val = []; | |
| } | |
| if ('plain' === controlType) { | |
| val = $listenTo.val(); | |
| } else { | |
| $listenTo.each(function () { | |
| var $control = $(this); | |
| if ($control.is(':checked')) { | |
| if ('checkbox' === controlType) { | |
| val.push($control.val()); | |
| } else { | |
| val = $control.val(); | |
| } | |
| } | |
| }); | |
| } | |
| if ('is-hidden' === val) { | |
| val = ''; | |
| } | |
| switch (operator) { | |
| case 'equal': | |
| if (val && val.constructor === Array) { | |
| checkResult = false; | |
| } else { | |
| checkResult = val == listenFor; | |
| } | |
| break; | |
| case 'greater': | |
| if (val && val.constructor === Array) { | |
| checkResult = false; | |
| } else { | |
| checkResult = parseFloat(val) > parseFloat(listenFor); | |
| } | |
| break; | |
| case 'less': | |
| if (val && val.constructor === Array) { | |
| checkResult = false; | |
| } else { | |
| checkResult = parseFloat(val) < parseFloat(listenFor); | |
| } | |
| break; | |
| case 'between': | |
| if (val && val.constructor === Array) { | |
| checkResult = false; | |
| } else { | |
| if (2 <= listenFor.length) { | |
| let from = parseFloat(listenFor[0]); | |
| let to = parseFloat(listenFor[1]); | |
| val = parseFloat(val); | |
| checkResult = from <= val && val <= to; | |
| } else { | |
| checkResult = false; | |
| } | |
| } | |
| break; | |
| case 'one_of': | |
| if (val && val.constructor === Array) { | |
| var intersect = listenFor.filter(function (n) { | |
| return val.indexOf(n) !== -1; | |
| }); | |
| checkResult = 0 < intersect.length; | |
| } else if (!val) { | |
| checkResult = false; | |
| } else { | |
| if (listenFor.length) { | |
| checkResult = 0 <= listenFor.indexOf(val); | |
| } else { | |
| checkResult = false; | |
| } | |
| } | |
| break; | |
| case 'contain': | |
| if (val && val.constructor === Array) { | |
| var intersect = val.filter(function (n) { | |
| return n.indexOf(listenFor) !== -1; | |
| }); | |
| checkResult = 0 < intersect.length; | |
| } else if (!val) { | |
| checkResult = false; | |
| } else { | |
| checkResult = 0 <= val.indexOf(listenFor); | |
| } | |
| break; | |
| } | |
| return checkResult; | |
| }; | |
| var checkVisibilityCond = function ( | |
| listenTo, | |
| listenFor, | |
| $section, | |
| operator, | |
| type | |
| ) { | |
| var checked = $section.data('checked'); | |
| var $listenTo = $(listenTo); | |
| var checkResult = checkValue($listenTo, listenFor, operator); | |
| type = type || 'show'; | |
| if (!checked) { | |
| checked = {}; | |
| } | |
| if ('show' === type) { | |
| checked[listenTo] = checkResult; | |
| } else { | |
| checked[listenTo] = !checkResult; | |
| } | |
| $section.data('checked', checked); | |
| }; | |
| var checkSetValueCond = function ( | |
| listenTo, | |
| listenFor, | |
| $section, | |
| operator, | |
| value, | |
| type | |
| ) { | |
| var currentVal = $section.data('result_' + type); | |
| var $listenTo = $(listenTo); | |
| var checkResult = checkValue($listenTo, listenFor, operator); | |
| if (checkResult) { | |
| currentVal = value; | |
| } | |
| $section.data('result_' + type, currentVal); | |
| }; | |
| var setValue = function ($section) { | |
| var setVal = false; | |
| var setCalcVal = false; | |
| var $field; | |
| var triggered = false; | |
| if ($section.data('result_set_value')) { | |
| setVal = $section.data('result_set_value'); | |
| } | |
| if ($section.data('result_set_calculated_value')) { | |
| setCalcVal = $section.data('result_set_calculated_value'); | |
| } | |
| if (!setVal && !setCalcVal) { | |
| return; | |
| } | |
| $field = $section.find('.jet-form__field'); | |
| if (!$field.length) { | |
| return; | |
| } | |
| if ($field.is('select')) { | |
| $field.find(':selected').removeAttr('selected'); | |
| if (setVal) { | |
| $field | |
| .find('option[value="' + setVal + '"]') | |
| .attr('selected', 'selected') | |
| .trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| if (setCalcVal) { | |
| $field | |
| .find('option[data-calculate="' + setCalcVal + '"]') | |
| .attr('selected', 'selected'); | |
| if (!triggered) { | |
| $field.trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| } | |
| } else if ($field.is(':not( input[type=checkbox], input[type=radio] )')) { | |
| if (setVal) { | |
| $field.val(setVal).trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| if (setCalcVal) { | |
| $field.data('calculate', setCalcVal); | |
| if (!triggered) { | |
| $field.trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| } | |
| } else { | |
| $field.each(function () { | |
| var $this = $(this); | |
| if ($this.is(':checked')) { | |
| $this.removeAttr('checked'); | |
| } | |
| if (setVal && setVal == $this.val()) { | |
| $this.attr('checked', 'checked').trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| if (setCalcVal && setCalcVal == $this.data('calculate')) { | |
| $this.attr('checked', 'checked'); | |
| if (!triggered) { | |
| $this.trigger('change.JetEngine'); | |
| triggered = true; | |
| } | |
| } | |
| }); | |
| } | |
| }; | |
| var setVisibility = function ($section) { | |
| var checked = $section.data('checked'); | |
| var $row = $section.closest('.jet-form-row'); | |
| var res = true; | |
| if (!checked) { | |
| return; | |
| } | |
| for (var check in checked) { | |
| if (!checked[check]) { | |
| res = false; | |
| } | |
| } | |
| if (res) { | |
| $section.show(); | |
| $row.show(); | |
| $section.find('*[data-initial-type]').each(function () { | |
| var $this = $(this); | |
| $this.attr('type', $this.data('initial-type')); | |
| }); | |
| $section.find('select option[data-is-hidden="1"]').remove(); | |
| $section | |
| .find('.jet-form__fields-group input[data-is-hidden="1"]') | |
| .remove(); | |
| //$section.find( '*[data-required="1"]:not(.checkradio-field)' ).val( '' ); | |
| $section.find('.jet-form__field[data-value]').each(function () { | |
| var $this = $(this); | |
| $this.val($this.attr('data-value')); | |
| $this.removeAttr('data-value'); | |
| }); | |
| $section | |
| .find('*[data-required="1"]') | |
| .removeAttr('data-required') | |
| .attr('required', true); | |
| } else { | |
| $section.hide(); | |
| $section | |
| .find( | |
| '*[type="date"],*[type="time"],*[type="email"],*[type="url"],*[type="number"]' | |
| ) | |
| .each(function () { | |
| var $this = $(this), | |
| type = $this.attr('type'); | |
| $this.attr('data-initial-type', type); | |
| $this.attr('type', 'text'); | |
| }); | |
| var $select = $section.find('select'); | |
| var val = 'is-hidden'; | |
| if ($select.length) { | |
| var defaultVal = $select.data('default-val'); | |
| if (defaultVal || 0 === defaultVal) { | |
| val = defaultVal; | |
| } | |
| $select.append( | |
| '<option value="' + val + '" data-is-hidden="1"></option>' | |
| ); | |
| } | |
| var $checkradio = $section.find('.jet-form__field.checkradio-field'); | |
| if ($checkradio.length) { | |
| var $group = $checkradio.closest('.jet-form__fields-group'); | |
| if (!$group.find('input[data-is-hidden="1"]').length) { | |
| $group.append( | |
| '<input type="hidden" name="' + | |
| $checkradio.attr('name').replace('[]', '') + | |
| '" value="' + | |
| val + | |
| '" data-is-hidden="1">' | |
| ); | |
| } | |
| } | |
| //$section.find( '*[required="required"]:not(.checkradio-field)' ).val( val ); | |
| $section | |
| .find('.jet-form__field:not(.checkradio-field):not(.file-field)') | |
| .each(function () { | |
| var $this = $(this); | |
| if (val === $this.val()) { | |
| return; | |
| } | |
| $this.attr('data-value', $this.val()); | |
| $this.val(val); | |
| }); | |
| $section | |
| .find('*[required="required"]') | |
| .removeAttr('required') | |
| .attr('data-required', 1); | |
| // Maybe hide parent row. | |
| var $hiddenItems = $row.find('>*').filter(function () { | |
| return $(this).css('display') === 'none'; | |
| }); | |
| if ($row.find('>*').length === $hiddenItems.length) { | |
| $row.hide(); | |
| } | |
| } | |
| }; | |
| return this.each(function () { | |
| var $section = $(this); | |
| var conditions = $section.data('conditional'); | |
| if (!conditions || !conditions.length) { | |
| return; | |
| } | |
| for (var i = 0; i < conditions.length; i++) { | |
| let condition = conditions[i]; | |
| if (!condition.field) { | |
| continue; | |
| } | |
| let listenTo = | |
| '.jet-form__field[name=' + | |
| condition.field + | |
| '], .jet-form__field [name=' + | |
| condition.field + | |
| '], .jet-form__field[name=' + | |
| condition.field + | |
| '\\[\\]]'; | |
| let listenFor = condition.value; | |
| let operator = condition.operator; | |
| let type = condition.type; | |
| let valueToSet = condition.set_value; | |
| //Set up event listener | |
| $(document).on('change.JetEngine', listenTo, function () { | |
| if ('show' === type || 'hide' === type) { | |
| checkVisibilityCond(listenTo, listenFor, $section, operator, type); | |
| } else { | |
| checkSetValueCond( | |
| listenTo, | |
| listenFor, | |
| $section, | |
| operator, | |
| valueToSet, | |
| type | |
| ); | |
| } | |
| setValue($section); | |
| setVisibility($section); | |
| }); | |
| //If setting was chosen, hide everything first... | |
| if (settings.hideJS && ('show' === type || 'hide' === type)) { | |
| $section.hide(); | |
| } | |
| //Show based on current value on page load | |
| if ('show' === type || 'hide' === type) { | |
| checkVisibilityCond(listenTo, listenFor, $section, operator, type); | |
| } else { | |
| checkSetValueCond( | |
| listenTo, | |
| listenFor, | |
| $section, | |
| operator, | |
| valueToSet, | |
| type | |
| ); | |
| } | |
| } | |
| setValue($section); | |
| setVisibility($section); | |
| }); | |
| }; | |
| var JetEngineForms = { | |
| calcFields: {}, | |
| repeaterCalcFields: {}, | |
| childrenCalcFields: {}, | |
| pages: {}, | |
| init: function () { | |
| var widgets = { | |
| 'jet-engine-booking-form.default': JetEngineForms.widgetBookingForm, | |
| }; | |
| $.each(widgets, function (widget, callback) { | |
| window.elementorFrontend.hooks.addAction( | |
| 'frontend/element_ready/' + widget, | |
| callback | |
| ); | |
| }); | |
| }, | |
| commonInit: function () { | |
| var self = JetEngineForms; | |
| $(document) | |
| .on( | |
| 'click.JetEngine', | |
| '.jet-form__submit.submit-type-ajax', | |
| self.ajaxSubmitForm | |
| ) | |
| .on( | |
| 'submit.JetEngine', | |
| 'form.jet-form.submit-type-reload', | |
| self.reloadSubmitForm | |
| ) | |
| .on('click.JetEngine', '.jet-form__next-page', self.nextFormPage) | |
| .on('click.JetEngine', '.jet-form__prev-page', self.prevFormPage) | |
| .on('focus.JetEngine', '.jet-form__field', self.clearFieldErrors) | |
| .on('click.JetEngine', '.jet-form__field-template', self.simLabelClick) | |
| .on('change.JetEngine', '.jet-form__field', self.recalcFields) | |
| .on( | |
| 'jet-engine/form/repeater-changed', | |
| '.jet-form-repeater', | |
| self.recalcFields | |
| ) | |
| .on( | |
| 'change.JetEngine', | |
| '.jet-form__field.checkboxes-group-required', | |
| self.requiredCheckboxGroup | |
| ) | |
| .on( | |
| 'change.JetEngine', | |
| '.checkradio-field', | |
| self.changeActiveTemplateClass | |
| ) | |
| .on( | |
| 'input.JetEngine/range', | |
| '.jet-form__field.range-field', | |
| self.updateRangeField | |
| ) | |
| .on('click.JetEngine', '.jet-form-repeater__new', self.newRepeaterItem) | |
| .on( | |
| 'click.JetEngine', | |
| '.jet-form-repeater__remove', | |
| self.removeRepeaterItem | |
| ) | |
| .on( | |
| 'click.JetEngine', | |
| '.jet-form-repeater__remove', | |
| self.removeRepeaterItem | |
| ) | |
| // File custom mulai disini | |
| .on( | |
| 'click.JetEngine', | |
| '.jet-form-repeater__selesai', | |
| self.moveValueRepeaterItem | |
| ) | |
| // File custom berakhir disini | |
| .on( | |
| 'input.JetEngine', | |
| '.jet-form__field.text-field, .jet-form__field.textarea-field', | |
| self.inputTextFields | |
| ) | |
| .on('jet-engine/form/page/field-changed', self.maybeSwitchPage); | |
| }, | |
| initBlocks: function ($scope) { | |
| $scope = $scope || $('body'); | |
| window.JetPlugins.init($scope, [ | |
| { | |
| block: 'jet-engine/booking-form', | |
| callback: JetEngineForms.widgetBookingForm, | |
| }, | |
| ]); | |
| }, | |
| removeRepeaterItem: function () { | |
| var $this = $(this), | |
| $repeater = $this.closest('.jet-form-repeater'), | |
| $repeaterItem = $this.closest('.jet-form-repeater__row'), | |
| $editor = $repeaterItem.find('.wp-editor-area'); | |
| $this.trigger('jet-engine/form/on-remove-repeater-item'); | |
| if ($editor.length && window.wp && window.wp.editor) { | |
| $editor.each(function () { | |
| window.wp.editor.remove($(this).attr('id')); | |
| }); | |
| } | |
| $repeaterItem.remove(); | |
| $repeater.trigger('jet-engine/form/repeater-changed'); | |
| }, | |
| // File custom mulai disini | |
| moveValueRepeaterItem: function () { | |
| const row = this.closest('.jet-form-repeater__row'); | |
| const rtlInput = row.querySelector('input[data-field-name="rtl"]'); | |
| const rtlInput2 = row.querySelector('input[data-field-name="rtl_date"]'); | |
| const upayaInput = row.querySelector('input[data-field-name="upaya_yd"]'); | |
| const upayaInput2 = row.querySelector( | |
| 'input[data-field-name="upaya_yd_date"]' | |
| ); | |
| const valueToTransfer = rtlInput.value; | |
| const valueToTransfer2 = rtlInput2.value; | |
| // Get the current date in YYYY-MM-DD format | |
| const currentDate = new Date().toISOString().split('T')[0]; | |
| // Set value with small delay to ensure it takes effect | |
| setTimeout(() => { | |
| upayaInput.value = valueToTransfer; // Transfer value from rtlInput to upayaInput | |
| rtlInput.value = ''; // Clear rtlInput | |
| upayaInput2.value = currentDate; // Set upayaInput2 to the current date | |
| rtlInput2.value = ''; // Clear rtlInput2 | |
| // Trigger events | |
| upayaInput.dispatchEvent(new Event('input', { bubbles: true })); | |
| upayaInput.dispatchEvent(new Event('change', { bubbles: true })); | |
| upayaInput2.dispatchEvent(new Event('input', { bubbles: true })); | |
| upayaInput2.dispatchEvent(new Event('change', { bubbles: true })); | |
| }, 100); | |
| }, | |
| // File custom berakhir disini | |
| newRepeaterItem: function () { | |
| var $this = $(this), | |
| $repeater = $this.closest('.jet-form-repeater'), | |
| $initial = $repeater.find('.jet-form-repeater__initial'), | |
| $items = $repeater.find('.jet-form-repeater__items'), | |
| $newVal = $initial.html(), | |
| index = 0; | |
| if ($items.find('.jet-form-repeater__row').length) { | |
| $items.find('.jet-form-repeater__row').each(function () { | |
| var $this = $(this), | |
| currentIndex = parseInt($this.data('index'), 10); | |
| if (currentIndex > index) { | |
| index = currentIndex; | |
| } | |
| }); | |
| index++; | |
| } | |
| $newVal = $newVal.replace(/__i__/g, index); | |
| $newVal = $($newVal); | |
| $newVal.data('index', index); | |
| $newVal.attr('data-index', index); | |
| JetEngineForms.initRangeFields($newVal); | |
| $items.append($newVal); | |
| var $editor = $newVal.find('.wp-editor-area'); | |
| if ($editor.length && window.wp && window.wp.editor) { | |
| $editor.each(function () { | |
| JetEngineForms.wysiwygInitWithTriggers(this); | |
| }); | |
| } | |
| if ($.fn.inputmask) { | |
| $newVal.find('.jet-form__masked-field').inputmask(); | |
| } | |
| JetEngineForms.initConditions($newVal); | |
| $repeater.trigger('jet-engine/form/repeater-changed'); | |
| $this.trigger('jet-engine/form/repeater-add-new', [index]); | |
| JetEngineForms.calculateRowValue($newVal); | |
| }, | |
| updateRepeaterItems: function ($repeater, $field) { | |
| var val = JetEngineForms.getFieldValue($field); | |
| if (!val) { | |
| return; | |
| } | |
| for (var i = 0; i < val; i++) { | |
| var $item = $repeater.find( | |
| '.jet-form-repeater__row[data-index="' + i + '"]' | |
| ); | |
| if (!$item.length) { | |
| JetEngineForms.newRepeaterItem.call($repeater); | |
| } | |
| } | |
| var $rows = $repeater.find('.jet-form-repeater__row'); | |
| if ($rows.length) { | |
| $rows.each(function () { | |
| var $row = $(this), | |
| index = parseInt($row.data('index'), 10); | |
| index++; | |
| if (index > val) { | |
| $row.remove(); | |
| $repeater.trigger('jet-engine/form/repeater-changed'); | |
| } | |
| }); | |
| } | |
| $repeater.trigger('change'); | |
| }, | |
| calculateRowValue: function ($row) { | |
| var val = JetEngineForms.calculateValue($row); | |
| $row.data('value', val); | |
| JetEngineForms.calculateFieldsInRow($row); | |
| }, | |
| calculateFieldsInRow: function ($row) { | |
| $row.find('.jet-form__calculated-field--child').each(function () { | |
| var $childCalculatedField = $(this), | |
| val = JetEngineForms.calculateValue($childCalculatedField); | |
| if (!val) { | |
| val = 0; | |
| } | |
| $childCalculatedField | |
| .find('.jet-form__calculated-field-val') | |
| .text(val.toFixed($childCalculatedField.data('precision'))); | |
| $childCalculatedField | |
| .find('.jet-form__calculated-field-input') | |
| .val(val.toFixed($childCalculatedField.data('precision'))) | |
| .trigger('change.JetEngine'); | |
| }); | |
| }, | |
| initRepeaterListener: function ($scope) { | |
| var $repeater = $scope.find('.jet-form-repeater'); | |
| if (!$repeater.length) { | |
| return; | |
| } | |
| $repeater.each(function () { | |
| var $this = $(this), | |
| settings = $this.data('settings'); | |
| if ('dynamically' === settings.manageItems && settings.itemsField) { | |
| var $itemsField = $scope.find( | |
| '[data-field-name="' + settings.itemsField + '"]' | |
| ); | |
| JetEngineForms.updateRepeaterItems($this, $itemsField); | |
| $itemsField.on('change', function () { | |
| JetEngineForms.updateRepeaterItems($this, $itemsField); | |
| }); | |
| } | |
| if ('custom' === settings.calcType) { | |
| var calculated = null; | |
| JetEngineForms.repeaterCalcFields[$this.data('field-name')] = { | |
| el: $this, | |
| listenTo: $this.data('listen_fields'), | |
| }; | |
| calculated = JetEngineForms.calculateValue($this); | |
| $this.data('value', calculated.toFixed(0)); | |
| } | |
| var $initial = $this.find('.jet-form-repeater__initial'); | |
| $initial = $($initial.html()); | |
| var $calcFields = $initial.find('.jet-form__calculated-field--child'); | |
| if ($calcFields.length) { | |
| $calcFields.each(function () { | |
| var $childField = $(this); | |
| JetEngineForms.childrenCalcFields[$childField.data('name')] = { | |
| el: $childField, | |
| parentEl: $this, | |
| listenTo: $childField.data('listen_to'), | |
| }; | |
| $this.find('.jet-form-repeater__row').each(function () { | |
| JetEngineForms.calculateRowValue( | |
| $(this), | |
| $childField.data('precision') | |
| ); | |
| }); | |
| }); | |
| } | |
| }); | |
| }, | |
| simLabelClick: function (event) { | |
| $(this).next('.jet-form__field-label').trigger('click'); | |
| }, | |
| maybeSwitchPage: function (event, $field, $page, disabled) { | |
| var $item = $field[0], | |
| isSwitch = $field.data('switch'), | |
| value = null, | |
| $toPage = null; | |
| if (!isSwitch) { | |
| return; | |
| } | |
| if (disabled) { | |
| return; | |
| } | |
| value = $item.value; | |
| if (!value) { | |
| return; | |
| } | |
| $toPage = $page.next(); | |
| if (!$page || !$page.length) { | |
| return; | |
| } | |
| if (!$toPage || !$toPage.length) { | |
| return; | |
| } | |
| JetEngineForms.switchFormPage($page, $toPage); | |
| }, | |
| changeActiveTemplateClass: function (event) { | |
| var $this = $(this), | |
| $template = $this | |
| .closest('.jet-form__field-wrap') | |
| .find('.jet-form__field-template'); | |
| if (!$template.length) { | |
| return; | |
| } | |
| if ('radio' === $this[0].type) { | |
| $template | |
| .closest('.jet-form__fields-group') | |
| .find('.jet-form__field-template--checked') | |
| .removeClass('jet-form__field-template--checked'); | |
| } | |
| $template.toggleClass( | |
| 'jet-form__field-template--checked', | |
| $this[0].checked | |
| ); | |
| }, | |
| initConditions: function ($scope) { | |
| $scope.find('.jet-form-col').jetFormConditional(); | |
| }, | |
| widgetBookingForm: function ($scope) { | |
| var $calcFields = $scope.find('.jet-form__calculated-field'); | |
| var $editor = $scope.find('.jet-form__field .wp-editor-area'); | |
| if ($editor.length && window.wp && window.wp.editor) { | |
| $editor.each(function () { | |
| JetEngineForms.wysiwygInitWithTriggers(this, true); | |
| }); | |
| } | |
| JetEngineForms.initRequiredCheckboxGroup($scope); | |
| $(document).trigger('jet-engine/booking-form/init', [$scope]); | |
| JetEngineForms.initFormPager($scope); | |
| JetEngineForms.initRangeFields($scope); | |
| JetEngineForms.initRepeaterListener($scope); | |
| JetEngineForms.initConditions($scope); | |
| if ($.fn.inputmask) { | |
| $scope.find('.jet-form__masked-field').inputmask(); | |
| } | |
| if (!$calcFields.length) { | |
| return; | |
| } | |
| $calcFields.each(function () { | |
| var $this = $(this), | |
| calculated = null; | |
| JetEngineForms.calcFields[$this.data('name')] = { | |
| el: $this, | |
| listenTo: $this.data('listen_to'), | |
| }; | |
| calculated = JetEngineForms.calculateValue($this); | |
| $this | |
| .find('.jet-form__calculated-field-val') | |
| .text(calculated.toFixed($this.data('precision'))); | |
| $this | |
| .find('.jet-form__calculated-field-input') | |
| .val(calculated.toFixed($this.data('precision'))) | |
| .trigger('change.JetEngine'); | |
| }); | |
| }, | |
| initFormPager: function ($scope) { | |
| var $pages = $scope.find('.jet-form-page'), | |
| $form = $scope.find('.jet-form'); | |
| if (!$pages.length) { | |
| return; | |
| } | |
| $pages.each(function () { | |
| var $page = $(this); | |
| if (!$page.hasClass('.jet-form-page--hidden')) { | |
| JetEngineForms.initSingleFormPage($page, $form, false); | |
| } | |
| }); | |
| }, | |
| initSingleFormPage: function ($page, $form, $changedField) { | |
| var $button = $page.find('.jet-form__next-page'), | |
| $msg = $page.find('.jet-form__next-page-msg'), | |
| requiredFields = $page[0].querySelectorAll( | |
| '.jet-form__field[required]' | |
| ), | |
| pageNum = parseInt($page.data('page'), 10), | |
| disabled = false, | |
| radioFields = {}; | |
| $changedField = $changedField || false; | |
| if (requiredFields.length) { | |
| for (var i = 0; i < requiredFields.length; i++) { | |
| var $field = $(requiredFields[i]); | |
| var val = null; | |
| var isRadio = false; | |
| if ('INPUT' === $field[0].nodeName) { | |
| if ($field.length > 1) { | |
| for (var j = 0; j < $field.length; j++) { | |
| if ($field[j].checked) { | |
| val = $field[j].value; | |
| } | |
| } | |
| } else if ('radio' === $field[0].type) { | |
| isRadio = true; | |
| if ($field[0].checked) { | |
| radioFields[$field[0].name] = $field[0].value; | |
| } | |
| } else { | |
| val = $field.val(); | |
| } | |
| } | |
| if ('TEXTAREA' === $field[0].nodeName) { | |
| val = $field.val(); | |
| } | |
| if ('SELECT' === $field[0].nodeName) { | |
| val = $field.find('option:selected').val(); | |
| } | |
| if (!val) { | |
| disabled = true; | |
| } | |
| if (isRadio && radioFields[$field[0].name]) { | |
| disabled = false; | |
| } | |
| } | |
| } | |
| if (disabled) { | |
| if ($msg.length) { | |
| $msg.addClass('jet-form__next-page-msg--visible'); | |
| } | |
| $button.attr('disabled', true); | |
| } else { | |
| if ($msg.length) { | |
| $msg.removeClass('jet-form__next-page-msg--visible'); | |
| } | |
| $button.attr('disabled', false); | |
| } | |
| if (!JetEngineForms.pages[pageNum]) { | |
| JetEngineForms.pages[pageNum] = { | |
| page: $page, | |
| disabled: disabled, | |
| }; | |
| } else { | |
| JetEngineForms.pages[pageNum].disabled = disabled; | |
| } | |
| if ($changedField) { | |
| $(document).trigger('jet-engine/form/page/field-changed', [ | |
| $changedField, | |
| $page, | |
| disabled, | |
| ]); | |
| } | |
| if ($page.hasClass('jet-form-page--initialized')) { | |
| return; | |
| } | |
| $page.on('change.JetEngine', '.jet-form__field', function () { | |
| JetEngineForms.initSingleFormPage($page, $form, $(this)); | |
| }); | |
| $page.addClass('jet-form-page--initialized'); | |
| }, | |
| nextFormPage: function () { | |
| var $button = $(this), | |
| $fromPage = $button.closest('.jet-form-page'), | |
| $pageFields = $fromPage.find('.jet-form__field').filter(':input'), | |
| $toPage = $fromPage.next(); | |
| if (!JetEngineForms.isFieldsValid($pageFields)) { | |
| return; | |
| } | |
| JetEngineForms.switchFormPage($fromPage, $toPage); | |
| }, | |
| prevFormPage: function () { | |
| var $button = $(this), | |
| $fromPage = $button.closest('.jet-form-page'), | |
| $toPage = $fromPage.prev(); | |
| JetEngineForms.switchFormPage($fromPage, $toPage); | |
| }, | |
| isFieldsValid: function ($fields) { | |
| var isValid = true; | |
| $fields.each(function (ind, field) { | |
| if (!field.checkValidity()) { | |
| field.reportValidity(); | |
| isValid = false; | |
| return false; | |
| } | |
| }); | |
| return isValid; | |
| }, | |
| switchFormPage: function ($fromPage, $toPage) { | |
| var $form = $fromPage.closest('.jet-form'); | |
| $fromPage.addClass('jet-form-page--hidden'); | |
| $toPage.removeClass('jet-form-page--hidden'); | |
| JetEngineForms.initSingleFormPage($toPage, $form, false); | |
| $(document).trigger('jet-engine/form/switch-page', [$fromPage, $toPage]); | |
| $( | |
| '.jet-form-messages-wrap[data-form-id="' + $form.data('form-id') + '"]' | |
| ).html(''); | |
| }, | |
| getFieldValue: function ($field) { | |
| var val = 0; | |
| if ($field.length) { | |
| if ('INPUT' === $field[0].nodeName) { | |
| if ($field.length > 1) { | |
| for (var i = 0; i < $field.length; i++) { | |
| if ($field[i].checked) { | |
| var itemVal = 0; | |
| if (undefined !== $field[i].dataset.calculate) { | |
| itemVal = $field[i].dataset.calculate; | |
| } else { | |
| itemVal = $field[i].value; | |
| } | |
| if ('checkbox' === $field[i].type) { | |
| val += parseInt(itemVal, 10); | |
| } else { | |
| val = itemVal; | |
| } | |
| } | |
| } | |
| } else { | |
| if ('checkbox' === $field[0].type) { | |
| if ($field[0].checked) { | |
| if (undefined !== $field[0].dataset.calculate) { | |
| val = $field[0].dataset.calculate; | |
| } else { | |
| val = $field[0].value; | |
| } | |
| } | |
| } else { | |
| val = $field.val(); | |
| } | |
| } | |
| } | |
| if ('SELECT' === $field[0].nodeName) { | |
| var selectedOption = $field.find('option:selected'), | |
| calcValue = selectedOption.data('calculate'); | |
| if (undefined !== calcValue) { | |
| val = calcValue; | |
| } else { | |
| val = $field.find('option:selected').val(); | |
| } | |
| } | |
| if ('DIV' === $field[0].nodeName) { | |
| if ($field.hasClass('jet-form-repeater')) { | |
| var repeaterSettings = $field.data('settings'); | |
| if (repeaterSettings && 'custom' === repeaterSettings.calcType) { | |
| $field.find('.jet-form-repeater__row').each(function () { | |
| var $row = $(this), | |
| rowVal = JetEngineForms.calculateValue($row); | |
| $row.data('value', rowVal); | |
| val += rowVal; | |
| }); | |
| } else { | |
| val = $field.find('.jet-form-repeater__row').length; | |
| } | |
| } | |
| } | |
| } | |
| if (!val) { | |
| val = '0'; | |
| } | |
| val = JetEngine.filters.applyFilters( | |
| 'forms/calculated-field-value', | |
| val, | |
| $field | |
| ); | |
| return val; | |
| }, | |
| calculateValue: function ($scope) { | |
| var formula = String($scope.data('formula')), | |
| listenTo = $( | |
| '[name^="' + $scope.data('listen_to') + '"]', | |
| $scope.closest('form') | |
| ), | |
| regexp = /%([a-zA-Z0-9-_]+)%/g, | |
| func = null; | |
| if (!formula) { | |
| return null; | |
| } | |
| formula = JetEngine.filters.applyFilters( | |
| 'forms/calculated-formula-before-value', | |
| formula, | |
| $scope | |
| ); | |
| formula = formula.replace(regexp, function (match1, match2) { | |
| var object = null; | |
| if ($scope.data('repeater')) { | |
| object = $scope; | |
| } else if ($scope.hasClass('jet-form__calculated-field--child')) { | |
| object = $scope | |
| .closest('.jet-form-repeater__row') | |
| .find('[data-field-name="' + match2 + '"]'); | |
| } else if ($scope.data('repeater-row')) { | |
| object = $scope.find('[data-field-name="' + match2 + '"]'); | |
| } else { | |
| object = $scope | |
| .closest('form') | |
| .find('[name="' + match2 + '"], [name="' + match2 + '[]"]'); | |
| } | |
| return JetEngineForms.getFieldValue(object); | |
| }); | |
| formula = JetEngine.filters.applyFilters( | |
| 'forms/calculated-formula-after-value', | |
| formula, | |
| $scope | |
| ); | |
| func = new Function('return ' + formula); | |
| return func(); | |
| }, | |
| recalcFields: function (event) { | |
| var $this = $(this), | |
| fieldName = $this.attr('name'), | |
| fieldPrecision = 2, | |
| calculated = null, | |
| done = false; | |
| if ($this.data('field-name')) { | |
| fieldName = $this.data('field-name'); | |
| } | |
| if (!fieldName) { | |
| return; | |
| } | |
| $.each(JetEngineForms.calcFields, function (calcFieldName, field) { | |
| fieldName = fieldName.replace('[]', ''); | |
| if (0 <= $.inArray(fieldName, field.listenTo)) { | |
| calculated = JetEngineForms.calculateValue(field.el); | |
| fieldPrecision = field.el.data('precision'); | |
| field.el | |
| .find('.jet-form__calculated-field-val') | |
| .text(calculated.toFixed(fieldPrecision)); | |
| field.el | |
| .find('.jet-form__calculated-field-input') | |
| .val(calculated.toFixed(fieldPrecision)) | |
| .trigger('change.JetEngine'); | |
| } | |
| }); | |
| if ('jet-engine/form/repeater-changed' !== event.type) { | |
| $.each( | |
| JetEngineForms.repeaterCalcFields, | |
| function (calcFieldName, field) { | |
| fieldName = fieldName.replace('[]', ''); | |
| if (0 <= $.inArray(fieldName, field.listenTo)) { | |
| field.el.trigger('jet-engine/form/repeater-changed'); | |
| } | |
| } | |
| ); | |
| } | |
| $.each( | |
| JetEngineForms.childrenCalcFields, | |
| function (calcFieldName, field) { | |
| fieldName = fieldName.replace('[]', ''); | |
| if (0 <= $.inArray(fieldName, field.listenTo)) { | |
| var $row = $this.closest('.jet-form-repeater__row'); | |
| JetEngineForms.calculateFieldsInRow($row); | |
| } | |
| } | |
| ); | |
| }, | |
| initRequiredCheckboxGroup: function ($scope) { | |
| var $group = $scope.find('.jet-form__fields-group'); | |
| $group.each(function () { | |
| var $this = $(this), | |
| $checkboxes = $('.checkboxes-group-required', $this); | |
| if ($checkboxes.length) { | |
| var isChecked = $checkboxes.is(':checked'); | |
| $checkboxes.attr('required', !isChecked); | |
| } | |
| }); | |
| }, | |
| requiredCheckboxGroup: function (event) { | |
| var $this = $(event.target), | |
| $group = $this.closest('.jet-form__fields-group'), | |
| $checkboxes = $('.checkboxes-field', $group); | |
| if ($checkboxes.length < 2) { | |
| return; | |
| } | |
| var isChecked = $checkboxes.is(':checked'); | |
| $checkboxes.attr('required', !isChecked); | |
| }, | |
| initRangeFields: function ($scope) { | |
| var $rangeFields = $scope.find('.jet-form__field.range-field'); | |
| if (!$rangeFields.length) { | |
| return; | |
| } | |
| $rangeFields.each(function () { | |
| JetEngineForms.updateRangeField({ target: $(this), firstInit: true }); | |
| }); | |
| }, | |
| updateRangeField: function (event) { | |
| var $target = $(event.target), | |
| $wrap = $target.closest('.jet-form__field-wrap'), | |
| $number = $wrap.find('.jet-form__field-value-number'), | |
| max = $target.attr('max') || 100, | |
| val = $target.val(), | |
| isElemEditMode = window.elementorFrontend | |
| ? window.elementorFrontend.isEditMode() | |
| : false; | |
| if (event.firstInit && !isElemEditMode) { | |
| $number.text(max).css('min-width', $number.width()); | |
| } | |
| $number.text(val); | |
| }, | |
| inputTextFields: function () { | |
| $(this).trigger('change.JetEngine'); | |
| }, | |
| reloadSubmitForm: function (event) { | |
| var $maskedFields = $(event.target).find('.jet-form__masked-field'); | |
| if ($maskedFields.length) { | |
| $maskedFields.each(function () { | |
| var $maskedField = $(this); | |
| // Remove mask if empty value | |
| if (!$maskedField.val() && $maskedField.inputmask) { | |
| $maskedField.inputmask('remove'); | |
| } | |
| }); | |
| } | |
| $(this).find('.jet-form__submit').attr('disabled', true); | |
| }, | |
| ajaxSubmitForm: function () { | |
| var $this = $(this), | |
| $form = $this.closest('.jet-form'), | |
| formID = $form.data('form-id'), | |
| data = { | |
| action: 'jet_engine_form_booking_submit', | |
| }; | |
| if ( | |
| 'undefined' !== typeof $form[0].checkValidity && | |
| 'undefined' !== typeof $form[0].reportValidity && | |
| !$form[0].checkValidity() | |
| ) { | |
| $form[0].reportValidity(); | |
| return; | |
| } | |
| if (window.tinyMCE) { | |
| window.tinyMCE.triggerSave(); | |
| } | |
| data.values = $form.serializeArray(); | |
| data._jet_engine_booking_form_id = formID; | |
| $form.addClass('is-loading'); | |
| $this.attr('disabled', true); | |
| $('.jet-form-messages-wrap[data-form-id="' + formID + '"]').html(''); | |
| $form.find('.jet-form__field-error').remove(); | |
| $.ajax({ | |
| url: JetEngineSettings.ajaxurl, | |
| type: 'POST', | |
| dataType: 'json', | |
| data: data, | |
| }).done(function (response) { | |
| $form.removeClass('is-loading'); | |
| $this.attr('disabled', false); | |
| switch (response.status) { | |
| case 'validation_failed': | |
| $.each(response.fields, function (index, fieldName) { | |
| var $field = $form.find( | |
| '.jet-form__field[name="' + fieldName + '"]:last' | |
| ); | |
| if ($field.hasClass('checkradio-field')) { | |
| $field | |
| .closest('.jet-form__field-wrap') | |
| .after(response.field_message); | |
| } else { | |
| $field.after(response.field_message); | |
| } | |
| }); | |
| break; | |
| case 'success': | |
| $(document).trigger('jet-engine/form/ajax/on-success', [ | |
| response, | |
| $form, | |
| data, | |
| ]); | |
| break; | |
| } | |
| if (response.redirect) { | |
| window.location = response.redirect; | |
| } else if (response.reload) { | |
| window.location.reload(); | |
| } | |
| $('.jet-form-messages-wrap[data-form-id="' + formID + '"]').html( | |
| response.message | |
| ); | |
| }); | |
| }, | |
| clearFieldErrors: function () { | |
| var $this = $(this), | |
| formID = $this.closest('.jet-form').data('form-id'); | |
| $this.closest('.jet-form-col').find('.jet-form__field-error').remove(); | |
| $('.jet-form-messages-wrap[data-form-id="' + formID + '"]').html(''); | |
| }, | |
| addTriggersWysiwyg: function (field, editorId) { | |
| const callable = function (e) { | |
| this.save(); | |
| field.trigger('change.JetEngine', [this]); | |
| }; | |
| setTimeout(function () { | |
| const editor = tinymce.get(editorId); | |
| if (!editor) { | |
| return; | |
| } | |
| editor.on('input', callable).on('change', callable); | |
| }); | |
| }, | |
| wysiwygInit: function (closure, replace = false) { | |
| const self = $(closure), | |
| editorID = self.attr('id'), | |
| field = self.closest('.jet-form__field'); | |
| if (replace && window.tinymce && window.tinymce.get(editorID)) { | |
| window.tinymce.get(editorID).remove(); | |
| } | |
| window.wp.editor.initialize(editorID, field.data('editor')); | |
| return { editorID, field: self }; | |
| }, | |
| wysiwygInitWithTriggers: function (closure, replace = false) { | |
| const { editorID, field } = JetEngineForms.wysiwygInit(closure, replace); | |
| JetEngineForms.addTriggersWysiwyg(field, editorID); | |
| }, | |
| }; | |
| $(window).on('elementor/frontend/init', JetEngineForms.init); | |
| window.addEventListener('DOMContentLoaded', function () { | |
| JetEngineForms.initBlocks(); | |
| }); | |
| window.JetEngineForms = JetEngineForms; | |
| JetEngineForms.commonInit(); | |
| })(jQuery); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment