Я разрабатываю собственный плагин jQuery под названием DataTablePro, чтобы добавить в мою таблицу такие функции, как поиск, нумерация страниц и сортировка. Однако я столкнулся с проблемой, из-за которой функция поиска не работает должным образом.
Вводные данные для поиска отображаются правильно.
Когда я печатаю в поле поиска, строки должны фильтроваться на основе поискового запроса.
Однако строки не фильтруются, и в консоли браузера не отображается ошибка.
После отладки я обнаружил, что проблема возникает, когда applyPagination() запускается после функция поиска. Похоже, это препятствует правильной работе функции поиска.
js-код
(function ($) {
$.fn.DataTablePro = function (options) {
// Default options
const settings = $.extend({
dropdownColumns: {}, // Dropdowns: {columnIndex: ['Option1', 'Option2']}
nonEditableColumns: [], // Non-editable columns (array of indexes)
enableSearch: false, // Enable search box
enableSorting: false, // Enable sorting
enablePaging: false, // Enable pagination
enablePageLengthSelector: false, // Enable page length selector
showNextPrevButtons: true, // Show Next/Previous buttons in pagination
showLastButton: true, // Show Last button in pagination
showTotalRecords: false, // Show total records count
pageLengths: [10, 25, 50, 100], // Page length options
defaultPageLength: 10, // Default page length
maxVisiblePages: 3, // Maximum visible page numbers
sortableColumns: [], // Array of sortable column indexes (e.g., [0, 2, 3])
//enableCustomFeature: false, // New option to enable/disable custom functionality
}, options);
const table = this;
const tableBody = table.find("tbody");
const paginationContainer = $('');
const lengthSelectorContainer = $('');
const totalRecordsContainer = $('');
let currentPageLength = settings.defaultPageLength;
let currentPage = 0; // Start at page 0 (Page 1)
// Add containers dynamically
if (settings.enablePaging) table.after(paginationContainer);
if (settings.showTotalRecords) table.after(totalRecordsContainer);
if (settings.enablePageLengthSelector) table.before(lengthSelectorContainer);
// Function for Pagination
function applyPagination() {
if (!settings.enablePaging) return;
const rows = tableBody.find("tr").not(".no-records");
const totalRows = rows.length;
const totalPages = Math.ceil(totalRows / currentPageLength);
paginationContainer.empty();
// Add Previous button
if (settings.showNextPrevButtons) {
const prevButton = $('Previous');
prevButton.prop("disabled", currentPage === 0);
paginationContainer.append(prevButton);
}
// Add dynamic page buttons
const visiblePages = settings.maxVisiblePages;
let startPage = Math.max(0, currentPage - Math.floor(visiblePages / 2));
let endPage = Math.min(totalPages, startPage + visiblePages);
if (endPage - startPage < visiblePages) {
startPage = Math.max(0, endPage - visiblePages);
}
for (let i = startPage; i < endPage; i++) {
const btn = $(`${i + 1}`);
if (i === currentPage) btn.addClass("active");
paginationContainer.append(btn);
}
// Add Next and Last buttons
if (settings.showNextPrevButtons) {
const nextButton = $('Next');
nextButton.prop("disabled", currentPage === totalPages - 1);
paginationContainer.append(nextButton);
if (settings.showLastButton) {
const lastButton = $('Last');
lastButton.prop("disabled", currentPage === totalPages - 1);
paginationContainer.append(lastButton);
}
}
updatePage(rows, totalRows, totalPages);
// Pagination button click event
paginationContainer.find(".pagination-btn").on("click", function () {
const dir = $(this).data("dir");
if (dir) {
currentPage = Math.min(Math.max(0, currentPage + dir), totalPages - 1);
} else if ($(this).hasClass("last-btn")) {
currentPage = totalPages - 1;
} else {
currentPage = parseInt($(this).text(), 10) - 1;
}
updatePage(rows, totalRows, totalPages);
applyPagination(); // Reapply buttons dynamically
});
}
function updatePage(rows, totalRows, totalPages) {
const start = currentPage * currentPageLength;
const end = Math.min(start + currentPageLength, totalRows);
rows.hide().slice(start, end).show();
paginationContainer.find(".pagination-btn").removeClass("active");
paginationContainer.find(`.pagination-btn`).filter(function () {
return $(this).text() == currentPage + 1;
}).addClass("active");
if (settings.showNextPrevButtons) {
paginationContainer.find(".prev-btn").prop("disabled", currentPage === 0);
paginationContainer.find(".next-btn").prop("disabled", currentPage === totalPages - 1);
}
if (settings.showTotalRecords) {
totalRecordsContainer.text(`Showing ${start + 1}-${end} of ${totalRows} records`);
}
}
// Page Length Selector
function addPageLengthSelector() {
if (!settings.enablePageLengthSelector) return;
const selector = $('');
settings.pageLengths.forEach(length => {
const option = $(`${length} records per page`);
if (length === currentPageLength) option.prop("selected", true);
selector.append(option);
});
lengthSelectorContainer.empty().append(selector);
selector.on("change", function () {
currentPageLength = parseInt($(this).val(), 10);
currentPage = 0;
applyPagination();
});
}
// Inline Editing
function enableInlineEditing() {
tableBody.find("td").off("dblclick").on("dblclick", function () {
const currentCell = $(this);
const columnIndex = currentCell.index();
if (settings.nonEditableColumns.includes(columnIndex)) return;
const originalContent = currentCell.text();
if (currentCell.find("input, select").length > 0) return;
const cellWidth = currentCell.outerWidth();
const cellHeight = currentCell.outerHeight();
if (settings.dropdownColumns[columnIndex]) {
let dropdownHtml = ``;
settings.dropdownColumns[columnIndex].forEach(option => {
dropdownHtml += `${option}`;
});
dropdownHtml += ``;
currentCell.html(dropdownHtml);
const dropdown = currentCell.find("select");
dropdown.focus();
dropdown.on("blur change", function () {
const selectedValue = dropdown.val();
currentCell.text(selectedValue);
// Submit on blur for dropdown
submitCellData(columnIndex, selectedValue, originalContent);
});
} else {
currentCell.html(``);
const input = currentCell.find("input");
input.focus();
input.on("blur keypress", function (e) {
if (e.type === "blur" || e.which === 13) {
const newValue = input.val();
currentCell.text(newValue);
// Submit on blur for text input
submitCellData(columnIndex, newValue, originalContent);
}
});
}
});
}
// Function to handle submission of cell data
function submitCellData(columnIndex, newValue, originalValue) {
if (newValue !== originalValue) {
// Example AJAX request to submit data
$.ajax({
url: "/update-cell", // Replace with your server-side endpoint
method: "POST",
data: {
columnIndex: columnIndex,
value: newValue
},
success: function (response) {
console.log("Cell updated successfully:", response);
},
error: function (xhr, status, error) {
console.error("Error updating cell:", error);
alert("Failed to update cell. Reverting to original value.");
// Revert to original value in case of error
tableBody.find("td").eq(columnIndex).text(originalValue);
}
});
}
}
// Search
if (settings.enableSearch) {
const searchBox = $('');
table.before(searchBox);
searchBox.on("keyup", function () {
const value = $(this).val().toLowerCase();
let visibleRows = 0;
tableBody.find("tr").each(function () {
const rowText = $(this).text().toLowerCase();
const isMatch = rowText.indexOf(value) > -1;
$(this).toggle(isMatch);
if (isMatch && !$(this).hasClass("no-records")) {
visibleRows++;
}
});
// Show/hide "no records" row
if (visibleRows === 0) {
tableBody.find(".no-records").show();
} else {
tableBody.find(".no-records").hide();
}
// Reapply pagination after filtering
applyPagination && applyPagination();
});
}
// Sorting Functionality with Vertical Arrows Always Visible
if (settings.enableSorting) {
table.find("th").each(function () {
const columnIndex = $(this).index();
// Check if column is sortable
if (!settings.sortableColumns.includes(columnIndex)) {
$(this).css("cursor", "not-allowed"); // Disable cursor for non-sortable columns
return;
}
// Dynamically add the vertical arrows to each column header
if ($(this).find('.sort-arrow-container').length === 0) {
$(this).append(`
▲
▼
`);
}
// Add click event for sorting
$(this).on("click", function () {
const rows = tableBody.find("tr").get();
const isNumericColumn = $(this).hasClass("numeric");
const currentColumn = $(this);
// Check current sort direction
let isAscending = currentColumn.hasClass("asc");
// Clear previous sort classes
table.find("th").removeClass("asc desc");
// Toggle sorting direction and update classes
if (isAscending) {
currentColumn.addClass("desc");
} else {
currentColumn.addClass("asc");
}
// Sort the rows based on the current column
rows.sort(function (a, b) {
const cellA = $(a).children("td").eq(columnIndex).text();
const cellB = $(b).children("td").eq(columnIndex).text();
let comparison = 0;
if (isNumericColumn) {
comparison = parseFloat(cellA) - parseFloat(cellB);
} else {
comparison = cellA.localeCompare(cellB);
}
return isAscending ? comparison : -comparison; // Toggle ascending/descending
});
// Append sorted rows to the table body
$.each(rows, function (index, row) {
tableBody.append(row);
});
});
});
}
// Apply Pagination and Length Selector
applyPagination();
addPageLengthSelector();
enableInlineEditing();
//applyCustomFeature();
};
})(jQuery);
Подробнее здесь: https://stackoverflow.com/questions/793 ... tom-plugin
Функциональность поиска не работает в пользовательском плагине (разработка собственного плагина) ⇐ Jquery
Программирование на jquery
1736068303
Anonymous
Я разрабатываю собственный плагин jQuery под названием DataTablePro, чтобы добавить в мою таблицу такие функции, как поиск, нумерация страниц и сортировка. Однако я столкнулся с проблемой, из-за которой функция поиска не работает должным образом.
Вводные данные для поиска отображаются правильно.
Когда я печатаю в поле поиска, строки должны фильтроваться на основе поискового запроса.
Однако строки не фильтруются, и в консоли браузера не отображается ошибка.
После отладки я обнаружил, что проблема возникает, когда applyPagination() запускается после функция поиска. Похоже, это препятствует правильной работе функции поиска.
js-код
(function ($) {
$.fn.DataTablePro = function (options) {
// Default options
const settings = $.extend({
dropdownColumns: {}, // Dropdowns: {columnIndex: ['Option1', 'Option2']}
nonEditableColumns: [], // Non-editable columns (array of indexes)
enableSearch: false, // Enable search box
enableSorting: false, // Enable sorting
enablePaging: false, // Enable pagination
enablePageLengthSelector: false, // Enable page length selector
showNextPrevButtons: true, // Show Next/Previous buttons in pagination
showLastButton: true, // Show Last button in pagination
showTotalRecords: false, // Show total records count
pageLengths: [10, 25, 50, 100], // Page length options
defaultPageLength: 10, // Default page length
maxVisiblePages: 3, // Maximum visible page numbers
sortableColumns: [], // Array of sortable column indexes (e.g., [0, 2, 3])
//enableCustomFeature: false, // New option to enable/disable custom functionality
}, options);
const table = this;
const tableBody = table.find("tbody");
const paginationContainer = $('');
const lengthSelectorContainer = $('');
const totalRecordsContainer = $('');
let currentPageLength = settings.defaultPageLength;
let currentPage = 0; // Start at page 0 (Page 1)
// Add containers dynamically
if (settings.enablePaging) table.after(paginationContainer);
if (settings.showTotalRecords) table.after(totalRecordsContainer);
if (settings.enablePageLengthSelector) table.before(lengthSelectorContainer);
// Function for Pagination
function applyPagination() {
if (!settings.enablePaging) return;
const rows = tableBody.find("tr").not(".no-records");
const totalRows = rows.length;
const totalPages = Math.ceil(totalRows / currentPageLength);
paginationContainer.empty();
// Add Previous button
if (settings.showNextPrevButtons) {
const prevButton = $('Previous');
prevButton.prop("disabled", currentPage === 0);
paginationContainer.append(prevButton);
}
// Add dynamic page buttons
const visiblePages = settings.maxVisiblePages;
let startPage = Math.max(0, currentPage - Math.floor(visiblePages / 2));
let endPage = Math.min(totalPages, startPage + visiblePages);
if (endPage - startPage < visiblePages) {
startPage = Math.max(0, endPage - visiblePages);
}
for (let i = startPage; i < endPage; i++) {
const btn = $(`${i + 1}`);
if (i === currentPage) btn.addClass("active");
paginationContainer.append(btn);
}
// Add Next and Last buttons
if (settings.showNextPrevButtons) {
const nextButton = $('Next');
nextButton.prop("disabled", currentPage === totalPages - 1);
paginationContainer.append(nextButton);
if (settings.showLastButton) {
const lastButton = $('Last');
lastButton.prop("disabled", currentPage === totalPages - 1);
paginationContainer.append(lastButton);
}
}
updatePage(rows, totalRows, totalPages);
// Pagination button click event
paginationContainer.find(".pagination-btn").on("click", function () {
const dir = $(this).data("dir");
if (dir) {
currentPage = Math.min(Math.max(0, currentPage + dir), totalPages - 1);
} else if ($(this).hasClass("last-btn")) {
currentPage = totalPages - 1;
} else {
currentPage = parseInt($(this).text(), 10) - 1;
}
updatePage(rows, totalRows, totalPages);
applyPagination(); // Reapply buttons dynamically
});
}
function updatePage(rows, totalRows, totalPages) {
const start = currentPage * currentPageLength;
const end = Math.min(start + currentPageLength, totalRows);
rows.hide().slice(start, end).show();
paginationContainer.find(".pagination-btn").removeClass("active");
paginationContainer.find(`.pagination-btn`).filter(function () {
return $(this).text() == currentPage + 1;
}).addClass("active");
if (settings.showNextPrevButtons) {
paginationContainer.find(".prev-btn").prop("disabled", currentPage === 0);
paginationContainer.find(".next-btn").prop("disabled", currentPage === totalPages - 1);
}
if (settings.showTotalRecords) {
totalRecordsContainer.text(`Showing ${start + 1}-${end} of ${totalRows} records`);
}
}
// Page Length Selector
function addPageLengthSelector() {
if (!settings.enablePageLengthSelector) return;
const selector = $('');
settings.pageLengths.forEach(length => {
const option = $(`${length} records per page`);
if (length === currentPageLength) option.prop("selected", true);
selector.append(option);
});
lengthSelectorContainer.empty().append(selector);
selector.on("change", function () {
currentPageLength = parseInt($(this).val(), 10);
currentPage = 0;
applyPagination();
});
}
// Inline Editing
function enableInlineEditing() {
tableBody.find("td").off("dblclick").on("dblclick", function () {
const currentCell = $(this);
const columnIndex = currentCell.index();
if (settings.nonEditableColumns.includes(columnIndex)) return;
const originalContent = currentCell.text();
if (currentCell.find("input, select").length > 0) return;
const cellWidth = currentCell.outerWidth();
const cellHeight = currentCell.outerHeight();
if (settings.dropdownColumns[columnIndex]) {
let dropdownHtml = ``;
settings.dropdownColumns[columnIndex].forEach(option => {
dropdownHtml += `${option}`;
});
dropdownHtml += ``;
currentCell.html(dropdownHtml);
const dropdown = currentCell.find("select");
dropdown.focus();
dropdown.on("blur change", function () {
const selectedValue = dropdown.val();
currentCell.text(selectedValue);
// Submit on blur for dropdown
submitCellData(columnIndex, selectedValue, originalContent);
});
} else {
currentCell.html(``);
const input = currentCell.find("input");
input.focus();
input.on("blur keypress", function (e) {
if (e.type === "blur" || e.which === 13) {
const newValue = input.val();
currentCell.text(newValue);
// Submit on blur for text input
submitCellData(columnIndex, newValue, originalContent);
}
});
}
});
}
// Function to handle submission of cell data
function submitCellData(columnIndex, newValue, originalValue) {
if (newValue !== originalValue) {
// Example AJAX request to submit data
$.ajax({
url: "/update-cell", // Replace with your server-side endpoint
method: "POST",
data: {
columnIndex: columnIndex,
value: newValue
},
success: function (response) {
console.log("Cell updated successfully:", response);
},
error: function (xhr, status, error) {
console.error("Error updating cell:", error);
alert("Failed to update cell. Reverting to original value.");
// Revert to original value in case of error
tableBody.find("td").eq(columnIndex).text(originalValue);
}
});
}
}
// Search
if (settings.enableSearch) {
const searchBox = $('');
table.before(searchBox);
searchBox.on("keyup", function () {
const value = $(this).val().toLowerCase();
let visibleRows = 0;
tableBody.find("tr").each(function () {
const rowText = $(this).text().toLowerCase();
const isMatch = rowText.indexOf(value) > -1;
$(this).toggle(isMatch);
if (isMatch && !$(this).hasClass("no-records")) {
visibleRows++;
}
});
// Show/hide "no records" row
if (visibleRows === 0) {
tableBody.find(".no-records").show();
} else {
tableBody.find(".no-records").hide();
}
// Reapply pagination after filtering
applyPagination && applyPagination();
});
}
// Sorting Functionality with Vertical Arrows Always Visible
if (settings.enableSorting) {
table.find("th").each(function () {
const columnIndex = $(this).index();
// Check if column is sortable
if (!settings.sortableColumns.includes(columnIndex)) {
$(this).css("cursor", "not-allowed"); // Disable cursor for non-sortable columns
return;
}
// Dynamically add the vertical arrows to each column header
if ($(this).find('.sort-arrow-container').length === 0) {
$(this).append(`
▲
▼
`);
}
// Add click event for sorting
$(this).on("click", function () {
const rows = tableBody.find("tr").get();
const isNumericColumn = $(this).hasClass("numeric");
const currentColumn = $(this);
// Check current sort direction
let isAscending = currentColumn.hasClass("asc");
// Clear previous sort classes
table.find("th").removeClass("asc desc");
// Toggle sorting direction and update classes
if (isAscending) {
currentColumn.addClass("desc");
} else {
currentColumn.addClass("asc");
}
// Sort the rows based on the current column
rows.sort(function (a, b) {
const cellA = $(a).children("td").eq(columnIndex).text();
const cellB = $(b).children("td").eq(columnIndex).text();
let comparison = 0;
if (isNumericColumn) {
comparison = parseFloat(cellA) - parseFloat(cellB);
} else {
comparison = cellA.localeCompare(cellB);
}
return isAscending ? comparison : -comparison; // Toggle ascending/descending
});
// Append sorted rows to the table body
$.each(rows, function (index, row) {
tableBody.append(row);
});
});
});
}
// Apply Pagination and Length Selector
applyPagination();
addPageLengthSelector();
enableInlineEditing();
//applyCustomFeature();
};
})(jQuery);
Подробнее здесь: [url]https://stackoverflow.com/questions/79330465/search-functionality-not-working-in-custom-plugin-developing-a-custom-plugin[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия