SQLの窓

2016年10月18日


Firebase storage の画像をメモリに直接ダウンロードして ImageView に表示する / Android

Firebase の環境とプロジェクトの作成方法

9.6.1 を使用する場合
エミュレータ : SDK Manager で最新に更新
実機 : Google Play 開発者サービスを最新に更新

Firebase ドキュメント : メモリにダウンロードする
メモリへのダウンロードは、画像の大きさを考慮しておれば、他は特別な内容はありません。ストレージのルールは allow read; にしておいて、ログインなしでテストしています。 ※ 取得した Byte の配列から Bitmap の作成は BitmapFactory.decodeByteArray で行っています。 MainActivity
public class MainActivity extends AppCompatActivity {

	static long MAX_SIZE_BYTE = 1024 * 100;
	// ダウンロード用
	private FirebaseStorage storage;
	private StorageReference storageRef;
	private StorageReference imageRef;
	private ImageView imageView;
	private ProgressDialog progress;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

// ▼ テスト用のルール
//		service firebase.storage {
//			match /b/freebase-654b7.appspot.com/o {
//				match /{allPaths=**} {
//					allow read;
//					allow write: if true;
//				}
//			}
//		}

		// ダウンロードするファイル
		storage = FirebaseStorage.getInstance();
		storageRef = storage.getReferenceFromUrl("gs://freebase-654b7.appspot.com/");
		imageRef = storageRef.child("sworc2.png");

		// 表示する場所
		imageView = (ImageView) MainActivity.this.findViewById(R.id.imageView);

		// ダウンロード中のダイアログ
		progress = new ProgressDialog(MainActivity.this);

		// *************************************
		// 表示1 ( メモリに取得 : bytes[] )
		// *************************************
		Button byteButton = (Button) MainActivity.this.findViewById(R.id.byteButton);
		byteButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				// ダウンロード中の表示
				progress.setProgressStyle(ProgressDialog.STYLE_SPINNER);
				progress.setMessage("画像をダウンロードしています");
				progress.show();

				// ダウンロード
				imageRef.getBytes(MainActivity.MAX_SIZE_BYTE)
					.addOnSuccessListener(new OnSuccessListener<byte[]>() {
					@Override
					public void onSuccess(byte[] bytes) {
						Log.i("lightbox","データ取得に成功しました");
						Log.i("lightbox", String.format("%d",bytes.length));
						if (bytes != null) {
							Bitmap image = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
							imageView.setImageBitmap(image);
						}
						// ダウンロード中の表示解除
						progress.dismiss();
					}
				}).addOnFailureListener(new OnFailureListener() {
					@Override
					public void onFailure(@NonNull Exception e) {
						// *****************************************
						// ルールを allow read: if false; にすると失敗します
						// => User does not have permission to access this object.
						// ファイルが存在しない場合
						// => Object does not exist at location.
						// *****************************************
						Log.i("lightbox","データ取得に失敗しました");
						Log.i("lightbox",e.getMessage());
						e.printStackTrace();
						// ダウンロード中の表示解除
						progress.dismiss();
						// メッセージ表示
						Toast.makeText(MainActivity.this,"ダウンロードに失敗しました",Toast.LENGTH_LONG).show();
					}
				});

			}
		});

	}
}


build.gradle(Project)
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.2.1'
        classpath 'com.google.gms:google-services:3.0.0'
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}


build.gradle(Module: app)
apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "23.0.3"

    defaultConfig {
        applicationId "lightbox.sep.fire1"
        minSdkVersion 19
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:22.2.1'
    compile 'com.google.firebase:firebase-core:9.6.1'
    compile 'com.google.firebase:firebase-storage:9.6.1'
    compile 'com.google.firebase:firebase-auth:9.6.1'
}

apply plugin: 'com.google.gms.google-services'
※ AndroidManifest.xml には、android.permission.INTERNET を設定


posted by lightbox at 2016-10-18 14:35 | 2016 Android Studio | このブログの読者になる | 更新情報をチェックする

2016年10月17日


Android : Firebase の データを REST API の PUT コマンドで更新する

Firebase の環境とプロジェクトの作成方法

▼ 表示 / 更新用の Firebase URL
https://freebase-654b7.firebaseio.com/class.json
▼ 構成 インターネットデータの読み込みと メッセージボックスの処理は、tools.jar を使用しています。 Firebase における REST API どうも、単純読み出しと更新しか現時点(2016/10/17)では、あてにならないようです。少なくとも、以前のバージョンではソートができていたはずなのですが、現在正しく動きません。というか、そもそも現在の最新ドキュメントに何も書いてくれていません。なので、User Authentication もダメです。しばらくは放置しておいたほうが賢明だと思います。 JSON 文字列を引き渡す更新に関しては、PHP からも簡単に実装できます。Android からも特別な事は必要ありません。 Android : Firebase 用 HttpPut クラス ( URL を非公開にして、ルールを ".write" : true で使用するといいです ) Firebase API を使用すれば、REST API を使用せずとも、ソートや更新が簡単にできますが、他の API との互換性等を考えた場合、このような方法(REST API)も必要かと思います。 ListView と ViewSwitcher アクティビティは、取り回ししやすいように MainActivity のみです。ListView からの1件の表示は ViewSwitcher に設定した別画面(include)で行い、処理は専用の処理クラス(NextPage) を作成してそこで記述するようにしています。ここでは、new GsonBuilder().setPrettyPrinting().create() を使って、JSON 文字列を整形していますが、処理には Gson gson = new Gson() で十分です。 MainActivity REST API では、ソートができないので、ArrayList をソートして使用します。JSON 文字列の扱いは、Google Gson で行います。
public class MainActivity extends AppCompatActivity {

	public static int FIRST_PAGE = 0;
	public static int NEXT_PAGE = 1;
	private MyArrayAdapter adapter;
	private ListView listview;
	private ViewSwitcher vs;
	private NextPage nextPage;
	private Gson gson;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// 画面表示
		MainActivity.this.setContentView(R.layout.activity_main);

		// 複数画面処理
		vs = (ViewSwitcher) MainActivity.this.findViewById(R.id.viewSwitcher);
		// 次画面処理
		nextPage = new NextPage(MainActivity.this);
		// イベント登録
		nextPage.initAction();

		// アダプタを作成
		adapter = new MyArrayAdapter(MainActivity.this,R.layout.list_item);

		// リストビューの取得
		listview = (ListView) MainActivity.this.findViewById(R.id.listView);
		// リストビューの行をタップした時の処理
		listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

				// アダプターを取得
				MyArrayAdapter adapter = (MyArrayAdapter)parent.getAdapter();
				// 行データを取得
				JsonData json = (JsonData)adapter.getItem(position);

				String jsonString = gson.toJson(json,JsonData.class);
				Log.i("lightbox",jsonString);

				View include1 = MainActivity.this.findViewById(R.id.include1);

				TextView tv = (TextView) include1.findViewById(R.id.textKey);
				tv.setText(json.getCode());

				EditText et;
				et =  (EditText) include1.findViewById(R.id.editName);
				et.setText(json.getName());
				et =  (EditText) include1.findViewById(R.id.editFuri);
				et.setText(json.getFuri());

				nextPage.setJson(json);

				// 画面移動
				vs.setDisplayedChild(MainActivity.NEXT_PAGE);
			}
		});
		// リストビューにデータを表示
		listview.setAdapter(adapter);

		// JSON データの URL ( Firebase を使用 )
		String json_url = "https://freebase-654b7.firebaseio.com/class.json?print=pretty";
		// tools.jar の static メソッド
		Tools.callHttpGet(json_url, "utf-8", new Tools.OnAsyncTaskListener() {
			@Override
			public void onAsyncTaskListener(String s) {

				// JSON データをデシリアライズ
				gson = new GsonBuilder().setPrettyPrinting().create();
				Type myMap = new TypeToken<Map<String, JsonData>>(){}.getType();
				Map<String,JsonData> map = gson.fromJson(s, myMap);

				adapter.clear();
				// map.values() から ArrayList を作成
				ArrayList al = new ArrayList<JsonData>(map.values());
				// ソート
				Collections.sort(al, new Comparator<JsonData>() {
					public int compare(JsonData a, JsonData b) {
						String  name_a = a.getFuri();
						String  name_b = b.getFuri();

						return name_a.compareTo(name_b);
					}

				});
				// アダプターにセット
				adapter.addAll(al);

			}
		});

	}

}



NextPage
public class NextPage {

	private MainActivity mainActivity;
	private ViewSwitcher vs;
	private JsonData json;

	public NextPage(MainActivity mainActivity) {
		this.mainActivity = mainActivity;
	}

	public void setJson(JsonData json) {
		this.json = json;
	}

	public void initAction(){

		// 複数画面処理
		vs = (ViewSwitcher) mainActivity.findViewById(R.id.viewSwitcher);

		// activity_next.xml の 親 view です
		View include1 = mainActivity.findViewById(R.id.include1);

		// *****************************************
		// 戻るボタン
		// *****************************************
		Button backButton = (Button)include1.findViewById(R.id.backButton);
		backButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				// 最初の画面へ移動
				vs.setDisplayedChild(MainActivity.FIRST_PAGE);

			}

		});

		// *****************************************
		// 更新ボタン
		// *****************************************
		Button updateButton = (Button)include1.findViewById(R.id.updateButton);
		updateButton.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {

				Tools.messageBox(mainActivity, "更新確認", "更新しますか?", new Tools.OnMessageBoxListener() {
					@Override
					public void onMessageBoxYesListener() {
						updateData();
					}

					@Override
					public void onMessageBoxNoListener() {

					}
				});

			}

		});


	}

	private void updateData(){
		View include1 = mainActivity.findViewById(R.id.include1);

		EditText et;
		et =  (EditText) include1.findViewById(R.id.editName);
		json.setName(et.getText().toString());
		et =  (EditText) include1.findViewById(R.id.editFuri);
		json.setFuri(et.getText().toString());

		Gson gson = new GsonBuilder().setPrettyPrinting().create();
		String jsonString = gson.toJson(json,JsonData.class);
		String url = String.format("https://freebase-654b7.firebaseio.com/class/%s.json", json.getCode());

		new AsyncTask<String,Void,String>(){
			@Override
			protected String doInBackground(String... params) {
				String result = HttpPut.execute(params[0],params[1],"utf-8");
				Log.i("lightbox", result);
				return result;
			}

			@Override
			protected void onPostExecute(String s) {
				// 最初の画面へ移動
				vs.setDisplayedChild(MainActivity.FIRST_PAGE);
			}
		}.execute(url,jsonString);

	}
}


activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <ViewSwitcher
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/viewSwitcher">

        <ListView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:id="@+id/listView"/>

        <include
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            layout="@layout/activity_next"
            android:id="@+id/include1"/>

    </ViewSwitcher>

</LinearLayout>


MyArrayAdapter

オーソドックスな、ListView 用の 専用 ArrayAdapter です。
public class MyArrayAdapter extends ArrayAdapter<JsonData> {

	// JsonData を格納する、この処理専用の
	// ArrayAdapter のカスタマイズ

	// コンストラクタで渡された画面の保存
	private int mResource;

	public MyArrayAdapter(Context context, int resource) {
		super(context, resource);
		// ArrayAdapter でも、このようにして保存して利用してます
		mResource = resource;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {

		if (convertView == null) {
			// 現在の View の取得
			// getContext() で super で渡されたものを取得できます
			LayoutInflater inflater
				= (LayoutInflater) MyArrayAdapter.this.getContext().getSystemService
				(Context.LAYOUT_INFLATER_SERVICE);
			// super で渡されたものは取得できないので自前で用意します
			convertView = inflater.inflate(mResource, null);
		}

		// アダプターより行データを取得
		JsonData json = MyArrayAdapter.this.getItem(position);

		// 画面にデータをセット
		TextView tv;

		// キー
		tv = (TextView) convertView.findViewById(R.id.textKey);
		tv.setText(json.getCode());

		// Subject
		tv	= (TextView) convertView.findViewById(R.id.textItem1);
		tv.setText(json.getName());

		// Name
		tv = (TextView) convertView.findViewById(R.id.textItem2);
		tv.setText(json.getFuri());

		// 行の画面をシステムに返す
		return convertView;
	}

}


JsonData

Android Studio では、private の変数を作っておいて、ALT + Insert から Getter and Setter で一気に作成できます。toString() はここでは特に必要ありませんが、Android の単純リソースを使用するなら必要です。

空のコンストラクタも、新規用のコンストラクタもここでは使用しませんが、前者は Firebase API を使用する際には必要になります。後者も使用しませんが、ALT + Insert で簡単に作成できます。

※ kyuyo が int ではなく long なのも、Firebase API の都合です。
public class JsonData {

	private String code;
	private String name;
	private String furi;
	private String birthday;
	private String kanri;
	private long kyuyo;
	private String sex;
	private String syozoku;
	private String teate;

	public JsonData(){}

	public JsonData(String birthday, String code, String furi, String kanri, long kyuyo, String name, String sex, String syozoku, String teate) {
		this.birthday = birthday;
		this.code = code;
		this.furi = furi;
		this.kanri = kanri;
		this.kyuyo = kyuyo;
		this.name = name;
		this.sex = sex;
		this.syozoku = syozoku;
		this.teate = teate;
	}

	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

	public String getFuri() {
		return furi;
	}
	public void setFuri(String furi) {
		this.furi = furi;
	}

	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getKanri() {
		return kanri;
	}
	public void setKanri(String kanri) {
		this.kanri = kanri;
	}

	public long getKyuyo() {
		return kyuyo;
	}
	public void setKyuyo(long kyuyo) {
		this.kyuyo = kyuyo;
	}

	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

	public String getSyozoku() {
		return syozoku;
	}
	public void setSyozoku(String syozoku) {
		this.syozoku = syozoku;
	}

	public String getTeate() {
		return teate;
	}
	public void setTeate(String teate) {
		this.teate = teate;
	}

	@Override
	public String toString() {
		return this.name;
	}
}



posted by lightbox at 2016-10-17 21:37 | 2016 Android Studio | このブログの読者になる | 更新情報をチェックする

2016年10月10日


Android Studio で、ListView アプリケーションを作成するテンプレート

全てのソースコード



仕様の概略
1) MainActivity には ListView コントロールのみ
2) ListView 内に TextView は縦に2項目
3) NextActvity には、元へ戻るボタンと TextView が一つ
※ MyArrayAdapter を private で 一つのソースに記述しています。インターネットから JSON データを取得して ListView に表示します (https://lightbox.sakura.ne.jp/homepage/demo/data/csvtype/json.php) ➡ インターネットへのアクセスは、tools.jarTools.callHttpGet を使用します。 ➡ 読み出した JSON 文字列を Google Gson でデシリアライズして、JsonDataList にセットします。( リンク先には クラス定義があります ) このオブジェクトを ArrayAdapter<JsonData> を継承した MyArrayAdapter にセットし、ListView に MyArrayAdapter をセットして ListView を表示します。 ListView には、setOnItemClickListener で行をクリックしたイベントを定義し、その中で 行データを Intent にセットして次画面へ移動します。 次画面では、受け取った行データより、本文を取得して画面の TextView へ表示します。 MainActivity
public class MainActivity extends AppCompatActivity {

	private final int MY_REQUEST_CODE = 1000;
	private ListView listview;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		// リストビューの取得
		listview = (ListView) MainActivity.this.findViewById(R.id.listView);
		// リストビューの行をタップした時の処理
		listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

				// アダプターを取得
				MyArrayAdapter adapter = (MyArrayAdapter)parent.getAdapter();
				// 行データを取得
				JsonData json = (JsonData)adapter.getItem(position);

				// 引渡しデータを作成
				Intent intent = new Intent(MainActivity.this,NextActivity.class);
				intent.putExtra("DATA","こんにちは");
				// Serializable インターフェイスなのでまとめて渡す
				intent.putExtra("OBJECT",json);

				// 画面移動
				MainActivity.this.startActivityForResult(intent,MY_REQUEST_CODE);
			}
		});

		// JSON データの URL
		String json_url = "https://lightbox.sakura.ne.jp/homepage/demo/data/csvtype/json.php";
		// tools.jar の static メソッド
		Tools.callHttpGet(json_url, "utf-8", new Tools.OnAsyncTaskListener() {
			@Override
			public void onAsyncTaskListener(String s) {

				// JSON データをデシリアライズ
				Gson gson = new Gson();
				JsonDataList jdl = gson.fromJson(s, JsonDataList.class);

				// アダプタを作成して、データをセット
				MyArrayAdapter adapter
					= new MyArrayAdapter(MainActivity.this,R.layout.list_item);
				// jdl.item は配列
				adapter.addAll(jdl.item);

				// リストビューにデータを表示
				listview.setAdapter(adapter);

			}
		});
	}


	// ******************************
	// 次画面から戻って来た時の処理
	// ******************************
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		if ( requestCode == MY_REQUEST_CODE ) {
			// NextActivity の 戻るボタン以外で戻ると 0
			Log.i("lightbox",String.format("NextActivity からの戻り値 : %d", resultCode));
			if ( data != null ) {
				String message = data.getStringExtra("DATA");
				Log.i("lightbox",String.format("NextActivity からのメッセージ : %s", message));
			}
		}

	}

	// ******************************
	// JsonData を格納する、この処理専用の
	// ArrayAdapter のカスタマイズ
	// ******************************
	private class MyArrayAdapter extends ArrayAdapter<JsonData> {

		// コンストラクタで渡された画面の保存
		private int mResource;

		public MyArrayAdapter(Context context, int resource) {
			super(context, resource);
			// ArrayAdapter でも、このようにして保存して利用してます
			mResource = resource;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			if (convertView == null) {
				// 現在の View の取得
				LayoutInflater inflater = (LayoutInflater) MainActivity.this.getSystemService
					(Context.LAYOUT_INFLATER_SERVICE);
				convertView = inflater.inflate(mResource, null);
			}

			// アダプターより行データを取得
			JsonData json = MyArrayAdapter.this.getItem(position);

			// 画面にデータをセット
			TextView tv;

			// Subject
			tv	= (TextView) convertView.findViewById(R.id.textItem1);
			tv.setText(json.getSubject());

			// Name
			tv = (TextView) convertView.findViewById(R.id.textItem2);
			tv.setText(json.getName());

			// 行の画面をシステムに返す
			return convertView;
		}

	}

}

MainActivity での特記事項onItemClick 内での 行データの参照は、parent.getAdapter() によって、使用しているアダプターを取得します。
JsonData は、そのまま Intent にセットする為に Serializable インターフェイスを実装しています
JsonData へのデータのセットは、Google Gson 経由を想定しているので、setter および コンストラクタは定義していません
JsonData の getText 以外のメソッドはここでは使用しませんが、仕様の拡張を想定した最低限必要と判断したものです。特に、toString は、システムが用意した一つの項目しかない行を定義した画面で使う為に必要です(ここでは必要ありません)。
MyArrayAdapter で画面 id を内部保存しているのは、ArrayAdapter のソースコードに準じたものです


tools.jar は、ソースコードを簡略化する為のテスト用のライブラリです。本番には相応のコードを用意します。

NextActivity


public class NextActivity extends AppCompatActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_next);

		// 引き渡された Intent を取得
		Intent intent = NextActivity.this.getIntent();
		// 文字列のデータを取り出す
		String message = intent.getStringExtra("DATA");
		Log.i("lightbox",String.format("MainActivity からのメッセージ : %s", message));
		// Serializable オブジェクトを取り出す
		JsonData json = (JsonData) intent.getSerializableExtra("OBJECT");

		// 画面へデータをセット
		TextView tv = (TextView) NextActivity.this.findViewById(R.id.textView);
		// text データ上の 改行文字列を実際の改行に変換する
		String text = json.getText();
		text = text.replace("\\n", "\n");
		tv.setText(text);

		// MainActivity へ戻る為のボタン
		Button button = (Button) NextActivity.this.findViewById(R.id.backButton);
		button.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View view) {

				// 戻る時にも Intent を引き渡す
				Intent intent = new Intent();
				intent.putExtra("DATA", "今戻りました");
				// MainActivity で受け取る int データをセットする
				NextActivity.this.setResult(NextActivity.RESULT_OK,intent);
				// この画面を終了して MainActivity へ戻る
				NextActivity.this.finish();

			}
		});

	}
}

NextActivity での特記事項

Android Studio では、New => Activity で作成しており、AndroidManifest への定義は自動的に追加されます。


全てのソースコード


posted by lightbox at 2016-10-10 14:48 | Android Studio 2 | このブログの読者になる | 更新情報をチェックする

JavaScript : 入力文字列を 変数用16進数表現 に変換する

\u を使って、ソースコードに埋め込む文字列として、キャラクタセットに依存せずにコードを作成する為に使用します。( "あ" == "\u3042" )
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function htmlentities2() {
	var a = $("#do_encode").val();
	var w = "";
	var n = 0;
	var p;
	for( var i = 0; i < a.length; i++ ) {
		p = (a.charCodeAt(i)).toString(16);
		if ( p.length > 2 || a.substr( i, 1 ) == "\"" || a.substr( i, 1 ) == "'" ) {
			w += "\\u" + ("00"+p).substr(2+p.length-4,4);
		}
		else {
			w += a.substr( i, 1 );
		}
	}
	$("#result").text( w );
}
</script>
<input id="do_encode" type="text" size="60">
<br>
<input
	type="button"
	value="入力文字列を alert 用16進数表現 に変換"
	onclick='htmlentities2()'>
<pre id="result"></pre>

※ JavaScript外部ファイル を charset を使用せずに作成する為に htmlentitie と併用します。


関連する記事

JS : 入力文字列を htmlentitie に変換する


posted by lightbox at 2016-10-10 12:55 | JavaScript | このブログの読者になる | 更新情報をチェックする

JavaScript : 入力文字列を htmlentity に変換する

一文字づつプログラムで判断して、都合のいいように変換する方法です。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script>
function htmlentities() {
	var a = $("#do_encode").val();
	var w = "";
	for( var i = 0; i < a.length; i++ ) {
		if ( $("#check").prop("checked") ) {
			if ( a.substr(i,1) == '&' ) {
				w += "&amp;";
			}
			else if ( a.substr(i,1) == '<' ) {
				w += "&lt;";
			}
			else if ( a.substr(i,1) == '>' ) {
				w += "&gt;";
			}
			else if ( a.substr(i,1) == '"' ) {
				w += "&#" + a.charCodeAt(i) + ";";
			}
			else if ( a.substr(i,1) == "'" ) {
				w += "&#" + a.charCodeAt(i) + ";";
			}
			else {
				if ( $("#check_jp").prop("checked") ) {
					if ( a.charCodeAt(i) > 255 ) {
						w += "&#" + a.charCodeAt(i) + ";";
					}
					else {
						w += a.substr(i,1);
					}
				}
				else {
					w += a.substr(i,1);
				}
			}
		}
		else {
			w += "&#" + a.charCodeAt(i) + ";";
		}
	}
	$("#result").text( w );
}
</script>
<input id="do_encode" type="text" size="60">
<br>
<input
	type="button"
	value="入力文字列を htmlentitie に変換"
	onClick='htmlentities()'>
<br>
<label for="check">変換を必要最低限にする</label>
<input type="checkbox" id="check">
 / 
<label for="check_jp">但し、日本語は変換する</label>
<input type="checkbox" id="check_jp">
<br>
▼ 以下に表示されます
<pre id="result"></pre>
&# を使用して数字で文字列を表す方法に変換します

変換後の文字列は、ボタンの下に表示されます。選択してコピーして下さい。

この文字列は alert 内では、文字列の代替えとしては使用できません


/
▼ 以下に表示されます


関連する記事

JavaScript : 入力文字列を 変数用16進数表現 に変換する



posted by lightbox at 2016-10-10 12:41 | JavaScript | このブログの読者になる | 更新情報をチェックする

2016年10月09日


Lightbox2 ライブラリの今時の使い方

2015年の7月の中旬以降のバージョンでは、lightbox.js は、ページの最後で読み込むようになっていました(WEBアーカイブ調べ)
Include the Javascript at the bottom of your page before the closing </body> tag:
( 画像より後に読み込むといいようです。また css を読み込んでから js です ) バージョン v2.04 のころは、prototype.js と scriptaculous.js が使われていたのですが、2.6(2014/03/20) では、jQuery が使用されていました( バージョンは 1.10.2 ) です。 今時では jQuery は Google がホスティングしてくれるのでそれを使うのが簡単です。あと、Lightbox2 のファイルが lightbox.min.js と lightbox.css(又はlightbox.min.css) と 画像ファイルがいくつか必要になります。 ここでは、関係するファイルを一箇所にまとめるために、lightbox.css(又はlightbox.min.css) 内の画像のパスを変更しています( 例えばここでは url(../img/close.png) を url(close.png) にしています )
body:after {
  content: url(close.png) url(loading.gif) url(prev.png) url(next.png);
  display: none;
}
それらを使用して Lightbox2 を使う場合以下のようになります
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<link type="text/css" rel="stylesheet" href="https://lightbox.sakura.ne.jp/demo/lightbox2/lightbox2/lightbox.min.css">
<a href="http://goo.gl/nC01x4" data-lightbox="daz3d"><img src="http://goo.gl/AgJ1QU"></a>
<a href="http://goo.gl/ibgyRW" data-lightbox="daz3d"><img src="http://goo.gl/ulC3Hs"></a>

<script type="text/javascript" src="https://lightbox.sakura.ne.jp/demo/lightbox2/lightbox2/lightbox.min.js"></script>


この画像は、Picasa に登録してあるのでやたらと URL が長いので Google の URL 短縮機能を使って画像の URL を短くしています。

また、Lightbox の現在の最新仕様として data-lightbox 要素が使用されていますが、古くからの rel を使った方法も動作します。( rel="lightbox[group_string]" )

data-lightbox="daz3d"daz3d は、画像のグループで、表示後に直接画像間の表示を切り替える事ができるようになります。

※ 他のライブラリやCSSの影響で、Lightbox の実行時の背景を暗くできない場合がある場合は、そのページに以下の CSS を設定するといいと思います。
<style type="text/css">
#lightboxOverlay {
	opacity: 0.8!important;
}
</style> 

その他のオプション

リンク( アンカー要素 ) に title 属性を指定すると、その内容が画像の左下に表示されます。
2.7.1 では、data-title="タイトル文字列" が使用できます。


タイトルの中には、HTML の表現も可能ですが、以下のような記述に変換する必要があります。( 実際には、一部分でいいのですが、全て変換しています )

※ リンクを試したのですが、クリックしても動作しませんでした。
2.7.1 ではリンクも動作しました。
但し、アプリで操作しているからなのか、target="_blank" が動作しなかったのと、IFRAME 内ではリンクが動作しませんでした。
<a href="http://goo.gl/UUjQaE" data-lightbox="daz3d" data-title="&#9660;&#12522;&#12531;&#12463;&#12391;&#12377;&#12290;&#12463;&#12522;&#12483;&#12463;&#12391;&#12365;&#12414;&#12377;&#60;&#98;&#114;&#62;&#60;&#97;&#32;&#104;&#114;&#101;&#102;&#61;&#34;&#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#116;&#119;&#105;&#116;&#116;&#101;&#114;&#46;&#99;&#111;&#109;&#47;&#115;&#119;&#111;&#114;&#99;&#34;&#62;&#60;&#105;&#109;&#103;&#32;&#115;&#114;&#99;&#61;&#34;&#104;&#116;&#116;&#112;&#115;&#58;&#47;&#47;&#108;&#104;&#53;&#46;&#103;&#111;&#111;&#103;&#108;&#101;&#117;&#115;&#101;&#114;&#99;&#111;&#110;&#116;&#101;&#110;&#116;&#46;&#99;&#111;&#109;&#47;&#45;&#107;&#67;&#89;&#84;&#83;&#109;&#84;&#114;&#74;&#88;&#115;&#47;&#85;&#82;&#118;&#77;&#81;&#121;&#57;&#67;&#108;&#113;&#73;&#47;&#65;&#65;&#65;&#65;&#65;&#65;&#65;&#65;&#82;&#117;&#119;&#47;&#53;&#66;&#84;&#75;&#84;&#107;&#50;&#99;&#95;&#115;&#119;&#47;&#115;&#49;&#48;&#48;&#47;&#95;&#105;&#109;&#103;&#46;&#112;&#110;&#103;&#34;&#62;&#60;&#47;&#97;&#62;"><img src="http://goo.gl/9n0KCM"></a>
変換用の簡単なプログラム

▼ 以下に表示されます

関連する記事

JavaScript : 入力文字列を htmlentity に変換する



posted by lightbox at 2016-10-09 03:14 | JavaScript ライブラリ | このブログの読者になる | 更新情報をチェックする
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 ドロップシャドウの参考デモ
イラストAC
ぱくたそ
写真素材 足成
フリーフォント一覧
utf8 文字ツール
右サイド 終わり
base 終わり