Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/3217 abandon sortablejs #3227

Merged
merged 22 commits into from
Aug 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9b6ee5c
https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 24, 2021
0576e2a
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 24, 2021
9fd1b65
Merge branch 'master' into feature/3217-abandon-sortablejs
dmitry-kurmanov Aug 24, 2021
737fd63
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 25, 2021
a05b29e
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 25, 2021
721501e
Merge branch 'master' into feature/3217-abandon-sortablejs
dmitry-kurmanov Aug 25, 2021
de65d3c
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 25, 2021
331715d
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 25, 2021
32f01ab
Merge branch 'master' into feature/3217-abandon-sortablejs
dmitry-kurmanov Aug 26, 2021
ae944ce
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
cd016ec
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
273da8a
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
b8b5b20
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
fc070e6
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
ea0a7ef
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 26, 2021
8ff1fbd
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 27, 2021
6e4ba37
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 27, 2021
d4fde78
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 29, 2021
a507f06
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 29, 2021
ea991e8
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 30, 2021
a916b0a
Merge branch 'master' into feature/3217-abandon-sortablejs
dmitry-kurmanov Aug 30, 2021
7a32d65
work for the https://github.com/surveyjs/survey-library/issues/3217
dmitry-kurmanov Aug 30, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 16 additions & 11 deletions src/dragdrop/choices.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,22 @@
import { ItemValue } from "survey-core";
import { ItemValue } from "../itemvalue";
import { QuestionSelectBase } from "../question_baseselect";
import { DragDropCore } from "./core";

export class DragDropChoices extends DragDropCore {
export class DragDropChoices extends DragDropCore<QuestionSelectBase> {
protected get draggedElementType(): string {
return "item-value";
}

protected getShortcutText(draggedElement: any) {
protected getShortcutText(draggedElement: ItemValue): string {
return draggedElement.text;
}

protected getDropTargetByDataAttributeValue(dataAttributeValue: string) {
protected findDropTargetNodeByDragOverNode(dragOverNode:HTMLElement):HTMLElement {
const result: HTMLElement = dragOverNode.closest(this.dropTargetDataAttributeName);
return result;
}

protected getDropTargetByDataAttributeValue(dataAttributeValue: string): ItemValue {
let dragOverChoice;

dragOverChoice = this.parentElement.choices.filter(
Expand All @@ -20,14 +26,13 @@ export class DragDropChoices extends DragDropCore {
return dragOverChoice;
}

protected isDropTargetValid(dropTarget: any) {
protected isDropTargetValid(dropTarget: ItemValue):boolean {
const choices = this.parentElement.choices;

if (this.dropTarget === this.draggedElement) return false;

// shouldn't allow to drop on "adorners" (selectall, none, other)
if (choices.indexOf(dropTarget) === -1) {
this.banDropHere();
return false;
}
if (choices.indexOf(dropTarget) === -1) return false;

return true;
}
Expand All @@ -40,7 +45,7 @@ export class DragDropChoices extends DragDropCore {
);
}

protected doDrop = () => {
protected doDrop():any {
const isTop = !this.isBottom;
const choices = this.parentElement.choices;
const oldIndex = choices.indexOf(this.draggedElement);
Expand All @@ -56,5 +61,5 @@ export class DragDropChoices extends DragDropCore {
choices.splice(newIndex, 0, this.draggedElement);

return this.parentElement;
};
}
}
73 changes: 42 additions & 31 deletions src/dragdrop/core.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
import { DragDropInfo } from "src/panel";
import { SurveyModel } from "../survey";
import { Base, EventBase } from "../base";
import { ISurvey } from "../base-interfaces";
import { property } from "../jsonobject";

export abstract class DragDropCore extends Base {
@property({ defaultValue: null, onSet: (val, target: DragDropCore) => {
target.ghostPositionChanged();
} }) isBottom: boolean; //TODO rename isBottom to isShowGhostAtBottomOfDropTarget
export abstract class DragDropCore<T> extends Base {
@property({
defaultValue: null,
onSet: (val, target: DragDropCore<T>) => {
target.ghostPositionChanged();
},
})
isBottom: boolean; //TODO rename isBottom to isShowGhostAtBottomOfDropTarget
public onGhostPositionChanged: EventBase<Base> = new EventBase<Base>();
protected ghostPositionChanged() {
protected ghostPositionChanged(): void {
this.onGhostPositionChanged.fire({}, {});
}

public onBeforeDrop: EventBase<DragDropCore> = new EventBase();
public onAfterDrop: EventBase<DragDropCore> = new EventBase();
public onBeforeDrop: EventBase<DragDropCore<T>> = new EventBase();
public onAfterDrop: EventBase<DragDropCore<T>> = new EventBase();

protected draggedElement: any = null;
protected abstract get draggedElementType(): string;
protected parentElement: any;
protected dropTarget: any = null;
protected get dropTargetDataAttributeName() {
protected parentElement: T;
public dropTarget: any = null;
protected get dropTargetDataAttributeName(): string {
return `[data-sv-drop-target-${this.draggedElementType}]`;
}
protected get survey() {
protected get survey(): SurveyModel {
return this.surveyValue || this.creator.survey;
}

Expand All @@ -39,7 +43,7 @@ export abstract class DragDropCore extends Base {
event: PointerEvent,
draggedElement: any,
parentElement?: any
) {
): void {
this.draggedElement = draggedElement;
this.parentElement = parentElement;

Expand Down Expand Up @@ -77,17 +81,19 @@ export abstract class DragDropCore extends Base {

const isDropTargetValid = this.isDropTargetValid(this.dropTarget, isBottom);

if (this.dropTarget === this.draggedElement || !isDropTargetValid) {
this.doDragOver(dropTargetNode);

if (!isDropTargetValid) {
this.banDropHere();
return;
}

this.allowDropHere = true;
if (this.isDropTargetDoesntChanged(isBottom)) return;

this.isBottom = null; //TODO need for property change trigger with guarantee but it would be better not to watch on isBottom property but reate some event like onValidTargetDragOver
this.isBottom = null; //TODO need for property change trigger with guarantee but it would be better not to watch on isBottom property but have some event like onValidTargetDragOver
this.isBottom = isBottom;
this.doDragOver();
this.afterDragOver(dropTargetNode);
this.prevDropTarget = this.dropTarget;
};

Expand All @@ -101,13 +107,13 @@ export abstract class DragDropCore extends Base {
this.clear();
};

protected isDropTargetDoesntChanged(newIsBottom: boolean) {
protected isDropTargetDoesntChanged(newIsBottom: boolean): boolean {
return (
this.dropTarget === this.prevDropTarget && newIsBottom === this.isBottom
);
}

protected doStartDrag() {}
protected doStartDrag(): void {}
protected abstract getShortcutText(draggedElement: any): string;

private createDraggedElementShortcut(text: string) {
Expand All @@ -118,9 +124,10 @@ export abstract class DragDropCore extends Base {
return draggedElementShortcut;
}

protected doDragOver(): void {}
protected doDragOver(dropTargetNode?: HTMLElement): void {}
protected afterDragOver(dropTargetNode?: HTMLElement): void {}

public getGhostPosition(item: any) {
public getGhostPosition(item: any): string {
if (this.dropTarget !== item) return null;
if (this.isBottom) return "bottom";
return "top";
Expand Down Expand Up @@ -226,15 +233,15 @@ export abstract class DragDropCore extends Base {
this.scrollIntervalId = requestAnimationFrame(repeat);
}

protected banDropHere = () => {
protected banDropHere = (): void => {
this.doBanDropHere();
this.allowDropHere = false;
this.dropTarget = null;
this.draggedElementShortcut.style.cursor = "not-allowed";
this.isBottom = null;
};

protected doBanDropHere = () => {};
protected doBanDropHere = (): void => {};

private getDataAttributeValueByNode(node: HTMLElement) {
let datasetName = "svDropTarget";
Expand All @@ -248,7 +255,7 @@ export abstract class DragDropCore extends Base {
protected getDropTargetByNode(
dropTargetNode: HTMLElement,
event: PointerEvent
) {
): any {
let dataAttributeValue = this.getDataAttributeValueByNode(dropTargetNode);

return this.getDropTargetByDataAttributeValue(
Expand All @@ -264,12 +271,12 @@ export abstract class DragDropCore extends Base {

//TODO adandone unrequired params (survey-elements)
protected abstract getDropTargetByDataAttributeValue(
dataAttributeValue: any,
dataAttributeValue: string,
dropTargetNode?: HTMLElement,
event?: PointerEvent
): any;

protected calculateMiddleOfHTMLElement(HTMLElement: HTMLElement) {
protected calculateMiddleOfHTMLElement(HTMLElement: HTMLElement): number {
const rect = HTMLElement.getBoundingClientRect();
return rect.y + rect.height / 2;
}
Expand All @@ -287,17 +294,21 @@ export abstract class DragDropCore extends Base {
clientY: number
): HTMLElement {
this.draggedElementShortcut.hidden = true;
let dragOverNode = document.elementFromPoint(clientX, clientY);
let dragOverNode = <HTMLElement>document.elementFromPoint(clientX, clientY);
this.draggedElementShortcut.hidden = false;

if (!dragOverNode) return null;

return (
dragOverNode.querySelector(this.dropTargetDataAttributeName) ||
dragOverNode.closest(this.dropTargetDataAttributeName)
);
return this.findDropTargetNodeByDragOverNode(dragOverNode);
}

protected findDropTargetNodeByDragOverNode(dragOverNode:HTMLElement):HTMLElement {
const result: HTMLElement =
dragOverNode.querySelector(this.dropTargetDataAttributeName) ||
dragOverNode.closest(this.dropTargetDataAttributeName);

return result;
}
protected abstract doDrop(): any;

private clear = () => {
Expand All @@ -320,5 +331,5 @@ export abstract class DragDropCore extends Base {
this.scrollIntervalId = null;
};

protected doClear() {}
protected doClear(): void {}
}
23 changes: 12 additions & 11 deletions src/dragdrop/matrix-rows.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { ISurvey, QuestionMatrixDropdownRenderedRow } from "survey-core";
import { QuestionMatrixModel, MatrixRowModel } from "../question_matrix";
import { MatrixDropdownRowModelBase, QuestionMatrixDropdownRenderedRow } from "../question_matrixdropdownbase";
import { QuestionMatrixDynamicModel } from "../question_matrixdynamic";
import { DragDropCore } from "./core";
export class DragDropMatrixRows extends DragDropCore {
export class DragDropMatrixRows extends DragDropCore<QuestionMatrixDynamicModel> {
protected get draggedElementType(): string {
return "matrix-row";
}

protected ghostPositionChanged() {
protected ghostPositionChanged(): void {
this.parentElement.renderedTable.rows.forEach(
(renderedRow: QuestionMatrixDropdownRenderedRow) => {
renderedRow.ghostPosition = this.getGhostPosition(
Expand All @@ -17,8 +17,8 @@ export class DragDropMatrixRows extends DragDropCore {
super.ghostPositionChanged();
}

protected getShortcutText(draggedElement: any) {
const matrix = <QuestionMatrixModel>this.parentElement;
protected getShortcutText(draggedElement: any): string {
const matrix = this.parentElement;
const index = matrix.visibleRows.indexOf(draggedElement) + 1;
return (
draggedElement.cells[1].questionValue.value ||
Expand All @@ -29,8 +29,8 @@ export class DragDropMatrixRows extends DragDropCore {

protected getDropTargetByDataAttributeValue(
dataAttributeValue: any
): MatrixRowModel {
const matrix = <QuestionMatrixModel>this.parentElement;
): MatrixDropdownRowModelBase {
const matrix = this.parentElement;
let dropTargetRow;

dropTargetRow = matrix.visibleRows.filter(
Expand All @@ -40,7 +40,8 @@ export class DragDropMatrixRows extends DragDropCore {
return dropTargetRow;
}

protected isDropTargetValid(dropTarget: any) {
protected isDropTargetValid(dropTarget: any): boolean {
if (this.dropTarget === this.draggedElement) return false;
const rows = this.parentElement.visibleRows;
return rows.indexOf(dropTarget) !== -1;
}
Expand All @@ -52,8 +53,8 @@ export class DragDropMatrixRows extends DragDropCore {
);
}

protected doDrop = () => {
const matrix = <QuestionMatrixModel>this.parentElement;
protected doDrop = (): QuestionMatrixDynamicModel => {
const matrix = this.parentElement;
const fromIndex = matrix.visibleRows.indexOf(this.draggedElement);
const toIndex = matrix.visibleRows.indexOf(this.dropTarget);
matrix.moveRowByIndex(fromIndex, toIndex);
Expand Down
44 changes: 44 additions & 0 deletions src/dragdrop/ranking-choices.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { ItemValue } from "../itemvalue";
import { DragDropChoices } from "./choices";
export class DragDropRankingChoices extends DragDropChoices {
protected getShortcutText(draggedElement: ItemValue): string {
const index = this.parentElement.ran;
return draggedElement.text;
}

protected getDropTargetByDataAttributeValue(
dataAttributeValue: string
): ItemValue {
return this.parentElement.rankingChoices[dataAttributeValue];
}

protected isDropTargetValid(dropTarget: ItemValue): boolean {
const choices = this.parentElement.visibleChoices;

// shouldn't allow to drop on "adorners" (selectall, none, other)
if (choices.indexOf(dropTarget) === -1) return false;

return true;
}

protected afterDragOver(): void {
const choices = this.parentElement.choices;
const dropTargetIndex = choices.indexOf(this.dropTarget);
const draggedElementIndex = choices.indexOf(this.draggedElement);

choices.splice(draggedElementIndex, 1);
choices.splice(dropTargetIndex, 0, this.draggedElement);
this.parentElement.setValue();
}

protected ghostPositionChanged(): void {
this.parentElement.currentDragTarget = this.draggedElement;
super.ghostPositionChanged();
}

protected doDrop = (): any => {
super.doDrop();
this.parentElement.setValue();
return this.parentElement;
};
}
7 changes: 4 additions & 3 deletions src/dragdrop/survey-elements.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { JsonObject, Serializer } from "../jsonobject";
import { PageModel } from "../page";
import { DragDropCore } from "./core";

export class DragDropSurveyElements extends DragDropCore {
export class DragDropSurveyElements extends DragDropCore<any> {
public static newGhostPage: PageModel = null;
public static restrictDragQuestionBetweenPages: boolean = false;
public static edgeHeight: number = 30;
Expand Down Expand Up @@ -78,7 +78,7 @@ export class DragDropSurveyElements extends DragDropCore {
}

// drop to page
let page = this.survey.getPageByName(dataAttributeValue);
let page:any = this.survey.getPageByName(dataAttributeValue);
if (page) {
if (
// TODO we can't drop on not empty page directly for now
Expand Down Expand Up @@ -129,6 +129,7 @@ export class DragDropSurveyElements extends DragDropCore {

protected isDropTargetValid(dropTarget: any, isBottom: boolean) {
if (!dropTarget) return false;
if (this.dropTarget === this.draggedElement) return false;

if (
DragDropSurveyElements.restrictDragQuestionBetweenPages &&
Expand Down Expand Up @@ -187,7 +188,7 @@ export class DragDropSurveyElements extends DragDropCore {
return Math.abs(clientY - middle) >= DragDropSurveyElements.edgeHeight;
}

protected doDragOver() {
protected afterDragOver() {
this.prevIsEdge = this.isEdge;
this.insertGhostElementIntoSurvey();
}
Expand Down
Loading