Last active
November 11, 2017 23:20
-
-
Save nishimotz/b3a4b4676a60c1067e8ebac419908f64 to your computer and use it in GitHub Desktop.
171111 アクセシビリティ検証ツールとしてのNVDA入門 で使ったデモサイト(サーバサイドのコードは一部省略)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "layout.html" %} | |
{% block content %} | |
<div class="card"> | |
<img class="card-img-top" src="https://placehold.jp/24/cc9999/993333/318x180.png" alt="商品「スマイル」の写真"> | |
<div class="card-body"> | |
<h2 class="card-text">スマイル 1000円</h2> | |
<p class="card-text">このサイトは pay.jp のテストモードで動作しています。</p> | |
</div> | |
</div> | |
{% if email is none %} | |
<div class="row"> | |
<div class="col"> | |
<p>購入するにはGoogleアカウントでログインしてください</p> | |
</div> | |
</div> | |
{% else %} | |
<div class="row"> | |
<div class="col"> | |
<h2>クレジットカードで購入</h2> | |
<div id="pj_guide" role="status" aria-live="assertive" class="alert alert-primary">カード情報を入力して「確認」を押してください</div> | |
</div> | |
</div> | |
<div class="form-row"> | |
<div class="col-12"> | |
<label for="card_number">カード番号</label> | |
<input type="text" id="card_number" class="form-control" aria-describedby="card_number_help" value="5555555555554444" required aria-required="true" pattern="[0-9]{13,16}" /> | |
<small id="card_number_help" class="form-text text-muted">半角数字 <span aria-hidden="true">省略できません</span></small> | |
</div> | |
<div class="col-6"> | |
<label for="card_exp_year">有効期限(年)</label> | |
<input type="text" id="card_exp_year" class="form-control" aria-describedby="card_exp_year_help" value="2020" required aria-required="true" pattern="[0-9]{2,4}" /> | |
<small id="card_exp_year_help" class="form-text text-muted">半角数字 <span aria-hidden="true">省略できません</span></small> | |
</div> | |
<div class="col-6"> | |
<label for="card_exp_month">有効期限(月)</label> | |
<input type="text" id="card_exp_month" class="form-control" aria-describedby="card_exp_month_help" value="12" required aria-required="true" pattern="[0-9]{1,2}" /> | |
<small id="card_exp_month_help" class="form-text text-muted">半角数字 <span aria-hidden="true">省略できません</span></small> | |
</div> | |
<div class="col-12"> | |
<label for="card_cvc">カード確認コード(CVC)</label> | |
<input type="text" id="card_cvc" class="form-control" aria-describedby="card_cvc_help" value="111" pattern="[0-9]{3,4}" /> | |
<small id="card_cvc_help" class="form-text text-muted">半角数字</small> | |
</div> | |
<div class="col"> | |
<button id="get_token_btn" onclick="getToken()" class="form-control btn btn-primary">確認</button> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col"> | |
<div id="pj_alert" role="status" aria-live="assertive" class="alert alert-light"></div> | |
</div> | |
</div> | |
<form id="pay_form" action="/pay" method="post" class="form-row"> | |
<input type="hidden" name="pj_token" id="pj_token" value="" /> | |
<div class="col"> | |
<button type="submit" id="pj_submit_btn" disabled="disabled" class="form-control btn btn-primary">購入する</button> | |
</div> | |
</form> | |
<div class="form-row"> | |
<div class="col"> | |
<button id="reset_token_btn" onclick="resetToken()" disabled="disabled" class="form-control btn btn-secondary">キャンセル</button> | |
</div> | |
</div> | |
<script type="text/javascript" src="https://js.pay.jp/"></script> | |
<script type="text/javascript" src="/static/index.js"></script> | |
<script type="text/javascript"> | |
Payjp.setPublicKey("{{ public_key }}"); | |
</script> | |
{% endif %} | |
{% endblock %} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
var clearAlert = function () { | |
$('#pj_alert').text('').addClass('alert-light') | |
.removeClass('alert-success').removeClass('alert-warning'); | |
}; | |
var setAlertSuccess = function (message) { | |
$('#pj_guide').text('').addClass('alert-light'); | |
$('#pj_alert').text(message).addClass('alert-success') | |
.removeClass('alert-light').removeClass('alert-warning'); | |
}; | |
var setAlertWarning = function (message) { | |
$('#pj_alert').text(message).addClass('alert-warning') | |
.removeClass('alert-success').removeClass('alert-light'); | |
}; | |
var setGuidePrimary = function (message) { | |
$('#pj_alert').text('').addClass('alert-light') | |
.removeClass('alert-success').removeClass('alert-warning'); | |
$('#pj_guide').text(message).addClass('alert-primary') | |
.removeClass('alert-light'); | |
}; | |
var getToken = function () { | |
var card = { | |
number: $('#card_number').val(), | |
exp_year: $('#card_exp_year').val(), | |
exp_month: $('#card_exp_month').val(), | |
cvc: $('#card_cvc').val() | |
}; | |
clearAlert(); | |
$('#card_number').attr('aria-invalid', false); | |
$('#card_exp_year').attr('aria-invalid', false); | |
$('#card_exp_month').attr('aria-invalid', false); | |
$('#card_cvc').attr('aria-invalid', false); | |
Payjp.createToken(card, function(status, response) { | |
if (status === 200) { | |
$('#pj_token').val(response.id); | |
$('#get_token_btn').prop('disabled', true); | |
$('#reset_token_btn').prop('disabled', false); | |
$('#pj_submit_btn').prop('disabled', false).focus(); | |
$('#card_number').attr('readonly', true); | |
$('#card_exp_year').attr('readonly', true); | |
$('#card_exp_month').attr('readonly', true); | |
$('#card_cvc').attr('readonly', true); | |
setAlertSuccess('カード情報が確認できました。「購入する」を押すと1000円のお支払いが完了します。'); | |
} else { | |
//console.log(response); | |
if (typeof response.error != 'undefined') { | |
if (response.error.code === 'invalid_number') { | |
$('#card_number').attr('aria-invalid', true); | |
setAlertSuccess('カード番号が正しくありません'); | |
} else if (response.error.code === 'invalid_expiry_year') { | |
$('#card_exp_year').attr('aria-invalid', true); | |
setAlertSuccess('有効期限(年)が正しくありません'); | |
} else if (response.error.code === 'invalid_expiry_month') { | |
$('#card_exp_month').attr('aria-invalid', true); | |
setAlertSuccess('有効期限(月)が正しくありません'); | |
} else if (response.error.code === 'invalid_cvc') { | |
$('#card_cvc').attr('aria-invalid', true); | |
setAlertSuccess('カード確認コード(CVC)が正しくありません'); | |
} else { | |
setAlertWarning('カード情報が確認できません。'); | |
} | |
} | |
}; | |
}); | |
}; | |
var resetToken = function () { | |
$('#pj_token').val(''); | |
$('#get_token_btn').prop('disabled', false).focus(); | |
$('#reset_token_btn').prop('disabled', true); | |
$('#pj_submit_btn').prop('disabled', true); | |
$('#card_number').attr('readonly', false); | |
$('#card_exp_year').attr('readonly', false); | |
$('#card_exp_month').attr('readonly', false); | |
$('#card_cvc').attr('readonly', false); | |
setGuidePrimary('カード情報を入力して「確認」を押してください'); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
h1 { | |
margin-top: 3rem; | |
margin-bottom: 1rem; | |
} | |
h2 { | |
margin-top: 0.5rem; | |
margin-bottom: 0.5rem; | |
} | |
.card { | |
width: 18rem; | |
margin-bottom: 0.5rem; | |
} | |
button { | |
margin-top: 1rem; | |
margin-bottom: 1rem; | |
} | |
label { | |
margin-top: 1rem; | |
} | |
footer { | |
margin-top: 3rem; | |
} | |
#pj_guide:empty, #pj_alert:empty { | |
/* display: none; */ | |
height: 1px; | |
margin: 0; | |
padding: 0; | |
} | |
[aria-invalid="true"] { | |
border-width: thick; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> | |
<title>ショッピング</title> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css" integrity="sha384-PsH8R72JQ3SOdhVi3uxftmaW6Vc51MKb0q5P2rRUpPvrszuE4W1povHYgTpBfshb" crossorigin="anonymous"> | |
<link rel="stylesheet" href="/static/layout.css"> | |
</head> | |
<body class="container"> | |
<main role="main"> | |
<h1>ショッピング</h1> | |
{% block content %}{% endblock %} | |
</main> | |
<footer class="row" role="contentinfo"> | |
<div class="col-12"> | |
{% if email is none %} | |
<p class="text-left"><a href="{{ login_url }}">ログインする</a></p> | |
{% else %} | |
<p class="text-left">Googleアカウント {{ email }}</p> | |
<p class="text-left"><a href="{{ logout_url }}">ログアウトする</a></p> | |
{% endif %} | |
</div> | |
<div class="col"> | |
<p class="text-left">サイト管理者 <a href="https://ja.nishimotz.com/">nishimotz</a></p> | |
<p class="text-left">このサイトは入力されたパスワードを記録しません</p> | |
<p class="text-left">クレジットカードの情報は pay.jp にのみ送信されます</p> | |
<p class="text-left">事前に入力されているのはテスト用のクレジットカード番号です</p> | |
</div> | |
</footer> | |
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js" integrity="sha384-vFJXuSJphROIrBnz7yo7oB41mKfc8JzQZiCq4NCceLEaO4IHwicKwpJf9c9IpFgh" crossorigin="anonymous"></script> | |
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js" integrity="sha384-alpBpkh1PFOepccYVYDB4do5UnbKysX5WZXm3XxPqe5iKTfUKjNkCk9SaVuEZflJ" crossorigin="anonymous"></script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
app = Flask(__name__) | |
def render_index(): | |
user = users.get_current_user() | |
email = user.email() if user else None | |
login_url = users.create_login_url('/') | |
logout_url = users.create_logout_url('/') | |
return render_template('index.html', public_key=PUBLIC_KEY, email=email, login_url=login_url, logout_url=logout_url) | |
@app.route('/') | |
def index(): | |
return render_index() | |
@app.route('/pay', methods=['POST']) | |
def pay(): | |
user = users.get_current_user() | |
email = user.email() if user else None | |
if not email: | |
return render_index() | |
logout_url = users.create_logout_url('/') | |
amount = 1000 | |
customer = payjp.Customer.create( | |
email=user.email(), | |
card=request.form['pj_token'] | |
) | |
payjp.Charge.create( | |
amount=amount, | |
currency='jpy', | |
customer=customer.id, | |
description='example charge' | |
) | |
return render_template('pay.html', amount=amount, email=email, logout_url=logout_url) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{% extends "layout.html" %} | |
{% block content %} | |
<div class="row"> | |
<div class="col-12"> | |
<div class="alert alert-success">{{ amount }}円のお支払いが完了しました。</div> | |
<p><a href="/">戻る</a></p> | |
</div> | |
</div> | |
{% endblock %} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment