JavaScriptでphpの変数が使えない?

以下のように書いたら、全くgoogle map apiが表示されず、

{
                    'address': <?php echo $address; ?>,
                    'region': 'jp'
                },

jsonにエンコードしたら表示されるようになりました。

{
                    'address': <?php echo json_encode($address); ?>,
                    'region': 'jp'
},

たったこれだけに1時間以上嵌ってしまいました。。

選択ファイルのjavascript側の表示数をsliceで制御

適当に数時間試していたら上手くいきました。
変数のlengthをcountして条件分岐で欲しい数だけsliceしてます。

<script>
  function handleFileSelect(evt){
    var files = evt.target.files;
    if(files.length > 2){
      files = files.slice(0, 2);
    }    

    for (var i = 0, f; f = files[i]; i++) {
    // for (var i = 0, f; f = files[i]; i++) {

      if (!f.type.match('image.*')) {
            continue;
          }

      var reader = new FileReader();

      reader.onload = (function(theFile){
        return function(e){
              var span = document.createElement('span');
              span.innerHTML = ['<img class="thumb" src="', e.target.result,
                                '" title="', escape(theFile.name), '"/>'].join('');
              document.getElementById('list').insertBefore(span, null);
            };
          })(f);

      reader.readAsDataURL(f);
    }

    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
    // for (var i = 0, f; f = files[i]; i++) {

      output.push('<li><strong>', escape(f.name), '</strong> (', f.type || 'n/a', ') - ',
                  f.size, ' bytes, last modified: ',
                  f.lastModifiedDate.toLocaleDateString(), '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

OK! Nice!

さて、問題は、送信ファイルをどうやって保存するかですね。
gmailやhotmailなどは、ファイル名は変わらずに送られてくるので、拡張子にバリデーションをかけて、ファイル名はそのままにしたいと思います。

ファイルアップロードの進捗(%)をjavascriptで表示

コードでは一番下に来ていますが、addEventListenerで、getElementById(‘files’).addEventListener(‘change’, handleFileSelect, false)として、handleFileSelectの関数を実行します。
handleFileSelectでは、new FileReader();とした後、errorHandlerとupdateProgressを実行します。
%は、Math.round((evt.loaded / evt.total) * 100);

<style>
#progress_bar {
	margin: 10px 0;
	padding: 3px;
	border: 1px solid #000;
	font-size: 14px;
	clear: both;
	opacity: 0;
	-moz-transition: opacity ls linear;
	-o-transition: opacity ls linear;
	-webkit-transition: opacity ls linear;
}
#progress_bar.loading {
	opacity: 1.0;
}
#progress_bar .percent {
	background-color: #99ccff;
	height: auto;
	width: 0;
}
</style>

<input type="file" id="files" name="file" />
<button onclick="abortRead();">Cancel read</button>
<div id="progress_bar"><div class="percent">0%</div></div>

<script>
	var reader;
	var progress = document.querySelector('.percent');

	function abortRead(){
		reader.abort();
	}

	function errorHandler(evt){
		switch(evt.target.error.code){
			case evt.target.error.NOT_FOUND_ERR:
				alert('File Not Found!');
				break;
			case evt.target.error.NOT_READABLE_ERR:
				alert('File is not readable');
				break;
			case evt.target.error.ABORT_ERR:
				break;
			default:
				alert('An error occurred reading this file.');
		};
	}

	function updateProgress(evt) {
    if (evt.lengthComputable) {
      var percentLoaded = Math.round((evt.loaded / evt.total) * 100);
      if (percentLoaded < 100) {
        progress.style.width = percentLoaded + '%';
        progress.textContent = percentLoaded + '%';
      }
    }
  }


		function handleFileSelect(evt) {
	    progress.style.width = '0%';
	    progress.textContent = '0%';

	    reader = new FileReader();
	    reader.onerror = errorHandler;
	    reader.onprogress = updateProgress;
	    reader.onabort = function(e) {
	      alert('File read cancelled');
	    };
	    reader.onloadstart = function(e) {
	      document.getElementById('progress_bar').className = 'loading';
	    };
	    reader.onload = function(e) {
	      progress.style.width = '100%';
	      progress.textContent = '100%';
	      setTimeout("document.getElementById('progress_bar').className='';", 2000);
	    }

		reader.readAsBinaryString(evt.target.files&#91;0&#93;);
	}
	document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

容量が小さいと、直ぐに100%となるので、最近downloadして重かったJavaの”spring-tool-suite-3.9.2.RELEASE-e4.7.2-win32-x86_64.zip”で試してみます。

いや、参りました。って感じですかね。参ってばっかりですが。。

FileReader()

FileReader クラスは、HTML5 世代の機能

File APIで出来ること
-ローカルにある画像をアップロードする前にプレビューを表示する
-ローカルにある画像をブラウザで加工してダウンロードする
-テキストファイルをブラウザで解析する
-データをJSONファイルとしてエクスポートして、インポートする
-大きなファイルを分割してサーバーに送信する

特に、「ローカルにある画像をアップロードする前にプレビューを表示する」ですね。

readAsDataURL メソッドは、指定された Blob ないし File オブジェクトを読み込むために使用
reader.readAsDataURL(file);
escape():16 進数エスケープシーケンスに置換
insertBefore:指定のノードを現在のノードの子ノードとして参照要素の前に挿入

inputで選択した複数画像をブラウザ上で表示させる

<style>
.thumb {
	height: 100px;
	width: 100px;
	border: 1px solid #000;
	margin: 10px 5px 0 0;
}
</style>

<input type="file" id="files" name="files&#91;&#93;" multiple /><br>
<output id="list"></output>
<script>
	function handleFileSelect(evt){
		var files = evt.target.files;

		for (var i = 0, f; f = files[i]; i++) {

			if (!f.type.match('image.*')) {
		        continue;
		      }

			var reader = new FileReader();

			reader.onload = (function(theFile){
				return function(e){
							var span = document.createElement('span');
		          span.innerHTML = ['<img class="thumb" src="', e.target.result,
		                            '" title="', escape(theFile.name), '"/>'].join('');
		          document.getElementById('list').insertBefore(span, null);
		        };
		      })(f);

			reader.readAsDataURL(f);
		}
	}

	document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

初期

画像を選択

選択後
なんだこりゃーー!!すげー

では繋げてみましょう。

<?php
	  for ($i=0; $i<count($_FILES&#91;'files'&#93;&#91;'name'&#93;); $i++) {
    $file_ext = pathinfo($_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;, PATHINFO_EXTENSION);
    if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;)) {
      if(move_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;, "upload/img/".$_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;)) {
          echo $_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93; . "をアップロードしました。<br>";
      } else {
        echo "ファイルをアップロードできません。<br>";
      }
    } else {
      echo "ファイルが選択されていません。<br>";
    }
  }
  //アップロードできるファイルに拡張子の制限をかけたい時
  function FileExtensionGetAllowUpload($ext){
    $allow_ext = array("gif","jpg","jpeg","png","eps");
    foreach($allow_ext as $v){
      if ($v === $ext){
        return 1;
      }
    }
    return 0;
  }

?>
<style>
.thumb {
  height: 100px;
  width: 100px;
  border: 1px solid #000;
  margin: 10px 5px 0 0;
}
</style>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files&#91;&#93;" multiple />
<input type="submit" value="Send">
</form>
<output id="list"></output>
<script>
  function handleFileSelect(evt){
    var files = evt.target.files;

    for (var i = 0, f; f = files[i]; i++) {

      if (!f.type.match('image.*')) {
            continue;
          }

      var reader = new FileReader();

      reader.onload = (function(theFile){
        return function(e){
              var span = document.createElement('span');
              span.innerHTML = ['<img class="thumb" src="', e.target.result,
                                '" title="', escape(theFile.name), '"/>'].join('');
              document.getElementById('list').insertBefore(span, null);
            };
          })(f);

      reader.readAsDataURL(f);
    }

    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
      output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
        f.size, ' bytes, last modified: ',
        f.lastModifiedDate.toLocaleDateString(), '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

ほお

php側にもちゃんと渡されています。

ファイルをdrag & drop

<style>
#drop_zone {
	height:100px;
	width:400px;
	background-color:#EEEEEE;
	display: flex;
	align-items: center;
	justify-content: center;
	color:white;

}
</style>
Drop files here
<div id="drop_zone">ここに添付ファイルをドロップ</div>
<output id="list"></output>

<script>
function handleFileSelect(evt){
	evt.stopPropagation();
	evt.preventDefault();

	var files = evt.dataTransfer.files;

	var output = [];
	for (var i = 0, f; f = files[i]; i++) {
		output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
			f.size, ' bytes, last modified: ',
			f.lastModifiedDate.toLocaleDateString(), '</li>');
	}
	document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
}

	function handleDragOver(evt){
		evt.stopPropagation();
		evt.preventDefault();
		evt.dataTransfer.dropEffect = 'copy';
	}

	var dropZone = document.getElementById('drop_zone');
	dropZone.addEventListener('dragover', handleDragOver, false);
	dropZone.addEventListener('drop', handleFileSelect, false);
</script>

あ、これマジ凄い

preventDefault() は、その要素のイベントをキャンセルし、stopPropagation()は、親要素への伝播をキャンセル

dataTransfer:ドラッグを開始した時に、DataTransfer オブジェクトを取得する
addEventListener(‘dragover’,”,false)ドロップ領域に入っている間連続して発生
addEventListener(‘drop’,”,false)ドロップされた時に発生

jsで複数添付ファイルのtype, size, lastModifiedDateを表示する

var file = event.target.files[0]; で、ファイルオブジェクトを取り出す。

<input type="file" id="files" name="files&#91;&#93;" multiple />
<output id="list"></output>

<script>
	function handleFileSelect(evt){
		var files = evt.target.files;

		var output = [];
		for (var i = 0, f; f = files[i]; i++) {
			output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
				f.size, ' bytes, last modified: ',
				f.lastModifiedDate.toLocaleDateString(), '</li>');
		}
		document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
	}

	document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

jsで複数の初期化式

<script>
document.write("<p>");

for(var i = 1, j=10; i < 10; i++, j++){
	document.write("i = " + i + ", j = " + j + "<br>");
}

document.write("</p>");
</script>

toLocaleDateString()
->日付のみ抽出

<script>
var date = new Date();

document.write(date.toLocaleDateString());
</script>

addEventListener
イベント追加

<form>
<input type="button" id="ev" value="button" onclick="func1()">
</form>
<script>
function func1(){ alert("関数1が呼び出されました");}
var obj = document.getElementById("ev");

obj.addEventListener("click", func2, false);
function func2(){ alert("関数2が呼び出されました");}

obj.addEventListener("click", function(){
	alert("関数3が呼び出されました")
}, false);
</script>

つなげると、

<?php
	  for ($i=0; $i<count($_FILES&#91;'files'&#93;&#91;'name'&#93;); $i++) {
    $file_ext = pathinfo($_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;, PATHINFO_EXTENSION);
    if (/*FileExtensionGetAllowUpload($file_ext) && */ is_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;)) {
      if(move_uploaded_file($_FILES&#91;"files"&#93;&#91;"tmp_name"&#93;&#91;$i&#93;, "upload/img/".$_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93;)) {
          echo $_FILES&#91;"files"&#93;&#91;"name"&#93;&#91;$i&#93; . "をアップロードしました。<br>";
      } else {
        echo "ファイルをアップロードできません。<br>";
      }
    } else {
      echo "ファイルが選択されていません。<br>";
    }
  }
  //アップロードできるファイルに拡張子の制限をかけたい時
  function FileExtensionGetAllowUpload($ext){
    $allow_ext = array("gif","jpg","jpeg","png","eps");
    foreach($allow_ext as $v){
      if ($v === $ext){
        return 1;
      }
    }
    return 0;
  }

?>
<form action="#" method="post" enctype="multipart/form-data">
<input type="file" id="files" name="files&#91;&#93;" multiple />
<input type="submit" value="Send">
</form>
<output id="list"></output>

<script>
  function handleFileSelect(evt){
    var files = evt.target.files;

    var output = [];
    for (var i = 0, f; f = files[i]; i++) {
      output.push('<li><strong>', escape(f.name), '</strong>(', f.type || 'n/a', ') -',
        f.size, ' bytes, last modified: ',
        f.lastModifiedDate.toLocaleDateString(), '</li>');
    }
    document.getElementById('list').innerHTML = '<ul>' + output.join('') + '</ul>';
  }

  document.getElementById('files').addEventListener('change', handleFileSelect, false);
</script>

いいですね!

onChange()メソッド

onChangeとは、フォーム内のエレメント(要素)の内容が変更された時に起こるイベント処理

sample

<form name="link">
<select name="linkselect" onChange="confirm()">
<option value="">選択してください</option>
<option value="https://products.office.com/ja-jp/exchange/exchange-online">Microsoft Exchange Online</option>
<option value="https://willcloud.jp/">Will Mail</option>
<option value="http://www.cybersaas.jp/">CYBERMAIL Σ</option>
</select>
</form>
<script>
function confirm(){
	obj = document.link.linkselect;

	index = obj.selectedIndex;
	if(index != 0){
		href = obj.options[index].value;
		location.href = href;
	}
}
</script>

javascriptで北京の標準時間

<b>北京の標準時間</b>
<div id="time"></div>
<script type="text/javascript">
var diff = 1;
var value = diff + 15;
time();
function time(){
  var now = new Date(Date.now() - (value*60 - new Date().getTimezoneOffset())*60000);
  document.getElementById("time").innerHTML = now.toLocaleTimeString();
}
setInterval('time()', 1000);
</script>