| 1 |
const dispatch = wp.data.dispatch; |
| 2 |
|
| 3 |
jQuery( document ).ready( function ( $ ) { |
| 4 |
$( 'a.show-more' ).on( 'click', function () { |
| 5 |
const parent = $( this ).closest( 'td.day-unit' ); |
| 6 |
$( 'ul li', parent ).removeClass( 'hidden' ); |
| 7 |
$( this ).hide(); |
| 8 |
return false; |
| 9 |
} ); |
| 10 |
|
| 11 |
/** |
| 12 |
* Listen for click event and subsitute correct type of replacement |
| 13 |
* html given the input type |
| 14 |
*/ |
| 15 |
$( '.day-unit' ).on( 'click', '.editable-value', function ( event ) { |
| 16 |
//Reset anything that was currently being edited. |
| 17 |
reset_editorial_metadata(); |
| 18 |
const t = this; |
| 19 |
const $editable_el = $( this ).addClass( 'hidden' ).next( '.editable-html' ); |
| 20 |
|
| 21 |
if ( $editable_el.children().first().is( 'select' ) ) { |
| 22 |
$editable_el.find( 'option' ).each( function () { |
| 23 |
if ( $( this ).text() == $( t ).text() ) { |
| 24 |
$( this ).attr( 'selected', 'selected' ); |
| 25 |
} |
| 26 |
} ); |
| 27 |
} |
| 28 |
|
| 29 |
$editable_el |
| 30 |
.removeClass( 'hidden' ) |
| 31 |
.addClass( 'editing' ) |
| 32 |
.closest( '.day-item' ) |
| 33 |
.find( '.item-actions .save' ) |
| 34 |
.removeClass( 'hidden' ); |
| 35 |
} ); |
| 36 |
|
| 37 |
//Save the editorial metadata we've changed |
| 38 |
$( '.day-unit' ).on( 'click', 'a#save-editorial-metadata', function () { |
| 39 |
const post_id = $( this ).attr( 'class' ).replace( 'post-', '' ); |
| 40 |
save_editorial_metadata( post_id ); |
| 41 |
return false; |
| 42 |
} ); |
| 43 |
|
| 44 |
function reset_editorial_metadata() { |
| 45 |
$( '.editing' ).removeClass( 'editing' ).addClass( 'hidden' ).prev().removeClass( 'hidden' ); |
| 46 |
|
| 47 |
$( '.item-actions .save' ).addClass( 'hidden' ); |
| 48 |
} |
| 49 |
|
| 50 |
/** |
| 51 |
* save_editorial_metadata |
| 52 |
* Save the editorial metadata that's been edited (whatever is marked '#actively-editing'). |
| 53 |
* @param post_id Id of post we're editing |
| 54 |
*/ |
| 55 |
function save_editorial_metadata( post_id ) { |
| 56 |
const metadata_info = { |
| 57 |
action: 'ef_calendar_update_metadata', |
| 58 |
nonce: $( '#ef-calendar-modify' ).val(), |
| 59 |
metadata_type: $( '.editing' ).attr( 'data-type' ), |
| 60 |
metadata_value: $( '.editing' ).children().first().val(), |
| 61 |
metadata_term: $( '.editing' ).attr( 'data-metadataterm' ), |
| 62 |
post_id, |
| 63 |
}; |
| 64 |
|
| 65 |
$( '.editing' ) |
| 66 |
.addClass( 'hidden' ) |
| 67 |
.after( $( '<div class="spinner spinner-calendar"></div>' ).show() ); |
| 68 |
|
| 69 |
// Send the request |
| 70 |
jQuery.ajax( { |
| 71 |
type: 'POST', |
| 72 |
url: ajaxurl ? ajaxurl : wpListL10n.url, |
| 73 |
data: metadata_info, |
| 74 |
success( x ) { |
| 75 |
let val = $( '.editing' ).children().first(); |
| 76 |
if ( val.is( 'select' ) ) { |
| 77 |
val = val.find( 'option:selected' ).text(); |
| 78 |
} else { |
| 79 |
val = val.val(); |
| 80 |
} |
| 81 |
|
| 82 |
$( '.editing' ).next().remove(); |
| 83 |
|
| 84 |
$( '.editing' ) |
| 85 |
.addClass( 'hidden' ) |
| 86 |
.removeClass( 'editing' ) |
| 87 |
.prev() |
| 88 |
.removeClass( 'hidden' ) |
| 89 |
.text( val ); |
| 90 |
|
| 91 |
reset_editorial_metadata(); |
| 92 |
}, |
| 93 |
error( r ) { |
| 94 |
$( '.editing' ) |
| 95 |
.next( '.spinner' ) |
| 96 |
.replaceWith( '<span class="edit-flow-error-message">Error saving metadata.</span>' ); |
| 97 |
}, |
| 98 |
} ); |
| 99 |
} |
| 100 |
|
| 101 |
// Hide a message. Used by setTimeout() |
| 102 |
function edit_flow_calendar_hide_message() { |
| 103 |
$( '.edit-flow-message' ).fadeOut( function () { |
| 104 |
$( this ).remove(); |
| 105 |
} ); |
| 106 |
} |
| 107 |
|
| 108 |
// Close out all of the overlays with your escape key, |
| 109 |
// or by clicking anywhere other than inside an existing overlay |
| 110 |
$( document ).on( 'keydown', function ( event ) { |
| 111 |
if ( event.keyCode == '27' ) { |
| 112 |
edit_flow_calendar_close_overlays(); |
| 113 |
} |
| 114 |
} ); |
| 115 |
|
| 116 |
/** |
| 117 |
* Somewhat hackish way to close overlays automagically when you click outside an overlay |
| 118 |
*/ |
| 119 |
$( document ).on( 'click', function ( event ) { |
| 120 |
//Did we click on a list item? How do we figure that out? |
| 121 |
//First let's see if we directly clicked on a .day-item |
| 122 |
let target = $( event.target ); |
| 123 |
//Case where we've clicked on the list item directly |
| 124 |
if ( target.hasClass( 'day-item' ) ) { |
| 125 |
if ( target.hasClass( 'active' ) ) { |
| 126 |
return; |
| 127 |
} else if ( target.hasClass( 'post-insert-overlay' ) ) { |
| 128 |
return; |
| 129 |
} |
| 130 |
|
| 131 |
edit_flow_calendar_close_overlays(); |
| 132 |
|
| 133 |
target |
| 134 |
.addClass( 'active' ) |
| 135 |
.find( '.item-static' ) |
| 136 |
.removeClass( 'item-static' ) |
| 137 |
.addClass( 'item-overlay' ); |
| 138 |
|
| 139 |
return; |
| 140 |
} |
| 141 |
|
| 142 |
//Case where we've clicked in the list item |
| 143 |
target = target.closest( '.day-item' ); |
| 144 |
if ( target.length ) { |
| 145 |
if ( target.hasClass( 'day-item' ) ) { |
| 146 |
if ( target.hasClass( 'active' ) ) { |
| 147 |
return; |
| 148 |
} else if ( target.hasClass( 'post-insert-overlay' ) ) { |
| 149 |
return; |
| 150 |
} |
| 151 |
|
| 152 |
edit_flow_calendar_close_overlays(); |
| 153 |
|
| 154 |
target |
| 155 |
.addClass( 'active' ) |
| 156 |
.find( '.item-static' ) |
| 157 |
.removeClass( 'item-static' ) |
| 158 |
.addClass( 'item-overlay' ); |
| 159 |
|
| 160 |
return; |
| 161 |
} |
| 162 |
} |
| 163 |
|
| 164 |
target = $( event.target ).closest( '#ui-datepicker-div' ); |
| 165 |
if ( target.length ) { |
| 166 |
return; |
| 167 |
} |
| 168 |
|
| 169 |
target = $( event.target ).closest( '.post-insert-dialog' ); |
| 170 |
if ( target.length ) { |
| 171 |
return; |
| 172 |
} |
| 173 |
|
| 174 |
edit_flow_calendar_close_overlays(); |
| 175 |
} ); |
| 176 |
|
| 177 |
function edit_flow_calendar_close_overlays() { |
| 178 |
reset_editorial_metadata(); |
| 179 |
$( '.day-item.active' ) |
| 180 |
.removeClass( 'active' ) |
| 181 |
.find( '.item-overlay' ) |
| 182 |
.removeClass( 'item-overlay' ) |
| 183 |
.addClass( 'item-static' ); |
| 184 |
|
| 185 |
$( '.post-insert-overlay' ).remove(); |
| 186 |
} |
| 187 |
|
| 188 |
/** |
| 189 |
* Instantiates drag and drop sorting for posts on the calendar |
| 190 |
*/ |
| 191 |
let snackbarMessageTimeout = null; |
| 192 |
$( 'td.day-unit ul' ).sortable( { |
| 193 |
items: 'li.day-item.sortable', |
| 194 |
connectWith: 'td.day-unit ul', |
| 195 |
placeholder: 'ui-state-highlight', |
| 196 |
start( event, ui ) { |
| 197 |
$( this ).disableSelection(); |
| 198 |
edit_flow_calendar_close_overlays(); |
| 199 |
$( 'td.day-unit ul li' ).unbind( 'click.ef-calendar-show-overlay' ); |
| 200 |
$( this ).css( 'cursor', 'move' ); |
| 201 |
}, |
| 202 |
sort( event, ui ) { |
| 203 |
$( 'td.day-unit' ).removeClass( 'ui-wrapper-highlight' ); |
| 204 |
$( '.ui-state-highlight' ).closest( 'td.day-unit' ).addClass( 'ui-wrapper-highlight' ); |
| 205 |
}, |
| 206 |
stop( event, ui ) { |
| 207 |
$( this ).css( 'cursor', 'auto' ); |
| 208 |
$( 'td.day-unit' ).removeClass( 'ui-wrapper-highlight' ); |
| 209 |
// Only do a POST request if we moved the post off today |
| 210 |
if ( |
| 211 |
$( this ).closest( '.day-unit' ).attr( 'id' ) != |
| 212 |
$( ui.item ).closest( '.day-unit' ).attr( 'id' ) |
| 213 |
) { |
| 214 |
let post_id = $( ui.item ).attr( 'id' ).split( '-' ); |
| 215 |
post_id = post_id[ post_id.length - 1 ]; |
| 216 |
const prev_date = $( this ).closest( '.day-unit' ).attr( 'id' ); |
| 217 |
const next_date = $( ui.item ).closest( '.day-unit' ).attr( 'id' ); |
| 218 |
const nonce = $( document ).find( '#ef-calendar-modify' ).val(); |
| 219 |
$( '.edit-flow-message' ).remove(); |
| 220 |
dispatch( 'edit-flow/calendar' ).setCalendarIsLoading( true ); |
| 221 |
// $('li.ajax-actions .waiting').show(); |
| 222 |
// make ajax request |
| 223 |
const params = { |
| 224 |
action: 'ef_calendar_drag_and_drop', |
| 225 |
post_id, |
| 226 |
prev_date, |
| 227 |
next_date, |
| 228 |
nonce, |
| 229 |
}; |
| 230 |
jQuery.post( ajaxurl, params, function ( response ) { |
| 231 |
if ( snackbarMessageTimeout ) { |
| 232 |
clearTimeout( snackbarMessageTimeout ); |
| 233 |
} |
| 234 |
|
| 235 |
dispatch( 'edit-flow/calendar' ).setPostSaved( response.message ); |
| 236 |
|
| 237 |
snackbarMessageTimeout = setTimeout( () => { |
| 238 |
dispatch( 'edit-flow/calendar' ).clearCalendarSnackbarMessage(); |
| 239 |
}, 2500 ); |
| 240 |
|
| 241 |
setTimeout( edit_flow_calendar_hide_message, 10000 ); |
| 242 |
} ); |
| 243 |
} |
| 244 |
$( this ).enableSelection(); |
| 245 |
}, |
| 246 |
} ); |
| 247 |
|
| 248 |
// Enables quick creation/edit of drafts on a particular date from the calendar |
| 249 |
var EFQuickPublish = { |
| 250 |
/** |
| 251 |
* When user clicks the '+' on an individual calendar date or |
| 252 |
* double clicks on a calendar square pop up a form that allows |
| 253 |
* them to create a post for that date |
| 254 |
*/ |
| 255 |
init() { |
| 256 |
const $day_units = $( 'td.day-unit' ); |
| 257 |
|
| 258 |
// Bind the form display to the '+' button |
| 259 |
// or to a double click on the calendar square |
| 260 |
$day_units |
| 261 |
.find( '.schedule-new-post-button' ) |
| 262 |
.on( 'click.editFlow.quickPublish', EFQuickPublish.open_quickpost_dialogue ); |
| 263 |
$day_units.on( 'dblclick.editFlow.quickPublish', EFQuickPublish.open_quickpost_dialogue ); |
| 264 |
$day_units.on( 'mouseenter', function () { |
| 265 |
$( this ).find( '.schedule-new-post-button' ).stop().delay( 500 ).fadeIn( 100 ); |
| 266 |
} ); |
| 267 |
$day_units.on( 'mouseleave', function () { |
| 268 |
$( this ).find( '.schedule-new-post-button' ).stop().hide(); |
| 269 |
} ); |
| 270 |
}, // init |
| 271 |
|
| 272 |
/** |
| 273 |
* Callback for click and double click events that open the |
| 274 |
* quickpost dialogue |
| 275 |
* @param Event e The user interaction event |
| 276 |
*/ |
| 277 |
open_quickpost_dialogue( e ) { |
| 278 |
e.preventDefault(); |
| 279 |
|
| 280 |
// Close other overlays |
| 281 |
edit_flow_calendar_close_overlays(); |
| 282 |
|
| 283 |
$this = $( this ); |
| 284 |
|
| 285 |
// Get the current calendar square |
| 286 |
if ( $this.is( 'td.day-unit' ) ) { |
| 287 |
EFQuickPublish.$current_date_square = $this; |
| 288 |
} else if ( $this.is( '.schedule-new-post-button' ) ) { |
| 289 |
EFQuickPublish.$current_date_square = $this.parent(); |
| 290 |
} |
| 291 |
|
| 292 |
//Get our form content |
| 293 |
const $new_post_form_content = |
| 294 |
EFQuickPublish.$current_date_square.find( '.post-insert-dialog' ); |
| 295 |
|
| 296 |
//Inject the form (it will automatically be removed on click-away because of its 'item-overlay' class) |
| 297 |
EFQuickPublish.$new_post_form = $new_post_form_content |
| 298 |
.clone() |
| 299 |
.addClass( 'item-overlay post-insert-overlay' ) |
| 300 |
.appendTo( EFQuickPublish.$current_date_square ); |
| 301 |
|
| 302 |
// Get the inputs and controls for this injected form and focus the cursor on the post title box |
| 303 |
const $edit_post_link = EFQuickPublish.$new_post_form.find( |
| 304 |
'.post-insert-dialog-edit-post-link' |
| 305 |
); |
| 306 |
EFQuickPublish.$post_title_input = EFQuickPublish.$new_post_form |
| 307 |
.find( '.post-insert-dialog-post-title' ) |
| 308 |
.focus(); |
| 309 |
|
| 310 |
// Setup the ajax mechanism for form submit |
| 311 |
EFQuickPublish.$new_post_form.on( 'submit', function ( e ) { |
| 312 |
e.preventDefault(); |
| 313 |
EFQuickPublish.ajax_ef_create_post( false ); |
| 314 |
} ); |
| 315 |
|
| 316 |
// Setup direct link to new draft |
| 317 |
$edit_post_link.on( 'click', function ( e ) { |
| 318 |
e.preventDefault(); |
| 319 |
EFQuickPublish.ajax_ef_create_post( true ); |
| 320 |
} ); |
| 321 |
|
| 322 |
return false; // prevent bubbling up |
| 323 |
}, |
| 324 |
|
| 325 |
/** |
| 326 |
* Sends an ajax request to create a new post |
| 327 |
* @param bool redirect_to_draft Whether or not we should be redirected to the post's edit screen on success |
| 328 |
*/ |
| 329 |
ajax_ef_create_post( redirect_to_draft ) { |
| 330 |
// Get some of the form elements for later use |
| 331 |
const $submit_controls = EFQuickPublish.$new_post_form.find( '.post-insert-dialog-controls' ); |
| 332 |
const $spinner = EFQuickPublish.$new_post_form.find( '.spinner' ); |
| 333 |
|
| 334 |
// Set loading animation |
| 335 |
$submit_controls.hide(); |
| 336 |
$spinner.show(); |
| 337 |
|
| 338 |
// Delay submit to prevent spinner flashing |
| 339 |
setTimeout( function () { |
| 340 |
jQuery.ajax( { |
| 341 |
type: 'POST', |
| 342 |
url: ajaxurl, |
| 343 |
dataType: 'json', |
| 344 |
data: { |
| 345 |
action: 'ef_insert_post', |
| 346 |
ef_insert_date: EFQuickPublish.$new_post_form |
| 347 |
.find( 'input.post-insert-dialog-post-date' ) |
| 348 |
.val(), |
| 349 |
ef_insert_title: EFQuickPublish.$post_title_input.val(), |
| 350 |
nonce: $( document ).find( '#ef-calendar-modify' ).val(), |
| 351 |
}, |
| 352 |
success( response, textStatus, XMLHttpRequest ) { |
| 353 |
if ( response.status == 'success' ) { |
| 354 |
//The response message on success is the html for the a post list item |
| 355 |
const $new_post = $( response.message ); |
| 356 |
|
| 357 |
if ( redirect_to_draft ) { |
| 358 |
//If user clicked on the 'edit post' link, let's send them to the new post |
| 359 |
const edit_url = $new_post.find( '.item-actions .edit a' ).attr( 'href' ); |
| 360 |
window.location = edit_url; |
| 361 |
} else { |
| 362 |
// Otherwise, inject the new post and bind the appropriate click event |
| 363 |
$new_post.appendTo( EFQuickPublish.$current_date_square.find( 'ul.post-list' ) ); |
| 364 |
edit_flow_calendar_close_overlays(); |
| 365 |
} |
| 366 |
} else { |
| 367 |
EFQuickPublish.display_errors( EFQuickPublish.$new_post_form, response.message ); |
| 368 |
} |
| 369 |
}, |
| 370 |
error( XMLHttpRequest, textStatus, errorThrown ) { |
| 371 |
EFQuickPublish.display_errors( EFQuickPublish.$new_post_form, errorThrown ); |
| 372 |
}, |
| 373 |
} ); // .ajax |
| 374 |
|
| 375 |
return false; // prevent bubbling up |
| 376 |
}, 200 ); // setTimout |
| 377 |
}, // ajax_ef_create_post |
| 378 |
|
| 379 |
/** |
| 380 |
* Displays form errors and resets the UI |
| 381 |
* @param jQueryObj $form The form to display the errors in |
| 382 |
* @param str error_msg Error message |
| 383 |
*/ |
| 384 |
display_errors( $form, error_msg ) { |
| 385 |
$form.find( '.error' ).remove(); // clear out old errors |
| 386 |
$form.find( '.spinner' ).hide(); // stop the loading animation |
| 387 |
|
| 388 |
// show submit controls and the error |
| 389 |
$form |
| 390 |
.find( '.post-insert-dialog-controls' ) |
| 391 |
.show() |
| 392 |
.before( '<div class="error">Error: ' + error_msg + '</div>' ); |
| 393 |
}, // display_errors |
| 394 |
}; |
| 395 |
|
| 396 |
if ( ef_calendar_params.can_add_posts === 'true' ) { |
| 397 |
EFQuickPublish.init(); |
| 398 |
} |
| 399 |
} ); |
| 400 |
|