16.11.2014, 22:29
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
Перенос данных из таблицы на одной странице в форму на другой.
Я наверное опишу то, что я хочу сделать полностью, а потом опишу конкретную задачу.
Итак, есть отчёт в бумажном виде в формате таблицы. Я сканирую файнридером этот документ. На выходе получается html страница с обычной таблицей. Эти данные из таблицы нужно заполнять в форму на сайте сторонней CRM.
Задача: Автоматизировать процесс заполнения формы на стороннем сайте, изначально забирая эти данные из другой страницы, которая формируется файн ридером.
Я лично пока не могу понять в какую сторону черпать знания, что бы передавать данные со страницы на страницу. Думаю в сторону юзерскрипта.
Буду очень признателен, если найдётся добрый человек и напишет пошаговую инструкцию того что нужно делать, а так же в какую сторону копать.
|
|
16.11.2014, 22:37
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,586
|
|
Юзерскрипт - верное решение.
Юзерскриптом либо добавляете на страницу input:file(если результат скана у вас на компьютере), либо кроссдоменным запросом вытягиваете его с вашего сайта.
Дальше чистый javascript: берём текст из полей таблицы и вставляем в поля ввода.
Чтобы говорить конкретно - нужны и конкретные примеры.
__________________
29375, 35
|
|
16.11.2014, 23:43
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
Не совсем понял зачем добавлять инпут файл.
Из конкретных вещей прикладываю архив. В нём finereader_table это пример того, что получается на выходе у файнридера. Остальное это сохранённая страница CRM. Смысл в том, что в ней нужно будет прокликивать это дерево с категориями товара, потому что колонка справа подгружается аяксом. Потом нужно брать из третьей колонки таблицы модель товара, искать её на странице CRM и вставлять в инпуты колличество товара и цену.
|
|
16.11.2014, 23:46
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
На счёт автоматического прокликивания скриптом, то это я ещё спрошу. Конечно хотелось бы реализовать, но это не главное. Пока что, и если вручную кликать и автоматизировать процесс подстановки данных, уже счастье.
|
|
17.11.2014, 16:33
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,586
|
|
Примерно так должен выглядеть юзерскрипт(без прокликивания, ибо там многое зависит от раелизации):
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); //удаляем из загруженной таблицы отработанную строку(если какие строки остались - значит такой артикул не найден)
}
})
}
Могут быть всякие подводные камни связанные с задержками.
По хорошему конечно надо просить это всё сделать разработчиков ваших, через внутреннюю систему.)
__________________
29375, 35
Последний раз редактировалось Aetae, 17.11.2014 в 16:41.
|
|
28.11.2014, 00:42
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
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, 28.11.2014 в 00:51.
|
|
28.11.2014, 03:11
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,586
|
|
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 и обращался напрямую к её функциям.
__________________
29375, 35
Последний раз редактировалось Aetae, 28.11.2014 в 03:16.
|
|
28.11.2014, 04:02
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
Aetae,
Вы спаситель!
|
|
28.11.2014, 04:04
|
Интересующийся
|
|
Регистрация: 16.11.2014
Сообщений: 29
|
|
Aetae,
А почему нельзя остановить цикл, а потом продолжить? Мне просто для себя что бы понять.
|
|
28.11.2014, 04:41
|
|
Тлен
|
|
Регистрация: 02.01.2010
Сообщений: 6,586
|
|
SokDobriy, js однопоточный язык. Остановка выполнения скрипта в js равносильна остановке всего, т.е. зависанию браузера(страницы).
В новых версиях js есть подвижки на тему прозрачной асинхронности, но суть от этого не меняется.
__________________
29375, 35
|
|
|
|