質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

1600閲覧

一つだけ数値を増減したいのに、すべて同期されてしまう

Seiwell

総合スコア54

Flask

FlaskはPython用のマイクロフレームワークであり、Werkzeug・Jinja 2・good intentionsをベースにしています。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

1クリップ

投稿2021/12/04 08:32

編集2021/12/04 21:39

PythonのFlask+HTML+Javascriptで簡単な書籍管理システムを作成しています。

問題点

競合人数を設定するボタン(+と-)ボタンがあり、そのボタンを押すと入力されている値が増減するようになっています。
しかし、どれか一つのボタンを押しても、すべての値が連動してしまいます。
どのようにすれば、連動しないようになりますか?

ファイル構成

/
├ templates
│ └ index.html
└app.py

ソースコード

app.py

from flask import Flask, render_template, request, session, url_for, redirect, jsonify, g from flask.views import MethodView import sqlite3, pickle app = Flask(__name__) # get Database Object. def get_db(): db = sqlite3.connect('all_data.db') return db # close Database Object. def close_db(e=None): db = g.pop('db', None) if db is not None: db.close() def data_get(): book_data = [] db = get_db() cur = db.execute("select * from book_management_db") book_data = cur.fetchall() return book_data @app.route('/') def index(): book_data = data_get() return render_template('index.html', title='書籍管理システム', data=book_data) @app.route('/', methods=['POST']) def post(): label = request.form.get("label") db = get_db() db.execute(f"UPDATE book_management_db set people = {label.split(':')[1]} where book_name = {label.split(':')[0]}") db.commit() book_data = data_get() return render_template("index.html", title=f"書籍管理システム+{label}", data=book_data) if __name__ == '__main__': app.run(debug=True)

index.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <title>{{title}}</title> </head> <body> <h1>{{title}}</h1> <table class="table table-bordered table-striped"> <thead> <tr> <th scope="col">#</th> <th scope="col">書籍名</th> <th scope="col">競合人数</th> </tr> </thead> <tbody> {% for item in data %} <tr> <th>{{loop.index}}</th> <th scope="row">{{item[0]}}</th> <td> <form action="/" method="POST"> <div class="spinner_area"> <input type="number" value="0" class="counter1" data-max="500" data-min="0"> <input type="button" value="+" class="btnspinner" data-cal="1" data-target=".counter1"> <input type="button" value="-" class="btnspinner" data-cal="-1" data-target=".counter1"> <input class="btn btn-outline-success" type="submit" value="保存する"> </div> </form> </td> </tr> {% endfor %} </tbody> </table> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=1.12.4"></script> <script> $(function(){ var arySpinnerCtrl = []; var spin_speed = 20; //変動スピード //長押し押下時 $('.btnspinner').on('touchstart mousedown click', function(e){ if(arySpinnerCtrl['interval']) return false; var target = $(this).data('target'); arySpinnerCtrl['target'] = target; arySpinnerCtrl['timestamp'] = e.timeStamp; arySpinnerCtrl['cal'] = Number($(this).data('cal')); //クリックは単一の処理に留める if(e.type == 'click'){ spinnerCal(); arySpinnerCtrl = []; return false; } //長押し時の処理 setTimeout(function(){ //インターバル未実行中 + 長押しのイベントタイプスタンプ一致時に計算処理 if(!arySpinnerCtrl['interval'] && arySpinnerCtrl['timestamp'] == e.timeStamp){ arySpinnerCtrl['interval'] = setInterval(spinnerCal, spin_speed); } }, 500); }); //長押し解除時 画面スクロールも解除に含む $(document).on('touchend mouseup scroll', function(e){ if(arySpinnerCtrl['interval']){ clearInterval(arySpinnerCtrl['interval']); arySpinnerCtrl = []; } }); //変動計算関数 function spinnerCal(){ var target = $(arySpinnerCtrl['target']); var num = Number(target.val()); num = num + arySpinnerCtrl['cal']; if(num > Number(target.data('max'))){ target.val(Number(target.data('max'))); }else if(Number(target.data('min')) > num){ target.val(Number(target.data('min'))); }else{ target.val(num); } } }); </script> </body> </html>

データベースの構造

ファイル名:all_data.db
テーブル名:book_management_db

book_namepeople
コーパス30000
一億人の英文法0
チャート式 基礎と演習 数学Ⅱ+B0

book_nameが本の名前、peopleが競合人数

※競合人数→その本を借りたい人が今どれだけいるのかという人数のこと

参考にしたサイト

HTMLフォームの数値入力で増減(スピナー)ボタンを実装

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/12/04 10:48 編集

スピナーの連動を切り離す方法はすぐわかるのですが、それを直しても、現状「保存する」を押したときにエラーになります。 このエラーを解決するには、 book_management_db(all_data.db) のデータ構造 (カラム名及び、各カラムにどのようなデータが入っているのか、 及び、それらがフォーム上の「書籍名」・「競合数」とどういう関係なのか) がわからないと解析しようがありません。 したがって、book_management_db(all_data.db) の構造を明示していただけないでしょうか。
Seiwell

2021/12/04 21:40

データベースの構造を追加させていただきました。
guest

回答2

0

回答者様のヒントを得て自己解決できました。ありがとうございました。

解決方法としては、各+-ボタンのdata-target{{loop.index}}で数字を変えることによってスピナーの動作を分離することができました。
下記に、最終的なソースコードを載せておきます。

app.py

from flask import Flask, render_template, request, session, url_for, redirect, jsonify, g from flask.views import MethodView import sqlite3, pickle app = Flask(__name__) # get Database Object. def get_db(): db = sqlite3.connect('all_data.db') return db # close Database Object. def close_db(e=None): db = g.pop('db', None) if db is not None: db.close() def data_get(): book_data = [] db = get_db() cur = db.execute("select * from book_management_db") book_data = cur.fetchall() return book_data @app.route('/') def index(): book_data = data_get() return render_template('index.html', title='書籍管理システム', data=book_data) @app.route('/', methods=['POST']) def post(): label = request.form.get("label") db = get_db() db.execute(f"UPDATE book_management_db set people = {label.split(':')[1]} where book_name = {label.split(':')[0]}") db.commit() book_data = data_get() return render_template("index.html", title=f"書籍管理システム+{label}", data=book_data) if __name__ == '__main__': app.run(debug=True)

index.html

<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous"> <title>{{title}}</title> </head> <body> <h1>{{title}}</h1> <table class="table table-bordered table-striped"> <thead> <tr> <th scope="col">#</th> <th scope="col">書籍名</th> <th scope="col">競合人数</th> </tr> </thead> <tbody> {% for item in data %} <tr> <th>{{loop.index}}</th> <th scope="row">{{item[0]}}</th> <td> <form action="/" method="POST"> <div class="spinner_area"> <input type="number" value="0" class="counter{{loop.index}}" data-max="500" data-min="0"> <input class="btn btn-outline-success" type="submit" value="保存する" formtarget="counter1"> </div> </form> <input type="button" value="+" class="btnspinner" data-cal="1" data-target=".counter{{loop.index}}"> <input type="button" value="-" class="btnspinner" data-cal="-1" data-target=".counter{{loop.index}}"> </td> </tr> {% endfor %} </tbody> </table> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js?ver=1.12.4"></script> <script> $(function(){ var arySpinnerCtrl = []; var spin_speed = 20; //変動スピード //長押し押下時 $('.btnspinner').on('touchstart mousedown click', function(e){ if(arySpinnerCtrl['interval']) return false; var target = $(this).data('target'); arySpinnerCtrl['target'] = target; arySpinnerCtrl['timestamp'] = e.timeStamp; arySpinnerCtrl['cal'] = Number($(this).data('cal')); //クリックは単一の処理に留める if(e.type == 'click'){ spinnerCal(); arySpinnerCtrl = []; return false; } //長押し時の処理 setTimeout(function(){ //インターバル未実行中 + 長押しのイベントタイプスタンプ一致時に計算処理 if(!arySpinnerCtrl['interval'] && arySpinnerCtrl['timestamp'] == e.timeStamp){ arySpinnerCtrl['interval'] = setInterval(spinnerCal, spin_speed); } }, 500); }); //長押し解除時 画面スクロールも解除に含む $(document).on('touchend mouseup scroll', function(e){ if(arySpinnerCtrl['interval']){ clearInterval(arySpinnerCtrl['interval']); arySpinnerCtrl = []; } }); //変動計算関数 function spinnerCal(){ var target = $(arySpinnerCtrl['target']); var num = Number(target.val()); num = num + arySpinnerCtrl['cal']; if(num > Number(target.data('max'))){ target.val(Number(target.data('max'))); }else if(Number(target.data('min')) > num){ target.val(Number(target.data('min'))); }else{ target.val(num); } } }); </script> </body> </html>

投稿2021/12/04 21:54

Seiwell

総合スコア54

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Seiwell

2021/12/04 22:40

スピナーの分離はできたものの、保存するボタンを押した際に`None`と返ってきます。 保存するを押した際に`value`値をPOSTする方法が分かる方いたら教えていただけると幸いです。
退会済みユーザー

退会済みユーザー

2021/12/04 23:03 編集

すでにスピナーの件で完了しているので、別質問で立ててください
guest

0

ベストアンサー

---------- 引用 ----------

html

1<input type="number" value="0" class="counter1" data-max="500" data-min="0"> 2<input type="button" value="" class="btnspinner" data-cal="1" data-target=".counter1"> 3var target = $(this).data('target');

---------- 引用 ----------

ループで複数の行(<tr>)を表示していると思いますが、
行を識別するのに、全ての行がcounter1になってしまっているように見えます。
Flaskを使い込んだことがないので具体的にはわからないですが、
このcounter1の部分をcounter2,counter3のように変更することで解消できるように見えました。

投稿2021/12/04 10:13

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問