Таблица HTML - Javascript для выбора и отмены выбора элементов (ячеек) - PullRequest
0 голосов
/ 13 ноября 2018

Я создал эту таблицу HTML + JavaScript для целей планирования. Это позволяет мне выбрать несколько ячеек в таблице и вывести их в файл JSON с несколькими дополнительными функциями.

В настоящий момент, когда я пытаюсь выбрать несколько ячеек, он правильно создает «виртуальный» прямоугольник и выделяет все необходимые ячейки.

Я хочу то же самое для отмены выбора, но по какой-то причине я не вижу, в чем проблема.

У кого-нибудь есть идеи?

Вот фрагмент кода.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>

    var app = angular.module('plunker', []);

    app.controller('MainCtrl', function ($scope) {
        $scope.ids = [];
    });

    app.directive('dragSelect', function ($window, $document) {
        return {
            scope: {
                dragSelectIds: '='
            },
            controller: function ($scope, $element) {
                var cls = 'eng-selected-item';
                var startCell = null;
                var dragging = false;
                var weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];

                function mouseUp(el) {
                    dragging = false;
                    // Select or deselect the all class switchers

                    // Make sure that headers are not selected for weekdays
                    for (var k = 0; k < weekdays.length; k++) {
                        var count_selected = 0;
                        for (i = 0; i < 11; i++) {
                            var id = weekdays[k] + "-" + i;
                            if (document.getElementById(id).classList.contains(cls)) {
                                count_selected = count_selected + 1
                            };

                        }
                        if (count_selected === 11) {
                            var id = weekdays[k] + "-all";

                            document.getElementById(id).classList.add(cls);
                        } else {
                            var id = weekdays[k] + "-all";
                            document.getElementById(id).classList.remove(cls);
                        };
                    }

                    // Make sure that headers are not selected for hours
                    for (i = 0; i < 11; i++) {
                        var count_selected = 0;
                        for (var k = 0; k < weekdays.length; k++) {
                            var id = weekdays[k] + "-" + i;
                            if (document.getElementById(id).classList.contains(cls)) {
                                count_selected = count_selected + 1
                            };

                        }
                        if (count_selected === 7) {
                            var id = "hour-" + i;
                            document.getElementById(id).classList.add(cls);
                        } else {
                            var id = "hour-" + i;
                            document.getElementById(id).classList.remove(cls);
                        }


                    }


                }

                function mouseDown(el) {
                    dragging = true;
                    setStartCell(el);
                    setEndCell(el);
                }



                function setStartCell(el) {
                    startCell = el;
                }

                function mouseEnter(el) { if (!dragging) return; setEndCell(el); }


                function setEndCell(el) {

                    // Code for Monday
                    var day_of_week = "mon";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 24; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "tue";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "wed";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "thu";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "fri";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 24; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "sat";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "sun";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    // Code for hours

                    if (el.attr('id').startsWith("hour")) {
                        var hour = el.attr('id').split("-")[1];
                        console.log(hour);
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < weekdays.length; i++) {
                                var id = weekdays[i] + "-" + hour;
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < weekdays.length; i++) {
                                var id = weekdays[i] + "-" + hour;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };

                        }

                    }


                    if (el.hasClass(cls)) { // if added then remove on click
                        el.removeClass(cls);
                        var elIndex = $scope.dragSelectIds.indexOf(el[0].id);
                        elIndex !== -1 && $scope.dragSelectIds.splice(elIndex, 1)
                        return false;
                    }
                    if (!$scope.dragSelectIds) {
                        $scope.dragSelectIds = [];
                    }
                    //$element.find('td').removeClass(cls);
                    $(cellsBetween(startCell, el)).each(function () {
                        var el = angular.element(this);
                        el.addClass(cls);
                        // change if added, then not to add twice.
                        var elIndex = $scope.dragSelectIds.indexOf(el[0].id);
                        elIndex === -1 && $scope.dragSelectIds.push(el.attr('id'));
                    });


                }



                function rectangleSelect(selector, x1, x2, y1, y2) {
                    var elements = [];
                    jQuery(selector).each(function () {
                        var $this = jQuery(this);
                        var offset = $this.offset();
                        var x = offset.left;
                        var y = offset.top;
                        var w = $this.width();
                        var h = $this.height();

                        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
                            // this element fits inside the selection rectangle
                            elements.push($this.get(0));
                        }
                    });
                    return elements;
                }

                function cellsBetween(start, end) {

                    var bounds = { minX: 0, minY: 0, maxX: 0, maxY: 0 };
                    bounds.minX = $window.Math.min($(start).offset().left, $(end).offset().left);
                    bounds.minY = $window.Math.min($(start).offset().top, $(end).offset().top);
                    bounds.maxX = $window.Math.max($(end).offset().left + $(end).width(), $(start).offset().left + $(start).width());
                    bounds.maxY = $window.Math.max($(end).offset().top + $(end).height(), $(start).offset().top + $(start).height());

                    var initiallySelectedTds = rectangleSelect("td", bounds.minX, bounds.maxX, bounds.minY, bounds.maxY);

                    for (var i = 0; i < initiallySelectedTds.length; i++) {
                        if ($(initiallySelectedTds[i]).offset().left < bounds.minX)
                            bounds.minX = $(initiallySelectedTds[i]).offset().left;
                        if ($(initiallySelectedTds[i]).offset().left + $(initiallySelectedTds[i]).width() > bounds.maxX)
                            bounds.maxX = $(initiallySelectedTds[i]).offset().left + $(initiallySelectedTds[i]).width();
                        if ($(initiallySelectedTds[i]).offset().top < bounds.minY)
                            bounds.minY = $(initiallySelectedTds[i]).offset().top;
                        if ($(initiallySelectedTds[i]).offset().top + $(initiallySelectedTds[i]).height() > bounds.maxY)
                            bounds.maxY = $(initiallySelectedTds[i]).offset().top + $(initiallySelectedTds[i]).height();
                    }
                    return rectangleSelect("td", bounds.minX, bounds.maxX, bounds.minY, bounds.maxY);

                }


                function wrap(fn) {
                    return function () {
                        var el = angular.element(this);
                        $scope.$apply(function () {
                            fn(el);
                        });
                    }
                }

                $element.delegate('td', 'mousedown', wrap(mouseDown));
                $element.delegate('td', 'mouseenter', wrap(mouseEnter));
                $document.delegate('body', 'mouseup', wrap(mouseUp));
            }
        }
    });
</script>
[drag-select] {
    cursor: pointer;
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -khtml-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   user-select: none;
  }
  
  [drag-select] .eng-selected-item {
    background: green;
    color: white;
  }
<!DOCTYPE html>
<html ng-app="plunker">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
    crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
    crossorigin="anonymous"></script>

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"
        data-semver="1.2.16"></script>
    <script src="app.js"></script>
</head>


<body ng-controller="MainCtrl">

    <div class="container">
        <div class="col-lg-6">
            <table drag-select drag-select-ids="ids" class="table table-responsive table-bordered">
                <tr>
                    <td id="hour">Hours ></td>
                    <td id="hour-0">00</td>
                    <td id="hour-1">01</td>
                    <td id="hour-2">02</td>
                    <td id="hour-3">03</td>
                    <td id="hour-4">04</td>
                    <td id="hour-5">05</td>
                    <td id="hour-6">06</td>
                    <td id="hour-7">07</td>
                    <td id="hour-8">08</td>
                    <td id="hour-9">09</td>
                    <td id="hour-10">10</td>
                    
                </tr>
                <tr>
                    <td id="mon-all">MON</td>
                    <td id="mon-0"></td>
                    <td id="mon-1"></td>
                    <td id="mon-2"></td>
                    <td id="mon-3"></td>
                    <td id="mon-4"></td>
                    <td id="mon-5"></td>
                    <td id="mon-6"></td>
                    <td id="mon-7"></td>
                    <td id="mon-8"></td>
                    <td id="mon-9"></td>
                    <td id="mon-10"></td>
                    
                </tr>
                <tr>
                    <td id="tue-all">TUE</td>
                    <td id="tue-0"></td>
                    <td id="tue-1"></td>
                    <td id="tue-2"></td>
                    <td id="tue-3"></td>
                    <td id="tue-4"></td>
                    <td id="tue-5"></td>
                    <td id="tue-6"></td>
                    <td id="tue-7"></td>
                    <td id="tue-8"></td>
                    <td id="tue-9"></td>
                    <td id="tue-10"></td>
                    
                </tr>
                <tr>
                    <td id="wed-all">WED</td>
                    <td id="wed-0"></td>
                    <td id="wed-1"></td>
                    <td id="wed-2"></td>
                    <td id="wed-3"></td>
                    <td id="wed-4"></td>
                    <td id="wed-5"></td>
                    <td id="wed-6"></td>
                    <td id="wed-7"></td>
                    <td id="wed-8"></td>
                    <td id="wed-9"></td>
                    <td id="wed-10"></td>
                    
                </tr>
                <tr>
                    <td id="thu-all">THU</td>
                    <td id="thu-0"></td>
                    <td id="thu-1"></td>
                    <td id="thu-2"></td>
                    <td id="thu-3"></td>
                    <td id="thu-4"></td>
                    <td id="thu-5"></td>
                    <td id="thu-6"></td>
                    <td id="thu-7"></td>
                    <td id="thu-8"></td>
                    <td id="thu-9"></td>
                    <td id="thu-10"></td>
                    
                </tr>
                <tr>
                    <td id="fri-all">FRI</td>
                    <td id="fri-0"></td>
                    <td id="fri-1"></td>
                    <td id="fri-2"></td>
                    <td id="fri-3"></td>
                    <td id="fri-4"></td>
                    <td id="fri-5"></td>
                    <td id="fri-6"></td>
                    <td id="fri-7"></td>
                    <td id="fri-8"></td>
                    <td id="fri-9"></td>
                    <td id="fri-10"></td>
                    
                </tr>
                <tr>
                    <td id="sat-all">SAT</td>
                    <td id="sat-0"></td>
                    <td id="sat-1"></td>
                    <td id="sat-2"></td>
                    <td id="sat-3"></td>
                    <td id="sat-4"></td>
                    <td id="sat-5"></td>
                    <td id="sat-6"></td>
                    <td id="sat-7"></td>
                    <td id="sat-8"></td>
                    <td id="sat-9"></td>
                    <td id="sat-10"></td>
                    
                </tr>
                <tr>
                    <td id="sun-all">SUN</td>
                    <td id="sun-0"></td>
                    <td id="sun-1"></td>
                    <td id="sun-2"></td>
                    <td id="sun-3"></td>
                    <td id="sun-4"></td>
                    <td id="sun-5"></td>
                    <td id="sun-6"></td>
                    <td id="sun-7"></td>
                    <td id="sun-8"></td>
                    <td id="sun-9"></td>
                    <td id="sun-10"></td>
                    
                </tr>
            </table>
        </div>
    </div>
    <p>Selected IDs: {{ids | json}}</p>
</body>


</html>

UPDATE Создан GIF, который, надеюсь, объясняет это лучше: https://media.giphy.com/media/39yUQuAbdRSmfVfCll/giphy.gif -> при отмене выбора я должен отменить выбор ячейки один за другим вместо отмены выбора нескольких.

1 Ответ

0 голосов
/ 14 ноября 2018

Попробуйте этот фрагмент. Я обобщу свои изменения (вы можете увидеть их как комментарии в коде)

Резюме:

(1) определяет, удаляем ли мы или добавляем на основе начальной ячейки

Вам нужно определить, удаляете ли вы коллекцию или добавление, исходя из начальной ячейки.

(2) не возвращайтесь сюда

Вы не хотите возвращаться при удалении ячейки, потому что мы хотим, чтобы она запускала код для удаления диапазона.

(3) удалить или добавить каждый элемент здесь

Это самое важное изменение. В функции .each() вам нужно фактически удалить или добавить каждый элемент в коллекцию. Я создал вспомогательные функции с именами removeElement и addElement только для удобства чтения.

Я бы также предложил вам попытаться реорганизовать свой код, поскольку я вижу много повторяющихся логических элементов, которые можно разделить на собственные функции. Но ради этого примера я сохранил его в основном таким же.

<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<script>

    var app = angular.module('plunker', []);

    app.controller('MainCtrl', function ($scope) {
        $scope.ids = [];
    });

    app.directive('dragSelect', function ($window, $document) {
        return {
            scope: {
                dragSelectIds: '='
            },
            controller: function ($scope, $element) {
                var cls = 'eng-selected-item';
                var startCell = null;
                var isRemoving = false;
                var dragging = false;
                var weekdays = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];

                function mouseUp(el) {
                    dragging = false;
                    // Select or deselect the all class switchers

                    // Make sure that headers are not selected for weekdays
                    for (var k = 0; k < weekdays.length; k++) {
                        var count_selected = 0;
                        for (i = 0; i < 11; i++) {
                            var id = weekdays[k] + "-" + i;
                            if (document.getElementById(id).classList.contains(cls)) {
                                count_selected = count_selected + 1
                            };

                        }
                        if (count_selected === 11) {
                            var id = weekdays[k] + "-all";

                            document.getElementById(id).classList.add(cls);
                        } else {
                            var id = weekdays[k] + "-all";
                            document.getElementById(id).classList.remove(cls);
                        };
                    }

                    // Make sure that headers are not selected for hours
                    for (i = 0; i < 11; i++) {
                        var count_selected = 0;
                        for (var k = 0; k < weekdays.length; k++) {
                            var id = weekdays[k] + "-" + i;
                            if (document.getElementById(id).classList.contains(cls)) {
                                count_selected = count_selected + 1
                            };

                        }
                        if (count_selected === 7) {
                            var id = "hour-" + i;
                            document.getElementById(id).classList.add(cls);
                        } else {
                            var id = "hour-" + i;
                            document.getElementById(id).classList.remove(cls);
                        }


                    }


                }

                function mouseDown(el) {
                    dragging = true;
                    setStartCell(el);
                    setEndCell(el);
                }



                function setStartCell(el) {
                    startCell = el;
                    // (1) determine if we're removing or adding based on the start cell
                    isRemoving = el.hasClass(cls);
                }

                function mouseEnter(el) { if (!dragging) return; setEndCell(el); }


                function setEndCell(el) {

                    // Code for Monday
                    var day_of_week = "mon";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 24; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "tue";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "wed";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "thu";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "fri";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 24; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "sat";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    var day_of_week = "sun";
                    if (el.attr('id') === day_of_week + "-all") {
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < 11; i++) {
                                var id = day_of_week + "-" + i;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };
                        }

                    };

                    // Code for hours

                    if (el.attr('id').startsWith("hour")) {
                        var hour = el.attr('id').split("-")[1];
                        console.log(hour);
                        // If highlighted true
                        if (el.hasClass(cls) === true) {
                            var i;
                            for (i = 0; i < weekdays.length; i++) {
                                var id = weekdays[i] + "-" + hour;
                                document.getElementById(id).classList.remove(cls);
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                $scope.dragSelectIds.splice(elIndex, 1)

                            };

                        }
                        /// If highlighted false
                        if (el.hasClass(cls) === false) {
                            var i;
                            for (i = 0; i < weekdays.length; i++) {
                                var id = weekdays[i] + "-" + hour;
                                var elIndex = $scope.dragSelectIds.indexOf(id);
                                document.getElementById(id).classList.add(cls);
                                elIndex === -1 && $scope.dragSelectIds.push(id);
                            };

                        }

                    }

                    if (el.hasClass(cls)) { // if added then remove on click
                        el.removeClass(cls);
                        var elIndex = $scope.dragSelectIds.indexOf(el[0].id);
                        elIndex !== -1 && $scope.dragSelectIds.splice(elIndex, 1)
                        // (2) don't return here
                        // return false; 
                    }
                    if (!$scope.dragSelectIds) {
                        $scope.dragSelectIds = [];
                    }
                    
                    // (3) remove or add each element here
                    $(cellsBetween(startCell, el)).each(function(i, elem) {
                        if (isRemoving)
                          removeElement($(elem));
                        else 
                          addElement($(elem));
                    });


                }

                function removeElement(el) {
                  el.removeClass(cls);
                  var elIndex = $scope.dragSelectIds.indexOf(el[0].id);
                  elIndex !== -1 && $scope.dragSelectIds.splice(elIndex, 1)
                }
                
                function addElement(el) {
                  el.addClass(cls);
                  var elIndex = $scope.dragSelectIds.indexOf(el[0].id);
                  elIndex === -1 && $scope.dragSelectIds.push(el.attr('id'));
                }

                function rectangleSelect(selector, x1, x2, y1, y2) {
                    var elements = [];
                    jQuery(selector).each(function () {
                        var $this = jQuery(this);
                        var offset = $this.offset();
                        var x = offset.left;
                        var y = offset.top;
                        var w = $this.width();
                        var h = $this.height();

                        if (x >= x1 && x <= x2 && y >= y1 && y <= y2) {
                            // this element fits inside the selection rectangle
                            elements.push($this.get(0));
                        }
                    });
                    return elements;
                }

                function allCells(start, end) {
                  console.log('start, end', start, end);
                }

                function cellsBetween(start, end) {

                    var bounds = { minX: 0, minY: 0, maxX: 0, maxY: 0 };
                    bounds.minX = $window.Math.min($(start).offset().left, $(end).offset().left);
                    bounds.minY = $window.Math.min($(start).offset().top, $(end).offset().top);
                    bounds.maxX = $window.Math.max($(end).offset().left + $(end).width(), $(start).offset().left + $(start).width());
                    bounds.maxY = $window.Math.max($(end).offset().top + $(end).height(), $(start).offset().top + $(start).height());

                    var initiallySelectedTds = rectangleSelect("td", bounds.minX, bounds.maxX, bounds.minY, bounds.maxY);

                    for (var i = 0; i < initiallySelectedTds.length; i++) {
                        if ($(initiallySelectedTds[i]).offset().left < bounds.minX)
                            bounds.minX = $(initiallySelectedTds[i]).offset().left;
                        if ($(initiallySelectedTds[i]).offset().left + $(initiallySelectedTds[i]).width() > bounds.maxX)
                            bounds.maxX = $(initiallySelectedTds[i]).offset().left + $(initiallySelectedTds[i]).width();
                        if ($(initiallySelectedTds[i]).offset().top < bounds.minY)
                            bounds.minY = $(initiallySelectedTds[i]).offset().top;
                        if ($(initiallySelectedTds[i]).offset().top + $(initiallySelectedTds[i]).height() > bounds.maxY)
                            bounds.maxY = $(initiallySelectedTds[i]).offset().top + $(initiallySelectedTds[i]).height();
                    }
                    return rectangleSelect("td", bounds.minX, bounds.maxX, bounds.minY, bounds.maxY);

                }


                function wrap(fn) {
                    return function () {
                        var el = angular.element(this);
                        $scope.$apply(function () {
                            fn(el);
                        });
                    }
                }

                $element.delegate('td', 'mousedown', wrap(mouseDown));
                $element.delegate('td', 'mouseenter', wrap(mouseEnter));
                $document.delegate('body', 'mouseup', wrap(mouseUp));
            }
        }
    });
</script>
[drag-select] {
    cursor: pointer;
   -webkit-touch-callout: none;
   -webkit-user-select: none;
   -khtml-user-select: none;
   -moz-user-select: none;
   -ms-user-select: none;
   user-select: none;
  }
  
  [drag-select] .eng-selected-item {
    background: green;
    color: white;
  }
<!DOCTYPE html>
<html ng-app="plunker">
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u"
    crossorigin="anonymous">

<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp"
    crossorigin="anonymous">

<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa"
    crossorigin="anonymous"></script>

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="jquery" data-semver="2.0.3" src="http://code.jquery.com/jquery-2.0.3.min.js"></script>
    <script data-require="angular.js@1.2.x" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min.js"
        data-semver="1.2.16"></script>
    <script src="app.js"></script>
</head>


<body ng-controller="MainCtrl">

    <div class="container">
        <div class="col-lg-6">
            <table drag-select drag-select-ids="ids" class="table table-responsive table-bordered">
                <tr>
                    <td id="hour">Hours ></td>
                    <td id="hour-0">00</td>
                    <td id="hour-1">01</td>
                    <td id="hour-2">02</td>
                    <td id="hour-3">03</td>
                    <td id="hour-4">04</td>
                    <td id="hour-5">05</td>
                    <td id="hour-6">06</td>
                    <td id="hour-7">07</td>
                    <td id="hour-8">08</td>
                    <td id="hour-9">09</td>
                    <td id="hour-10">10</td>
                    
                </tr>
                <tr>
                    <td id="mon-all">MON</td>
                    <td id="mon-0"></td>
                    <td id="mon-1"></td>
                    <td id="mon-2"></td>
                    <td id="mon-3"></td>
                    <td id="mon-4"></td>
                    <td id="mon-5"></td>
                    <td id="mon-6"></td>
                    <td id="mon-7"></td>
                    <td id="mon-8"></td>
                    <td id="mon-9"></td>
                    <td id="mon-10"></td>
                    
                </tr>
                <tr>
                    <td id="tue-all">TUE</td>
                    <td id="tue-0"></td>
                    <td id="tue-1"></td>
                    <td id="tue-2"></td>
                    <td id="tue-3"></td>
                    <td id="tue-4"></td>
                    <td id="tue-5"></td>
                    <td id="tue-6"></td>
                    <td id="tue-7"></td>
                    <td id="tue-8"></td>
                    <td id="tue-9"></td>
                    <td id="tue-10"></td>
                    
                </tr>
                <tr>
                    <td id="wed-all">WED</td>
                    <td id="wed-0"></td>
                    <td id="wed-1"></td>
                    <td id="wed-2"></td>
                    <td id="wed-3"></td>
                    <td id="wed-4"></td>
                    <td id="wed-5"></td>
                    <td id="wed-6"></td>
                    <td id="wed-7"></td>
                    <td id="wed-8"></td>
                    <td id="wed-9"></td>
                    <td id="wed-10"></td>
                    
                </tr>
                <tr>
                    <td id="thu-all">THU</td>
                    <td id="thu-0"></td>
                    <td id="thu-1"></td>
                    <td id="thu-2"></td>
                    <td id="thu-3"></td>
                    <td id="thu-4"></td>
                    <td id="thu-5"></td>
                    <td id="thu-6"></td>
                    <td id="thu-7"></td>
                    <td id="thu-8"></td>
                    <td id="thu-9"></td>
                    <td id="thu-10"></td>
                    
                </tr>
                <tr>
                    <td id="fri-all">FRI</td>
                    <td id="fri-0"></td>
                    <td id="fri-1"></td>
                    <td id="fri-2"></td>
                    <td id="fri-3"></td>
                    <td id="fri-4"></td>
                    <td id="fri-5"></td>
                    <td id="fri-6"></td>
                    <td id="fri-7"></td>
                    <td id="fri-8"></td>
                    <td id="fri-9"></td>
                    <td id="fri-10"></td>
                    
                </tr>
                <tr>
                    <td id="sat-all">SAT</td>
                    <td id="sat-0"></td>
                    <td id="sat-1"></td>
                    <td id="sat-2"></td>
                    <td id="sat-3"></td>
                    <td id="sat-4"></td>
                    <td id="sat-5"></td>
                    <td id="sat-6"></td>
                    <td id="sat-7"></td>
                    <td id="sat-8"></td>
                    <td id="sat-9"></td>
                    <td id="sat-10"></td>
                    
                </tr>
                <tr>
                    <td id="sun-all">SUN</td>
                    <td id="sun-0"></td>
                    <td id="sun-1"></td>
                    <td id="sun-2"></td>
                    <td id="sun-3"></td>
                    <td id="sun-4"></td>
                    <td id="sun-5"></td>
                    <td id="sun-6"></td>
                    <td id="sun-7"></td>
                    <td id="sun-8"></td>
                    <td id="sun-9"></td>
                    <td id="sun-10"></td>
                    
                </tr>
            </table>
        </div>
    </div>
    <p>Selected IDs: {{ids | json}}</p>
</body>


</html>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...