Angular ui 可排序:无法在嵌套项中正确拖动
Angular ui sortable: can't drag correctly in nested items
您好,我已经在我的项目 surveys module
中实现了嵌套的可排序项目设置。即我可以对单个问题进行排序,我可以创建一个空组,将一个问题放入其中,这样我就可以填满该组,我也可以按层次结构对组进行排序。像这样:
Surveys Module
这是我的代码:
HTML:
<!-- Group type questions: -->
<div class="row connector group-type-question-min-height-compulsory myHandle" ng-if="question.type == allQuestionTypes.group" ui-sortable="sortableOptionsGroup" ng-model="question.questions">
<div class="col-md-6 col-sm-6 question-overview">
<div class="ellipsis">
<i class="fa fa-bars"></i>
<input type="checkbox" ng-value="0" ng-model="question._selected" />
<span ng-attr-title="{{question.name}}" ng-if="question.type == allQuestionTypes.group">
<b>{{question.name}}</b>
</span>
</div>
</div>
<div class="col-md-6 col-sm-6 answer-overview pull-right word-wrap">
<span class="badge">{{showQuestionTypeText(question.type)}}</span>
<button type="button" ng-if="question.type != allQuestionTypes.group" class="button btn btn-success btn-sm" ng-click="$event.stopPropagation(); editSurveyQuestion(question, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<button type="button" ng-if="question.type == allQuestionTypes.group" class="button btn btn-success btn-sm" ng-click="$event.stopPropagation(); openModal(question, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<span class="delete-icon">
<button class="btn btn-sm btn-danger" ng-click="$event.stopPropagation(); removeGroup(question)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
<div class="col-md-12 col-sm-12 question-overview group-type-question-bar" ng-if="question.questions.length == 0">
<div class="ellipsis text-center">
<i class="fa fa-info-circle"></i>
<span>
{{app.translateByLocale('group_questions_drag_info')}}
</span>
</div>
</div>
<div ng-repeat="subQuestion in question.questions" class="group-type-question">
<div class="col-md-5 col-sm-5 question-overview" style="margin-left: 34px">
<div class="ellipsis">
<i class="fa fa-bars myHandle"></i>
<!-- <input type="checkbox" ng-value="0" ng-model="subQuestion._selected" /> -->
<span ng-attr-title="{{subQuestion.text}}">
{{subQuestion.text}}
</span>
</div>
</div>
<div class="col-md-6 col-sm-6 answer-overview pull-right word-wrap">
<span class="badge">{{subQuestion.predefined_mcq_type.title}}</span>
<span class="badge">{{showQuestionTypeText(subQuestion.type)}}</span>
<button type="button" class="button btn btn-success btn-xs" ng-click="$event.stopPropagation(); editSurveyQuestion(subQuestion, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<span class="delete-icon">
<button class="btn btn-xs btn-danger" ng-click="$event.stopPropagation(); removeSurveyGroupQuestion(subQuestion, question.questions)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
</div>
</div>
这些是控制器的相关功能:
JS:
function sortableOptionsGroup(scope) {
let sortableGroup = {
handle: '.myHandle',
receive: function(event, ui) {
sortingReceivedFunction(event, ui, scope);
},
remove: function(event, ui) {
sortingRemovedFunction(event, ui, scope);
},
axis: 'y',
'ui-floating': false,
dropOnEmpty: true,
cursor: 'move',
tolerance: 'pointer',
connectWith: '.connector'
}
return sortableGroup;
}
/**
* invoked when an item is added to the main group
*
* @param {obj} event
* @param {obj} ui
* @param {obj} scope
*
* @returns none
*/
function sortingReceivedFunction(event, ui, scope) {
let obj = ui.item.sortable.model;
let index = ui.item.sortable.index;
let group_type = null;
let invalidIncomingQuestion = false;
//Group Questions Types Maintaining
// when second and more questions are added:
if (ui.item.sortable.droptargetModel.length >= 1) {
_.map(ui.item.sortable.droptargetModel, function(questionObject) {
if (questionObject.type == allQuestionTypes.mcq && ui.item.sortable.model.type == allQuestionTypes.mcq && (questionObject.predefined_mcq_type.key != ui.item.sortable.model.predefined_mcq_type.key)) {
invalidIncomingQuestion = true;
}
});
if (invalidIncomingQuestion) {
showErrorMessage(localeService.translateByLocale("group_question_error4"));
cancelDraging(index, obj, scope, ui);
return;
} else if (ui.item.sortable.droptargetModel.length == maxQuestionLimitInGroup) {
showErrorMessage(localeService.translateByLocale("group_question_error3"));
cancelDraging(index, obj, scope, ui);
} else if (incomingMcqQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else if (incomingCustomQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = false;
}
});
}
}
// when first question is added:
else if (incomingMcqQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else if (incomingCustomQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = false;
}
});
}
}
/**
* invoked when an item is removed from the main group
*
* @param {obj} event
* @param {obj} ui
* @param {obj} scope
*
* @returns none
*/
function sortingRemovedFunction(event, ui, scope) {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = true;
}
});
}
一切正常,但几乎没有问题。
1- 当有两个相邻的组并且我尝试将一个单独的问题拖到上面的组中时,它总是被添加到 lower/second 组中。
如图所示:我在 group 1
中添加了 here is the text for question
但它在 group 2
中添加了。 group 1
的模型在控制台中
Groups after dragging a question in group 1
2- 我无法对组内的问题进行排序。
有人可以帮我解决这个问题吗?我已经很努力了。
我通过在 GitHub 回购中提出问题来寻求支持,所有者建议我的解决方案有点乱。最终我不得不更改代码库中的整个库。这是我用的..
https://github.com/marceljuenemann/angular-drag-and-drop-lists
探索它。希望对你也有帮助。
您好,我已经在我的项目 surveys module
中实现了嵌套的可排序项目设置。即我可以对单个问题进行排序,我可以创建一个空组,将一个问题放入其中,这样我就可以填满该组,我也可以按层次结构对组进行排序。像这样:
Surveys Module
这是我的代码:
HTML:
<!-- Group type questions: -->
<div class="row connector group-type-question-min-height-compulsory myHandle" ng-if="question.type == allQuestionTypes.group" ui-sortable="sortableOptionsGroup" ng-model="question.questions">
<div class="col-md-6 col-sm-6 question-overview">
<div class="ellipsis">
<i class="fa fa-bars"></i>
<input type="checkbox" ng-value="0" ng-model="question._selected" />
<span ng-attr-title="{{question.name}}" ng-if="question.type == allQuestionTypes.group">
<b>{{question.name}}</b>
</span>
</div>
</div>
<div class="col-md-6 col-sm-6 answer-overview pull-right word-wrap">
<span class="badge">{{showQuestionTypeText(question.type)}}</span>
<button type="button" ng-if="question.type != allQuestionTypes.group" class="button btn btn-success btn-sm" ng-click="$event.stopPropagation(); editSurveyQuestion(question, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<button type="button" ng-if="question.type == allQuestionTypes.group" class="button btn btn-success btn-sm" ng-click="$event.stopPropagation(); openModal(question, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<span class="delete-icon">
<button class="btn btn-sm btn-danger" ng-click="$event.stopPropagation(); removeGroup(question)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
<div class="col-md-12 col-sm-12 question-overview group-type-question-bar" ng-if="question.questions.length == 0">
<div class="ellipsis text-center">
<i class="fa fa-info-circle"></i>
<span>
{{app.translateByLocale('group_questions_drag_info')}}
</span>
</div>
</div>
<div ng-repeat="subQuestion in question.questions" class="group-type-question">
<div class="col-md-5 col-sm-5 question-overview" style="margin-left: 34px">
<div class="ellipsis">
<i class="fa fa-bars myHandle"></i>
<!-- <input type="checkbox" ng-value="0" ng-model="subQuestion._selected" /> -->
<span ng-attr-title="{{subQuestion.text}}">
{{subQuestion.text}}
</span>
</div>
</div>
<div class="col-md-6 col-sm-6 answer-overview pull-right word-wrap">
<span class="badge">{{subQuestion.predefined_mcq_type.title}}</span>
<span class="badge">{{showQuestionTypeText(subQuestion.type)}}</span>
<button type="button" class="button btn btn-success btn-xs" ng-click="$event.stopPropagation(); editSurveyQuestion(subQuestion, $index)">
{{app.translateByLocale('label_edit')}}
</button>
<span class="delete-icon">
<button class="btn btn-xs btn-danger" ng-click="$event.stopPropagation(); removeSurveyGroupQuestion(subQuestion, question.questions)">
<i class="fa fa-trash"></i>
</button>
</span>
</div>
</div>
</div>
这些是控制器的相关功能:
JS:
function sortableOptionsGroup(scope) {
let sortableGroup = {
handle: '.myHandle',
receive: function(event, ui) {
sortingReceivedFunction(event, ui, scope);
},
remove: function(event, ui) {
sortingRemovedFunction(event, ui, scope);
},
axis: 'y',
'ui-floating': false,
dropOnEmpty: true,
cursor: 'move',
tolerance: 'pointer',
connectWith: '.connector'
}
return sortableGroup;
}
/**
* invoked when an item is added to the main group
*
* @param {obj} event
* @param {obj} ui
* @param {obj} scope
*
* @returns none
*/
function sortingReceivedFunction(event, ui, scope) {
let obj = ui.item.sortable.model;
let index = ui.item.sortable.index;
let group_type = null;
let invalidIncomingQuestion = false;
//Group Questions Types Maintaining
// when second and more questions are added:
if (ui.item.sortable.droptargetModel.length >= 1) {
_.map(ui.item.sortable.droptargetModel, function(questionObject) {
if (questionObject.type == allQuestionTypes.mcq && ui.item.sortable.model.type == allQuestionTypes.mcq && (questionObject.predefined_mcq_type.key != ui.item.sortable.model.predefined_mcq_type.key)) {
invalidIncomingQuestion = true;
}
});
if (invalidIncomingQuestion) {
showErrorMessage(localeService.translateByLocale("group_question_error4"));
cancelDraging(index, obj, scope, ui);
return;
} else if (ui.item.sortable.droptargetModel.length == maxQuestionLimitInGroup) {
showErrorMessage(localeService.translateByLocale("group_question_error3"));
cancelDraging(index, obj, scope, ui);
} else if (incomingMcqQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else if (incomingCustomQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = false;
}
});
}
}
// when first question is added:
else if (incomingMcqQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else if (incomingCustomQuestionValidation(ui.item.sortable.model)) {
cancelDraging(index, obj, scope, ui);
} else {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = false;
}
});
}
}
/**
* invoked when an item is removed from the main group
*
* @param {obj} event
* @param {obj} ui
* @param {obj} scope
*
* @returns none
*/
function sortingRemovedFunction(event, ui, scope) {
let groupQuestionId = ui.item.sortable.model.id;
scope.questions.data.forEach(function(item, i, val) {
if (scope.questions.data[i].id == groupQuestionId) {
scope.questions.data[i].isSelected = true;
}
});
}
一切正常,但几乎没有问题。
1- 当有两个相邻的组并且我尝试将一个单独的问题拖到上面的组中时,它总是被添加到 lower/second 组中。
如图所示:我在 group 1
中添加了 here is the text for question
但它在 group 2
中添加了。 group 1
的模型在控制台中
Groups after dragging a question in group 1
2- 我无法对组内的问题进行排序。
有人可以帮我解决这个问题吗?我已经很努力了。
我通过在 GitHub 回购中提出问题来寻求支持,所有者建议我的解决方案有点乱。最终我不得不更改代码库中的整个库。这是我用的.. https://github.com/marceljuenemann/angular-drag-and-drop-lists
探索它。希望对你也有帮助。