SQLの窓

2018年02月08日


jQuery + bootstrap.js で ajax の GET と POST を使用した DB テーブルを更新する UI テンプレート

実際のアプリケーションの UI 部分のみ取り出して、ブラウザでテストできるように構成しました。特に jQuery の ajax を用いたテンプレートとして流用できると思います。

初回の キー入力部分では、$.get で GET 読み込みを行っています。第二パスである更新時は $.ajax で POST を使用して送信しています。( POST では FormData オブジェクトを使用しています )

更新確認には、bootstrap のダイアログを使用して、一つのフォームで二つのデータ送信がコードとして別々に読めるようになっています。

実際の FORM の中に入力フィールドを配置して、HTML のチェック機能を利用できるようにしています。ブラウザの送信は、preventDefault() でキャンセルして、ajax でデータを送信するスタイルとなっています。

※ submit_type == "pass1" は、第一パス(キーの送信)です
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/js/bootstrap.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.3/toastr.min.js"></script>

<script>
// ▼ このコードのみでのテスト用変数
var submit_type = "pass1";
//var submit_type = "pass2";

$(function(){

	if ( submit_type == "pass1" ) {
		$("[name^='fld_'],#ref_btn").prop('disabled', true);
	}
	if ( submit_type == "pass2" ) {
		$("input[name='key_code']").prop('readonly', true);
		$("[name^='fld_'],#ref_btn").prop('disabled', false);
	}

	// **************************************
	// 確認処理
	// **************************************
	$("#base").on( "submit", function(event){

		// 更新確認ダイアログの表示の為、本来の送信処理はキャンセル
		event.preventDefault();

		// 入力したコードよりデータを取得する
		if ( submit_type == "pass1" ) {

			console.log("key_code");
			console.log(key_code);

			// Ajax で GET する
			$.get({
				url: "app-get.php",
				cache: false,
				data: { "key_code" : $(this).find("input[name='key_code']" ).val() }
			})
			.done(function( data, textStatus ){
				console.log( "status:" + textStatus );
				console.log( "data:" + JSON.stringify(data, null, "    ") );

				if ( data.status == 0 ) {

					// *************************************
					// コード部分を入力不可に設定
					// *************************************
					$("input[name='key_code']").prop('readonly', true);

					// *************************************
					// 明細部分を入力可能に変更
					// *************************************
					$("[name^='fld_'],#ref_btn").prop('disabled', false);

					// 氏名
					$("input[name='fld_name']").val( data.row["氏名"] );
					// フリガナ
					$("input[name='fld_kana']").val( data.row["フリガナ"] );
					// 給与
					$("input[name='fld_kyuyo']").val( data.row["給与"] );

					// 所属
					$("input[name='fld_syozoku']").val( data.row["所属"] );
					$("#ref_syozoku").text( data.row["所属名"] );

					// 性別
					$("select[name='fld_seibetu']").val( data.row["性別"] );
					// 生年月日
					$("input[name='fld_birth']").val( data.row["生年月日"].substring(0,10) );

					// フォーカスを設定
					$("input[name='fld_name']").focus();

					// コードをローカルストレージに保存
					localStorage["code"] = parent.$("input[name='key_code']").val();


					// エラーが無ければ次の処理を行えるようにする
					submit_type = "pass2";

				}

				// 対象データが無い場合
				if ( data.status == 1 ) {
					// エラーメッセージを表示
					toastr.error("入力された社員コードは存在しません");

					// エラー部分にフォーカスをセット
					$("input[name='key_code']").focus();
					// エラーが発生したフィールド内の文字列を選択する
					$("input[name='key_code']").select();

				}

				if ( data.status == -1 ) {
					// エラーメッセージを表示
					toastr.error("システムエラーです : SQL にあやまりがあります");

				}
				
			})
			// 失敗
			.fail(function(jqXHR, textStatus, errorThrown ){
				console.log( "status:" + textStatus );
				console.log( "errorThrown:" + errorThrown );

				// エラーメッセージを表示
				toastr.error("システムエラーです");

			})
			// 常に実行
			.always(function() {
			})
			;

		}


		// Bootstrap の モーダルダイアログの表示
		if ( submit_type == "pass2" ) {
			$("#update_check").modal();
		}

	});

	// **************************************
	// Bootstrap OK ボタン
	// ※ ここで第二パスの送信処理を確定
	// **************************************
	$("#data_update").on("click", function(){

		// Ajax で POSTする

		// 新規送信用オブジェクト
		var formData = new FormData();

		// ファイルオブジェクト
		formData.append("key_code", $("input[name='key_code']").val() );
		formData.append("fld_name", $("input[name='fld_name']").val() );
		formData.append("fld_kana", $("input[name='fld_kana']").val() );
		formData.append("fld_seibetu", $("select[name='fld_seibetu']").val() );
		formData.append("fld_birth", $("input[name='fld_birth']").val() );
		formData.append("fld_kyuyo", $("input[name='fld_kyuyo']").val() );
		formData.append("fld_syozoku", $("input[name='fld_syozoku']").val() );

		// **************************************
		// サーバ呼び出し
		// **************************************
		$.ajax({
			url: "app-update.php",
			type: "POST",
			data: formData,
			processData: false,  // jQuery がデータを処理しないよう指定
			contentType: false   // jQuery が contentType を設定しないよう指定
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );

			// *************************************
			// コードを入力可に設定
			// *************************************
			$("input[name='key_code']").prop('readonly', false);

			// *************************************
			// 明細部分を入力不可に変更
			// *************************************
			$("[name^='fld_'],#ref_btn")
				.prop('disabled', true);

			// 氏名のクリア
			$("input[name='fld_name']").val( "" );
			// フリガナのクリア
			$("input[name='fld_kana']").val( "" );
			// 給与のクリア
			$("input[name='fld_kyuyo']").val( "" );

			// 所属のクリア
			$("input[name='fld_syozoku']").val( "" );
			$("#ref_syozoku").text("");

			// 性別の初期化
			$("select[name='fld_seibetu']").val( "0" );
			// 生年月日の初期化
			$("input[name='fld_birth']").val( "" );

			// フォーカスを設定
			$("input[name='key_code']").focus();
			
			// エラーが無ければ次の処理を行えるようにする
			submit_type = "pass1";

			toastr.info("更新されました");


		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "code:" + jqXHR.status );
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
		})
		.always(function() {
		})
		;



	});

});
</script>


<input
	id="action_copy"
	type="submit"
	value="送信"
	class="btn btn-primary"
	onclick="$('#action').click();"
	style='float:right'>

<input
	id="action_reset"
	type="button"
	value="リセット"
	class="btn btn-danger mr-3"
	onclick="location.href='/access-1129/app/syain-upd/syain.php'"
	style='float:right'>

<form id="base" method="post" target="_self">
	<div>
		<div class="left">社員コード</div>
		<div class="right">
			<input
				type="text"
				id="key_code"
				name="key_code"
				class="unit"
				value="" required >
		</div>
	</div>
	<div>
		<div class="left">氏名</div>
		<div class="right">
			<input
				type="text"
				id="fld_name"
				name="fld_name"
				class="unit"
				value="" required >
		</div>
	</div>
	<div>
		<div class="left">フリガナ</div>
		<div class="right">
			<input
				type="text"
				id="fld_kana"
				name="fld_kana"
				class="unit"
				value=""  >
		</div>
	</div>
	<div>
		<div class="left">給与</div>
		<div class="right">
			<input
				type="text"
				id="fld_kyuyo"
				name="fld_kyuyo"
				class="unit"
				value="" required maxlength='7' pattern='\d+' >
		</div>
	</div>
	<div>
		<div class="left">所属</div>
		<div class="right">
			<div class="input-group">
				<input
					type="text"
					id="fld_syozoku"
					name="fld_syozoku"
					class="unit form-control"
					value=""
					maxlength="4"
					readonly>
		
				<span class="ml-2 pl-2 pt-2" id="ref_syozoku"></span>

				<input class="ml-2" type="button" value="参照" id="ref_btn">
			</div>
		</div>
	</div>
 
	<div>
		<div class="left">性別</div>
		<div class="right">
			<select class="unit form-control" name="fld_seibetu" id="fld_seibetu" >
				<option value="0">男性</option>
				<option value="1">女性</option>
			</select>
		</div>
	</div>

	<div>
		<div class="left">生年月日</div>
		<div class="right">
			<div class="input-group">
				<input readonly type="text" id="fld_birth" name="fld_birth">
				<button
					type="button"
					class="btn"
					onclick='$(this).prev().val("");'>×</button>
			</div>
		</div>
	</div>

	<div style='height:60px'>
		<div class="left"><label for="fld_skbn">正社員</label></div>
		<div class="right">
			<input type="checkbox" id="fld_skbn" name="fld_skbn" class="unit form-control" value="1" style="width: 1rem;margin-top: 14px;height 1rem">
		</div>
	</div>

	<div>
		<div class="left">年代</div>
		<div class="right">
			<div class="input-group">
				<label for="fld_nendai_a" class="mt-2">20代</label>
				<input type="radio" id="fld_nendai_a" name="fld_nendai" class="ml-1 mr-3" value="A" style="width: 1rem;margin-top: 0.75rem;">

				<label for="fld_nendai_b" class="mt-2">30代</label>
				<input type="radio" id="fld_nendai_b" name="fld_nendai" class="ml-1 mr-3" value="B" style="width: 1rem;margin-top: 0.75rem;">

				<label for="fld_nendai_c"  class="mt-2">40代</label>
				<input type="radio" id="fld_nendai_c" name="fld_nendai" class="ml-1 mr-3" value="C" style="width: 1rem;margin-top: 0.75rem;">

				<label for="fld_nendai_d"  class="mt-2">50代</label>
				<input type="radio" id="fld_nendai_d" name="fld_nendai" class="ml-1" value="D" style="width: 1rem;margin-top: 0.75rem;">
			</div>
		</div>
	</div>

	<div>
		<input
		id="action"
			type="submit"
			value="送信"
			class="btn btn-primary unit mt-5"
			title="mt5 は margin-top の略で 1〜5">
	</div>

</form>

<div class="modal fade" id="update_check" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
	<div class="modal-dialog" role="document">
		<div class="modal-content">

			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
				<h4 class="modal-title" id="myModalLabel">確認</h4>
			</div>

			<div class="modal-body">
			更新しますか?
			</div>

			<div class="modal-footer">
				<button id="data_update" type="button" class="btn btn-default" data-dismiss="modal">OK</button>
			</div>

		</div>
	</div>
</div>





posted by lightbox at 2018-02-08 10:03 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2018年01月13日


jQuery による link 要素の追加と削除を bootstrap.css でリアルタイムチェック

このサンプルは、css 用ですが、script でも同じです。bootstrap を組み込むと、たいていなんらかの変化が出るので確認に使用してます。

特定の要素の下に追加、削除を想定しているので id を持つ要素だともっと簡単ですが、ここではそのページの最後の link 要素を使用しています > 『$("link").eq($("link").length-1)


<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>

$(function(){

	// Bootstrap 削除
	$("#btn-remove").on("click", function(){

		if ( $("#bootstrap").length != 0 ) {
			$("#bootstrap").remove();
		}

	});

	// Bootstrap 適用
	$("#btn-apply").on("click", function(){

		if ( $("#bootstrap").length == 0 ) {

			var link = $("<link id='bootstrap'>");
			link.prop({
				"rel": "stylesheet",
				"href": "https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.css"
			});

			// 最後の link の後に追加
			var target = $("link").eq($("link").length-1);
			link.insertAfter(target);
		}

	});

});
</script>

<div>
	<p>
		<input type="button" id="btn-remove" value="Bootstrap 削除">
		<input type="button" id="btn-apply" value="Bootstrap 適用">
	</p>
</div>


タグ:jquery
posted by lightbox at 2018-01-13 22:46 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2018年01月09日


ページの右下に、ページの先頭へ移動するボタンを追加する(ページの先頭から 200px までは、スクロールボタンを表示しない)

このブログにも設置しました。スクロールすると、文字部分が白く、影の付いた ▲ ボタンがページの右下に表示されます。

『ページの先頭から 200px までは、スクロールボタンを表示しない』という処理の部分にのみ jQuery を使用しています。常に表示しておくのならば CSS のみで問題ありません( その場合は、A 要素に display:none は必要ありません )

CSS
#scroll_top {
	position: fixed;
	text-decoration: none;
	font-size: 40px;
	color: rgba(255,255,255,0.85);
	text-shadow: 1px 1px 2px #656a6f;
	right: 0.5%;
	bottom: 5rem;

}


A 要素

これは、</body> の直前に記述しています。
<a href="javascript:void(0);" id="scroll_top" onclick="window.scroll(0,0);" style="display:none;">▲</a>
※ CSS の記述を A 要素に全てインラインスタイルとして記述してもいいです。

jQuery 部分
$(function(){

	$(window).on("scroll",function(){
		var scroll = $("html").scrollTop();
		if ( scroll <= 200 && $("#scroll_top").css("display") != "none" ) {
			$("#scroll_top").css("display","none");
		}
		if ( scroll > 200 && $("#scroll_top").css("display") == "none" ) {
			$("#scroll_top").css("display","inline");
		}
	});

});

この jQuery では、A 要素のインラインスタイルである、display プロパティをフラグとして使用し、表示したり消したりするのは最低限の回数になるようにしています。なので、display:none は必ず インラインスタイル側で指定する必要があります。


posted by lightbox at 2018-01-09 20:19 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年10月12日


テーブルのTDをクリックしたら、INPUT で値を変更可能にして、元の値と違うものにはフラグを立てる処理を絵で書いて説明してみました



とにかく、複雑になってしまったので絵にしてみました。

デモページ(送信ボタンで一覧表示した後でデモ)


ソースコードはこんな感じ
	$("#data .row_data").each(function(i){

		var td = $(this).find("td").eq(2);

		td.css( 
			{ "text-decoration":"underline", "cursor":"crosshair", "background-color" : "pink" }
		);

		// 入力内容
		var text = td.text();
		// 入力内容を保存
		td.data("text", text );

		td.on("click", function(){
			if ( $(this).data("input") != "use" ) {
				// 入力切替えフラグ
				$(this).data("input", "use" );

				// 入力内容
				var text_now = $(this).text();

				// TD の表示を消去
				$(this).text("");

				// 入力を追加
				$("<input>")
						.appendTo($(this))		// TD に追加
						.val(text_now)			// テキストセット
						.focus()			// フォーカスセット
						// focusout で元に戻す
						.on( "focusout", function(){

							// 現在の入力
							var text = $(this).val();

							// 親 TD
							var td = $(this).parent();

							// データが変更されていたら『変更フラグ』をセット
							if ( text != td.data("text") ) {
								td.data("change", "yes");
								td.css("background-color","silver");
							}
							else {
								td.data("change", "");
								td.css("background-color","pink");
							}

							// TD に値を戻して 切替えフラグを消去
							td
								.append(text)
								.data("input", "" );

							// INPUT を削除
							$(this).remove();


						});

			}

		});

	});



posted by lightbox at 2017-10-12 03:17 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年09月28日


jQuery を使用してサーバから取得した JSON データを元にテーブルを作成し、その後から列を加工する

HTML 部分は、タイトル部分と thead のみ作成し、JSON データを取り出す毎に作り直すようになっています。

$.each でループ処理している対象のデータは row です。これは JSON オブジェクトで、1行1行のデータを保持したデータセットの配列です。

▼ フォーマット
[
        {
            "社員コード": "0001",
            "氏名": "浦岡 友也",
            "フリガナ": "ウラオカ トモヤ",
            "所属": "0003",
            "性別": "0",
            "給与": "270000",
            "手当": "9000",
            "管理者": "",
            "生年月日": "2000-01-01 00:00:00",
            "性別2": "男",
            "所属名": "営業部第三",
            "手当2": "9000"
        },
        {
            "社員コード": "0002",
            "氏名": "山村 洋代",
            "フリガナ": "ヤマムラ ヒロヨ",
            "所属": "0003",
            "性別": "1",
            "給与": "300000",
            "手当": "",
            "管理者": "",
            "生年月日": "",
            "性別2": "女",
            "所属名": "営業部第三",
            "手当2": "0"
        }
]

※ number_format() は、String.prototype.number_format として定義済みです
※ text-right は、twitter-bootstrap で定義されています
	// テーブル表示リセット
	$("#data .row_data").remove();

	// データ用
	var row_data;
	var col_data;

	// 行のループ  ( <tr></tr> )
	$.each(row, function( index, obj ) {

		// テーブルに行を追加	
		row_data = $("<tr class=\"row_data\"></tr>").appendTo( "#data" );
	
		// 行に列を追加	
		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["社員コード"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["氏名"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["フリガナ"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["性別2"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["所属"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["所属名"] );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.attr("class","text-right")
		// head-js.view で String.prototype に定義
		col_data.text( obj["給与"].number_format() );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.attr("class","text-right")
		// head-js.view で String.prototype に定義
		col_data.text( obj["手当2"].number_format() );

		col_data = $("<td></td>").appendTo( row_data );
		col_data.text( obj["生年月日"] != null ? obj["生年月日"].substr(0,10) : "" );
	
	});


1 列目をコード、2列目を氏名として、2列目のテキストにリンクを設定するには以下のよう記述します。
	$("#data .row_data").each(function(i){

		var code = $(this).find("td").eq(0).text();
		var name = $(this).find("td").eq(1).text();

		var link = '<a href="https://ドメイン/?code=' + code  +  '" target="_blank">' + name + '</a>';

		$(this).find("td").eq(1).html( link );

	});



TD の中の文字列にスタイルを適用してクリックした時のイベントを登録する(条件付)には、以下のように記述します

※ ここでは、特定の行のみ処理しています
	$("#data .row_data").each(function(i){

		var type = $(this).find("td").eq(1).text();
		var td = $(this).find("td").eq(0);

		if ( type == "特定の文字列" ) {
			td.css( 
				{ "text-decoration":"underline", "cursor":"pointer" }
			);
			td.on("click", function(){ 
				alert( $(this).text() );
			});
		}

	});



以下は対象となる HTML の記述です
<div id="req">
	<table id="data" class="table table-condensed table-hover">
	<thead>
		<tr>
		<th>コード</th>
		<th>氏名</th>
		<th>フリガナ</th>
		<th>性別</th>
		<th>所属</th>
		<th>所属名</th>
		<th class="text-right">給与</th>
		<th class="text-right">手当</th>
		<th>生年月日</th>
		</tr>
	</thead>
	</table>
</div>




posted by lightbox at 2017-09-28 20:18 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年06月09日


JSON 配列を WEB より読み出して jQuery で動的にテーブルを作成して表示する


デモページ

関連する記事デモで実際に使用している自家製 API です

PHP : SQLインジェクション対策付きの、MySQL のデータを JSON で返す自家製 API テスト用のテンプレート3パターン

https://lightbox.sakura.ne.jp/demo/json/syain_api_bind.php
https://lightbox.sakura.ne.jp/demo/json/syain_api_bind.php?pretty=no : 整形なし
https://lightbox.sakura.ne.jp/demo/json/syain_api_bind.php?escape=no : \uXXXX にエスケープ

▼ TABLE 作成部分はほぼ同じです

FileReader で、ローカルの CSV を読み込んで(shift_jis)、jQuery でテーブルを作成して表示する

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
body {
	padding: 10px 0 0 20px;
}
@media screen and ( max-width:479px )
{
	body {
		padding: 0px;
	}
}
#table_wrap {
	width:900px;

}
#syain  td {
	padding: 5px;
	border: solid #000000 1px;
	white-space: nowrap;
}
#syain  th {
	background-color: #e0e0e0;
	font-weight: bold;
	padding: 5px;
	border: solid #000000 1px;
	white-space: nowrap;
}
</style>
<script>
$(function(){

	$("#btn").on( "click", function(){
	
		console.log("クリックされました");
		$.ajax({
			url: "https://lightbox.sakura.ne.jp/demo/json/syain_api_bind.php",
			cache: false,
			data: { "name" : $("#cond").val() }
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );

			// テーブル作成処理
			loadData( data );
			
		})
		// 失敗
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
		})
		// 常に実行
		.always(function() {
			console.log("常に実行");
		})
		;		
	
	});

});


function loadData( data ) {

	console.log("処理開始");

	// テーブル表示リセット
	$("#syain tr,#syain th").remove();

	// タイトル専用
	var title_row;
	var title_col_data;
	// データ用
	var row_data;
	var col_data;

	// 行のループ  ( <tr></tr> )
	$.each(data, function( index, value ) {
	
		// 初回はタイトル作成
		if ( index == 0 ) {
			$.each( value, function( key, val ) {
				title_col_data = $("<th></th>").appendTo( "#syain" );
				title_col_data.text( key );
			});
		}

		// テーブルに行を追加	
		row_data = $("<tr></tr>").appendTo( "#syain" );
	
		// 列のループ ( <td></td> )
		$.each( value, function( key, val ) {
		
			// 行に列を追加
			col_data = $("<td></td>").appendTo( row_data );
			col_data.text( val );

		});
	
	});

}
</script>
<h3>社員一覧</h3>

<input id="cond" type="text">
<input id="btn" type="button" value="検索">

<div class="table-responsive">
<table id="syain"></table>
</div>



twitter-bootstrap は、スマホでテーブルが横スクロールする効果で使用しています( class="table-responsive" )。


posted by lightbox at 2017-06-09 22:04 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年06月04日


FileReader で、ローカルの CSV を読み込んで(shift_jis)、jQuery でテーブルを作成して表示する



デモページ

type="file" でローカルのファイルを指定して、キャラクタセットを指定して読み込みます。ここでは、input 要素に multiple を指定していないのでファイルは一つしか指定できませんが、multiple を指定して追加の処理(cssファイルを読み込んでテーブルの見た目を調整する等)を行うのもいいでしょう。

※ 処理は、multiple を想定して files.length ぶんループしています
※ JavaScript のコレクション処理は、$.each を使う必要があります。

input に accept="text/*" を指定できますが、csv は対象では無かったので使用していません。画像を使う場合には絶対に使用する必要があるでしょう。



ソースコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<style>
#list {
	border-collapse: collapse;
}
#list  td {
	padding: 5px;
	border: solid #000000 1px;
	white-space: nowrap;
}
</style>
<input type="file" id="row1_fld" name="row1_fld">
<table id="list"></table>
<script>
$("#row1_fld").on("change", function(){

	for( i = 0; i < this.files.length; i++ ) {

		// FileReader は毎回作成(同時に複数のファイルを扱えない)
		var reader = new FileReader();

		// FileReader にデータが読み込まれた時のイベント
		var token1 = "";
		var token2 = "";
		var tr = null;
		$(reader).on("load", function () {
			token1 = this.result.split("\n");
			$.each( token1, function( idx, value ){
				// 空行を無視
				if ( value == "" ) {
					return;
				}
				token2 = value.split(",");
				// 行を作成
				tr = $("<tr></tr>").appendTo("#list");
				$.each( token2, function( idx, value ){
					// TD を追加して、テキストをセット
					$("<td></td>").appendTo(tr)
						.text(value);
				} )
			} )
		});

		// 上記イベントを発動するための処理( this.files[i] は blob )
		if (this.files[i]) {
			// CSV は通常 shift_jis なので、指定します
			reader.readAsText(this.files[i],"shift_jis");
		}
	}

});
</script>



posted by lightbox at 2017-06-04 12:11 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年03月13日


jQuery UI の Datepicker Widget のオプション


デモページ

デモページでは、いろいろなオプションを設定した Datepicker のフィールドの動きを確認できます。これらのフィールドは、デフォルトのオプションとして以下のようなものを設定済みです。
var datepicker_option = {
	dateFormat: 'yy/mm/dd',
	dayNamesMin: ['日', '月', '火', '水', '木', '金', '土'],
	monthNames:  ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
	showMonthAfterYear: true,
	yearSuffix: '年',
	changeYear: true,
	showAnim: 'fadeIn',
	yearRange: "c-70:c"
}

このオプションは、日本語としてカレンダーを利用する為に最低限必要なものです。


※ ▼ コンボボックスの幅を以下で最適化しています
.ui-datepicker-month, .ui-datepicker-year {
	width: 70px!important;
}
yearRange: "c-70:c" のオプションは、c が現在の年を示す相対範囲指定です。デモページでは、2) cは当年 c-3:c+3 にあたります。そして、1) dateRangeなし は、そのオプションを削除したもので、その場合は "c-10:c+10" を指定したのと同じ事になります。 ▼ "c-3:c+3" ▼ jQuery を使用して、JSON オブジェクトのクローンを作成
	var datepicker_option1 = $.extend(true, {}, datepicker_option);
	delete datepicker_option1.yearRange;

	$("#date_picker1_fld").datepicker( datepicker_option1 );
※ デモで複数のオプション作成の為、$.extend を使用しています

altField, altFormat, appentText, autoSize

altField と altFormat は、alternate(代わりの) フィールドの定義です。altField で右横にあるフィールドを id で参照します。altFormat では、そのフィールドで表示するフォーマットを指定します(ここでは日本語を使用しています。)

さらに、appentText で、DatePicker フィールドの後ろにテキストを追加し、autoSize で jQuery UI にDatePicker フィールドの幅を調整させます。
	var datepicker_option3 = $.extend(true, {}, datepicker_option);
	datepicker_option3.altField  = "#date_picker3_fld_alt";
	datepicker_option3.altFormat  = "yy年mm月dd日";
	datepicker_option3.appendText  = " altFormat で日本語表現 ";
	datepicker_option3.autoSize = true;

	$("#date_picker3_fld").datepicker( datepicker_option3 );

※ 二番目のフィールドは固定で 120px を指定しており、3番目のフィールドが autoSize です。

ボタンでカレンダーを表示させる

通常では、フィールドにカーソルが移動するとカレンダーが表示されますが、それでは他の画面部分が隠されてしまって、エンドユーザが操作しづらい場合があります。そういう場合にボタンを追加してその操作を行う方法です。ここでは、その目的のために showOn = "button" と buttonText = "開く" を指定しています。(showOn では、both というオプションがありますが、それでは意味が無いので button のみの動作、また、buttonText では無く buttonImage で画像ボタンにする事もできます)

月を変更可

★重要 : 表示したい月表現を monthNamesShort = ["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"] のように設定する必要がありました

誕生日の指定等、連続していない年月の指定の為、月をコンボボックスに変更します。



※ ▼ コンボボックスの幅を以下で最適化しています
.ui-datepicker-month, .ui-datepicker-year {
	width: 70px!important;
}
※ 月を変更可にした場合、これをしておかないと、年と月が入りきらずに二段になってしまいます。 前後の月を表示して選択可能にする これは、現実のカレンダーのように、表示できる場合は前月の最後と次月の最初を表示して選択できるようにするものです。そのために showOtherMonths = true と selectOtherMonths = true を両方設定しています。 jQuery.ajax による送信処理
	// *************************************
	// 送信 <input type="submit">
	// *************************************
	$("#frm").submit( function(event){
		// 本来の送信処理はキャンセル
		event.preventDefault();

		// 入力部分をプロテクト
		$("fieldset").eq(0).prop("disabled", true);

		// エラーメッセージエリアをクリア
		$(".error").next().text( "" );

		// 結果の表示エリアを全てクリア
		$("#result").html( "" );


		// 新規送信用オブジェクト
		var formData = new FormData();

		formData.append("datepicker1", $("#date_picker1_fld").val() );
		formData.append("datepicker2", $("#date_picker2_fld").val() );
		formData.append("datepicker3", $("#date_picker3_fld").val() );
		formData.append("datepicker3_alt", $("#date_picker3_fld_alt").val() );
		formData.append("datepicker4", $("#date_picker4_fld").val() );
		formData.append("datepicker5", $("#date_picker5_fld").val() );
		formData.append("datepicker6", $("#date_picker6_fld").val() );

		// **************************************
		// サーバ呼び出し
		// **************************************
		$.ajax({
			url: "./post_action.php",
			type: "POST",
			data: formData,
			processData: false,  // jQuery がデータを処理しないよう指定
			contentType: false   // jQuery が contentType を設定しないよう指定
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );
			options.info("送信処理が完了しました");

		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
			options.info("送信処理を失敗しました");
		})
		.always(function() {

			// 入力部分のプロテクトを解除
			$("fieldset").eq(0).prop("disabled", false);
		})
		;


	} );



タグ:datepicker jquery
posted by lightbox at 2017-03-13 14:27 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年03月10日


FormData を使用して、jQuery で配列として PHP に送る

必要なデータを隠しリストボックス( multiple ) に jQuery で追加して配列として PHP に送る では、select 要素を使用しましたが、jQuery の ajax と FormData を使用すれば、もっと単純に送る事ができます。

送信用データ作成部分は結局4行です
		// 新規送信用オブジェクト
		var formData = new FormData();

		// 送信フィールド作成
		$("#row1_fld option").each( function(){
			formData.append("ybp[]", $(this).val());
		});

		// **************************************
		// サーバ呼び出し
		// **************************************
		$.ajax({
			url: "./post_action.php",
			type: "POST",
			data: formData,
			processData: false,
			contentType: false
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );
			options.info("処理が完了しました");

		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
			options.info("アップロードに失敗しました");
		})
		.always(function() {

		})
		;


デモページ



ソースコードセットダウンロード

メインソースコード(view_main.php)
<?php
// *************************************
// 表示コントロール
// *************************************
$GLOBALS['title'] = "jQuery Ajax POST : 配列";
$GLOBALS['comment'] = 'ようこそ jQuery + Bootstrap(css) + mmenu + FormData + PHP';

?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta content="width=device-width initial-scale=1.0 minimum-scale=1.0 maximum-scale=1.0 user-scalable=no" name="viewport">
<meta charset="utf-8">
<title><?= $GLOBALS['title'] ?></title>

<?php require_once('std/libs.php') ?>

<link rel="stylesheet" href="std/mmenu.css">
<link rel="stylesheet" href="std/basic.css">

<style>
/* タイトル部分 */
.fields {
	width: 90px;
	font-size: 12px;
	/* vertical-align: middle!important; */
}

legend {
	font-size: 18px;
	padding-left: 6px;
}

</style>

<script>
<?php require_once('std/js.php') ?>
// -------------------------------------
// 画面とメッセージ
// -------------------------------------
var options = {
	row1 : { title : "複数データ<br>(Yahoo!テレビ番組表地域コード)", pcss : { width: "400px" }, attr: { size : 6 } },
	row_last : { title :"メッセージ" },
	error : function(message){
		$("#row_last").next().text( message );
		toastr.error(message);
	},
	info : function(message){
		$("#row_last").next().text( message );
		toastr.success(message);
	}
};

$(function(){

	$("#wrapper").css({"visibility":"visible", "margin-bottom": "0px"}); 
	// -------------------------------------
	// 固定テンプレート
	// -------------------------------------
	// 1) options による行とフィールドの設定
	// 2) Bootstrap 用 form-control クラスの追加
	$(".fields").each(function(){
		if ( options[ $(this).prop("id") ] ) {
			$(this).html( options[ $(this).prop("id") ].title );
			// 個別 css
			if ( options[ $(this).prop("id") ].css ) {
				$(this).next().find("input,select,textarea").css( options[ $(this).prop("id") ].css );
			}
			// 入力チェック用属性
			if ( options[ $(this).prop("id") ].attr ) {
				$(this).next().find("input,select,textarea").attr( options[ $(this).prop("id") ].attr );
			}
			// pc のみの css
			if ( options[ $(this).prop("id") ].pcss ) {
				if ( !$.isMobile ) {
					$(this).next().find("input,select,textarea").css( options[ $(this).prop("id") ].pcss );
				}
			}

		}
		$(this).next().find("input,select,textarea").addClass("form-control");
	});

	// 初期フォーカス
	setTimeout( function(){$('#row1_fld').focus();}, 100 );
	// -------------------------------------

	// *************************************
	// 送信ボタン
	// *************************************
	$("#frm").submit( function(event){
		// 本来の送信処理はキャンセル
		event.preventDefault();

		$("#post_check").modal();

	} );


	// **************************************
	// Bootstrap OK ボタン
	// **************************************
	$("#data_post").on("click", function(){

		// エラーメッセージエリアをクリア
		$(".error").next().text( "" );

		// 結果の表示エリアを全てクリア
		$("#result").html( "" );

		// **************************************
		// サーバへ送信
		// **************************************

		// 新規送信用オブジェクト
		var formData = new FormData();

		// 送信フィールド作成
		$("#row1_fld option").each( function(){
			formData.append("ybp[]", $(this).val());
		});

		// **************************************
		// サーバ呼び出し
		// **************************************
		$.ajax({
			url: "./post_action.php",
			type: "POST",
			data: formData,
			processData: false,
			contentType: false
		})
		.done(function( data, textStatus ){
			console.log( "status:" + textStatus );
			console.log( "data:" + JSON.stringify(data, null, "    ") );
			options.info("処理が完了しました");

		})
		.fail(function(jqXHR, textStatus, errorThrown ){
			console.log( "status:" + textStatus );
			console.log( "errorThrown:" + errorThrown );
			options.info("アップロードに失敗しました");
		})
		.always(function() {

		})
		;

	});

	// -------------------------------------
	// 固定テンプレート
	// -------------------------------------
	$("#mmenu_left").mmenu({
		navbar: {
			title: "メニュー"
		},
		offCanvas: {
			position  : "left",
			zposition : "next"
		}
	});
	// -------------------------------------


});

</script>
</head>
<body>

<div id="wrapper">
<script>
$("#wrapper").css( {"visibility": "hidden", "margin-bottom" : "1000px" } );
</script>

	<div id="head">
		<?php require_once('std/view_hamburger.php') ?>
		<div id="title"><?= $GLOBALS['title'] ?></div>
	</div>

	<div id="body">
		<form id="frm" class="form-inline">

			<fieldset>
				<legend></legend>
				<table class="table table-condensed">
			
					<tr>
						<td class="fields" id="row1"></td>
						<td>
							<select name="row1_fld" id="row1_fld">
								<option value="43">和歌山</option>
								<option value="44">奈良</option>
								<option value="45">滋賀</option>
								<option value="41">京都</option>
								<option value="40">大阪</option>
								<option value="42">兵庫</option>
							</select>
						</td>
					</tr>

					<tr>
						<td class="fields" id="row2"></td>
						<td>
							<input id="action" type="submit" class="btn btn-primary btn-sm" value="送信">
						</td>
					</tr>

					<tr>
						<td class="fields error" id="row_last"></td>
						<td></td>
					</tr>

				</table>

			</fieldset>

			<fieldset>
				<legend>結果</legend>
				<table id="result" class="table table-condensed">


				</table>

			</fieldset>

		</form>
	</div>

	<div id="comment">
	<?= $GLOBALS['comment'] ?>
	</div>

	<div class="modal fade" id="post_check" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
		<div class="modal-dialog" role="document">
			<div class="modal-content">

				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
					<h4 class="modal-title" id="myModalLabel">確認</h4>
				</div>

				<div class="modal-body">
				送信しますか?
				</div>

				<div class="modal-footer">
					<button id="data_post" type="button" class="btn btn-default" data-dismiss="modal">OK</button>
					<button type="button" class="btn btn-primary" data-dismiss="modal">キャンセル</button>
				</div>

			</div>
		</div>
	</div>

</div>


<?php require_once('unit_menu.php') ?>


</body>
</html>

※ jQuery + Bootstrap(css) + mmenu + FormData + PHP の総合テンプレートです


post_action.php
<?php
// *************************************
// キャラクタセット
// *************************************
header( "Content-Type: application/json; charset=utf-8" );
// *************************************
// キャッシュ無効
// *************************************
session_cache_limiter('nocache');
session_start();


// *************************************
// 処理
// *************************************


// *************************************
// PHP の結果を result キーで
// JSON としてブラウザに返す
// *************************************
print json_encode($_POST , JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT );

?>

※ 処理の結果は、開発者ツールのコンソールで確認して下さい。








posted by lightbox at 2017-03-10 23:04 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2017年03月09日


必要なデータを隠しリストボックス( multiple ) に jQuery で追加して配列として PHP に送る

送信直前に onsubmit="return check_form();" で追加して、PHP がページを再表示したら元の状態に戻るというデータの送信方法です。

jQuery は、最初に option 要素を作って、その属性を設定して最後に appendTo で select に追加して行きます。PHP 対象なので、name="target[]" となっていますが、ASP(いまだに運用してるので) だと name="target" で Request.Form("target")(n) とかで参照できます。


<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>

function check_form() {

	if ( !confirm("送信しますか?") ) {

		return false;

	}

	$("#target option").each( function(){

		$("<option></option>")
			.prop("selected", true)
			.val( $(this).val() )
			.appendTo( $("#send_target") )

	});

	return true;

}
</script>
</head>
<body>

<form method="post" onsubmit="return check_form();">

<input id="send" name="send" type="submit" value="send">

<select multiple id="send_target" name="target[]" style='display:none'>
</select>
<select id="target" size="3">
<option value="A001">テキスト1</option>
<option value="A002">テキスト2</option>
<option value="B001">テキスト3</option>
</select>


</form>

<pre>
<?php

print_r($_POST)

?>
</pre>
</body>
</html>




posted by lightbox at 2017-03-09 21:00 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2016年12月17日


Android Studio の追加日本語化用に、キャラクタセットに依存しないコード文字列を作成するツールを作成しました

PHP で作ると大げさなので、jQuery で作成しました。元に戻したい時はデベロッパーツールで console.log すればいいと思います。ソースコードは、記事の最後にあります。ここでは、サンプルとして表示する為に、テキストエリアのサイズを小さくしているので、実際に使う場合はこちらからどうぞ。

Android Studio の日本語化は、『ANDROID STUDIO 2.0 を日本語化してみた』 で入手できるもので十分ですが、自分用に表現方法を変えたい場合は、こういう文字列が必要になります。


▼ 結果の文字列( クリックすると選択します )


▼ テスト用文字列( クリックすると選択します / デベロッパーツールのコンソールで実行用 )




ソースコード
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
$(function(){

	var text;

	$("#convert").on( "click", function(){
		text = "";
		var base = $("#text").val();
		var charCode = 0;
		for( i=0; i < base.length; i++ ) {
			charCode = base.charCodeAt(i);
			if ( charCode < 0x7f ) {
				text += base.charAt(i);
			}
			else {
				text += "\\u" + ( '0000' + base.charCodeAt(i).toString(16) ).slice( -4 );
			}
		}
		$("#result").val( text );

		$("#test_string").val("console.log('" + text + "')");
	});

//	$("#check").on( "click", function(){
//		eval("var x = \"" + $("#result").val() +"\"");
//		alert( x );
//	});

});
</script>
<pre>
<input id="convert" type="button" value="日本語を文字列内用コードに変換">
<textarea id="text" style='width:90%;height:100px;margin-top:5px;font-size:16px;'>abc 日本語を文字列内用コードに変換 123</textarea>
▼ 結果の文字列( クリックすると選択します )
<textarea id="result" style='width:90%;height:200px;font-size:16px;' onclick='this.select()'></textarea>
<!--input id="check" type="button" value="alert で表示"-->
▼ テスト用文字列( クリックすると選択します / デベロッパーツールのコンソールで実行用 )
<textarea id="test_string" style='width:90%;height:200px;font-size:16px;' onclick='this.select()'></textarea>




</pre>
その場で結果を見るコードとして、コメント内で eval を使った部分があります。ですが、一般的にはデベロッパーツールで確認するのがいいでしょう。

\unnnn (nは数字) というフォーマットでないと文字列としてエラーになるので eval が必要でした。




posted by lightbox at 2016-12-17 16:24 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2016年11月17日


画像ファイルが存在した時のみ、表示する jQuery の記述

ローカルにある画像ファイルで、PHP ならば file_exists で簡単ですが、ブラウザから画像の存在チェックするにはどうするか・・・と考えてできた結論です。

php で画像を返して、image 要素の src で使い、存在しない場合は透明の小さな png を表示するのも、スッキリしていいかなと思いましたが、取り急ぎ JavaScript だけで解決する方法です。

テストすると、画像ファイルがある時だけ onload イベントが発生したので、jQuery で全て書くために、数珠繋ぎをループするという形態になっています。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<style>
.target {
	border: solid 1px #000;
	padding: 15px;
}
</style>

<table>
<tr> <td class="target"></td> </tr>
<tr> <td class="target"></td> </tr>
<tr> <td class="target"></td> </tr>
<tr> <td class="target"></td> </tr>
</table>

<script>

var img = [
"https://lightbox.sakura.ne.jp/toolbox/image/__.png", 
"https://lightbox.sakura.ne.jp/toolbox/image/script.png", 
"https://lightbox.sakura.ne.jp/toolbox/image/jquery.png", 
"https://lightbox.sakura.ne.jp/toolbox/image/__.png", 
];

$(".target").each(function( idx ){

	$("<img>").data("container", $(this) ).on("load",function(){

		$(this).data("container").append( this );

	}).prop("src",img[idx]);

});

</script>



$("<img>") が createElement にあたります。jQuery では値取得以外は自分自身が返るので、そのまま自身に設置する場所のコンテナを data で登録し、そのまま on で load イベントを登録します。その後、src に url を設定すれば、onload イベントに入り、data でコンテナを取り出して、そこへ自身を追加します。

この処理をコンテナぶん each でループしています。


posted by lightbox at 2016-11-17 22:11 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2016年09月30日


jQuery で mobile(スマホ) かどうかのチェックをしたくて調べたら、Stack Overflow の記事でいろんな方法が答えられていました。

What is the best way to detect a mobile device in jQuery?

結局 jQuery に特化した回答は無く、但し何通りもの回答がたくさんよせられていました。その中でもよさげなのが 3つほどありますのでご紹介します。

userAgent を使ったとてもシンプルなもの
jQuery.isMobile = (/android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test(navigator.userAgent.toLowerCase()));
jQuery で $ で使いたいので、左辺を jQuery にしてあります。とても簡単ですが、ちょっと拡張性が低く、メンテナンスはしづらいパターンです。

userAgent を使った拡張性の高いもの

これはとても応用が利き、最も読みやすくて理解しやすくてメンテナンスが楽なものです。

Detecting Mobile Devices with JavaScript
( このリンク先のものを少し改造しています )
<script>
jQuery.isMobile = {
    Android: function() {
        return navigator.userAgent.match(/Android/i) == null ? false : true;
    },
    BlackBerry: function() {
        return navigator.userAgent.match(/BlackBerry/i) == null ? false : true;
    },
    iOS: function() {
        return navigator.userAgent.match(/iPhone|iPad|iPod/i) == null ? false : true;
    },
    Opera: function() {
        return navigator.userAgent.match(/Opera Mini/i) == null ? false : true;
    },
    Windows: function() {
        return navigator.userAgent.match(/IEMobile/i) == null ? false : true;
    },
    any: function() {
        return (jQuery.isMobile.Android() || jQuery.isMobile.BlackBerry() || jQuery.isMobile.iOS() || jQuery.isMobile.Opera() || jQuery.isMobile.Windows());
    }
};

console.log($.isMobile.any())
</script>

CSS レスポンシブに同期するもの

個別にデバイス一覧をメンテするよりも、元々の画面の状況でチェックするようになっています。CSS を使うので、判定用の BR 要素を一つ画面の最終に置くという前提でのサンプルです。
<style>
@media screen and (max-width:479px) {
  #lastbr { display: none; }
}
</style>

<script>
$( function() {      
    jQuery.isMobile = false;
    if( $('#lastbr').css('display')=='none') {
        jQuery.isMobile = true;       
    }


 });

</script>


<br id="lastbr">

PHP 側で判定したものを使う

あと、PHP のライブラリで判定したものを埋め込むという手も、開発環境によっては一番有効であろうと思われるものもあります。
<script>
//set defaults
var device_type = 'desktop';
</script>

<?php
require_once( 'Mobile_Detect.php');
$detect = new Mobile_Detect();
?>

<script>
device_type="<?php echo ($detect->isMobile() ? ($detect->isTablet() ? 'tablet' : 'mobile') : 'desktop'); ?>";
alert( device_type);
</script>

userAgent を使うと、Chrome でテストしやすい

厳密に判定してしまうと、その環境でしかテストできなくなるので、あまりお勧めではありません。例で言うと、スマホデバイスでしか判定できないタッチイベントの有無で判定しているものもありました。
function isMobile() {
  try{ document.createEvent("TouchEvent"); return true; }
  catch(e){ return false; }
}

それに、これだと将来的には常に true になってしまう可能性があります。



posted by lightbox at 2016-09-30 13:24 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2016年09月09日


jQuery と FileReader オブジェクトによる、ローカルの複数画像ファイルのプレビュー表示

INPUT 要素の type="file" 属性に加えて multiple 属性を追加する事によって、ローカルのファイルを複数選択が可能になります。

ここでは、画像表示を前提としていますが、ファイルの種類を accept 属性によって指定が可能です。指定方法もいろいろあるので、コンボボックスで選択可能にしました。
(ファイルを選択するダイアログで、accept 属性に指定したファイルグループが作成されて選択された状態になります)

ファイル選択後の処理の流れ

ファイルを選択後、INPUT 要素のオブジェクトの files プロパティに複数のファイルの情報がセットされるので、その配列に対して for ループ処理を作成します。

一回のループ毎に FileReader オブジェクトを作成して、それに対するイベントを登録します。そして、その FileReader オブジェクトに readAsDataURL で、INPUT 要素が保持する各ファイルの blob オブジェクトをセットします。

そうすると、イベントが実行されて、jQuery の appendTo メソッドによって、それぞれの画像用の img 要素が作成されて行きます。

イベント内でオリジナルファイル名を参照する

FileReader オブジェクトに name プロパティとして this.files[i].name をセットしておくと、後から this で参照が可能になります( ここでは title 属性にセットしました )

<script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script>
$(function(){
	$("#myfile").on("change", function(){

		$("#images").html("");
		for( i = 0; i < this.files.length; i++ ) {

			// FileReader は毎回作成(同時に複数のファイルを扱えない)
			var reader = new FileReader();
			// オリジナルファイル名をプロパティとして追加しておく
			reader.name = this.files[i].name;

			// FileReader に画像が読み込まれた時のイベント
			$(reader).on("load", function () {
				// div の中に img 要素を追加してその都度 this.result(ArrayBuffer) をセット
				$("<img>").appendTo("#images")
				.prop( {"src": this.result, "title": this.name } )	// title にはオリジナルファイル名
				.css("width", "100px");
			});

			// 上記イベントを発動するための処理( this.files[i] は blob )
			if (this.files[i]) {
				reader.readAsDataURL(this.files[i]);
			}
		}

	});

	// ファイルの種類の選択
	$("#accept").on("change", function(){
		$("#myfile").prop("accept", $(this).val() );
	});
});

</script>
<select id="accept">
<option value="image/jpeg">MIME 指定 image/jpeg</option>
<option value="text/plain">MIME 指定 text/plain</option>
<option value=".txt,.jpg,.png,.zip">拡張子指定 .txt,.jpg,.png,.zip</option>
<option value="image/*">画像全て image/*</option>
<option value="video/*">動画全て video/*</option>
<option value="audio/*">音声全て audio/*</option>
</select>
<br>
<input type="file" id="myfile" multiple accept="image/jpeg">
<div id="images"></div>



デモ実行



タグ:jquery FileReader
posted by lightbox at 2016-09-09 17:18 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする

2016年07月02日


jQuery で NAVER の インセンティブレポートページの日付の行数をカウントする

昨今たいていの WEB ページには、jQuery が使用されている為、各ブラウザのデベロッパーツールで容易に【行の数】をカウントする事ができます。

以下では、Google Chrome を使用しています。

対象ページ開く

そのページの対象部分の HTML を読む必要があるので、まずは、F12 でデベロッパーツールを開きます。但し、ここで注意するべきは、WEB ページは複数のウインドウで成り立っている場合があるので、自分が知りたい表示部分に対して、デベロッパーツールを開く必要があります。その為には、F12 で開いた後、インスペクタで、対象部分をクリックしてからコンソールに移動します。



このサンプルでは、IFRAME 内が対象なので、選択の必要があります。しかし、たいていは、top で問題は無いと思います。

構造を確認して jQuery を実行

jQuery が無い場合は、コンソールコマンドの $$(セレクタ)を使う方法がありますが、複雑な検索する場合は、ブックマークレットで jQuery を埋め込むか、コンソールで jQuery で埋め込んでから実行したほうがいいでしょう。



$("table").eq(1).find("tbody tr").length
ちなみに、Seesaa ブログの カテゴリ数のカウントは、http://blog.seesaa.jp/cms/category/edit/list を開いて、$(".entrytable .wordlimit").length です。 それと、そのページに jQuery が無い場合、以下のコードをコンソールで実行すれば、jQuery が読み込めると思います
var _x = document.createElement("script");
_x.setAttribute("src","//ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js");
document.body.appendChild(_x);




posted by lightbox at 2016-07-02 13:41 | Comment(0) | jQuery | このブログの読者になる | 更新情報をチェックする
Seesaa の各ページの表示について
Seesaa の 記事がたまに全く表示されない場合があります。その場合は、設定> 詳細設定> ブログ設定 で 最新の情報に更新の『実行ボタン』で記事やアーカイブが最新にビルドされます。

Seesaa のページで、アーカイブとタグページは要注意です。タグページはコンテンツが全く無い状態になりますし、アーカイブページも歯抜けページはコンテンツが存在しないのにページが表示されてしまいます。

また、カテゴリページもそういう意味では完全ではありません。『カテゴリID-番号』というフォーマットで表示されるページですが、実際存在するより大きな番号でも表示されてしまいます。

※ インデックスページのみ、実際の記事数を超えたページを指定しても最後のページが表示されるようです

対処としては、このようなヘルプ的な情報を固定でページの最後に表示するようにするといいでしょう。具体的には、メインの記事コンテンツの下に『自由形式』を追加し、アーカイブとカテゴリページでのみ表示するように設定し、コンテンツを用意するといいと思います。


※ エキスパートモードで表示しています

アーカイブとカテゴリページはこのように簡単に設定できますが、タグページは HTML 設定を直接変更して、以下の『タグページでのみ表示される内容』の記述方法で設定する必要があります

<% if:page_name eq 'archive' -%>
アーカイブページでのみ表示される内容
<% /if %>

<% if:page_name eq 'category' -%>
カテゴリページでのみ表示される内容
<% /if %>

<% if:page_name eq 'tag' -%>
タグページでのみ表示される内容
<% /if %>
この記述は、以下の場所で使用します
container 終わり

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

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