初心者向けWEBアプリ開発のコツ(2)

##はじめに
今日のソースはフロントエンド側の話。。。

WEBアプリ開発においては、JAVASCRIPTの習得が必須。
これはバックエンド＋フロントエンド＝ＷＥＢアプリみたいに、
対で成立するものであって、どっちがどうとか言う問題ではない。

つまりFLASKをPYTHONのライブラリと思っていれば良いという事でなく、
FLASK＝PYTHON＋JAVASCRIPTということ
（ここでHTML,CCSのことは、必要最低限できているのが前提にあるが）

##参考ソース
Python(FLASK) - SQLite　で発見
https://github.com/zeeshanshamsuddeen/Online-Food-Ordering-System

##テンプレート

ルーティングの際に静的ファイルは、STATICというフォルダに入れるらしい
url_forの指定の仕方は、'static'＋ファイル名　で書かないと、だめらしい

実はここで、つまずいていたが、下記のソースを見て明らかになった。
https://github.com/zeeshanshamsuddeen/Online-Food-Ordering-System/blob/master/templates/customer.html

```html
<!DOCTYPE html>
<html >
<head>
<link type="text/css" href="{{url_for('static',filename='省略.css')}}" rel="stylesheet"/>
<link rel="stylesheet" href="{{url_for('static',filename='省略.css')}}">

<script type="text/javascript" src="{{url_for('static',filename='ライブラリ.js')}}"></script>
<link rel="stylesheet" href="{{url_for('static',filename='ライブラリ.css')}}">
```

##ログイン処理

このソースを見て、プロフェッショナルの仕事だと実感。
JAVASCRIPTの達人であれば、すべてフロントエンドでログイン認証まで完了できてしまう。
（ちなみにJQUERYは使っていない）

データベースから、ユーザー名、パスワードが対になった、リストを持ってきている。
ここではテンプレート側で、ループを組んでいて{%　ループ　in　VAR　%}は
FLASK側から持ってきたリスト変数VARである。
JSの型宣言のVARと、変数のVARが被ってる。なぜこんな変数名にしたのか疑問！

```javascript
function ログイン判定(){
var username=document.forms[フォーム]["username"].value;　→　フォームから取得
var password=document.forms[フォーム]["password"].value;　→　フォームから取得
var x=0;　
	if(username=="")	{ alert("ユーザ名を催促"); 	document.form1.action=""; 	}
	else if(password=="") 	{ alert("パスワードを催促"); 	document.form1.action=""; 	}
	else {
		{% for x in var %}
			if(username=="{{x[0]}}" && password=="{{x[1]}}") { 	x=1; }
		{% endfor %}	
	if(x==1){alertify.log( "welcome "+username, "success" );
		document.form1.action="http://localhost:8080/ログイン処理";
		document.form1.method="post";　→　ポストさせる
		}else{
		alert("拒否メッセージ");
		document.form1.action="";　　→　ポストさせない
		}}}
```
こんな感じで、ローカルホストのポートまでJSに突っ込んで、
ポストのリクエストまで、直接書き換えてしまう。
とりあえず動いたらええんや！って感じ。


```html
<h2>ログイン</h2>  
  <button class="btn_login" onclick="login()">LOGIN</button>
<h2>サインアップ</h2>
  <button class="btn_sign_up" onclick="sign_up()">SIGN UP</button>

<a href="#" onclick="共通処理" ><i class="material-icons">&#8592;</i></a>
   <h2>LOGIN</h2>
   	<form name='form1' onsubmit="required_login()">
	<br>
	<input class="login_space" type="text" name="username"  placeholder="Username">
	<input class="login_space" type="password" name="password" placeholder="Password">
    <button class="btn_login" type="submit" name="submit" value="Sign in" />SIGN IN</button>
	</form>	

<a href="#" onclick="共通処理"><i class="material-icons">&#8592;</i></a>
     <h2>SIGN UP</h2>
	 
<form name='form2' onsubmit="required_signup()">
 <br>
<input class="login_space" type="text" name="username" placeholder="Username" >
<input class="login_space" type="password" name="password" placeholder="Password" >
<input class="login_space" type="password" name="password2" placeholder="Confirm Password" >
<button class="btn_sign_up" type="submit" name="submit" value="Sign up" />SIGN UP</button>
</form>	

```
最初のメニューで、ログインとサインアップのどちらかを選ばせて、
サブウィンドウを出させて、そこでログイン、サインアップ処理をさせている。
この時点で、バックエンドに処理をさせずに、フロントエンド側で対処できるとは、しらなんだ。。。

マテリアルアイコンがJS側での、パスワードの見せる、見せないを示すアイコンだが
これも、こんな簡単な仕組みで実装できるなんて驚愕（もっと何かやっていると思っていた）


#見栄えのトリック

JAVASCRIPTを使って、画面にぬるっと出す処理。
この辺は、骨格ができてからの最終段階だと思うが・・・
最初はなくても動く
あと重文が続いており、JQUERYが開発された理由が分かった。

```javascript
function ログイン処理() {
document.querySelector().className = "";  
document.querySelector().style.display = "block";
document.querySelector().style.opacity = "0";               
setTimeout(function(){  document.querySelector(　).style.opacity = "1"; },400);  
setTimeout(function(){    document.querySelector(　).style.display = "none";},200);  }

function サインアップ処理() {
document.querySelector().className = "";
document.querySelector().style.display = "block";
document.querySelector().style.opacity = "0"; 
setTimeout(function(){  document.querySelector().style.opacity = "1";},100);  
setTimeout(function(){   document.querySelector().style.display = "none";},400);  }    

function 共通() {
document.querySelector().className = "cont_forms";  
document.querySelector().style.opacity = "0";               
document.querySelector().style.opacity = "0"; 
setTimeout(function(){
document.querySelector().style.display = "none";
document.querySelector().style.display = "none";
},500);    }
```

#バックエンド

お次はバックエンド側
ごり押しで触ってみる

データベースは既に作成ずみというのが前提
（わざわざＤＢメンテナンスまで、PYTHONで書かなくてもいいことを発見）

```python

@app.route('/カスタマ')
def customer():
    conn=sqlite3.connect('データベース.db')
    cur=conn.cursor()
    cur.execute("SELECT * FROM ちょめちょめ")
    var=cur.fetchall()
    conn.close()
    return render_template('カスタマ.html',var=var)

@app.route('/サイン',methods=['GET','POST'])
def サインアップ():
	session['username']=request.form['username']
	password=request.form['password']
	conn=sqlite3.connect('データベース.db')
	cur=conn.cursor()
	cur.execute("INSERT INTO customers(username,password) VALUES (?,?)",(session['username'],password))
	cur.execute("CREATE TABLE {}(　チョメチョメ　)".format(session['username']))
	temp=session['username']+'_orders'
	cur.execute("CREATE TABLE IF NOT EXISTS {}(チョメチョメ);".format(temp))
	conn.commit()
	return redirect(url_for('メイン'))

@app.route('/ログイン',methods=['GET','POST'])
def　ログイン():
	session['username']=request.form['username']
	return redirect(url_for('homepage_customer'))

@app.route('/メイン')
def メイン():
    conn=sqlite3.connect('members.db')
    cur=conn.cursor()
    cur.execute("SELECT * FROM response WHERE username=?",(session['username'],))
    response=cur.fetchall()
    cur.execute("SELECT * FROM most_ordered ORDER BY orders DESC limit 4")
    most_ordered=cur.fetchall()
    conn.close()
    return render_template('メイン.html',response=response,most_ordered=most_ordered)
```

サインアップ見てびびる。
ユーザー名でテーブル作ってるやんか・・・
これってアンチやんか！・・・

あとSQL・・・　かろうじてアクセス触っていたから読める・・・
（読むことはできても、書くことは別世界）


とりあえず、ログインさせてメインページまで、入るところがイメージングできた。

ログイン後は、下記でセッション登録している。

```python
session['username']=request.form['username']
```