ログインしてさらにmixiを楽しもう

コメントを投稿して情報交換!
更新通知を受け取って、最新情報をゲット!

JavaScriptコミュの【質問】チェックボックス名をクリックすると反転する動的リスト

  • mixiチェック
  • このエントリーをはてなブックマークに追加
表題の件なのですが、行き詰ってしまったのでどなたかお知恵を貸してください。
リスト名をクリックするとチェックボックスにチェックが入るナビゲーションを、現在<a>タグを使用してonClickで行っています。これはこれとして成立していたのですが、さらに、擬似2次配列で

Ar1 = new Array ( "商品a\1000","商品b\2000"","商品c\3000"");//商品名
Ar2 = new Array ( "a", "b", "c");//商品コード
Ar3 = new Array ( "1000", "2000", "3000");//価格
var gds_col//桁数
if(( Ar1.length == Ar2.length)&&( Ar2.length == Ar3.length ))gds_col =
Ar1.length;
else alert("テーブルの桁が違います。");


といった配列を作ってhtmlを書き出し、
動的に注文フォームを作ろうとしています。
こんな感じ。

<!--
for (i=0; i<gds_col; i++){
document.write (
"<a href=\"#" + Ar2[i] + "\" name= \"" + Ar2[i] + "\"
onClick=\"document.AppForm.gds." + Ar2[i] + ".checked =true\">" +
Ar1[i] + "<input name=\"gds\" type=\"radio\" id=\"" + Ar2[i] + "\"
value=\"" + Ar3[i] + "\"></a>"
);
};
//-->

ところが、「';'がありません」というエラーがどうしても回避できなくて困っています。
このエラーを回避する方法がありましたらご指導いただければ幸いです。

また、リスト名をクリックするとチェックボックスにチェックが入るナビゲーションを、もっとスマートに(^^;実現する方法があれば、ご指導いただければ幸いです。

よろしくお願いいたします。

#js-mlにも同じ内容でpostしたのですが、12時間経っても配信されないようなので
#こちらにも書き込ませていただきました。マルチポストになっていたらご容赦ください。m(__)m

コメント(17)

>Ar1 = new Array ( "商品a\1000","商品b\2000"","商品c\3000"");//商品名

「"商品b\2000""」←""が2つ続いているようですが、これがマズいのではないでしょうか?
あ、すみません、実商品データを削除した時のコピペミスです。m(_ _)m
テーブルが正しくてもエラーとなります。
ありゃ、コピペミスでしたか。じゃああとは・・

エラー発生時に何行目で発生しているか出ますよね?
その行で

 ダブルクォート(")の開閉がちゃんとしていない

とか、その行の前後にある

 条件文や関数の()や{}の開閉がちゃんとしていない
 
が考えられますが、いかがでしょうか。


あと、for(;;){}; ←最後の;は不要です。
もう一丁。

テキストをクリックしたらチェックが反転する、のやり方は
Google検索ページのソースを覗くと書いてありますね。

<input>と<label>を駆使しましょう(^_^)
あら、<label>でいともあっさり解決してしまいました…。(恥

とりあえず、同じようなパターンはありそうなので、引き続き検討させていただきたいのですが、一応、平文表記した状態で問題なく動くのですが…。最後の;は苦心の果てだったり。
scriptキックするときにテーブル要素と突っ込むのがダメってことなんでしょうかね?
むむむ・・・これどうですかね。

 「;(セミコロン)」ではなく「:(コロン)」になってるところがある

よくあるタイプミスです。
今再現してみたらいとも簡単に「';'がありません」と言われました。

テーブル要素と突っ込むとダメというのは
ソース全体を見ないと何とも言えません(>_<;
いや、トピを見ていただければ分かるとおり、「いとも簡単に」出てしまうからこそ質問しているわけですが…。(--;
「:(コロン)」を使っている箇所は全文検索をしてもありませんし、「;(セミコロン)」が必要なところも、平文表記すれば動作するので見当がつかないんです。

とりあえず、自分で悩んでみます。
>"商品a\1000"
\がエスケープされてないようですが大丈夫ですか。
実ソースでは問題ないです。
このサンプルソースをちゃんと書き直さんとご意見も受けられないですね。
あとで修正してupします。
>onClick=\"
>value=\""
の前に改行が入ってるなら、それはまずいですね。
前の行を" +で終わるようにして、"で始めるようにしないと。

それから、先に連結して、1つの文字列だけをdocument.writeするほうが良いです。
もしかしたらもう解決されているかも知れませんが・・・。
document.write で出力している内容が、掲載されているとおりの改行状態であれば、mio さんが言われているように改行位置に問題があると思います。
で、ためしにちょこっと修正してみました。

Ar1 = new Array ( "商品a\\1000","商品b\\2000","商品c\\3000");//商品名
Ar2 = new Array ( "a", "b", "c");//商品コード
Ar3 = new Array ( "1000", "2000", "3000");//価格
var gds_col;//桁数
if(( Ar1.length == Ar2.length)&&( Ar2.length == Ar3.length ))gds_col = Ar1.length;
else alert("テーブルの桁が違います。");

document.write ( "<form name='AppForm'>" );
for (i=0; i<gds_col; i++){
document.write (
"<a href=\"#" + Ar2[i] + "\" name= \"" + Ar2[i] +
"\" onClick=\"document.AppForm.gds[" + i + "].checked =true\">" +
Ar1[i] + "<input name=\"gds\" type=\"radio\" id=\"" + Ar2[i] +
"\" value=\"" + Ar3[i] + "\"></a>"

);
}
document.write ("</form>");

修正した内容は、
・商品名内の「\」を「\\」に変更
・改行位置を「+」の後ろに変更
・onclickイベント時のラジオボタンへのアクセスを変更
gds." + Ar2[i] + ".checked
↓
gds[" + i + "].checked
・単体で動くように<form></form>も出力

これで大体期待した動きになるのではないかと思います。

エラーが出ていたのは、改行位置が悪くてちゃんと閉じられていない(引用符で始まって引用符で終わっていない)文字列と認識されていたのだと思います。
ありがとうございます。エスケープや改行、明け、閉じ括弧の類は問題ないです。お客さんに迷惑がかからないようにと変数やらなんやらいろいろ小細工したのがまずかったみたいです。しかも、その編集のためにBecky!に貼り付けたもので自動改行が入ってしまったようで。
そうか、checkって、gds[i]で行けばいいんですね。
結局引っかかっていたキモは、
javascriptで、

document.AppForm.item_name_" + i + ".value

とかって出力したものをscript上で拾うときにどうすればいいか?っていうことなんです。
当然っちゃ当然なんですけど、

alert("document.AppForm.item_name_" + i + ".value");

じゃ、

document.AppForm.item_name_0.value

にしかならないですよね?
数値ならeval()でくくれば出たんですけど、テキストの場合がうまく出せなくて。
FYIだと思うのですが、ちょっとどういうキーワードで探せばいいのか思いつかず…。

一応、紆余曲折あり、当初とは大幅に変わっていますが、こんな感じになっています。

<html>
<head>
<script language="JavaScript" type="text/JavaScript">
<!--
DefaultStatus = "データをロード中です。しばらくお待ちください。";

itm_nam = new Array ("microSD256","microSD512","microSD1G","microSD2G");//商品名
itm_ast = new Array ( "microSD", "microSD", "microSD", "microSD");//種別
itm_cap = new Array ( "256MB", "512MB", "1GB", "2GB");//容量
itm_pri = new Array ( "256", "512", "1024", "2048");//料金
var itm_col//桁数
var tot_pri_tmp//合計計算
if(( itm_nam.length == itm_cap.length)&&( itm_cap.length == itm_pri.length))itm_col = itm_nam.length;
else alert("商品名の桁が異なっています。管理者までご連絡ください。");

//-->
</script>
</head>
<body>
<form name="AppForm" id="Order">
<table width="600" border="1" cellpadding="0" cellspacing="0">
<tr>
<td align = "center" bgcolor = "#FFFFFF">商品名</td>
<td align = "center" bgcolor = "#FFFFFF">種別</td>
<td align = "center" bgcolor = "#FFFFFF">容量</td>
<td align = "center" bgcolor = "#FFFFFF">単価</td>
<td align = "center" bgcolor = "#FFFFFF">個数</td>
<td align = "center" bgcolor = "#FFFFFF">小計</td>
</tr>
<script language="JavaScript" type="text/JavaScript">
<!--
function tot_pri_val(){
tot_pri = 0
tot_pri_tmp = 0
for (i=0; i<itm_col; i++){
tot_pri_tmp = tot_pri;
itm_sum_tmp = eval("document.AppForm.itm_sum_" + i + ".value");
tot_pri = eval(tot_pri_tmp) + eval(itm_sum_tmp)
}
}
function on_chg_val(){
on_chg =
("onChange=\" ")+
(" itm_pri_tmp_" + i + " = ")+
(" eval(" + itm_pri[i] + ") ")+
(" * ")+
(" eval( ")+
(" document.AppForm.itm_num_10_" + i + ".value ")+
(" + ")+
(" document.AppForm.itm_num_01_" + i + ".value ")+
(" ), ")+
(" document.AppForm.itm_sum_" + i + ".value =itm_pri_tmp_" + i + ", ")+
(" tot_pri_val(), ")+
(" document.AppForm.price.value = tot_pri ")+
("\" ");
}
var num_sel =
("> ");
for (j=0; j<10; j++){
num_sel = num_sel+
("<option value=\"" + j + "\">" + j + "</option> ");
}

for (i=0; i<itm_col; i++){

on_chg_val();

var itm_tbl =
("<tr> ")+
(" <td align = \"center\" bgcolor = \"#FFFFFF\"> ")+
(" " + itm_nam[i] + " ")+
(" </td> ")+
(" <td align = \"center\" bgcolor = \"#FFFFFF\"> ")+
(" " + itm_ast[i] + " ")+
(" </td> ")+
(" <td align = \"right\" bgcolor = \"#FFFFFF\"> ")+
(" " + itm_cap[i] + " ")+
(" </td> ")+
(" <td align = \"right\" bgcolor = \"#FFFFFF\"> ")+
(" " + itm_pri[i] + " ")+
(" </td> ")+
(" <td align = \"right\" bgcolor = \"#FFFFFF\"> ")+
(" <select ")+
(" name=\"itm_num_10_" + i + "\" ")+
on_chg +
( "> ")+
num_sel +
(" </select> ")+
(" <select ")+
(" name=\"itm_num_01_" + i + "\" ")+
on_chg +
( "> ")+
num_sel +
(" </select> ")+
(" </td> ")+
(" <td align = \"right\" bgcolor = \"#FFFFFF\"> ")+
(" <input ")+
(" name=\"itm_sum_" + i + "\" ")+
(" type=\"text\" ")+
(" id=\"itm_sum_" + i + "\" ")+
(" value=\"0\" ")+
(" style=\"text-align:right\" ")+
(" onFocus = \"this.blur()\" ")+
(" > ")+
(" </td> ")+
("</tr> ")+
("<hidden> ");
document.write(itm_tbl)
}
//-->
</script>
<tr>
<td colspan="5" align="right" bgcolor = "#FFFFFF">合計</td>
<td align="right" bgcolor = "#FFFFFF">
<input name="price" type="text" id="price" style="text-align:right" onFocus="this.blur()" value="0">
</td>
</tr>
</table>
</form>
</body>
</html>

#実際にはタブで行頭を合わせています。
これで、各行の注文内容を引っ張り出すのに、上記が引っかかってうまく行きません。
引き続き、お知恵を拝借できれば幸いです。
#あと、こうしたらもっとスマートになるというご提案も大歓迎で…。
はじめまして&初めて投稿します。
オブジェクト指向的なアプローチを提案してみます。

<html>
<head>
<script language="JavaScript" type="text/JavaScript">
<!--
function xItem(nam, ast, cap, pri) {
this.name = nam;
this.ast = ast;
this.cap = cap;
this.pri = pri;
}
xItem.prototype = {
createRow : function(id) {
var tr = this.createElementTo(null, 'tr');
var td0 = this.createElementTo(tr, 'td', {align:"center", bgcolor:"#FFFFFF"}, this.name);
var td1 = this.createElementTo(tr, 'td', {align:"center", bgcolor:"#FFFFFF"}, this.ast);
var td2 = this.createElementTo(tr, 'td', {align:"right", bgcolor:"#FFFFFF"});
td2.innerHTML = (this.cap < 1024)? this.cap+"MB" : Math.round(this.cap/1024)+"GB";

var td3 = this.createElementTo(tr, 'td', {align:"right", bgcolor:"#FFFFFF"}, this.pri);
var td4 = this.createElementTo(tr, 'td', {align:"right", bgcolor:"#FFFFFF"});

this.sel10 = this.createSelect(td4, 'itm_num_10_'+id);
this.createTextTo(td4, " ");
this.sel01 = this.createSelect(td4, 'itm_num_01_'+id);
var td5 = this.createElementTo(tr, 'td', {align:"right", bgcolor:"#FFFFFF"});
td5.innerHTML = '<input name="itm_sum_'+ id + '" type="text" id="itm_sum_"' + id +'" value="0" style="text-align:right" / >';
this.sum = td5.firstChild;
this.sum.onselectstart = function() {return false;}
this.sum.onfocus = function() {this.blur();}

var me = this;
this.sel10.onchange = this.sel01.onchange = function() {me.chgVal()};
return tr;
},

chgVal : function() {
this.sum.value = this.pri * this.getCount();
tot_pri_val();
},

getCount : function() {
return parseInt(this.sel10.value + this.sel01.value);
},

getSum : function() {
return parseInt(this.sum.value);
},

createSelect : function(parent, name) {
var sel = this.createElementTo(parent, 'select', {name:name});
for(var i=0; i<10; i++) {
sel.options[i] = new Option(i, i);
}
return sel;
},

createElementTo : function(parent, nodeName, attrs, nodeValue) {
var elm = document.createElement(nodeName);
if (attrs) {
for(var i in attrs) {
elm[i] = attrs[i];
}
}
if (nodeValue) elm.innerHTML = nodeValue;
if (parent) parent.appendChild(elm);

return elm;
},

createTextTo : function(parent, nodeValue) {
var node = document.createTextNode(nodeValue);
parent.appendChild(node);
}
}

var items = [
new xItem("microSD256", "microSD", 256, 256),
new xItem("microSD512", "microSD", 512, 512),
new xItem("microSD1G" , "microSD", 1024, 1024),
new xItem("microSD2G" , "microSD", 2048, 2048)
]

function init() {
var tr = document.getElementById("product_sum");
for(var i=0; i<items.length; i++) {
tr.parentNode.insertBefore( items[i].createRow(i), tr);
}
}

function tot_pri_val(){
var sum = 0;
for (i=0; i<items.length; i++){
sum += items[i].getSum();
}
document.getElementById("price").value = sum;
}

window.onload = init;
//-->
</script>
</head>
<body>
<form name="AppForm" id="Order">
<table id="product" width="600" border="1" cellpadding="0" cellspacing="0">
<thead>
<tr>
<td align = "center" bgcolor = "#FFFFFF">商品名</td>
<td align = "center" bgcolor = "#FFFFFF">種別</td>
<td align = "center" bgcolor = "#FFFFFF">容量</td>
<td align = "center" bgcolor = "#FFFFFF">単価</td>
<td align = "center" bgcolor = "#FFFFFF">個数</td>
<td align = "center" bgcolor = "#FFFFFF">小計</td>
</tr>
</thead>
<tboody>
<tr id="product_sum">
<td colspan="5" align="right" bgcolor = "#FFFFFF">合計</td>
<td align="right" bgcolor = "#FFFFFF">
<input name="price" id="price" type="text" id="price" style="text-align:right" onFocus="this.blur()" value="0">
</td>
</tr>
</tbody>
</table>
</form>
</body>
</html>
>document.AppForm.item_name_" + i + ".value
よく分かりませんが、

document.AppForm.elements["item_name_" + i].value

じゃだめですか。
>しかも、その編集のためにBecky!に貼り付けたもので自動改行が入ってしまったようで。
現状あるものをそのまま出さないと、今度はデバッグしてくれようという人の迷惑になります。

で、オブジェクトを作るかどうかはともかく、document.writeやらname要素やら使わずに、DOMを操るほうが良いと思います。
document.writeはあくまでロード時のちょっとした作り替えに使えるもので、ロード後には使えないし、融通が効きません。
そうか、elementsですね。なるほど。
DOM使う方法も、ご提案のソース含めちょっと勉強してみます。
ソースの貼り付け方も気をつけるようにします。
ありがとうございました。

ログインすると、残り1件のコメントが見れるよ

mixiユーザー
ログインしてコメントしよう!

JavaScript 更新情報

JavaScriptのメンバーはこんなコミュニティにも参加しています

星印の数は、共通して参加しているメンバーが多いほど増えます。