Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 16.11.2014, 22:29
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 16.11.2014
Сообщений: 29

Перенос данных из таблицы на одной странице в форму на другой.
Я наверное опишу то, что я хочу сделать полностью, а потом опишу конкретную задачу.
Итак, есть отчёт в бумажном виде в формате таблицы. Я сканирую файнридером этот документ. На выходе получается html страница с обычной таблицей. Эти данные из таблицы нужно заполнять в форму на сайте сторонней CRM.
Задача: Автоматизировать процесс заполнения формы на стороннем сайте, изначально забирая эти данные из другой страницы, которая формируется файн ридером.
Я лично пока не могу понять в какую сторону черпать знания, что бы передавать данные со страницы на страницу. Думаю в сторону юзерскрипта.
Буду очень признателен, если найдётся добрый человек и напишет пошаговую инструкцию того что нужно делать, а так же в какую сторону копать.
Ответить с цитированием
  #2 (permalink)  
Старый 16.11.2014, 22:37
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,586

Юзерскрипт - верное решение.

Юзерскриптом либо добавляете на страницу input:file(если результат скана у вас на компьютере), либо кроссдоменным запросом вытягиваете его с вашего сайта.
Дальше чистый javascript: берём текст из полей таблицы и вставляем в поля ввода.

Чтобы говорить конкретно - нужны и конкретные примеры.
__________________
29375, 35
Ответить с цитированием
  #3 (permalink)  
Старый 16.11.2014, 23:43
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 16.11.2014
Сообщений: 29

Не совсем понял зачем добавлять инпут файл.
Из конкретных вещей прикладываю архив. В нём finereader_table это пример того, что получается на выходе у файнридера. Остальное это сохранённая страница CRM. Смысл в том, что в ней нужно будет прокликивать это дерево с категориями товара, потому что колонка справа подгружается аяксом. Потом нужно брать из третьей колонки таблицы модель товара, искать её на странице CRM и вставлять в инпуты колличество товара и цену.
Вложения:
Тип файла: zip sample.zip (161.6 Кб, 8 просмотров)
Ответить с цитированием
  #4 (permalink)  
Старый 16.11.2014, 23:46
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 16.11.2014
Сообщений: 29

На счёт автоматического прокликивания скриптом, то это я ещё спрошу. Конечно хотелось бы реализовать, но это не главное. Пока что, и если вручную кликать и автоматизировать процесс подстановки данных, уже счастье.
Ответить с цитированием
  #5 (permalink)  
Старый 17.11.2014, 16:33
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 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.
Ответить с цитированием
  #6 (permalink)  
Старый 28.11.2014, 00:42
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 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.
Ответить с цитированием
  #7 (permalink)  
Старый 28.11.2014, 03:11
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 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.
Ответить с цитированием
  #8 (permalink)  
Старый 28.11.2014, 04:02
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 16.11.2014
Сообщений: 29

Aetae,
Вы спаситель!
Ответить с цитированием
  #9 (permalink)  
Старый 28.11.2014, 04:04
Интересующийся
Отправить личное сообщение для SokDobriy Посмотреть профиль Найти все сообщения от SokDobriy
 
Регистрация: 16.11.2014
Сообщений: 29

Aetae,
А почему нельзя остановить цикл, а потом продолжить? Мне просто для себя что бы понять.
Ответить с цитированием
  #10 (permalink)  
Старый 28.11.2014, 04:41
Аватар для Aetae
Тлен
Отправить личное сообщение для Aetae Посмотреть профиль Найти все сообщения от Aetae
 
Регистрация: 02.01.2010
Сообщений: 6,586

SokDobriy, js однопоточный язык. Остановка выполнения скрипта в js равносильна остановке всего, т.е. зависанию браузера(страницы).
В новых версиях js есть подвижки на тему прозрачной асинхронности, но суть от этого не меняется.
__________________
29375, 35
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Передача данных из формы в форму на разных страницах Катерина Общие вопросы Javascript 1 04.03.2010 18:18
Два одинаковых сценария на одной странице Genetics Общие вопросы Javascript 7 12.07.2009 01:46
Две одинаковые страницы: на одной скрипты видны, на другой нет Маня Общие вопросы Javascript 9 03.06.2009 11:57
Вставка текста с одной страницы в форму на другой странице Dima Общие вопросы Javascript 19 22.01.2009 17:35
Сохранение данных для передачи с одной страницы в другую Andrey Freeman Общие вопросы Javascript 6 15.09.2008 22:32