javascriptを学習しています。
追加ボタンを押した際に「[namae]さん[nickname]を登録します。よろしいですか?」 という確認ダイアログ(confirm)を挟み、 ok ボタンを押した場合のみ入力値が追記されるように変更しなさい。
([namae]、[nickname]の部分は入力値で置換されること).という問題がありました。
キャンセルボタンを押しても追記されてしまいます。
どなたかご教授お願いいたします。
『javascript』
<script>
let tuikaTimes = 0;
let result = document.getElementById('result');
let hyoji = document.getElementById("tuikaBtn");
tuikaBtn.addEventListener('click', function () {
let namae = document.getElementById("namae");
let nickname = document.getElementById("nickname");
if( namae.value===""||nickname.value==="") { return false; }
if(!window.confirm('「'+'['+namae.value+']' + 'さん' +'['+ nickname.value +']'+ 'を登録します。よろしいですか?」')) {
return false;
}
alert('「'+'['+ namae.value + ']' + 'さん' + '[' + nickname.value + ']'+'にて登録しました。」');
tuikaTimes++;
if(tuikaTimes >= 3) {
hyoji.style.visibility="hidden";
return false;
}
});
window.addEventListener('DOMContentLoaded', ()=>{
tuikaBtn.addEventListener('click',()=>{
let tbl=result.querySelector('table');
if(!tbl){
tbl=document.createElement('table');
result.appendChild(tbl);
}
const v1=namae.value;
const v2=nickname.value;
if(v1 && v2){
const tr=[v1,v2].reduce( (x,y)=>(x.appendChild( Object.assign( document.createElement('td'),{textContent:y})),x),document.createElement('tr'));
tr.appendChild(Object.assign( document.createElement('input'),{type:'button',value:'削除',className:'del'}));
tbl.appendChild(tr);
namae.value='';
nickname.value='';
}
});
});
document.addEventListener('click',e=>{
if(e.target.matches('.del')){
tuikaTimes--; hyoji.style.visibility="visible";
e.target.closest('tr').remove();
}
});
</script>
</body>
</html>
A 回答 (6件)
- 最新から表示
- 回答順に表示
No.6
- 回答日時:
No3です。
>~~追記されるように変更しなさい。~~という問題がありました。
問題や課題であるのならば、それまでに学習したことの延長になっているはずです。
ですので、もしもわからないのであれば、復習をするのが最良の方法です。
>分かる範囲でご教示いただけると幸いです。
DOM操作のスクリプトは、HTMLの構造と密接に関係します。
HTMLが全く不明の状態ですので、何もわからないとも言えます。
(回答者には質問文に記されていること以外は分かりませんので)
HTMLがidやclassだらけになっていれば多少は想定できますが、それでも構造は必要ですね。
文章で回答できる範囲であれば、すでにNo3に記した通りです。
また、あちこちで同じ質問をやたら繰り返しているようですが・・
https://teratail.com/questions/rq530w2k4y136w
https://detail.chiebukuro.yahoo.co.jp/qa/questio …
https://detail.chiebukuro.yahoo.co.jp/qa/questio …
回答が無いのならまだしも、回答(=ベストアンサー)があるのにも関わらず、反応を見ていると回答の内容を理解できていないのではないかと懸念します。
ついでながら、ご質問には直接関係はありませんけれど・・
登録、削除が自由にできる操作を想定していながら、目視で確認できるにもかかわらず、毎回「登録します」の確認や、「登録しました」などのメッセージを表示するのも、UIとしてはいかがなものかと感じますけれど・・・
更に言うなら、通常は何かの登録の際には、nameあるいはnicknameが他の登録者と重複しないようにチェックを行うものと思いますが、その辺りに関して何らかの処置を考えている様にはまったく見受けられません。
ですので、ご質問のスクリプトは、いったい「何の目的で、どのようなシチュエーションを想定して」いるのかすらも推測できかねる状態です。
No.5
- 回答日時:
No4です。
>3回目の表記で完全にボタンを非表示にするためには、
Object.assginについては、以下のサイトが参考になります。
https://developer.mozilla.org/ja/docs/Web/JavaSc …
もちろん、.style.visibility="hidden";を使っても良いと思います。
No.4
- 回答日時:
No3さんのご指摘がもっともだと思ったので、
少し修正してみました。
なお、fetch apiはmdnに解説があります。
https://developer.mozilla.org/ja/docs/Web/API/Fe …
<input type="text" id="namae" />
<input type="text" id="nickname" />
<input type="button" id="tuikaBtn" value="追加ボタン" />
<table id="result-table">
<thead>
<tr>
<th>名前</th>
<th>ニックネーム</th>
<th>削除</th>
</tr>
</thead>
</table>
<script>
class NameTable {
constructor() {
this.data = [];
this.table = document.getElementById('result-table');
this.tbody = this.table.createTBody();
this.btn = document.getElementById("tuikaBtn");
this.input_namae = document.getElementById("namae");
this.input_nickname = document.getElementById("nickname");
}
handleEvent(e) {
if (e.target === this.btn) {
const name_value = this.input_namae.value,
nickname_value = this.input_nickname.value;
if (this.checkTsuika(name_value, nickname_value)) {
this.pushData(name_value, nickname_value);
this.createTable();
};
} else if (e.target.matches('.del')) {
this.clickDel(e.target);
}
}
pushData(name, nickname) {
/* DBなどに追加する場合は、ここでfetchなどで通信 */
this.data.push({ name: name, nickname: nickname });
window.alert(`「[${name}]さん[${nickname}]にて登録しました。」`);
this.input_namae.value = '';
this.input_nickname.value = '';
if (this.data.length > 2) {
Object.assign(this.btn, {
value: 'これ以上追記できません',
disabled: true,
});
}
}
createTable() {
while (this.tbody.firstChild) {
this.tbody.removeChild(this.tbody.firstChild);
}
this.data.forEach(d => {
const tr = this.tbody.insertRow(-1);
tr.insertCell(0).appendChild(document.createTextNode(d.name));
tr.insertCell(1).appendChild(document.createTextNode(d.nickname));
const input_del = document.createElement('input');
Object.assign(input_del, {
type: 'button',
value: '削除',
className: 'del',
});
tr.insertCell(2).appendChild(input_del);
});
}
checkTsuika(name, nickname) {
if (name === "" || nickname === "") {
window.alert('両方入力してください');
return false;
}
if (!this.data.every(d => d.name !== name)) {
window.alert(`${name}さんはすでに登録されています`);
return false;
}
return window.confirm(`「[${name}]さん[${nickname}]を登録します。よろしいですか?」`);
}
clickDel(target) {
/* fetchなどで削除を送信 */
window.alert('削除しました');
const dels = [...this.tbody.querySelectorAll('.del')];
this.data = this.data.filter((_, i) => dels[i] !== target);
this.createTable();
Object.assign(this.btn, {
value: '追加ボタン',
disabled: false,
});
}
}
// 実行
window.addEventListener('DOMContentLoaded', () => {
const table = new NameTable();
document.addEventListener('click', table, false);
});
</script>
ご指導ありがとうございます。
参考にさせて頂きます。
3回目の表記で完全にボタンを非表示にするためには、
value: 'これ以上追記できません',
ここを変える必要がありますよね。
調べておりますが、分かる範囲でご教示いただきたいです。
No.3
- 回答日時:
こんにちは
>キャンセルボタンを押しても追記されてしまいます。
confirmの戻り値を元に、処理を制御すれば良いのですが、そうなっていませんよね?
confirmで「OK」を押したときには、Trueが返されますので、
if( confirm("~~")) {
// 登録処理
}
という流れにしておけば良いのですが、ご提示のスクリプトでは
・「登録します」というメッセージを表示する
・既登録数によって、ボタンの表示/非表示を制御する
だけの内容になっています。
一方で、実際の登録処理は、confirmとは無関係に、無条件で処理されるように設定(=addEventListener)されています。
ですので、ご質問のようなことになっていると考えられます。
このあたりの、処理の制御を修正なされば、意図通りの動作になるでしょう。
なお、ご質問には関係ありませんけれど・・
・同じ名前でも何度でも登録可能
・「登録」と言っても、実際にはどこにも登録してはいない
(リロードすれば、白紙状態に戻る)
となっており、実際には何をなさりたいのかも不明です。
また、HTMLが不明ですので、ざっと見ただけですけれど・・
・tableが存在しない場合も想定しているが、実際に起こり得る状態なのか
・tr、tdの生成に大層持って回った記述をなさっていますけれど・・・
などの点も疑問です。
ご指導ありがとうございます。
至らぬ点ばかりで大変申し訳ございません。
addEventListenerとreturn falseを同時に使用しても効かないことがわかりました。
調べておりますが、処理の仕方がうまく行っておりません。
分かる範囲でご教示いただけると幸いです。
No.2
- 回答日時:
こんなふうでしょうか。
<input type="text" id="namae" />
<input type="text" id="nickname" />
<input type="button" id="tuikaBtn" value="追加ボタン" />
<div id="result">
<table></table>
</div>
<script>
let tuikaTimes = 0;
const result = document.getElementById('result');
const tbl = result.querySelector('table');
if (!tbl) {
tbl = document.createElement('table');
result.appendChild(tbl);
}
const hyoji = document.getElementById("tuikaBtn");
function clickTsuika() {
const namae = document.getElementById("namae");
const nickname = document.getElementById("nickname");
const v1 = namae.value;
const v2 = nickname.value;
if (v1 === "" || v2 === "") { return false; }
if (!window.confirm(`「[${v1}]さん[${v2}]を登録します。よろしいですか?」`)) {
return false;
}
const tr = [v1, v2].reduce((x, y) => (x.appendChild(Object.assign(document.createElement('td'), { textContent: y })), x), document.createElement('tr'));
tr.insertCell(-1).appendChild(Object.assign(document.createElement('input'), { type: 'button', value: '削除', className: 'del' }));
tbl.appendChild(tr);
alert(`「[${v1}]さん[${v2}]にて登録しました。」`);
namae.value = '';
nickname.value = '';
tuikaTimes++;
if (tuikaTimes >= 3) {
hyoji.style.visibility = "hidden";
return false;
}
}
function clickDel(e) {
tuikaTimes--;
hyoji.style.visibility = "visible";
e.target.closest('tr').remove();
}
// 実行
window.addEventListener('DOMContentLoaded', () => {
document.addEventListener('click', e => {
if(e.target.matches('#tuikaBtn')) {
clickTsuika();
}else if(e.target.matches('.del')) {
clickDel(e);
}
});
});
</script>
No.1
- 回答日時:
もしかしたらこんな感じかもしれません。
<input type="text" id="namae" />
<input type="text" id="nickname" />
<input type="button" id="tuikaBtn" value="追加ボタン" />
<div id="result">
<table></table>
</div>
<script>
let tuikaTimes = 0;
let result = document.getElementById('result');
let hyoji = document.getElementById("tuikaBtn");
window.addEventListener('DOMContentLoaded', () => {
hyoji.addEventListener('click', function () {
let namae = document.getElementById("namae");
let nickname = document.getElementById("nickname");
if (namae.value === "" || nickname.value === "") { return false; }
if (!window.confirm('「' + '[' + namae.value + ']' + 'さん' + '[' + nickname.value + ']' + 'を登録します。よろしいですか?」')) {
return false;
}
alert('「' + '[' + namae.value + ']' + 'さん' + '[' + nickname.value + ']' + 'にて登録しました。」');
tuikaTimes++;
if (tuikaTimes >= 3) {
hyoji.style.visibility = "hidden";
return false;
}
let tbl = result.querySelector('table');
if (!tbl) {
tbl = document.createElement('table');
result.appendChild(tbl);
}
const v1 = namae.value;
const v2 = nickname.value;
if (v1 && v2) {
const tr = [v1, v2].reduce((x, y) => (x.appendChild(Object.assign(document.createElement('td'), { textContent: y })), x), document.createElement('tr'));
tr.appendChild(Object.assign(document.createElement('input'), { type: 'button', value: '削除', className: 'del' }));
tbl.appendChild(tr);
namae.value = '';
nickname.value = '';
}
});
});
document.addEventListener('click', e => {
if (e.target.matches('.del')) {
tuikaTimes--; hyoji.style.visibility = "visible";
e.target.closest('tr').remove();
}
});
お忙しい所、ご回答ありがとうございます。
大変感謝いたします。
やってみたところ、キャンセルボタンがしっかりと動いてくれました。
ただ、条件にある入力した 名前 と ニックネーム を最大3人分までテーブル表示できるようにすること、データを3件入力して追加ボタンを消すようにしたが、削除ボタンでデータが削除され3件未満になった場合は追加ボタンを再表示させ、3件になるまで追加し直せるようにすることができなくなったため、調べている所です。
もしお分かりであれば、ご教授いただけると幸いです。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・「みんな教えて! 選手権!!」開催のお知らせ
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~1/20】 追い込まれた犯人が咄嗟に言った一言とは?
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・【選手権お題その3】この画像で一言【大喜利】
- ・【お題】逆襲の桃太郎
- ・自分独自の健康法はある?
- ・最強の防寒、あったか術を教えてください!
- ・【大喜利】【投稿~1/9】 忍者がやってるYouTubeが炎上してしまった理由
- ・歳とったな〜〜と思ったことは?
- ・ちょっと先の未来クイズ第6問
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・【選手権お題その2】この漫画の2コマ目を考えてください
- ・【選手権お題その1】これってもしかして自分だけかもしれないな…と思うあるあるを教えてください
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
onchangeイベントを強制的に発...
-
ボタンかリンクをクリックする...
-
javaScriptの変数をJavaの変数...
-
Firefoxでwindow.openerが動作...
-
JavaScriptのfileオブジェクト...
-
formのfileの値をhiddenでも持...
-
JavaScriptによるnull判定
-
クリックでテーブル内の背景色...
-
マウス座標の値を保存する方法...
-
クリックさせたいが、click()が...
-
innerHTML内では改行は禁止?
-
オンクリックで現在時刻の取得→...
-
JavaScriptで特定のtdタグにcla...
-
プルダウン選択を変更すると、...
-
return trueとreturn falseの用...
-
ラジオボタンにタブインデック...
-
jQuery セレクトボックスで選択...
-
全てのselect要素をデフォルト...
-
一覧から選択した行の行番号を...
-
selectを変更不可にしたい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
onchangeイベントを強制的に発...
-
onclickが動作しない
-
JavaScriptのfileオブジェクト...
-
クリックさせたいが、click()が...
-
formのfileの値をhiddenでも持...
-
javascriptで作成されたテーブ...
-
javaScriptの変数をJavaの変数...
-
追加ボタンを押した際に ok ボ...
-
innerHTML内では改行は禁止?
-
onClickがinput type="image"だ...
-
jQueryで設定したイベントハン...
-
VB.NETで<Input>タグ、<text...
-
ボタンかリンクをクリックする...
-
URL 判定
-
クリックでテーブル内の背景色...
-
jQueryでshow/hideが上手く行か...
-
親ウィンドウのフォームの値を変更
-
開いた子ウィンドウにあるボタ...
-
ボタンをクリックするとテキス...
-
インラインフレームから親ウィ...
おすすめ情報
条件としては、
・名前とニックネームを3回追記したらボタンを非表示にし、それ以降は追記できないようにすること。
・tableタグとそれに関連するタグを利用し、入力した 名前 と ニックネーム を最大3人分までテーブル表示できるようにすること。
・データを3件登録して追加ボタンを消すようにしたが、削除ボタンでデータが削除され3件未満になった場合は追加ボタンを再表示させ、3件になるまで追加し直せるようにすること
これらも同時に操作できるようにしたいです。
宜しくお願いいたします。