Initial commit: Atomaste website

This commit is contained in:
2025-12-10 12:17:30 -05:00
commit 0b9e5d1605
19260 changed files with 5206382 additions and 0 deletions

View File

@@ -0,0 +1,24 @@
<?php
if( ! function_exists( 'rara_business_register_custom_controls' ) ) :
/**
* Register Custom Controls
*/
function rara_business_register_custom_controls( $wp_customize ){
// Load our custom control.
require_once get_template_directory() . '/inc/custom-controls/note/class-note-control.php';
require_once get_template_directory() . '/inc/custom-controls/radioimg/class-radio-image-control.php';
require_once get_template_directory() . '/inc/custom-controls/select/class-select-control.php';
require_once get_template_directory() . '/inc/custom-controls/slider/class-slider-control.php';
require_once get_template_directory() . '/inc/custom-controls/toggle/class-toggle-control.php';
require_once get_template_directory() . '/inc/custom-controls/repeater/class-repeater-setting.php';
require_once get_template_directory() . '/inc/custom-controls/repeater/class-control-repeater.php';
// Register the control type.
$wp_customize->register_control_type( 'Rara_Business_Radio_Image_Control' );
$wp_customize->register_control_type( 'Rara_Business_Select_Control' );
$wp_customize->register_control_type( 'Rara_Business_Slider_Control' );
$wp_customize->register_control_type( 'Rara_Business_Toggle_Control' );
}
endif;
add_action( 'customize_register', 'rara_business_register_custom_controls' );

View File

@@ -0,0 +1,27 @@
<?php
/**
* Customizer Control: Note.
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Note_Control' ) ) {
class Rara_Business_Note_Control extends WP_Customize_Control {
public function render_content(){ ?>
<span class="customize-control-title">
<?php echo esc_html( $this->label ); ?>
</span>
<?php if( $this->description ){ ?>
<span class="description customize-control-description">
<?php echo wp_kses_post($this->description); ?>
</span>
<?php }
}
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* Customizer Control: radio-image.
*
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Radio_Image_Control' ) ) {
/**
* Radio Image control (modified radio).
*/
class Rara_Business_Radio_Image_Control extends WP_Customize_Control {
public $type = 'radio-image';
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['value'] = $this->value();
$this->json['choices'] = $this->choices;
$this->json['link'] = $this->get_link();
$this->json['id'] = $this->id;
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
}
public function enqueue() {
wp_enqueue_style( 'rara-business-radio-image', get_template_directory_uri() . '/inc/custom-controls/radioimg/radio-image.css', null );
wp_enqueue_script( 'rara-business-radio-image', get_template_directory_uri() . '/inc/custom-controls/radioimg/radio-image.js', array( 'jquery' ), false, true ); //for radio-image
}
protected function content_template() {
?>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<label class="customizer-text">
<# if ( data.label ) { #>
<span class="customize-control-title">{{{ data.label }}}</span>
<# } #>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
</label>
<div id="input_{{ data.id }}" class="image">
<# for ( key in data.choices ) { #>
<input {{{ data.inputAttrs }}} class="image-select" type="radio" value="{{ key }}" name="_customize-radio-{{ data.id }}" id="{{ data.id }}{{ key }}" {{{ data.link }}}<# if ( data.value === key ) { #> checked="checked"<# } #>>
<label for="{{ data.id }}{{ key }}">
<img src="{{ data.choices[ key ] }}">
<span class="image-clickable"></span>
</label>
</input>
<# } #>
</div>
<?php
}
}
}

View File

@@ -0,0 +1,26 @@
/*Radio Image Button */
.customize-control-radio-image label {
position: relative;
display: inline-block;
margin-bottom: 10px;
}
.customize-control-radio-image input {
display: none;
}
.customize-control-radio-image input img {
border: 1px solid transparent;
}
.customize-control-radio-image input:checked + label img {
-webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);
border: 1px solid #3498DB;
}
.customize-control-radio-image input + label .image-clickable {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
width: 100%;
}
/*Radio Image Button Ends */

View File

@@ -0,0 +1,16 @@
wp.customize.controlConstructor['radio-image'] = wp.customize.Control.extend({
ready: function() {
'use strict';
var control = this;
// Change the value
this.container.on( 'click', 'input', function() {
control.setting.set( jQuery( this ).val() );
});
}
});

View File

@@ -0,0 +1,508 @@
<?php
/**
* Rara Business Customizer Repeater Control.
*
* @package Rara_Business
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if( ! class_exists( 'Rara_Business_Control_Repeater' ) ) {
/**
* Repeater control
*/
class Rara_Business_Control_Repeater extends WP_Customize_Control {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'rara-business-repeater';
/**
* Data type
*
* @access public
* @var string
*/
public $option_type = 'theme_mod';
/**
* The fields that each container row will contain.
*
* @access public
* @var array
*/
public $fields = array();
/**
* Will store a filtered version of value for advenced fields (like images).
*
* @access protected
* @var array
*/
protected $filtered_value = array();
/**
* The row label
*
* @access public
* @var array
*/
public $row_label = array();
/**
* Constructor.
* Supplied `$args` override class property defaults.
* If `$args['settings']` is not defined, use the $id as the setting ID.
*
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
* @param string $id Control ID.
* @param array $args {@see WP_Customize_Control::__construct}.
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
// Set up defaults for row labels.
$this->row_label = array(
'type' => 'text',
'value' => esc_attr__( 'row', 'rara-business' ),
'field' => false,
);
// Validate row-labels.
$this->row_label( $args );
if ( empty( $this->button_label ) ) {
$this->button_label = sprintf( esc_attr__( 'Add new %s', 'rara-business' ), $this->row_label['value'] );
}
if ( empty( $args['fields'] ) || ! is_array( $args['fields'] ) ) {
$args['fields'] = array();
}
// An array to store keys of fields that need to be filtered.
$media_fields_to_filter = array();
foreach ( $args['fields'] as $key => $value ) {
$args['fields'][ $key ]['default'] = ( isset( $value['default'] ) ) ? $value['default'] : '';
$args['fields'][ $key ]['id'] = $key;
// We check if the filed is an uploaded media ( image , file, video, etc.. ).
if ( isset( $value['type'] ) ) {
switch ( $value['type'] ) {
case 'image':
case 'cropped_image':
case 'upload':
// We add it to the list of fields that need some extra filtering/processing.
$media_fields_to_filter[ $key ] = true;
break;
}
}
}
$this->fields = $args['fields'];
// Now we are going to filter the fields.
// First we create a copy of the value that would be used otherwise.
$this->filtered_value = $this->value();
if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) {
// We iterate over the list of fields.
foreach ( $this->filtered_value as &$filtered_value_field ) {
if ( is_array( $filtered_value_field ) && ! empty( $filtered_value_field ) ) {
// We iterate over the list of properties for this field.
foreach ( $filtered_value_field as $key => &$value ) {
// We check if this field was marked as requiring extra filtering (in this case image, cropped_images, upload).
if ( array_key_exists( $key, $media_fields_to_filter ) ) {
// What follows was made this way to preserve backward compatibility.
// The repeater control use to store the URL for images instead of the attachment ID.
// We check if the value look like an ID (otherwise it's probably a URL so don't filter it).
if ( is_numeric( $value ) ) {
// "sanitize" the value.
$attachment_id = (int) $value;
// Try to get the attachment_url.
$url = wp_get_attachment_url( $attachment_id );
$filename = basename( get_attached_file( $attachment_id ) );
// If we got a URL.
if ( $url ) {
// 'id' is needed for form hidden value, URL is needed to display the image.
$value = array(
'id' => $attachment_id,
'url' => $url,
'filename' => $filename,
);
}
}
}
}
}
}
}
}
/**
* Refresh the parameters passed to the JavaScript via JSON.
*
* @access public
*/
public function to_json() {
parent::to_json();
$this->json['default'] = ( isset( $this->default ) ) ? $this->default : $this->setting->default;
$this->json['value'] = $this->value();
$this->json['choices'] = $this->choices;
$this->json['link'] = $this->get_link();
$this->json['id'] = $this->id;
if ( 'user_meta' === $this->option_type ) {
$this->json['value'] = get_user_meta( get_current_user_id(), $this->id, true );
}
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
$fields = $this->fields;
$this->json['fields'] = $fields;
$this->json['row_label'] = $this->row_label;
// If filtered_value has been set and is not empty we use it instead of the actual value.
if ( is_array( $this->filtered_value ) && ! empty( $this->filtered_value ) ) {
$this->json['value'] = $this->filtered_value;
}
}
/**
* Enqueue control related scripts/styles.
*
* @access public
*/
public function enqueue() {
// If we have a color picker field we need to enqueue the WordPress Color Picker style and script.
if ( is_array( $this->fields ) && ! empty( $this->fields ) ) {
foreach ( $this->fields as $field ) {
if ( isset( $field['type'] ) ){
if( 'color' === $field['type'] ){
wp_enqueue_script( 'wp-color-picker' );
wp_enqueue_style( 'wp-color-picker' );
}elseif( 'font' === $field['type'] ){
wp_enqueue_script( 'all', get_template_directory_uri() . '/js/all.min.js', array( 'jquery' ), '6.1.1', true );
wp_enqueue_script( 'v4-shims', get_template_directory_uri() . '/js/v4-shims.min.js', array( 'jquery', 'all' ), '6.1.1', true );
}
}
}
}
wp_enqueue_script( 'rara-business-repeater', get_template_directory_uri() . '/inc/custom-controls/repeater/repeater.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-sortable' ), false, true );
wp_enqueue_style( 'rara-business-repeater', get_template_directory_uri() . '/inc/custom-controls/repeater/repeater.css', null );
}
/**
* Render the control's content.
* Allows the content to be overriden without having to rewrite the wrapper in $this->render().
*
* @access protected
*/
protected function render_content() {
?>
<label>
<?php if ( ! empty( $this->label ) ) : ?>
<span class="customize-control-title"><?php echo esc_html( $this->label ); ?></span>
<?php endif; ?>
<?php if ( ! empty( $this->description ) ) : ?>
<span class="description customize-control-description"><?php echo wp_kses_post( $this->description ); ?></span>
<?php endif; ?>
<input type="hidden" {{{ data.inputAttrs }}} value="" <?php echo wp_kses_post( $this->get_link() ); ?> />
</label>
<ul class="repeater-fields"></ul>
<?php if ( isset( $this->choices['limit'] ) ) : ?>
<p class="limit"><?php printf( esc_html__( 'Limit: %s rows', 'rara-business' ), esc_html( $this->choices['limit'] ) ); ?></p>
<?php endif; ?>
<button class="button-secondary repeater-add"><?php echo esc_html( $this->button_label ); ?></button>
<?php
$this->repeater_js_template();
}
/**
* An Underscore (JS) template for this control's content (but not its container).
* Class variables for this control class are available in the `data` JS object.
*
* @access public
*/
public function repeater_js_template() {
?>
<script type="text/html" class="customize-control-repeater-content">
<# var field; var index = data.index; #>
<li class="repeater-row minimized" data-row="{{{ index }}}">
<div class="repeater-row-header">
<span class="repeater-row-label"></span>
<i class="dashicons dashicons-arrow-down repeater-minimize"></i>
</div>
<div class="repeater-row-content">
<# _.each( data, function( field, i ) { #>
<div class="repeater-field repeater-field-{{{ field.type }}}">
<# if ( 'text' === field.type || 'font' === field.type || 'url' === field.type || 'link' === field.type || 'email' === field.type || 'tel' === field.type || 'date' === field.type ) { #>
<# if ( 'link' === field.type ) { #>
<# field.type = 'url' #>
<# } #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<input type="{{field.type}}" name="" value="{{{ field.default }}}" data-field="{{{ field.id }}}">
</label>
<# } else if ( 'hidden' === field.type ) { #>
<input type="hidden" data-field="{{{ field.id }}}" <# if ( field.default ) { #> value="{{{ field.default }}}" <# } #> />
<# } else if ( 'checkbox' === field.type ) { #>
<label>
<input type="checkbox" value="true" data-field="{{{ field.id }}}" <# if ( field.default ) { #> checked="checked" <# } #> /> {{ field.label }}
<# if ( field.description ) { #>
{{ field.description }}
<# } #>
</label>
<# } else if ( 'select' === field.type ) { #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<select data-field="{{{ field.id }}}">
<# _.each( field.choices, function( choice, i ) { #>
<option value="{{{ i }}}" <# if ( field.default == i ) { #> selected="selected" <# } #>>{{ choice }}</option>
<# }); #>
</select>
</label>
<# } else if ( 'radio' === field.type ) { #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<# _.each( field.choices, function( choice, i ) { #>
<label>
<input type="radio" name="{{{ field.id }}}{{ index }}" data-field="{{{ field.id }}}" value="{{{ i }}}" <# if ( field.default == i ) { #> checked="checked" <# } #>> {{ choice }} <br/>
</label>
<# }); #>
</label>
<# } else if ( 'radio-image' === field.type ) { #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<# _.each( field.choices, function( choice, i ) { #>
<input type="radio" id="{{{ field.id }}}_{{ index }}_{{{ i }}}" name="{{{ field.id }}}{{ index }}" data-field="{{{ field.id }}}" value="{{{ i }}}" <# if ( field.default == i ) { #> checked="checked" <# } #>>
<label for="{{{ field.id }}}_{{ index }}_{{{ i }}}">
<img src="{{ choice }}">
</label>
</input>
<# }); #>
</label>
<# } else if ( 'color' === field.type ) { #>
<# var defaultValue = '';
if ( field.default ) {
if ( '#' !== field.default.substring( 0, 1 ) ) {
defaultValue = '#' + field.default;
} else {
defaultValue = field.default;
}
defaultValue = ' data-default-color=' + defaultValue; // Quotes added automatically.
} #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{{ field.label }}}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{{ field.description }}}</span>
<# } #>
<input class="color-picker-hex" type="text" maxlength="7" placeholder="<?php echo esc_attr__( 'Hex Value', 'rara-business' ); ?>" value="{{{ field.default }}}" data-field="{{{ field.id }}}" {{ defaultValue }} />
</label>
<# } else if ( 'textarea' === field.type ) { #>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<textarea rows="5" data-field="{{{ field.id }}}">{{ field.default }}</textarea>
<# } else if ( field.type === 'image' || field.type === 'cropped_image' ) { #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
</label>
<figure class="rara-business-image-attachment" data-placeholder="<?php esc_attr_e( 'No Image Selected', 'rara-business' ); ?>" >
<# if ( field.default ) { #>
<# var defaultImageURL = ( field.default.url ) ? field.default.url : field.default; #>
<img src="{{{ defaultImageURL }}}">
<# } else { #>
<?php esc_attr_e( 'No Image Selected', 'rara-business' ); ?>
<# } #>
</figure>
<div class="actions">
<button type="button" class="button remove-button<# if ( ! field.default ) { #> hidden<# } #>"><?php esc_html_e( 'Remove', 'rara-business' ); ?></button>
<button type="button" class="button upload-button" data-label=" <?php esc_attr_e( 'Add Image', 'rara-business' ); ?>" data-alt-label="<?php esc_attr_e( 'Change Image', 'rara-business' ); ?>" >
<# if ( field.default ) { #>
<?php esc_attr_e( 'Change Image', 'rara-business' ); ?>
<# } else { #>
<?php esc_attr_e( 'Add Image', 'rara-business' ); ?>
<# } #>
</button>
<# if ( field.default.id ) { #>
<input type="hidden" class="hidden-field" value="{{{ field.default.id }}}" data-field="{{{ field.id }}}" >
<# } else { #>
<input type="hidden" class="hidden-field" value="{{{ field.default }}}" data-field="{{{ field.id }}}" >
<# } #>
</div>
<# } else if ( field.type === 'upload' ) { #>
<label>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
</label>
<figure class="rara-business-file-attachment" data-placeholder="<?php esc_attr_e( 'No File Selected', 'rara-business' ); ?>" >
<# if ( field.default ) { #>
<# var defaultFilename = ( field.default.filename ) ? field.default.filename : field.default; #>
<span class="file"><span class="dashicons dashicons-media-default"></span> {{ defaultFilename }}</span>
<# } else { #>
<?php esc_attr_e( 'No File Selected', 'rara-business' ); ?>
<# } #>
</figure>
<div class="actions">
<button type="button" class="button remove-button<# if ( ! field.default ) { #> hidden<# } #>"></button>
<button type="button" class="button upload-button" data-label="<?php esc_attr_e( 'Add File', 'rara-business' ); ?>" data-alt-label="<?php esc_attr_e( 'Change File', 'rara-business' ); ?>" >
<# if ( field.default ) { #>
<?php esc_attr_e( 'Change File', 'rara-business' ); ?>
<# } else { #>
<?php esc_attr_e( 'Add File', 'rara-business' ); ?>
<# } #>
</button>
<# if ( field.default.id ) { #>
<input type="hidden" class="hidden-field" value="{{{ field.default.id }}}" data-field="{{{ field.id }}}" >
<# } else { #>
<input type="hidden" class="hidden-field" value="{{{ field.default }}}" data-field="{{{ field.id }}}" >
<# } #>
</div>
<# } else if ( 'custom' === field.type ) { #>
<# if ( field.label ) { #>
<span class="customize-control-title">{{ field.label }}</span>
<# } #>
<# if ( field.description ) { #>
<span class="description customize-control-description">{{ field.description }}</span>
<# } #>
<div data-field="{{{ field.id }}}">{{{ field.default }}}</div>
<# } #>
</div>
<# }); #>
<button type="button" class="button-link repeater-row-remove"><?php esc_html_e( 'Remove', 'rara-business' ); ?></button>
</div>
</li>
</script>
<?php
}
/**
* Validate row-labels.
*
* @access protected
* @since 2.4.0
* @param array $args {@see WP_Customize_Control::__construct}.
*/
protected function row_label( $args ) {
// Validating args for row labels.
if ( isset( $args['row_label'] ) && is_array( $args['row_label'] ) && ! empty( $args['row_label'] ) ) {
// Validating row label type.
if ( isset( $args['row_label']['type'] ) && ( 'text' === $args['row_label']['type'] || 'field' === $args['row_label']['type'] ) ) {
$this->row_label['type'] = $args['row_label']['type'];
}
// Validating row label type.
if ( isset( $args['row_label']['value'] ) && ! empty( $args['row_label']['value'] ) ) {
$this->row_label['value'] = esc_attr( $args['row_label']['value'] );
}
// Validating row label field.
if ( isset( $args['row_label']['field'] ) && ! empty( $args['row_label']['field'] ) && isset( $args['fields'][ esc_attr( $args['row_label']['field'] ) ] ) ) {
$this->row_label['field'] = esc_attr( $args['row_label']['field'] );
} else {
// If from field is not set correctly, making sure standard is set as the type.
$this->row_label['type'] = 'text';
}
}
}
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* Rara Business Repeater Customizer Setting.
*
* @package Rara_Business
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Repeater_Setting' ) ) {
/**
* Repeater Settings.
*/
class Rara_Business_Repeater_Setting extends WP_Customize_Setting {
/**
* Constructor.
*
* Any supplied $args override class property defaults.
*
* @access public
* @param WP_Customize_Manager $manager The WordPress WP_Customize_Manager object.
* @param string $id A specific ID of the setting. Can be a theme mod or option name.
* @param array $args Setting arguments.
*/
public function __construct( $manager, $id, $args = array() ) {
parent::__construct( $manager, $id, $args );
// Will onvert the setting from JSON to array. Must be triggered very soon.
add_filter( "customize_sanitize_{$this->id}", array( $this, 'sanitize_repeater_setting' ), 10, 1 );
}
/**
* Fetch the value of the setting.
*
* @access public
* @return mixed The value.
*/
public function value() {
$value = parent::value();
if ( ! is_array( $value ) ) {
$value = array();
}
return $value;
}
/**
* Convert the JSON encoded setting coming from Customizer to an Array.
*
* @access public
* @param string $value URL Encoded JSON Value.
* @return array
*/
public static function sanitize_repeater_setting( $value ){
if ( ! is_array( $value ) ) {
$value = json_decode( urldecode( $value ) );
}
$sanitized = ( empty( $value ) || ! is_array( $value ) ) ? array() : $value;
// Make sure that every row is an array, not an object.
foreach ( $sanitized as $key => $_value ) {
if ( empty( $_value ) ) {
unset( $sanitized[ $key ] );
} else {
$sanitized[ $key ] = (array) $_value;
}
}
// Reindex array.
$sanitized = array_values( $sanitized );
return $sanitized;
}
}
}

View File

@@ -0,0 +1,204 @@
.customize-control-rara-business-repeater .repeater-fields .repeater-row {
border: 1px solid #999;
margin-top: 0.5rem;
background: #eee;
position: relative;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row.minimized {
border: 1px solid #dfdfdf;
padding: 0;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row.minimized:hover {
border: 1px solid #999;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row.minimized .repeater-row-content {
display: none;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row label {
margin-bottom: 12px;
clear: both;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row .repeater-field.repeater-field- {
display: none;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input {
display: none;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input img {
border: 1px solid transparent;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row .repeater-field.repeater-field-radio-image input:checked + label img {
-webkit-box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);
box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.25);
border: 1px solid #3498DB;
}
.customize-control-rara-business-repeater .repeater-fields .repeater-row .repeater-field:last-child {
border-bottom: none;
padding-bottom: 0;
}
.customize-control-rara-business-repeater button.repeater-add {
margin-top: 1rem;
}
.customize-control-rara-business-repeater .repeater-row-content {
padding: 10px 15px;
}
.customize-control-rara-business-repeater .repeater-field {
margin-bottom: 12px;
width: 100%;
clear: both;
padding-bottom: 12px;
border-bottom: 1px dotted #CCC;
}
.customize-control-rara-business-repeater .repeater-field .customize-control-title {
font-size: 13px;
line-height: initial;
}
.customize-control-rara-business-repeater .repeater-field .customize-control-description {
font-size: 13px;
line-height: initial;
}
.customize-control-rara-business-repeater .repeater-field.repeater-field-hidden {
margin: 0;
padding: 0;
border: 0;
}
.customize-control-rara-business-repeater .repeater-field-select select {
margin-left: 0;
}
.customize-control-rara-business-repeater .repeater-field-checkbox label {
line-height: 28px;
}
.customize-control-rara-business-repeater .repeater-field-checkbox input {
line-height: 28px;
margin-right: 5px;
}
.customize-control-rara-business-repeater .repeater-field-textarea textarea {
width: 100%;
resize: vertical;
}
.customize-control-rara-business-repeater .repeater-row-header {
background: white;
border: 1px solid #dfdfdf;
position: relative;
padding: 10px 15px;
height: auto;
min-height: 20px;
line-height: 30px;
overflow: hidden;
word-wrap: break-word;
}
.customize-control-rara-business-repeater .repeater-row-header:hover {
cursor: move;
}
.customize-control-rara-business-repeater .repeater-row-header .dashicons {
font-size: 18px;
position: absolute;
right: 12px;
top: 2px;
color: #a0a5aa;
}
.customize-control-rara-business-repeater .repeater-row-label {
font-size: 13px;
font-weight: 600;
line-height: 20px;
display: block;
width: 90%;
overflow: hidden;
height: 18px;
}
.customize-control-rara-business-repeater .repeater-row-remove {
color: #a00;
}
.customize-control-rara-business-repeater .repeater-row-remove:hover {
color: #f00;
}
.customize-control-rara-business-repeater .repeater-minimize {
line-height: 36px;
}
.customize-control-rara-business-repeater .remove-button,
.customize-control-rara-business-repeater .upload-button {
width: 48%;
}
.rara-business-image-attachment {
margin: 0;
text-align: center;
margin-bottom: 10px;
}
.rara-business-image-attachment img {
display: inline-block;
}
.rara-business-file-attachment {
margin: 0;
text-align: center;
margin-bottom: 10px;
}
.rara-business-file-attachment .file {
display: block;
padding: 10px 5px;
border: 1px dotted #c3c3c3;
background: #f9f9f9;
}
.limit {
padding: 3px;
border-radius: 3px;
}
.limit.highlight {
background: #D32F2F;
color: #fff;
}
/** Font awesome list */
.font-group{
text-align: center;
height: 350px;
overflow-y: scroll;
position: relative;
border: 1px solid #EEE;
margin: 0;
}
.font-group li{
width: 50px;
height: 50px;
display: inline-block;
margin: 4px;
cursor: pointer;
font-size: 25px;
}
input[type="font"]{
width: 100%;
border: 0;
}

View File

@@ -0,0 +1,860 @@
/*jshint -W065 */
var rarabusinessRepeaterRow = function( rowIndex, container, label ){
'use strict';
var self = this;
this.rowIndex = rowIndex;
this.container = container;
this.label = label;
this.header = this.container.find( '.repeater-row-header' ),
this.header.on( 'click', function() {
self.toggleMinimize();
});
this.container.on( 'click', '.repeater-row-remove', function() {
self.remove();
});
this.header.on( 'mousedown', function() {
self.container.trigger( 'row:start-dragging' );
});
this.container.on( 'keyup change', 'input, select, textarea', function( e ) {
self.container.trigger( 'row:update', [ self.rowIndex, jQuery( e.target ).data( 'field' ), e.target ] );
});
this.setRowIndex = function( rowIndex ) {
this.rowIndex = rowIndex;
this.container.attr( 'data-row', rowIndex );
this.container.data( 'row', rowIndex );
this.updateLabel();
};
this.toggleMinimize = function() {
// Store the previous state.
this.container.toggleClass( 'minimized' );
this.header.find( '.dashicons' ).toggleClass( 'dashicons-arrow-up' ).toggleClass( 'dashicons-arrow-down' );
};
this.remove = function() {
this.container.slideUp( 300, function() {
jQuery( this ).detach();
});
this.container.trigger( 'row:remove', [ this.rowIndex ] );
};
this.updateLabel = function() {
var rowLabelField,
rowLabel;
if ( 'field' === this.label.type ) {
rowLabelField = this.container.find( '.repeater-field [data-field="' + this.label.field + '"]' );
if ( 'function' === typeof rowLabelField.val ) {
rowLabel = rowLabelField.val();
if ( '' !== rowLabel ) {
this.header.find( '.repeater-row-label' ).text( rowLabel );
return;
}
}
}
this.header.find( '.repeater-row-label' ).text( this.label.value + ' ' + ( this.rowIndex + 1 ) );
};
this.updateLabel();
};
wp.customize.controlConstructor['rara-business-repeater'] = wp.customize.Control.extend({
ready: function(){
'use strict';
var control = this,
limit,
theNewRow;
// The current value set in Control Class (set in Rara_Business_Control_Repeater::to_json() function)
var settingValue = this.params.value;
// The hidden field that keeps the data saved (though we never update it)
this.settingField = this.container.find( '[data-customize-setting-link]' ).first();
// Set the field value for the first time, we'll fill it up later
this.setValue( [], false );
// The DIV that holds all the rows
this.repeaterFieldsContainer = this.container.find( '.repeater-fields' ).first();
// Set number of rows to 0
this.currentIndex = 0;
// Save the rows objects
this.rows = [];
// Default limit choice
limit = false;
if ( 'undefined' !== typeof this.params.choices.limit ) {
limit = ( 0 >= this.params.choices.limit ) ? false : parseInt( this.params.choices.limit );
}
this.container.on( 'click', 'button.repeater-add', function( e ) {
e.preventDefault();
if ( ! limit || control.currentIndex < limit ) {
theNewRow = control.addRow();
theNewRow.toggleMinimize();
control.initColorPicker();
//control.initDropdownPages( theNewRow );
} else {
jQuery( control.selector + ' .limit' ).addClass( 'highlight' );
}
});
this.container.on( 'click', '.repeater-row-remove', function( e ) {
control.currentIndex--;
if ( ! limit || control.currentIndex < limit ) {
jQuery( control.selector + ' .limit' ).removeClass( 'highlight' );
}
});
this.container.on( 'click keypress', '.repeater-field-image .upload-button,.repeater-field-cropped_image .upload-button,.repeater-field-upload .upload-button', function( e ) {
e.preventDefault();
control.$thisButton = jQuery( this );
control.openFrame( e );
});
this.container.on( 'click keypress', '.repeater-field-image .remove-button,.repeater-field-cropped_image .remove-button', function( e ) {
e.preventDefault();
control.$thisButton = jQuery( this );
control.removeImage( e );
});
this.container.on( 'click keypress', '.repeater-field-upload .remove-button', function( e ) {
e.preventDefault();
control.$thisButton = jQuery( this );
control.removeFile( e );
});
/**
* Function that loads the Mustache template
*/
this.repeaterTemplate = _.memoize( function() {
var compiled,
/*
* Underscore's default ERB-style templates are incompatible with PHP
* when asp_tags is enabled, so WordPress uses Mustache-inspired templating syntax.
*
* @see trac ticket #22344.
*/
options = {
evaluate: /<#([\s\S]+?)#>/g,
interpolate: /\{\{\{([\s\S]+?)\}\}\}/g,
escape: /\{\{([^\}]+?)\}\}(?!\})/g,
variable: 'data'
};
return function( data ) {
compiled = _.template( control.container.find( '.customize-control-repeater-content' ).first().html(), null, options );
return compiled( data );
};
});
// When we load the control, the fields have not been filled up
// This is the first time that we create all the rows
if( settingValue.length ){
_.each( settingValue, function( subValue ) {
theNewRow = control.addRow( subValue );
control.initColorPicker();
//control.initDropdownPages( theNewRow, subValue );
});
}
// Once we have displayed the rows, we cleanup the values
this.setValue( settingValue, true, true );
this.repeaterFieldsContainer.sortable({
handle: '.repeater-row-header',
update: function( e, ui ) {
control.sort();
}
});
},
/**
* Open the media modal.
*/
openFrame: function( event ){
'use strict';
if ( wp.customize.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
if ( this.$thisButton.closest( '.repeater-field' ).hasClass( 'repeater-field-cropped_image' ) ) {
this.initCropperFrame();
} else {
this.initFrame();
}
this.frame.open();
},
initFrame: function(){
'use strict';
var libMediaType = this.getMimeType();
this.frame = wp.media({
states: [
new wp.media.controller.Library({
library: wp.media.query({ type: libMediaType }),
multiple: false,
date: false
})
]
});
// When a file is selected, run a callback.
this.frame.on( 'select', this.onSelect, this );
},
/**
* Create a media modal select frame, and store it so the instance can be reused when needed.
* This is mostly a copy/paste of Core api.CroppedImageControl in /wp-admin/js/customize-control.js
*/
initCropperFrame: function(){
'use strict';
// We get the field id from which this was called
var currentFieldId = this.$thisButton.siblings( 'input.hidden-field' ).attr( 'data-field' ),
attrs = [ 'width', 'height', 'flex_width', 'flex_height' ], // A list of attributes to look for
libMediaType = this.getMimeType();
// Make sure we got it
if ( 'string' === typeof currentFieldId && '' !== currentFieldId ) {
// Make fields is defined and only do the hack for cropped_image
if ( 'object' === typeof this.params.fields[ currentFieldId ] && 'cropped_image' === this.params.fields[ currentFieldId ].type ) {
//Iterate over the list of attributes
attrs.forEach( function( el, index ) {
// If the attribute exists in the field
if ( 'undefined' !== typeof this.params.fields[ currentFieldId ][ el ] ) {
// Set the attribute in the main object
this.params[ el ] = this.params.fields[ currentFieldId ][ el ];
}
}.bind( this ) );
}
}
this.frame = wp.media({
button: {
text: 'Select and Crop',
close: false
},
states: [
new wp.media.controller.Library({
library: wp.media.query({ type: libMediaType }),
multiple: false,
date: false,
suggestedWidth: this.params.width,
suggestedHeight: this.params.height
}),
new wp.media.controller.CustomizeImageCropper({
imgSelectOptions: this.calculateImageSelectOptions,
control: this
})
]
});
this.frame.on( 'select', this.onSelectForCrop, this );
this.frame.on( 'cropped', this.onCropped, this );
this.frame.on( 'skippedcrop', this.onSkippedCrop, this );
},
onSelect: function(){
'use strict';
var attachment = this.frame.state().get( 'selection' ).first().toJSON();
if ( this.$thisButton.closest( '.repeater-field' ).hasClass( 'repeater-field-upload' ) ) {
this.setFileInRepeaterField( attachment );
} else {
this.setImageInRepeaterField( attachment );
}
},
/**
* After an image is selected in the media modal, switch to the cropper
* state if the image isn't the right size.
*/
onSelectForCrop: function(){
'use strict';
var attachment = this.frame.state().get( 'selection' ).first().toJSON();
if ( this.params.width === attachment.width && this.params.height === attachment.height && ! this.params.flex_width && ! this.params.flex_height ) {
this.setImageInRepeaterField( attachment );
} else {
this.frame.setState( 'cropper' );
}
},
/**
* After the image has been cropped, apply the cropped image data to the setting.
*
* @param {object} croppedImage Cropped attachment data.
*/
onCropped: function( croppedImage ){
'use strict';
this.setImageInRepeaterField( croppedImage );
},
/**
* Returns a set of options, computed from the attached image data and
* control-specific data, to be fed to the imgAreaSelect plugin in
* wp.media.view.Cropper.
*
* @param {wp.media.model.Attachment} attachment
* @param {wp.media.controller.Cropper} controller
* @returns {Object} Options
*/
calculateImageSelectOptions: function( attachment, controller ){
'use strict';
var control = controller.get( 'control' ),
flexWidth = !! parseInt( control.params.flex_width, 10 ),
flexHeight = !! parseInt( control.params.flex_height, 10 ),
realWidth = attachment.get( 'width' ),
realHeight = attachment.get( 'height' ),
xInit = parseInt( control.params.width, 10 ),
yInit = parseInt( control.params.height, 10 ),
ratio = xInit / yInit,
xImg = realWidth,
yImg = realHeight,
x1,
y1,
imgSelectOptions;
controller.set( 'canSkipCrop', ! control.mustBeCropped( flexWidth, flexHeight, xInit, yInit, realWidth, realHeight ) );
if ( xImg / yImg > ratio ) {
yInit = yImg;
xInit = yInit * ratio;
} else {
xInit = xImg;
yInit = xInit / ratio;
}
x1 = ( xImg - xInit ) / 2;
y1 = ( yImg - yInit ) / 2;
imgSelectOptions = {
handles: true,
keys: true,
instance: true,
persistent: true,
imageWidth: realWidth,
imageHeight: realHeight,
x1: x1,
y1: y1,
x2: xInit + x1,
y2: yInit + y1
};
if ( false === flexHeight && false === flexWidth ) {
imgSelectOptions.aspectRatio = xInit + ':' + yInit;
}
if ( false === flexHeight ) {
imgSelectOptions.maxHeight = yInit;
}
if ( false === flexWidth ) {
imgSelectOptions.maxWidth = xInit;
}
return imgSelectOptions;
},
/**
* Return whether the image must be cropped, based on required dimensions.
*
* @param {bool} flexW
* @param {bool} flexH
* @param {int} dstW
* @param {int} dstH
* @param {int} imgW
* @param {int} imgH
* @return {bool}
*/
mustBeCropped: function( flexW, flexH, dstW, dstH, imgW, imgH ){
'use strict';
if ( true === flexW && true === flexH ) {
return false;
}
if ( true === flexW && dstH === imgH ) {
return false;
}
if ( true === flexH && dstW === imgW ) {
return false;
}
if ( dstW === imgW && dstH === imgH ) {
return false;
}
if ( imgW <= dstW ) {
return false;
}
return true;
},
/**
* If cropping was skipped, apply the image data directly to the setting.
*/
onSkippedCrop: function(){
'use strict';
var attachment = this.frame.state().get( 'selection' ).first().toJSON();
this.setImageInRepeaterField( attachment );
},
/**
* Updates the setting and re-renders the control UI.
*
* @param {object} attachment
*/
setImageInRepeaterField: function( attachment ){
'use strict';
var $targetDiv = this.$thisButton.closest( '.repeater-field-image,.repeater-field-cropped_image' );
$targetDiv.find( '.rara-business-image-attachment' ).html( '<img src="' + attachment.url + '">' ).hide().slideDown( 'slow' );
$targetDiv.find( '.hidden-field' ).val( attachment.id );
this.$thisButton.text( this.$thisButton.data( 'alt-label' ) );
$targetDiv.find( '.remove-button' ).show();
//This will activate the save button
$targetDiv.find( 'input, textarea, select' ).trigger( 'change' );
this.frame.close();
},
/**
* Updates the setting and re-renders the control UI.
*
* @param {object} attachment
*/
setFileInRepeaterField: function( attachment ){
'use strict';
var $targetDiv = this.$thisButton.closest( '.repeater-field-upload' );
$targetDiv.find( '.rara-business-file-attachment' ).html( '<span class="file"><span class="dashicons dashicons-media-default"></span> ' + attachment.filename + '</span>' ).hide().slideDown( 'slow' );
$targetDiv.find( '.hidden-field' ).val( attachment.id );
this.$thisButton.text( this.$thisButton.data( 'alt-label' ) );
$targetDiv.find( '.upload-button' ).show();
$targetDiv.find( '.remove-button' ).show();
//This will activate the save button
$targetDiv.find( 'input, textarea, select' ).trigger( 'change' );
this.frame.close();
},
getMimeType: function(){
'use strict';
// We get the field id from which this was called
var currentFieldId = this.$thisButton.siblings( 'input.hidden-field' ).attr( 'data-field' ),
attrs = [ 'mime_type' ]; // A list of attributes to look for
// Make sure we got it
if ( 'string' === typeof currentFieldId && '' !== currentFieldId ) {
// Make fields is defined and only do the hack for cropped_image
if ( 'object' === typeof this.params.fields[ currentFieldId ] && 'upload' === this.params.fields[ currentFieldId ].type ) {
// If the attribute exists in the field
if ( 'undefined' !== typeof this.params.fields[ currentFieldId ].mime_type ) {
// Set the attribute in the main object
return this.params.fields[ currentFieldId ].mime_type;
}
}
}
return 'image';
},
removeImage: function( event ){
'use strict';
var $targetDiv,
$uploadButton;
if ( wp.customize.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
$targetDiv = this.$thisButton.closest( '.repeater-field-image,.repeater-field-cropped_image,.repeater-field-upload' );
$uploadButton = $targetDiv.find( '.upload-button' );
$targetDiv.find( '.rara-business-image-attachment' ).slideUp( 'fast', function() {
jQuery( this ).show().html( jQuery( this ).data( 'placeholder' ) );
});
$targetDiv.find( '.hidden-field' ).val( '' );
$uploadButton.text( $uploadButton.data( 'label' ) );
this.$thisButton.hide();
$targetDiv.find( 'input, textarea, select' ).trigger( 'change' );
},
removeFile: function( event ){
'use strict';
var $targetDiv,
$uploadButton;
if ( wp.customize.utils.isKeydownButNotEnterEvent( event ) ) {
return;
}
$targetDiv = this.$thisButton.closest( '.repeater-field-upload' );
$uploadButton = $targetDiv.find( '.upload-button' );
$targetDiv.find( '.rara-business-file-attachment' ).slideUp( 'fast', function() {
jQuery( this ).show().html( jQuery( this ).data( 'placeholder' ) );
});
$targetDiv.find( '.hidden-field' ).val( '' );
$uploadButton.text( $uploadButton.data( 'label' ) );
this.$thisButton.hide();
$targetDiv.find( 'input, textarea, select' ).trigger( 'change' );
},
/**
* Get the current value of the setting
*
* @return Object
*/
getValue: function(){
'use strict';
// The setting is saved in JSON
return JSON.parse( decodeURI( this.setting.get() ) );
},
/**
* Set a new value for the setting
*
* @param newValue Object
* @param refresh If we want to refresh the previewer or not
*/
setValue: function( newValue, refresh, filtering ){
'use strict';
// We need to filter the values after the first load to remove data requrired for diplay but that we don't want to save in DB
var filteredValue = newValue,
filter = [];
if ( filtering ) {
jQuery.each( this.params.fields, function( index, value ) {
if ( 'image' === value.type || 'cropped_image' === value.type || 'upload' === value.type ) {
filter.push( index );
}
});
jQuery.each( newValue, function( index, value ) {
jQuery.each( filter, function( ind, field ) {
if ( 'undefined' !== typeof value[field] && 'undefined' !== typeof value[field].id ) {
filteredValue[index][field] = value[field].id;
}
});
});
}
this.setting.set( encodeURI( JSON.stringify( filteredValue ) ) );
if ( refresh ) {
// Trigger the change event on the hidden field so
// previewer refresh the website on Customizer
this.settingField.trigger( 'change' );
}
},
/**
* Add a new row to repeater settings based on the structure.
*
* @param data (Optional) Object of field => value pairs (undefined if you want to get the default values)
*/
addRow: function( data ){
'use strict';
var control = this,
template = control.repeaterTemplate(), // The template for the new row (defined on Rara_Business_Control_Repeater::render_content() ).
settingValue = this.getValue(), // Get the current setting value.
newRowSetting = {}, // Saves the new setting data.
templateData, // Data to pass to the template
newRow,
i;
if ( template ) {
// The control structure is going to define the new fields
// We need to clone control.params.fields. Assigning it
// ould result in a reference assignment.
templateData = jQuery.extend( true, {}, control.params.fields );
// But if we have passed data, we'll use the data values instead
if ( data ) {
for ( i in data ) {
if ( data.hasOwnProperty( i ) && templateData.hasOwnProperty( i ) ) {
templateData[ i ]['default'] = data[ i ];
}
}
}
templateData.index = this.currentIndex;
// Append the template content
template = template( templateData );
// Create a new row object and append the element
newRow = new rarabusinessRepeaterRow(
control.currentIndex,
jQuery( template ).appendTo( control.repeaterFieldsContainer ),
control.params.row_label
);
newRow.container.on( 'row:remove', function( e, rowIndex ) {
control.deleteRow( rowIndex );
});
newRow.container.on( 'row:update', function( e, rowIndex, fieldName, element ) {
control.updateField.call( control, e, rowIndex, fieldName, element );
newRow.updateLabel();
});
// Add the row to rows collection
this.rows[ this.currentIndex ] = newRow;
for ( i in templateData ) {
if ( templateData.hasOwnProperty( i ) ) {
newRowSetting[ i ] = templateData[ i ]['default'];
}
}
settingValue[ this.currentIndex ] = newRowSetting;
this.setValue( settingValue, true );
this.currentIndex++;
return newRow;
}
},
sort: function(){
'use strict';
var control = this,
$rows = this.repeaterFieldsContainer.find( '.repeater-row' ),
newOrder = [],
settings = control.getValue(),
newRows = [],
newSettings = [];
$rows.each( function( i, element ) {
newOrder.push( jQuery( element ).data( 'row' ) );
});
jQuery.each( newOrder, function( newPosition, oldPosition ) {
newRows[ newPosition ] = control.rows[ oldPosition ];
newRows[ newPosition ].setRowIndex( newPosition );
newSettings[ newPosition ] = settings[ oldPosition ];
});
control.rows = newRows;
control.setValue( newSettings );
},
/**
* Delete a row in the repeater setting
*
* @param index Position of the row in the complete Setting Array
*/
deleteRow: function( index ){
'use strict';
var currentSettings = this.getValue(),
row,
i,
prop;
if ( currentSettings[ index ] ) {
// Find the row
row = this.rows[ index ];
if ( row ) {
// The row exists, let's delete it
// Remove the row settings
delete currentSettings[ index ];
// Remove the row from the rows collection
delete this.rows[ index ];
// Update the new setting values
this.setValue( currentSettings, true );
}
}
// Remap the row numbers
i = 1;
for ( prop in this.rows ) {
if ( this.rows.hasOwnProperty( prop ) && this.rows[ prop ] ) {
this.rows[ prop ].updateLabel();
i++;
}
}
},
/**
* Update a single field inside a row.
* Triggered when a field has changed
*
* @param e Event Object
*/
updateField: function( e, rowIndex, fieldId, element ){
'use strict';
var type,
row,
currentSettings;
if ( ! this.rows[ rowIndex ] ) {
return;
}
if ( ! this.params.fields[ fieldId ] ) {
return;
}
type = this.params.fields[ fieldId].type;
row = this.rows[ rowIndex ];
currentSettings = this.getValue();
element = jQuery( element );
if ( 'undefined' === typeof currentSettings[ row.rowIndex ][ fieldId ] ) {
return;
}
if ( 'checkbox' === type ) {
currentSettings[ row.rowIndex ][ fieldId ] = element.is( ':checked' );
} else {
// Update the settings
currentSettings[ row.rowIndex ][ fieldId ] = element.val();
}
this.setValue( currentSettings, true );
},
/**
* Init the color picker on color fields
* Called after AddRow
*
*/
initColorPicker: function(){
'use strict';
var control = this,
colorPicker = control.container.find( '.color-picker-hex' ),
options = {},
fieldId = colorPicker.data( 'field' );
// We check if the color palette parameter is defined.
if ( 'undefined' !== typeof fieldId && 'undefined' !== typeof control.params.fields[ fieldId ] && 'undefined' !== typeof control.params.fields[ fieldId ].palettes && 'object' === typeof control.params.fields[ fieldId ].palettes ) {
options.palettes = control.params.fields[ fieldId ].palettes;
}
// When the color picker value is changed we update the value of the field
options.change = function( event, ui ) {
var currentPicker = jQuery( event.target ),
row = currentPicker.closest( '.repeater-row' ),
rowIndex = row.data( 'row' ),
currentSettings = control.getValue();
currentSettings[ rowIndex ][ currentPicker.data( 'field' ) ] = ui.color.toString();
control.setValue( currentSettings, true );
};
// Init the color picker
if ( 0 !== colorPicker.length ) {
colorPicker.wpColorPicker( options );
}
},
});
jQuery( document ).ready(function($){
'use strict';
$(document).on('click','.repeater-add',function() {
$('.repeater-field').find('input[type="font"]').attr('placeholder','search icons');
});
$(document).on( 'click', 'input[type="font"]', function(){
var $this = $(this);
if( ( ! $this.hasClass('ajax-running') ) && $this.siblings( '.font-awesome-list' ).length < 1 ){
$.ajax({
type: "POST",
url : ajaxurl,
data: {
action : 'rara_business_get_fontawesome_ajax',
rara_business_customize_nonce: rara_business_customize.nonce
},
beforeSend: function(){
$this.addClass('ajax-running');
},
success: function (response) {
var html = '<div class="font-awesome-list">'+response+'</div>';
$this.after(html);
$this.removeClass('ajax-running');
}
});
}
});
$(document).on( 'click', '.font-group li', function(event){
var val = $(this).data( 'font' );
$(this).parent().parent().siblings( 'input[type="font"]' ).val( val );
$(this).parent().parent().siblings( 'input[type="font"]' ).trigger( 'change' );
$(this).parent().parent().fadeOut( 'slow', function(){
$(this).remove();
});
event.preventDefault();
});
$(document).on( 'keyup', 'input[type="font"]', function(){
var value = $(this).val();
var matcher = new RegExp( value, 'gi' );
$(this).next( '.font-awesome-list' ).children('.font-group').children( 'li' ).show().not(function(){
return matcher.test( $(this).find( 'svg' ).attr( 'class' ) );
}).hide();
});
});

View File

@@ -0,0 +1,87 @@
<?php
/**
* Customizer Control: rara-business-select.
*
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Select_Control' ) ) {
/**
* Select control.
*/
class Rara_Business_Select_Control extends WP_Customize_Control {
public $type = 'rara-business-select';
public $multiple = 1;
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['multiple'] = $this->multiple;
$this->json['value'] = $this->value();
$this->json['choices'] = $this->choices;
$this->json['link'] = $this->get_link();
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
}
public function enqueue() {
wp_enqueue_style( 'rara-business-selectize', get_template_directory_uri() . '/inc/custom-controls/select/select.css', null );
wp_enqueue_script( 'rara-business-selectize', get_template_directory_uri() . '/inc/custom-controls/select/selectize.js', array( 'jquery' ) ); //for multi select
wp_enqueue_script( 'rara-business-select', get_template_directory_uri() . '/inc/custom-controls/select/select.js', array( 'jquery', 'rara-business-selectize' ), false, true ); //for multi select
}
protected function content_template() {
?>
<# if ( ! data.choices ) return; #>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<label>
<# if ( data.label ) { #>
<span class="customize-control-title">{{ data.label }}</span>
<# } #>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<select {{{ data.inputAttrs }}} {{{ data.link }}} data-multiple="{{ data.multiple }}"<# if ( 1 < data.multiple ) { #> multiple<# } #>>
<# if ( 1 < data.multiple && data.value ) { #>
<# for ( key in data.value ) { #>
<option value="{{ data.value[ key ] }}" selected>{{ data.choices[ data.value[ key ] ] }}</option>
<# } #>
<# for ( key in data.choices ) { #>
<# if ( data.value[ key ] in data.value ) { #>
<# } else { #>
<option value="{{ key }}">{{ data.choices[ key ] }}</option>
<# } #>
<# } #>
<# } else { #>
<# for ( key in data.choices ) { #>
<option value="{{ key }}"<# if ( key === data.value ) { #>selected<# } #>>{{ data.choices[ key ] }}</option>
<# } #>
<# } #>
</select>
</label>
<?php
}
}
}

View File

@@ -0,0 +1,300 @@
/* Select Control */
.selectize-control {
position: relative;
}
.selectize-control.single .selectize-input,
.selectize-control.single .selectize-input input {
cursor: pointer;
}
.selectize-control.single .selectize-input.input-active, .selectize-control.single .selectize-input.input-active input {
cursor: text;
}
.selectize-control.single .selectize-input:after {
content: "\f347";
display: block;
position: absolute;
top: 0;
right: 0;
margin-top: 0;
width: 12px;
height: 36px;
font-family: dashicons;
border-left: 1px solid rgba(0, 0, 0, 0.06);
line-height: 36px;
padding: 0 3px;
}
.selectize-control.single .selectize-input.dropdown-active:after {
content: "\f343";
border-left: 1px solid rgba(0, 0, 0, 0.1);
}
.selectize-control.single .selectize-input.disabled {
opacity: 0.5;
background-color: #fafafa;
}
.selectize-control.single.rtl .selectize-input:after {
left: 15px;
right: auto;
}
.selectize-control.rtl .selectize-input > input {
margin: 0 4px 0 -2px !important;
}
.selectize-control .plugin-drag_drop.multi > .selectize-input > div.ui-sortable-placeholder {
visibility: visible !important;
background: #f2f2f2 !important;
background: rgba(0, 0, 0, 0.06) !important;
border: 0 none !important;
-webkit-box-shadow: inset 0 0 12px 4px #ffffff;
box-shadow: inset 0 0 12px 4px #ffffff;
}
.selectize-control .plugin-drag_drop .ui-sortable-placeholder::after {
content: '!';
visibility: hidden;
}
.selectize-control .plugin-drag_drop .ui-sortable-helper {
-webkit-box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
}
.selectize-control .plugin-remove_button [data-value] {
position: relative;
padding-right: 24px !important;
}
.selectize-control .plugin-remove_button [data-value] .remove {
z-index: 1;
/* fixes ie bug (see #392) */
position: absolute;
top: 0;
right: 0;
bottom: 0;
width: 17px;
text-align: center;
font-weight: bold;
font-size: 12px;
color: inherit;
text-decoration: none;
vertical-align: middle;
display: inline-block;
padding: 2px 0 0 0;
border-left: 1px solid #d0d0d0;
-webkit-border-radius: 0 2px 2px 0;
-moz-border-radius: 0 2px 2px 0;
border-radius: 0 2px 2px 0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.selectize-control .plugin-remove_button .remove:hover {
background: rgba(0, 0, 0, 0.05);
}
.selectize-control .plugin-remove_button.active .remove {
border-left-color: #cacaca;
}
.selectize-control .plugin .disabled [data-value] .remove:hover {
background: none;
}
.selectize-control .plugin .disabled [data-value] .remove {
border-left-color: #ffffff;
}
.selectize-control.multi .selectize-input {
min-height: 36px;
}
.selectize-control.multi .selectize-input.has-items {
padding: 6px 8px 3px;
}
.selectize-control.multi .selectize-input > div {
cursor: pointer;
margin: 0 3px 3px 0;
padding: 2px 6px;
background: #f2f2f2;
color: #303030;
border: 0 solid #d0d0d0;
}
.selectize-control.multi .selectize-input > div.active {
background: #e8e8e8;
color: #303030;
border: 0 solid #cacaca;
}
.selectize-control.multi .selectize-input.disabled > div, .selectize-control.multi .selectize-input.disabled > div.active {
color: #7d7d7d;
background: #ffffff;
border: 0 solid #ffffff;
}
.selectize-dropdown {
position: relative;
top: -4px !important;
z-index: 10;
border: 1px solid #d0d0d0;
background: #ffffff;
margin: -1px 0 0 0;
border-top: 0 none;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
z-index: 999;
}
.selectize-dropdown-header {
position: relative;
padding: 5px 8px;
border-bottom: 1px solid #d0d0d0;
background: #f8f8f8;
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
.selectize-dropdown-header-close {
position: absolute;
right: 8px;
top: 50%;
color: #303030;
opacity: 0.4;
margin-top: -12px;
line-height: 20px;
font-size: 20px !important;
}
.selectize-dropdown-header-close:hover {
color: #000000;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup {
border-right: 1px solid #f2f2f2;
border-top: 0 none;
float: left;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup:last-child {
border-right: 0 none;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup:before {
display: none;
}
.selectize-dropdown.plugin-optgroup_columns .optgroup-header {
border-top: 0 none;
}
.selectize-dropdown, .selectize-input, .selectize-input input {
color: #303030;
font-family: inherit;
font-size: 13px;
line-height: 18px;
-webkit-font-smoothing: inherit;
}
.selectize-input, .selectize-control.single .selectize-input.input-active {
background: #ffffff;
cursor: text;
display: inline-block;
}
.selectize-input {
border: 1px solid rgba(0, 0, 0, 0.1);
padding: 8px 8px;
display: inline-block;
width: 100%;
overflow: hidden;
position: relative;
z-index: 1;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
.selectize-input.full {
background-color: #ffffff;
}
.selectize-input.disabled, .selectize-input.disabled * {
cursor: default !important;
}
.selectize-input.focus {
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.15);
}
.selectize-input.dropdown-active {
-webkit-border-radius: 3px 3px 0 0;
-moz-border-radius: 3px 3px 0 0;
border-radius: 3px 3px 0 0;
}
.selectize-input > * {
vertical-align: baseline;
display: -moz-inline-stack;
display: inline-block;
zoom: 1;
*display: inline;
}
.selectize-input > input {
display: inline-block !important;
padding: 0 !important;
min-height: 0 !important;
max-height: none !important;
max-width: 100% !important;
margin: 0 2px 0 0 !important;
text-indent: 0 !important;
border: 0 none !important;
background: none !important;
line-height: inherit !important;
-webkit-user-select: auto !important;
-webkit-box-shadow: none !important;
box-shadow: none !important;
}
.selectize-input > input::-ms-clear {
display: none;
}
.selectize-input > input:focus {
outline: none !important;
}
.selectize-input::after {
content: ' ';
display: block;
clear: left;
}
.selectize-input.dropdown-active::before {
content: ' ';
display: block;
position: absolute;
background: #f0f0f0;
height: 1px;
bottom: 0;
left: 0;
right: 0;
}
.selectize-dropdown [data-selectable] {
cursor: pointer;
overflow: hidden;
}
.selectize-dropdown [data-selectable] .highlight {
background: rgba(125, 168, 208, 0.2);
-webkit-border-radius: 1px;
-moz-border-radius: 1px;
border-radius: 1px;
}
.selectize-dropdown [data-selectable],
.selectize-dropdown .optgroup-header {
padding: 5px 8px;
}
.selectize-dropdown .optgroup:first-child .optgroup-header {
border-top: 0 none;
}
.selectize-dropdown .optgroup-header {
color: #303030;
background: #ffffff;
cursor: default;
}
.selectize-dropdown .active {
background-color: #f5fafd;
color: #495c68;
}
.selectize-dropdown .active.create {
color: #495c68;
}
.selectize-dropdown .create {
color: rgba(48, 48, 48, 0.5);
}
.selectize-dropdown-content {
overflow-y: auto;
overflow-x: hidden;
max-height: 200px;
}
/* Select Control Ends */

View File

@@ -0,0 +1,41 @@
/*jshint -W065 */
wp.customize.controlConstructor['rara-business-select'] = wp.customize.Control.extend({
ready: function() {
'use strict';
var control = this,
element = this.container.find( 'select' ),
multiple = parseInt( element.data( 'multiple' ) ),
selectValue;
// If this is a multi-select control,
// then we'll need to initialize selectize using the appropriate arguments.
// If this is a single-select, then we can initialize selectize without any arguments.
if ( multiple > 1 ) {
jQuery( element ).selectize({
maxItems: multiple,
plugins: ['remove_button', 'drag_drop']
});
} else {
jQuery( element ).selectize();
}
// Change value
this.container.on( 'change', 'select', function() {
selectValue = jQuery( this ).val();
// If this is a multi-select, then we need to convert the value to an object.
if ( multiple > 1 ) {
selectValue = _.extend( {}, jQuery( this ).val() );
}
control.setting.set( selectValue );
});
}
});

View File

@@ -0,0 +1,79 @@
<?php
/**
* Customizer Control: slider.
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Slider_Control' ) ) {
/**
* Slider control (range).
*/
class Rara_Business_Slider_Control extends WP_Customize_Control {
public $type = 'slider';
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['value'] = $this->value();
$this->json['choices'] = $this->choices;
$this->json['link'] = $this->get_link();
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
$this->json['choices']['min'] = ( isset( $this->choices['min'] ) ) ? $this->choices['min'] : '0';
$this->json['choices']['max'] = ( isset( $this->choices['max'] ) ) ? $this->choices['max'] : '100';
$this->json['choices']['step'] = ( isset( $this->choices['step'] ) ) ? $this->choices['step'] : '1';
}
public function enqueue() {
wp_enqueue_style( 'rara-business-slider', get_template_directory_uri() . '/inc/custom-controls/slider/slider.css', null );
wp_enqueue_script( 'rara-business-slider', get_template_directory_uri() . '/inc/custom-controls/slider/slider.js', array( 'jquery' ), false, true ); //for slider
}
protected function content_template() {
?>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<label>
<# if ( data.label ) { #>
<span class="customize-control-title">{{{ data.label }}}</span>
<# } #>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<div class="wrapper">
<input {{{ data.inputAttrs }}} type="range" min="{{ data.choices['min'] }}" max="{{ data.choices['max'] }}" step="{{ data.choices['step'] }}" value="{{ data.value }}" {{{ data.link }}} data-reset_value="{{ data.default }}" />
<div class="range_value">
<span class="value">{{ data.value }}</span>
<# if ( data.choices['suffix'] ) { #>
{{ data.choices['suffix'] }}
<# } #>
</div>
<div class="slider-reset">
<span class="dashicons dashicons-image-rotate"></span>
</div>
</div>
</label>
<?php
}
}
}

View File

@@ -0,0 +1,94 @@
.customize-control-slider input[type=range] {
-webkit-appearance: none;
-webkit-transition: background .3s;
-moz-transition: background .3s;
transition: background .3s;
background-color: rgba(0, 0, 0, 0.1);
height: 5px;
width: calc(100% - 70px);
padding: 0;
}
.customize-control-slider input[type=range]:focus {
box-shadow: none;
outline: none;
}
.customize-control-slider input[type=range]:hover {
background-color: rgba(0, 0, 0, 0.25);
}
.customize-control-slider input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 15px;
height: 15px;
border-radius: 50%;
-webkit-border-radius: 50%;
background-color: #3498D9;
}
.customize-control-slider input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 15px;
height: 15px;
border: none;
border-radius: 50%;
background-color: #3498D9;
}
.customize-control-slider input[type=range]::-moz-range-thumb {
width: 15px;
height: 15px;
border: none;
border-radius: 50%;
background-color: #3498D9;
}
.customize-control-slider input[type=range]::-ms-thumb {
width: 15px;
height: 15px;
border-radius: 50%;
border: 0;
background-color: #3498D9;
}
.customize-control-slider input[type=range]::-moz-range-track {
border: inherit;
background: transparent;
}
.customize-control-slider input[type=range]::-ms-track {
border: inherit;
color: transparent;
background: transparent;
}
.customize-control-slider input[type=range]::-ms-fill-lower, .customize-control-slider input[type=range]::-ms-fill-upper {
background: transparent;
}
.customize-control-slider input[type=range]::-ms-tooltip {
display: none;
}
.customize-control-slider .range_value {
display: inline-block;
font-size: 14px;
padding: 0 5px;
font-weight: 400;
position: relative;
top: 2px;
}
.customize-control-slider .range_value {
display: inline-block;
font-size: 14px;
padding: 0 5px;
font-weight: 400;
position: relative;
top: 2px;
}
.customize-control-slider .slider-reset {
color: rgba(0, 0, 0, 0.2);
float: right;
-webkit-transition: color .5s ease-in;
-moz-transition: color .5s ease-in;
-ms-transition: color .5s ease-in;
-o-transition: color .5s ease-in;
transition: color .5s ease-in;
}
.customize-control-slider .slider-reset span {
font-size: 16px;
line-height: 22px;
}
.customize-control-slider .slider-reset:hover {
color: red;
}

View File

@@ -0,0 +1,39 @@
wp.customize.controlConstructor['slider'] = wp.customize.Control.extend({
ready: function() {
'use strict';
var control = this,
value,
thisInput,
inputDefault,
changeAction;
// Update the text value
jQuery(document).on('input change', 'input[type=range]', function() {
jQuery( this ).closest( 'label' ).find( '.range_value .value' ).html(jQuery(this).val());
});
// Handle the reset button
jQuery( '.slider-reset' ).on( 'click', function() {
thisInput = jQuery( this ).closest( 'label' ).find( 'input' );
inputDefault = thisInput.data( 'reset_value' );
thisInput.val( inputDefault );
thisInput.change();
jQuery( this ).closest( 'label' ).find( '.range_value .value' ).text( inputDefault );
});
if ( 'postMessage' === control.setting.transport ) {
changeAction = 'mousemove change';
} else {
changeAction = 'change';
}
// Save changes.
this.container.on( changeAction, 'input', function() {
control.setting.set( jQuery( this ).val() );
});
}
});

View File

@@ -0,0 +1,65 @@
<?php
/**
* Customizer Control: toggle.
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( ! class_exists( 'Rara_Business_Toggle_Control' ) ) {
/**
* Toggle control (modified checkbox).
*/
class Rara_Business_Toggle_Control extends WP_Customize_Control {
public $type = 'toggle';
public $tooltip = '';
public function to_json() {
parent::to_json();
if ( isset( $this->default ) ) {
$this->json['default'] = $this->default;
} else {
$this->json['default'] = $this->setting->default;
}
$this->json['value'] = $this->value();
$this->json['link'] = $this->get_link();
$this->json['id'] = $this->id;
$this->json['tooltip'] = $this->tooltip;
$this->json['inputAttrs'] = '';
foreach ( $this->input_attrs as $attr => $value ) {
$this->json['inputAttrs'] .= $attr . '="' . esc_attr( $value ) . '" ';
}
}
public function enqueue() {
wp_enqueue_style( 'rara-business-toggle', get_template_directory_uri() . '/inc/custom-controls/toggle/toggle.css', null );
wp_enqueue_script( 'rara-business-toggle', get_template_directory_uri() . '/inc/custom-controls/toggle/toggle.js', array( 'jquery' ), false, true ); //for toggle
}
protected function content_template() {
?>
<# if ( data.tooltip ) { #>
<a href="#" class="tooltip hint--left" data-hint="{{ data.tooltip }}"><span class='dashicons dashicons-info'></span></a>
<# } #>
<label for="toggle_{{ data.id }}">
<span class="customize-control-title">
{{{ data.label }}}
</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
<input {{{ data.inputAttrs }}} name="toggle_{{ data.id }}" id="toggle_{{ data.id }}" type="checkbox" value="{{ data.value }}" {{{ data.link }}}<# if ( '1' == data.value ) { #> checked<# } #> hidden />
<span class="switch"></span>
</label>
<?php
}
}
}

View File

@@ -0,0 +1,64 @@
.customize-control-toggle label {
display: flex;
flex-wrap: wrap;
}
.customize-control-toggle label .customize-control-title {
width: calc(100% - 55px);
}
.customize-control-toggle label .description {
order: 99;
}
.customize-control-toggle input[type="checkbox"] {
display: none;
}
.customize-control-toggle .switch {
border: 1px solid rgba(0, 0, 0, 0.1);
display: inline-block;
width: 35px;
height: 12px;
border-radius: 8px;
background: #ccc;
vertical-align: middle;
position: relative;
cursor: pointer;
user-select: none;
transition: background 350ms ease;
}
.customize-control-toggle .switch:before, .customize-control-toggle .switch:after {
content: "";
display: block;
width: 20px;
height: 20px;
border-radius: 50%;
position: absolute;
top: 50%;
left: -3px;
transition: all 350ms cubic-bezier(0, 0.95, 0.38, 0.98), background 150ms ease;
}
.customize-control-toggle .switch:before {
background: rgba(0, 0, 0, 0.2);
transform: translate3d(0, -50%, 0) scale(0);
}
.customize-control-toggle .switch:after {
background: #999;
border: 1px solid rgba(0, 0, 0, 0.1);
transform: translate3d(0, -50%, 0);
}
.customize-control-toggle .switch:active:before {
transform: translate3d(0, -50%, 0) scale(3);
}
.customize-control-toggle input:checked + .switch {
background: rgba(52, 152, 222, 0.3);
}
.customize-control-toggle input:checked + .switch:before {
background: rgba(52, 152, 222, 0.075);
transform: translate3d(100%, -50%, 0) scale(1);
}
.customize-control-toggle input:checked + .switch:after {
background: #3498DE;
transform: translate3d(100%, -50%, 0);
}
.customize-control-toggle input:checked + .switch:active:before {
background: rgba(52, 152, 222, 0.075);
transform: translate3d(100%, -50%, 0) scale(3);
}

View File

@@ -0,0 +1,18 @@
wp.customize.controlConstructor['toggle'] = wp.customize.Control.extend({
ready: function() {
'use strict';
var control = this,
checkboxValue = control.setting._value;
// Save the value
this.container.on( 'change', 'input', function() {
checkboxValue = ( jQuery( this ).is( ':checked' ) ) ? true : false;
control.setting.set( checkboxValue );
});
}
});