indexedDB – это что-то среднее между локальным хранилищем в браузере и полноценной СУБД. У indexedDB есть индексация с авто инкрементом. Данные сохраняются в виде объекта, что весьма удобно. indexedDB имеет несложный синтаксис, но тем не менее излагать сухую теорию я не стану, т.к. это только запутает начинающего. В место этого объясню принципы работы с indexedDB на конкретном примере. indexedDB подойдет для хранения каких-либо настроек и небольшого объема информации. А вот для крупных web-приложений indexedDB не подойдёт из-за ограничений. Приступим к написанию приложения, которое будет представлять из себя сохранение и вывод данных пользователя (имя, фамилия, e-mail и телефон). Для начала создайте в папке три файла: index.html, style.css и app.js.
Теперь откройте файл index.html и создайте в нем разметку.
После чего создадим оформление в стилях.
Откройте файл style.css.
Для начала уберем все отступы по умолчанию и назначим цвет фона страницы.
Зададим оформление текстовым полям.
Оформим кнопки.
Зададим оформление таблице .
Так же оформим ячейки таблицы.
Оформим блок с текстовыми полями для добавления записи и кнопки "очистить".
Наше оформление готово и можно открыть index.html в браузере, чтобы посмотреть на то, что у нас получилось.
Теперь можно перейти к написанию кода. Откройте файл app.js. Первым делом создадим конструктор объекта Users, а также создадим обработчик события load().
Теперь создадим три переменные, в которых сохраним ссылки на наши элементы. Переменная add – это наша кнопка, по которой будут добавляться новые записи в базу, переменная cleer – это кнопка, по которой мы будем очищать нашу базу, переменная tbl – это див, в который мы будем встраивать полученные из базы данные.
В объект Users добавим два свойства: db – ему мы присвоим null, и request–здесь мы сохраним подключение к базе. Открыть базу можно при помощи метода open объекта indexedb. Этот метод принимает в качестве первого параметра имя базы данных, а в качестве второго параметра номер версии.
Определим, какие действия мы будем совершать с базой данных:
1. Добавлять записи в базу;
2. Удалять записи из базы;
3. Изменять данные в базе;
4. Получать данные из базы и отображать их на экране;
5. Очищать базу данных.
Для каждого действия создадим отдельный метод в объекте Users:
1. add() – метод для добавления новой записи в базу;
2. load() – метод для получения записей из базы;
3. del() – метод для удаления записи из базы;
4. update() – метод для изменения существующей записи в базе;
5. cleer() – метод для очистки базы от записей.
Следующим шагом создадим экземпляр объекта Users.
У объекта indexedDB есть три собственных события:
1. onupgradeneeded – это событие возникает всего один раз, в момент создания базы данных;
2. onsuccess – это событие возникает в том случае, если обращение к базе данных прошло успешно;
3. onerror – это событие возникает в том случае, если при обращении к базе данных произошла какая-то ошибка.
Создадим обработчик события onupgradeneeded, в котором присвоим свойству db ссылку на открытую базу данных. Затем проверим, существует ли таблица users и, если не существует, создадим её. У таблицы создадим свойство id с автоинкрементном ({ keyPath: 'id', autoIncrement: true }). Также создадим индекс по полю name и сделаем его не уникальным ({ unique: false }).
Теперь перейдем к созданию обработчика события onsuccess. Выведем сообщение в консоль о том, что подключение прошло успешно. Также присвоим свойству db ссылку на открытую базу данных, получим данные из базы и отобразим их в виде таблицы методом load().
Создадим обработчик события onerror, в котором выведем в консоль сообщение об ошибке подключения к базе данных.
Создадим два обработчика события клик. В первом случае будем обрабатывать событие клика по кнопке с id add (кнопка для добавления новой записи), вызвав метод add(). А во втором случае обработаем клик по кнопке “очистить”, вызвав метод cleer().
Перейдем к обработке события по нажатию на кнопку удаления записи. В данном случае мы не можем отобрать кнопки и навесить на них событие клик из-за того, что в момент загрузки страницы данные из базы ещё не загружены и кнопок просто нет. Они будут созданы динамически в момент вызова метода load. Нам придется воспользоваться делегированием события. Для этого мы повесим событие на див с классом “tbl-body” и при возникновении события проверим имя тега элемента, на котором сработало событие. Если имя “BUTTON” – мы делаем вывод, что нажата кнопка. После чего мы вызываем метод del() и получаем атрибут data-id элемента, на котором был произведен клик. Приводим его к числу при помощи parseIint() и передаем в метод del() в качестве параметра.
Для того чтобы было легко изменять данные при создании элементов, в которых эти данные будут содержаться, мы добавим атрибут editable и присвоим ему значение true. В этом случае данные в элементах станут редактируемыми, т.е. элемент div превратится в подобие многострочного текстового поля textarea. Поэтому мы будем обрабатывать событие keyup. Здесь мы снова вынуждены применить делегирование, т.к. элементы с данными создаются динамически. В первую очередь, сохраним ссылку на элемент в переменной self, а затем проверим, является ли элемент, на котором произошло событие, дивом. Если это так – проверим, какая кнопка была нажата. Дело в том, что если мы будем вносить изменения в базу после каждого нажатия, это будет не целесообразно. Например, у нас есть имя из 10 символов. Чтобы его заменить, мы 10 раз обратимся к базе. Будет лучше, если мы перезапишем данные по нажатию кнопки ENTER. Для этого мы проверим, равен ли код нажатой клавиши тринадцати, если это так, то мы делаем вывод что нажата кнопка ENTER. В этом случае мы удалим образовавшийся перевод строки методом replace() и вызовем метод update(), передав в него ссылку на элемент. После чего уберем фокус с редактируемого элемента.
Займёмся нашими методами. В методе cleer() мы вызовем метод deleteDatabase() объекта indexedDB и передадим в него имя нашей базы, тем самым удалив её. После чего обновим страницу методом reload().
Откроем методом transaction() таблицу users. У метода два параметра: в первом параметре передается массив с именами таблиц, которые надо открыть (в нашем случае таблица одна). А вторым параметром передаём режим открытия таблицы (в нашем случае “readonly” – на чтение). Получим данные из таблицы методом objectStore() и сохраним в переменной store. Создадим две переменные (div и btn) и сохраним указатель на элемент с классом tbl-body.
Получим первую строку из базы методом openCursor() и обработаем событие onsuccess, которое наступит, если строка получена успешно. В этом случае присвоим переменной cursor результат выполнения метода. Далее проверим, есть ли данные в переменной cursor. Если есть, то создадим элемент div, создадим у элемента атрибут contenteditable и присвоим ему значение true. Создадим атрибут data-id и присвоим ему в качестве значения id, полученной из базы строки. Также создадим атрибут data-value и присвоим ему имя соответствующего поля из базы. Поместим в элемент текст, взятый из поля name базы и методом appendChild() встроим ячейку таблицы.
Точно так же поступим и с другими полями нашей таблицы.
Создадим последнюю ячейку таблицы, но в место текста из базы встроим в неё кнопку, у которой также будет атрибут data-id. Методом continue() осуществим переход к следующей записи в базе.
Перейдем к методу add(). Создадим объект users со свойствами: name, family, email, phone и присвоим каждому свойству текст из соответствующего текстового поля. Откроем таблицу (в данном случае режим будет readwrite, т.е. для чтения и записи). Методом add() объекта indexedDB запишем объект user в базу. Если данные успешно записались, выведем соответствующее сообщение в консоль и перезагрузим страницу. Если при сохранении возникла ошибка, выведем в консоль сообщение об ошибке.
Теперь займёмся удалением записей. Откроем таблицу для записи. Методом delete удалим строку под номером id, который мы передали в метод. Если удаление прошло успешно, выведем сообщение в консоли. Затем отберем все элементы с атрибутом data-id = id и удалим в цикле все эти элементы методом removeChild().
Осталось только описать метод изменения данных. Переменной text присвоим текст из редактируемого элемента. Переменной id присвоим число из атрибута data-id. Переменной value присвоим имя из атрибута data-value. Откроем базу для чтения и записи. В переменную store получим записи из базы. Методом get() получим запись под номером id и присвоим это все переменной result. В условии if проверяем, какое поле мы изменяем и, в соответствии с условием, меняем значение поля на текст из редактируемого элемента. Методом put() записываем измененные данные в базу. Затем выводим соответствующее сообщение в консоль исходя из того, успешно была проведена замена данных или нет.
На этом всё. Можете протестировать приложение в браузере.