may show per-row Save UI (save_ui: always|when_changed) * - scope=form -> saved only via "Save Form" (settings_json: {"options":{key:value}}) * - scope=ui -> UI-only (no DB save) * * Args shape: * array( * 'type' => 'toggle'|'select'|'radio'|'length'|'range'|'input'|'textarea', * 'key' => 'booking_timeslot_picker', * 'scope' => 'global'|'form'|'ui', * 'save_ui' => 'always'|'when_changed', // only for scope=global * 'default' => 'On', // initial value for control * 'label' => __( '...', 'booking' ), * 'help' => __( '...', 'booking' ), * 'attr' => array( 'id' => '...', 'class' => '...' ), * * // select/radio * 'options' => array( 'value' => 'Label', ... ), * 'radio_layout' => 'inline'|'stack', * * // input * 'input_type' => 'text'|'number'|..., * 'input_attrs' => array( 'placeholder' => '...', ... ), * * // length * 'length' => array( * 'default_unit' => '%', * 'units' => array( '%' => '%', 'px' => 'px', ... ), * 'bounds_map' => array( '%' => array('min'=>30,'max'=>100,'step'=>1), ... ), // optional * ), * * // range (slider number) * 'range' => array( * 'min' => 0, * 'max' => 100, * 'step' => 1, * ), * ) * * @package Booking Calendar * @since 11.0.x * @file ../includes/page-form-builder/form-settings/options-render.php */ if ( ! defined( 'ABSPATH' ) ) { exit; } class WPBC_BFB_Setting_Options { /** * Print one option row. * * @param array $args */ public static function print_option( $args ) { if ( ! is_array( $args ) ) { return; } $type = isset( $args['type'] ) ? (string) $args['type'] : 'input'; $key = isset( $args['key'] ) ? (string) $args['key'] : ''; $scope = isset( $args['scope'] ) ? (string) $args['scope'] : 'ui'; $save_ui = isset( $args['save_ui'] ) ? (string) $args['save_ui'] : 'when_changed'; if ( '' === $key ) { return; } $label = isset( $args['label'] ) ? (string) $args['label'] : ''; $help = isset( $args['help'] ) ? (string) $args['help'] : ''; $attr = ( isset( $args['attr'] ) && is_array( $args['attr'] ) ) ? $args['attr'] : array(); $id = isset( $attr['id'] ) ? (string) $attr['id'] : 'wpbc_bfb_setting__' . sanitize_html_class( $key ); $default_value = isset( $args['default'] ) ? $args['default'] : ''; // Wrapper classes. $row_class = 'wpbc_bfb__form_setting wpbc-setting'; ?>

/>
$key, 'data-wpbc-bfb-fs-scope' => $scope, 'data-wpbc-bfb-fs-type' => 'radio', 'data-wpbc-bfb-fs-initial' => $v, 'data-wpbc-bfb-fs-controlid' => $id, ); $wrap_attr_str = self::build_attr_string( $wrap_attr ); ?>
>
$opt_label ) : $i++; $rid = $id . '__' . $i; ?>
... *
*
* * *
*
*/ private static function print_range( $id, $key, $scope, $label, $value, $range, $attr, $css_class ) { $min = isset( $range['min'] ) ? (float) $range['min'] : 0; $max = isset( $range['max'] ) ? (float) $range['max'] : 100; $step = isset( $range['step'] ) ? (float) $range['step'] : 1; $v = is_scalar( $value ) ? (string) $value : ''; if ( '' === trim( $v ) ) { $v = (string) $min; } // Clamp numeric value. if ( is_numeric( $v ) ) { $n = (float) $v; if ( $n < $min ) { $n = $min; } if ( $n > $max ) { $n = $max; } // Keep formatting simple. $v = (string) $n; } // Number input = writer (id stays here, Save UI reads #id). // Keep FS type as "input" for compatibility with existing apply/collect code. $num_attr = self::with_common_fs_data( $attr, $key, $scope, 'input', $v ); $num_attr['data-wpbc-bfb-fs-type'] = 'input'; $num_attr['data-wpbc_slider_range_value'] = '1'; $num_attr['data-wpbc_slider_range_writer'] = '1'; // Ensure the number input keeps the $id. $num_attr['id'] = $id; $num_attr_str = self::build_attr_string( $num_attr ); // Number input CSS (adds width helper). $num_class = trim( $css_class . ' inspector__w_30' ); ?>
/>
'%' ); $default_unit = isset( $length['default_unit'] ) ? (string) $length['default_unit'] : '%'; $bounds_map = ( isset( $length['bounds_map'] ) && is_array( $length['bounds_map'] ) ) ? $length['bounds_map'] : array(); $raw = is_scalar( $value ) ? trim( (string) $value ) : ''; $num = ''; $unit = ''; if ( preg_match( '/^\s*([\-]?\d+(?:\.\d+)?)\s*([a-z%]*)\s*$/i', $raw, $m ) ) { $num = isset( $m[1] ) ? (string) $m[1] : ''; $unit = isset( $m[2] ) ? (string) $m[2] : ''; } if ( '' === $unit ) { $unit = $default_unit; } if ( '' === $num && '' !== $raw ) { $num = $raw; } // Ensure unit exists in list. if ( ! isset( $units[ $unit ] ) ) { $unit = $default_unit; } // Bounds for current unit. $bounds = array(); if ( isset( $bounds_map[ $unit ] ) && is_array( $bounds_map[ $unit ] ) ) { $bounds = $bounds_map[ $unit ]; } elseif ( isset( $bounds_map[ $default_unit ] ) && is_array( $bounds_map[ $default_unit ] ) ) { $bounds = $bounds_map[ $default_unit ]; } $min = isset( $bounds['min'] ) ? (float) $bounds['min'] : 0; $max = isset( $bounds['max'] ) ? (float) $bounds['max'] : 128; $step = isset( $bounds['step'] ) ? (float) $bounds['step'] : 1; // Clamp numeric value to bounds when it is numeric. if ( '' !== $num && is_numeric( $num ) ) { $n = (float) $num; if ( $n < $min ) { $n = $min; } if ( $n > $max ) { $n = $max; } $num = (string) $n; } $combined = ( '' === $num ) ? '' : ( $num . $unit ); // Writer input (main value) must have the FS markers + special type="length". // Add the new strict writer marker for wpbc_slider_len_groups.js $writer_attr = self::with_common_fs_data( array( 'id' => $id ), $key, $scope, 'length', $combined ); $writer_attr['data-wpbc-bfb-fs-type'] = 'length'; $writer_attr['data-wpbc_slider_len_writer'] = '1'; $writer_attr_str = self::build_attr_string( $writer_attr ); // Bounds JSON for JS. $bounds_json = ( ! empty( $bounds_map ) ) ? wp_json_encode( $bounds_map ) : ''; ?>
data-wpbc_slider_len_bounds_map="" >
/>
$v ) { if ( ! is_scalar( $k ) || '' === trim( (string) $k ) ) { continue; } $attr_key = strtolower( trim( (string) $k ) ); // Block inline handlers. if ( 0 === strpos( $attr_key, 'on' ) ) { continue; } if ( null === $v ) { continue; } $out .= ' ' . esc_attr( $attr_key ) . '="' . esc_attr( (string) $v ) . '"'; } return $out; } }