Введите поисковый запрос

drag and drop для ajax сортировки элементов Битрикс

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


<ul id="sortable-list" class="bl_ft_aj_o_nas">
<ul id="sortable-list" class="bl_ft_aj_o_nas">
<?
$arSelect = Array("ID", "NAME", "PREVIEW_PICTURE");
$arFilter = Array("IBLOCK_ID"=>IntVal(42), "ACTIVE"=>"", "PROPERTY_SALON_ID"=>$id_orgiginal);
$res = CIBlockElement::GetList(Array("SORT"=>"asc"), $arFilter, false, Array("nPageSize"=>500), $arSelect);
while($ob = $res->GetNextElement())
{
$arFields = $ob->GetFields();
$file = CFile::ResizeImageGet($arFields['PREVIEW_PICTURE'], array('width'=>161, 'height'=>161), BX_RESIZE_IMAGE_EXACT, true);
$sl_img = $file['src'];
echo '



<li class="sortable-item" data-id="'. $arFields['ID'].'"   data-sort="'. $arFields['SORT'].'">
<img src="'.$sl_img.'" alt=""  >
<a href="" class="dell_img" rel="'. $arFields['ID'].'"><i class="fas fa-trash-alt blue_icon"></i> Удалить картинку</a><br>
</li>

'
}
?>
</ul>

Далее добавляем стили



<style>
#sortable-list{
display: flex;
list-style-type: none;
padding: 0;
margin: 0;
justify-content: flex-start;
flex-wrap: wrap;
}

.sortable-item {
width: 150px;
height: 150px;
margin: 20px;
border: 1px solid #ccc;
cursor: move;
}

</style>

Ajax сортировка

После перетаскивания фотографии, мне необходимо поменять сортировку файлов. Для этого создадим файл change_sort.php и добавлю его в папку ajax.

содержания файла change_sort.php


<?
require_once($_SERVER['DOCUMENT_ROOT'] . "/bitrix/modules/main/include/prolog_before.php");
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();
CModule::IncludeModule("iblock");

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $data = json_decode(file_get_contents("php://input"), true);
    foreach ($data as $item) {
        $id = $item['id'];
        $sort = $item['sotr'];
        if (!$sort) $sort = 500;
        $el = new CIBlockElement;
        $arLoadProductArray = Array(
            "SORT" => $sort
        );
        if ($PRODUCT_ID = $el->Update($id, $arLoadProductArray))
            echo "Обновлен элемент с ID $id и новым значением сортировки $sort<br>";
    }
}


?>


для проверки работы, я добавил еще дополнительно вывод информации. При необходимости можно его убрать
Осталось на все это дело навесить скрипт.

Код скрипта


        const sortableList = document.getElementById("sortable-list");
        let draggedItem = null;

        sortableList.addEventListener("dragstart", function(event) {
            const target = event.target.closest(".sortable-item");
            if (!target) return;
            draggedItem = target;
            event.dataTransfer.setData("text/plain", null);
        });

        sortableList.addEventListener("dragover", function(event) {
            event.preventDefault();
            const target = event.target.closest(".sortable-item");
            if (!target) return;
            const targetRect = target.getBoundingClientRect();
            const draggedItemRect = draggedItem.getBoundingClientRect();
            const afterElement = event.clientX < targetRect.left + targetRect.width / 2 ? target : target.nextElementSibling;
            const draggable = document.querySelector(".dragging");
            if (afterElement == null) {
                sortableList.appendChild(draggedItem);
            } else {
                sortableList.insertBefore(draggedItem, afterElement);
            }
        });

        function getDragAfterElement(container, y) {
            const draggableElements = [...container.querySelectorAll(".sortable-item:not(.dragging)")];
            return draggableElements.reduce((closest, child) => {
                const box = child.getBoundingClientRect();
                const offset = y - box.top - box.height / 2;
                if (offset < 0 && offset > closest.offset) {
                    return { offset: offset, element: child };
                } else {
                    return closest;
                }
            }, { offset: Number.NEGATIVE_INFINITY }).element;
        }

        sortableList.addEventListener("dragend", function(event) {
            const items = [...sortableList.querySelectorAll('.sortable-item')];
            const newSortOrder = items.map((item, index) => {
                item.setAttribute('data-sort', index + 1);
                return {
                    id: item.getAttribute('data-id'),
                    sotr: item.getAttribute('data-sort')
                }
                console.log(items);

            });

            // Отправляем запрос AJAX на сервер с новыми значениями data-id
            const xhr = new XMLHttpRequest();
            xhr.open('POST', '/profile/moderator/ajax_new/change_sort.php');
            xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.onload = function() {
                if (xhr.status === 200) {
                    console.log('Sort order updated successfully');
                } else {
                    console.error('Error updating sort order');
                }
            };
            xhr.send(JSON.stringify(newSortOrder));
        });



Общий рейтинг: 5
1 оценка
Ваша оценка:

Комментарии (0)


Оставить заявку
 
 

Денис Бунаков

C 2012 года являюсь Битрикс Программистом.
Программист 1С:Битрикс – это веб-разработчик с узким профилем, который работает непосредственно с продукцией от компании 1С.