Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Базы Данных > Анкета. Чекбоксы и радио-кнопки.


Автор: bugsb 11.9.2009, 13:21
Имеется анкета, вопросы выводятся из базы данных.
Но имеются и такие вопросы, которые я не знаю как лучше организовать, например:

Цитата

Где вы бывали?
- Париж
- Франция
- Германия
* Нигде не был


"-" - это чекбокс
"*" - это радио-кнопка.

как такое реализовать? чувствую тут надо поле создавать в mysql и указывать там тип каждого вопроса либо чекбокс либо радиокнопка.

Автор: bars80080 11.9.2009, 13:24
если уж анкета генерируется настолько автоматически, то да, надо в БД сохранять и тип ответа

Автор: bugsb 11.9.2009, 13:43
наверно это уже относится к разделу js, но раз тут начал спрашивать то думаю не стоит темы размножать...

Цитата

<input type="checkbox" name="variant[534]" value="1"> Франция<br/>
<input type="checkbox" name="variant[534]" value="2"> Англия<br/>
<input type="radio" name="variant[534]" value="3"> Нигде не был<br/>

вот примерно такое можно вывести из базы, 544 - это id вопроса.
1,2,3 - это id ответа

но тогда надо чтобы когда пользователь отметит "Нигде не был" убирались все отмеченные ранее чекбоксы и наоборот, если он отметит сначала "Нигде не был", а потом захочет выбрать еще и "Францию", надо чтобы радио-кнопка опять была неотмечена. 

Автор: bars80080 11.9.2009, 13:49
это уже чистая зависимость, которую придётся считать на клиенте, т.е. javascript.
тут бы я тогда предложил не заморачиваться с radio, а чисто строить чекбоксы, просто некоторые с пометкой уникальности.

но вопрос всё равно советую перезадать в разделе javascript, здесь всё-таки другим занимаются

Автор: bugsb 11.9.2009, 17:13
вот тут http://forum.vingrad.ru/forum/topic-272488/anchor-entry1963534/0.html
мне даже готовый код написали... =) в принципе все как надо, только щас я не знаю как в бд это сделать...

Получается так
Цитата

* Здесь я был
    - Франция
    - Германия
    - Италия
* Нигде не был

"*" - радио-кнопки
"-" - чекбоксы

но по сути варианта ответа "Здесь я был" нету...

на данный момент вот такие поля имеются в mysql
Цитата

anketa_quest - таблица с вопросами
- quest_id - идентификатор, выставляется автоматически
- quest_variant - если 1, то 1 вариант ответа, если 0, то несколько.
- quest_name - сам вопрос

anketa_var - таблица с ответами
- var_id - идентификатор, выставляется автоматически
- var_idq - ид вопроса к которому относится вариант ответа
- var_golos - количество голосов за этот вариант
- var_name - сам вариант
- var_text_act - Если 1, то выводим дополнительно текстовое поле
- var_text - Варианты ответа через запятую которые указали пользователи дополнительно

Автор: capitan 11.9.2009, 17:22
bugsb, 

anketa_quest - таблица с вопросами
- quest_id - идентификатор, выставляется автоматически
- quest_variant - если 1, то 1 вариант ответа, если 0, то несколько.
- quest_name - сам вопрос

я бы добавил поле :
- parent_id => quest_id - если 0 - главная т.е. "*" - радио-кнопки
если >0 тогда "-" - чекбоксы

Автор: bugsb 13.9.2009, 11:42
Цитата

я бы добавил поле :
- parent_id => quest_id - если 0 - главная т.е. "*" - радио-кнопки
если >0 тогда "-" - чекбоксы

capitan, это наверно надо не в таблицу с вопросами, а в таблицу с ответами!? 

а если в вопросе нет ответов имеющие радио-кнопки? т.е. надо чтобы главными были чекбоксы и небыло подвариантов.

вот пример анкеты: http://itay.ru/123.html

реально ли вообще такую генерировать автоматически из базы?

Автор: capitan 14.9.2009, 13:20
Генерировать реально.

anketa_quest - таблица с вопросами
- quest_id - идентификатор, выставляется автоматически
- quest_type - checkbox/ radio/main.
- quest_value
- quest_text
- parent_id - родитель (0 - главный вопрос )

1. Делаем выборку parent_id = 0 (получим список вопросов)
2. Делаем выборку для подвопросов  parent_id = quest_id (id вопроса)
3. IF quest_type = radio => делаем выборку checkbox  parent_id = quest_id (id radio)

Логика примерно такая.  Типа дерева.

Автор: bugsb 14.9.2009, 13:26
capitan, у меня нет подвопросов! у меня есть подответы ;-)

думаю база будет примерно такой

Таблица вопросов:
quest_id
quest_text

Таблица ответов:
var_id
var_idq - ид вопроса
var_txt - ответ
var_type - 1 - checkbox; 0 - radio
var_idv - 0 - главный ответ; >0 значит подответ (указать id родительского ответа)

Например 
3 | 5 | Где то был | 0 | 0
4 | 5 | Франция | 1 | 3
5 | 5 | Германия | 1 | 3
6 | 5 | Нигде не был | 0 | 0

вот это выведет:
* Где то был
---- Франция
---- Германия
* Нигде не был

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

Автор: capitan 14.9.2009, 13:48
quest_id | quest_type | quest_value |        quest_text                                     |                 parent_id
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1                    main                                Откуда вы о нас узнали?                                0
2                    main                                Где вы были?                                                   0
3                    main                                Порекомендуете ли вы нас друзьям?             0 
4                 checkbox                            Газеты                                                             1 
5                 checkbox                            Интернет                                                        1 
6                 checkbox                            Телевидение                                                  1 
7                 checkbox                            Другое                                                             1
8                    radio                               А я был здесь                                                   2
9                checkbox                            Франция                                                          8
10              checkbox                            Англия                                                              8
11                  radio                              Нигде не был                                                    2
12                  radio                              Да                                                                     3
13                  radio                              Нет                                                                   3


Я бы пошел в этом направлении.

Автор: bugsb 14.9.2009, 16:30
capitan, интересный вариант, вместо двух таблиц использовать одну...
но у таблицы с вопросами есть еще дополнительные поля (количество проголосовавших и т.д.) они будут пустыми у строк с полем type=main

а как это все потом выводить? я не очень хорошо понимаю как эту всю иерархию строить....
и в админке надо будет как то запрещать пользователю создавать родительский ответ с чекбоксом и с радио. И к чекбоксу подуровни нельзя радио приделывать и вот много подобных нюансов.

Автор: bugsb 15.9.2009, 16:04
capitan, сделал так как Вы посоветовали, вот что у меня получилось http://itay.ru/quest/

все нормально, кроме последнего вопроса... не знаю как автоматизировать вывод... надеюсь кто-нибудь поможет.

вот этой функцией я делаю вывод 

Код

// Параметры: переменная, куда будем формировать контент $content (по ссылке), массив из которого формируем (должен быть в специально форме)
function printChildMenu(&$content, $menu) {
    // начинаем обход массива $menu в цикле по записям
    foreach($menu as $value) {
        // определяем тип
        if($value['quest_type']==0) $type = "<b>{$value['quest_text']}</b>";
        elseif($value['quest_type']==1) {
            $type = "<input type=\"radio\" name=\"variant[{$value['parent_id']}]\" id=\"{$value['quest_id']}\" /> <label for=\"{$value['quest_id']}\">{$value['quest_text']}</label>";
            $onclick = "onclick=\"choose(this, event);\"";
        }
        elseif($value['quest_type']==2) $type = "<input type=\"checkbox\" name=\"variant[{$value['parent_id']}]\" id=\"{$value['quest_id']}\" /> <label for=\"{$value['quest_id']}\">{$value['quest_text']}</label>";
        
        
        // если у текущего элемента нет детей
        if(count($value['child'])==0)
            $content.="<li {$onclick}>{$type}</li>"; // заносим элемент списка li
        // если у текущего элемента есть дети
        else {
            $content.="<li {$onclick}>{$type}<ul>"; // заносим элемент списка li и открываем список детей
            printChildMenu($content, $value['child']); // (рекурсивный вызов) обходим детей элемента для формирования списка
            $content.="</ul></li>"; // заносим конец списка детей.     
        }
    }    
}


не работает последний вопрос из-за $onclick = "onclick=\"choose(this, event);\"";, но если я это уберу, то у меня не будет работать второй вопрос.

вопрос решили с помощью исправления JS

Автор: gcc 16.9.2009, 14:17
я хотел сделать много разширенное анкетирование... такое как vkontakte.ru, сделать большой конструктор голосования
(и чтобы можно было выбрать свой вариант еще)

а есть ли где пример MySQL запросов, статьи? нужно будет перебирать структуры, чтобы отправить все данные в шаблон smarty или template?

=====

я пока придумал вариант выбрать из форм данные, потом сериализации структуру через JSON (или пл другому http://ru.wikipedia.org/wiki/Сериализация и сохранить в MySQL само голосование и ответы, так же... (может перевести в MIME тип)

потом сделать выборку и десериализации, и отправить прямо в шаблон...

тип таблицы:

id int
vo bigtext


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


Автор: Ипатьев 16.9.2009, 14:33
непонятно, при чем здесь MySQL запросы.
непонятно, при чем здесь вопрос про "немного расширенное анкетирование".
вроде бы, есть правило, один топик - один вопрос?

Автор: gcc 16.9.2009, 14:42
автор говориn по-моиму про RDBMS (MySQL)
вопрос такой же... 
про анкетирование...

Автор: bugsb 11.10.2009, 10:34
_http://anketa.itay.ru/result.php
вот что у меня на данный момент

Код

id | type | value |              text                   | parent_id
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5     0      0      Бывали ли Вы на мероприятиях музея?       0
 6     1      7      Да                                        5
 7     1      2      Нет                                       5
 8     2      0      Рождество в музее                         6
 9     2      2      Сударыня-масленица                        6
10     2      2      Остров детства                            6




вот так примерно составлена БД. Каким образом можно сделать чтобы при выводе результатов полоски у подответов (рождество в музее, сударыня-масленица, остров детства) выводился другим цветом (не зеленым). 

возьмем к примеру ответ и подответ, они ничем не отличаются в базе, то что один из них по типу чекбокс (type=2) а другой радио (type=1) ничего не значит, т.к. есть ответы с type=2 (чекбоксы).

Автор: bars80080 11.10.2009, 11:55
при выборке вы их размещаете под родителем, то есть ответы под вопросом, подответы под ответом. не сложно в этом случае расписать стили так, чтобы более глубокий уровень отмечался другим цветом. также не сложно раскидать в разные классы. только это уже относится к использованию условия if(), а не к БД

Автор: bugsb 11.10.2009, 12:06
Код

foreach($menu as $value) {
     
            if ($value['quest_type']==0) $type = $value['quest_text'];
            else $type = $value['quest_text']."<div style='width:400px; height:4px; margin-bottom:5px; border-top:1px solid #d7d7d7;'><div style='width:".$value['procent']."%; background:#3caa3c; height:4px;'></div></div>";
      
            // если у текущего элемента нет детей
            if(count($value['child'])==0)
                $content.="<li>{$type}</li>"; // заносим элемент списка li
            // если у текущего элемента есть дети
            else {
                $content.="<li>{$type}<ul>"; // заносим элемент списка li и открываем список детей
                printChildMenu2($content, $value['child']); // (рекурсивный вызов) обходим детей элемента для формирования списка
                $content.="</ul></li>"; // заносим конец списка детей.     
            }
}

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

Автор: bars80080 11.10.2009, 12:39
            // если у текущего элемента есть дети
            else {
                $content.="<li>{$type}<ul class="qw">"; // заносим элемент списка li и открываем список детей

здесь же достаточно прописать соответствующий класс:

Автор: bugsb 11.10.2009, 12:54
не совсем... этот код что я писал выше формирует вот такой хтмл код (все лишнее убрал)

Код

<li>
    <b>Бывали ли Вы на мероприятиях музея?</b>
    <ul>
        <li>Да
            <ul>
                <li>Рождество в музее</li>
                <li>Сударыня-масленица </li>
                <li>Остров детства </li>
                <li>День Военно-Морского флота </li>
            </ul>
        </li>
        <li>Нет</li>
    </ul>
</li>


если добавить класс к <ul> ответы и подответы будут с этим классом. Для скрипта первый уровень - сам вопрос.

Автор: capitan 11.10.2009, 17:33
А что мешает в таблице завести поле level ? И писать в него уровень вложенности.

Автор: bugsb 11.10.2009, 17:41
в таком случае эта проблема решится, но возникнет другая более сложная, каким образом прописывать уровень? если все вопросы создаются через админ-панель (ну пока еще не создаются, но будут)

можно сделать просто "каким цветом отображать полоску в результатах". 
- Зеленым
- Синим

но как то слишком много настроек для простого создания анкеты....


хм.. щас еще мысль пришла, если parent_id у родителя = 0, то это второй уровень, если parent_id отличен от нуля, то это третий, а четвертый и пятый и шестой автоматом никак не прописать, а если ручками, то это равносильно прописыванию цвета к каждому вопросу

Автор: capitan 11.10.2009, 18:41
Цитата(bugsb @ 11.10.2009,  17:41)
в таком случае эта проблема решится, но возникнет другая более сложная, каким образом прописывать уровень? если все вопросы создаются через админ-панель (ну пока еще не создаются, но будут)

А что тут сложного? Подвопрос вешается на родителя. У родителя считываем уровень и прибавляем 1.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)