SQLの窓

2018年07月23日


Python + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート





JavaScript は jQuery を使用します。

テンプレート構造

IFRAME 内の処理( req フォルダ内 )が実際の問い合わせ処理になります。メインページの下部に CSS の calc 関数を使用してフィットさせています。



メインの control.py( エントリポイント )

Python の import は PHP の require( または include ) や Ruby の require と違って モジュールを利用する為のメモリ空間の利用方法が厳格です。PHP の require は、単純にソースコードの外部読みこみで、Ruby の require は、仕様としてライブラリを読み込むようになっているのですが、現実としてソースコードレベルの読み込みと考えて問題は無いようです( グローバル変数がソース間で使用可能 )

Python ではソース間のグローバル変数は存在せず、モジュール内の変数を読みこむ側がいかに参照するかというアプローチになります。これに関してもエントリポイントの開始ソースとその他のソースの場合ではモジュール変数の扱いが微妙に違うので注意が必要です( from モジュール import * の動作 )

from settings import * の * で全ての内容をインポートする方法は、Python では推奨されていませんが、ここでは必ずすべて必要になるテンプレートとしての仕様に基づいて使用しています。
import cgitb
cgitb.enable()

# **************************************
# 共有メソッド
# **************************************
from settings import *
set( "base_name", __file__ )

# **************************************
# CGI 初期処理
# **************************************
cgi_init()

import view

settings.py ( 共通処理 )

Python ではソース単位で必要なモジュールは常に import する必要があります。ただ、最終的に実行単位のメモリ空間では同じモジュールは各ソースで共有されるようです。

単純なグローバル変数が使用できないので、settings モジュールに val デイクショナリを作成しておいて、get/set メソッドで値の操作を可能にしてグローバル変数代わりに使用しています。

settings で定義された変数は、settings 内で定義されている メソッド内で global キーワードを使用して参照可能になります( PHP と類似 )

log と pplog はデバッグ用のメソッドで、テキストフアイルに出力する為に使用します。
import cgi
import sys
import io
import pprint

# **************************************
# デバッグログの初期化
# **************************************
with open('debug.log', 'w') as f:
	print("開始",end='\n',file=f)

# **************************************
# グローバル変数
# **************************************
pp = None

# **************************************
# 共有ディクショナリ
# **************************************
val = {}
val["pass"] = "1"
val["check_message"] = ""
val["lines"] = ""

# **************************************
# フォーム用変数
# **************************************
fld_names = {}
form = {}
form_data = {}

# **************************************
# CGI 初期処理
# **************************************
def cgi_init():

	global pp
	global form

	sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
	 
	print("Content-Type: text/html; charset=utf-8")
	print( "Expires: Thu, 19 Nov 1981 08:52:00 GMT" )
	print( "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0" )
	print( "Pragma: no-cache" )
	print()

	pp = pprint.PrettyPrinter(indent=4)

	form = cgi.FieldStorage()

# **************************************
# データの整形表示
# **************************************
def print_r(data):

	global pp

	print("<pre>")
	pp.pprint(data)
	print("</pre>")

# **************************************
# フォームデータの取得
# **************************************
def forms(target, set_data=None):

	global fld_names
	global form

	if set_data is not None:
		form_data[fld_names[target]] = set_data
		return

	result = ""

	if form_data.get(fld_names[target]) is not None:
		return( form_data[fld_names[target]] )

	if not fld_names[target] not in form:
		result = form[fld_names[target]].value

	return(result)

# **************************************
# フォームフィールド名取得
# **************************************
def fields(target):

	return(fld_names[target])

# **************************************
# フォームフィールドセット設定
# **************************************
def set_field_names( field_set ):

	global fld_names

	fld_names = field_set


# **************************************
# ディクショナリ : set & get
# **************************************
def set( my_key, my_val ):

	global val
	val[my_key] = my_val

def get( my_key ):

	global val
	return( val[my_key] )

# **************************************
# ログ出力
# **************************************
def log( message ):
	with open('debug.log', 'a') as f:
		print(message,end='\n',file=f)
	
# **************************************
# ログ出力( pprint )
# **************************************
def pplog( obj ):

	with open("debug.log", "a") as f:
		pprint.pprint(obj, stream=f)




view.py ( メイン画面定義 )

画面定義は、三重クオート文字列と f-string を使用して PHP のヒアドキュメント的に行っています( 変数のパースは {メソッドまたは変数} です )

JavaScript の外部ファイルの読み込み時のキャッシュ制御を行う為、ページが表示された時間を URL に付加しています。
import os
from settings import *
# **************************************
# js 選択
# **************************************
js = "entry.js";
#js = "entry-json.js";

# **************************************
# js キャッシュ用
# **************************************
from datetime import datetime
tm = datetime.now().strftime("%Y%m%d%H%M%S")

# **************************************
# 画面定義
# **************************************
out_client = f"""<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="{js}?{tm}"></script>

<link rel="stylesheet" href="entry.css?{tm}">
</head>
<body>

<div id="head">
	<p class="ttl">
		氏名で検索
	</p>
	<p class="entry">
		<input
			id="cond"
			type="text">
		<input
			class="ml-4 btn btn-success"
			id="btn"
			type="button"
			value="問合せ">

		<a
			class="ml-4 btn btn-info btn-sm"
			href="{os.path.basename(get("base_name"))}">GET 再読み込み</a>	
	</p>
	<p class="line"></p>

	<h4 class="text-danger">{get("check_message")}</h4>

</div>

<iframe id="extend" name="extend" class="iframe-option" src="req/control.py"></iframe>

</body>
</html>"""


print(out_client)


entry.js

1) Bootstrap のボタンの表示位置の調整を行っています。
2) 問い合わせの条件を JavaScript 側で作成して IFRAME の src にセットしています。
$(function(){
	// ***************************
	// ボタン表示位置微調整
	// ***************************
	$( ".btn" ).css({
		"margin-top": "-4px"
	});

	// ***************************
	// IFRAME に問合せを表示
	// ***************************
	$( "#btn" ).click(function() {
		$("#extend").prop("src","req/control.py?nm=" + encodeURIComponent($("#cond").val()));
	});


});


entry.css

Python では、CSS 内に書く記述が一部文字列内でエラーになったので .css として利用しています。
/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

/* IFRAMEコントロール用  */
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 100px;
	background-color: #e0e0e0;
}
iframe {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 100px - 2px );
	border: solid 2px #c0c0c0;
}

control.py ( 問い合わせのエントリポイント )

単独で動作する問い合わせアプリケーションです。GET メソッドで QueryString を受け取って内部の SQL 処理に引き渡します。セキュリティ上の文字列の処理は省略しています。

mysql.connector は、Oracle が提供している Connector/Python を使用します( インストールが必要です ) 
※ autocommit がデフォルトで False なので接続時に True に設定しています

set_field_names メソッドは、settings モジュールで定義されており、画面のフィールド名やフィールド値を参照する為の日本語の定義となります。

sys.path.append('..') は、親フォルダにあるモジュールをインポートするパスをシステムに追加しています。
# **************************************
# 親ディレクトリに参照パス追加
# **************************************
import sys
sys.path.append('..')

# **************************************
# CGI
# **************************************
import cgitb
cgitb.enable()
# **************************************
# MySQL
# **************************************
import mysql.connector

# **************************************
# アプリケーションメソッド
# **************************************
from model import *

# **************************************
# 共有メソッド
# **************************************
from settings import *
set( "base_name", __file__ )

# **************************************
# CGI 初期処理
# **************************************
cgi_init()

# **************************************
# フォームフィールドセット設定
# **************************************
set_field_names( {
	"条件" : "nm",
	"送信ボタン" : "send"
})

# **************************************
# 接続 / 更新兼用
# **************************************
cnn = mysql.connector.connect(
	host='localhost',
	port=3306,
	db='lightbox',
	user='root',
	passwd='',
	charset="utf8",
	autocommit='True')

build_table( cnn )

# **************************************
# 接続解除
# **************************************
cnn.close()

import view


view.rb ( 問い合わせ用画面 )

table 部分の行データの埋め込み部分に tbody を明示しているのは、行を jQuery で動的に作成した時に tbody が無いと Bootstrap の css が動作しないからです( 他のテンプレートと差異を少なくする為 )。

一番最後に pplog で、ディクショナリの内容を出力していますが、control.py はエントリポイントなので 変数の参照ができないので、処理の最後として view.py の最後で参照しています( エントリポイントでは、エントリポイントのメモリ空間に最初に使った変数が割り付けられるようです / それ以外の場合は from モジュール import * で直接モジュール変数の参照が可能です )
# **************************************
# 親ディレクトリに参照パス追加
# **************************************
import sys
sys.path.append('..')

#import os
# **************************************
# 共有メソッド
# **************************************
from settings import *
# **************************************
# js 選択
# **************************************
js = "entry.js";
#js = "entry-json.js";

# **************************************
# js キャッシュ用
# **************************************
from datetime import datetime
tm = datetime.now().strftime("%Y%m%d%H%M%S")

# **************************************
# 画面定義
# **************************************
out_client = f"""<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="{js}?{tm}"></script>

<link rel="stylesheet" href="entry.css?{tm}">
</head>
<body>

	<table class="table table-hover">
		<tbody id="tbl">
			{get("lines")}
		</tbody>
	</table>

</body>
</html>"""


print(out_client)

pplog(fld_names)
pplog(val)

entry.css

テーブル表示時のカーソルを常にデフォルトに固定して、テーブルのデータが折り返さないように以下の CSS が追加定義されています
td,th {
	cursor: default!important;
	white-space: pre;
}

body {
	margin: 0;
	padding: 16px;
}


model.py ( テーブル作成部分 )

1) 列データの文字列をまずループで作成しています( SQLを変更するだけで違った問い合わせを表現できます )
2) 列データが完成する毎に、行データを作成して全体の文字列に追加していきます。
3) cnn.cursor(dictionary=True) で、結果をディクショナリ(PHP:連想配列/Ruby:ハッシュ)
import mysql.connector
from settings import *

# ***************************
# テーブル作成
# ***************************
def build_table( cnn ):

	cursor = cnn.cursor(dictionary=True)

	sql = f"""select
		社員コード,
		氏名,
		フリガナ,
		所属,
		性別,
		作成日,
		更新日,
		給与,
		手当,
		管理者,
		DATE_FORMAT(生年月日,'%Y/%m/%d') as 生年月日
		from 社員マスタ
		where 氏名 like '%{forms("条件")}%'"""

	# デバッグ
	log(sql)

	cursor.execute(sql)

	lines  = ""
	for row in cursor:

		if lines == "":
			# タイトル
			for col in row.keys():
				lines += f"<th>{col}</th>"

		cells  = ""
		for col in row.values():
			if col is None:
				cells += f"<td></td>"
			else:
				cells += f"<td>{col}</td>"
	
		lines += f"<tr>{cells}</tr>"
	
	cursor.close()

	set("lines",lines)




関連する記事

Ruby + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

PHP + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

CSS の calc 関数を使って、IFRAME を画面下半分にフィットさせる





posted by lightbox at 2018-07-23 10:32 | Python | このブログの読者になる | 更新情報をチェックする

2018年07月16日


Ruby + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート





JavaScript は jQuery を使用します。

テンプレート構造

IFRAME 内の処理( req フォルダ内 )が実際の問い合わせ処理になります。メインページの下部に CSS の calc 関数を使用してフィットさせています。



メインの control.rb( エントリポイント )

更新等を行う場合は、ここに入力値のコントロールが入ります。ここでは画面を表示するだけなので、Ruby を実行する為の基本的な設定と、画面の読み込みを行っています。
Encoding.default_internal='utf-8'
# カレントフォルダを require 参照パスに追加
$:.unshift File.dirname(__FILE__)
require 'cgi'
require 'mysql'
require 'pp'
require 'json'
require 'settings'
require 'model'

txlog( "Script Encoding : " << __ENCODING__.to_s )
txlog( "Default external Encoding : " << Encoding.default_external.to_s )
txlog( "Default internal Encoding : " << Encoding.default_internal.to_s )

# **************************************
# グローバル変数
# **************************************
$error_flg = 0
$error_msg = ""
$base_path = __FILE__

# **************************************
# フィールド参照の定義
# **************************************
$fld_names = {
	"条件" => "nm",
	"送信" => "send"
}

require 'view'

冒頭の Encoding.default_internal='utf-8' は、Ruby にかかわるエンコーディングを utf-8 に揃える為に行っています。( Encoding.default_external はインストール時に設定しています )



▼ デバッグログ
開始
Script Encoding : UTF-8
Default external Encoding : UTF-8
Default internal Encoding : UTF-8
# **************************************
# フィールド参照の定義
# **************************************
$fld_names = {
	"条件" => "nm",
	"送信" => "send"
}
$fld_names は、settings.rb で定義されている forms メソッドと fields メソッドで使用する為のハッシュです。

ソースコード上の呼び名を日本語で定義して、画面(ヒアドキュメント)の INPUT 要素に埋め込んだり、値を参照する為に用意しています。
<input
	data-pass="2i"
	type="text"
	name="#{fields("氏名")}" 
	value="#{forms("氏名")}">
settings.rb ( 共通処理 ) Ruby の cgi としての設定( メソッド定義を含む )と、アプリとしての初期設定と、デバッグ用のログ関数の定義を行っています。この処理は、問い合わせ処理側( req フォルダ内 )からも読み込まれて使用されます。
# ***************************
# 共通処理
# ***************************
$cgi = CGI.new
 
puts "Content-Type: text/html; charset=utf-8"
puts  "Expires: Thu, 19 Nov 1981 08:52:00 GMT"
puts "Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0"
puts "Pragma: no-cache"
puts
 
$params = $cgi.params


# ここで $params 内の文字列のセキュリティ上の処理


# デバッグログの初期化
File.open("debug.log", "w"){ |f| f.puts "開始" }

# デバッグ用メッセージ
$check_message = "";

# クライアントコントロール
$pass = "1";


# **************************************
# FORM 用変数の参照と設定
# **************************************
def forms( target, setter=nil )

	result = ""

	key = $fld_names[target]

	if not setter.nil? then
		$params[key][0] = setter
		return
	end

	if not $params[key].empty? then
		result = $params[key][0]
	end

	return result

end

# **************************************
# フィールド用文字列の参照
# **************************************
def fields( target )

	return $fld_names[target]

end

# ***************************
# デバッグログ関数(テキスト)
# ***************************
def txlog(message)

	File.open("debug.log", "a"){ |f| f.puts message + "\n" }

end

# ***************************
# デバッグログ関数
# (オブジェクト等)
# ***************************
def pplog(data)

	File.open("debug.log", "a"){ |f| f.puts data.pretty_inspect }

end



以下は、pplog の pretty_inspect で、$cgi.params の結果を表示したものです。
{"nm"=>["川"], "send"=>["問合せ"]}
view.rb ( メイン画面定義 ) 画面定義はヒアドキュメントで行っています。変数のパースは #{メソッドまたは変数} です。 JavaScript の外部ファイルの読み込み時のキャッシュ制御を行う為、ページが表示された時間を URL に付加しています。
# **************************************
# js 選択
# **************************************
$js = "entry.js";
#$js = "entry-json.js";

# **************************************
# js キャッシュ用
# **************************************
$tm = Time.now.to_f.to_s.gsub(/[.]/,"")

# **************************************
# 画面定義
# **************************************
$out_client = <<HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="#{$js}?#{$tm}"></script>

<style>
/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

/* IFRAMEコントロール用  */
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 100px;
	background-color: #e0e0e0;
}
#extend {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 100px - 2px );
	border: solid 2px #c0c0c0;
}
</style>
</head>
<body>

<div id="head">
	<input type="hidden" value="#{$pass}" id="pass">

	<form method="post" action="req/control.rb" target="extend">
		<p class="ttl">
			氏名検索
		</p>
		<p class="entry">

			<input
				class="ml-4"
				name="#{fields("条件")}"
				id="cond"
				type="text">
			<input
				class="ml-4 iframe-option btn btn-success"
				id="btn"
				name="#{fields("送信")}"
				type="submit"
				value="問合せ">

			<a
				class="ml-4 btn btn-info btn-sm"
				href="#{File.basename($base_path)}"
				title="1:#{ENV["SCRIPT_NAME"]}, 2:#{$cgi.script_name}">GET 再読み込み</a>


		</p>
		<p class="line"></p>

	</form>

	<h4 class="text-danger">#{$check_message}</h4>

</div>

<iframe id="extend" name="extend" src="req/control.rb"></iframe>

</body>
</html>
HTML

print $out_client


※ 画面上のスペーシングに Bootsrtap のクラスである ml-4( margin-left: 1.5rem !important; ) を使用しています。
※ btn btn-success、btn btn-info btn-sm は、ボタン用の Bootsrtap のクラス

entry.js

Bootstrap のボタンの表示位置の調整を行っています。
$(function(){

	// ***************************
	// ボタン表示位置微調整
	// ***************************
	$( ".btn" ).css({
		"margin-top": "-4px"
	});

});


control.rb ( 問い合わせのエントリポイント )

単独で動作する問い合わせアプリケーションです。GET メソッドで QueryString を受け取って内部の SQL 処理に引き渡します。セキュリティ上の文字列の処理は省略しています。

MySQL の処理を行う為に最も容易な Ruby/MySQL を使用しています。


Encoding.default_internal='utf-8'
# カレントフォルダを require 参照パスに追加
$:.unshift File.dirname(__FILE__)
require 'cgi'
require 'mysql'
require 'pp'
require 'json'
require '../settings'
require '../model'

txlog( "Script Encoding : " << __ENCODING__.to_s )
txlog( "Default external Encoding : " << Encoding.default_external.to_s )
txlog( "Default internal Encoding : " << Encoding.default_internal.to_s )

# **************************************
# グローバル変数
# **************************************
$error_flg = 0
$error_msg = ""
$base_path = __FILE__

# **************************************
# フィールド参照の定義
# **************************************
$fld_names = {
	"条件" => "nm"
}

# ***************************
# MySQL 接続
# http://www.tmtm.org/ruby/mysql/
# ***************************
begin
	$con = Mysql.connect("127.0.0.1", "root", "", "lightbox")
rescue => ex
	print "<pre>"
	print format("%d エラーが発生しました\n%s\n",ex.errno,ex.error)
	# 接続エラーの場合は終了
	exit
end

build_table()

# **************************************
# 接続解除
# **************************************
$con.close

require 'view'

view.rb ( 問い合わせ用画面 )

テーブル表示時のカーソルを常にデフォルトに固定して、テーブルのデータが折り返さないように以下の CSS が追加定義されています

table 部分の行データの埋め込み部分に tbody を明示しているのは、行を jQuery で動的に作成した時に tbody が無いと Bootstrap の css が動作しないからです( 他のテンプレートと差異を少なくする為 )。
# **************************************
# js 選択
# **************************************
$js = "entry.js";
#$js = "entry-json.js";

# **************************************
# js キャッシュ用
# **************************************
$tm = Time.now.to_f.to_s.gsub(/[.]/,"")

# **************************************
# 画面定義
# **************************************
$out_client = <<HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="#{$js}?#{$tm}"></script>

<style>
td {
	cursor: default!important;
	white-space: pre;
}

body {
	margin: 0;
	padding: 16px;
}
</style>
</head>
<body>

	<table class="table table-hover">
		<tbody id="tbl">
			#{$lines}
		</tbody>
	</table>

</body>
</html>
HTML

print $out_client

print pplog( $params )


model.rb ( テーブル作成部分 )

1) 列データの文字列をまずループで作成しています( SQLを変更するだけで違った問い合わせを表現できます )
2) 列データが完成する毎に、行データを作成して全体の文字列に追加していきます。

※ Ruby/MySQL ではデータを取得時に日本語の列名を扱えなかったので、SQL で別名として英字を使用しています
# ***************************
# テーブル表示
# ***************************
def build_table()

	$lines = "";

	sql = <<-SQL
		select
			社員コード as scode,
			氏名 as shimei,
			フリガナ as furi,
			所属 as syozoku,
			性別 as seibetu,
			作成日 as create_date,
			更新日 as update_date,
			給与 as kyuyo,
			手当 as teate,
			管理者 as kanri,
			DATE_FORMAT(生年月日,'%Y/%m/%d') as birthday
		from 社員マスタ
		where 
			氏名 like '%#{forms("条件")}%'
	SQL

	txlog( sql )

	begin
		result = $con.query(sql)

		# 列の名前でタイトル作成
		fields = result.fetch_fields()
		fields.each do |field|
			$lines << "<th>#{field.name}</th>\n"
		end

		result.each do |fld|
			len = fld.length
			cells  = ""
			for data in fld do
				# 文字列追加
				cells << "<td>#{data}</td>"
			end
			# 次の行の為改行( 文字列追加 )
			$lines << "<tr>#{cells}</tr>\n"
		end
	# エラー処理
	rescue => ex
		pplog( ex )
		$check_message = "SQL に問題があります"
	end

end


関連する記事

PHP + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

Python + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

CSS の calc 関数を使って、IFRAME を画面下半分にフィットさせる




posted by lightbox at 2018-07-16 13:09 | Ruby | このブログの読者になる | 更新情報をチェックする

2018年07月15日


PHP + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート



デモページ


JavaScript は jQuery を使用します。

テンプレート構造

IFRAME 内の処理( req フォルダ内 )が実際の問い合わせ処理になります。メインページの下部に CSS の calc 関数を使用してフィットさせています。



メインの control.php( エントリポイント )

更新等を行う場合は、ここに入力値のコントロールが入ります。ここでは画面を表示するだけなので、共通処理と画面のみを require_once しています。

※ コメントに # を使用しているのは、Ruby と Python に合わすためです( テンプレート )
<?php
# ***************************
# ソースベースの取り込み
# ***************************
require_once('settings.php');

# ***************************
# 画面定義
# ***************************
require_once('view.php');
?>


settings.php ( 共通処理 )

PHP としての設定と、アプリとしての初期設定と、デバッグ用のログ関数の定義を行っています。この処理は、問い合わせ処理側( req フォルダ内 )からも読み込まれて使用されます。
<?php
# ***************************
# 共通処理( UTF8N で保存 )
# ***************************
error_reporting( E_ALL & ~E_NOTICE & ~E_STRICT );
ini_set('display_errors', '1');
ini_set('date.timezone', 'Asia/Tokyo');
ini_set('default_charset', 'utf-8');
session_cache_limiter('nocache');
session_start();
header( "Content-Type: text/html; charset=utf-8" );


foreach( $_REQUEST as $key => $value ) {

	# ここで $_REQUEST 内の(入力された)文字列の処理

}

# ***************************
# デバッグログの初期化
# ***************************
file_put_contents("debug.log", "開始\n" );

# ***************************
# メッセージ
# ***************************
$check_message = "";

# ***************************
# クライアント会話コントロール
# 1 は第一会話
# ***************************
$gpass = "1";

# ***************************
# デバッグログ関数(テキスト)
# ***************************
function txlog($message) {

	file_put_contents("debug.log", "{$message}\n" , FILE_APPEND );

}

# ***************************
# デバッグログ関数
# (オブジェクト等)
# ***************************
function pplog($data) {

	file_put_contents("debug.log", print_r($data, true) , FILE_APPEND );

}
?>


view.php ( メイン画面定義 )

画面定義は、PHP の HTML モードでは無くヒアドキュメントで行っています( これも、Ruby と Python に合わす為です )。変数のパースも {} を必ず使用するようにして、Ruby と Python との差異をできるだけ小さくしようとしています。

JavaScript の外部ファイルの読み込み時のキャッシュ制御を行う為、ページが表示された時間を URL に付加しています。
<?php
require_once('view_config.php');

# **************************************
# js キャッシュ用
# **************************************
$tm = mktime();

# **************************************
# 画面定義
# ( Ruby や Python に合わせた画面形式 )
# **************************************
$out_client = <<<HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="{$view_js}?{$tm}"></script>

<style>
/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}


/* IFRAMEコントロール用  */
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: {$view_head_height}px;
	background-color: #e0e0e0;
}
#extend {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - {$view_head_height}px - 2px );
	border: solid 2px #c0c0c0;
}
</style>
</head>
<body>

<div id="head">
	<p class="ttl">
		氏名で検索
	</p>
	<p class="entry">
		<input
			id="cond"
			type="text">
		<input
			class="ml-4 btn btn-success"
			id="btn"
			type="button"
			value="問合せ">

		<a
			class="ml-4 btn btn-info btn-sm"
			href="{$_SERVER["PHP_SELF"]}">GET 再読み込み</a>
	</p>
	<p class="line"></p>

	<h4 class="text-danger">{$check_message}</h4>

</div>

<iframe id="extend" name="extend" class="iframe-option" src="req/control.php"></iframe>

</body>
</html>
HTML;

print $out_client;


?>

※ 画面上のスペーシングに Bootsrtap のクラスである ml-4( margin-left: 1.5rem !important; ) を使用しています。
※ btn btn-success、btn btn-info btn-sm は、ボタン用の Bootsrtap のクラス

view_config.php ( 画面用定数の定義 )

PHP の変数を使用して、画面に必要な文字列や数値を定義しています。
<?php
# ***************************
# 画面に埋め込む定数用変数
# ***************************
$view_js = "entry.js";

$view_head_height = "100";


?>


entry.js

1) Bootstrap のボタンの表示位置の調整を行っています。
2) 問い合わせの条件を JavaScript 側で作成して IFRAME の src にセットしています。
// ロードイベント
$(function(){

	// ***************************
	// ボタン表示位置微調整
	// ***************************
	$( ".btn" ).css({
		"margin-top": "-4px"
	});

	// ***************************
	// IFRAME に問合せを表示
	// ***************************
	$( "#btn" ).click(function() {
		$("#extend").prop("src","req/control.php?nm=" + encodeURIComponent($("#cond").val()));
	});

});


control.php ( 問い合わせのエントリポイント )

単独で動作する問い合わせアプリケーションです。GET メソッドで QueryString を受け取って内部の SQL 処理に引き渡すので、real_escape_string でエスケープして専用の連想配列を作成しています。( オリジナルはそのままです )

データベースの接続に必要な値は、include_path に設定されたディレクトリに config.php を作成してセットします
<?php
$host = "MySQLサーバ";
$user = "ユーザ";
$pass = "パスワード";
$db = "データベース";
?>
<?php
# ***************************
# ソースベースの取り込み
# ***************************
require_once('../settings.php');
require_once('../model.php');
require_once('config.php');

# ***************************
# MySQL 接続
# ***************************
$con = @new mysqli($host, $user, $pass, $db);
$con->set_charset("utf8");

# ***************************
# MySQL 用特殊文字エスケープ
# ***************************
foreach( $_REQUEST as $key => $value ) {
	$_REQUEST["db"][$key] = $con->real_escape_string($value);
}

# ***************************
# テーブル表示
# ***************************
build_table($con);

# ***************************
# MySQL 接続解除
# ***************************
$con->close();

# ***************************
# 画面定義
# ***************************
require_once('view.php');
?>


view.php ( 問い合わせ用画面 )

テーブル表示時のカーソルを常にデフォルトに固定して、テーブルのデータが折り返さないように以下の CSS が追加定義されています

table 部分の行データの埋め込み部分に tbody を明示しているのは、行を jQuery で動的に作成した時に tbody が無いと Bootstrap の css が動作しないからです( 他のテンプレートと差異を少なくする為 )。
td,th {
	cursor: default!important;
	white-space: pre;
}
<?php
require_once('view_config.php');

# **************************************
# js キャッシュ用
# **************************************
$tm = mktime();

# **************************************
# 画面定義
# ( Ruby や Python に合わせた画面形式 )
# **************************************
$out_client = <<<HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="{$view_js}?{$tm}"></script>

<style>
td,th {
	cursor: default!important;
	white-space: pre;
}

body {
	margin: 0;
	padding: 16px;
}

#tbl {
	user-select: none;
	-moz-user-select: none;
	-webkit-user-select: none;
	-ms-user-select: none;
}

</style>
</head>
<body>

	<table class="table table-hover">
		<tbody id="tbl">
			{$GLOBALS['table']}
		</tbody">
	</table>

</body>
</html>
HTML;

print $out_client;

?>


model.php ( テーブル作成部分 )

1) 列データの文字列をまずループで作成しています( SQLを変更するだけで違った問い合わせを表現できます )
2) 列データが完成する毎に、行データを作成して全体の文字列に追加していきます。
<?php
# ***************************
# モデル用関数を定義する
# ***************************

# ***************************
# テーブル表示
# ***************************
function build_table($con) {

	// デバッグ用
	txlog( "build_table:開始" );
	pplog( $con );

	// TR 内の HTML 文字列
	$lines = "";
	$sql= <<<SQL
		select 
			社員コード,
			氏名,
			フリガナ,
			所属,
			性別,
			作成日,
			更新日,
			給与,
			手当,
			管理者,
			DATE_FORMAT(生年月日,'%Y/%m/%d') as 生年月日
		from 社員マスタ
		where 氏名 like '%{$_REQUEST["db"]["nm"]}%'
SQL;

	$rs = $con->query($sql);	// エラー処理省略(本当は必要)
	//  デバッグ用
	pplog( $rs );

	// 列情報を取得( タイトル用 )
	$fields_data = $rs->fetch_fields();
	foreach( $fields_data as $field ){
		$lines .= "<th>{$field->name}</th>";
	}

	// 列データを取得
	while( $row = $rs->fetch_array(MYSQLI_BOTH) ) {
	
		$cells  = "";
		for( $i = 0; $i < $rs->field_count; $i++ ) {
			$cells .= "<td>{$row[$i]}</td>";
		}
	
		$lines .= "<tr>{$cells}</tr>" . "\n";
	}

	// 埋め込み用グローバル変数へセット	
	$GLOBALS['table'] = $lines;

	//  デバッグ用
	txlog( "build_table:終了" );

}

?>


関連する記事

Ruby + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

Python + MySQL + IFRAME + Bootstrap : 問い合せ WEB アプリテンプレート

CSS の calc 関数を使って、IFRAME を画面下半分にフィットさせる




posted by lightbox at 2018-07-15 12:27 | PHP + WEBアプリ | このブログの読者になる | 更新情報をチェックする

CSS の calc 関数を使って、IFRAME を画面下半分にフィットさせる



デモページ



以前は、JavaScript で実装してたのですが、知らない間に calc 関数というものがあったのを知り、IE11 ですらうまく動作する結果になっていました。

以下は php を使って、高さの部分を PHP の側の変数を使用して埋め込んでいます。IE11 以外のブラウザならば、var 関数を使用できるのですが、IE11 が実装する見通しも無いのでこのような形にするか、固定値を2度設定する必要があります。
<?php
require_once('view_config.php');

# **************************************
# js キャッシュ用
# **************************************
$tm = mktime();

# **************************************
# 画面定義
# ( Ruby や Python に合わせた画面形式 )
# **************************************
$out_client = <<<HTML
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />

<script src="{$view_js}?{$tm}"></script>

<style>
/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}


/* IFRAMEコントロール用  */
html,body {
	height: 100%;
}

body {
	margin: 0;
}
#head {
	padding: 16px;
	width: 100%;
	height: {$view_head_height}px;
	background-color: #e0e0e0;
}
#extend {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - {$view_head_height}px - 2px );
	border: solid 2px #c0c0c0;
}
</style>
</head>
<body>

<div id="head">
	<p class="ttl">
		氏名で検索
	</p>
	<p class="entry">
		<input
			id="cond"
			type="text">
		<input
			class="ml-4 btn btn-success"
			id="btn"
			type="button"
			value="問合せ">

		<a
			class="ml-4 btn btn-info btn-sm"
			href="{$_SERVER["PHP_SELF"]}">GET 再読み込み</a>
	</p>
	<p class="line"></p>

	<h4 class="text-danger">{$check_message}</h4>

</div>

<iframe id="extend" name="extend" class="iframe-option" src="req/control.php"></iframe>

</body>
</html>
HTML;

print $out_client;


?>


まず、高さを正しく計算させる為に html と body 要素の高さを 100% として明示します。次に基本部分の body 要素の margin を 0 として余白は #head 側で作成します。

そして、calc 関数で IFRAME の高さブラウザに計算させます。(他の小さな数値は縦と横の小さな余白用に使用しています)

view_config.php
<?php
$view_js = "entry.js";

$view_head_height = "100";


?>





posted by lightbox at 2018-07-15 01:11 | IFRAME パッケージ | このブログの読者になる | 更新情報をチェックする

2018年07月12日


HTA + Basp21 + jQuery + twitter-bootstrap(4.1.1) でメール受信ツール

Basp21 は SSL に対応していない(POP3:110番ポートでのアクセスです)ので、運用の範囲内でうまく利用する事が必要です。アプリケーションのテスト用のツールとして使うなどして、実際の重要な文書のやりとりに使うのはおすすめではありません。

このサンプルの趣旨は、HTA でも最新 jQuery + twitter-bootstrap が動作する事の確認です
( ここでは実装していませんが、jQuery UI の Resizable のテストは行いました )

関連する記事

HTA + Basp21 + jQuery + twitter-bootstrap(4.1.1) でメール送信ツール

HTA(HTMLアプリケーション) のコードを html として IE11 でデバッグする方法


▼ 初期画面

画面下部はIFRAME で、ウインドウの大きさを変えてもフィットするようになっています。この実装には CSS の calc 関数を使用しています。

IFRAME 部分には、iframe_in.html を使用していますが、IFRAME に APPLICATION="yes" を指定する事によって、HTA として動作します。
▼ 受信済メールデータ一覧の実行結果
『メール一覧』と同じ結果ですが、『メール一覧』ではパスワードの入力が必要で、実際にインターネットからデータを取得します。

『受信済メールデータ一覧』では、『メール本体を全て受信』でいったんデータを可能な限り(256件)受信し、ディレクトリに保存します。そして、『受信済メールデータ一覧』の実行でディレクトリよりデータを取得して表示します(その際、添付ファイルがあれば分離して保存します)

さらに、データ行をクリックすると、本文のテキストエリアに受信データの本文を表示します
メールサーバーは 『さくらインターネット』を使用しています main.hta( メール送信部分 )
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>

	// ウインドウの位置とサイズ
	top.moveTo( 30, 30 );
	top.resizeTo( 800, 800 );

	// エラーメッセージ
	var ErrMessage;

	// 
	var WshShell = new ActiveXObject("WScript.Shell");
	var Basp21 = new ActiveXObject("Basp21");

	$(function(){

		$("#send").on("click", function(){

			pass = $("#pass").val();
			if ( pass.trim() == "" ) {
				alert("パスワードを入力して下さい");
				$("#pass").focus();
				return;
			}
			if ( $("#to").val() == "" ) {
				alert("宛先を入力してください");
				$("#to").focus()
				return;
			}

			ErrMessage = Basp21.SendMail( 
				"user.sakura.ne.jp:587", 
				$("#to").val(), 
				"username@user.sakura.ne.jp" + "\t" + "account" + ":" + pass, 
				$("#subject").val(), 
				$("#body").val(), 
				"" 
			);

			// 成功すると空文字列が返り、失敗するとエラメッセージ			
			if ( ErrMessage != "" ) {
				alert(ErrMessage);
			}
			else {
				alert("メール送信が終了しました。");
			}
		});
		
		$("#taskmgr").on("click", function(){

			WshShell.Run("ms-settings:windowsupdate");

		});

	});

</script>
<style>
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 360px;
	background-color: #e0e0e0;
}
#extend {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 360px - 2px );
	border: solid 2px #c0c0c0;
}

</style>
</head>
<body>
<div id="head">

	<p class="ttl">
		宛先
	</p>
	<p class="entry">
		<input
			id="to"
			type="text">

		<span
			class="ml-5">パスワード</span>
		<input
			class="ml-3"
			style="width:120px;"
			id="pass"
			type="password">
	</p>
	<p class="line"></p>

	<p class="ttl">
		件名
	</p>
	<p class="entry">
		<input
			style='width:500px;'
			type="text"
			id="subject">
	</p>
	<p class="line"></p>

	<p class="ttl">
		本文 
	</p>
	<p class="entry">
		<textarea
			style='width:500px;height:150px;'
			id="body"></textarea>
	</p>
	<p class="line"></p>

	<p>
		<input
			id="send"
			class="btn btn-outline-primary"
			type="button"
			value="メール送信">

		<input
			id="taskmgr"
			class="btn btn-info ml-5"
			type="button"
			value="Windows Update">
	</p>

	<h4 class="text-danger"></h4>

</div>

<iframe id="extend" name="extend" APPLICATION="yes" src="iframe_in.html"></iframe>


</body>
</html>


iframe_in.html

Basp21 の RcvMail メソッドが返す配列は、VBArray なので、toArray() メソッドで JavaScript の配列に変換しています。
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css">
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"></script>
<script>

	// 親ウインドウのオブジェクトを使用
	var Basp21 = parent.Basp21;
	var rcv_data;

	// テーブルの行作成用
	var row_data;


	$(function(){

		// *********************************
		// Subject,From,Date の一覧のみ
		// *********************************
		$("#list").on("click", function(){

			// テーブル表示リセット
			$("#tbl .row_data").remove();

			// 親ウインドウの入力チェック
			pass = parent.$("#pass").val();
			if ( pass.trim() == "" ) {
				alert("パスワードを入力して下さい")
				parent.$("#pass").focus();
			return;
			}
			
			// 実行中カーソル
			$("*").css({"cursor": "wait"});
			
			result = Basp21.RcvMail("user.sakura.ne.jp", 
				"username@user.sakura.ne.jp",
				pass,
				"LIST",
				">C:\\temp\\rcvmail")

			// 失敗した場合はエラーメッセージが文字列として戻されます
			if ( typeof result !== "string" ) {
			
				// *********************************
				// result は、VBArray なので、
				// JScript の標準配列に変換
				// *********************************
				rcv_data = result.toArray();

				for( i = rcv_data.length-1; i >= 0; i-- ) {
					headers = rcv_data[i].split("\t")
					
					// IFRAME 内で行を作成して IFRAME 内のテーブルに追加
					row_data = $("<tr></tr>")
						.addClass("row_data")
						.appendTo( "#tbl" );

					// Subject
					$("<td></td>")
						.text(headers[0].substring(9))
						.appendTo( row_data );

					// From
					$("<td></td>")
						.text(headers[1].substring(6))
						.appendTo( row_data );

					// Date
					$("<td></td>")
						.text(headers[2].substring(6))
						.appendTo( row_data );

				}

			}
			else {
				// エラーメッセージ
				alert( result );
			}
			
			// 通常カーソル
			$("*").css({"cursor": "auto"});

		});

		// *********************************
		// メールデータを最大256受信して保存
		// *********************************
		$("#recieve").on("click", function(){

			// 親ウインドウの入力チェック
			pass = parent.$("#pass").val();
			if ( pass.trim() == "" ) {
				alert("パスワードを入力して下さい")
				parent.$("#pass").focus();
				return;
			}

			// 実行中カーソル
			$("*").css({"cursor": "wait"});

			result = Basp21.RcvMail("user.sakura.ne.jp", 
				"username@user.sakura.ne.jp",
				pass,
				"SAVEALL",
				">C:\\temp\\rcvmail")
				
			// 通常カーソル
			$("*").css({"cursor": "auto"});

			// 失敗した場合はエラーメッセージが文字列として戻されます
			// 成功した場合はファイル名の VBArray になります
			if ( typeof result == "string" ) {
				alert( result );
			}
			else {
				alert( "正しくデータを取得しました" )
			}

		});

		// *********************************
		// 受信したデータより一覧を表示
		// *********************************
		$("#datalist").on("click", function(){

			// テーブル表示リセット
			$("#tbl .row_data").remove();

			// 実行中カーソル
			$("*").css({"cursor": "wait"});
			
			// 最新日付順
			result = Basp21.SortMail("C:\\temp\\rcvmail","date:",1)

			if ( typeof result == "string" ) {
				alert( result )
				$("*").css({"cursor": "auto"});
				return;
			}

			// *********************************
			// result は、VBArray なので、
			// JScript の標準配列に変換
			// *********************************
			rcv_data = result.toArray();

			for( i = 0; i < rcv_data.length; i++ ) {
			
				filename = rcv_data[i];
				
				// メールデータ取得
				result = Basp21.ReadMail("C:\\temp\\rcvmail\\" + filename,"subject:from:date:","C:\\temp\\rcvdata")
				if ( typeof result == "string" ) {
					alert( result )
					$("*").css({"cursor": "auto"});
					return;
				}
				
				row_cols = result.toArray();


				// IFRAME 内で行を作成して IFRAME 内のテーブルに追加
				row_data = $("<tr></tr>")
					.addClass("row_data")
					.appendTo( "#tbl" )
					.on("click", function(){
					
						filename = $(this).find("td").eq(0).text();
						// メールデータの本文取得
						result = Basp21.ReadMail("C:\\temp\\rcvmail\\" + filename,"body:","C:\\temp\\rcvdata");
						if ( typeof result == "string" ) {
							alert( result )
							$("*").css({"cursor": "auto"});
							return;
						}
						
						body_data = result.toArray();
						parent.$("#body").val( body_data[0].substring(6));

					})
					;

				// ファイル名(非表示)
				$("<td></td>")
					.text(filename)
					.css({ "display": "none" })
					.appendTo( row_data );

				// Subject
				$("<td></td>")
					.text(row_cols[0].substring(9))
					.appendTo( row_data );

				// From
				$("<td></td>")
					.text(row_cols[1].substring(6))
					.appendTo( row_data );

				// Date
				$("<td></td>")
					.text(row_cols[2].substring(6))
					.appendTo( row_data );

			}

			// 通常カーソル
			$("*").css({"cursor": "auto"});
		});



	});

</script>
<style>
.row_data td {
	cursor: pointer!important;
}

html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

/* IFRAMEコントロール用  */
#head {
	padding: 16px;
	width: 100%;
	height: 70px;
	background-color: #e0e0e0;
}
#extend {
	display: block;
	margin-left: auto;
	margin-right: auto;
	width: calc( 100% - 3px );
	height: calc( 100% - 70px - 2px );
	border: solid 2px #c0c0c0;
}

</style>
</head>
<body>
<div id="head">

	<p>
		<input
			id="list"
			class="btn btn-outline-primary"
			type="button"
			value="メール一覧">

		<input
			id="recieve"
			class="btn btn-outline-primary ml-5"
			type="button"
			value="メール本体を全て受信">

		<input
			id="datalist"
			class="btn btn-outline-primary ml-5"
			type="button"
			value="受信済メールデータ一覧">

	</p>

	<h4 class="text-danger"></h4>

</div>

<table class="table table-hover">
	<tbody id="tbl">
	</tbody>
</table>


</body>
</html>


関連する記事

HTA(HTMLアプリケーション) のコードを html として IE11 でデバッグする方法





posted by lightbox at 2018-07-12 16:18 | HTA ( HTMLアプリケーション ) | このブログの読者になる | 更新情報をチェックする

2018年07月11日


HTA + Basp21 + jQuery + twitter-bootstrap(4.1.1) でメール送信ツール

Basp21 は SSL に対応していないので、運用の範囲内でうまく利用する事が必要です。バッチ処理のログ代わり使うなど、レンタルサーバのメールアカウント等(すぐに変更削除可能なもの)を使って、外部に出ても問題の無いデータに利用しましょう。

また、このサンプルの趣旨は、HTA を使った小回りの効く運用ツールとしての使い方の紹介です。



Basp21 は、32ビットですが、HTA はそもそも 32ビットで動作します。
Basp21 は、Down Load! BASP21-2003-0211.exe (1.44MB) 2003/02/11 Update!  推奨です。


<meta http-equiv="x-ua-compatible" content="ie=edge" /> で、bootstrap(4.1.1) が動作したので、たぶん jQuery も最新版が動作するとは思いますが、IE系で JavaScript の動作確認はいろいろ大変なので古い jQuery を使用しています

※ メールアカウントは、さくらインターネットを使用しています

▼ ソースコード
<html>
<head>
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.1/css/bootstrap.css" />
<script>

	top.moveTo( 300, 150 );
	top.resizeTo( 800, 600 );

	var ErrMessage

	var WshShell = new ActiveXObject("WScript.Shell");
	var Basp21 = new ActiveXObject("Basp21");

	$(function(){

		$("#send").on("click", function(){
			ErrMessage = Basp21.SendMail( 
				"サーバーアドレス:587", 
				$("#to").val(), 
				"差出人メールアドレス" + "\t" + "アカウント" + ":" + $("#pass").val(), 
				$("#subject").val(), 
				$("#body").val(), 
				"" 
			);
			
			if ( ErrMessage != "" ) {
				alert(ErrMessage);
			}
			else {
				alert("メール送信が終了しました。");
			}
		});

	});

</script>
<style>
html,body {
	height: 100%;
}

body {
	margin: 0;
}

/* ブロックを左右に表示  */
.ttl {
	display: inline-block;
	width: 150px;
	vertical-align: top;
}
.entry {
	display: inline-block;
}
.line {
	margin-bottom: 0;
}

#head {
	padding: 16px;
}

</style>
</head>
<body>
<div id="head">

	<p class="ttl">
		宛先
	</p>
	<p class="entry">
		<input
			id="to"
			type="text">

		<span
			class="ml-5">パスワード</span>
		<input
			class="ml-3"
			style="width:120px;"
			id="pass"
			type="password">
	</p>
	<p class="line"></p>

	<p class="ttl">
		件名
	</p>
	<p class="entry">
		<input
			style='width:500px;'
			type="text"
			id="subject">
	</p>
	<p class="line"></p>

	<p class="ttl">
		本文 
	</p>
	<p class="entry">
		<textarea
			style='width:500px;height:300px;'
			id="body"></textarea>
	</p>
	<p class="line"></p>

	<p>
		<input
			id="send"
			class="btn btn-outline-primary"
			type="button"
			value="メール送信">
	</p>

	<h4 class="text-danger"></h4>

</div>
</body>
</html>


Bootstrap Buttons

Bootstrap Spacing




posted by lightbox at 2018-07-11 16:26 | HTA ( HTMLアプリケーション ) | このブログの読者になる | 更新情報をチェックする
container 終わり

フリーフォントで簡単ロゴ作成
フリーフォントでボタン素材作成
フリーフォントで吹き出し画像作成
フリーフォントではんこ画像作成
ほぼ自由に利用できるフリーフォント
フリーフォントの書体見本とサンプル
画像を大きく見る為のウインドウを開くボタンの作成

CSS ドロップシャドウの参考デモ
BUTTONS (CSS でボタン)
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり