package ONO::FW::Apps::Core::Check;
################################################################################
# COPYRIGHT / LICENSE #
################################################################################
#
# This file is part of the ONO Software Project.
#
# Copyright (C) 2000-2025 Jos KIRPS [ www.kirps.com | jos_AT_kirps_DOT_com ]
# and The Joopita Project [ www.joopita.org | contact_AT_joopita_DOT_com ]
#
# This file, as well as other parts of the ONO Software Project or related
# elements, are FREE SOFTWARE available under the ARTISTIC LICENSE 2.0.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# For the full license, see /ono/osr/license/LICENSE.txt, or write to
# jos_AT_kirps_DOT_com or contact_AT_joopita_DOT_com.
#
################################################################################
# END OF COPYRIGHT / LICENSE, HERE COMES THE CODE ... #
################################################################################
use strict;
use ONO::IO;
###################################################################
#
###################################################################
#: This module offers helpers that allow to check if user answers
#: in ONO apps are correct or not. Note that this is mostly the UI
#: logic, and not the actual checking of the provided data.
sub check_rightwrong {
my (
$self,
$is_wrong,
$BLK_ref,
) = @_;
#: Check mode: right or wrong (special case)
my %BLK = %$BLK_ref;
my $ANS;
if ($is_wrong) {
$ANS = qq~<div id="apps_core_question" class="box_paper">
<table class="default_table auto">
<tr>
<td><a href="javascript:void(0);" onclick="onojs_hide('apps_core_question');onojs_block('apps_core_question_right');" class="button_green button_big">$BLK{'right_alt'}</a></td>
<td><a href="javascript:void(0);" onclick="onojs_hide('apps_core_question');onojs_block('apps_core_question_wrong');" class="button_red button_big">$BLK{'wrong_alt'}</a></td>
</tr>
</table>
</div>
<div id="apps_core_question_right" class="box_red hide">
<table class="default_table auto">
<tr>
<td><div class="trans30"><a href="javascript:void(0);" class="button_green button_big">$BLK{'right_alt'}</a></div></td>
<td><input type="submit" name="output_web_continue_key_mistake" value="$BLK{'wrong_alt'}..." class="button_red button_big"></td>
</tr>
</table>
</div>
<div id="apps_core_question_wrong" class="box_green hide">
<table class="default_table auto">
<tr>
<td><div class="trans30"><a href="javascript:void(0);" class="button_green button_big">$BLK{'right_alt'}</a></div></td>
<td><input type="submit" name="output_web_continue_key" value="$BLK{'continue'}..." class="button_yellow button_big"></td>
</tr>
</table>
</div>
~;
} else {
$ANS = qq~<div id="apps_core_question" class="box_paper">
<table class="default_table auto">
<tr>
<td><a href="javascript:void(0);" onclick="onojs_hide('apps_core_question');onojs_block('apps_core_question_right');" class="button_green button_big">$BLK{'right_alt'}</a></td>
<td><a href="javascript:void(0);" onclick="onojs_hide('apps_core_question');onojs_block('apps_core_question_wrong');" class="button_red button_big">$BLK{'wrong_alt'}</a></td>
</tr>
</table>
</div>
<div id="apps_core_question_right" class="box_green hide">
<table class="default_table auto">
<tr>
<td><input type="submit" name="output_web_continue_key" value="$BLK{'continue'}..." class="button_green button_big"></td>
</tr>
</table>
</div>
<div id="apps_core_question_wrong" class="box_red hide">
<table class="default_table auto">
<tr>
<td><input type="submit" name="output_web_continue_key_mistake" value="$BLK{'right_alt'}..." class="button_green button_big"></td>
<td><div class="trans30"><a href="javascript:void(0);" class="button_red button_big">$BLK{'wrong_alt'}</a></div></td>
</tr>
</table>
</div>
~;
}
return qq~<div class="inline auto" style="min-width:320px">$ANS</div>~;
}
sub check_custom {
my (
$self,
$CHECK,
$switches,
$CLASS,
$STYLE,
$BUTTON,
) = @_;
#: Check mode: customizable
#:
#: Switches:
#:
#: -b display button at the bottom (inline buttons should be part of the code), may use BUTTON var
#: -B button -b is separated on top by a horizontal line
#: -C no class
#: -G green (correct answer)
#: -L loading icon
#: -R red (wrong answer)
#: -S no style
#: -T flat top
#: -Y yellow (incomplete answer, warning, etc...)
if (!$CLASS && $switches !~ /C/) {
$CLASS = "inline auto";
}
if (!$STYLE && $switches !~ /S/) {
$STYLE = "margin-top:70px";
}
my ($BUT,$CLASS2);
my $COLOR = "fabric";
if ($switches =~ /G/) {
$COLOR = "green";
}
if ($switches =~ /R/) {
$COLOR = "red";
}
if ($switches =~ /Y/) {
$COLOR = "yellow";
}
if ($switches =~ /b/) {
if (!$BUTTON) {
$BUTTON = "OK";
}
$BUT = qq~<div class="inline auto"><input type="submit" name="check_custom_button_submit" value="$BUTTON" class="button_green mt10"></div>~;
if ($switches =~ /B/) {
$BUT = qq~<div class="bt mt10">$BUT</div>~;
}
$BUT = qq~<div id="check_custom_button">$BUT</div>~;
}
if ($switches =~ /L/) {
$BUT .= qq~<div class="inline auto"><img id="check_custom_loading_img" class="block32" src="/ono/osr/images/loading/wheel_32.gif" alt=""></div>~;
}
if ($switches =~ /T/) {
$CLASS2 .= " flat_top";
}
return qq~<div class="$CLASS">
<div class="box_$COLOR xlarge$CLASS2" style="$STYLE">
<div class="box_paper">
<table class="default_table auto">
<tr>$CHECK</tr>
</table>
$BUT
</div>
</div>
</div>
~;
}
sub check_single {
my (
$self,
$TDS1,
$TDS2,
$width,
$maxlength,
$BLK_ref,
$vars_ref,
$switches,
$devpla,
) = @_;
#: Check mode: single question (standard mode)
#:
#: Switches:
#:
#: -B put TDS Behind the input fields
#: -C correct answer displays continue button (see also: -f)
#: -d dual / double input fields
#: -f feedback color frame (status 1 = green, status 2 = red, see also: -C)
#: -F disable input field focus
#: -I no Input fields (check / continue buttons only)
#: -M no Margin top 75px
#: -n use number instead of text (auto-disable in comma mode)
#: -m maxlength affects number min/max (requires -n, does not work with negatives)
#: -P small padding, reducing overall height
#: -R radius10
#: -S auto-submit if -C and output_web_answer_status == 1, width output_web_next_question = 1
#: -T transparent is default
#: -y double zero answer 1 if -Z
#: -Y double zero answer 2 if -Z
#: -z set answers to zero (always)
#: -Z set answers to zero (only when showing results, also see -y/-Y)
#:
#: output_web_answer_status:
#: -0 none
#: -1 correct
#: -2 wrong
my %BLK = %$BLK_ref;
my %vars = %$vars_ref;
my $boxcolor = "box_fabric";
my $boxpaper = "box_paper";
if ($switches =~ /T/) {
$boxcolor = "p10";
$boxpaper = "p10";
}
if ($vars{'output_web_answer'} ne "" && $vars{'output_web_answer_status'} == 2) {
$boxcolor = "box_red";
}
if (!$maxlength) {
$maxlength = 1000;
}
my ($maxlength1,$maxlength2) = ($maxlength,$maxlength);
if ($maxlength =~ /^(.*?):(.*?)$/) {
($maxlength1,$maxlength2) = ($1,$2);
}
my $margin_top = 75;
if ($switches =~ /M/) {
$margin_top = 0;
}
if ($switches =~ /z/) {
if (!$vars{'output_web_answer'}) {
$vars{'output_web_answer'} = 0;
}
if (!$vars{'output_web_answer2'}) {
$vars{'output_web_answer2'} = 0;
}
}
my @minmax1 = ("-9999999","9999999");
my @minmax2 = ("-9999999","9999999");
if ($switches =~ /m/) {
@minmax1 = ("0","");
@minmax2 = ("0","");
for (my $m = 0; $m < $maxlength1; $m++) {
$minmax1[1] .= 9;
}
for (my $m = 0; $m < $maxlength2; $m++) {
$minmax2[1] .= 9;
}
}
my $INPUT_PAD = "pad10_2";
my $PLA = "?";
if (ONO::IO->devstation) {
if ($vars{'output_web_answer'}) {
$PLA = $vars{'output_web_answer'};
}
if ($devpla) {
$PLA = $devpla;
}
}
my $INPUT = qq~<input type="text" id="output_web_answer_id" name="output_web_answer" value="$vars{'output_web_answer'}" autocomplete="off"
onkeydown="onojs_input_limit('output_web_answer_id','$maxlength1');" onkeyup="onojs_input_limit('output_web_answer_id','$maxlength1');"
class="center" style="width:${width}px" maxlength="$maxlength1" placeholder="$PLA" onclick="this.select();">
~;
if ($switches =~ /n/ && $vars{'app_input_comma_status'} < 1) {
my $width2 = $width + 20;
$INPUT = qq~<input type="number" id="output_web_answer_id" name="output_web_answer" value="$vars{'output_web_answer'}" autocomplete="off"
onkeydown="onojs_input_limit('output_web_answer_id',$maxlength1);" onkeyup="onojs_input_limit('output_web_answer_id',$maxlength1);"
class="center" style="width:${width2}px" maxlength="$maxlength1" min="$minmax1[0]" max="$minmax1[1]" step="1" placeholder="$PLA" onclick="this.select();">
~;
}
my $INPUT2;
if ($switches =~ /d/) {
$INPUT2 = qq~<input type="text" id="output_web_answer2_id" name="output_web_answer2" value="$vars{'output_web_answer2'}" autocomplete="off"
onkeydown="onojs_input_limit('output_web_answer2_id','$maxlength2');" onkeyup="onojs_input_limit('output_web_answer2_id','$maxlength2');"
class="center" style="width:${width}px" maxlength="$maxlength2" placeholder="$PLA" onclick="this.select();">
~;
if ($switches =~ /n/) {
my $width2 = $width + 20;
$INPUT2 = qq~<input type="number" id="output_web_answer2_id" name="output_web_answer2" value="$vars{'output_web_answer2'}" autocomplete="off"
onkeydown="onojs_input_limit('output_web_answer2_id','$maxlength2');" onkeyup="onojs_input_limit('output_web_answer2_id','$maxlength2');"
class="center" style="width:${width2}px" maxlength="$maxlength2" min="$minmax2[0]" max="$minmax2[1]" step="1" placeholder="$PLA" onclick="this.select();">
~;
}
}
if ($switches =~ /I/) {
$INPUT = qq~<div class="hide"><input type="text" id="output_web_answer_id" name="output_web_answer_disabled" value="" style="width:1px"></div>~;
$INPUT_PAD = "p0";
}
my $BUTTON = $BLK{'do_correct'};
if ($vars{'output_web_answer_status'} == 1 && $switches =~ /C/) {
if ($switches =~ /Z/) {
if (!$vars{'output_web_answer'}) {
$vars{'output_web_answer'} = 0;
if ($switches =~ /y/) {
$vars{'output_web_answer'} = "00";
}
}
if (!$vars{'output_web_answer2'}) {
$vars{'output_web_answer2'} = 0;
if ($switches =~ /Y/) {
$vars{'output_web_answer2'} = "00";
}
}
}
# the hidden input field allows to continue using the return key...
$BUTTON = "$BLK{'continue'}...";
$INPUT = qq~<div class="bold green p2">$vars{'output_web_answer'}</div>
<div class="abs" style="width:1px;height:1px;overflow:hidden">
<input type="text" id="output_web_answer_id" name="output_web_continue_key" value="1" style="width:1px">
</div>
~;
if ($switches =~ /d/) {
$INPUT2 = qq~<div class="bold green p2">$vars{'output_web_answer2'}</div>~;
}
}
my $TDS3;
if ($switches =~ /B/) {
$TDS3 = $TDS2;
$TDS2 = $TDS1;
$TDS1 = "";
}
if ($switches =~ /d/) {
$TDS2 .= qq~<td>$INPUT2</td>~;
}
my $PAD = "p5_720";
if ($switches =~ /P/) {
$PAD = "p2";
}
if ($switches =~ /R/) {
$PAD .= " radius10";
}
if ($switches =~ /f/) {
if ($vars{'output_web_answer_status'} == 1) {
$boxcolor = "box_green";
}
if ($vars{'output_web_answer_status'} == 2) {
$boxcolor = "box_red";
}
}
if ($vars{'output_web_hints'}) {
$vars{'output_web_hints_single'} = $vars{'output_web_hints_single'} + $vars{'output_web_hints'};
}
my $SCRIPT;
if ($switches !~ /F/) {
$SCRIPT .= qq~<script>onojs_focus('output_web_answer_id');</script>~;
}
if ($vars{'output_web_answer_status'} == 1 && $switches =~ /C/ && $switches =~ /S/) {
$BUTTON = "$BLK{'please_wait'}...";
$SCRIPT .= qq~<input type="hidden" name="output_web_next_question" value="1">
<script>onojs_submit();</script>
~;
}
my $BUT1 = qq~<input type="submit" name="do_correct" value="$BUTTON" class="button_green">~;
my $BUT2 = qq~<input type="submit" name="do_correct_2" value="$BUTTON" class="button_green mt5">~;
if ($vars{'output_block_online_checking'}) {
my $txt = &check_demo_mode("",$vars{'app_lang'});
$SCRIPT = qq~<div class="center small italic lightred mt5">$txt</div>~;
$BUT1 = qq~<div class="button_yellow">$BUTTON</div>~;
$BUT2 = qq~<div class="button_yellow mt5">$BUTTON</div>~;
}
return qq~<div class="inline auto">
<div class="$boxcolor $PAD xlarge" style="margin-top:${margin_top}px">
<div class="$boxpaper $PAD">
<table class="default_table auto">
<tr>
$TDS1
<td class="$INPUT_PAD">$INPUT</td>
$TDS2
$TDS3
<td class="pad10_2 hide800">$BUT1</td>
</tr>
</table>
<input type="hidden" name="output_web_hints_single" value="$vars{'output_web_hints_single'}">
$SCRIPT
</div>
<div class="hide block800"><div class="inline auto">$BUT2</div></div>
</div>
</div>
~;
}
sub check_multi {
my (
$self,
$BLK_ref,
$remaining,
$page,
$pages,
$switches,
$vars_ref,
) = @_;
#: Check mode: multiple questions (standard mode)
#:
#: Switches:
#:
#: -n next_page / done buttons
#: -N undocumented (?)
my %BLK = %$BLK_ref;
my %vars;
if ($vars_ref) {
%vars = %$vars_ref;
}
if ($vars{'output_block_online_checking'}) {
my $txt = &check_demo_mode("",$vars{'app_lang'});
return qq~<div class="inline auto"><div class="button_yellow">$txt</div></div>~;
} else {
if ($remaining) {
return qq~<div class="inline auto"><input type="submit" name="output_web_do_correct" value="$BLK{'do_correct'}" class="button_green"></div>~;
} else {
if ($page == $pages) {
return qq~<div class="inline auto"><input type="submit" name="output_web_finish" value="$BLK{'continue'}" class="button_green"></div>
<div class="abs" style="width:1px;height:1px;overflow:hidden">
<input type="text" id="output_web_answer_id" name="output_web_continue_key" value="1" style="width:1px">
</div>
<script>document.getElementById('output_web_answer_id').focus();</script>
~;
} else {
if ($switches =~ /n/ || ($switches =~ /N/ && !$pages)) {
return qq~<div class="inline auto">
<input type="submit" name="output_web_continue" value="$BLK{'next_page'}" class="button_green mr10">
<input type="submit" name="output_web_finish" value="$BLK{'done'}" class="button_yellow">
</div>
<div class="abs" style="width:1px;height:1px;overflow:hidden">
<input type="text" id="output_web_answer_id" name="output_web_continue_key" value="1" style="width:1px">
</div>
<script>document.getElementById('output_web_answer_id').focus();</script>
~;
} else {
my $next = $page + 1;
return qq~<div class="inline auto">
<input type="submit" name="output_web_continue" value="$BLK{'next_page'} ( $next / $pages )" class="button_green">
<input type="hidden" name="output_web_next_page" value="$next">
</div>
~;
}
}
}
}
}
sub check_demo_mode {
#: Check mode: demo mode option
my $txt = "demo mode (corrections disabled)";
if ($_[1] eq "de" || $_[1] eq "lu") {
$txt = "Demo Modus (keine Verbesserung)";
}
if ($_[1] eq "fr") {
$txt = "mode démo (pas de corrections)";
}
return $txt;
}
###################################################################
# THAT'S IT :-D
###################################################################
1;
__END__