-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Short description of the enhancement
There is a UX problem that has been bothering me at ProcessWire for years. In the editing process of pages, especially those which, for example, become very long due to a repeater, the workflow of saving is very cumbersome.
You edit the content and have to scroll up or down each time to save it. In addition, after each saving, the scroll position is at the top again.
I changed this behavior in a proof of concept. In ProcessPageEdit I clone the current buttons and fade them in as floating buttons on the left side when the original buttons are no longer visible. This saves the user a lot of time.
In addition, I use a cookie to save the current scroll position of the page, which is restored after saving the page. When you leave the site, this cookie is removed.
This behavior makes the editing of pages from my experience and feedback from my customers much more effective. This allows users to change content faster, save and view their changes.
Here is a screencast:
What do you think of this modification?
Here is the changed code, which of course can be improved significantly. But for a test hack, it works well for me.
Javascript extension
/**
* ------------------------------------------------------------------------
* + Clone save and draft buttons for better UX
* + Save scroll position
* ------------------------------------------------------------------------
*/
$(function(){
// ------------------------------------------------------------------------
// Only on page edit
// ------------------------------------------------------------------------
if($("body[class*='ProcessPageEdit']").length > 0) {
// ------------------------------------------------------------------------
// Check if draft buttons present
// ------------------------------------------------------------------------
if(($("button#submit_save") && $("button#submit_save_draft")) || ($("button#Inputfield_submit_publish") && $("button#submit_save_draft"))) {
// ------------------------------------------------------------------------
// Create clone holder
// ------------------------------------------------------------------------
var cloned = false,
topThreshold = 100,
bottomThreshold = 1500;
$cloneHolder = $('<div id="submit_float"></div>');
$cloneHolder.appendTo('form#ProcessPageEdit');
// ------------------------------------------------------------------------
// On scroll events
// ------------------------------------------------------------------------
$(document).on('scroll', function(){
// ------------------------------------------------------------------------
// If not cloned, create clones
// ------------------------------------------------------------------------
if($(document).scrollTop() > topThreshold && !cloned) {
$cloneSave = $("button#submit_save").eq(0).clone(true);
$cloneDraft = $("button#submit_save_draft").eq(0).clone(true);
$clonePublish = $("button#Inputfield_submit_publish").eq(0).clone(true);
$clonePreview = $("a#_ProcessPageEditView").eq(0).clone(true);
cloned = true;
$clonePreview.addClass('ui-button ui-widget ui-corner-all pw-head-button ui-state-default preview_float');
$cloneSave.attr('id', 'submit_save_float').removeClass('pw-button-dropdown-main');
$cloneDraft.attr('id', 'submit_draft_float');
$clonePublish.attr('id', 'submit_publish_float').removeClass('pw-button-dropdown-main');
$clonePreview.appendTo('div#submit_float');
$cloneDraft.appendTo('div#submit_float');
$cloneSave.appendTo('div#submit_float');
$clonePublish.appendTo('div#submit_float');
$cloneDraft.bind('click', function(){
$(this).addClass('loader').children().find('i').addClass('fa-spin');
});
$cloneSave.bind('click', function(){
$(this).addClass('loader').children().find('i').addClass('fa-spin');
});
$clonePublish.bind('click', function(){
$(this).addClass('loader').children().find('i').addClass('fa-spin');
});
}
// ------------------------------------------------------------------------
// Show clones on scroll
// ------------------------------------------------------------------------
if($(document).scrollTop() > topThreshold && !$cloneHolder.hasClass('showit') && $(document).scrollTop() < ($('html').prop('scrollHeight') - bottomThreshold)) {
$cloneHolder.addClass('showit');
// ------------------------------------------------------------------------
// Hide clones on top and bittom
// -------------------------------------------------------------------------
} else if($(document).scrollTop() > ($('html').prop('scrollHeight') - bottomThreshold) && $cloneHolder.hasClass('showit') || $(document).scrollTop() < topThreshold && $cloneHolder.hasClass('showit')) {
$cloneHolder.removeClass('showit');
}
});
}
// ------------------------------------------------------------------------
// Get page edit id on process-page-edit
// ------------------------------------------------------------------------
var pageEditID = $("body").attr("class").match(/ProcessPageEdit-id-[\w-]*\b/),
pageEditID = pageEditID[0];
// ------------------------------------------------------------------------
// Check if position is present on page load
// ------------------------------------------------------------------------
if($.cookie("process-edit-scroll-position")) {
var scrollData = $.cookie("process-edit-scroll-position");
// ------------------------------------------------------------------------
// If same page stored, scroll to position
// ------------------------------------------------------------------------
if(scrollData["id"] == pageEditID) {
$(document).scrollTop(scrollData["position"]);
// ------------------------------------------------------------------------
// Else delete cookie
// ------------------------------------------------------------------------
} else {
$.cookie("process-edit-scroll-position", null);
}
}
// ------------------------------------------------------------------------
// Bind scroll event and save current scroll position after scroll
// event ended
// ------------------------------------------------------------------------
$(window).scroll(function() {
clearTimeout($.data(this, 'scrollTimer'));
$.data(this, 'scrollTimer', setTimeout(function() {
$.cookie("process-edit-scroll-position", {"id": pageEditID, "position": $(document).scrollTop()}, {expires: 21600});
}, 250));
});
// ------------------------------------------------------------------------
// No page edit, delete cookie
// ------------------------------------------------------------------------
} else {
$.cookie("process-edit-scroll-position", null);
}
});
CSS (as LESS) extension
// ------------------------------------------------------------------------
// Backend floating save buttons
// ------------------------------------------------------------------------
div#submit_float {
position: fixed;
z-index: 100;
left: 30px;
bottom: 30px;
opacity: 0;
transition: opacity .3s ease;
&.showit {
opacity: 1;
}
button,
a {
float: none;
display: block;
border-radius: 50%;
width: 85px;
height: 85px;
font-size: .75rem !important;
padding: .1rem !important;
box-shadow: 0 0 20px rgba(0,0,0,.3) !important;
&.preview_float {
padding-top: 22px !important;
background: #6d6d6d !important;
border-color: #6d6d6d !important;
&:hover {
background: #828282 !important;
border-color: #828282 !important;
}
&:before {
display: block;
font-size: 1.6rem!important;
margin-bottom: .2rem;
font: normal normal normal 14px/1 FontAwesome;
content: "\f06e";
}
}
span#_ProcessPageEditViewDropdownToggle {
display: none;
}
span.ui-button-text {
padding: 0 !important;
i {
display: block;
font-size: 1.6rem !important;
margin-bottom: .2rem;
}
}
&.loader {
span.ui-button-text {
i:before {
content: "\f110";
}
}
}
&#submit_draft_float,
&.preview_float {
margin-bottom: .5rem;
}
}
}