From 73d133c10755500c87152399205625d98578f997 Mon Sep 17 00:00:00 2001 From: And Finally Date: Thu, 8 Dec 2016 15:53:02 +0000 Subject: [PATCH 1/7] [save-button] Added save-zone-posts input to save the post list for the zone on demand. Added zoninator.forceSavePosts method to update internal post list and save the current UI post list to the zone. --- css/zoninator.css | 419 ++++++++++++++++++++++++++-------------------- js/zoninator.js | 145 +++++++++------- zoninator.php | 6 +- 3 files changed, 324 insertions(+), 246 deletions(-) diff --git a/css/zoninator.css b/css/zoninator.css index d9bc005..b901537 100644 --- a/css/zoninator.css +++ b/css/zoninator.css @@ -1,77 +1,93 @@ .wrap.zoninator-page { width: 95%; } + #zoninator-wrap { overflow: hidden; clear: both; position: relative; margin-top: 15px; } - #zoninator-wrap .delete { - color: #BC0B0B; - } + +#zoninator-wrap .delete { + color: #BC0B0B; +} /** Tabs **/ .zone-tabs-container { width: 30%; float: left; } - .zone-tabs-wrapper .zone-tab { - display: block; - background: #fff; - float: none; - font-size: 12px; - line-height: 16px; - padding: 4px 14px 6px; - margin: 0px; - font-weight: normal; - } - .zone-tabs-wrapper .zone-tab:hover, - .zone-tabs-wrapper .zone-tab:active, - .zone-tabs-wrapper .zone-tab-active { - background: #0074a2; - color: #fff; - margin-bottom: -1px; - } - .nav-tab-active { - float: none; - } + +.zone-tabs-wrapper .zone-tab { + display: block; + background: #fff; + float: none; + font-size: 12px; + line-height: 16px; + padding: 4px 14px 6px; + margin: 0px; + font-weight: normal; +} + +.zone-tabs-wrapper .zone-tab:hover, +.zone-tabs-wrapper .zone-tab:active, +.zone-tabs-wrapper .zone-tab-active { + background: #0074a2; + color: #fff; + margin-bottom: -1px; +} + +.nav-tab-active { + float: none; +} /** Edit **/ #zone-edit-wrapper { padding: 10px; overflow: hidden; border: 1px solid #ccc; - -moz-border-radius: 4px; -wekbit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; + -moz-border-radius: 4px; + -wekbit-border-radius: 4px; + -ms-border-radius: 4px; + border-radius: 4px; background: url(images/gray-grad.png) repeat-x scroll left top #dfdfdf; width: 67%; float: right; } - #zone-edit-wrapper .form-wrap { - margin: 0; - } - #zone-edit-wrapper .form-field { - padding: 0; - } - #zone-edit-wrapper .form-field.error { - padding: 0 10px 5px; - } - #zone-edit-wrapper .form-field input, - #zone-edit-wrapper .form-field textarea { - width: 98%; - } - #zone-edit-wrapper .submit-field { - width: 95%; - } - #zone-edit-wrapper .submit-field .submitdelete { - float: right; - } - #zone-info-readonly label { - font-weight: bold; - } - #zone-info-readonly span { - } + +#zone-edit-wrapper .form-wrap { + margin: 0; +} + +#zone-edit-wrapper .form-field { + padding: 0; +} + +#zone-edit-wrapper .form-field.error { + padding: 0 10px 5px; +} + +#zone-edit-wrapper .form-field input, +#zone-edit-wrapper .form-field textarea { + width: 98%; +} + +#zone-edit-wrapper .submit-field { + width: 95%; +} + +#zone-edit-wrapper .submit-field .submitdelete { + float: right; +} + +#zone-info-readonly label { + font-weight: bold; +} + +#zone-info-readonly span { +} /** Zone Posts **/ .zone-info-col { @@ -79,157 +95,197 @@ padding-bottom: 15px; margin-bottom: 15px; } + .zone-posts-col { background: #fff; border: 1px solid #ccc; - -moz-border-radius: 4px; -wekbit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; + -moz-border-radius: 4px; + -wekbit-border-radius: 4px; + -ms-border-radius: 4px; + border-radius: 4px; padding: 10px; } - .zone-posts-col h3 { - margin: 3px 0; - } - .zone-posts-wrapper.loading { - background: url(images/wpspin_light.gif) no-repeat right top; - } - .zone-posts-wrapper.readonly { - } - .zone-posts-wrapper.readonly .zone-search-wrapper, - .zone-posts-wrapper.readonly .row-actions { - display: none !important; - } - .zone-posts-wrapper.readonly .zone-post { - cursor: default !important; - } - .zone-posts-wrapper.readonly .zone-post:hover .zone-post-position { - background: none; - text-indent: 0; - } + +.zone-posts-col h3 { + margin: 3px 0; +} + +.zone-posts-wrapper.loading { + background: url(images/wpspin_light.gif) no-repeat right top; +} + +.zone-posts-wrapper.readonly { +} + +.zone-posts-wrapper.readonly .zone-search-wrapper, +.zone-posts-wrapper.readonly .row-actions { + display: none !important; +} + +.zone-posts-wrapper.readonly .zone-post { + cursor: default !important; +} + +.zone-posts-wrapper.readonly .zone-post:hover .zone-post-position { + background: none; + text-indent: 0; +} .zone-posts-list { margin: 10px 0; } - .zone-posts-list .ui-state-highlight { - margin-bottom: 5px; - -moz-border-radius: 4px; -wekbit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; - } - .zone-posts-list.ui-sortable .zone-post { - cursor: move; - } - .zone-post { - padding: 5px 0 5px 10px; - margin-bottom: 5px; - font-size: 12px; - line-height: 15px; - font-weight: bold; - color: #444; - overflow: hidden; - - border: 1px dotted #eee; - -moz-border-radius: 4px; -wekbit-border-radius: 4px; -ms-border-radius: 4px; border-radius: 4px; - - background: #f5f5f5; - } - .zone-post table { - width: 100%; - } - .zone-post-col { - } - .zone-post:hover .zone-post-position { - background: url(images/drag.png) no-repeat left center; - text-indent: -9999px; - } - .zone-post-position { - font-size: 24px; - line-height: 32px; - font-weight: normal; - text-align: center; - width: 32px; - } - /* - .zone-post-handle { - display: block; - background: url(images/drag.png) no-repeat center center; - width: 32px; - height: 32px; - - float: right; - visibility: hidden; - } - */ - .zone-post-status { - color: #999; - } - .zone-post .row-actions { - font-size: 11px; - font-weight: normal; - } - .zone-post:hover .row-actions, - .zone-post.loading .row-actions, - .zone-post:hover .zone-post-handle, - .zone-post.loading .zone-post-handle { - visibility: visible; - } - .zone-post.loading .zone-post-position { - background: url(images/wpspin_light.gif) no-repeat center center; - text-indent: -9999px; - } - .zone-search-wrapper { - padding: 7px 0; - border-bottom: 1px dotted #999; - } - #zone-post-search { - width: 99%; - } - #zone-post-latest { - width: 98%; - } + +.zone-posts-list .ui-state-highlight { + margin-bottom: 5px; + -moz-border-radius: 4px; + -wekbit-border-radius: 4px; + -ms-border-radius: 4px; + border-radius: 4px; +} + +.zone-posts-list.ui-sortable .zone-post { + cursor: move; +} + +.zone-post { + padding: 5px 0 5px 10px; + margin-bottom: 5px; + font-size: 12px; + line-height: 15px; + font-weight: bold; + color: #444; + overflow: hidden; + + border: 1px dotted #eee; + -moz-border-radius: 4px; + -wekbit-border-radius: 4px; + -ms-border-radius: 4px; + border-radius: 4px; + + background: #f5f5f5; +} + +.zone-post table { + width: 100%; +} + +.zone-post-col { +} + +.zone-post:hover .zone-post-position { + background: url(images/drag.png) no-repeat left center; + text-indent: -9999px; +} + +.zone-post-position { + font-size: 24px; + line-height: 32px; + font-weight: normal; + text-align: center; + width: 32px; +} + +/* +.zone-post-handle { + display: block; + background: url(images/drag.png) no-repeat center center; + width: 32px; + height: 32px; + + float: right; + visibility: hidden; +} +*/ +.zone-post-status { + color: #999; +} + +.zone-post .row-actions { + font-size: 11px; + font-weight: normal; +} + +.zone-post:hover .row-actions, +.zone-post.loading .row-actions, +.zone-post:hover .zone-post-handle, +.zone-post.loading .zone-post-handle { + visibility: visible; +} + +.zone-post.loading .zone-post-position { + background: url(images/wpspin_light.gif) no-repeat center center; + text-indent: -9999px; +} + +.zone-search-wrapper { + padding: 7px 0; + border-bottom: 1px dotted #999; +} + +.zone-posts-save-input { + padding: 7px 0; +} + +#zone-post-search { + width: 99%; +} + +#zone-post-latest { + width: 98%; +} /** Autocomplete **/ .ui-autocomplete-input.loading { background: url(images/wpspin_light.gif) no-repeat right center; } + .ui-autocomplete { min-width: 330px; max-width: 600px; font-size: 13px; line-height: 17px; } - .ui-autocomplete .ui-corner-all { - padding-top: 5px; - padding-bottom: 5px; - border-bottom: 1px dotted #eee; - cursor: pointer; - overflow: hidden; - } - .ui-autocomplete .title { - display: block; - width: 80%; - float: left; - } - .ui-autocomplete .date { - text-transform: uppercase; - color: #666; - font-size: 11px; - clear: both; - float: left; - } - .ui-autocomplete .type { - text-transform: uppercase; - color: #666; - font-size: 11px; - width: 19%; - margin-left: 1%; - float: right; - text-align: right; - } - .ui-autocomplete .status { - font-size: 10px; - width: 19%; - margin-left: 1%; - float: right; - text-align: right; - } + +.ui-autocomplete .ui-corner-all { + padding-top: 5px; + padding-bottom: 5px; + border-bottom: 1px dotted #eee; + cursor: pointer; + overflow: hidden; +} + +.ui-autocomplete .title { + display: block; + width: 80%; + float: left; +} + +.ui-autocomplete .date { + text-transform: uppercase; + color: #666; + font-size: 11px; + clear: both; + float: left; +} + +.ui-autocomplete .type { + text-transform: uppercase; + color: #666; + font-size: 11px; + width: 19%; + margin-left: 1%; + float: right; + text-align: right; +} + +.ui-autocomplete .status { + font-size: 10px; + width: 19%; + margin-left: 1%; + float: right; + text-align: right; +} .zone-advanced-search-filters-wrapper { display: none; @@ -239,6 +295,7 @@ float: right; font-weight: bold; } - .zone-toggle-advanced-search { - cursor: pointer; - } + +.zone-toggle-advanced-search { + cursor: pointer; +} diff --git a/js/zoninator.js b/js/zoninator.js index 2cda4a9..3d1898e 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -1,7 +1,7 @@ var zoninator = {} ;(function($, window, undefined) { - + zoninator.init = function() { zoninator.autocompleteCache = {} zoninator.autocompleteAjax = {} @@ -12,7 +12,7 @@ var zoninator = {} zoninator.$zoneAdvancedCat = $("#zone_advanced_filter_taxonomy"); zoninator.$zoneAdvancedDate = $("#zone_advanced_filter_date"); zoninator.$zoneSubmit = $("#zone-info input[type='submit']") - + zoninator.$zonePostsSave = $('#save-zone-posts'); zoninator.$zoneAdvancedDate.change(function() { zoninator.autocompleteCache = {}; @@ -24,11 +24,11 @@ var zoninator = {} zoninator.updateLatest(); }); - zoninator.updatePostOrder(); - + zoninator.updatePostOrder(); + // Bind actions to buttons zoninator.initZonePost(zoninator.$zonePostsList.children()); - + // Initialize sortable if(!zoninator.$zonePostsWrap.hasClass('readonly')) { zoninator.$zonePostsList.sortable({ @@ -38,7 +38,7 @@ var zoninator = {} //, handle: '.zone-post-handle' }); } - + // Bind loading events zoninator.$zonePostsWrap .bind('loading.start', function() { @@ -49,20 +49,22 @@ var zoninator = {} $(this).removeClass('loading'); zoninator.$zoneSubmit.attr("disabled", false); }); - + // Validate form // TODO: This is really simplistic validation; beef it up a bit. $('#zone-info').submit(function(e) { var $form = $(this); var $name = $form.find('input[name="name"]'); if( !$name.val().trim() ) { - $name.closest( '.zone-field' ).addClass('error'); + $name.closest( '.zone-field' ).addClass('error'); return false; } else { - $name.closest( '.zone-field' ).removeClass('error'); + $name.closest( '.zone-field' ).removeClass('error'); } }); + zoninator.$zonePostsSave.on('click', zoninator.forceSavePosts); + zoninator.$zonePostLatest.change(function() { var $this = $(this), post_id = $this.val(); @@ -72,7 +74,7 @@ var zoninator = {} } }); - + // Initialize autocomplete if(zoninator.$zonePostSearch.length) { @@ -98,7 +100,7 @@ var zoninator = {} zoninator.$zonePostSearch.trigger('loading.end'); return; } - + // Append more request vars request.action = zoninator.getAjaxAction('search_posts'); request.exclude = zoninator.getZonePostIds(); @@ -139,7 +141,7 @@ var zoninator = {} ; } } - + // Initialize lock heartbeat if( zoninator.getZoneId() && ! $('#zone-locked').length ) { zoninator.currentLockPeriod = 0; @@ -149,16 +151,16 @@ var zoninator = {} if( zoninator.heartbeatInterval > 0 && zoninator.maxLockPeriod != -1) { zoninator.heartbeatInterval = zoninator.heartbeatInterval * 1000; zoninator.maxLockPeriod = zoninator.maxLockPeriod * 1000; - + zoninator.updateLock(); } } - + // TODO: move / copy posts to zones } zoninator.updateLatest = function() { - + zoninator.$zonePostSearch.trigger('loading.start'); zoninator.ajax('update_recent', { zone_id: zoninator.getZoneId(), @@ -176,40 +178,40 @@ var zoninator = {} } zoninator.addPost = function(postId) { - + zoninator.$zonePostSearch.trigger('loading.start'); - + zoninator.ajax('add_post', { zone_id: zoninator.getZoneId() , post_id: postId }, zoninator.addPostSuccessCallback); - + } - + zoninator.addPostSuccessCallback = function(returnData) { - + zoninator.$zonePostSearch.trigger('loading.end'); - + // Add Post to List var $post = $(returnData.content); $post.hide() .appendTo(zoninator.$zonePostsList) .fadeIn() ; - + zoninator.initZonePost($post); - + // Reorder Posts zoninator.updatePostOrder(true); } - + zoninator.initZonePost = function($elem) { $elem.bind('loading.start', function(e) { $(this).addClass('loading'); }).bind('loading.end', function(e) { $(this).removeClass('loading'); }); - + $elem.find('.delete').bind('click', function(e) { e.preventDefault(); var postId = zoninator.getPostIdFromElem(this); @@ -219,16 +221,16 @@ var zoninator = {} zoninator.removePost = function(postId) { zoninator.getPost(postId).trigger('loading.start'); - + zoninator.ajax('remove_post', { zone_id: zoninator.getZoneId() , post_id: postId - }, zoninator.removePostSuccessCallback); + }, zoninator.removePostSuccessCallback); } - + zoninator.removePostSuccessCallback = function(returnData, originalData) { var postId = originalData.post_id; - + zoninator.getPost(postId).fadeOut('slow', function() { $(this).remove(); if ( zoninator.getZonePostIds().length ) @@ -242,35 +244,35 @@ var zoninator = {} var zoneId = zoninator.getZoneId() , postIds = zoninator.getZonePostIds() ; - + // Reorder only if changed if(!compareArrays(postIds, zoninator.getPostOrder())) { var data = { zone_id: zoneId , posts: postIds } - + zoninator.$zonePostsWrap.trigger('loading.start'); - + // make ajax call to save order zoninator.ajax('reorder_posts', data, zoninator.reorderPostsSuccessCallback); } } - + zoninator.reorderPostsSuccessCallback = function(returnData, originalData) { zoninator.$zonePostsWrap.trigger('loading.end'); zoninator.updatePostOrder(false); - + // The user took some action so reset the lock period zoninator.resetCurrentLockPeriod(); } - + zoninator.updateLock = function() { zoninator.ajax('update_lock', { zone_id: zoninator.getZoneId() - }, function(returnData, originalData) { + }, function(returnData, originalData) { zoninator.currentLockPeriod += zoninator.heartbeatInterval; - + // We want to set a max to avoid people leaving their tabs open and then running away for long periods if( zoninator.currentLockPeriod < zoninator.maxLockPeriod ) { setTimeout(zoninator.updateLock, zoninator.heartbeatInterval); @@ -284,11 +286,11 @@ var zoninator = {} location.reload(); }); } - + zoninator.resetCurrentLockPeriod = function() { zoninator.currentLockPeriod = 0; } - + zoninator.ajax = function(action, values, successCallback, errorCallback, params) { var data = { action: zoninator.getAjaxAction(action) @@ -312,28 +314,28 @@ var zoninator = {} } } params = $.extend({}, defaultParams, params); - + $.ajax(params); } - + zoninator.ajaxSuccessCallback = function(returnData, originalData, successCallback, errorCallback) { if(typeof(returnData) === 'undefined' || !returnData.status) { // If we didn't get a valid return, it's probably an error return zoninator.ajaxErrorCallback(returnData, originalData, successCallback, errorCallback); } - + //console.log('ajaxSuccessCallback', returnData, originalData); - + if(returnData.nonce) zoninator.updateAjaxNonce(returnData.nonce); - + if(typeof(successCallback) === 'function') { - return successCallback(returnData, originalData); + return successCallback(returnData, originalData); } else { alert(returnData.content); } } - + zoninator.ajaxErrorCallback = function(returnData, originalData, successCallback, errorCallback) { if( typeof(returnData) === 'undefined' || !returnData ) { returnData = { @@ -341,18 +343,18 @@ var zoninator = {} , content: zoninatorOptions.errorGeneral } } - + //console.log('ajaxErrorCallback', returnData, originalData); - + if(typeof(errorCallback) === 'function') { - return errorCallback(returnData, originalData); + return errorCallback(returnData, originalData); } else { if( typeof(returnData.content) === 'undefined' || !returnData.content ) returnData.content = zoninatorOptions.errorGeneral; alert(returnData.content); } } - + zoninator.updateAjaxNonce = function(action, nonce) { zoninator.getAjaxNonceField(action).val(nonce); } @@ -364,7 +366,7 @@ var zoninator = {} zoninator.getAdvancedDate = function() { return $('#zone_advanced_filter_date').length ? zoninator.$zoneAdvancedDate.val() : 0; } - + zoninator.getAjaxNonce = function(action) { return zoninator.getAjaxNonceField(action).val(); } @@ -372,23 +374,23 @@ var zoninator = {} action = action || zoninatorOptions.ajaxNonceAction; return $('#' + action ); } - + zoninator.getZoneId = function() { return $('#zone_id').length ? $('#zone_id').val() : 0; } - + zoninator.getZonePosts = function() { return zoninator.$zonePostsList.children(); } - + zoninator.getPost = function(postId) { return $('#zone-post-' + postId); } - + zoninator.getPostIdFromElem = function(elem) { return $(elem).closest('.zone-post').attr('data-post-id'); } - + zoninator.getZonePostIds = function() { var ids = [] , $posts = zoninator.getZonePosts(); @@ -397,34 +399,49 @@ var zoninator = {} }); return ids; } - + zoninator.getPostOrder = function() { if(!$.isArray(zoninator.currentPostOrder)) zoninator.updatePostOrder(); return zoninator.currentPostOrder; } - + zoninator.updatePostOrder = function(save) { if(save) zoninator.reorderPosts(); - + zoninator.currentPostOrder = zoninator.getZonePostIds(); zoninator.renumberPosts(); } - + zoninator.renumberPosts = function() { var $numbers = zoninator.$zonePostsList.find('.zone-post-position'); $numbers.each(function(i, elem) { $(elem).text(i + 1); }); } - + zoninator.getAjaxAction = function(action) { return 'zoninator_' + action; } zoninator.emptyFunc = function() {} + zoninator.forceSavePosts = function() { + // Grab post list from DOM + var zoneId = zoninator.getZoneId(), + postIds = zoninator.getZonePostIds(), + data = { + zone_id: zoneId, + posts : postIds + } + // Update internal list to match UI list + zoninator.updatePostOrder(); + // Save list to server + zoninator.$zonePostsWrap.trigger('loading.start'); + zoninator.ajax('reorder_posts', data, zoninator.reorderPostsSuccessCallback); + }; + /** * compareArrays - Compares two arrays! * @@ -440,13 +457,13 @@ var zoninator = {} */ var compareArrays = function(arr1, arr2, sort) { if (arr1.length != arr2.length) return false; - + if(sort) { arr1 = arr1.sort(), arr2 = arr2.sort(); } for (var i = 0; arr2[i]; i++) { - if (arr1[i] !== arr2[i]) { + if (arr1[i] !== arr2[i]) { return false; } } @@ -464,7 +481,7 @@ var zoninator = {} }); // TODO: fix this - function parseIntOrZero(str) { + function parseIntOrZero(str) { var parsed = parseInt( str ); if( isNaN(parsed) || !parsed ) parsed = 0; return parsed; diff --git a/zoninator.php b/zoninator.php index 5f46d47..f32b2cb 100644 --- a/zoninator.php +++ b/zoninator.php @@ -394,7 +394,7 @@ function admin_page_zone_edit( $zone = null ) {
- + @@ -449,6 +449,10 @@ function admin_page_zone_edit( $zone = null ) { zone_admin_search_form(); ?> +
+ +
+
admin_page_zone_post( $post, $zone ); ?> From 3f7210a6148e439127e8c8856f5523822ba9006e Mon Sep 17 00:00:00 2001 From: And Finally Date: Thu, 8 Dec 2016 15:58:05 +0000 Subject: [PATCH 2/7] [save-button] Added a few comments to the JS. Changed some single quotes to double for consistency. --- js/zoninator.js | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/js/zoninator.js b/js/zoninator.js index 3d1898e..9b2ac8d 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -3,15 +3,15 @@ var zoninator = {} ;(function($, window, undefined) { zoninator.init = function() { - zoninator.autocompleteCache = {} - zoninator.autocompleteAjax = {} + zoninator.autocompleteCache = {}; + zoninator.autocompleteAjax = {}; zoninator.$zonePostsList = $('.zone-posts-list'); zoninator.$zonePostsWrap = $('.zone-posts-wrapper'); - zoninator.$zonePostSearch = $("#zone-post-search"); - zoninator.$zonePostLatest = $("#zone-post-latest"); - zoninator.$zoneAdvancedCat = $("#zone_advanced_filter_taxonomy"); - zoninator.$zoneAdvancedDate = $("#zone_advanced_filter_date"); - zoninator.$zoneSubmit = $("#zone-info input[type='submit']") + zoninator.$zonePostSearch = $('#zone-post-search'); + zoninator.$zonePostLatest = $('#zone-post-latest'); + zoninator.$zoneAdvancedCat = $('#zone_advanced_filter_taxonomy'); + zoninator.$zoneAdvancedDate = $('#zone_advanced_filter_date'); + zoninator.$zoneSubmit = $('#zone-info input[type="submit"]'); zoninator.$zonePostsSave = $('#save-zone-posts'); zoninator.$zoneAdvancedDate.change(function() { @@ -24,12 +24,13 @@ var zoninator = {} zoninator.updateLatest(); }); + // Update the currentPostOrder property which keeps track of the list order internally zoninator.updatePostOrder(); // Bind actions to buttons zoninator.initZonePost(zoninator.$zonePostsList.children()); - // Initialize sortable + // Initialize sortable - call reorderPosts method when the user drops a post element if(!zoninator.$zonePostsWrap.hasClass('readonly')) { zoninator.$zonePostsList.sortable({ stop: zoninator.reorderPosts @@ -65,6 +66,7 @@ var zoninator = {} zoninator.$zonePostsSave.on('click', zoninator.forceSavePosts); + // On selecting a post from the latest posts list, add it to the zone zoninator.$zonePostLatest.change(function() { var $this = $(this), post_id = $this.val(); @@ -240,12 +242,12 @@ var zoninator = {} } zoninator.reorderPosts = function() { - // get list of post ids + // Get list of post ids from the DOM var zoneId = zoninator.getZoneId() , postIds = zoninator.getZonePostIds() ; - // Reorder only if changed + // Reorder only if DOM list has changed compared to internal list if(!compareArrays(postIds, zoninator.getPostOrder())) { var data = { zone_id: zoneId @@ -379,6 +381,7 @@ var zoninator = {} return $('#zone_id').length ? $('#zone_id').val() : 0; } + // Get the list of posts from the DOM zoninator.getZonePosts = function() { return zoninator.$zonePostsList.children(); } @@ -391,6 +394,7 @@ var zoninator = {} return $(elem).closest('.zone-post').attr('data-post-id'); } + // Get the IDs of post elements in the DOM list zoninator.getZonePostIds = function() { var ids = [] , $posts = zoninator.getZonePosts(); @@ -400,12 +404,14 @@ var zoninator = {} return ids; } + // Get the post list we stored internally zoninator.getPostOrder = function() { if(!$.isArray(zoninator.currentPostOrder)) zoninator.updatePostOrder(); return zoninator.currentPostOrder; } + // Update the internal list based on the list in the DOM zoninator.updatePostOrder = function(save) { if(save) zoninator.reorderPosts(); @@ -414,6 +420,7 @@ var zoninator = {} zoninator.renumberPosts(); } + // Change the numbers in the UI to match the order of posts in the list zoninator.renumberPosts = function() { var $numbers = zoninator.$zonePostsList.find('.zone-post-position'); $numbers.each(function(i, elem) { From ebf35a549be6127fe5d51a45a000b1c64394d215 Mon Sep 17 00:00:00 2001 From: And Finally Date: Thu, 8 Dec 2016 16:54:05 +0000 Subject: [PATCH 3/7] [save-button] Added zone-posts-save-info element - displaying save status from ajaxSuccessCallback and any error from ajaxErrorCallback. --- css/zoninator.css | 19 +++++ js/zoninator.js | 198 ++++++++++++++++++++++++++-------------------- zoninator.php | 3 +- 3 files changed, 135 insertions(+), 85 deletions(-) diff --git a/css/zoninator.css b/css/zoninator.css index b901537..fb54248 100644 --- a/css/zoninator.css +++ b/css/zoninator.css @@ -225,8 +225,27 @@ .zone-posts-save-input { padding: 7px 0; + overflow: hidden; +} + +#zone-posts-save { + float: left; } +.zone-posts-save-info { + float: left; + margin: 0 0 0 10px; + padding: 0 10px; + line-height: 30px; + color: #666; +} + +.notice-error { color: #a94442; background-color: #f2dede; } + +.notice-success { color: #3c763d; background-color: #dff0d8; } + +.notice-info { color: #0f1d79; background-color: #d9edf7; } + #zone-post-search { width: 99%; } diff --git a/js/zoninator.js b/js/zoninator.js index 9b2ac8d..f79f883 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -1,6 +1,7 @@ var zoninator = {} -;(function($, window, undefined) { + ; +(function($, window, undefined) { zoninator.init = function() { zoninator.autocompleteCache = {}; @@ -12,7 +13,8 @@ var zoninator = {} zoninator.$zoneAdvancedCat = $('#zone_advanced_filter_taxonomy'); zoninator.$zoneAdvancedDate = $('#zone_advanced_filter_date'); zoninator.$zoneSubmit = $('#zone-info input[type="submit"]'); - zoninator.$zonePostsSave = $('#save-zone-posts'); + zoninator.$zonePostsSave = $('#zone-posts-save'); + zoninator.$zonePostsSaveInfo = $('#zone-posts-save-info'); zoninator.$zoneAdvancedDate.change(function() { zoninator.autocompleteCache = {}; @@ -31,10 +33,10 @@ var zoninator = {} zoninator.initZonePost(zoninator.$zonePostsList.children()); // Initialize sortable - call reorderPosts method when the user drops a post element - if(!zoninator.$zonePostsWrap.hasClass('readonly')) { + if (!zoninator.$zonePostsWrap.hasClass('readonly')) { zoninator.$zonePostsList.sortable({ - stop: zoninator.reorderPosts - , placeholder: 'ui-state-highlight' + stop : zoninator.reorderPosts + , placeholder : 'ui-state-highlight' , forcePlaceholderSize: true //, handle: '.zone-post-handle' }); @@ -56,11 +58,11 @@ var zoninator = {} $('#zone-info').submit(function(e) { var $form = $(this); var $name = $form.find('input[name="name"]'); - if( !$name.val().trim() ) { - $name.closest( '.zone-field' ).addClass('error'); + if (!$name.val().trim()) { + $name.closest('.zone-field').addClass('error'); return false; } else { - $name.closest( '.zone-field' ).removeClass('error'); + $name.closest('.zone-field').removeClass('error'); } }); @@ -70,16 +72,15 @@ var zoninator = {} zoninator.$zonePostLatest.change(function() { var $this = $(this), post_id = $this.val(); - if ( post_id ) { - zoninator.addPost( post_id ); - $this.find( '[value="' + post_id + '"]' ).remove(); + if (post_id) { + zoninator.addPost(post_id); + $this.find('[value="' + post_id + '"]').remove(); } }); - // Initialize autocomplete - if(zoninator.$zonePostSearch.length) { + if (zoninator.$zonePostSearch.length) { zoninator.$zonePostSearch .bind('loading.start', function(e) { $(this).addClass('loading'); @@ -90,15 +91,15 @@ var zoninator = {} .autocomplete({ minLength: 3 // Remote source with caching - , source: function( request, response ) { + , source : function(request, response) { var term = request.term; request.cat = zoninator.getAdvancedCat(); request.date = zoninator.getAdvancedDate(); request.zone_id = zoninator.getZoneId(); - if ( term in zoninator.autocompleteCache ) { //&& request.cat && request.date ) { - response( zoninator.autocompleteCache[ term ] ); + if (term in zoninator.autocompleteCache) { //&& request.cat && request.date ) { + response(zoninator.autocompleteCache[term]); zoninator.$zonePostSearch.trigger('loading.end'); return; } @@ -110,47 +111,47 @@ var zoninator = {} // Allow developers to hook onto the request zoninator.$zonePostSearch.trigger('search.request', request); - zoninator.autocompleteAjax = $.getJSON( ajaxurl, request, function( data, status, xhr ) { - zoninator.autocompleteCache[ term ] = data; - if ( xhr === zoninator.autocompleteAjax ) { - response( data ); + zoninator.autocompleteAjax = $.getJSON(ajaxurl, request, function(data, status, xhr) { + zoninator.autocompleteCache[term] = data; + if (xhr === zoninator.autocompleteAjax) { + response(data); } zoninator.$zonePostSearch.trigger('loading.end'); }); } - , select: function( e, ui ) { + , select : function(e, ui) { zoninator.addPost(ui.item.post_id); } - , search: function( e, ui ) { + , search : function(e, ui) { zoninator.$zonePostSearch.trigger('loading.start'); } }); // Compat with jQuery 1.8 and 1.9; the latter uses ui- prefix for data attribute - var autocomplete = zoninator.$zonePostSearch.data( 'autocomplete' ) || zoninator.$zonePostSearch.data( 'ui-autocomplete' ); + var autocomplete = zoninator.$zonePostSearch.data('autocomplete') || zoninator.$zonePostSearch.data('ui-autocomplete'); - autocomplete._renderItem = function( ul, item ) { + autocomplete._renderItem = function(ul, item) { var content = '' + '' + item.title + '' + '' + item.post_type + '' + '' + item.date + '' + '' + item.post_status + '' + ''; - return $( '
  • ' ) - .data( 'item.autocomplete', item ) - .append( content ) - .appendTo( ul ) + return $('
  • ') + .data('item.autocomplete', item) + .append(content) + .appendTo(ul) ; } } // Initialize lock heartbeat - if( zoninator.getZoneId() && ! $('#zone-locked').length ) { + if (zoninator.getZoneId() && !$('#zone-locked').length) { zoninator.currentLockPeriod = 0; - zoninator.heartbeatInterval = parseInt( zoninatorOptions.zoneLockPeriod ); - zoninator.maxLockPeriod = parseInt( zoninatorOptions.zoneLockPeriodMax ); + zoninator.heartbeatInterval = parseInt(zoninatorOptions.zoneLockPeriod); + zoninator.maxLockPeriod = parseInt(zoninatorOptions.zoneLockPeriodMax); - if( zoninator.heartbeatInterval > 0 && zoninator.maxLockPeriod != -1) { + if (zoninator.heartbeatInterval > 0 && zoninator.maxLockPeriod != -1) { zoninator.heartbeatInterval = zoninator.heartbeatInterval * 1000; zoninator.maxLockPeriod = zoninator.maxLockPeriod * 1000; @@ -166,8 +167,8 @@ var zoninator = {} zoninator.$zonePostSearch.trigger('loading.start'); zoninator.ajax('update_recent', { zone_id: zoninator.getZoneId(), - cat: zoninator.getAdvancedCat(), - date: zoninator.getAdvancedDate() + cat : zoninator.getAdvancedCat(), + date : zoninator.getAdvancedDate() }, zoninator.addUpdateLatestSuccessCallback); } @@ -184,7 +185,7 @@ var zoninator = {} zoninator.$zonePostSearch.trigger('loading.start'); zoninator.ajax('add_post', { - zone_id: zoninator.getZoneId() + zone_id : zoninator.getZoneId() , post_id: postId }, zoninator.addPostSuccessCallback); @@ -199,7 +200,7 @@ var zoninator = {} $post.hide() .appendTo(zoninator.$zonePostsList) .fadeIn() - ; + ; zoninator.initZonePost($post); @@ -225,7 +226,7 @@ var zoninator = {} zoninator.getPost(postId).trigger('loading.start'); zoninator.ajax('remove_post', { - zone_id: zoninator.getZoneId() + zone_id : zoninator.getZoneId() , post_id: postId }, zoninator.removePostSuccessCallback); } @@ -235,7 +236,7 @@ var zoninator = {} zoninator.getPost(postId).fadeOut('slow', function() { $(this).remove(); - if ( zoninator.getZonePostIds().length ) + if (zoninator.getZonePostIds().length) zoninator.updatePostOrder(true); zoninator.$zonePostsWrap.trigger('loading.end'); }); @@ -248,7 +249,7 @@ var zoninator = {} ; // Reorder only if DOM list has changed compared to internal list - if(!compareArrays(postIds, zoninator.getPostOrder())) { + if (!compareArrays(postIds, zoninator.getPostOrder())) { var data = { zone_id: zoneId , posts: postIds @@ -276,7 +277,7 @@ var zoninator = {} zoninator.currentLockPeriod += zoninator.heartbeatInterval; // We want to set a max to avoid people leaving their tabs open and then running away for long periods - if( zoninator.currentLockPeriod < zoninator.maxLockPeriod ) { + if (zoninator.currentLockPeriod < zoninator.maxLockPeriod) { setTimeout(zoninator.updateLock, zoninator.heartbeatInterval); } else { alert(zoninatorOptions.errorZoneLockMax); @@ -295,43 +296,61 @@ var zoninator = {} zoninator.ajax = function(action, values, successCallback, errorCallback, params) { var data = { - action: zoninator.getAjaxAction(action) + action : zoninator.getAjaxAction(action) , _wpnonce: zoninator.getAjaxNonce() } data = $.extend({}, data, values); // Allow developers to filter the ajax parameters - zoninator.$zonePostSearch.trigger( 'zoninator.ajax', [ action, data ] ); + zoninator.$zonePostSearch.trigger('zoninator.ajax', [action, data]); var defaultParams = { - url: ajaxurl - , data: data + url : ajaxurl + , data : data , dataType: 'json' - , type: 'POST' - , success: function(returnData) { + , type : 'POST' + , success : function(returnData) { zoninator.ajaxSuccessCallback(returnData, data, successCallback, errorCallback); } - , error: function(returnData) { + , error : function(returnData) { zoninator.ajaxErrorCallback(returnData, data, successCallback, errorCallback); } } params = $.extend({}, defaultParams, params); + if (action === 'reorder_posts') { + zoninator.$zonePostsSaveInfo + .removeClass('notice-error') + .addClass('notice-info') + .text('Saving...') + } + $.ajax(params); } zoninator.ajaxSuccessCallback = function(returnData, originalData, successCallback, errorCallback) { - if(typeof(returnData) === 'undefined' || !returnData.status) { + if (typeof(returnData) === 'undefined' || !returnData.status) { // If we didn't get a valid return, it's probably an error return zoninator.ajaxErrorCallback(returnData, originalData, successCallback, errorCallback); } //console.log('ajaxSuccessCallback', returnData, originalData); - if(returnData.nonce) + if (originalData.action === 'zoninator_reorder_posts') { + zoninator.$zonePostsSaveInfo + .removeClass('notice-error') + .addClass('notice-info') + .text('Saved at ' + new Date().toLocaleTimeString()); + } + + setTimeout(function() { + zoninator.$zonePostsSaveInfo.removeClass('notice-info'); + }, 1000); + + if (returnData.nonce) zoninator.updateAjaxNonce(returnData.nonce); - if(typeof(successCallback) === 'function') { + if (typeof(successCallback) === 'function') { return successCallback(returnData, originalData); } else { alert(returnData.content); @@ -339,19 +358,26 @@ var zoninator = {} } zoninator.ajaxErrorCallback = function(returnData, originalData, successCallback, errorCallback) { - if( typeof(returnData) === 'undefined' || !returnData ) { + if (typeof(returnData) === 'undefined' || !returnData) { returnData = { - status: 0 + status : 0 , content: zoninatorOptions.errorGeneral } } //console.log('ajaxErrorCallback', returnData, originalData); - if(typeof(errorCallback) === 'function') { + if (originalData.action === 'zoninator_reorder_posts') { + zoninator.$zonePostsSaveInfo + .removeClass('notice-info') + .addClass('notice-error') + .text('Error saving posts. Please try again.'); + } + + if (typeof(errorCallback) === 'function') { return errorCallback(returnData, originalData); } else { - if( typeof(returnData.content) === 'undefined' || !returnData.content ) + if (typeof(returnData.content) === 'undefined' || !returnData.content) returnData.content = zoninatorOptions.errorGeneral; alert(returnData.content); } @@ -374,7 +400,7 @@ var zoninator = {} } zoninator.getAjaxNonceField = function(action) { action = action || zoninatorOptions.ajaxNonceAction; - return $('#' + action ); + return $('#' + action); } zoninator.getZoneId = function() { @@ -406,14 +432,14 @@ var zoninator = {} // Get the post list we stored internally zoninator.getPostOrder = function() { - if(!$.isArray(zoninator.currentPostOrder)) + if (!$.isArray(zoninator.currentPostOrder)) zoninator.updatePostOrder(); return zoninator.currentPostOrder; } // Update the internal list based on the list in the DOM zoninator.updatePostOrder = function(save) { - if(save) + if (save) zoninator.reorderPosts(); zoninator.currentPostOrder = zoninator.getZonePostIds(); @@ -424,15 +450,16 @@ var zoninator = {} zoninator.renumberPosts = function() { var $numbers = zoninator.$zonePostsList.find('.zone-post-position'); $numbers.each(function(i, elem) { - $(elem).text(i + 1); - }); + $(elem).text(i + 1); + }); } zoninator.getAjaxAction = function(action) { return 'zoninator_' + action; } - zoninator.emptyFunc = function() {} + zoninator.emptyFunc = function() { + } zoninator.forceSavePosts = function() { // Grab post list from DOM @@ -462,35 +489,35 @@ var zoninator = {} * @param bool Sort the arrays before comparing? * */ - var compareArrays = function(arr1, arr2, sort) { - if (arr1.length != arr2.length) return false; - - if(sort) { - arr1 = arr1.sort(), - arr2 = arr2.sort(); - } - for (var i = 0; arr2[i]; i++) { - if (arr1[i] !== arr2[i]) { - return false; - } - } - return true; - }; - - $('.zone-toggle-advanced-search').click( function() { - var $this = $( this ), - currentLabel = $( this ).text(), - altLabel = $( this ).data( 'alt-label' ); + var compareArrays = function(arr1, arr2, sort) { + if (arr1.length != arr2.length) return false; + + if (sort) { + arr1 = arr1.sort(), + arr2 = arr2.sort(); + } + for (var i = 0; arr2[i]; i++) { + if (arr1[i] !== arr2[i]) { + return false; + } + } + return true; + }; + + $('.zone-toggle-advanced-search').click(function() { + var $this = $(this), + currentLabel = $(this).text(), + altLabel = $(this).data('alt-label'); $('.zone-advanced-search-filters-wrapper').toggle(); - $this.text( altLabel ).data( 'alt-label', currentLabel ); + $this.text(altLabel).data('alt-label', currentLabel); }); // TODO: fix this function parseIntOrZero(str) { - var parsed = parseInt( str ); - if( isNaN(parsed) || !parsed ) parsed = 0; + var parsed = parseInt(str); + if (isNaN(parsed) || !parsed) parsed = 0; return parsed; } @@ -500,5 +527,8 @@ var zoninator = {} }) })(jQuery, window); -if(typeof(console) === 'undefined') - console = { log: function(){} } +if (typeof(console) === 'undefined') + console = { + log: function() { + } + } diff --git a/zoninator.php b/zoninator.php index f32b2cb..bd85285 100644 --- a/zoninator.php +++ b/zoninator.php @@ -450,7 +450,8 @@ function admin_page_zone_edit( $zone = null ) { zone_admin_search_form(); ?>
    - + +

    From 5594969dd2a201b6a10bd3e0a2a3017ac2e50214 Mon Sep 17 00:00:00 2001 From: And Finally Date: Thu, 8 Dec 2016 17:16:24 +0000 Subject: [PATCH 4/7] [save-button] Some JS code formatting. --- js/zoninator.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/js/zoninator.js b/js/zoninator.js index f79f883..4df1f1b 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -1,6 +1,5 @@ -var zoninator = {} +var zoninator = {}; - ; (function($, window, undefined) { zoninator.init = function() { @@ -398,6 +397,7 @@ var zoninator = {} zoninator.getAjaxNonce = function(action) { return zoninator.getAjaxNonceField(action).val(); } + zoninator.getAjaxNonceField = function(action) { action = action || zoninatorOptions.ajaxNonceAction; return $('#' + action); @@ -523,8 +523,8 @@ var zoninator = {} $(document).ready(function() { zoninator.init(); + }); - }) })(jQuery, window); if (typeof(console) === 'undefined') From cbe3c8d1b4d1a6c1d39e6089ea4231c8b8fa3767 Mon Sep 17 00:00:00 2001 From: And Finally Date: Fri, 9 Dec 2016 10:29:00 +0000 Subject: [PATCH 5/7] [save-button] Disabling #zone-posts-save button and changing text to indicate when reorder_posts action is going on. --- css/zoninator.css | 3 ++- js/zoninator.js | 23 +++++++++++++++-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/css/zoninator.css b/css/zoninator.css index fb54248..ce8c649 100644 --- a/css/zoninator.css +++ b/css/zoninator.css @@ -230,13 +230,14 @@ #zone-posts-save { float: left; + width: 125px; } .zone-posts-save-info { float: left; margin: 0 0 0 10px; padding: 0 10px; - line-height: 30px; + line-height: 28px; color: #666; } diff --git a/js/zoninator.js b/js/zoninator.js index 4df1f1b..621d7bf 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -318,10 +318,11 @@ var zoninator = {}; params = $.extend({}, defaultParams, params); if (action === 'reorder_posts') { - zoninator.$zonePostsSaveInfo - .removeClass('notice-error') - .addClass('notice-info') - .text('Saving...') + zoninator.$zonePostsSave + .prop({ + value: 'Saving...', + disabled: 'disabled' + }); } $.ajax(params); @@ -336,16 +337,22 @@ var zoninator = {}; //console.log('ajaxSuccessCallback', returnData, originalData); if (originalData.action === 'zoninator_reorder_posts') { + zoninator.$zonePostsSave + .prop({ + value: 'Save zone posts', + disabled: false + }); zoninator.$zonePostsSaveInfo .removeClass('notice-error') .addClass('notice-info') .text('Saved at ' + new Date().toLocaleTimeString()); + setTimeout( function() { + zoninator.$zonePostsSaveInfo + .removeClass('notice-error notice-info') + .text(''); + }, 2000); } - setTimeout(function() { - zoninator.$zonePostsSaveInfo.removeClass('notice-info'); - }, 1000); - if (returnData.nonce) zoninator.updateAjaxNonce(returnData.nonce); From 75409fcee6afe19ca2f3479d398da2e4a1f7575a Mon Sep 17 00:00:00 2001 From: And Finally Date: Fri, 9 Dec 2016 10:50:48 +0000 Subject: [PATCH 6/7] [save-button] Added timeout so display of saving action persists slightly longer - was happening too fast. --- js/zoninator.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/js/zoninator.js b/js/zoninator.js index 621d7bf..349554e 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -320,7 +320,7 @@ var zoninator = {}; if (action === 'reorder_posts') { zoninator.$zonePostsSave .prop({ - value: 'Saving...', + value : 'Saving...', disabled: 'disabled' }); } @@ -337,20 +337,22 @@ var zoninator = {}; //console.log('ajaxSuccessCallback', returnData, originalData); if (originalData.action === 'zoninator_reorder_posts') { - zoninator.$zonePostsSave - .prop({ - value: 'Save zone posts', - disabled: false - }); - zoninator.$zonePostsSaveInfo - .removeClass('notice-error') - .addClass('notice-info') - .text('Saved at ' + new Date().toLocaleTimeString()); - setTimeout( function() { + setTimeout(function() { + zoninator.$zonePostsSave + .prop({ + value : 'Save zone posts', + disabled: false + }); zoninator.$zonePostsSaveInfo - .removeClass('notice-error notice-info') - .text(''); - }, 2000); + .removeClass('notice-error') + .addClass('notice-info') + .text('Saved at ' + new Date().toLocaleTimeString()); + setTimeout(function() { + zoninator.$zonePostsSaveInfo + .removeClass('notice-error notice-info') + .text(''); + }, 2000); + }, 250); } if (returnData.nonce) From 015001df999f480b8077d1db27fa2c8559963ebb Mon Sep 17 00:00:00 2001 From: And Finally Date: Fri, 9 Dec 2016 10:52:54 +0000 Subject: [PATCH 7/7] [save-button] Persisting saved timestamp notification. --- js/zoninator.js | 1 - 1 file changed, 1 deletion(-) diff --git a/js/zoninator.js b/js/zoninator.js index 349554e..ba6ce87 100644 --- a/js/zoninator.js +++ b/js/zoninator.js @@ -350,7 +350,6 @@ var zoninator = {}; setTimeout(function() { zoninator.$zonePostsSaveInfo .removeClass('notice-error notice-info') - .text(''); }, 2000); }, 250); }