Skip to content
This repository was archived by the owner on Sep 8, 2020. It is now read-only.
This repository was archived by the owner on Sep 8, 2020. It is now read-only.

Problem with nested items being sorted #551

@ZtheLeader

Description

@ZtheLeader

Hi I've implemented nested sortable items setup in surveys module in my project. i.e. I can sort Individual questions AND I can create an empty group, drop a single question into it and like this I fill up the group and I can sort the groups in hierarchy as well. Like this:

screen shot 2018-06-07 at 4 09 37 pm

Here's my code:

<!-- 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>

Related Functions from Controller:

 * Defines the options for Group type questions to be used in both Survey creation and Edit
 * @param {object} scope 
 */
    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;
            }
        });
    }

Things are working pretty fine but there are few problems.

1- When there are two adjacent groups and I try to drag an individual question into upper group, it always gets added into the lower/second group.

See in the image: I added here is the text for question in group 1 but it added in group 2. Model of group 1 is in console
screen shot 2018-06-07 at 4 23 56 pm

2- I can't sort the questions into a group.

Can someone help me here on it. I've been trying quite hard on it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions