2016-12-21 6 views
0

私は家の暖房制御システムのプロトタイプフロントエンドを書いています。ユーザーがドロップダウンボックスから部屋と曜日を選択すると、 Redisデータベースを照会し、現在設定されている1時間ごとの温度を取得し、これを使用して温度ドロップダウンボックスに選択した値を設定します。ユーザーは1つまたは複数の値を変更して送信することができます。私は提出して作業を書いているだけで、私の頭を選択して設定することを試みている。ここで フラスコでHTMLドロップダウンの値を変更する

はHTMLです:

{% extends "bootstrap/base.html" %} 
{% block title %}Setting Room Temperatures{% endblock %} 
{% block navbar %} 
<div class="navbar navbar-fixed-top"> 
    <!-- ... --> 
</div> 
{% endblock %} 
{% block content %} 
</head> 
<body> 
<h1>Room temperature configuration</h1> 
<form action="{{ url_for('heating_config_form')}}" method="post" class="form-inline"> 
<div class="form-group"> 
<label for="roomselect">Room:</label> 
<select class="form-control" name="roomselect"> 
    <option value="dining">Dining</option> 
    <option value="kitchen">Kitchen</option> 
    <option value="lounge">Lounge</option> 
    <option value="study">Study</option> 
</select> 
</div> 
<br> 
<br> 
<div class="form-group"> 
<label for="dayselect">Day :</label> 
<select class="form-control" name="dayselect"> 
    <option value="monday">Monday</option> 
    <option value="tuesday">Tuesday</option> 
    <option value="wednesday">Wednesday</option> 
    <option value="thursday">Thursday</option> 
    <option value="friday">Friday</option> 
    <option value="saturday">Saturday</option> 
    <option value="sunday">Sunday</option> 
</select> 
</div> 
<br> 
<br> 
<div class="form-group"> 
<label for="1AM">1AM :</label> 
<select class="form-control" name="1AM"> 
    <option value="5">5</option> 
    <option value="6">6</option> 
</select> 
<label for="2AM">2AM :</label> 
<select class="form-control" name="2AM"> 
    <option value="5">5</option> 
    <option value="6">6</option> 
</select> 
</div> 
<br> 
<br> 
<button type="submit" value="submitted" name="update">Update temperature </button><br> 
<br> 
</form> 
<br> 
</body></html> 
{% endblock %}<html><head> 

そして、ここでのPythonフラスココード

from flask import Flask 
from flask import request 
from flask import render_template 
from flask_bootstrap import Bootstrap 
import redis 

app = Flask(__name__) 
app.debug = True 
bootstrap = Bootstrap(app) 

db = redis.Redis('localhost') 

@app.route('/', methods=['GET','POST']) 
def heating_config_form(): 
    error="" 
    if request.method == 'POST' and request.form['update'] == 'submitted': 
     Room = (request.form.get('roomselect')) 
     Day = (request.form.get('dayselect')) 
     AM1 = (request.form.get('1AM')) 
     AM2 = (request.form.get('2AM')) 
     key = (Room + "_" + Day) 
     db.hset(key, "1:00", AM1) 
     db.hset(key, "2:00", AM2) 
     return render_template('set-room-tempv5.html') 
    else : 
     return render_template('set-room-tempv5.html') 
if __name__ == '__main__': 
    app.run(host='0.0.0.0', debug=True) 

私は、このアプローチする、おそらくより良い方法があります知っていますが、シンプルを取得したい(WTFormsに?)私が理解しているインタフェースを理解しているので、私はFlaskを初めて使っているので、システムのプロトタイプを作成することができます。暖房システム全体がこれを選択する能力に依存しないようにしてください。

データベースに温度を追加すると、正常に動作し、これは私は多分、次のコンテキスト・プロセッサのようなものが助けることができると考えていたのRedis-CLIモニター

127.0.0.1:6379> monitor 
OK 
1482336847.287342 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "1:00" "5" 
1482336847.288042 [0 127.0.0.1:34180] "HSET" "kitchen_tuesday" "2:00" "5" 

からの典型的なモニタ出力のですか?

@app.context_processor 
def utility_processor(): 
    def retrieve_temp(sroom, sday, stime): 
     skey= (sroom + "_" + sday) 
     stemp = db.hget(skey, stime) 
     return stemp 
    return dict(retrieve_temp=retrieve_temp) 

これは、retrieve_temp関数をすべてのテンプレートで使用できるようにします。

何とかテンプレートがレンダリングされると、デフォルトのルームと曜日が時間のドロップダウンで "選択された"オプションを設定するために使用されます。そして、ルームと曜日のドロップダウンが移動されるたびに、 。

デフォルトでは、食事と月曜日は選択肢の最初のもので、1AMと2AMの温度が検索され、これらのドロップダウンのために選択されます(これ以上の温度があります。簡潔さのために削除されました)。部屋や日が変更された場合は、再度発生します。

+0

明確にするには、セレクトボックスのセットを使用します。セカンドボックスは最初の選択に基づいた値のみを表示します。最初のボックスの選択が変更されるたびに、データベースにpingを実行して適切な選択を取得して2番目の選択を入力するかどうかを確認します。 – abigperson

+0

それは公正な要約PJです。ユーザが部屋と昼を選択すると、その部屋/曜日の組み合わせのデータベースから各時間の適切な温度設定が検索され、適切なドロップダウン選択が行われます。たとえば、ユーザーがラウンジと火曜日を選択すると、その日の各時間の現在のすべての温度設定がデータベースに照会され、その時間に選択が設定されます。私は部屋/日を選択するページを持つ方が簡単かもしれないと思っています。一度それが提出されれば、新しいページはdbから適切なセレクトをドロップダウンボックスに表示します –

答えて

0

OK - 問題を解決するための情報を提供する前に、あなたの質問に確実に答えてください。コメントの中で代替案として概説したアプローチは、これを有効にする最も簡単な方法です(たとえば、最初の選択を行う中間ページなど)。

すべてのpythonまたはjinja2コードは1回だけ実行されることを覚えておくことが重要です。 Jinja2はいくつかのロジックを使用してHTML出力をレンダリングし、Flaskはブラウザに静的なHTMLページで応答しますので、context_processorを使用して特定のロジックをjinja2に渡すことができますが、Flaskはレンダリングした後にjavascript 。

あなたはjQueryのjavascriptライブラリを含むBootstrapを使用しているようです。 jQueryはDOMとのやりとりの仕方(DOM(Document Object Model)、HTML要素のjavascript表現など)に関して、いくつかのブラウザの特徴を扱うため、素晴らしいです(私の意見では)。

したがって、2番目の選択を動的に設定する場合は、ブラウザからFlaskエンドポイントにデータを送信して、必要なオプションを取得するために、別のHTTPリクエストを作成したり(ページを再ロードせずに)フロントエンドを更新します。

HTMLはこのように見えます(私はちょうどIDを追加しています)。forタグは名前ではなくIDフィールドを参照していると思います。

<div class="form-group"> 
    <label for="roomselect">Room:</label> 
    <select class="form-control" name="roomselect" id="roomselect"> 
     <option value="dining">Dining</option> 
     <option value="kitchen">Kitchen</option> 
     <option value="lounge">Lounge</option> 
     <option value="study">Study</option> 
    </select> 
</div> 

<div class="form-group"> 
    <label for="dayselect">Day:</label> 
    <select class="form-control" name="dayselect" id="dayselect"> 
     <option value="monday">Monday</option> 
     <option value="tuesday">Tuesday</option> 
     <option value="wednesday">Wednesday</option> 
     <option value="thursday">Thursday</option> 
     <option value="friday">Friday</option> 
     <option value="saturday">Saturday</option> 
     <option value="sunday">Sunday</option> 
    </select> 
</div> 

<div class="form-group"> 
    <label for="1AM">1AM:</label> 
    <select class="form-control" name="1AM" id="1AM"> 
     <option value="5">5</option> 
     <option value="6">6</option> 
    </select> 
    <label for="2AM">2AM:</label> 
    <select class="form-control" name="2AM" id="2AM" disabled> 
     <option value="5">5</option> 
     <option value="6">6</option> 
    </select> 
</div> 

その後、あなたは通常、あなたのHTMLの本体の底部にまたはリンクされたファイルでこれを行うには、JavaScriptのイベントリスナーとAJAXのメソッドを追加する必要があります:あなたが必要とする、

<script charset="utf-8" type="text/javascript"> 
    // this is called a javascript closure. it also wont run the code until the page is finished loading 
    // and it protects the scope of your variables from other code you may later add to the page 
    $(function() { 
     var select_room = $('#roomselect'), 
      select_day = $('#dayselect'), 
      select_1am = $('#1am'), 
      select_2am = $('#2am'); 

     select_room.on('change', function() { 
      // fires when room selection changes 
      getUpdatedSettings(); 
     }); 

     select_day.on('change', function() { 
      // fires when day selection changes 
      getUpdatedSettings(); 
     }); 

     function getUpdatedSettings() { 
      // data to send back to the server 
      var send = { 
       room: select_room.val(), 
       day: select_day.val() 
      }; 

      // make the selections disabled while fetching new data 
      select_1am.attr('disabled', true); 
      select_2am.attr('disabled', true); 

      $.getJSON("/_get_updated_settings", send, function(response) { 
       // this send the room and the day select vals to the URL specified 
       // we will need to add a handler for this in Flask 

       // for the purpose of the example I am assuming the response will be 
       // a JSON object that has a dictionary of elements ("am_1" and "am_2") 
       // each of which is a list of values for the selects.... 

       console.log(response); // good for QA! 

       // populate 1am 
       select_1am.empty(); 
       $.each(response.am_1, function (index, value) { 
        select_1am.append(
        $('<option>', { 
         value: value, 
         text: value 
        }, '</option>')) 
       }); 

       // populate 2am 
       select_2am.empty(); 
       $.each(response.am_2, function (index, value) { 
        select_2am.append(
        $('<option>', { 
         value: value, 
         text: value 
        }, '</option>')) 
       }); 

       // remove disabled now 
       select_1am.removeAttr('disabled'); 
       select_2am.removeAttr('disabled'); 
      }); 
     } 

    }); 
</script> 

このAJAXリクエストを処理するFlaskロジックを追加する:

from flask import jsonify 

@app.route('/_get_updated_settings') 
def get_updated_settings(): 
    # good for debug, make sure args were sent 
    print request.args 
    day = request.args.get('day', 'default_if_none') 
    room = request.args.get('room', 'default_if_none') 
    key = (room + "_" + day) 
    output = {} 
    # I have no idea what this returns...just doing a list generator here assuming we get a list of values 
    output['am_1'] = [x for x in db.hget(skey, '1am')] 
    output['am_2'] = [x for x in db.hget(skey, '1am')] 
    return jsonify(output) 

Ha ...私が予想していたよりも少し時間がかかりましたが、これは少なくともこのような機能を得るためにはストローマンを提供するべきです。 Javascriptはユーザーエクスペリエンスを向上させることは間違いありませんが、静的なページを埋め込む一連の中間フォームを使用することで、同じことを達成できます。

+0

あなたのお時間をありがとう、返信するが、最初にテストに基づいて質問があるかどうかを確認したいと思った。私はjqueryにさまざまなスコープの問題を持っていました。私よりもウェブに精通している同僚の助けを借りて、これらの問題を修正しました。ただし、jqueryスクリプトはselectイベントによってトリガーされません。私がページをリロードすると、論理的なスクリプトに関連付けられたフラスコのコンソールに304が表示され、ブラウザのコンソールで「reflow:0.43ms function n.event.fix、jquery.min.js line 3」と表示されますドロップダウンの選択。だから私はまだデバッグしています。 –

関連する問題