Как сделать редактируемую таблицу в php
По просьбам трудящихся — исходники. В архиве .sql и .php — всё в одном, и вывод и обработчик, всё с подробными комментариями.
Привет тебе дорогой читатель, сегодня мы немного поговорим об инлайновом редактировании данных в таблицах без перезагрузки страницы (inline edit ajax).
Как я уже сказал, передо мной встала задача редактирования данных в таблицах. После непродолжительных поисков нашел подходящий вариант, который не использует дополнительные плагины и библиотеки кроме самой jQuery. А таких на самом деле вагон и целая тележка и у каждого есть свои преимущества и недостатки. Один из самых неплохих по функционалу — jqGrid, но о нём мы поговорим в следующий раз.
Представим, что наши данные, по умолчанию, хранятся в базе. В моём примере это будет MySql, обновляться они будут с помощью JS и PHP по технологии AJAX.
Итак обсудим то, что у нас имеется, и то, что мы хотим получит в итоге
Исходные данные:
ТаблицЫ с данными, которые генерируются на PHP, запросом из нашей базы данных.
Допустим у нас есть две таблицы: клиенты (clients) и сотрудники (workers)
Поля наших таблиц на самом деле неважно какие, но возьмём для примера такие:
- id — первичный уникальный ключ с авто инкрементом.
- firstname — имя сотрудника или клиента
- lastname — фамилия сотрудника или клиента
- phone — телефон сотрудника или клиента
Необходимый результат:
Возможность редактирования всех полей всех таблиц без перезагрузки страницы.
Что нам для этого потребуется?
- jquery.js — jQuery javascript framework
- Заполненные таблицы в БД
- Азы PHP + JS
- Смекалка
Приступим к выполнению нашей задачи
Первым делом подключаем необходимую библиотеку (jQuery) внутри тегов . Я обычно использую самую последнюю версию, чтобы поддерживать актуальность знаний о возможностях этой чудно библиотеки и подключаю её минифицированную версию из репозитория Google Hosted Library. На момент написания статьи актуальная версия 1.9.1, её и подключаем.
Далее присваиваем нашей таблице уникальный идентификатор id, который соответствует названию таблицы в базе (это важно!).
Выводим все строки циклом и присваиваем строкам класс — edit, класс с названием столбца в БД и числовой класс с идентификатором строки в БД.
Имя | Фамилия | Телефон |
---|---|---|
'.$rows['firstname'].' | '.$rows['lastname'].' | '.$rows['phone'].' |
Далее нам необходим скрипт, который позволит редактировать данные в таблице. Как он работает, я опишу комментариями к каждой строке ниже в коде
Итак форма для редактирования текста у нас появилась, что же мы с ней будем делать дальше?
Теперь нам необходимо сохранять введенные данные при каком то событии, я приведу пример сохранения данных при нажатии Enter.
Вам остаётся только обработать полученные данные в файле update_cell.php, все необходимые переменные у Вас есть, пусть это будем вашей самостоятельной работой.
Таким образом мы получаем компактный, универсальный скрипт для быстрого редактирования любых табличных данных.
Если кому нужны будут полные исходники моего варианта скрипта — пишите в коменты.
Дополнение №1
В версии jQuery 1.9.1 отключен метод .live. Вместо него нужно использовать метод .on, сравните синтаксис сами:
Постановка задачи
Покажем наглядно, на странице Учебный пример редактирования таблицы MySQL в браузере. Всплывающее на этой странице окно для редактирования – savecell.php, а необходимые для работы Javascript-функции – в файле tableedit.js. Описание работы скриптов PHP на сервере выходит за рамки этой статьи (за небольшим исключением – о генерации возвращаемого сервером Javascript кода упомянуть придётся).
Принципиальная схема редактирования таблицы в браузере
В нашем случае к странице tableedit.htm присоединён ещё сортировщик HTML таблиц. Всего используется 4 файла Javascript (в сумме 11Кб): ir2.js (общая библиотека функций), dom-javascript.js, tabsort.js, tableedit.js.
Доступ к документу в окне iframe
То есть, если мы находим фрейм по формуле myframe=window.frames[0] , мы не можем потом в сценарии Javascript использовать выражения вида myframe.style.display="none" . Нужно всё-таки получать доступ к фрейму через editframe=document.getElementById("edit") . Но после этого возникнет сложность с доступом к back – документу, вложенному во фрейм. Использовав наш DOM-инспектор (для этого пришлось подключить его к странице и сделать форму выбора режима) и пощёлкав клавишами Ctrl+Alt+I в разных браузерах, мы обнаружили у элемента iframe свойства contentDocument и contentWindow (а в некоторых браузерах оба эти свойства). Свойство contentWindow встречалось чаще всего, поэтому его поставили на первое место. Получилась формула:
Последнее свойство фрейма (document) не встретилось нам ни в одном браузере, где не было бы уже contentWindow. Но, после проверки наших гипотез в Гугле, мы решили эту конструкцию на всякий случай добавить тоже (возможно, она нужна для старых версий какого-нибудь ИЕ).
Мы отчасти усложнили себе жизнь, отказавшись от вложения iframe в редактируемую ячейку таблицы. Теперь его надо как-то очень точно позиционировать, чтобы он по возможности не заслонял ячейку и сам был виден весь. Да ещё размер его желательно сделать как раз по содержимому. То есть размер элемента iframe должен быть таким, чтобы его документ был виден без прокрутки (но не больше). После того как мы получили элемент iframe (editframe) и внешний документ, привязанный к этому элементу (editdoc), вычислить размеры оказалось несложно. Только надо, чтобы в момент вычислений, элемент был виден на странице (его свойство style.display не должно быть "none"):
В первый момент отображения на странице элемент body в нашем вложенном документе может отображаться не весь, а с прокруткой, поэтому для получения всей ширины body (и видимой, и невидимой), используем свойство scrollWidth. Так же и с высотой. Идею parseInt (как и много других полезных мелочей) мы подсмотрели на сайте javascript.ru. Очень разумная предосторожность (вдруг scrollWidth в каком-нибудь браузере окажется равным "450px").
После выяснения left-top (позиции от начала документа) редактируемой ячейки и высоты (offsetHeight) и зная высоту формы редактирования (вложенной в iframe), можно принимать решение, выше или ниже ячейки показывать форму. Это уже арифметика. Для неё, правда, понадобится (чуть не забыли!) ещё расстояние до верхнего края видимой части (а не всего) документа. Тут, чтобы не мудрствовать долго, мы использовали не край элемента (ячейки), а место, куда щёлкнула мышь. Потому что оно (это свойство), одинаково во всех известных нам браузерах – это свойство события event.clientY.
Общая схема нахождения места фрейма получилась такая:
- Измеряем расстояние от места щелчка до верхнего края окна.
- Если туда по высоте влезает наш iframe с формой редактирования, помещаем его на 20px выше верхнего края ячейки.
- Если не влезает, помещаем его на 20px ниже нижнего края ячейки.
А помещать нужно, используя расстояние не от края окна, а от верхней границы всего документа (неважно, видна она или нет); как раз для этого и приходится вычислять абсолютную высоту элемента на странице. Полностью код нашей функции showframe() находится в файле tableedit.js.
Если редактируемая таблица будет узенькая, посередине экрана с большими полями, всплывающая форма редактирования будет сильно смещена влево. Поэтому правильнее, конечно, левую координату формы тоже вычилять функцией getOffsetSum(). Ну, мы оставили это как есть для наглядности (почувствовать разницу).
Некоторые особенности SQL запросов
- пользователь отправил на сервер текст без изменений;
- пользователь изменил только регистр букв;
- пользователь изменил только тэги HTML.
Во всех этих случаях обновления не произойдёт, и форма редактирования останется висеть на странице. Последний пункт, впрочем, к MySQL-серверу отношения не имеет (его выполняет PHP). Регистр букв – дело настраиваемое (в принципе, на SQL-сервере можно менять запросом только регистр букв), администраторы БД могут менять этот пункт по своему усмотрению.
Веб-сайт в одной странице: самый короткий учебник HTML
Комментарии
Данный пример почему – то не корректно работает в хроме. А именно, не отрисовывается рамка и не всплывает окно редактирования
Вообще эта статья больше не о PHP, а о том, как организовать интерфейс в браузере для редактирования таблиц в БД.
И еще, в этом файле (savecell.php) идет речь вначале, что необходим "config.php"; а его нигде нету. – и где происходит соединение с БД? Чтобы опробовать метод нужно создать БД "betontest" с 4-мя полями? – и их нужно заполнить или нет? (они же есть в таблице, может опишите еще какие атрибуты у полей таблицы должны быть?)
Материал не полный ((
А я сохранил файл: savecell.php
и выдает ошибку при обработке:
Fatal error: Call to undefined function cacheh() in C:\Program Files\xampp\htdocs\222\savecell.php on line 52
Доброго время суток!А нельзя исходники учебной таблицы выложить? а то не сильно понятно как работает.
Выбор и удаление нескольких записей
При создании админки часто встает задача выбора или удаления сразу нескольких записей из базы данных. Для этого обычно создается HTML-форма с набором флажков:
Скрипт, формирующий список элементов checkbox формы, и удаляющий выбранные записи может выглядеть так:
Массив $_POST['item'] содержит ID всех отмеченных checkbox-ов (не отмеченные на сервер не передаются). Запрос к БД на удаление выглядит так:
Если стоит задача не удаления записей, а их выборки, то вместо оператора DELETE следует использовать оператор SELECT .
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
Редактирование и удаление записи из таблицы MySql
PHP скрипт с запросом на вывод, редактирование или удаление записей из базы данных MySql.
Скрипт выводит в html таблицу записи из БД. Как вывести записи в таблицу см. в отдельной статье.
Напротив каждой записи выводятся ссылки Копирование и Удаление.
При нажатии кнопки Редактировать, на этой же странице открывается форма редактирования элемента.
PHPExcel позволяет производить импорт и экспорт данных в excel. Применять различные стили оформления к отчетам. В общем, все на высоте. Даже есть возможность работы с формулами. Только необходимо учитывать, что вся работа (чтение и запись) должна вестись в кодировке utf-8.
Установка библиотеки
С помощью библиотеки PHPExcel можно записывать данные в следующие форматы:
- Excel 2007;
- Excel 97 и поздние версии;
- PHPExcel Serialized Spreadshet;
- HTML;
- PDF;
- CSV.
Импорт данных из PHP в Excel
Рассмотрим пример по формированию таблицы умножения.
Рассмотрим еще на примере три полезные инструкции:
- $sheet->getColumnDimension('A')->setWidth(40) – устанавливает столбцу “A” ширину в 40 единиц;
- $sheet->getColumnDimension('B')->setAutoSize(true) – здесь у столбца “B” будет установлена автоматическая ширина;
- $sheet->getRowDimension(4)->setRowHeight(20) – устанавливает четвертой строке высоту равную 20 единицам.
Также обратите внимание на следующие необходимые для работы с отчетом методы:
- Методы для вставки данных в ячейку:
- setCellValue([$pCoordinate = 'A1' [, $pValue = null [, $returnCell = false]]]) — принимает три параметра: координату ячейки, данные для вывода в ячейку и третий параметр эта одна из констант типа boolean: true или false (если передать значение true, то метод вернет объект ячейки, иначе объект рабочего листа);
- setCellValueByColumnAndRow([$pColumn = 0 [, $pRow = 1 [, $pValue = null [, $returnCell = false]]]]) — принимает четыре параметра: номер столбца ячейки, номер строки ячейки, данные для вывода в ячейку и четвертый параметр действует по аналогии с третьим параметром метода setCellValue().
- getCell([$pCoordinate = 'A1']) — принимает в качестве параметра координату ячейки;
- getCellByColumnAndRow([$pColumn = 0 [, $pRow = 1]]) — принимает два параметра в виде номеров столбца и строки ячейки.
Как мы видим, вышеприведенные методы являются парными. Поэтому мы можем работать с ячейками используя строковое или числовое представление координат. Что конечно же является дополнительным преимуществом в работе.
Оформление отчета средствами PHP в Excel
Очень часто возникает необходимость выделить в отчете некоторые данные. Сделать выделение шрифта или применить рамку с заливкой фона для некоторых ячеек и т.д. Что позволяет сконцентрироваться на наиболее важной информации (правда может и наоборот отвлечь). Для этих целей в библиотеке PHPExcel есть целый набор стилей, которые можно применять к ячейкам в excel. Есть конечно в этой библиотеке небольшой “минус” – нельзя применить стиль к нескольким ячейкам одновременно, а только к каждой индивидуально. Но это не создает дискомфорта при разработке web-приложений.
Назначить стиль ячейке можно тремя способами:
- Использовать метод applyFromArray, класса PHPExcel_Style. В метод applyFromArray передается массив со следующими параметрами:
- fill — массив с параметрами заливки;
- font — массив с параметрами шрифта;
- borders — массив с параметрами рамки;
- alignment — массив с параметрами выравнивания;
- numberformat — массив с параметрами формата представления данных ячейки;
- protection — массив с параметрами защиты ячейки.
- pCellStyle – данный параметр является экземпляром класса PHPExcel_Style;
- pRange – диапазон ячеек.
Заливка
Значением параметра fill является массив со следующими необязательными параметрами:
- type — тип заливки;
- rotation — угол градиента;
- startcolor — значение в виде массива с параметром начального цвета в формате RGB;
- endcolor — значение в виде массива с параметром конечного цвета в формате ARGB;
- color — значение в виде массива с параметром начального цвета в формате RGB.
Или можно использовать следующие методы:
Вставка изображений
Довольно редко, но бывает полезным произвести вставку изображения в отчет. Это может быть логотип, схема и т.д. Для работы нам понадобятся следующие методы:
- setPath([$pValue = '', [$pVerifyFile = true]]) — данный метод принимает два параметра. В качестве первого параметра указывается путь к файлу с изображением. А второй параметр имеет смысл указывать, если необходимо осуществлять проверку существования файла (может принимать одно из значений true или false).
- setCoordinates([$pValue = 'A1'])) — принимает на вход один параметр в виде строки с координатой ячейки.
- setOffsetX([$pValue = 0]) — принимает один параметр со значением смещения по X от левого края ячейки.
- setOffsetY([$pValue = 0]) — принимает один параметр со значением смещения по Y от верхнего края ячейки.
- setWorksheet([$pValue = null, [$pOverrideOld = false]]) — этот метод принимает на вход два параметра. Первый является обязательным, а второй нет. В качестве первого параметра указывается экземпляр класса PHPExcel_Worksheet (текущий активный лист). Если в качестве значения второго параметра передать true, то если лист уже был назначен ранее – произойдет его перезапись и соответственно изображение удалится.
Код демонстрирующий алгоритм вставки изображения приведен ниже:
Вот так выглядит отчет со вставленным изображением:
Шрифт
В качестве значения параметра font указывается массив, который содержит следующие необязательные параметры:
- name — имя шрифта;
- size — размер шрифта;
- bold — выделять жирным;
- italic — выделять курсивом;
- underline — стиль подчеркивания;
- strike — перечеркнуть;
- superScript — надстрочный знак;
- subScript — подстрочный знак;
- color — значение в виде массива с параметром цвета в формате RGB.
Или воспользоваться следующими методами:
Рамка
В качестве значения параметра borders указывается массив, который содержит следующие необязательными параметры:
- тип рамки — (top|bootom|left|right|diagonal|diagonaldirection);
- style — стиль рамки;
- color — значение в виде массива с параметром цвета в формате RGB.
Так же можно прибегнуть к использованию следующих методов:
$PHPExcel_Style->getBorders()->getLeft()->applyFromArray(array(‘style’ =>PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080')));
$PHPExcel_Style->getBorders()->getRight()->applyFromArray(array(‘style’ =>PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080')));
$PHPExcel_Style->getBorders()->getTop()->applyFromArray(array(‘style’ =>PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080')));
$PHPExcel_Style->getBorders()->getBottom()->applyFromArray(array(‘style’ =>PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080')));
$PHPExcel_Style->getBorders()->getDiagonal()->applyFromArray(array(‘style’ => PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080')));
$PHPExcel_Style->getBorders()->setDiagonalDirection(array(‘style’ =>PHPExcel_Style_Border::BORDER_DASHDOT,’color’ => array(‘rgb’ => ’808080'))).
Выравнивание
Значением параметра alignment является массив, который принимает на вход четыре необязательных параметра:
- horizontal — константа горизонтального выравнивания;
- vertical — константа вертикального выравнивания;
- rotation — угол поворота текста;
- wrap — разрешить перенос текста;
- shrinkToFit — изменять ли размер шрифта при выходе текста за область ячейки;
- indent — отступ от левого края.
Или использовать следующие методы:
Формат представления данных
Параметр numberformat представляет собой массив, который включает только один параметр: code — формат данных ячейки.
А можно и воспользоваться методом:
Защита ячеек
В качестве значения параметра protection выступает массив, который содержит два необязательных параметра:
- locked — защитить ячейку;
- hidden — скрыть формулы.
Или использовать следующие методы:
Теперь мы знаем, какие есть настройки стилей и какие присутствуют параметры у каждого стиля. Сейчас мы к ячейкам таблицы применим стиль оформления, но проделаем это тремя способами. Первый способ заключается в создании массива настроек, который в качестве параметра мы передадим в метод applyFromArray, класса PHPExcel_Style.
Далее мы применим созданный нами стиль к ячейкам excel.
Сейчас применим тот же стиль, но используя другую методику.
Вот что у нас получилось:
Для получения данных о стиле конкретной ячейки необходимо использовать один из следующих методов, который вернет экземпляра класса PHPExcel_Style:
- getStyleByColumnAndRow([$pColumn = 0 [, $pRow = 1]]) – применяется если требуется обратиться к ячейке по числовым координатам. Методу необходимо передать два параметра в виде номеров столбца и строки ячейки;
- getStyle([pCellCoordinate = 'A1']) – используется для обращения по строковой координате ячейки. Методу требуется передать один параметр, это строковое представление координаты.
А теперь рассмотрим третий способ назначения стиля ячейкам путем дублирования стиля. Пример использования представлен ниже (предполагается, что к ячейке “B2” применен некий стиль и мы его хотим продублировать для диапазона ячеек “F2:F10”):
Добавление комментариев
Я думаю, что не часто кто-то пользуется возможностью добавления комментариев к ячейкам, но это сугубо мое личное мнение, однако такая возможность имеется. Добавить комментарий к ячейке довольно просто, что видно из примера ниже:
Следует заметить, что при повторном вызове метода createTextRun() новый комментарий добавится к уже существующему, а не заменит его. Следует отметить, что данный метод возвращает объект класса PHPExcel_RichText_Run, у которого имеются методы для установки и получения параметров шрифта:
- getFont() – возвращает объект класса для работы со шрифтами PHPExcel_Style_Font.
- setFont([$pFont = null]))]) – данному методу требуется передать в качестве параметра объект класса PHPExcel_Style_Font.
Вот какой комментарий мы должны получить:
Вставка ссылки
Вставка ссылок в ячейку тоже не вызывает каких-либо затруднений, что можно видеть из нижеописанного примера:
Чтение данных из Excel
Формировать отчеты и применять к ним стили это конечно отлично. Но на этом возможности библиотеки PHPExcel не заканчиваются. Ну что же, посмотрим на что она еще способна. А способна она еще и читать данные из файлов формата *.xls / *.xlsx.
С помощью библиотеки PHPExcel можно читать следующие форматы:
- Excel 2007;
- Excel 5.0/Excel 95;
- Excel 97 и поздние версии;
- PHPExcel Serialized Spreadshet;
- Symbolic Link;
- CSV.
Для работы нам понадобятся объекты двух классов:
- PHPExcel_Worksheet_RowIterator – используется для перебора строк;
- PHPExcel_Worksheet_CellIterator – используется для перебора ячеек.
Для демонстрации выведем данные из таблицы с информацией об автомобилях.
Пример чтения файла представлен ниже:
Первый вариант
Второй вариант
В первом варианте мы производим чтение данных, из ячеек используя итераторы. А во втором, мы используем индексную адресацию для обращения и получения данных из ячеек листа. Получить данные о количестве строк и столбцов, можно воспользовавшись следующими методами класса PHPExcel_Worksheet:
- getHighestColumn() – возвращает символьное представление последнего занятого столбца в активном листе. Обратите внимание: не индекс столбца, а его символьное представление (A, F и т.д.);
- getHighestRow() – возвращает количество занятых строк в активном листе.
Другие полезные методы
Возможностей по работе с отчетами формата excel с использованием PHP как мы видим, достаточно много. Но мы рассмотрим еще несколько полезных методов, которые могут оказаться весьма полезны в работе:
- getMergeCells() – с помощью данного метода принадлежащего классу PHPExcel_Worksheet можно получить информацию обо всех объединенных ячейках в листе;
- setPreCalculateFormulas([$pCellStyle = true]) – данный метод необходимо использовать если требуется произвести расчет формул в листе (он имеется у двух классов: PHPExcel_Writer_Excel5 и PHPExcel_Writer_Excel2007). В рассматриваемый метод передается параметр типа boolean: true или false (если передать значение true, то расчет формул произойдет перед сохранением файла автоматически, иначе расчета формул не последует). Использование данного метода может оказаться полезным если созданный файл потребуется загрузить, к примеру на Google Drive. Ведь в таком случае расчет формул не будет произведен автоматически указанным сервисом и здесь вся ответственность ложиться на нас;
- stringFromColumnIndex([$pColumnIndex = 0]) – данный метод позволяет определить по номеру столбца его символьное представление, для этого в качестве параметра необходимо передать его номер;
- columnIndexFromString([$pString = 'A']) – с помощью данного метода можно определить номер столбца по его символьному представлению, для этого в качестве единственного параметра необходимо передать его обозначение.
Примечание: Методы stringFromColumnIndex и columnIndexFromString примечательны тем, что их можно использовать без создания объекта класса. Пример использования представлен ниже:
С помощью продемонстрированных возможностей, можно формировать и считывать любые отчеты в виде файлов, формата excel. А также были продемонстрированы почти все возможные методы для работы со стилями.
Читайте также: