#oracle #oracle-apex
#Oracle #oracle-apex
Вопрос:
Я ищу совет по созданию простого приложения типа викторины в Oracle Apex.
Мне не нужно создавать какие-либо экраны создания / обновления / удаления для базовых таблиц, поскольку я буду заполнять свои таблицы данными с помощью операторов SQL.
У меня есть две таблицы
Create Table Question_Bank
(
Question_Id Number (5) Primary Key ,
Question_Description Varchar2(1000)
)
;
Question_Choice_Id похож на 1,2,3,4 (это похоже на отсутствие вариантов выбора викторины)
Create Table Question_Choices
(
Question_Choice_Pk Number (5) Primary Key,
Question_Id Number(5) References Question_Bank(Question_Id),
Question_Choice_Id Number(1),
Question_Choice_Description Varchar2(200),
Is_Correct Varchar(1) Default 'N',
Explanation Varchar2(500)
);
Таким образом, приложение должно отображать вопросы и параметры, подобные этому.
Я бы предпочел одну прокручиваемую страницу с некоторыми номерами по вопросу на одной странице.
This is Question No 1
Option 1
Option 2
Option 3
Option 4
This is Question No 2
Another Option 1
Another Option 2
Another Option 3
Another Option 4
This is Question No 3
Q No 3 Option 1
Q No 3 Option 2
Q No 3 Option 3
Q No 3 Option 4
До сих пор я создал основную / подробную форму, которая является своего рода отчетом (не редактируемым), и я могу видеть вопросы и возможные варианты (у меня есть вопрос выбора, и варианты показаны во 2-м столбце), но это не то, что я хочу.
Я использую бесплатную онлайн-учетную запись Oracle Apex версии 20.2.
Комментарии:
1. Если вам нужен sql-файл для таблицы и данных, drive.google.com/file/d/1ZGTNr5RnHpT_ljllTuaVteFoZ4VAjNws /…
2. Как должна выглядеть страница docs.google.com/document/d /…
Ответ №1:
Вы можете попробовать динамически создавать страницу с вопросами и вариантами. Необходимо добавить новый PL/SQL Dynamic Region
регион на страницу. В Source > PL/SQL Code
атрибуте region укажите пример кода ниже.
FOR l_question IN (
SELECT QUESTION_ID, QUESTION_DESCRIPTION
FROM QUESTION_BANK
order by QUESTION_ID
) LOOP
HTP.P('<h3>' || APEX_ESCAPE.HTML(l_question.QUESTION_DESCRIPTION) || '</h3>');
HTP.P(
APEX_ITEM.HIDDEN(
p_idx => 1, -- Values stored in APEX_APPLICATION.g_f01 table.
p_value => l_question.QUESTION_ID
)
);
HTP.P('<fieldset id="qfs' || l_question.QUESTION_ID || '">');
HTP.P(
APEX_ITEM.TEXT(
p_idx => 2, -- Values stored in APEX_APPLICATION.g_f02 table.
p_item_id => 'qh' || l_question.QUESTION_ID,
p_attributes => 'style="display:none"'
)
);
FOR l_choice IN (
SELECT QUESTION_CHOICE_ID, QUESTION_CHOICE_DESCRIPTION
FROM QUESTION_CHOICES
WHERE QUESTION_ID = l_question.QUESTION_ID
) LOOP
HTP.P('<input type="radio" value="' || l_choice.QUESTION_CHOICE_ID || '" name="' || l_question.QUESTION_ID || '" onchange="document.getElementById(''qh' || l_question.QUESTION_ID || ''').value = this.value">');
HTP.P('<label for="' || l_question.QUESTION_ID || '">' || APEX_ESCAPE.HTML(l_choice.QUESTION_CHOICE_DESCRIPTION) || '</label>');
END LOOP;
HTP.P('</fieldset>');
END LOOP;
Этот блок PL / SQL перебирает все вопросы, затем печатает HTML-разметку с описанием вопроса и набором полей с переключателями. Как вы можете видеть, я использую APEX_ITEM
пакет для создания двух столбцов — QUESTION_ID
и QUESTION_CHOICE_ID
. Каждая итерация создает новую запись с этими двумя столбцами. Если вы проверили документацию APEX, вы можете задаться вопросом, почему я не использовал APEX_ITEM.RADIOGROUP
для создания переключателей. Хитрость в том, что эта процедура не подходит для этого случая, потому что она ведет себя иначе, чем ожидают разработчики. Поэтому вместо использования этой процедуры я создаю кнопки группы переключателей вручную. Я также поставил простое onchange
событие для каждого input
, чтобы сохранить выбранный выбор в каждом вопросе. Это событие устанавливает элемент во второй столбец.
Каждый столбец хранится в коллекции APEX_APPLICATION.G_Fxx
, где xx
находится между 01
и 50
. Существует p_idx
параметр, который определяет индекс коллекции для значений столбцов хранилища. После отправки страницы APEX отправляет значения в эти коллекции. Вы можете справиться с этим, создав новый процесс ( Processing > Processes
или Processing > After Submit
) и вставив код ниже.
DECLARE
v_question_count NUMBER := APEX_APPLICATION.g_f01.COUNT;
v_question_answer_id QUESTION_ANSWERS.QUESTION_ANSWER_ID%TYPE := QUESTION_ANSWERS_SEQ.NEXTVAL;
BEGIN
FOR i IN 1..v_question_count LOOP
INSERT INTO QUESTION_ANSWERS (QUESTION_ANSWER_ID, QUESTION_ID, QUESTION_CHOICE_ID)
VALUES (v_question_answer_id, APEX_APPLICATION.g_f01(i), APEX_APPLICATION.g_f02(i));
END LOOP;
END;
Существует еще одна итерация по коллекциям (обе имеют одинаковое количество элементов) и вставляют значения в некоторую таблицу.
Мой код генерирует форму без причудливого стиля, поэтому вам придется справиться с этим самостоятельно 🙂
Комментарии:
1.
p_idx
параметр предназначен для указания индекса целевойAPEX_APPLICATION.g_fxx
коллекции. Еслиp_idx = 1
затем APEX создаст нового участника вAPEX_APPLICATION.g_f01
коллекции. Еслиp_idx = 2
затем создает нового участника вAPEX_APPLICATION.g_f02
etc. В этом случае вам нужно создать «виртуальную» таблицу с двумя столбцами — quiestion_id и question_choice_id. Для этого я помещаю дваAPEX_ITEM
вызова в каждую итерацию. ОдинAPEX_ITEM
хранится в первой коллекции, а второйAPEX_ITEM
— во второй коллекции.2.
p_item_id
параметр предназначен для установкиid
атрибута HTML нового элемента. Я делаю это, потому что мне нужно установить конкретныйid
для каждого скрытого элемента, в котором хранится выбранный выбор в конкретном вопросе. Я использую этоid
в коде JavaScript дляonchange
каждогоinput
элемента. В этом случае браузер устанавливает целевой скрытый элемент. В качестве селектора я использую значениеid
атрибута.3. В первом цикле сохраняется первый элемент
QUESTION_ID
, но во втором сохраняется значение NULL (потому что я не установилp_value
параметр). I как упоминалось ранее, второй элемент предназначен для хранения выбранного выбора. Когда APEX отображает ваш тест, пользователь еще не выбрал какой-либо выбор, поэтому по умолчанию второй элемент равен NULL. Для установки этого элемента я используюonchange
событие.4. Я думаю, будет лучше, когда вы введете свою проверку
Processing > Validation
.Processing > After Submit
Вы помещаете процесс, который должен быть выполнен перед проверкой страницы.5. Нет проблем 🙂 Вы должны отправить этот элемент (например, с помощью кнопки «Новая страница»). Динамическая область PL / SQL считывает значение этого элемента из состояния сеанса. После отправки ваша страница будет перезагружена. Вы также должны установить
Server Side Condition
на странице процесс, который обрабатывает выбор пользователя. Это будет необходимо, чтобы предотвратить выполнение этого процесса с помощью вашей новой кнопки «фильтр».
Ответ №2:
Пожалуйста, взгляните на приложение Survey Builder, которое позволяет пользователям просматривать / просматривать / отправлять вопросы и ответы. Это приложение может решить ваши требования или дать вам представление о том, как их создать.
Комментарии:
1. Спасибо, Моника. Я заглянул в приложение для опроса, но почему-то мне не удалось заставить его работать в соответствии с моими требованиями.