diff --git a/Gruntfile.js b/Gruntfile.js index e38d7f50..9914b156 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -16,7 +16,15 @@ module.exports = function(grunt) { banner: '<%= banner %>' }, files: { - 'css/dist/cmb.min.css': [ 'css/src/layout.css', 'css/src/generic.css', 'css/src/repeatable.css', 'css/src/group.css', 'css/src/file.css', 'css/src/misc-fields.css' ] + 'css/dist/cmb.min.css': [ + 'css/src/layout.css', + 'css/src/generic.css', + 'css/src/repeatable.css', + 'css/src/sortable.css', + 'css/src/group.css', + 'css/src/file.css', + 'css/src/misc-fields.css' + ] } } } diff --git a/class.cmb-meta-box.php b/class.cmb-meta-box.php index f5b3af55..8c2415fe 100644 --- a/class.cmb-meta-box.php +++ b/class.cmb-meta-box.php @@ -119,7 +119,7 @@ function enqueue_styles() { $suffix = CMB_DEV ? '' : '.min'; - if ( version_compare( get_bloginfo( 'version' ), '3.7', '>' ) ) + if ( version_compare( get_bloginfo( 'version' ), '3.7.1', '>' ) ) wp_enqueue_style( 'cmb-styles', trailingslashit( CMB_URL ) . "css/dist/cmb$suffix.css" ); else wp_enqueue_style( 'cmb-styles', trailingslashit( CMB_URL ) . 'css/legacy.css' ); @@ -245,6 +245,9 @@ static function layout_fields( array $fields ) { ?> if ( ! empty( $field->args['repeatable'] ) ) $classes[] = 'repeatable'; + if ( ! empty( $field->args['sortable'] ) ) + $classes[] = 'cmb-sortable'; + $classes[] = get_class($field); $classes = 'class="' . esc_attr( implode(' ', array_map( 'sanitize_html_class', $classes ) ) ) . '"'; diff --git a/classes.fields.php b/classes.fields.php index 0b05f2c1..1d9050d6 100644 --- a/classes.fields.php +++ b/classes.fields.php @@ -67,6 +67,10 @@ public function __construct( $name, $title, array $values, $args = array() ) { * @uses wp_enqueue_script() */ public function enqueue_scripts() { + + if ( isset( $this->args['sortable'] ) && $this->args['sortable'] ) + wp_enqueue_script( 'jquery-ui-sortable' ); + } /** @@ -1352,7 +1356,7 @@ public function display() { - + [class*=cmb-cell-]>.field{border-bottom:0}.postbox>.inside>.cmb_metabox{margin:-10px 0}.cmb_metabox .cmb-row{overflow:hidden;margin:0 -5px;zoom:1}.cmb_metabox .cmb-row:after,.cmb_metabox .cmb-row:before{content:"";display:table}.cmb_metabox .cmb-row:after{clear:both}.cmb_metabox [class*=cmb-cell-]{float:left;padding:0 5px;-moz-box-sizing:border-box;box-sizing:border-box}.cmb_metabox .cmb-cell-1{width:8.333333333%}.cmb_metabox .cmb-cell-2{width:16.666666667%}.cmb_metabox .cmb-cell-3{width:25%}.cmb_metabox .cmb-cell-4{width:33.333333333%}.cmb_metabox .cmb-cell-5{width:41.666666667%}.cmb_metabox .cmb-cell-6{width:50%}.cmb_metabox .cmb-cell-7{width:58.333333333%}.cmb_metabox .cmb-cell-8{width:66.666666667%}.cmb_metabox .cmb-cell-9{width:75%}.cmb_metabox .cmb-cell-10{width:83.333333333%}.cmb_metabox .cmb-cell-11{width:91.666666667%}.cmb_metabox .cmb-cell-12{width:100%}@media all and (max-width:850px){.cmb_metabox [class*=cmb-cell-]{width:100%}}.cmb_metabox .field-item{position:relative}.cmb_metabox_description{color:#AAA;font-style:italic;margin:0 0 16px!important}.cmb_metabox input[type=text],.cmb_metabox select,.cmb_metabox textarea{width:100%}.cmb_metabox input.cmb_text_small{width:100px}.cmb_metabox input.cmb_text_medium{width:230px;margin-right:15px}.cmb_metabox input[type=checkbox],.cmb_metabox input[type=radio]{margin:0 5px 0 0;padding:0}.cmb_metabox .field-title{margin-bottom:16px;margin-top:0;font-weight:700}.cmb_metabox .field-title label{vertical-align:baseline}.cmb_metabox .field.repeatable>.field-item{padding-right:30px;margin-bottom:10px}.cmb_metabox .repeat-field{display:block!important;clear:both}.CMB_Date_Field.repeatable .field-item,.CMB_Date_Timestamp_Field.repeatable .field-item,.CMB_Datetime_Timestamp_Field.repeatable .field-item,.CMB_Text_Small_Field.repeatable .field-item,.CMB_Time_Field.repeatable .field-item{float:left;clear:both}.cmb-delete-field{display:inline-block;text-decoration:none;font-size:11px;line-height:20px;height:22px;width:22px;margin:0;padding:0;cursor:pointer;border-width:1px;border-style:solid;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top;position:absolute;top:3px;right:0;text-indent:100%;overflow:hidden;white-space:nowrap}.cmb-delete-field:active,.cmb-delete-field:focus,.cmb-delete-field:hover{background:#fafafa;border-color:#999;color:#222}.cmb-delete-field .cmb-delete-field-icon{content:' ';display:block;position:absolute;height:8px;width:8px;top:50%;left:50%;margin-top:-4px;margin-left:-4px;background-image:url( '../../images/cmb-icon-remove.png');background-repeat:no-repeat;text-indent:8px;overflow:hidden}@media only screen and (-webkit-min-device-pixel-ratio :1.5),only screen and (min-device-pixel-ratio :1.5){.cmb-delete-field .cmb-delete-field-icon{background-image:url( '../../images/cmb-icon-remove@2x.png');background-size:8px 8px}}* Group **/ .cmb_metabox .CMB_Group_Field>.field-title{font-size:1.5em;clear:left;color:#464646;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:lighter}.cmb_metabox .CMB_Group_Field>.field-title h2{margin:8px 5px!important}.cmb_metabox .CMB_Group_Field.repeatable>.field-item{padding:30px 10px 0;margin-bottom:16px;border:1px solid #DDD;background:#FAFAFA;position:relative}.cmb_metabox .CMB_Group_Field.repeatable>.field-item:before{content:' ';display:block;position:absolute;top:0;left:0;right:0;height:33px;border-bottom:1px solid #DDD}.cmb_metabox .CMB_Group_Field.repeatable>.field-item>.cmb-delete-field{top:5px;right:5px;width:auto;text-indent:0;padding-left:24px;padding-right:8px;height:22px;line-height:20px;font-size:11px}.cmb_metabox .CMB_Group_Field.repeatable>.field-item>.cmb-delete-field .cmb-delete-field-icon{left:12px}.CMB_File_Field .field-item,.CMB_Image_Field .field-item{float:left;margin:0 16px 16px 0!important;text-align:center;padding:0!important;z-index:1}.cmb-file-wrap{position:relative;overflow:hidden;width:150px;height:150px;line-height:150px}.cmb-file-wrap-placeholder{content:' ';position:absolute;top:0;left:0;display:block;height:142px;width:142px;border:4px dashed #DDD;z-index:-1}.cmb-file-wrap-placeholder .dimensions{line-height:normal;position:absolute;bottom:10px;right:10px;font-size:18px;font-weight:700;opacity:.2}.cmb-file-holder{position:relative;overflow:hidden;box-shadow:inset 0 0 15px rgba(0,0,0,.1),inset 0 0 0 1px rgba(0,0,0,.05);background:#eee;width:100%;height:100%}.cmb-file-holder.type-file img{position:absolute;top:43%;margin-top:-30px;left:50%;margin-left:-23px}.cmb-file-holder.type-img img{width:100%;height:auto;margin-top:0;vertical-align:top}.cmb-file-holder.type-img::after{content:'';display:block;position:absolute;top:0;left:0;right:0;bottom:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);overflow:hidden;z-index:1}.cmb-file-name{position:absolute;left:0;right:0;bottom:0;line-height:1.4;overflow:hidden;max-height:100%;word-wrap:break-word;text-align:center;font-weight:700;background:rgba(255,255,255,.8);box-shadow:inset 0 0 0 1px rgba(0,0,0,.15)}.cmb-file-name strong{padding:5px 10px;display:block}.CMB_File_Field .cmb-delete-field,.CMB_Image_Field .cmb-delete-field{z-index:10;top:10px;right:10px}.CMB_File_Field .cmb-remove-file,.CMB_Image_Field .cmb-remove-file{position:absolute;z-index:1;top:5px;right:5px}.CMB_File_Field.repeatable .cmb-remove-file,.CMB_Image_Field.repeatable .cmb-remove-file{display:none!important}.cmb-file-wrap .cmb-file-upload{vertical-align:middle}.cmb-loading::before{content:' ';display:block;background:url( '../../images/wpspin.gif' ) no-repeat;width:16px;height:16px;position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}@media only screen and (-webkit-min-device-pixel-ratio :1.5),only screen and (min-device-pixel-ratio :1.5){.cmb-loading::before{background-image:url( '../../images/wpspin-2x.gif');background-size:16px 16px}}.CMB_Title .field-title{margin:8px 0!important}.CMB_Title h2{margin:0!important;padding:0!important}.CMB_Color_Picker .field-item{float:left;clear:both}.CMB_Color_Picker:after,.CMB_Color_Picker:before{content:"";display:table}.CMB_Color_Picker:after{clear:both}.CMB_Color_Picker{zoom:1}div.time-picker{position:absolute;height:191px;width:4em;overflow:auto;background:#fff;border:1px solid #aaa;z-index:99;margin:0}div.time-picker-12hours{width:6em}div.time-picker ul{list-style-type:none;margin:0;padding:0}div.time-picker li{cursor:pointer;height:10px;font:12px/1 Helvetica,Arial,sans-serif;padding:4px 3px}div.time-picker li.selected{background:#0063CE;color:#fff}.cmb_metabox input.cmb_timepicker{width:100px;margin-right:0}.CMB_Datetime_Timestamp_Field input+input{margin-left:4px}.cmb_select{width:100%}.select2-offscreen{display:none} \ No newline at end of file +.cmb_metabox .field{padding:16px 0;border-bottom:1px solid #DFDFDF}.cmb-row:last-child>[class*=cmb-cell-]>.field{border-bottom:0}.postbox>.inside>.cmb_metabox{margin:-10px 0}.cmb_metabox .cmb-row{overflow:hidden;margin:0 -5px;zoom:1}.cmb_metabox .cmb-row:after,.cmb_metabox .cmb-row:before{content:"";display:table}.cmb_metabox .cmb-row:after{clear:both}.cmb_metabox [class*=cmb-cell-]{float:left;padding:0 5px;-moz-box-sizing:border-box;box-sizing:border-box}.cmb_metabox .cmb-cell-1{width:8.333333333%}.cmb_metabox .cmb-cell-2{width:16.666666667%}.cmb_metabox .cmb-cell-3{width:25%}.cmb_metabox .cmb-cell-4{width:33.333333333%}.cmb_metabox .cmb-cell-5{width:41.666666667%}.cmb_metabox .cmb-cell-6{width:50%}.cmb_metabox .cmb-cell-7{width:58.333333333%}.cmb_metabox .cmb-cell-8{width:66.666666667%}.cmb_metabox .cmb-cell-9{width:75%}.cmb_metabox .cmb-cell-10{width:83.333333333%}.cmb_metabox .cmb-cell-11{width:91.666666667%}.cmb_metabox .cmb-cell-12{width:100%}@media all and (max-width:850px){.cmb_metabox [class*=cmb-cell-]{width:100%}}.cmb_metabox .field-item{position:relative}.cmb_metabox_description{color:#AAA;font-style:italic;margin:0 0 16px!important}.cmb_metabox input[type=text],.cmb_metabox select,.cmb_metabox textarea{width:100%}.cmb_metabox input.cmb_text_small{width:100px}.cmb_metabox input.cmb_text_medium{width:230px;margin-right:15px}.cmb_metabox input[type=checkbox],.cmb_metabox input[type=radio]{margin:0 5px 0 0;padding:0}.cmb_metabox .field-title{margin-bottom:16px;margin-top:0;font-weight:700}.cmb_metabox .field-title label{vertical-align:baseline}.cmb_metabox .field.repeatable>.field-item{padding-right:30px;margin-bottom:10px}.cmb_metabox .repeat-field{display:block!important;clear:both}.CMB_Date_Field.repeatable .field-item,.CMB_Date_Timestamp_Field.repeatable .field-item,.CMB_Datetime_Timestamp_Field.repeatable .field-item,.CMB_Text_Small_Field.repeatable .field-item,.CMB_Time_Field.repeatable .field-item{float:left;clear:both}.cmb-delete-field{display:inline-block;text-decoration:none;font-size:11px;line-height:20px;height:22px;width:22px;margin:0;padding:0;cursor:pointer;border-width:1px;border-style:solid;-webkit-border-radius:3px;-webkit-appearance:none;border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;color:#555;border-color:#ccc;background:#f7f7f7;-webkit-box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);box-shadow:inset 0 1px 0 #fff,0 1px 0 rgba(0,0,0,.08);vertical-align:top;position:absolute;top:3px;right:0;text-indent:100%;overflow:hidden;white-space:nowrap}.cmb-delete-field:active,.cmb-delete-field:focus,.cmb-delete-field:hover{background:#fafafa;border-color:#999;color:#222}.cmb-delete-field .cmb-delete-field-icon{content:' ';display:block;position:absolute;height:8px;width:8px;top:50%;left:50%;margin-top:-4px;margin-left:-4px;background-image:url( '../../images/cmb-icon-remove.png');background-repeat:no-repeat;text-indent:8px;overflow:hidden}@media only screen and (-webkit-min-device-pixel-ratio :1.5),only screen and (min-device-pixel-ratio :1.5){.cmb-delete-field .cmb-delete-field-icon{background-image:url( '../../images/cmb-icon-remove@2x.png');background-size:8px 8px}}.cmb-sortable>.field-item{padding-left:15px}.cmb-sortable .cmb-handle{height:100%;width:3px;position:absolute;top:0;left:0;background:0 0;cursor:move;border-left:3px solid #DFDFDF;border-right:3px solid #DFDFDF}.cmb-sortable .ui-sortable-helper{opacity:.75}.cmb-sortable .ui-sortable-helper:before{content:' ';position:absolute;width:100%;height:100%;top:-6px;left:-6px;background-color:#F8F8F8;border:1px solid #DEDEDE;padding:5px;z-index:-1}.cmb-sortable>.ui-sortable-placeholder{border:1px dashed #DDD!important;background:transparent!important;visibility:visible!important;margin-bottom:8px!important}* Group **/ .cmb_metabox .CMB_Group_Field>.field-title{font-size:1.5em;clear:left;color:#464646;font-family:HelveticaNeue-Light,"Helvetica Neue Light","Helvetica Neue",sans-serif;font-weight:lighter}.cmb_metabox .CMB_Group_Field>.field-title h2{margin:8px 5px!important}.cmb_metabox .CMB_Group_Field.repeatable>.field-item{padding:30px 10px 0;margin-bottom:16px;border:1px solid #DDD;background:#FAFAFA;position:relative}.cmb_metabox .CMB_Group_Field.repeatable>.field-item:before{content:' ';display:block;position:absolute;top:0;left:0;right:0;height:33px;border-bottom:1px solid #DDD}.cmb_metabox .CMB_Group_Field.repeatable>.field-item>.cmb-delete-field{top:5px;right:5px;width:auto;text-indent:0;padding-left:24px;padding-right:8px;height:22px;line-height:20px;font-size:11px;z-index:1}.cmb_metabox .CMB_Group_Field.repeatable>.field-item>.cmb-delete-field .cmb-delete-field-icon{left:12px}.CMB_Group_Field.cmb-sortable>.field-item{position:relative;padding-top:30px}.CMB_Group_Field.cmb-sortable>.field-item>.cmb-handle{top:-1px;left:-1px;right:-1px;height:34px;width:auto;border:0;border-bottom:1px solid #DDD}.CMB_Group_Field.cmb-sortable>.field-item.ui-sortable-helper>.cmb-handle{padding:0 5px}.cmb_metabox .CMB_Group_Field.repeatable.cmb-sortable>.field-item:before{display:none!important}.CMB_Group_Field.cmb-sortable>.ui-sortable-placeholder{margin-bottom:16px!important}.CMB_File_Field .field-item,.CMB_Image_Field .field-item{float:left;margin:0 16px 16px 0!important;text-align:center;padding:0!important;z-index:1}.cmb-file-wrap{position:relative;overflow:hidden;width:150px;height:150px;line-height:150px}.cmb-file-wrap-placeholder{content:' ';position:absolute;top:0;left:0;display:block;height:142px;width:142px;border:4px dashed #DDD;z-index:-1}.cmb-file-wrap-placeholder .dimensions{line-height:normal;position:absolute;bottom:10px;right:10px;font-size:18px;font-weight:700;opacity:.2}.cmb-file-holder{position:relative;overflow:hidden;box-shadow:inset 0 0 15px rgba(0,0,0,.1),inset 0 0 0 1px rgba(0,0,0,.05);background:#eee;width:100%;height:100%}.cmb-file-holder.type-file img{position:absolute;top:43%;margin-top:-30px;left:50%;margin-left:-23px}.cmb-file-holder.type-img img{width:100%;height:auto;margin-top:0;vertical-align:top}.cmb-file-holder.type-img::after{content:'';display:block;position:absolute;top:0;left:0;right:0;bottom:0;box-shadow:inset 0 0 0 1px rgba(0,0,0,.1);overflow:hidden;z-index:1}.cmb-file-name{position:absolute;left:0;right:0;bottom:0;line-height:1.4;overflow:hidden;max-height:100%;word-wrap:break-word;text-align:center;font-weight:700;background:rgba(255,255,255,.8);box-shadow:inset 0 0 0 1px rgba(0,0,0,.15)}.cmb-file-name strong{padding:5px 10px;display:block}.CMB_File_Field .cmb-delete-field,.CMB_Image_Field .cmb-delete-field{z-index:10;top:10px;right:10px}.CMB_File_Field .cmb-remove-file,.CMB_Image_Field .cmb-remove-file{position:absolute;z-index:1;top:5px;right:5px}.CMB_File_Field.repeatable .cmb-remove-file,.CMB_Image_Field.repeatable .cmb-remove-file{display:none!important}.cmb-file-wrap .cmb-file-upload{vertical-align:middle}.cmb-loading::before{content:' ';display:block;background:url( '../../images/wpspin.gif' ) no-repeat;width:16px;height:16px;position:absolute;top:50%;left:50%;margin-top:-8px;margin-left:-8px}@media only screen and (-webkit-min-device-pixel-ratio :1.5),only screen and (min-device-pixel-ratio :1.5){.cmb-loading::before{background-image:url( '../../images/wpspin-2x.gif');background-size:16px 16px}}.CMB_File_Field.cmb-sortable .cmb-handle,.CMB_Image_Field.cmb-sortable .cmb-handle{border:0;background:0 0;height:100%;width:100%;z-index:1}.CMB_File_Field.cmb-sortable .cmb-file-upload,.CMB_Image_Field.cmb-sortable .cmb-file-upload{position:relative;z-index:5}.CMB_File_Field.cmb-sortable .ui-sortable-helper:before,.CMB_Image_Field.cmb-sortable .ui-sortable-helper:before{top:0;left:0;padding:0;border:0;background:#F9F9F9}.CMB_Title .field-title{margin:8px 0!important}.CMB_Title h2{margin:0!important;padding:0!important}.CMB_Color_Picker .field-item{float:left;clear:both}.CMB_Color_Picker:after,.CMB_Color_Picker:before{content:"";display:table}.CMB_Color_Picker:after{clear:both}.CMB_Color_Picker{zoom:1}div.time-picker{position:absolute;height:191px;width:4em;overflow:auto;background:#fff;border:1px solid #aaa;z-index:99;margin:0}div.time-picker-12hours{width:6em}div.time-picker ul{list-style-type:none;margin:0;padding:0}div.time-picker li{cursor:pointer;height:10px;font:12px/1 Helvetica,Arial,sans-serif;padding:4px 3px}div.time-picker li.selected{background:#0063CE;color:#fff}.cmb_metabox input.cmb_timepicker{width:100px;margin-right:0}.CMB_Datetime_Timestamp_Field input+input{margin-left:4px}.cmb_select{width:100%}.select2-offscreen{display:none} \ No newline at end of file diff --git a/css/legacy.css b/css/legacy.css index ede43d82..9830ba74 100644 --- a/css/legacy.css +++ b/css/legacy.css @@ -132,9 +132,9 @@ button.repeat-field { display: block !important; clear: both; } .CMB_Datetime_Timestamp_Field input + input { margin-left: 4px; } #poststuff .CMB_Group_Field h2 { padding: 0; margin: 8px 5px; } -.CMB_Group_Field.repeatable > .field-item { padding: 0 9px; margin-bottom: 16px ; border: 1px solid #DDD; background: #ECECEC; border-radius: 3px; } -.CMB_Group_Field .cmb_element { display: block; height: 0; } -.CMB_Group_Field .cmb_element .ui-state-default { /*display: none;*/ margin-right: -3px; margin-top: -5px; } +.CMB_Group_Field.repeatable > .field-item { padding: 0 9px; margin-bottom: 16px ; border: 1px solid #DDD; background: #F9F9F9; border-radius: 3px; } + +.CMB_Group_Field.repeatable > .field-item.ui-sortable-placeholder { margin-bottom: 16px !important; } .CMB_Group_Field > .field-title { margin-top: 20px; @@ -148,14 +148,11 @@ button.repeat-field { display: block !important; clear: both; } font-weight: lighter; } - .CMB_Group_Field.repeatable > .field-item { padding: 0 9px; margin-bottom: 16px; border: 1px solid #DDD; - background: #ECECEC; border-radius: 3px; - position: relative; } .CMB_Group_Field .group > .cmb-delete-field { @@ -200,7 +197,122 @@ button.repeat-field { display: block !important; clear: both; } .CMB_Color_Picker .iris-picker .iris-strip .ui-slider-handle { margin-bottom: 0; } .CMB_Color_Picker .iris-picker .iris-strip .ui-slider-handle:focus { outline: none; } -.cmb-loading::before { content: ' '; display: block; background: url( '../images/wpspin.gif' ) no-repeat; width: 16px; height: 16px; position: absolute; top: 50%; left: 50%; margin-top: -8px; margin-left: -8px; } +.cmb-loading:before { content: ' '; display: block; background: url( '../images/wpspin.gif' ) no-repeat; width: 16px; height: 16px; position: absolute; top: 50%; left: 50%; margin-top: -8px; margin-left: -8px; } @media only screen and (-webkit-min-device-pixel-ratio : 1.5), only screen and (min-device-pixel-ratio : 1.5) { - .cmb-loading::before { background-image: url( '../images/wpspin-2x.gif'); background-size: 16px 16px; } + .cmb-loading:before { background-image: url( 'images/wpspin-2x.gif'); background-size: 16px 16px; } +} + +.cmb-sortable > .field-item { + padding-left: 16px; +} + +.cmb-sortable .cmb-handle { + height: 100%; + width: 2px; + position: absolute; + top: 0; + left: 0; + background: transparent; + cursor: move; + border-left: 2px solid #DFDFDF; + border-right: 2px solid #DFDFDF; +} + +.cmb-sortable .cmb-handle:after { + position: absolute; + content: ' '; + height: 100%; + width: 0; + position: absolute; + top: 0; + left: 100%; + margin-left: 4px; + background: transparent; + cursor: move; + border-left: 2px solid #DFDFDF; +} + +.cmb-sortable .ui-sortable-helper { + opacity: 0.75; +} + + +.cmb-sortable .ui-sortable-helper:before { + content: ' '; + position: absolute; + width: 100%; + height: 100%; + top: -6px; + left: -6px; + background-color: #F8F8F8; + border: 1px solid #DEDEDE; + padding: 5px; + z-index: -1; +} + +.cmb-sortable .ui-sortable-placeholder { + border: 1px dashed #DDD !important; + background: transparent !important; + visibility: visible !important; + margin-bottom: 6px !important; + margin-right: 6px !important; +} + +.CMB_File_Field.cmb-sortable .cmb-handle, +.CMB_Image_Field.cmb-sortable .cmb-handle { + background: transparent; + width: 100%; + z-index: 1; +} + +.CMB_File_Field.cmb-sortable .cmb-file-upload, +.CMB_Image_Field.cmb-sortable .cmb-file-upload { + position: relative; + z-index: 5; +} + +.CMB_File_Field.cmb-sortable .ui-sortable-helper:before, +.CMB_Image_Field.cmb-sortable .ui-sortable-helper:before { + top: 0; + left: 0; + padding: 0; + border: none; + background: #F9F9F9; +} + +.CMB_Group_Field.cmb-sortable > .field-item { + position: relative; + padding-top: 30px; +} + +.CMB_Group_Field.cmb-sortable > .field-item > .cmb-handle { + top: -1px; + left: -1px; + right: -1px; + height: 30px; + width: auto; + border: 1px solid #dfdfdf; + border-radius: 3px 3px 0 0; + background: #f1f1f1; + background-image: -webkit-gradient(linear,left bottom,left top,from(#ececec),to(#f9f9f9)); + background-image: -webkit-linear-gradient(bottom,#ececec,#f9f9f9); + background-image: -moz-linear-gradient(bottom,#ececec,#f9f9f9); + background-image: -o-linear-gradient(bottom,#ececec,#f9f9f9); + background-image: linear-gradient(to top,#ececec,#f9f9f9); +} + +.CMB_Group_Field.cmb-sortable .cmb-handle:after { + display: none; +} + +.CMB_Group_Field.cmb-sortable .group > .cmb-delete-field { + top: -33px; + right: -5px; + width: auto; + height: auto; + padding: 2px 5px 2px 20px; + text-indent: 0; + font-size: 12px; + line-height: 14px; + z-index: 1; } \ No newline at end of file diff --git a/css/src/file.css b/css/src/file.css index 9ba796e5..ce5f8d4d 100644 --- a/css/src/file.css +++ b/css/src/file.css @@ -139,4 +139,28 @@ background-size: 16px 16px; } +} + +.CMB_File_Field.cmb-sortable .cmb-handle, +.CMB_Image_Field.cmb-sortable .cmb-handle { + border: none; + background: transparent; + height: 100%; + width: 100%; + z-index: 1; +} + +.CMB_File_Field.cmb-sortable .cmb-file-upload, +.CMB_Image_Field.cmb-sortable .cmb-file-upload { + position: relative; + z-index: 5; +} + +.CMB_File_Field.cmb-sortable .ui-sortable-helper:before, +.CMB_Image_Field.cmb-sortable .ui-sortable-helper:before { + top: 0; + left: 0; + padding: 0; + border: none; + background: #F9F9F9; } \ No newline at end of file diff --git a/css/src/group.css b/css/src/group.css index 79af3332..7988c516 100644 --- a/css/src/group.css +++ b/css/src/group.css @@ -41,8 +41,37 @@ height: 22px; line-height: 20px; font-size: 11px; + z-index: 1; } .cmb_metabox .CMB_Group_Field.repeatable > .field-item > .cmb-delete-field .cmb-delete-field-icon { left: 12px; +} + + +.CMB_Group_Field.cmb-sortable > .field-item { + position: relative; + padding-top: 30px; +} + +.CMB_Group_Field.cmb-sortable > .field-item > .cmb-handle { + top: -1px; + left: -1px; + right: -1px; + height: 34px; + width: auto; + border: none; + border-bottom: 1px solid #DDDDDD; +} + +.CMB_Group_Field.cmb-sortable > .field-item.ui-sortable-helper > .cmb-handle { + padding: 0 5px; +} + +.cmb_metabox .CMB_Group_Field.repeatable.cmb-sortable > .field-item:before { + display: none !important; +} + +.CMB_Group_Field.cmb-sortable > .ui-sortable-placeholder { + margin-bottom: 16px !important; } \ No newline at end of file diff --git a/css/src/sortable.css b/css/src/sortable.css new file mode 100644 index 00000000..adc9844c --- /dev/null +++ b/css/src/sortable.css @@ -0,0 +1,40 @@ + +.cmb-sortable > .field-item { + padding-left: 15px; +} + +.cmb-sortable .cmb-handle { + height: 100%; + width: 3px; + position: absolute; + top: 0; + left: 0; + background: transparent; + cursor: move; + border-left: 3px solid #DFDFDF; + border-right: 3px solid #DFDFDF; +} + +.cmb-sortable .ui-sortable-helper { + opacity: 0.75; +} + +.cmb-sortable .ui-sortable-helper:before { + content: ' '; + position: absolute; + width: 100%; + height: 100%; + top: -6px; + left: -6px; + background-color: #F8F8F8; + border: 1px solid #DEDEDE; + padding: 5px; + z-index: -1; +} + +.cmb-sortable > .ui-sortable-placeholder { + border: 1px dashed #DDD !important; + background: transparent !important; + visibility: visible !important; + margin-bottom: 8px !important; +} \ No newline at end of file diff --git a/custom-meta-boxes.php b/custom-meta-boxes.php index b085d0e0..bab4ccbe 100755 --- a/custom-meta-boxes.php +++ b/custom-meta-boxes.php @@ -137,38 +137,36 @@ function _cmb_field_class_for_type( $type ) { * For the order of repeatable fields to be guaranteed, orderby meta_id needs to be set. * Note usermeta has a different meta_id column name. * - * TODO - * This is far from ideal as we are doing this on EVERY SINGLE QUERY. - * But... no other way to modify this query, or re-order in PHP. - * There is a trac ticket + patch that will fix this. http://core.trac.wordpress.org/ticket/25511 + * Only do this for older versions as meta is now ordered by ID (since 3.8) + * See http://core.trac.wordpress.org/ticket/25511 * * @param string $query * @return string $query */ function cmb_fix_meta_query_order($query) { - $pattern = '/^SELECT (post_id|user_id), meta_key, meta_value FROM \w* WHERE post_id IN \([\d|,]*\)$/'; - - if ( - 0 === strpos( $query, "SELECT post_id, meta_key, meta_value" ) && - preg_match( $pattern, $query, $matches ) - ) { - - if ( isset( $matches[1] ) && 'user_id' == $matches[1] ) - $meta_id_column = 'umeta_id'; - else - $meta_id_column = 'meta_id'; - - $meta_query_orderby = ' ORDER BY ' . $meta_id_column; - - if ( false === strpos( $query, $meta_query_orderby ) ) - $query .= $meta_query_orderby; - - } - - return $query; + $pattern = '/^SELECT (post_id|user_id), meta_key, meta_value FROM \w* WHERE post_id IN \([\d|,]*\)$/'; + + if ( + 0 === strpos( $query, "SELECT post_id, meta_key, meta_value" ) && + preg_match( $pattern, $query, $matches ) + ) { + + if ( isset( $matches[1] ) && 'user_id' == $matches[1] ) + $meta_id_column = 'umeta_id'; + else + $meta_id_column = 'meta_id'; + + $meta_query_orderby = ' ORDER BY ' . $meta_id_column; + + if ( false === strpos( $query, $meta_query_orderby ) ) + $query .= $meta_query_orderby; + + } + + return $query; } -if ( version_compare( get_bloginfo( 'version' ), '3.7', '<=' ) ) - add_filter( 'query', 'cmb_fix_meta_query_order', 1 ); +if ( version_compare( get_bloginfo( 'version' ), '3.7.1', '<=' ) ) + add_filter( 'query', 'cmb_fix_meta_query_order', 1 ); \ No newline at end of file diff --git a/example-functions.php b/example-functions.php index 530425b4..69f61b73 100644 --- a/example-functions.php +++ b/example-functions.php @@ -13,7 +13,7 @@ function cmb_sample_metaboxes( array $meta_boxes ) { array( 'id' => 'field-1', 'name' => 'Text input field', 'type' => 'text' ), array( 'id' => 'field-2', 'name' => 'Read-only text input field', 'type' => 'text', 'readonly' => true, 'default' => 'READ ONLY' ), - array( 'id' => 'field-3', 'name' => 'Repeatable text input field', 'type' => 'text', 'desc' => 'Add up to 5 fields.', 'repeatable' => true, 'repeatable_max' => 5 ), + array( 'id' => 'field-3', 'name' => 'Repeatable text input field', 'type' => 'text', 'desc' => 'Add up to 5 fields.', 'repeatable' => true, 'repeatable_max' => 5, 'sortable' => true ), array( 'id' => 'field-4', 'name' => 'Small text input field', 'type' => 'text_small' ), array( 'id' => 'field-5', 'name' => 'URL field', 'type' => 'url' ), @@ -21,7 +21,7 @@ function cmb_sample_metaboxes( array $meta_boxes ) { array( 'id' => 'field-6', 'name' => 'Radio input field', 'type' => 'radio', 'options' => array( 'Option 1', 'Option 2' ) ), array( 'id' => 'field-7', 'name' => 'Checkbox field', 'type' => 'checkbox' ), - array( 'id' => 'field-8', 'name' => 'WYSIWYG field', 'type' => 'wysiwyg', 'options' => array( 'editor_height' => '100' ) ), + array( 'id' => 'field-8', 'name' => 'WYSIWYG field', 'type' => 'wysiwyg', 'options' => array( 'editor_height' => '100' ), 'repeatable' => true, 'sortable' => true ), array( 'id' => 'field-9', 'name' => 'Textarea field', 'type' => 'textarea' ), array( 'id' => 'field-10', 'name' => 'Code textarea field', 'type' => 'textarea_code' ), @@ -29,7 +29,7 @@ function cmb_sample_metaboxes( array $meta_boxes ) { array( 'id' => 'field-11', 'name' => 'File field', 'type' => 'file', 'file_type' => 'image', 'repeatable' => 1, 'sortable' => 1 ), array( 'id' => 'field-12', 'name' => 'Image upload field', 'type' => 'image', 'repeatable' => true, 'show_size' => true ), - array( 'id' => 'field-13', 'name' => 'Select field', 'type' => 'select', 'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3' ), 'allow_none' => true ), + array( 'id' => 'field-13', 'name' => 'Select field', 'type' => 'select', 'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3' ), 'allow_none' => true, 'sortable' => true, 'repeatable' => true ), array( 'id' => 'field-14', 'name' => 'Select field', 'type' => 'select', 'options' => array( 'option-1' => 'Option 1', 'option-2' => 'Option 2', 'option-3' => 'Option 3' ), 'multiple' => true ), array( 'id' => 'field-15', 'name' => 'Select taxonomy field', 'type' => 'taxonomy_select', 'taxonomy' => 'category' ), array( 'id' => 'field-15b', 'name' => 'Select taxonomy field', 'type' => 'taxonomy_select', 'taxonomy' => 'category', 'multiple' => true ), diff --git a/js/cmb.js b/js/cmb.js index 2b90348f..b44dc29c 100644 --- a/js/cmb.js +++ b/js/cmb.js @@ -13,11 +13,14 @@ var CMB = { _clonedFieldCallbacks: [], _deletedFieldCallbacks: [], + _sortStartCallbacks: [], + _sortEndCallbacks: [], + init : function() { - jQuery( '.field.repeatable' ).each( function() { + jQuery( '.field.repeatable' ).each( function() { CMB.isMaxFields( jQuery(this) ); - } ); + } ); // Unbind & Re-bind all CMB events to prevent duplicates. jQuery(document).unbind( 'click.CMB' ); @@ -29,13 +32,18 @@ var CMB = { CMB.doneInit(); + jQuery('.field.cmb-sortable' ).each( function() { + CMB.sortableInit( jQuery(this) ); + } ); + + }, repeatField : function( e ) { - var templateField, newT, field, index, attr; + var templateField, newT, field, index, attr; - field = jQuery( this ).closest('.field' ); + field = jQuery( this ).closest('.field' ); e.preventDefault(); jQuery(this).blur(); @@ -43,19 +51,19 @@ var CMB = { if ( CMB.isMaxFields( field, 1 ) ) return; - templateField = field.children( '.field-item.hidden' ); + templateField = field.children( '.field-item.hidden' ); - newT = templateField.clone(); - newT.removeClass( 'hidden' ); - - var excludeInputTypes = '[type=submit],[type=button],[type=checkbox],[type=radio],[readonly]'; - newT.find( 'input' ).not( excludeInputTypes ).val( '' ); + newT = templateField.clone(); + newT.removeClass( 'hidden' ); + + var excludeInputTypes = '[type=submit],[type=button],[type=checkbox],[type=radio],[readonly]'; + newT.find( 'input' ).not( excludeInputTypes ).val( '' ); - newT.find( '.cmb_upload_status' ).html(''); + newT.find( '.cmb_upload_status' ).html(''); - newT.insertBefore( templateField ); + newT.insertBefore( templateField ); - // Recalculate group ids & update the name fields.. + // Recalculate group ids & update the name fields.. index = 0; attr = ['id','name','for','data-id','data-name']; @@ -76,7 +84,11 @@ var CMB = { } ); - CMB.clonedField( newT ); + CMB.clonedField( newT ); + + if ( field.hasClass( 'cmb-sortable' ) ) + CMB.sortableInit( field ); + }, @@ -86,7 +98,7 @@ var CMB = { e.preventDefault(); jQuery(this).blur(); - + fieldItem = jQuery( this ).closest('.field-item' ); field = fieldItem.closest( '.field' ); @@ -128,8 +140,8 @@ var CMB = { else addBtn.removeAttr( 'disabled' ); - if ( count > parseInt( max, 10 ) ) - return true; + if ( count > parseInt( max, 10 ) ) + return true; }, @@ -214,8 +226,82 @@ var CMB = { callbacks[a]( el ) }) - } + }, + + sortableInit : function( field ) { + + var items = field.find(' > .field-item').not('.hidden'); + + field.find( '> .field-item > .cmb-handle' ).remove(); + items.each( function() { + jQuery(this).append( '
' ); + } ); + + field.sortable( { + handle: "> .cmb-handle" , + cursor: "move", + items: " > .field-item", + beforeStop: function( event, ui ) { CMB.sortStart( jQuery( ui.item[0] ) ); }, + deactivate: function( event, ui ) { CMB.sortEnd( jQuery( ui.item[0] ) ); }, + } ); + + }, + + sortStart : function ( el ) { + + // also check child elements + el.add( el.find( 'div[data-class]' ) ).each( function(i, el) { + + el = jQuery( el ) + var callbacks = CMB._sortStartCallbacks[el.attr( 'data-class') ] + + if ( callbacks ) + for ( var a = 0; a < callbacks.length; a++ ) + callbacks[a]( el ) + + }) + + }, + + addCallbackForSortStart: function( fieldName, callback ) { + + if ( jQuery.isArray( fieldName ) ) + for ( var i = 0; i < fieldName.length; i++ ) + CMB.addCallbackForSortStart( fieldName[i], callback ); + + this._sortStartCallbacks[fieldName] = this._sortStartCallbacks[fieldName] ? this._sortStartCallbacks[fieldName] : [] + this._sortStartCallbacks[fieldName].push( callback ) + + }, + + sortEnd : function ( el ) { + + // also check child elements + el.add( el.find( 'div[data-class]' ) ).each( function(i, el) { + + el = jQuery( el ) + var callbacks = CMB._sortEndCallbacks[el.attr( 'data-class') ] + + if ( callbacks ) + for ( var a = 0; a < callbacks.length; a++ ) + callbacks[a]( el ) + + }) + + }, + + addCallbackForSortEnd: function( fieldName, callback ) { + + if ( jQuery.isArray( fieldName ) ) + for ( var i = 0; i < fieldName.length; i++ ) + CMB.addCallbackForSortEnd( fieldName[i], callback ); + + this._sortEndCallbacks[fieldName] = this._sortEndCallbacks[fieldName] ? this._sortEndCallbacks[fieldName] : [] + this._sortEndCallbacks[fieldName].push( callback ) + + } + } jQuery(document).ready( function() { diff --git a/js/field-wysiwyg.js b/js/field-wysiwyg.js index ceaafb6e..b259fc6d 100644 --- a/js/field-wysiwyg.js +++ b/js/field-wysiwyg.js @@ -63,4 +63,28 @@ CMB.addCallbackForClonedField( 'CMB_wysiwyg', function( newT ) { } ); -} ); \ No newline at end of file +} ); + + +CMB.addCallbackForSortStart( 'CMB_wysiwyg', function( el ) { + + el.find( '.wp-editor-area' ).each(function(){ + var id = jQuery(this).attr('id'); + tinyMCE.execCommand('mceRemoveControl', false, id); + }); + +} ); + +CMB.addCallbackForSortEnd( 'CMB_wysiwyg', function( el ) { + + el.find( '.wp-editor-area' ).each(function(){ + + var id = jQuery(this).attr('id'), + mode = jQuery(this).closest('.wp-editor-wrap').hasClass('tmce-active') ? 'tmce' : 'html'; + + if ( 'tmce' === mode ) + tinyMCE.execCommand('mceAddControl', false, id); + + }); + +} ); diff --git a/js/field.colorpicker.js b/js/field.colorpicker.js index 01bd32bc..a064e0db 100644 --- a/js/field.colorpicker.js +++ b/js/field.colorpicker.js @@ -15,4 +15,4 @@ CMB.addCallbackForClonedField( 'CMB_Color_Picker', function( newT ) { newT.find('.wp-color-result').remove(); newT.find('input:text.cmb_colorpicker').wpColorPicker(); -} ); +} ); \ No newline at end of file