Перенос данных из таблицы на одной странице в форму на другой.
Я наверное опишу то, что я хочу сделать полностью, а потом опишу конкретную задачу.
Итак, есть отчёт в бумажном виде в формате таблицы. Я сканирую файнридером этот документ. На выходе получается html страница с обычной таблицей. Эти данные из таблицы нужно заполнять в форму на сайте сторонней CRM. Задача: Автоматизировать процесс заполнения формы на стороннем сайте, изначально забирая эти данные из другой страницы, которая формируется файн ридером. Я лично пока не могу понять в какую сторону черпать знания, что бы передавать данные со страницы на страницу. Думаю в сторону юзерскрипта. Буду очень признателен, если найдётся добрый человек и напишет пошаговую инструкцию того что нужно делать, а так же в какую сторону копать. |
Юзерскрипт - верное решение.
Юзерскриптом либо добавляете на страницу input:file(если результат скана у вас на компьютере), либо кроссдоменным запросом вытягиваете его с вашего сайта. Дальше чистый javascript: берём текст из полей таблицы и вставляем в поля ввода. Чтобы говорить конкретно - нужны и конкретные примеры. |
Вложений: 1
Не совсем понял зачем добавлять инпут файл.
Из конкретных вещей прикладываю архив. В нём finereader_table это пример того, что получается на выходе у файнридера. Остальное это сохранённая страница CRM. Смысл в том, что в ней нужно будет прокликивать это дерево с категориями товара, потому что колонка справа подгружается аяксом. Потом нужно брать из третьей колонки таблицы модель товара, искать её на странице CRM и вставлять в инпуты колличество товара и цену. |
На счёт автоматического прокликивания скриптом, то это я ещё спрошу. Конечно хотелось бы реализовать, но это не главное. Пока что, и если вручную кликать и автоматизировать процесс подстановки данных, уже счастье.
|
Примерно так должен выглядеть юзерскрипт(без прокликивания, ибо там многое зависит от раелизации):
var d = document; var text = 'textContent' in d.body ? 'textContent' : 'innerText'; var forEach = Array.prototype.forEach; var hash = {}; var fixedDiv = d.createElement('div'); fixedDiv.style.cssText = 'position:fixed;top:0;right:0;background:#fff;border:1px solid;z-index:99999'; var input = fixedDiv.appendChild( d.createElement('input') ); input.type = 'button'; input.onclick = readPage; input.value = 'Считать артикулы со страницы.'; input = fixedDiv.appendChild( d.createElement('label') ); input.innerHTML = 'Загрузить таблицу:'; input = input.appendChild( d.createElement('input') ); input.type = 'file'; input.onchange = readTable; input = fixedDiv.appendChild( d.createElement('input') ); input.type = 'button'; input.onclick = setData; input.value = 'Внести данные из таблицы на страницу.'; var tableDiv = fixedDiv.appendChild( d.createElement('div') ); d.body.appendChild(fixedDiv) function readPage(){ hash = {}; //очищаем список артикулов полученый с текущей страницы forEach.call( d.querySelectorAll('.CoolGridViewTable.table td:first-child'), function(td){ //заполняем список артикулов текущей страницы hash[td[text].trim()] = td.parentNode; }) console.log(hash) } function readTable(){ var reader = new FileReader(); reader.onload = function(event) { //считываем таблицу из файла var contents = event.target.result.match(/<table[\s\S]+<\/table>/); if(!contents) return console.error("Нет таблицы."); //преобразуем в код и отображаем tableDiv.innerHTML = contents[0]; }; reader.onerror = function(event) { console.error("Файл не может быть прочитан! код " + event.target.error.code); }; reader.readAsText(this.files[0]); } function setData(){ //проходимся по всем рядам загруженной таблицы forEach.call( tableDiv.querySelectorAll('td:nth-of-type(3)'), function(td){ var rowTo = hash[td[text].trim()], //получаем ряд таблицы на странице с таким артикулом rowFrom = td.parentNode; if( rowTo ) { //если ряд с таким артикулом существует var qty = parseFloat(rowFrom.cells[3][text]), //получаем кол-во в виде текста и преобразуем в число price = parseFloat(rowFrom.cells[4][text].replace(/[,\s]+/g, '')); //получаем цену в виде текста, очищаем от запятых и преобразуем в число rowTo.cells[1].click(); //кликаем по клетке дабы появились поля ввода rowTo.querySelector('input[name="qty"]').value = qty; //вносим кол-во rowTo.querySelector('input[name="price"]').value = price; //вносим цену rowTo.querySelector('a').click(); //кликаем по первой ссылке rowFrom.parentNode.removeChild(rowFrom); //удаляем из загруженной таблицы отработанную строку(если какие строки остались - значит такой артикул не найден) } }) } Могут быть всякие подводные камни связанные с задержками. По хорошему конечно надо просить это всё сделать разработчиков ваших, через внутреннюю систему.) |
Aetae,
Вы просто гуру скрипта! Мой вам низкий поклон и спасибо что откликнулись! Задача немного упростилась. Мой друг будет обрабатывать таблицу с помощью PHP на сервере и выдавать файлом js в котором будут сформированы готовые объекты с информацией из таблички. Будет что-то вроде небольшой базы данных. Я написал скрипт, который будет сверять модели из этой базы с моделями на сайте црм, куда будут заноситься данные, и вставлять их в инпуты, а потом нажимать кнопку отправить. Всё хорошо, да всё никак не могу понять как сделать правильно задержку нажатия ссылки "отправить". Долго копал в сторону setTimeout. Но она, как я понял создаёт отдельный поток, поэтому цикл будет продолжаться и заполнять поля. И во-вторых, почему-то setTimeout выполняется мгновенно, какое время я бы не поставил. Я не знаю почему. То есть как то надо останавливать цикл на время скажем 3 секунды потом нажимать на "отправить" и продолжать цикл. Но как? Привожу код: function massiv() { var get_td = document.getElementsByTagName('td'); for (var i=0; i < get_td.length; i++) { for (item in catalog) { if (get_td[i].firstChild != undefined && catalog[item].model==get_td[i].firstChild.nodeValue && catalog[item].sold == true) { get_td[i].nextSibling.click(); get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('input')[0].value=catalog[item].sold; get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('input')[1].value=catalog[item].price; get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('a')[0].click(); }; }; }; |
SokDobriy, не использовать цикл, если нужна задержка.
function massiv() { var get_td = document.getElementsByTagName('td'), out = []; for (var i=0; i < get_td.length; i++) { for (item in catalog) { if (get_td[i].firstChild != undefined && catalog[item].model==get_td[i].firstChild.nodeValue && catalog[item].sold == true) { out.push([ get_td[i].nextSibling, [ get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('input')[0], catalog[item].sold ], [ get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('input')[1], catalog[item].price ], get_td[i].nextSibling.nextSibling.getElementsByTagName('div')[1].getElementsByTagName('a')[0] ]) }; }; }; var i = out.length; (function re(){ if(!i--) return; out[i][0].click(); out[i][1][0].value = out[i][1][1]; out[i][2][0].value = out[i][2][1]; out[i][3].click(); setTimeout(re, 3000) }()) };Примерно так. Можно само собой и в один проход, но мне лень думать над логикой рекурсии.) P.S. Вообще на вашем месте яб изучил код самой crm и обращался напрямую к её функциям. |
Aetae,
Вы спаситель! |
Aetae,
А почему нельзя остановить цикл, а потом продолжить? Мне просто для себя что бы понять. |
SokDobriy, js однопоточный язык. Остановка выполнения скрипта в js равносильна остановке всего, т.е. зависанию браузера(страницы).
В новых версиях js есть подвижки на тему прозрачной асинхронности, но суть от этого не меняется. |
Часовой пояс GMT +3, время: 16:25. |