Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Multiple Media Form Field #1235

Merged
merged 5 commits into from
Apr 24, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions base/inc/fields/css/multiple-media-field.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
@import "../../../less/mixins";

.siteorigin-widget-form .siteorigin-widget-field-type-multiple_media {

.multiple-media-field-wrapper {

* {
box-sizing: content-box;
}

.multiple-media-field-items {
line-height: 18.2px;
overflow: auto;
}

.multiple-media-field-item {
.box-sizing(border-box);
float: left;
padding: 4px;
position: relative;
margin: 5px 0;

.thumbnail {
border: 1px solid #999;
box-shadow: 0px 1px 1px #fff;
box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.2);
height: 75px;
.gradient(#cfcfcf, #cccccc, #cfcfcf);
line-height: 0;
width: 75px;
}

.title {
display: none;
}

.media-remove-button {
color: #aaa;
display: block;
font-size: 11px;
line-height: 1em;
opacity: 1;
text-align: center;
text-decoration: none;
.transition(0.25s);

&.remove-hide {
opacity: 0;
pointer-events: none;
}

&:hover {
color: #bc0b0b;
}
}
}
}

.media-field-template {
display: none;
}
}
129 changes: 129 additions & 0 deletions base/inc/fields/js/multiple-media-field.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
/* global jQuery, soWidgets */

( function( $ ) {

$( document ).on( 'sowsetupformfield', '.siteorigin-widget-field-type-multiple_media', function( e ) {
var $field = $( this ),
$data = $field.find( '.siteorigin-widget-input' ),
selectedMedia = $data.val().split( ',' );

if ( $field.data( 'initialized' ) ) {
return;
}

// Handle the media uploader
$field.find( '.button' ).on( 'click', function( e ) {
e.preventDefault();
if ( typeof wp.media === 'undefined' ) {
return;
}

var $$ = $( this );
var frame = $( this ).data( 'frame' );

// If the media frame already exists, reopen it.
if ( frame ) {
frame.open();
return false;
}

// Create the media frame.
frame = wp.media( {
title: $$.data( 'choose' ),
library: {
type: $$.data( 'library' ).split( ',' ).map( function( v ) { return v.trim(); } )
},
multiple: true,
button: {
text: $$.data( 'update' ),
close: false
}
} );

// If there's a selected image, highlight it.
frame.on( 'open', function() {
if ( selectedMedia.length ) {
var selection = frame.state().get( 'selection' );

$.each( selectedMedia, function() {
selection.add( wp.media.attachment( this ) );
} );
}
} );

// Store the frame
$$.data( 'frame', frame );

// When an image is selected, run a callback.
frame.on( 'select', function() {
var attachmentIds = [],
attachment,
attachmentUrl,
$currentItem,
$thumbnail;

$.each( frame.state().get('selection').models, function() {
attachment = this.attributes;

// Don't process images that already exist.
if ( selectedMedia.indexOf( attachment.id.toString() ) == -1 ) {
$field.find( '.multiple-media-field-template .multiple-media-field-item' ).clone().appendTo( $field.find( '.multiple-media-field-items' ) );
$currentItem = $field.find( '.multiple-media-field-items .multiple-media-field-item' ).last();

$thumbnail = $currentItem.find( '.thumbnail' );
$thumbnail.attr( 'title', attachment.title );

$currentItem.attr( 'data-id', attachment.id );

if ( typeof attachment.sizes !== 'undefined' ) {
if ( typeof attachment.sizes.thumbnail !== 'undefined' ) {
attachmentUrl = attachment.sizes.thumbnail.url;
} else {
attachmentUrl = attachment.sizes.full.url;
}
} else{
attachmentUrl = attachment.icon;
}
$thumbnail.attr( 'src', attachmentUrl );
}

attachmentIds.push( attachment.id );
} );

// Remove any no longer selected images
$field.find( '.multiple-media-field-items .multiple-media-field-item' ).each( function() {
if ( attachmentIds.indexOf( $( this ).data( 'id' ) ) == -1 ) {
$( this ).remove();
}
} )

// Store image data.
if ( attachmentIds.length ) {
selectedMedia = attachmentIds;
$data.val( attachmentIds.join( ',' ) );
} else {
selectedMedia = [];
$data.val( '' );
}

frame.close();
} );

// Finally, open the modal.
frame.open();
});

$field.find( 'a.media-remove-button' ).on( 'click', function( e ) {
e.preventDefault();
var $currentItem = $( this ).parent();

selectedMedia.splice( selectedMedia.indexOf( $currentItem.data( 'id' ) ) );
$data.val( selectedMedia.join( ',' ) );

$currentItem.remove();
} );

$field.data( 'initialized', true );
} );

} )( jQuery );
122 changes: 122 additions & 0 deletions base/inc/fields/multiple-media.class.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

/**
* Use of this field requires at least WordPress 3.5.
*
* Class SiteOrigin_Widget_Field_Multiple_Media
*/
class SiteOrigin_Widget_Field_Multiple_Media extends SiteOrigin_Widget_Field_Base {
/**
* A label for the title of the media selector dialog.
*
* @access protected
* @var string
*/
protected $choose;

/**
* A label for the confirmation button of the media selector dialog.
*
* @access protected
* @var string
*/
protected $update;

/**
* Sets the media library which to browse and from which media can be selected. Allowed values are 'image',
* 'audio', 'video', and 'file'. The default is 'file'.
*
* @access protected
* @var string
*/
protected $library;

protected function get_default_options() {
return array(
'choose' => __( 'Add Media', 'so-widgets-bundle' ),
'update' => __( 'Set Media', 'so-widgets-bundle' ),
'library' => 'image'
);
}

protected function render_field( $attachments, $instance ) {
if ( version_compare( get_bloginfo('version'), '3.5', '<' ) ){
printf( __( 'You need to <a href="%s">upgrade</a> to WordPress 3.5 to use media fields', 'so-widgets-bundle'), admin_url('update-core.php' ) );
return;
}

// If library is set to all, convert it to a wildcard as all isn't valid
if ( $this->library == 'all' ) {
$this->library = '*';
}
?>
<div class="multiple-media-field-wrapper">
<a href="#" class="button" data-choose="<?php echo esc_attr( $this->choose ); ?>"
data-update="<?php echo esc_attr( $this->update ); ?>"
data-library="<?php echo esc_attr( $this->library ); ?>">
<?php echo esc_html( $this->choose ); ?>
</a>


<div class="multiple-media-field-items">
<?php
if ( is_array( $attachments ) ) {
foreach ( $attachments as $attachment ) {
$post = get_post( $attachment );
$src = wp_get_attachment_image_src( $attachment, 'thumbnail' );

if ( empty( $src ) ) {
continue;
}
?>
<div class="multiple-media-field-item" data-id="<?php echo esc_attr( $attachment ); ?>">
<img src="<?php echo sow_esc_url( $src[0] ); ?>" class="thumbnail" title="<?php echo esc_attr( $post->post_title ); ?>"/>
<a href="#" class="media-remove-button"><?php esc_html_e( 'Remove', 'so-widgets-bundle' ); ?></a>
<div class="title">
<?php
if ( ! empty( $post ) ) {
echo esc_attr( $post->post_title );
}
?>
</div>
</div>
<?php
}
}
?>
</div>

<div class="multiple-media-field-template" style="display:none">
<div class="multiple-media-field-item">
<img class="thumbnail" />
<a href="#" class="media-remove-button"><?php esc_html_e( 'Remove', 'so-widgets-bundle' ); ?></a>
<div class="title"></div>
</div>

</div>

<input type="hidden" value="<?php echo is_array( $attachments ) ? esc_attr( implode( ',', $attachments ) ) : ''; ?>" data-element="<?php echo esc_attr( $this->element_name ); ?>" name="<?php echo esc_attr( $this->element_name ); ?>" class="siteorigin-widget-input" />
</div>

<?php
}

protected function sanitize_field_input( $value, $instance ) {
if ( empty( $value ) ) {
return array();
}

$value = explode( ',', $value );
$media = array();

foreach ( $value as $item ) {
$media[] = (int) $item;
}
return $media;
}

function enqueue_scripts() {
wp_enqueue_script( 'so-multiple-media-field', plugin_dir_url( __FILE__ ) . 'js/multiple-media-field' . SOW_BUNDLE_JS_SUFFIX . '.js', array( 'jquery' ), SOW_BUNDLE_VERSION );
wp_enqueue_style( 'so-multiple-media-field', plugin_dir_url( __FILE__ ) . 'css/multiple-media-field.css', array( ), SOW_BUNDLE_VERSION );
}
}