おそらく説明が難しい問題を抱えているので、最善を尽くします。簡単な JavaScript の To-Do アプリを作成しようとして、いじってみました。ページに複数のフォームがあり、それらはすべて個々の日付 (1 月 1 日、1 月 2 日など) に対応しています。もちろん、各フォームには入力があります。この場合、各フォームには 4 つの子ノード (What、Where、When、および送信ボタン) があります。
HTMLは次のとおりです。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta description="Gallery, Javascript">
<link rel="stylesheet" href="todo.css" media="screen" />
<title>Creating a simple to-do app</title>
</head>
<body>
<div id="outerWrapper">
<div id="wrapper">
<header id="header">
<h1>A simple to-do app</h1>
</header>
<section id="todo">
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 1st, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 2nd, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 3rd, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 4th, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 5th, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 6th, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
<div class="oneDateSection">
<div class="orangeBox">
<h1>January 7th, 2013</h1>
</div>
<div class="oneDateSectionList">
<form method="POST" class="formList" action="">
<div><label for="what">What:</label><input type="text" name="what" class="what" id="what" /></div>
<div><label for="where">Where:</label><input type="text" name="where" class="where" id="where" /></div>
<div><label for="what">When:</label><input type="text" name="when" class="when" id="when"/></div>
<div><input type="submit" value="Add!" name="submit" class="submit" /></div>
</form>
</div>
</div>
</section>
</div>
</div>
<script src="todo2.js"></script>
</body>
</html>
JavaScript は次のとおりです。
var utilities = {
$: function(id) {
return document.getElementById(id);
},
addEvent: function(obj, type, fn) {
if (obj && obj.addEventListener) {
obj.addEventListener(type, fn, false);
} else if (obj && obj.attachEvent) {
obj.attachEvent("on" + type, fn);
}
}
}
function removeErrorMessage(id) {
'use strict';
var span = utilities.$(id + 'Error');
if(span) {
span.parentNode.removeChild(span);
}
}
function addErrorMessage(id, msg) {
'use strict';
var elem = utilities.$(ID);
var newID = id + "Error";
var span = utilities.$(newID);
if(span) {
span.firstChild.value = msg;
} else {
span = document.createElement("span");
span.setAttribute("class", "error");
span.setAttribute("id", newID);
span.appendChild(document.createTextNode(msg));
elem.parentNode.appendChild(span);
}
}
function storeInformation(e) {
'use strict';
if (e == "undefined") {
e = window.event;
}
//Reference what, where and when input elements in form that calls this function
var whatElements = this.getElementsByClassName("what");
var whereElements = this.getElementsByClassName("where");
var whenElements = this.getElementsByClassName("when");
//Create object to store information
var information = {
what: whatElements[0].value,
where: whereElements[0].value,
when: whenElements[0].value,
postedDate: new Date()
}
//Create HTML that will display information from form
var output = "What: " + information.what + "<br />" +
"Where: " + information.where + "<br />" +
"When: " + information.when + "<br />" +
"Posted: " + information.postedDate;
//So you have TWO options. Either you have filled it out, or you haven't.
//First case, and main IF: Some part of the form hasn't been filled out
if ( (information.what == "") || (information.where == "") || (information.when == "") ) {
//If the 'what' form field is empty
if (information.what == "") {
addErrorMessage(this.what, "Please enter what!");
} else {
removeErrorMessage(this.getElementById("what"));
}
//If the 'where' form field is empty
if(information.where == "") {
addErrorMessage(this.where, "Please enter where!");
} else {
removeErrorMessage(this.getElementById("where"));
}
//If the 'when' form field is empty
if(information.when == "") {
addErrorMessage(this.when, "Please enter when!");
} else {
removeErrorMessage(this.getElementById("when"));
}
//OR, all the form fields HAVE BEEN FILLED OUT.
} else {
if (paragraph) {
paragraph.innerHTML = output;
} else {
var newDiv = document.createElement("div");
newDiv.setAttribute("class", "outputDiv");
var paragraph = document.createElement("p");
paragraph.setAttribute("class", "outputParagraph");
newDiv.appendChild(paragraph);
paragraph.innerHTML = output;
//Append everything
whatElements[0].parentNode.parentNode.appendChild(newDiv);
}
}
//Prevent form from submitting
if (e.preventDefault) {
e.preventDefault();
} else {
e.returnValue = false;
}
return false;
}
window.onload = function() {
'use strict';
var allForms = document.getElementsByClassName("formList");
for (var i = 0, count = allForms.length; i < count; i++) {
utilities.addEvent(allForms[i], "submit", storeInformation);
}
}
さて、おそらくレイアウトの問題と不適切な JS がここにあると確信しています (それを指摘していただけると助かります)。ただし、私の問題はthisキーワードにあります。JS では、フォームの入力 ID を参照するために、this.what、this.where、this.when を使用しています。私が「this」を使用しているのは、ページ上に複数のフォームがあり、イベント リスナーに渡すためです。これにより、実際の使用では、エンド ユーザーが使用するフォームが何であれ、正しい情報が格納されます。
問題は私の 'addErrorMessage' 関数にあります。'elem' は null と言われています。Chrome のデバッガーでプロセスをステップ実行した後、パラメーターとして addErrorMessage に渡される ID は引き続きフォームを参照しますが、何らかの理由で elem に格納されません。
たとえば、「this.what」は別の関数に引き継がれないのでしょうか? つまり、独自のプロパティを参照するフォームは別の関数で使用できませんか? 何が問題なのかわからない。Chrome は、「this.what」の値が正しく参照されていることを教えてくれ、「addErrorMessage」に渡されますが、この情報を「elem」に保存しようとするダイスはありません。
誰でも助けることができますか?私は今のところ JS 派ではありませんので、お手柔らかにお願いします。質問が長くなってすみません!
乾杯。