• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

Javascript - String mit Anführungszeichen -> " <- wird nicht übergeben.

mimbob

Neues Mitglied
Hallo an alle hier, ich habe ein vielleicht kleines Problem, leider bereitet es mir aber große Sorgen.

Also dann fang ich mal an: Ich muss einen Online-Englisch-Test programmieren. Das meißte wird mit PHP realisiert, hier und da ist Javascript dabei und die Fragen, die 4 möglichen Antworten und die richtige Antwort stehen in einer Datenbank.

Folgendes Problem:

Die Fragen sind wie folgt in die Datenbank eingetragen und werden so ausgegeben:
The book was _____ amusing than the film.

Nun soll beim Klick auf eine Antwort:
a) much b) more c) many d) very

die Antwort automatisch in die Frage eingetragen sprich:
The book was much amusing than the film.



Die Fragen werden mit der folgenden Funktion in einer Tabelle ausgegeben:

Code:
function show_questions($ID)
{
	srand ( (double)microtime () * 1000000 );
	$j = array(0,1,2,3);
	$IDanz = count ($ID);
	echo "<table border=2 style='width: 300; text-align: center; border: grey ridge thick; background-color: #f5f5f5;'>";
		echo "<tr>";
			echo "<th>$_POST[first_name] $_POST[family_name]</th><th id='Countdown'></th>";
		echo "</tr>";
	echo "</table>";
	
	
	echo "<br><br>";
	
	
	echo "<table border=2 style='border: grey ridge thick; background-color: #f5f5f5;'>";
		echo "<tr>";
			echo "<th style='padding: 2px;'>question</th><th style='padding: 2px;'>answers</th>";
		echo "</tr>";
	echo "<form action='english_test_analyse.php' onsubmit='return checkAnswers($IDanz)' name='question_form' method='post'>";
	$k = 0;
	for ($i = 0; $i < $IDanz; $i++) 
	{
			$k++;
			$result = mysql_query("select question from questions where ID = $ID[$i]") or die(mysql_error());
			$question = mysql_fetch_row($result);
			
			$question = searchSZ($question);
			
			echo "<tr>";
				echo "<td>".($k).". "."<span id='question$k'>".$question[0]."</span>"."<br></td>";
				$result = mysql_query("select answer1 from questions where ID = $ID[$i]") or die(mysql_error());
				$answer1 = mysql_fetch_row($result);
			
				$result = mysql_query("select answer2 from questions where ID = $ID[$i]") or die(mysql_error());
				$answer2 = mysql_fetch_row($result);
			
				$result = mysql_query("select answer3 from questions where ID = $ID[$i]") or die(mysql_error());
				$answer3 = mysql_fetch_row($result);
			
				$result = mysql_query("select answer4 from questions where ID = $ID[$i]") or die(mysql_error());
				$answer4 = mysql_fetch_row($result);
			
				echo "<td>";
				echo "<input type='radio' id='answer_$j[0]' name='answer$i' value='a'>a) <span id='word$j[0]$k' onclick='clickbutton($j[0], $k, \"$question[0]\")'>$answer1[0]</span><br>";
				$j[0] = $j[0] + 4;
				echo "<input type='radio' id='answer_$j[1]' name='answer$i' value='b'>b) <span id='word$j[1]$k' onclick='clickbutton($j[1], $k, \"$question[0]\")'>$answer2[0]</span><br>";
				$j[1] = $j[1] + 4;
				echo "<input type='radio' id='answer_$j[2]' name='answer$i' value='c'>c) <span id='word$j[2]$k' onclick='clickbutton($j[2], $k, \"$question[0]\")'>$answer3[0]</span><br>";
				$j[2] = $j[2] + 4;
				echo "<input type='radio' id='answer_$j[3]' name='answer$i' value='d'>d) <span id='word$j[3]$k' onclick='clickbutton($j[3], $k, \"$question[0]\")'>$answer4[0]</span><br>";
				$j[3] = $j[3] + 4;
				echo "</td>";
			echo "</tr>";
			$IDx = $ID[$i];
			#echo "IDx: $IDx<br> k: $k<br>";
			echo "<input type='hidden' name='ID$i' value ='$IDx'>";
	}
	echo "<input type='hidden' name='first_name' value='$_POST[first_name]'>";
	echo "<input type='hidden' name='family_name' value='$_POST[family_name]'>";
	echo "<input type='hidden' name='email' value='$_POST[email]'>";
	echo "<input type='hidden' name='birthday' value='$_POST[birthday]'>";
	echo "<input type='hidden' name='nationality' value='$_POST[nationality]'>";
	echo "<input type='hidden' name='agent' value='$_POST[agent]'>";
	echo "<input type='hidden' name='time' value=''>";
	echo "</table>";
	echo "<br>";
	echo "<input type='submit' style='width: 120px; height: 30px;' value='send results'>";
	echo "</form>";
}

Das sieht dann folgendermaßen aus:

tabellefragen.jpg




Das automatische Eintragen der Antwort hab ich so realisiert:

Code:
var replacepoint = "_____";
function clickbutton(radio_ID, number, question)
{
	document.question_form.elements["answer_"+radio_ID].click();
	strWord = document.getElementById("word"+radio_ID+number).innerHTML
	strHtml = "<b style=\"color: darkblue;\"><i>"+strWord+"</i></b>";
	newQuestion = question.replace(replacepoint, strHtml);
	document.getElementById("question"+number).innerHTML = newQuestion;
}

Was dann auch so passiert:

automatischeantwort.jpg



Doch es gibt auch Fragen bei denen Anführungszeichen enthalten sind und dort funktioniert diese Funktion nicht. Die Frage wird dann nicht übergeben und die Variable question ist leer. Ich habe schon versucht dieses Problem so zu lösen:

Code:
function searchSZ($string)
{
	$sign = array ("'","\"");
	$replace = array ("&#39","&#34");
	for ($i = 0; $i < count($sign); $i++) 
	{
		$string = str_replace($sign[$i],$replace[$i], $string);	
	}
	return $string;
}

Das klappt zwar mit den Appostrophen, also den einstelligen Anführungszeichen, doch das mit dem 2 stelligen Anführungszeichen funktioniert nicht.

Meine Fragen also:
Wieso wird die Frage...

Code:
onclick='clickbutton($j[0], $k, \"[B]$question[0][/B]\")

nicht mit übergeben wenn sie ein Anführungszeichen enthält? Hier mal ein Beispiel für eine solche Frage:

"I'm right, _____ I?"

Wie kann ich das am besten beheben?


Ich hoffe ich konnte mein Problem genau und verständlich schildern, falls noch Unklarheiten oder Fragen bestehen bitte stellt sie mir.

Schon einmal vielen Dank.

LG mimbob
 
Werbung:
In der Funktion searchSZ fehlen hinter den Entity-Deklarationen Semikolons. Zudem unterstützt str_replace Arrays. Du könntest die Funktion so schreiben:

Code:
function searchSZ($string)
{
    $sign = array ("'","\"");
    $replace = array ("'",""");
    $string = str_replace($sign, $replace, $string);    
    return $string;
}

Die korrekte Funktion ist an dieser Stelle aber htmlspecialchars (eventuell htmlentities bei Nicht-UTF-8-Ausgaben). Die solltest du einsetzen, um solche Daten in den HTML-Code einzufügen. Auch, um potentielle XSS-Attacken zu verhindern, falls du Daten ausgibst, die direkt oder indirekt vom Benutzer erzeugt wurden.

Der Ansatz sollte theoretisch aber funktionieren. Zeig mal den generierten HTML-Code für einen Radio-Button mit Anführungszeichen-Satz.

PS: Schöne Beschreibung.

Edit: Der Hinweis auf htmlspecialchars gilt definitiv auch für die Ausgabe von $_POST-Variablen.
 
Zuletzt bearbeitet:
Wenn ich htmlspecialchars nutze funktioniert die Funktion auch bei Fragen mit einfachem Apostroph nicht. Möglicherweise nutze ich sie auch falsch?

Code:
function searchSZ2($string)
{
	htmlspecialchars($string[0]);
	return $string;
}



Und hier ist der Code für einen der Radio Buttons bei einer Frage mit Anführungszeichen:

Code:
12. <span id='question12'>"I'm right, _____ I?"</span><br></td><td><input type='radio' id='answer_44' name='answer11' value='a'>a) <span id='word4412' onclick='clickbutton(44, 12, ""I'm right, _____ I?"")'>

Diese zwei " bei clickbutton scheinen das Problem zu sein oder???
 
Werbung:
Ja, wobei die inneren ja ersetzt werden sollten.

PHP:
<?php

header('Content-type: text/plain');
echo htmlspecialchars('Dies ist \' ein " Test.', ENT_QUOTES);
 
Also bei der Testausschrift ensteht das hier:

Code:
Dies ist ' ein &quot; Test.

Doch wenn ich die Fragen durch die Funktion schicke werden die " nicht ersetzt. Die ' auch nicht.

Code:
onclick='clickbutton(87, 22, ""I'm right, _____ I?"")'

Hast du eine Idee wie ich das lösen kann?

Edit: Ok ich hatte das htmlspecialchars falsch benutzt. Jetzt ersetzt es auch bei den Radiobuttons die ".

Code:
onclick='clickbutton(80, 21, "&quot;I'm right, _____ I?&quot;")'

Doch komischerweise wird die Frage jetzt trotzdem nicht übergeben. -.- Die question variable kommt trotzdem leer bei meiner Funktion an.
 
Zuletzt bearbeitet:
Offenbar werden Entities in Inline-JavaScript-Code (Code, der direkt in einem HTML-Event-Handler steht) aufgelöst, bevor die JavaScript-Funktion aufgerufen wird.

Code:
<p>Inline</p>

<button onclick="alert('&auml;');">Ausgabe: "&auml;"</button>
<button onclick="alert('&amp;auml;');">Ausgabe: "&amp;auml;"</button>



<p>Nicht inline</p>

<script type="text/javascript">
    function a() { alert('&auml;'); }
</script>

<button onclick="a();">Ausgabe: "&amp;auml;"</button>

Das war mir jetzt ehrlichgesagt auch neu. :?

Edit: Also, dass Anführungszeichen-Entities wie syntaktische Anführungszeichen interpretiert werden. Wobei das vermutlich auch völlig logisch ist.[/edit]​

PHP:
<?php

function searchSZ($string)
{
    $string[0] = str_replace(array('"'     , '\''),
                             array('&quot;', '&'.'#039;'),
                             $string[0]);
    $string[0] = htmlspecialchars($string[0]);
    return $string;
}

$test[0] = 'Dies ist \' ein " Test.';

$test = searchSZ($test);

?>

<button onclick="document.getElementById('demo').innerHTML
                    = '<?php echo $test[0]; ?>';">Test</button>

<p id="demo">Ausgabe</p>
 
Zuletzt bearbeitet:
Werbung:
Das hier ist wahrscheinlich einfacher verständlich (und hoffentlich funktionstüchtig und sicher ;)):

PHP:
<?php

function escape($s)
{
    return htmlspecialchars($s, ENT_QUOTES);
}

$question = '"I\'m right, _____ I?"';

$jsCode = "replaceTest('" . escape('aren\'t') . "',
                       '" . escape($question) . "');";

?>

<script type="text/javascript">

function replaceTest(replace, subject)
{
    document.getElementById('output').innerHTML
            = subject.replace('_____',
                              '<em style="color: red;">' + replace + '</em>')
}

</script>

<button onclick="<?php echo escape($jsCode); ?>">Test</button>

<p id="output"></p>

Spaß für die ganze Familie...

PS: Suchbegriff zu dem Thema wäre "Kontextwechsel".
 
Schöner ist es übrigens, auf Inline-JavaScript zu verzichten und die Funktionszuweisungen an Event-Handler beim Laden des Dokuments per Script zu erledigen. Die benötigten Daten können zudem von PHP in eine JavaScript-Variable übertragen und von dort abgerufen werden.

Beispiel mit jQuery:

Code:
<?php

class Question
{
    protected $id;
    protected $question;
    protected $answers;

    public function __construct($id, $question, array $answers)
    {
        $this->id       = (int) $id;
        $this->question = (string) $question;
        $this->answers  = $answers;
    }

    public function getAnswers()
    {
        return $this->answers;
    }

    public function getQuestion()
    {
        return $this->question;
    }

    public function getId()
    {
        return $this->id;
    }

    public function convertToArray()
    {
        $a = array(
            'id'       => $this->id,
            'question' => $this->question,
            'answers'  => $this->answers
        );

        return $a;
    }
}

function escape($s)
{
    return htmlspecialchars($s, ENT_QUOTES);
}

$questions = array();
$questions[] = new Question(12, '"I\'m right, _____ I?"', array(
                                'ain\'t',
                                'aren\'t',
                                'am not',
                                'isn\'t'));
$questions[] = new Question( 8, 'Apples do not cost very _____.', array(
                                'much',
                                'many',
                                'moneys',
                                'lot'));
$questions[] = new Question(26, 'People from China are called _____.', array(
                                'Chinamen',
                                'Chinese',
                                'Chinish',
                                'Chinas'));

$jsonQuestions = array();

foreach ($questions as $q) {
    $jsonQuestions[] = $q->convertToArray();
}

?>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
<script type="text/javascript">

var questions = <?php echo json_encode($jsonQuestions); ?>;

$(document).ready(function () {
    $('.question-box').each(function () {
        var questionBox = $(this);
        $(this).find('.answer').click(function () {
            var answerText = $(this).next('.answer-text').html(),
                id = parseInt($(this).attr('name').replace(/[^\d]+/g, '')),
                i = -1;
                
            while (questions[++i]['id'] != id);

            questionBox.find('.question')
                .html(questions[i]['question'].replace('_____',
                    '<span class="question-answer-part" style="color: red;">'
                    + answerText + '</span>'));

            questionBox.find('.question-answer-part')
                .hide()
                .css('background-color', '#ff6')
                .fadeIn('slow', function () {
                    $(this).css('background-color', 'white');
                });
        })
    });
});

</script>

<?php if (!empty($_POST)): ?>
    <pre>
    <?php print_r($_POST); ?>
    </pre>
<?php endif; ?>

<form method="post" action="">

    <?php foreach ($questions as $q): ?>
    <div class="question-box">
        <p class="question"><?php echo escape($q->getQuestion()); ?></p>
        <ol>
            <?php foreach ($q->getAnswers() as $index => $text): ?>
            <li>
                <input type="radio" class="answer"
                       name="answers[<?php echo $q->getId(); ?>]"
                       value="<?php echo $index; ?>" />
                <span class="answer-text"><?php echo escape($text); ?></span>
            </li>
            <?php endforeach; ?>
        </ol>
    </div>
    <?php endforeach; ?>

    <p><input type="submit" value="Submit" /></p>

</form>
 
Dankeschön mit deiner searchSZ funktion oben funktioniert es, ich musste nur ein bisschen was anpassen. Tut mir wirklich leid das ich das einfach so übernehme aber aus Zeitgründen muss ich das leider. :neutral:

Vielen Dank für deine Mühe. :-D
 
Werbung:
Zurück
Oben