Hotel Raxa - Advanced Booking System Implementation
🏨 Hotel Booking Enhancements: - Implemented Eagle Booking Advanced Pricing add-on - Added Booking.com-style rate management system - Created professional calendar interface for pricing - Integrated deals and discounts functionality 💰 Advanced Pricing Features: - Dynamic pricing models (per room, per person, per adult) - Base rates, adult rates, and child rates management - Length of stay discounts and early bird deals - Mobile rates and secret deals implementation - Seasonal promotions and flash sales 📅 Availability Management: - Real-time availability tracking - Stop sell and restriction controls - Closed to arrival/departure functionality - Minimum/maximum stay requirements - Automatic sold-out management 💳 Payment Integration: - Maintained Redsys payment gateway integration - Seamless integration with existing Eagle Booking - No modifications to core Eagle Booking plugin 🛠️ Technical Implementation: - Custom database tables for advanced pricing - WordPress hooks and filters integration - AJAX-powered admin interface - Data migration from existing Eagle Booking - Professional calendar view for revenue management 📊 Admin Interface: - Booking.com-style management dashboard - Visual rate and availability calendar - Bulk operations for date ranges - Statistics and analytics dashboard - Modal dialogs for quick editing 🔧 Code Quality: - WordPress coding standards compliance - Secure database operations with prepared statements - Proper input validation and sanitization - Error handling and logging - Responsive admin interface 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Repeater Extension Class
|
||||
*
|
||||
* @package Redux
|
||||
* @author Dovy Paukstys & Kevin Provance <kevin.provance@gmail.com>
|
||||
* @class Redux_Extension_Repeater
|
||||
*
|
||||
* @version 4.3.13
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Extension_Repeater' ) ) {
|
||||
|
||||
|
||||
/**
|
||||
* Class Redux_Extension_Repeater
|
||||
*/
|
||||
class Redux_Extension_Repeater extends Redux_Extension_Abstract {
|
||||
|
||||
/**
|
||||
* Extension version.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public static $version = '4.3.13';
|
||||
|
||||
/**
|
||||
* Extension friendly name.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $extension_name = 'Repeater';
|
||||
|
||||
/**
|
||||
* Class Constructor. Defines the args for the extensions class
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
*
|
||||
* @param object $redux Parent settings.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $redux ) {
|
||||
parent::__construct( $redux, __FILE__ );
|
||||
|
||||
$this->add_field( 'repeater' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class_alias( 'Redux_Extension_Repeater', 'ReduxFramework_Extension_repeater' );
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,451 @@
|
||||
<?php
|
||||
/**
|
||||
* Redux Repeater Field Class
|
||||
*
|
||||
* @package Redux
|
||||
* @author Dovy Paukstys & Kevin Provance <kevin.provance@gmail.com>
|
||||
* @class Redux_Repeater
|
||||
*/
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
// Don't duplicate me!
|
||||
if ( ! class_exists( 'Redux_Repeater' ) ) {
|
||||
|
||||
/**
|
||||
* Class Redux_Repeater
|
||||
*/
|
||||
class Redux_Repeater extends Redux_Field {
|
||||
|
||||
/**
|
||||
* Repeater values.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $repeater_values;
|
||||
|
||||
/**
|
||||
* Set defaults.
|
||||
*/
|
||||
public function set_defaults() {
|
||||
$this->repeater_values = '';
|
||||
|
||||
if ( ! isset( $this->field['bind_title'] ) && ! empty( $this->field['fields'] ) ) {
|
||||
$this->field['bind_title'] = $this->field['fields'][0]['id'];
|
||||
}
|
||||
|
||||
$default = array(
|
||||
'group_values' => false,
|
||||
'item_name' => '',
|
||||
'bind_title' => true,
|
||||
'sortable' => true,
|
||||
'limit' => 10,
|
||||
'init_empty' => false,
|
||||
'panels_closed' => false,
|
||||
);
|
||||
|
||||
$this->field = wp_parse_args( $this->field, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Field Render Function.
|
||||
* Takes the vars and outputs the HTML for the field in the settings
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function render() {
|
||||
$unallowed = array( 'tabbed', 'social_profiles', 'color_scheme', 'repeater' );
|
||||
|
||||
if ( isset( $this->field['group_values'] ) && $this->field['group_values'] ) {
|
||||
$this->repeater_values = '[' . $this->field['id'] . ']';
|
||||
}
|
||||
|
||||
if ( false === $this->field['init_empty'] ) {
|
||||
$title = '';
|
||||
|
||||
if ( empty( $this->value ) || ! is_array( $this->value ) ) {
|
||||
$this->value = array(
|
||||
'redux_repeater_data' => array(
|
||||
array(
|
||||
'title' => $title,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $this->field['subfields'] ) && empty( $this->field['fields'] ) ) {
|
||||
$this->field['fields'] = $this->field['subfields'];
|
||||
unset( $this->field['subfields'] );
|
||||
}
|
||||
|
||||
echo '<div class="redux-repeater-accordion" data-id="' . esc_attr( $this->field['id'] ) . '" data-panels-closed="' . esc_attr( $this->field['panels_closed'] ) . '">';
|
||||
|
||||
$x = 0;
|
||||
|
||||
if ( isset( $this->value['redux_repeater_data'] ) && is_array( $this->value['redux_repeater_data'] ) && ! empty( $this->value['redux_repeater_data'] ) ) {
|
||||
$repeaters = $this->value['redux_repeater_data'];
|
||||
|
||||
if ( '' === $this->field['bind_title'] ) {
|
||||
$keys = array_keys( min( $repeaters ) );
|
||||
$this->field['bind_title'] = $keys[0];
|
||||
}
|
||||
foreach ( $repeaters as $repeater ) {
|
||||
if ( empty( $repeater ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
echo '<div class="redux-repeater-accordion-repeater" data-sortid="' . esc_attr( $x ) . '">';
|
||||
echo '<table style="margin-top: 0;" class="redux-repeater-accordion redux-repeater form-table no-border">';
|
||||
echo '<fieldset class="redux-field " data-id="' . esc_attr( $this->field['id'] ) . '">';
|
||||
|
||||
echo '<input type="hidden" name="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][redux_repeater_data][' . esc_attr( $x ) . '][title]" value="' . esc_attr( $repeater['title'] ) . '" class="regular-text slide-title" data-key="' . esc_attr( $x ) . '" />';
|
||||
|
||||
if ( isset( $this->field['bind_title'] ) ) {
|
||||
foreach ( $this->field['fields'] as $field ) {
|
||||
if ( $field['id'] === $this->field['bind_title'] ) {
|
||||
if ( isset( $field['options'] ) ) {
|
||||
|
||||
// Sorter data filter.
|
||||
if ( 'sorter' === $field['type'] && ! empty( $field['data'] ) && is_array( $field['data'] ) ) {
|
||||
if ( ! isset( $field['args'] ) ) {
|
||||
$field['args'] = array();
|
||||
}
|
||||
|
||||
foreach ( $field['data'] as $key => $data ) {
|
||||
if ( ! isset( $field['args'][ $key ] ) ) {
|
||||
$field['args'][ $key ] = array();
|
||||
}
|
||||
|
||||
$field['options'][ $key ] = $this->parent->get_wordpress_data( $data, $field['args'][ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$default = $field['default'] ?? '';
|
||||
|
||||
if ( ! empty( $this->repeater_values ) ) {
|
||||
$repeater['title'] = ! isset( $this->parent->options[ $this->field['id'] ][ $field['id'] ][ $x ] ) ? $default : $this->parent->options[ $this->field['id'] ][ $field['id'] ][ $x ];
|
||||
} else {
|
||||
$repeater['title'] = ! isset( $this->parent->options[ $field['id'] ][ $x ] ) ? $default : $this->parent->options[ $field['id'] ][ $x ];
|
||||
}
|
||||
|
||||
if ( isset( $field['options'] ) && is_array( $field['options'] ) ) {
|
||||
if ( isset( $field['options'][ $repeater['title'] ] ) ) {
|
||||
$repeater['title'] = $field['options'][ $repeater['title'] ];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( is_array( $repeater['title'] ) ) {
|
||||
$repeater['title'] = esc_html__( 'Title', 'redux-framework' );
|
||||
}
|
||||
|
||||
echo '<h3><span class="redux-repeater-header">' . esc_html( $repeater['title'] ) . ' </span></h3>';
|
||||
|
||||
echo '<div>';
|
||||
|
||||
foreach ( $this->field['fields'] as $field ) {
|
||||
if ( ! isset( $field['class'] ) ) {
|
||||
$field['class'] = '';
|
||||
}
|
||||
|
||||
if ( isset( $this->field['bind_title'] ) && $field['id'] === $this->field['bind_title'] ) {
|
||||
$field['class'] .= ' bind_title';
|
||||
}
|
||||
|
||||
if ( in_array( $field['type'], $unallowed, true ) ) {
|
||||
echo esc_html__( 'The', 'redux-framework' ) . ' <code>' . esc_html( $field['type'] ) . '</code> ' . esc_html__( 'field is not supported within the Repeater field.', 'redux-framework' );
|
||||
} else {
|
||||
$this->output_field( $field, $x );
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! isset( $this->field['static'] ) && empty( $this->field['static'] ) ) {
|
||||
echo '<a href="javascript:void(0);" class="button deletion redux-warning-primary redux-repeaters-remove">' . esc_html__( 'Delete', 'redux-framework' ) . ' ' . esc_html( $this->field['item_name'] ) . '</a>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
echo '</fieldset>';
|
||||
echo '</table>';
|
||||
echo '</div>';
|
||||
|
||||
++$x;
|
||||
}
|
||||
}
|
||||
|
||||
if ( 0 === $x || ( isset( $this->field['static'] ) && ( $x - 1 ) < $this->field['static'] ) ) {
|
||||
if ( isset( $this->field['static'] ) && $x < $this->field['static'] ) {
|
||||
$loop = $this->field['static'] - $x;
|
||||
} else {
|
||||
$loop = 1;
|
||||
}
|
||||
|
||||
$class = '';
|
||||
|
||||
if ( 0 === $x && true === $this->field['init_empty'] ) {
|
||||
$class = 'close-me';
|
||||
}
|
||||
|
||||
while ( $loop > 0 ) {
|
||||
echo '<div class="redux-repeater-accordion-repeater ' . esc_attr( $class ) . '">';
|
||||
echo '<table style="margin-top: 0;" class="redux-repeater-accordion redux-repeater form-table no-border">';
|
||||
echo '<fieldset class="redux-field" data-id="' . esc_attr( $this->field['id'] ) . '">';
|
||||
|
||||
if ( ! isset( $this->value['redux_repeater_data'][ $x ]['title'] ) && is_array( $this->value ) && isset( $this->value['redux_repeater_data'] ) && is_array( $this->value['redux_repeater_data'] ) ) {
|
||||
$this->value['redux_repeater_data'][ $x ]['title'] = null;
|
||||
}
|
||||
|
||||
echo '<input type="hidden" name="' . esc_attr( $this->parent->args['opt_name'] ) . '[' . esc_attr( $this->field['id'] ) . '][redux_repeater_data][' . intval( $x ) . '][title]" value="" class="regular-text slide-title" />';
|
||||
|
||||
echo '<h3><span class="redux-repeater-header"> </span></h3>';
|
||||
echo '<div>';
|
||||
|
||||
foreach ( $this->field['fields'] as $field ) {
|
||||
if ( isset( $this->field['bind_title'] ) && $field['id'] === $this->field['bind_title'] ) {
|
||||
if ( ! isset( $field['class'] ) || ( isset( $field['title'] ) && empty( $field['title'] ) ) ) {
|
||||
$field['class'] = 'bind_title';
|
||||
} else {
|
||||
$field['class'] .= ' bind_title';
|
||||
}
|
||||
}
|
||||
|
||||
$this->output_field( $field, $x );
|
||||
}
|
||||
|
||||
if ( ! isset( $this->field['static'] ) && empty( $this->field['static'] ) ) {
|
||||
echo '<a href="javascript:void(0);" class="button deletion redux-repeaters-remove">' . esc_html__( 'Delete', 'redux-framework' ) . ' ' . esc_html( $this->field['item_name'] ) . '</a>';
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
echo '</fieldset>';
|
||||
echo '</table>';
|
||||
echo '</div>';
|
||||
|
||||
++$x;
|
||||
--$loop;
|
||||
}
|
||||
}
|
||||
|
||||
echo '</div>';
|
||||
if ( ! isset( $this->field['static'] ) && empty( $this->field['static'] ) ) {
|
||||
$disabled = '';
|
||||
|
||||
if ( isset( $this->field['limit'] ) && is_integer( $this->field['limit'] ) ) {
|
||||
if ( $x >= $this->field['limit'] ) {
|
||||
$disabled = ' button-disabled';
|
||||
}
|
||||
}
|
||||
|
||||
echo '<a href="javascript:void(0);" class="button redux-repeaters-add button-primary' . esc_attr( $disabled ) . '" data-name="' . esc_attr( $this->parent->args['opt_name'] . $this->repeater_values ) . '[title][]">' . esc_html__( 'Add', 'redux-framework' ) . ' ' . esc_html( $this->field['item_name'] ) . '</a><br/>';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Function.
|
||||
* If this field requires any scripts, or css define this function and register/enqueue the scripts/css
|
||||
*
|
||||
* @since 1.0.0
|
||||
* @access public
|
||||
* @return void
|
||||
*/
|
||||
public function enqueue() {
|
||||
wp_print_styles( 'editor-buttons' );
|
||||
|
||||
// Set up min files for dev_mode = false.
|
||||
$min = Redux_Functions::is_min();
|
||||
|
||||
wp_enqueue_script(
|
||||
'redux-field-repeater',
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->url . 'redux-repeater' . $min . '.js',
|
||||
array( 'jquery', 'jquery-ui-core', 'jquery-ui-accordion', 'jquery-ui-sortable', 'wp-color-picker', 'redux-js' ),
|
||||
Redux_Extension_Repeater::$version,
|
||||
true
|
||||
);
|
||||
|
||||
if ( $this->parent->args['dev_mode'] ) {
|
||||
wp_enqueue_style(
|
||||
'redux-field-repeater',
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$this->url . 'redux-repeater.css',
|
||||
array(),
|
||||
Redux_Extension_Repeater::$version
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Output field.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param int $x Index.
|
||||
*/
|
||||
public function output_field( array $field, int $x ) {
|
||||
$this->enqueue_dependencies( $field );
|
||||
|
||||
if ( ! isset( $field['class'] ) ) {
|
||||
$field['class'] = '';
|
||||
}
|
||||
|
||||
$field['class'] .= ' repeater';
|
||||
|
||||
if ( ! empty( $field['title'] ) ) {
|
||||
echo '<h4>' . wp_kses_post( $field['title'] ) . '</h4>';
|
||||
}
|
||||
|
||||
if ( ! empty( $field['subtitle'] ) ) {
|
||||
echo '<span class="description">' . wp_kses_post( $field['subtitle'] ) . '</span>';
|
||||
}
|
||||
|
||||
$orig_field_id = $field['id'];
|
||||
|
||||
$field['id'] = $field['id'] . '-' . $x;
|
||||
$field['name'] = $this->parent->args['opt_name'] . $this->repeater_values . '[' . $orig_field_id . ']';
|
||||
$field['name_suffix'] = '[' . $x . ']';
|
||||
$field['class'] .= ' in-repeater';
|
||||
$field['repeater_id'] = $orig_field_id;
|
||||
|
||||
if ( isset( $field['options'] ) ) {
|
||||
|
||||
// Sorter data filter.
|
||||
if ( 'sorter' === $field['type'] && ! empty( $field['data'] ) && is_array( $field['data'] ) ) {
|
||||
if ( ! isset( $field['args'] ) ) {
|
||||
$field['args'] = array();
|
||||
}
|
||||
|
||||
foreach ( $field['data'] as $key => $data ) {
|
||||
if ( ! isset( $field['args'][ $key ] ) ) {
|
||||
$field['args'][ $key ] = array();
|
||||
}
|
||||
$field['options'][ $key ] = $this->parent->get_wordpress_data( $data, $field['args'][ $key ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$default = $field['default'] ?? '';
|
||||
|
||||
if ( ! empty( $this->repeater_values ) ) {
|
||||
$value = empty( $this->parent->options[ $this->field['id'] ][ $orig_field_id ][ $x ] ) ? $default : $this->parent->options[ $this->field['id'] ][ $orig_field_id ][ $x ];
|
||||
} else {
|
||||
$value = empty( $this->parent->options[ $orig_field_id ][ $x ] ) ? $default : $this->parent->options[ $orig_field_id ][ $x ];
|
||||
}
|
||||
|
||||
ob_start();
|
||||
|
||||
$this->parent->render_class->field_input( $field, $value );
|
||||
|
||||
$content = ob_get_contents();
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$_field = apply_filters( 'redux-support-repeater', $content, $field, 0 );
|
||||
|
||||
ob_end_clean();
|
||||
|
||||
echo $_field; // phpcs:ignore WordPress.Security.EscapeOutput
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Localize.
|
||||
*
|
||||
* @param array $field Field array.
|
||||
* @param string $value Value.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function localize( array $field, string $value = '' ) {
|
||||
if ( isset( $field['subfields'] ) && empty( $field['fields'] ) ) {
|
||||
$field['fields'] = $field['subfields'];
|
||||
unset( $field['subfields'] );
|
||||
}
|
||||
|
||||
if ( isset( $field['group_values'] ) && $field['group_values'] ) {
|
||||
$this->repeater_values = '[' . $field['id'] . ']';
|
||||
}
|
||||
|
||||
$var = '';
|
||||
|
||||
if ( '' === $value ) {
|
||||
$value = array();
|
||||
}
|
||||
|
||||
if ( ! empty( $field['fields'] ) ) {
|
||||
ob_start();
|
||||
|
||||
foreach ( $field['fields'] as $f ) {
|
||||
if ( isset( $this->field['bind_title'] ) && $f['id'] === $this->field['bind_title'] ) {
|
||||
if ( ! isset( $f['class'] ) || ( isset( $f['title'] ) && empty( $f['title'] ) ) ) {
|
||||
$f['class'] = 'bind_title';
|
||||
} else {
|
||||
$f['class'] .= ' bind_title';
|
||||
}
|
||||
}
|
||||
|
||||
$this->output_field( $f, 99999 );
|
||||
}
|
||||
|
||||
$var = ob_get_contents();
|
||||
|
||||
$var = array(
|
||||
'html' => $var . '<a href="javascript:void(0);" class="button deletion redux-repeaters-remove">' . esc_html__( 'Delete', 'redux-framework' ) . '</a>',
|
||||
'count' => count( $value ),
|
||||
'sortable' => true,
|
||||
'limit' => '',
|
||||
'name' => $this->parent->args['opt_name'] . '[' . $field['id'] . '][0]',
|
||||
);
|
||||
|
||||
if ( isset( $field['sortable'] ) && is_bool( $this->field['sortable'] ) ) {
|
||||
$var['sortable'] = $field['sortable'];
|
||||
}
|
||||
if ( isset( $field['limit'] ) && is_integer( $field['limit'] ) ) {
|
||||
$var['limit'] = $field['limit'];
|
||||
}
|
||||
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
return $var;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue Deps.
|
||||
*
|
||||
* @param array $field Field.
|
||||
*/
|
||||
private function enqueue_dependencies( array $field ) {
|
||||
$field_type = $field['type'];
|
||||
|
||||
$field_class = 'Redux_' . $field_type;
|
||||
|
||||
if ( ! class_exists( $field_class ) ) {
|
||||
$field_type = str_replace( '_', '-', $field_type );
|
||||
|
||||
// phpcs:ignore WordPress.NamingConventions.ValidHookName
|
||||
$class_file = apply_filters( 'redux-typeclass-load', ReduxFramework::$_dir . 'inc/fields/' . $field_type . '/class-redux-' . $field_type . '.php', $field_class );
|
||||
|
||||
if ( file_exists( $class_file ) ) {
|
||||
require_once $class_file;
|
||||
}
|
||||
}
|
||||
|
||||
if ( class_exists( $field_class ) && method_exists( $field_class, 'enqueue' ) ) {
|
||||
$enqueue = new $field_class( '', '', $this->parent );
|
||||
$enqueue->enqueue();
|
||||
}
|
||||
|
||||
if ( class_exists( $field_class ) && method_exists( $field_class, 'localize' ) ) {
|
||||
|
||||
$enqueue = new $field_class( '', '', $this->parent );
|
||||
|
||||
$data = $enqueue->localize( $field );
|
||||
|
||||
$this->parent->enqueue_class->localize_data[ $field['type'] ][ $field['id'] ] = $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
/**
|
||||
* Silence is golden.
|
||||
*
|
||||
* @package Redux Framework
|
||||
*/
|
||||
|
||||
echo null;
|
||||
@@ -0,0 +1,43 @@
|
||||
.redux-container-repeater { margin-bottom: 7px; padding: 0 20px 15px; }
|
||||
|
||||
.redux-container-repeater h4 { margin: 5px 0 0 0; }
|
||||
|
||||
.redux-container-repeater h4:first-child { margin-top: 0; }
|
||||
|
||||
.redux-container-repeater .description { margin: 5px 0 5px 0; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-accordion { width: 100%; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-accordion .ui-state-focus { outline: none; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-accordion-repeater { margin-bottom: 10px; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-accordion-repeater > div { border: 1px solid #dfdfdf !important; border-radius: 0 !important; margin-top: 0 !important; padding: 10px; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-accordion-repeater h3.ui-accordion-header { border: 1px solid #dfdfdf; cursor: move; font-weight: bold; padding: 0 10px; height: 40px; line-height: 40px; background-color: #f1f1f1; background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec)); background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec); background-image: linear-gradient(to bottom, #f9f9f9, #ececec); overflow: hidden; border-radius: 3px; -webkit-box-shadow: inset 0 1px 0 #fff; box-shadow: inset 0 1px 0 #fff; text-align: center; margin-bottom: 0; }
|
||||
|
||||
.redux-container-repeater .redux-repeaters-add { float: right; }
|
||||
|
||||
.redux-container-repeater .redux-repeaters-add:after { clear: both; }
|
||||
|
||||
.redux-container-repeater .redux-repeaters-remove { /* color: #ef521d !important; */ float: right; }
|
||||
|
||||
.redux-container-repeater .redux-repeaters-remove:after { clear: both; }
|
||||
|
||||
.redux-container-repeater .redux-repeater-header { font-weight: bold; }
|
||||
|
||||
.redux-container-repeater .redux_repeaters_add_remove { margin-bottom: 10px; }
|
||||
|
||||
.redux-container-repeater .redux-field-container { padding: 0 0 10px 0; }
|
||||
|
||||
.redux-container-repeater .redux-field-container:last-child { padding-bottom: 0; }
|
||||
|
||||
.redux-container-repeater .ui-accordion .ui-accordion-content { padding: 1em; }
|
||||
|
||||
.redux-container-repeater .redux-container-sorter { margin-right: 0 !important; }
|
||||
|
||||
#poststuff .redux-container-repeater h3 { padding: 0; cursor: move !important; line-height: 40px; }
|
||||
|
||||
/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdXgtcmVwZWF0ZXIuY3NzIiwic291cmNlcyI6WyJyZWR1eC1yZXBlYXRlci5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLEFBQUEseUJBQXlCLENBQUMsRUFDdEIsYUFBYSxFQUFFLEdBQUcsRUFDbEIsT0FBTyxFQUFFLFdBQVcsR0F1RnZCOztBQXpGRCxBQUlJLHlCQUpxQixDQUlyQixFQUFFLENBQUMsRUFDQyxNQUFNLEVBQUUsU0FBUyxHQUlwQjs7QUFUTCxBQU1RLHlCQU5pQixDQUlyQixFQUFFLEFBRUcsWUFBWSxDQUFDLEVBQ1YsVUFBVSxFQUFFLENBQUMsR0FDaEI7O0FBUlQsQUFXSSx5QkFYcUIsQ0FXckIsWUFBWSxDQUFDLEVBQ1QsTUFBTSxFQUFFLFdBQVcsR0FDdEI7O0FBYkwsQUFlSSx5QkFmcUIsQ0FlckIseUJBQXlCLENBQUMsRUFDdEIsS0FBSyxFQUFFLElBQUksR0FDZDs7QUFqQkwsQUFtQkkseUJBbkJxQixDQW1CckIseUJBQXlCLENBQUMsZUFBZSxDQUFBLEVBQ3JDLE9BQU8sRUFBRSxJQUFJLEdBQ2hCOztBQXJCTCxBQXVCSSx5QkF2QnFCLENBdUJyQixrQ0FBa0MsQ0FBQyxFQUMvQixhQUFhLEVBQUUsSUFBSSxHQUN0Qjs7QUF6QkwsQUEyQkkseUJBM0JxQixDQTJCckIsa0NBQWtDLEdBQUcsR0FBRyxDQUFDLEVBQ3JDLE1BQU0sRUFBRSw0QkFBNEIsRUFDcEMsYUFBYSxFQUFFLFlBQVksRUFDM0IsVUFBVSxFQUFFLFlBQVksRUFDeEIsT0FBTyxFQUFFLElBQUksR0FDaEI7O0FBaENMLEFBa0NJLHlCQWxDcUIsQ0FrQ3JCLGtDQUFrQyxDQUFDLEVBQUUsQUFBQSxvQkFBb0IsQ0FBQyxFQUN0RCxNQUFNLEVBQUUsaUJBQWlCLEVBQ3pCLE1BQU0sRUFBRSxJQUFJLEVBQ1osV0FBVyxFQUFFLElBQUksRUFDakIsT0FBTyxFQUFFLE1BQU0sRUFDZixNQUFNLEVBQUUsSUFBSSxFQUNaLFdBQVcsRUFBRSxJQUFJLEVBQ2pCLGdCQUFnQixFQUFFLE9BQU8sRUFDekIsZ0JBQWdCLEVBQUUsMENBQTBDLEVBQzVELGdCQUFnQixFQUFFLDJDQUEyQyxFQUM3RCxnQkFBZ0IsRUFBRSx5Q0FBeUMsRUFDM0QsZ0JBQWdCLEVBQUUsMkVBQTJFLEVBQzdGLGdCQUFnQixFQUFFLDhDQUE4QyxFQUNoRSxnQkFBZ0IsRUFBRSw0Q0FBNEMsRUFDOUQsUUFBUSxFQUFFLE1BQU0sRUFDaEIscUJBQXFCLEVBQUUsR0FBRyxFQUMxQixrQkFBa0IsRUFBRSxHQUFHLEVBQ3ZCLGFBQWEsRUFBRSxHQUFHLEVBQ2xCLGVBQWUsRUFBRSxrQkFBa0IsRUFDbkMsa0JBQWtCLEVBQUUsa0JBQWtCLEVBQ3RDLFVBQVUsRUFBRSxrQkFBa0IsRUFDOUIsVUFBVSxFQUFFLE1BQU0sRUFDbEIsYUFBYSxFQUFDLENBQUMsR0FDbEI7O0FBekRMLEFBMERJLHlCQTFEcUIsQ0EwRHJCLG9CQUFvQixDQUFDLEVBQ2pCLEtBQUssRUFBRSxLQUFLLEdBSWY7O0FBL0RMLEFBNERRLHlCQTVEaUIsQ0EwRHJCLG9CQUFvQixBQUVmLE1BQU0sQ0FBQyxFQUNKLEtBQUssRUFBRSxJQUFJLEdBQ2Q7O0FBOURULEFBZ0VJLHlCQWhFcUIsQ0FnRXJCLHVCQUF1QixDQUFDLEVBQ3BCLGdDQUFnQyxDQUNoQyxLQUFLLEVBQUUsS0FBSyxHQUlmOztBQXRFTCxBQW1FUSx5QkFuRWlCLENBZ0VyQix1QkFBdUIsQUFHbEIsTUFBTSxDQUFDLEVBQ0osS0FBSyxFQUFFLElBQUksR0FDZDs7QUFyRVQsQUF1RUkseUJBdkVxQixDQXVFckIsc0JBQXNCLENBQUMsRUFDbkIsV0FBVyxFQUFFLElBQUksR0FDcEI7O0FBekVMLEFBMEVJLHlCQTFFcUIsQ0EwRXJCLDJCQUEyQixDQUFDLEVBQ3hCLGFBQWEsRUFBRSxJQUFJLEdBQ3RCOztBQTVFTCxBQTZFSSx5QkE3RXFCLENBNkVyQixzQkFBc0IsQ0FBQyxFQUNuQixPQUFPLEVBQUUsVUFBVSxHQUN0Qjs7QUEvRUwsQUFnRkkseUJBaEZxQixDQWdGckIsc0JBQXNCLEFBQUEsV0FBVyxDQUFDLEVBQzlCLGNBQWMsRUFBRSxDQUFDLEdBQ3BCOztBQWxGTCxBQW1GSSx5QkFuRnFCLENBbUZyQixhQUFhLENBQUMscUJBQXFCLENBQUMsRUFDaEMsT0FBTyxFQUFFLEdBQUcsR0FDZjs7QUFyRkwsQUFzRkkseUJBdEZxQixDQXNGckIsdUJBQXVCLENBQUMsRUFDcEIsWUFBWSxFQUFFLFlBQVksR0FDN0I7O0FBR0wsQUFBQSxVQUFVLENBQUMseUJBQXlCLENBQUMsRUFBRSxDQUFDLEVBQ3BDLE9BQU8sRUFBRSxDQUFDLEVBQ1YsTUFBTSxFQUFFLGVBQWUsRUFDdkIsV0FBVyxFQUFFLElBQUksR0FDcEIifQ== */
|
||||
|
||||
/*# sourceMappingURL=redux-repeater.css.map */
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,576 @@
|
||||
/* global redux_change, redux, reduxRepeaterAccordionActivate, reduxRepeaterAccordionBeforeActivate */
|
||||
|
||||
( function ( $ ) {
|
||||
'use strict';
|
||||
|
||||
var reduxObject;
|
||||
var panelsClosed;
|
||||
|
||||
redux.field_objects = redux.field_objects || {};
|
||||
redux.field_objects.repeater = redux.field_objects.repeater || {};
|
||||
|
||||
redux.field_objects.repeater.getOptName = function ( el ) {
|
||||
var optName;
|
||||
|
||||
optName = el.parents().find( '.redux-ajax-security' ).data( 'opt-name' );
|
||||
|
||||
if ( undefined === optName ) {
|
||||
optName = el.parents( '.redux-container' ).data( 'opt-name' );
|
||||
}
|
||||
|
||||
if ( undefined === optName ) {
|
||||
return redux;
|
||||
} else {
|
||||
return redux.optName;
|
||||
}
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.init = function ( selector ) {
|
||||
if ( ! selector ) {
|
||||
selector = $( document ).find( '.redux-group-tab:visible' ).find( '.redux-container-repeater:visible' );
|
||||
}
|
||||
|
||||
$( selector ).each(
|
||||
function () {
|
||||
var gid;
|
||||
var blank;
|
||||
|
||||
var el = $( this );
|
||||
var parent = el;
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
if ( parent.is( ':hidden' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! el.hasClass( 'redux-field-container' ) ) {
|
||||
parent = el.parents( '.redux-field-container:first' );
|
||||
}
|
||||
|
||||
reduxObject = redux.field_objects.repeater.getOptName( el );
|
||||
|
||||
gid = parent.attr( 'data-id' );
|
||||
blank = el.find( '.redux-repeater-accordion-repeater:last-child' );
|
||||
|
||||
reduxObject.repeater[gid].blank = blank.clone().wrap( '<p>' ).parent().html();
|
||||
|
||||
if ( parent.hasClass( 'redux-container-repeater' ) ) {
|
||||
parent.addClass( 'redux-field-init' );
|
||||
}
|
||||
|
||||
if ( parent.hasClass( 'redux-field-init' ) ) {
|
||||
parent.removeClass( 'redux-field-init' );
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
redux.field_objects.repeater.setAccordion( el, gid );
|
||||
redux.field_objects.repeater.bindTitle( el );
|
||||
redux.field_objects.repeater.remove( el, gid );
|
||||
redux.field_objects.repeater.add( el );
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.add = function ( el ) {
|
||||
|
||||
/* jshint -W121 */
|
||||
String.prototype.reduxReplaceAll = function ( s1, s2 ) {
|
||||
return this.replace( new RegExp( s1.replace( /[.^$*+?()[{|]/g, '\\$&' ), 'g' ), s2 );
|
||||
};
|
||||
|
||||
el.find( '.redux-repeaters-add' ).on(
|
||||
'click',
|
||||
function () {
|
||||
var parent;
|
||||
var count;
|
||||
var gid;
|
||||
var id;
|
||||
var newSlide;
|
||||
var html;
|
||||
|
||||
redux_change( $( this ) );
|
||||
|
||||
if ( $( this ).hasClass( 'button-disabled' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
parent = $( this ).parent().find( '.redux-repeater-accordion:first' );
|
||||
count = parent.find( '.redux-repeater-accordion-repeater' ).length;
|
||||
gid = parent.attr( 'data-id' ); // Group id.
|
||||
|
||||
if ( '' !== reduxObject.repeater[gid].limit ) {
|
||||
if ( count >= reduxObject.repeater[gid].limit ) {
|
||||
$( this ).addClass( 'button-disabled' );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
count += 1;
|
||||
|
||||
id = parent.find( '.redux-repeater-accordion-repeater' ).length; // Index number.
|
||||
|
||||
if ( parent.find( '.redux-repeater-accordion-repeater:last' ).find( '.ui-accordion-header' ).hasClass( 'ui-state-active' ) ) {
|
||||
parent.find( '.redux-repeater-accordion-repeater:last' ).find( '.ui-accordion-header' ).trigger( 'click' );
|
||||
}
|
||||
|
||||
newSlide = parent.find( '.redux-repeater-accordion-repeater:last' ).clone( true, true );
|
||||
|
||||
if ( 0 === newSlide.length ) {
|
||||
newSlide = reduxObject.repeater[gid].blank;
|
||||
}
|
||||
|
||||
if ( reduxObject.repeater[gid] ) {
|
||||
reduxObject.repeater[gid].count = el.find( '.redux-repeater-header' ).length;
|
||||
html = reduxObject.repeater[gid].html.reduxReplaceAll( '99999', id );
|
||||
|
||||
$( newSlide ).find( '.redux-repeater-header' ).text( '' );
|
||||
}
|
||||
|
||||
newSlide.find( '.ui-accordion-content' ).html( html );
|
||||
|
||||
// Append to the accordion.
|
||||
$( parent ).append( newSlide );
|
||||
|
||||
// Reorder.
|
||||
redux.field_objects.repeater.sort_repeaters( newSlide );
|
||||
|
||||
// Refresh the JS object.
|
||||
newSlide = $( this ).parent().find( '.redux-repeater-accordion:first' );
|
||||
|
||||
newSlide.find( '.redux-repeater-accordion-repeater:last .ui-accordion-header' ).trigger( 'click' );
|
||||
newSlide.find( '.redux-repeater-accordion-repeater:last .bind_title' ).on(
|
||||
'change keyup',
|
||||
function ( event ) {
|
||||
var value;
|
||||
|
||||
if ( $( event.target ).find( ':selected' ).text().length > 0 ) {
|
||||
value = $( event.target ).find( ':selected' ).text();
|
||||
} else {
|
||||
value = $( event.target ).val();
|
||||
}
|
||||
|
||||
$( this ).closest( '.redux-repeater-accordion-repeater' ).find( '.redux-repeater-header' ).text( value );
|
||||
}
|
||||
);
|
||||
|
||||
$.redux.checkRequired( el );
|
||||
|
||||
if ( reduxObject.repeater[gid].limit > 0 && count >= reduxObject.repeater[gid].limit ) {
|
||||
$( this ).addClass( 'button-disabled' );
|
||||
}
|
||||
|
||||
if ( true === panelsClosed ) {
|
||||
if ( count >= 2 ) {
|
||||
el.find( '.redux-repeater-accordion' ).accordion( 'option', { active: false } );
|
||||
}
|
||||
}
|
||||
|
||||
if ( count > 1 ) {
|
||||
redux.field_objects.repeater.remove( newSlide );
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.remove = function ( el ) {
|
||||
var x;
|
||||
|
||||
// Handler to remove the given repeater.
|
||||
el.find( '.redux-repeaters-remove' ).on(
|
||||
'click',
|
||||
function () {
|
||||
var parent;
|
||||
var gid;
|
||||
var count;
|
||||
|
||||
redux_change( $( this ) );
|
||||
|
||||
parent = $( this ).parents( '.redux-container-repeater:first' );
|
||||
gid = parent.attr( 'data-id' );
|
||||
|
||||
reduxObject.repeater[gid].blank = $( this ).parents( '.redux-repeater-accordion-repeater:first' ).clone( true, true );
|
||||
|
||||
$( this ).parents( '.redux-repeater-accordion-repeater:first' ).slideUp(
|
||||
'medium',
|
||||
function () {
|
||||
$( this ).remove();
|
||||
|
||||
redux.field_objects.repeater.sort_repeaters( el );
|
||||
|
||||
if ( '' !== reduxObject.repeater[gid].limit ) {
|
||||
count = parent.find( '.redux-repeater-accordion-repeater' ).length;
|
||||
|
||||
if ( count < reduxObject.repeater[gid].limit ) {
|
||||
parent.find( '.redux-repeaters-add' ).removeClass( 'button-disabled' );
|
||||
}
|
||||
}
|
||||
|
||||
parent.find( '.redux-repeater-accordion-repeater:last .ui-accordion-header' ).trigger( 'click' );
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
x = el.find( '.redux-repeater-accordion-repeater' );
|
||||
|
||||
if ( x.hasClass( 'close-me' ) ) {
|
||||
el.find( '.redux-repeaters-remove' ).trigger( 'click' );
|
||||
}
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.bindTitle = function ( el ) {
|
||||
el.find( '.redux-repeater-accordion-repeater .bind_title' ).on(
|
||||
'change keyup',
|
||||
function ( event ) {
|
||||
var value;
|
||||
|
||||
if ( $( event.target ).find( ':selected' ).text().length > 0 ) {
|
||||
value = $( event.target ).find( ':selected' ).text();
|
||||
} else {
|
||||
value = $( event.target ).val();
|
||||
}
|
||||
|
||||
$( this ).closest( '.redux-repeater-accordion-repeater' ).find( '.redux-repeater-header' ).text( value );
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.setAccordion = function ( el, gid ) {
|
||||
var active;
|
||||
var accordion;
|
||||
|
||||
var base = el.find( '.redux-repeater-accordion' );
|
||||
|
||||
panelsClosed = Boolean( base.data( 'panels-closed' ) );
|
||||
|
||||
if ( true === panelsClosed ) {
|
||||
active = Boolean( false );
|
||||
} else {
|
||||
active = 0;
|
||||
}
|
||||
|
||||
accordion = el.find( '.redux-repeater-accordion' ).accordion(
|
||||
{
|
||||
header: '> div > fieldset > h3',
|
||||
collapsible: true,
|
||||
active: active,
|
||||
|
||||
beforeActivate: function ( event ) {
|
||||
var a;
|
||||
var relName;
|
||||
var optName;
|
||||
var bracket;
|
||||
|
||||
a = $( this ).next( '.redux-repeaters-add' );
|
||||
relName = a.attr( 'data-name' );
|
||||
|
||||
bracket = relName.indexOf( '[' );
|
||||
|
||||
optName = relName.substring( 0, bracket );
|
||||
|
||||
if ( 'function' === typeof reduxRepeaterAccordionBeforeActivate ) {
|
||||
reduxRepeaterAccordionBeforeActivate( $( this ), el, event, optName );
|
||||
}
|
||||
},
|
||||
activate: function ( event, ui ) {
|
||||
var a;
|
||||
var relName;
|
||||
var optName;
|
||||
var bracket;
|
||||
|
||||
$.redux.initFields();
|
||||
|
||||
if ( 'function' === typeof reduxRepeaterAccordionActivate ) {
|
||||
a = $( this ).next( '.redux-repeaters-add' );
|
||||
relName = a.attr( 'data-name' );
|
||||
bracket = relName.indexOf( '[' );
|
||||
|
||||
optName = relName.substring( 0, bracket );
|
||||
|
||||
reduxRepeaterAccordionActivate( $( this ), el, event, ui, optName );
|
||||
}
|
||||
},
|
||||
heightStyle: 'content', icons: {
|
||||
'header': 'ui-icon-plus', 'activeHeader': 'ui-icon-minus'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
if ( true === reduxObject.repeater[gid].sortable ) {
|
||||
accordion.sortable(
|
||||
{
|
||||
axis: 'y',
|
||||
handle: 'h3',
|
||||
placeholder: 'ui-state-highlight',
|
||||
start: function ( e, ui ) {
|
||||
e = null;
|
||||
|
||||
ui.placeholder.height( ui.item.height() );
|
||||
ui.placeholder.width( ui.item.width() );
|
||||
},
|
||||
stop: function ( event, ui ) {
|
||||
event = null;
|
||||
|
||||
// IE doesn't register the blur when sorting
|
||||
// so trigger focusout handlers to remove .ui-state-focus.
|
||||
ui.item.children( 'h3' ).triggerHandler( 'focusout' );
|
||||
|
||||
redux.field_objects.repeater.sort_repeaters( $( this ) );
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
accordion.find( 'h3.ui-accordion-header' ).css( 'cursor', 'pointer' );
|
||||
}
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.sort_repeaters = function ( selector ) {
|
||||
if ( ! selector.hasClass( 'redux-container-repeater' ) ) {
|
||||
selector = selector.parents( '.redux-container-repeater:first' );
|
||||
}
|
||||
|
||||
selector.find( '.redux-repeater-accordion-repeater' ).each(
|
||||
function ( idx ) {
|
||||
var header;
|
||||
var split;
|
||||
var content;
|
||||
|
||||
var id = $( this ).attr( 'data-sortid' );
|
||||
var input = $( this ).find( '.redux-field .repeater[name*=\'[' + id + ']\']' );
|
||||
|
||||
input.each(
|
||||
function () {
|
||||
$( this ).attr( 'name', $( this ).attr( 'name' ).replace( '[' + id + ']', '[' + idx + ']' ) );
|
||||
}
|
||||
);
|
||||
|
||||
input = $( this ).find( '.slide-title' );
|
||||
|
||||
input.attr( 'name', input.attr( 'name' ).replace( '[' + id + ']', '[' + idx + ']' ) );
|
||||
input.attr( 'data-key', idx );
|
||||
|
||||
$( this ).attr( 'data-sortid', idx );
|
||||
|
||||
// Fix the accordion header.
|
||||
header = $( this ).find( '.ui-accordion-header' );
|
||||
split = header.attr( 'id' ).split( '-header-' );
|
||||
|
||||
header.attr( 'id', split[0] + '-header-' + idx );
|
||||
split = header.attr( 'aria-controls' ).split( '-panel-' );
|
||||
|
||||
header.attr( 'aria-controls', split[0] + '-panel-' + idx );
|
||||
|
||||
// Fix the accordion content.
|
||||
content = $( this ).find( '.ui-accordion-content' );
|
||||
split = content.attr( 'id' ).split( '-panel-' );
|
||||
|
||||
content.attr( 'id', split[0] + '-panel-' + idx );
|
||||
split = content.attr( 'aria-labelledby' ).split( '-header-' );
|
||||
|
||||
content.attr( 'aria-labelledby', split[0] + '-header-' + idx );
|
||||
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
redux.field_objects.repeater.check_parents_dependencies = function ( id ) {
|
||||
var show = '';
|
||||
var current = id;
|
||||
var dash = current.lastIndexOf( '-' );
|
||||
var index = current.substring( dash + 1 );
|
||||
var fixedId = current.replace( index, '99999' );
|
||||
|
||||
if ( reduxObject.required_child.hasOwnProperty( fixedId ) ) {
|
||||
$.each(
|
||||
reduxObject.required_child[fixedId],
|
||||
function ( i, parentData ) {
|
||||
var parentValue;
|
||||
var value;
|
||||
var idx;
|
||||
var x;
|
||||
|
||||
i = null;
|
||||
idx = $( '#' + reduxObject.args.opt_name + '-' + parentData.parent + '-' + index );
|
||||
|
||||
if ( idx.hasClass( 'hide' ) ) {
|
||||
show = false;
|
||||
return false;
|
||||
} else {
|
||||
if ( false !== show ) {
|
||||
value = idx.serializeForm();
|
||||
|
||||
if ( null !== value && 'object' === typeof value && value.hasOwnProperty( reduxObject.args.opt_name ) ) {
|
||||
if ( undefined === value[reduxObject.args.opt_name][parentData.parent] ) {
|
||||
x = Object.values( value[reduxObject.args.opt_name] )[0][parentData.parent];
|
||||
} else {
|
||||
x = value[reduxObject.args.opt_name][parentData.parent];
|
||||
}
|
||||
|
||||
value = x[index];
|
||||
}
|
||||
|
||||
if ( $( '#' + reduxObject.args.opt_name + '-' + id ).hasClass( 'redux-container-media' ) ) {
|
||||
value = value.url;
|
||||
}
|
||||
|
||||
parentValue = value;
|
||||
|
||||
show = $.redux.check_dependencies_visibility( parentValue, parentData );
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
} else {
|
||||
show = true;
|
||||
}
|
||||
|
||||
return show;
|
||||
};
|
||||
|
||||
/* jshint -W117, -W098 */
|
||||
/* jscs:disable disallowUnusedParams */
|
||||
redux_hook(
|
||||
$.redux,
|
||||
'required',
|
||||
function ( returnValue, originalFunction ) {
|
||||
var reduxObj;
|
||||
|
||||
reduxObj = redux.field_objects.repeater.getOptName( $( '.redux-container-repeater' ) );
|
||||
|
||||
$.each(
|
||||
reduxObj.folds,
|
||||
function ( i, v ) {
|
||||
|
||||
var fieldset;
|
||||
var div;
|
||||
var rawTable;
|
||||
|
||||
if ( i.indexOf( '-99999' ) !== - 1 ) {
|
||||
i = i.replace( '-99999', '' );
|
||||
}
|
||||
|
||||
fieldset = $( '[id^=' + reduxObj.args.opt_name + '-' + i + ']' );
|
||||
|
||||
if ( fieldset.find( '*' ).hasClass( 'in-repeater' ) ) {
|
||||
fieldset.addClass( 'fold' );
|
||||
|
||||
if ( 'hide' === v ) {
|
||||
fieldset.addClass( 'hide' );
|
||||
fieldset.prevUntil( 'fieldset' ).addClass( 'hide' );
|
||||
|
||||
if ( fieldset.hasClass( 'redux-container-section' ) ) {
|
||||
div = $( '#section-' + i );
|
||||
|
||||
if ( div.hasClass( 'redux-section-indent-start' ) ) {
|
||||
$( '#section-table-' + i ).hide().addClass( 'hide' );
|
||||
div.hide().addClass( 'hide' );
|
||||
}
|
||||
}
|
||||
|
||||
if ( fieldset.hasClass( 'redux-container-info' ) ) {
|
||||
$( '#info-' + i ).hide().addClass( 'hide' );
|
||||
}
|
||||
|
||||
if ( fieldset.hasClass( 'redux-container-divide' ) ) {
|
||||
$( '#divide-' + i ).hide().addClass( 'hide' );
|
||||
}
|
||||
|
||||
if ( fieldset.hasClass( 'redux-container-raw' ) ) {
|
||||
rawTable = fieldset.parents().find( 'table#' + redux.args.opt_name + '-' + i );
|
||||
rawTable.hide().addClass( 'hide' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
redux_hook(
|
||||
$.redux,
|
||||
'check_dependencies',
|
||||
function ( returnValue, originalFunction, variable ) {
|
||||
var current;
|
||||
var id;
|
||||
var container;
|
||||
var is_hidden;
|
||||
var dash;
|
||||
var idNoIndex;
|
||||
var index;
|
||||
|
||||
if ( $( variable ).hasClass( 'in-repeater' ) ) {
|
||||
current = $( variable );
|
||||
id = current.parents( '.redux-field:first' ).data( 'id' );
|
||||
container = current.parents( '.redux-field-container:first' );
|
||||
is_hidden = container.hasClass( 'hide' );
|
||||
dash = id.lastIndexOf( '-' );
|
||||
idNoIndex = id.substring( 0, dash );
|
||||
index = id.substring( dash + 1 );
|
||||
|
||||
$.each(
|
||||
reduxObject.required[idNoIndex],
|
||||
function ( child, dependents ) {
|
||||
var current;
|
||||
var show;
|
||||
var childFieldset;
|
||||
|
||||
if ( child.indexOf( '99999' ) !== - 1 ) {
|
||||
child = child.replace( '99999', index );
|
||||
}
|
||||
|
||||
current = $( this );
|
||||
show = false;
|
||||
childFieldset = $( '#' + reduxObject.args.opt_name + '-' + child );
|
||||
|
||||
if ( ! is_hidden ) {
|
||||
show = redux.field_objects.repeater.check_parents_dependencies( child );
|
||||
}
|
||||
|
||||
if ( true === show ) {
|
||||
childFieldset.fadeIn(
|
||||
300,
|
||||
function () {
|
||||
$( this ).removeClass( 'hide' );
|
||||
$( this ).prevUntil( 'fieldset' ).removeClass( 'hide' );
|
||||
|
||||
if ( reduxObject.required.hasOwnProperty( child ) ) {
|
||||
$.redux.check_dependencies( $( '#' + reduxObject.args.opt_name + '-' + child ).children().first() );
|
||||
}
|
||||
|
||||
$.redux.initFields();
|
||||
}
|
||||
);
|
||||
} else {
|
||||
childFieldset.fadeOut(
|
||||
100,
|
||||
function () {
|
||||
$( this ).addClass( 'hide' );
|
||||
$( this ).prevUntil( 'fieldset' ).addClass( 'hide' );
|
||||
|
||||
if ( reduxObject.required.hasOwnProperty( child ) ) {
|
||||
$.redux.required_recursive_hide( child );
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
current.find( 'select, radio, input[type=checkbox]' ).trigger( 'change' );
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
} )( jQuery );
|
||||
@@ -0,0 +1 @@
|
||||
.redux-container-repeater{padding:15px 20px;margin-bottom:7px;padding-top:0}.redux-container-repeater h4{margin:5px 0 0 0}.redux-container-repeater h4:first-child{margin-top:0}.redux-container-repeater .description{margin:5px 0 5px 0}.redux-container-repeater .redux-repeater-accordion{width:100%}.redux-container-repeater .redux-repeater-accordion .ui-state-focus{outline:0}.redux-container-repeater .redux-repeater-accordion-repeater{margin-bottom:10px}.redux-container-repeater .redux-repeater-accordion-repeater>div{border:1px solid #dfdfdf !important;border-radius:0 !important;margin-top:0 !important;padding:10px}.redux-container-repeater .redux-repeater-accordion-repeater h3.ui-accordion-header{border:1px solid #dfdfdf;cursor:move;font-weight:bold;padding:0 10px;height:40px;line-height:40px;background-color:#f1f1f1;background-image:-webkit-gradient(linear,left top,left bottom,from(#f9f9f9),to(#ececec));background-image:-webkit-linear-gradient(top,#f9f9f9,#ececec);background-image:linear-gradient(to bottom,#f9f9f9,#ececec);overflow:hidden;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 #fff;box-shadow:inset 0 1px 0 #fff;text-align:center;margin-bottom:0}.redux-container-repeater .redux-repeaters-add{float:right}.redux-container-repeater .redux-repeaters-add:after{clear:both}.redux-container-repeater .redux-repeaters-remove{color:#ef521d !important;float:right}.redux-container-repeater .redux-repeaters-remove:after{clear:both}.redux-container-repeater .redux-repeater-header{font-weight:bold}.redux-container-repeater .redux_repeaters_add_remove{margin-bottom:10px}.redux-container-repeater .redux-field-container{padding:0 0 10px 0}.redux-container-repeater .redux-field-container:last-child{padding-bottom:0}.redux-container-repeater .ui-accordion .ui-accordion-content{padding:1em}.redux-container-repeater .redux-container-sorter{margin-right:0 !important}#poststuff .redux-container-repeater h3{padding:0;cursor:move !important;line-height:40px}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,96 @@
|
||||
.redux-container-repeater {
|
||||
margin-bottom: 7px;
|
||||
padding: 0 20px 15px;
|
||||
|
||||
h4 {
|
||||
margin: 5px 0 0 0;
|
||||
&:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.description {
|
||||
margin: 5px 0 5px 0;
|
||||
}
|
||||
|
||||
.redux-repeater-accordion {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.redux-repeater-accordion .ui-state-focus{
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.redux-repeater-accordion-repeater {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.redux-repeater-accordion-repeater > div {
|
||||
border: 1px solid #dfdfdf !important;
|
||||
border-radius: 0 !important;
|
||||
margin-top: 0 !important;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.redux-repeater-accordion-repeater h3.ui-accordion-header {
|
||||
border: 1px solid #dfdfdf;
|
||||
cursor: move;
|
||||
font-weight: bold;
|
||||
padding: 0 10px;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
background-color: #f1f1f1;
|
||||
background-image: -ms-linear-gradient(top, #f9f9f9, #ececec);
|
||||
background-image: -moz-linear-gradient(top, #f9f9f9, #ececec);
|
||||
background-image: -o-linear-gradient(top, #f9f9f9, #ececec);
|
||||
background-image: -webkit-gradient(linear, left top, left bottom, from(#f9f9f9), to(#ececec));
|
||||
background-image: -webkit-linear-gradient(top, #f9f9f9, #ececec);
|
||||
background-image: linear-gradient(to bottom, #f9f9f9, #ececec);
|
||||
overflow: hidden;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
-moz-box-shadow: inset 0 1px 0 #fff;
|
||||
-webkit-box-shadow: inset 0 1px 0 #fff;
|
||||
box-shadow: inset 0 1px 0 #fff;
|
||||
text-align: center;
|
||||
margin-bottom:0;
|
||||
}
|
||||
.redux-repeaters-add {
|
||||
float: right;
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
.redux-repeaters-remove {
|
||||
/* color: #ef521d !important; */
|
||||
float: right;
|
||||
&:after {
|
||||
clear: both;
|
||||
}
|
||||
}
|
||||
.redux-repeater-header {
|
||||
font-weight: bold;
|
||||
}
|
||||
.redux_repeaters_add_remove {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.redux-field-container {
|
||||
padding: 0 0 10px 0;
|
||||
}
|
||||
.redux-field-container:last-child {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
.ui-accordion .ui-accordion-content {
|
||||
padding: 1em;
|
||||
}
|
||||
.redux-container-sorter {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#poststuff .redux-container-repeater h3 {
|
||||
padding: 0;
|
||||
cursor: move !important;
|
||||
line-height: 40px;
|
||||
}
|
||||
Reference in New Issue
Block a user