Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Создать Json объект на основе разметки (https://javascript.ru/forum/misc/66370-sozdat-json-obekt-na-osnove-razmetki.html)

Scantraxx 11.12.2016 17:43

Создать Json объект на основе разметки
 
Вложений: 1
Здравствуйте. Задача такова: парсить страницу и на ее основе сформировать массив объектов. Сам объект представляет собой 2 поля: 1)имя 2)массив объектов.
На скрине я цветами выделил все:
красный - это массив объектов
оранжевый - это сам объект в массиве
бардовый - поле "Имя"
желтый - поле массив
Вложение 3376
я пробую делать это как-то так:
<script>
        function PostData() {
            var questionsObj = [];
            var Polls_Possible_Answers = [];
            var c = [];
            var count_questions = $('.questionBlock>div').length;
            for (var j = 0; j < count_questions; j++)
            {
                var count_answers = $('.answer>div').length;
                for (var p = 0; p < count_answers; p++)
                {
                    if ($('#pos_ans[' + p + ']').val() != "") {
                        Polls_Possible_Answers.push($(this).val());
                    };
                    questionsObj[j] = {
                        que_name: $('#que_name['+j+']').val(),
                        posAns_value: Polls_Possible_Answers
                    }
                    
                }
            }
            var json = $.toJSON(questionsObj);
        }
    </script>

Может есть другие идеи как реализовать такую форму? мне надо передать этот набор объектов в контроллер, где я с его буду брать значения и записывать в бд

laimas 11.12.2016 18:26

Зачем парсить, если можно получить коллекцию input? Еще проще использовать форму и ее сериализацию.

Scantraxx 11.12.2016 18:42

Спасибо за совет. Я впервые пробую js и мне тут все в новизну. Можно вас попросить пример, как это будет к моей разметке применяться?

laimas 11.12.2016 18:50

А что именно надо? Ведь самое простое, это обрамить все эти элементы формой:

<form>
<div>....<input>...</div>
....
<div>....<input>...</div>
</form>


и получить ее поля как

var fields = $('form').serialise();


Что ну совсем просто. Вот только если с каждым из полей не связаны другие элементы формы, то указывать явно ключ в имени поля - [0], [1], ... нет необходимости, можно просто [].

Scantraxx 11.12.2016 19:07

Если я вас правильно понял, то применяя к такому примеру:
<form>
<div class="questionValue">
            <h4> Вопрос #1</h4>
                    <input type="text" name="que_name[0]" />
                    <div class="answer">
                        <div class="possibleAnswer">
                            <input <input type='text' name='pos_ans[0]' />
                        </div>
                    </div>
                    <div><p><a class="plus">Добавить ответ</a></p>
                </div>
        </div>
</form>

<form>
<div class="questionValue">
            <h4> Вопрос #2</h4>
                    <input type="text" name="que_name[0]" />
                    <div class="answer">
                        <div class="possibleAnswer">
                            <input <input type='text' name='pos_ans' />
                            <input <input type='text' name='pos_ans' />
                        </div>
                    </div>
                    <div><p><a class="plus">Добавить ответ</a></p>
                </div>
        </div>
</form>


и потом выполнить ваш пример
var fields = $('form').serialise();


то у меня в контроллер передастся json объект такой структуры, как я обозначил а своем скриншоте в первом посте?

laimas 11.12.2016 19:12

Какой язык используется сервером и обязательно ли передача ему JSON? Хотя и это не проблема:

JSON.stringify($('form').serialiseArray()) - все поля формы в json-формате.

PS. Так

<input <input type='text' name='pos_ans' />
<input <input type='text' name='pos_ans' />

нельзя - сервер получит значение последнего поля с именем pos_an, которое "затрет" значение первого с таким же именем.

Scantraxx 11.12.2016 19:17

Серверная часть на c#. Передавать jSON не обязательно, мне подходит любой способ, чтобы отправить в котроллер данные с формы так, чтобы "ответы" соответствовали "вопросам". То есть хочу передать массив, в котором будут объекты с такими данными: имя вопроса, массив[список вопросов]

Scantraxx 11.12.2016 19:30

тогда я буду делать как и раньше, при добавлении на форму элемента input ему будет даваться имя новое, типа:
<input <input type='text' name='pos_ans[0]' />

<input <input type='text' name='pos_ans[1]' />

но, на сколько я понял мне надо сделать, чтобы при динамическом добавлении элемента на форму, получалось следующее:
<form>
<input <input type='text' name='pos_ans[0]' />
</form>

<form>
<input <input type='text' name='pos_ans[0]' />
<input <input type='text' name='pos_ans[1]' />
</form>

верно?

laimas 11.12.2016 19:33

Ну тогда либо JSON, либо разбирать строку GET запроса.
Если имя вопроса (в базе вообще-то под уникальным id такое хранят, а не под именем), тогда достаточно список ответов передавать под ключами имен вопросов (по уму так это будут уникальные id), то есть:

<input type="radio" name="answer[id_вопроса]">
<input type="radio" name="answer[id_вопроса]">
....
<input type="radio" name="answer[id_вопроса]">

следующая группа ответов

<input type="radio" name="answer[id_вопроса]">
<input type="radio" name="answer[id_вопроса]">
....
<input type="radio" name="answer[id_вопроса]">

и так далее. И сервер получит массив ключами которого будут идентификаторы вопросов, а их значениями ответы на них.

laimas 11.12.2016 19:36

Цитата:

Сообщение от Scantraxx
верно?

Зачем куча форм? Все нужно размещать в одной форме, и потом, если вопрос, а на него варианты ответа, из которых нужно выбрать правильный, то это все таки не type='text', а type="radio". Или ответ на вопрос предполагает ввод произвольного текста?

Scantraxx 11.12.2016 19:49

На счет того что вопрос хранится под ключами id это верно. Но как мне его передать(как показано в вашем примере), если он(вопрос к ключ к нему) формируется только после отправки запроса subit(тут контроллер должен получить вопросы с ответами и добавить их в базу)?
<form>
<h4>Вопрос #1
<input type="text" name=question[0]/>
<div class="answer">
<input type="radio" name="answer[??]">
</div>
</form>

Scantraxx 11.12.2016 19:53

Возможно вы не поняли и это моя вина, но то что я пытаюсь сейчас сделать - это создать опрос, в котором с представления(то, что мы тут пытаемся сделать) передается список вопросов с вариантами ответов к ним на контроллер, а там добавляется в бд по соответствующим ключам.

laimas 11.12.2016 20:02

Сперва надо разделить понятия "получить вопросы и варианты ответов" и "получить ответы на вопросы и записать их в базу".

То есть, если речь идет об имеющейся базе вопросов и приведенный ранее html-код, это результат работы сервера на запрос клиента страницы, которая выводит вопросы и варианты. Тут в общем то понятно - id вопросов подставляются в форму при формировании страницы севером.

Если же речь идет об административном разделе, в котором добавляются новые вопросы и варианты ответов на них, то в этом случае id как ключ подставляется просто по-порядку, от 0 до N при формировании страницы (или динамическом добавлении полей в форму), по которому связываются вопросы и варианты ответов на них. После записи в базу они будут записаны под реальным id.

О чем у вас идет речь я не знаю поэтому трудно понять что за проблема и что означает "он(вопрос к ключ к нему) формируется только после отправки запроса subit(тут контроллер должен получить вопросы с ответами и добавить их в базу)".

Scantraxx 11.12.2016 20:45

"административном разделе, в котором добавляются новые вопросы и варианты ответов на них" именно это я сейчас пытаюсь сделать.
Суть: Пользователь создает опрос, в котором формирует сколько захочет вопросов и сколько хочет ответов на них.
Моя проблема: у меня не получается отправить на сервер данные так, чтобы они были вида -> object1(вопрос1, массив[варианты ответов]), object2(вопрос2, массив[варианты ответов])

laimas 12.12.2016 03:04

Как на сервере обрабатывается ответ клиента? Ведь можно сделать так:

Опрос 1
<input name="interview[0][question]" value="qst" />
<input name="interview[0][answer][]" value="ans" />
<input name="interview[0][answer][]" value="ans" />
<input name="interview[0][answer][]" value="ans" />
Опрос 2
<input name="interview[1][question]" value="qst" />
<input name="interview[1][answer][]" value="ans" />
<input name="interview[1][answer][]" value="ans" />


и передать хоть POST/GET форму, хоть JSON, и например РНР сам разберет данные и вернет такой массив

[interview] => Array
        (
            [0] => Array
                (
                    [question] => qst
                    [answer] => Array
                        (
                            [0] => ans
                            [1] => ans
                            [2] => ans
                        )

                )

            [1] => Array
                (
                    [question] => qst
                    [answer] => Array
                        (
                            [0] => ans
                            [1] => ans
                        )

                )

        )


Ответы будут восприняты как индексный массив ключа answer, потому как они указаны в имени как элементы массива [answer][]. В противном случае будет принят только последний из всех вариантов ответа, так как у массива все ключи должны быть уникальными, как и имена свойств объекта. Соответственно по индексу ключа interview формируется и массив опросов.

Ничего страшного не произойдет если передать серверу такую форму

<input name="question" value="qst" />
<input name="answer" value="ans" />
<input name="answer" value="ans" />
<input name="answer" value="ans" />

<input name="question" value="qst" />
<input name="answer" value="ans" />
<input name="answer" value="ans" />


если она в строгой последовательности, к примеру ее JSON представление будет таким

[{"name":"question","value":"qst"},{"name":"answer" ,"value":"ans"},{"name":"answer","value":"ans"},{" name":"question","value":"qst"},{"name":"answer"," value":"ans"},{"name":"answer","value":"ans"}]

и север осведомлен, что первый параметр "name", это вопрос (значение question), а за ним следует варианты (значение answer), которые нужно помещать в массив (в случае записи в базу, строку для многострочной вставки в таблицу вариантов, после того как будет записан вопрос и получен его идентификатор), а если параметр "name" опять равен "question", значит далее идут значения нового опроса.

Если пользователь сперва задает количество вопросов и вариантов ответа на них и сервер формирует ему готовую форму, выбирайте любой вариант, при "ручном разборе" хоть так, хоть иначе ориентироваться придется по значениям name.

PS. Если по каким либо причинам на сервере затруднительно сделать такой разбор и ему нужны не сырцы данных, а уже готовый объект, то можно такой разбор сделать и на клиенте.

Scantraxx 12.12.2016 10:42

laimas, спасибо вам большое, за уделенное мне время и раскрытый ответ.
[{"name":"question","value":"qst"},{"name":"answ er" ,"value":"ans"},{"name":"answer","value":"ans"} ,{" name":"question","value":"qst"},{"name":"answer"," value":"ans"},{"name":"answer","value":"ans"}]

Именно такой массив объектов я и хочу передать в контроллер, но все примеры что я находил в сети мне не подходят, так как там отправляют примерно так:
var jsonObject = {
                "Name" : "Rami",
                "Roles": [{ "RoleName": "Admin", "Description" : "Admin Role"}, { "RoleName": "User", "Description" : "User Role"}]
            };

а у меня ведь заранее не известно сколько будет полей и какие там будут значения, вот я и прибегнул за помощью на форум

Scantraxx 12.12.2016 12:08

Конкретно для такого примера:
<div class="questionValue">

            <h4> Вопрос #1</h4>

                    <input type="text" name="que_name[0]" />

                    <div class="answer">

                        <div class="possibleAnswer">

                            <input <input type='text' name='pos_ans[0]' />

                        </div>

                    </div>

                    <div><p><a class="plus">Добавить ответ</a></p>

                </div>

        </div>


<div class="questionValue">

            <h4> Вопрос #2</h4>

                    <input type="text" name="que_name[0]" />

                    <div class="answer">

                        <div class="possibleAnswer">

                            <input <input type='text' name='pos_ans' />

                            <input <input type='text' name='pos_ans' />

                        </div>

                    </div>

                    <div><p><a class="plus">Добавить ответ</a></p>

                </div>

        </div>

Пытаюсь сделать как-то так, я в правильном направлении? Повторюсь, я в javascript не силен, просто поставленная задача вынудила прибегнуть к нему и вот результат, мучаюсь не зная как мне правильно это сделать. Буду очень признателен, если поправите то, что ниже:
<script>
        function PostData() {
            var obj = $('.questionValue');
            var array = new Array();
            obj.each(function () {
                var question = $(this).attr('que_name');
                var answers = $(this).find('div.answer');
                var answer = $(this).attr('posAns_value');

                answers.each(function (i, item) {
                    var que = $(item).attr('que_name');
                    var o = { 'que_name': question, 'posAns_value': answer };
                    array.push(o);
                });
            });

            var json = JSON.stringify(array);

            $.ajax({
                type: 'POST',
                url: '/Poll/Create',
                data: json,
                contentType: 'application/json; charset=utf-8',
                success: function (msg) {
                    if (msg == 'True') {
                        alert('Опрос успешно добавлен');
                        window.location.reload(true);
                    };
                }
            });
            return false;
        }
    </script>

laimas 12.12.2016 16:45

Цитата:

Сообщение от Scantraxx
а у меня ведь заранее не известно сколько будет полей и какие там будут значения

А этого знать и не обязательно, скрипт клиента или сервера разберется сколько и чего, а значения прерогатива пользователя, что введет, то и будет.

Элементы формы это коллекция, и если из этой коллекции скриптом формировать объект/json, то указывать индексы не обязательно. Без них может получится пролет в таких языках как РНР, который освобождают программиста от заботы разбирать параметры запроса, он уже возвращает готовое, если только самому не захочется работать в RAW данными.

Это пример, в нем только возможность добавления полей в форму, без удаления их. После заполнения формы и ее отправления готовится объект, и преобразованный в JSON отправляется серверу:

<html> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
<style>

</style> 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script> 
$(function() {
    
    $('form').on('click', 'a.plus', function() {
        //добавление ответов к вопросу
        var fld = $(this).closest('div').prev().find('input').last(), add = fld.clone().val('');
        fld.after(add)
    }).submit(function(e) {
        //формирование отправления и отправка формы
        e.preventDefault();
        var obj = [];
        $.each(this.elements, function() {
            if(this.name=='que_name') obj.push({"que_name" : this.value, "pos_ans" : []});
            else if(this.name=='pos_ans') obj[obj.length-1].pos_ans.push(this.value)
        });
        console.log(JSON.stringify(obj)); //чисто посмотреть что отправляется
        $.ajax({
                type: 'POST',
                url: '/Poll/Create',
                data: {json : JSON.stringify(obj)}, 
                contentType: 'application/json; charset=utf-8',
                success: function (msg) {
                    if (msg == 'True') {
                        alert('Опрос успешно добавлен');
                        window.location.reload(true);
                    };
                }
        });
    });
    //добавление нового вопроса
    $('#add_qst').click(function() {
        var qst = $(this).closest('form').find('div.questionValue').last(), add = qst.clone(), h = add.find('h4');
        h.text(h.text().replace(/\d+/, function(v) {
            return +v + 1;
        }));
        add.find('input').val('').filter('[name="pos_ans"]').not(':first').remove(); 
        
        qst.after(add)
    });
});

</script>     
</head> 

<body>
<form>
<div class="questionValue">
 
            <h4> Вопрос #1</h4>
 
                    <input type="text" name="que_name" />
 
                    <div class="answer">
 
                        <div class="possibleAnswer">
 
                            <input type='text' name='pos_ans' />
 
                        </div>
 
                    </div>
 
                    <div><p><a class="plus">Добавить ответ</a></p>
 
                </div>
 
        </div>
 <a id="add_qst">Добавить вопрос</a>
 <div><button>Send</button></div>
</form>
</body> 
</html>

Scantraxx 12.12.2016 17:06

laimas, спасибо вам большое за помощь.


Часовой пояс GMT +3, время: 20:42.