class Viewer{ constructor(){ // Здесь данные хранятся this.data = null; } /** * Ищем элементы и ставим для них слушатели */ init(){ [this.loadBtn, this.saveBtn, this.view, this.empty, this.addRowBtn] = document.querySelectorAll('#load, #save, #addRow, #view, #empty'); this.loadBtn.addEventListener('change', this.loadFile.bind(this)); this.addRowBtn.addEventListener('click', this.addRow.bind(this)); this.saveBtn.addEventListener('click', this.saveData.bind(this)); } /** * Если файл выбран, пробуем читать и парсить из JSON * Формат файла: [{id: Number, value: String}...] * * @param {Event} e Объект события выбора файла */ loadFile(e){ let file = e.target.files[0]; if(file === undefined) return; let fr = new FileReader(); fr.onload = r => { try{ this.data = JSON.parse(fr.result); if(!Array.isArray(this.data)) this.data = []; }catch(e){ throw new Error('The file is broken!'); } this.insert(); } fr.readAsText(file); } /** * Вставляем данные в таблицу */ insert(){ let result = ''; this.data.forEach(e => { if(!e.id || !e.value) return; result += `<tr><td>${+e.id}</td><td>${e.value}</td></tr>`; }); if(result === '') result = `<tr id='empty'><td rowspan='100%' align='center'>Пусто</td></tr>`; this.view.innerHTML = '<tr><th>ID</th><th>Value</th></tr>' + result; } /** * Добавляем рандомные данные */ addRow(){ if(this.data === null) return; let [ids, wordsLen] = this.data.reduce((a, e) => a[0].push(e.id) && a[1].push(e.value.length) && a, [[], []]), id = 0, value = '', alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'; // Длина новой строки - от 1-го до средней длины строк (или 20, если длина большая) wordsLen = this.rand(1, Math.min(+wordsLen.reduce((a, e) => a += e, 0) / Math.round(wordsLen.length), 20)); // Ищем уникальный ID // Если за 10 циклов на находим - плюём на уникальность и выходим let f = 0; do{ id = this.rand(); f++; if(f === 10) break; }while(ids.includes(id)) // Из алфавита вырезаем случайную букву wordsLen раз for(let i = 0; i < wordsLen; i++){ value += alphabet.substr(this.rand(0, alphabet.length - 2), 1); } // Обновляем массив данных this.data.push({ id: id, value: value }); this.view.innerHTML += `<tr><td>${id}</td><td>${value}</td></tr>`; } rand(min = 0, max = 999){return Math.floor(Math.random() * (max - min + 1)) + min;} /** * Сохранение данных * * @param {Event} e Объект события клика */ saveData(e){ if(this.data === null) return; // Красиво превращаем данные в строку let data = JSON.stringify(this.data, null, 2), link = document.createElement('A'), filename = 'Data.json'; link.setAttribute('href', 'data:application/octet-stream,' + encodeURIComponent(data)); link.setAttribute('download', filename); link.style.display = 'none'; document.body.appendChild(link); link.click(); link.remove(); } } let viewer = new Viewer(); document.addEventListener('DOMContentLoaded', viewer.init.bind(viewer))
<input type='file' id='load' value='Загрузить данные' /> | <input type='button' id='save' value='Сохранить данные' /><hr /> <table id='view'> <tr><th>ID</th><th>Value</th></tr> <tr id='empty'><td colspan='100%' align='center'>Пусто</td></tr> </table> <hr /> <input type='button' id='addRow' value='Добавить строку' />