forked from friendica/friendica
Scripts and styling for sortable lists
This commit is contained in:
parent
60d94ed981
commit
8dda4a97bb
1 changed files with 221 additions and 2 deletions
|
|
@ -5,7 +5,7 @@
|
|||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*}}
|
||||
|
||||
|
||||
<script type="text/javascript" src="view/asset/es-jquery-sortable/source/js/jquery-sortable.js"></script>
|
||||
<script>
|
||||
var ispublic = "{{$ispublic nofilter}}";
|
||||
|
||||
|
|
@ -31,8 +31,227 @@
|
|||
$('.settings-content-block').hide();
|
||||
$(this).next('.settings-content-block').toggle();
|
||||
});
|
||||
|
||||
$( function() {
|
||||
var $container; // or onDrop loses reference
|
||||
$(".sortable").sortable({
|
||||
connectWith : ".sortable",
|
||||
containerSelector: "div",
|
||||
containerPath : ".sortable > .field",
|
||||
itemSelector : ".field",
|
||||
placeholder : '<div class="placeholder"></div>',
|
||||
nested: false,
|
||||
onDragStart: function ($item, container, _super, event) {
|
||||
$item.css({
|
||||
height: $item.outerHeight(),
|
||||
width: $item.outerWidth()
|
||||
});
|
||||
$item.addClass(container.group.options.draggedClass);
|
||||
$("body").addClass(container.group.options.bodyClass);
|
||||
$container = container;
|
||||
},
|
||||
onDrop : function($item, container, _super, event){
|
||||
if(!container){ container = $container;};
|
||||
$item.removeClass(container.group.options.draggedClass).removeAttr("style");
|
||||
$("body").removeClass(container.group.options.bodyClass);
|
||||
console.log(container);
|
||||
},
|
||||
afterMove : function($placeholder, container, $closestItemOrContainer){
|
||||
// need a delay so drag-n-drop is done before we re-index
|
||||
setTimeout(function(){
|
||||
if ($(".network").length > 0){
|
||||
indexList('#feature_widgetorder','.network','.field');
|
||||
}
|
||||
if ($(".timelines-widget").length > 0){
|
||||
indexList('#widget_timelineorder','.timelines-widget','.field');
|
||||
}
|
||||
if ($(".timelines-menu").length > 0){
|
||||
indexList('#menu_timelineorder','.timelines-menu','.field');
|
||||
}
|
||||
},1000);
|
||||
}
|
||||
});
|
||||
});
|
||||
// make widget indexing generic
|
||||
function indexList(input,widgets,children){
|
||||
var items = $(widgets).children(children);
|
||||
var order = [];
|
||||
for(let i=0; i < items.length; i++){
|
||||
$(items[i]).attr('data-order',i);
|
||||
$(items[i]).attr('tabindex',0);
|
||||
order.push(items[i].id.replace('div_id_feature_','').replace('div_id_enable[','').replace('div_id_bookmark[','').replace(']',''));
|
||||
}
|
||||
$(input).val(JSON.stringify(order));
|
||||
}
|
||||
// initial order index
|
||||
indexList('#feature_widgetorder','.network','.field');
|
||||
indexList('#widget_timelineorder','.timelines-widget','.field');
|
||||
indexList('#menu_timelineorder','.timelines-menu','.field');
|
||||
// accessible sorting with keyboard gives feedback to screenreaders
|
||||
$('.network .field, .timelines-widget .field, .timelines-menu .field').bind('keydown', function(event){
|
||||
let total = $('.network .field').length;
|
||||
console.log('total = '+total);
|
||||
// get the currently selected item index
|
||||
let index = parseInt($(this).attr('data-order'));
|
||||
let before = parseInt(index-1);
|
||||
let after = parseInt(index+1);
|
||||
if(event.which == 38){ // up arrow
|
||||
console.log('up arrow');
|
||||
if (index != 0){
|
||||
console.log('insert before '+before);
|
||||
$(this).attr('title','Moved up one space, position '+index+' in list');
|
||||
$(this).insertBefore( $('[data-order="'+before+'"]') );
|
||||
setTimeout(function(that){
|
||||
if ($(".network").length > 0){
|
||||
indexList('#feature_widgetorder','.network','.field');
|
||||
}
|
||||
if ($(".timelines-widget").length > 0){
|
||||
indexList('#widget_timelineorder','.timelines-widget','.field');
|
||||
}
|
||||
if ($(".timelines-menu").length > 0){
|
||||
indexList('#menu_timelineorder','.timelines-menu','.field');
|
||||
}
|
||||
$(that).attr('title','');
|
||||
},1000, $(this));
|
||||
}
|
||||
$(this).focus();
|
||||
}
|
||||
if (event.which == 40){ //down arrow
|
||||
console.log('down arrow');
|
||||
if (index != (total-1)){
|
||||
console.log('insert after'+after);
|
||||
$(this).attr('title','Moved down one space, position '+parseInt(after+1)+' in list');
|
||||
$(this).insertAfter( $('[data-order="'+after+'"]') );
|
||||
setTimeout(function(that){
|
||||
if ($(".network").length > 0){
|
||||
indexList('#feature_widgetorder','.network','.field');
|
||||
}
|
||||
if ($(".timelines-widget").length > 0){
|
||||
indexList('#widget_timelineorder','.timelines-widget','.field');
|
||||
}
|
||||
if ($(".timelines-menu").length > 0){
|
||||
indexList('#menu_timelineorder','.timelines-menu','.field');
|
||||
}
|
||||
$(that).attr('title','');
|
||||
},1000, $(this));
|
||||
}
|
||||
$(this).focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* styling for sortable lists */
|
||||
.placeholder {
|
||||
height: 60px;
|
||||
width: 100%;
|
||||
background-color: rgba(255,255,255,.3);
|
||||
border: 1px dashed black;
|
||||
list-style: none;
|
||||
}
|
||||
.sortable .field {
|
||||
position: relative;
|
||||
border: 1px solid #eee;
|
||||
padding: 10px 30px 10px 30px;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.sortable .field:first-of-type {
|
||||
border-top-left-radius: 8px;
|
||||
border-top-right-radius: 8px;
|
||||
}
|
||||
.sortable .field:last-of-type {
|
||||
border-bottom-left-radius: 8px;
|
||||
border-bottom-right-radius: 8px;
|
||||
}
|
||||
.sortable .field::after {
|
||||
content: '\2B0D'; /* unicode double-arrow */
|
||||
position: absolute;
|
||||
font-size: 18px;
|
||||
right: 15px;
|
||||
top: 40%;
|
||||
opacity: .2;
|
||||
}
|
||||
.sortable .field:hover::after,
|
||||
.sortable .field:focus::after,
|
||||
.sortable .field:active::after,
|
||||
.sortable .field:focus-within::after {
|
||||
opacity: 1;
|
||||
}
|
||||
.dragged {
|
||||
position: absolute !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/*
|
||||
* Content-Type:text/javascript
|
||||
*
|
||||
* A bridge between iPad and iPhone touch events and jquery draggable,
|
||||
* sortable etc. mouse interactions.
|
||||
* @author Oleg Slobodskoi
|
||||
*
|
||||
* modified by John Hardy to use with any touch device
|
||||
* fixed breakage caused by jquery.ui so that mouseHandled internal flag is reset
|
||||
* before each touchStart event
|
||||
*
|
||||
*/
|
||||
(function( $ ) {
|
||||
|
||||
$.support.touch = typeof Touch === 'object';
|
||||
|
||||
if (!$.support.touch) {
|
||||
return;
|
||||
}
|
||||
|
||||
var proto = $.ui.mouse.prototype,
|
||||
_mouseInit = proto._mouseInit;
|
||||
|
||||
$.extend( proto, {
|
||||
_mouseInit: function() {
|
||||
this.element
|
||||
.bind( "touchstart." + this.widgetName, $.proxy( this, "_touchStart" ) );
|
||||
_mouseInit.apply( this, arguments );
|
||||
},
|
||||
|
||||
_touchStart: function( event ) {
|
||||
if ( event.originalEvent.targetTouches.length != 1 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.element
|
||||
.bind( "touchmove." + this.widgetName, $.proxy( this, "_touchMove" ) )
|
||||
.bind( "touchend." + this.widgetName, $.proxy( this, "_touchEnd" ) );
|
||||
|
||||
this._modifyEvent( event );
|
||||
|
||||
$( document ).trigger($.Event("mouseup")); //reset mouseHandled flag in ui.mouse
|
||||
this._mouseDown( event );
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
_touchMove: function( event ) {
|
||||
this._modifyEvent( event );
|
||||
this._mouseMove( event );
|
||||
},
|
||||
|
||||
_touchEnd: function( event ) {
|
||||
this.element
|
||||
.unbind( "touchmove." + this.widgetName )
|
||||
.unbind( "touchend." + this.widgetName );
|
||||
this._mouseUp( event );
|
||||
},
|
||||
|
||||
_modifyEvent: function( event ) {
|
||||
event.which = 1;
|
||||
var target = event.originalEvent.targetTouches[0];
|
||||
event.pageX = target.clientX;
|
||||
event.pageY = target.clientY;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue