Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > перетаскивание строк таблицы


Автор: Pokoinik 1.10.2007, 12:48
Вобщем нужен скрипт, позволяющий менять местами строки таблицы, через перетаскивание...
Можете посоветовать что-нить готовое...

Автор: dsCode 1.10.2007, 13:07
Pokoinik, готовое нет, но алгоритм не сложный:

1. драг
2. дроп
3. вставка перетаскиваемой строки в "дроп-место"
4. удаление строки, которая находилась в  "дроп-месте"
5. вставка строки, которая находилась в "дроп-месте", в место, откуда пришла перетаскиваемая строка =)

На самом деле, у меня в проекте такая штука написана. Только там не меняются строки местами, а можно перетаскивать чайл-строки в другие паренты (таблица в виде дерева, outline, в общем). Но там жесткая привязка к конкретным виджетам, так что не подойдет. Да собственно, не код главное, а алгоритм, а он - простой - всего 5 пунктов.

Добавлено через 5 минут и 26 секунд
http://www.webreference.com/programming/javascript/mk/column2/, наподобие, что Вам нужно

Автор: Pokoinik 1.10.2007, 15:22
На ваял вот какой скрипт
Код

<html>
    <head>
        <title>Layer Dragging</title>
        <style type="text/css">
            .draggable {cursor:hand;}
            .polygon{}
            .section {
                width: 600px;
                height: 50px;
                background-color: Blue;
                border-style: double;
                border-width: 1px;
                border-color: Black;
                margin: 3px;
                position: block;
            }
      </style>
<script type="text/javascript">
    var draggedElem; 
    var offsetX = 0;
    var offsetY = 0;
    function dragIt(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (draggedElem) {
            targElem = draggedElem;
            if (targElem.className == "section") {
                //while (targElem.id != "myLayer" && targElem.parentNode) {
                while (targElem.className != "section" && targElem.parentNode) {
                    targElem = targElem.parentNode;
                }
                if (evt.pageX) {
                    //targElem.style.left = evt.pageX - offsetX + "px";
                    targElem.style.top = evt.pageY - offsetY + "px";
                } else {
                    //targElem.style.left = evt.clientX - offsetX + "px";
                    targElem.style.top = evt.clientY - offsetY + "px";
                }
                return false;
            }
        }
    }
    function engage(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (targElem.className == "section") {
            //targElem.style.display = 'none';
            targElem.style.position = 'absolute';
            targElem.style.opacity= '0.5';
            targElem.style.zIndex= '100';
            targElem.style.backgroundColor= 'White';
            while (targElem.className != "section" && targElem.parentNode) {
                targElem = targElem.parentNode;
            }
            if (targElem.className == "section") {
                draggedElem = targElem;
                if (evt.pageX) {
                    //offsetX = evt.pageX - targElem.offsetLeft;
                    offsetY = evt.pageY - targElem.offsetTop;
                } else {
                    //offsetX = evt.offsetX - document.body.scrollLeft;
                    offsetY = evt.offsetY - document.body.scrollTop;
                    if (navigator.userAgent.indexOf("Win") == -1) {
                        //offsetX += document.body.scrollLeft;
                        offsetY += document.body.scrollTop;
                    }
                }
                return false;
            }
        }
    }
    function release(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (targElem.className == "section") {
            while (targElem.className != "section" && targElem.parentNode) {
                targElem = targElem.parentNode;
            }
            if (draggedElem && targElem.className == "section") {
                targElem.style.position = 'block';
                targElem.style.opacity= '1';
                targElem.style.zIndex= '0';
                targElem.style.backgroundColor= 'blue';
                draggedElem = null;
            }
        }
    }
</script>
   </head>
   <body>
      <h1>Dragging a Layer</h1>
      <hr />
      <script type="text/javascript">
         document.onmousedown = engage;
         document.onmouseup = release;
         document.onmousemove = dragIt;
         </script>
    
         <div id='polygon'>
            <div class="section"><span class="polygon">Первый раздел</span></div>
            <div class="section"><span class="polygon">Второй раздел</span></div>
            <div class="section"><span class="polygon">Третий раздел</span></div>
            <div class="section"><span class="polygon">Четвертый раздел</span></div>
            <div class="section"><span class="polygon">Пятый раздел</span></div>
         </div>
   </body>
</html>


Перетаскивание работет нормально, но не реализована вставка:
по какому принципу это можно сделать?

Добавлено через 1 минуту и 14 секунд
Нужно чтобы при перетаскивании одного раздела на другой, он вставлялся перед ним...

Автор: dsCode 1.10.2007, 15:52
Pokoinik, а, ну ту div'ы, а не tr'ы таблицы. Так что легче еще.
Цитата(Pokoinik @  1.10.2007,  15:22 Найти цитируемый пост)
Нужно чтобы при перетаскивании одного раздела на другой, он вставлялся перед ним...

В той ссылки, которая была в первом моем посте - так и сделано (я думал, что надо менять местами, а тут просто вставлять). В приближенном описании - просто сдвинуть див, на который переностся, ниже (.top += высота_дива + отступ), а на его место вставить перетаскиваемый.

P.S.: кстати, в IE Ваш скрипт выдает ошибку, когда drop происходит

Автор: Pokoinik 1.10.2007, 17:21
dsCode, просто скрипт пока тестится в файерфоксе, опере и etc,
на ie пока не тестил, но по предворительным мыслям там нужно будет использовать события ondrag, которого нету в ff, opera...
хочется чтобы скрипт работал во всех популярных броузерах...

Автор: SelenIT 2.10.2007, 05:35
Цитата(Pokoinik @  1.10.2007,  17:21 Найти цитируемый пост)
по предворительным мыслям там нужно будет использовать события ondrag

Не нужно - он для другого предназначен и не для всех элементов работает. Наоборот, нежданное возникновение этого события может мешать, к счастью, это довольно легко обходится (напр., http://forum.vingrad.ru/forum/topic-122195.html сравнивали пару способов).

Вообще, существует масса готовых реализаций, можно воспользоваться поиском "Drag drop sortable lists" и выбрать что-нибудь в качестве основы. Например, http://tool-man.org/examples/sorting.html...

Автор: Pokoinik 2.10.2007, 09:12
SelenIT, спасибо за помощь
реализовал так:
Код

<html>
    <head>
        <title>Layer Dragging</title>
        <style type="text/css">
            .draggable {cursor:hand;}
            .polygon{}
            .section {
                width: 600px;
                height: 50px;
                background-color: Blue;
                border-style: double;
                border-width: 1px;
                border-color: Black;
                margin: 3px;
                position: block;
            }
      </style>
<script type="text/javascript">
    var draggedElem; 
    var offsetX = 0;
    var offsetY = 0;
    var polygon = null;
    var posY = null;
    var posSave = null;
    
    function dragIt(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (draggedElem) {
            targElem = draggedElem;
            if (targElem.className == "section") {
                while (targElem.className != "section" && targElem.parentNode)
                    targElem = targElem.parentNode;
                if (evt.pageX) targElem.style.top = evt.pageY - offsetY + "px";
                else targElem.style.top = evt.clientY - offsetY + "px";
                return false;
            }
        }
    }
    
    function sectionSort(a, b) {
        var posA = getAbsolutePos(a);
        var posB = getAbsolutePos(b);
        if (posA.y == posB.y) return 0;
        else if(posA.y < posB.y) return -1;
        return 1;
    }
    
    function engage(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (targElem.className == "section") {
            targElem.style.position = 'absolute';
            //fadeOpacity(targElem.id, targElem.id);
            targElem.style.zIndex= '100';
            targElem.style.backgroundColor= 'White';
            var childern = new Array();
            for (var i=0; i<polygon.childNodes.length; i++) 
                childern[i] = polygon.childNodes[i];
            posY = posSave;
            childern.sort(sectionSort);
            for (var i=0;i<childern.length;i++) {
                if(childern[i].id != targElem.id) {
                    childern[i].style.top = posY;
                    posY += 56;
                }
            }
            while (targElem.className != "section" && targElem.parentNode)
                targElem = targElem.parentNode;
            if (targElem.className == "section") {
                draggedElem = targElem;
                if (evt.pageX) {
                    offsetY = evt.pageY - targElem.offsetTop;
                } else {
                    offsetY = evt.offsetY - document.body.scrollTop;
                    if (navigator.userAgent.indexOf("Win") == -1)
                        offsetY += document.body.scrollTop;
                }
                return false;
            }
        }
    }
    function release(evt) {
        evt = (evt) ? evt : (window.event) ? window.event : "";
        var targElem = (evt.target) ? evt.target : evt.srcElement;
        if (targElem.className == "section") {
            while (targElem.className != "section" && targElem.parentNode)
                targElem = targElem.parentNode;
            if (draggedElem && targElem.className == "section") {
                //fadeOpacity.back(targElem.id);
                targElem.style.zIndex= '0';
                targElem.style.backgroundColor= 'blue';
                var childern = new Array();
                for (var i=0; i<polygon.childNodes.length; i++)
                    childern[i] = polygon.childNodes[i];
                posY = posSave;
                childern.sort(sectionSort);
                draggedElem = null;
                for (var i=0;i<childern.length;i++) {
                    childern[i].style.top = posY;
                    posY += 56;
                }
                draggedElem = null;
            }
        }
    }
    
    function getAbsolutePos(el) {
        var r = { x: el.offsetLeft, y: el.offsetTop };
        if (el.offsetParent) {
                var tmp = getAbsolutePos(el.offsetParent);
                r.x += tmp.x;
                r.y += tmp.y;
        }
        return r;
    }
    
    function init() {
        document.onmousedown = engage;
        document.onmouseup = release;
        document.onmousemove = dragIt;
        polygon = document.getElementById('polygon');
        posY = getAbsolutePos(polygon.childNodes[0]).y;
        posSave = posY;
        var childern = new Array();
        for (var i=0; i<polygon.childNodes.length; i++)
            childern[i] = polygon.childNodes[i];
        posY = posSave;
        childern.sort(sectionSort);
        draggedElem = null;
        for (var i=0;i<childern.length;i++) {
            childern[i].style.top = posY;
            childern[i].style.position = 'absolute';
            posY += 56;
            //fadeOpacity.addRule(childern[i].id, 1, .3, 30);
        }
    }
</script>
   </head>
   <body onload="init();">
<div id='polygon'><div id="sec1" class="section"><span class="polygon">Первый раздел</span></div><div id="sec2" class="section"><span class="polygon">Второй раздел</span></div><div id="sec3" class="section"><span class="polygon">Третий раздел</span></div><div id="sec4" class="section"><span class="polygon">Четвертый раздел</span></div><div id="sec5" class="section"><span class="polygon">Пятый раздел</span></div></div>
</body>
</html>

Смотрел в опере, конкуероре, файерфоксе, ослик 6 - вроде работает...
на 7 ослике не тестил...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)