FC2ブログ
スポンサーサイト
上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
【--/--/-- --:--】 | スポンサー広告 | page top↑
第1回:【Ext JSを使ってみよう。】(きっと続かない)
今回は早い更新です。
そして、前回に引き続き技術的な話。
つまりネタがないのです⊂⌒~⊃。Д。)⊃

第1回:【Ext JSを使ってみよう。】

前回もお話しましたが、Extを使うととてもアクティブな画面が作れます。
ライセンスの問題などもありますが、商業ベースで導入しても問題ないレベルです。
ただ、Javascriptガリガリなので、マシンパワーがかなり必要です(^^;

どれだけのページが作れるのか。
それはもうサンプルを見るのが早いでしょう。
と言うわけで、以下のソースをコピーしてhtmlファイルを作成してください。
保存する時はutf-8で保存してください。
また、一部表示領域の関係で無理に改行しているところがあるのはご勘弁を(^^;

今回のソースは長いです。
htmlファイルの中にJavascriptもhtmlも全部含んでますので(^^;
あ、ソースが長いので注意書き。
ソースの下に設定事項がまだあるので、ページを見ましょうまでは読んでください。

☆----------☆----------☆----------☆----------☆----------☆

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="keywords"content="ラグナロク">
<title>テストページ</title>
<link rel="stylesheet" type="text/css"
href="ext-2.0.2/resources/css/ext-all.css" />
<script type="text/javascript"
src="ext-2.0.2/adapter/ext/ext-base.js"></script>
<script type="text/javascript"
src="ext-2.0.2/ext-all.js"></script>
<script type="text/javascript"
src="ext-2.0.2/source/locale/ext-lang-ja.js"></script>
</head>
<body id="test_body">

<table>
<tr>
<td style="vertical-align:top;">
<div id="render_input_field_panel"></div>
<div id="content_input_field_panel">
<table>
<tr>
<td>
<table width=100%>
<tr>
<td>
&nbsp;
</td>
<td align="right" width=1%>
<div id="render_add_btn"></div>
</td>
<td align="right" width=1%>
<div id="render_clear_btn"></div>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>
ID:
</td>
<td>
<div id="render_user_id"></div>
</td>
</tr>
<tr>
<td>
ギルド:
</td>
<td>
<div id="render_affiliation_guild"></div>
</td>
</tr>
<tr>
<td>
名称:
</td>
<td>
<div id="render_user_name"></div>
</td>
</tr>
<tr>
<td>
備考:
</td>
<td>
<div id="render_remarks"></div>
</td>
</tr>
</table>
</td>
</tr>
</table>
</div>
</td>
<td>
<div id="render_member_view"></div>
</td>
</tr>
</table>

<style type="text/css">
#loading-mask{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
z-index:20000;
background-color:white;
}
</style>

<script type="text/javascript">

// コンボボックスのソース
var guildData = '{src:[{key:"",value:" "},{key:"0",value:"AAA"},{key:"1",value:"BBB"}]}';

/**
* 初期処理
*
* @param
* @return
* @author
* karin
*/
Ext.onReady(function(){
// 入力エリアパネルを作成
new Ext.Panel({
id:'id_input_field_panel',
title:'メンバー情報入力',
height:200,
width:350,
autoScroll:true,
renderTo:'render_input_field_panel',
contentEl:'content_input_field_panel'
});
// ID入力フィールドを作成
new Ext.form.NumberField({
id : 'id_user_id',
renderTo : 'render_user_id',
maxLength : 10,
name : 'user_id',
allowBlank : false,
blankText : 'ID は必須入力です。',
maxLengthText : 'ID は 10 桁以内で入力してください。',
allowDecimals : false,
allowNegative : false
});
// ギルド選択コンボを作成
var guildCmb = new Ext.form.ComboBox({
id : 'id_affiliation_guild',
renderTo : 'render_affiliation_guild',
name : 'affiliation_guild',
mode : 'local',
editable : false,
valueField : 'guildId',
displayField : 'guildName',
triggerAction : 'all',
store : new Ext.data.SimpleStore({
fields : ['guildId','guildName']
})
});
var srcGuild = guildData;
var objGuild = eval('(' + srcGuild + ')');
var guildArray = new Array();
for (var i = 0; i < objGuild.src.length; i++) {
var guildUnit = new Array();
guildUnit.push(objGuild.src[i].key);
guildUnit.push(objGuild.src[i].value);
guildArray.push(guildUnit);
}
guildCmb.store.loadData(guildArray);
guildCmb.setValue('');
// 名称入力フィールドを作成
var userName = new Ext.form.TextField({
id : 'id_user_name',
renderTo : 'render_user_name',
maxLength : 20,
name : 'user_name',
allowBlank : false,
blankText : '名称 は必須入力です。',
maxLengthText : '名称 は 20 文字以内で入力してください。'
});
// 備考入力フィールドを作成
var remarks = new Ext.form.TextArea({
id : 'id_remarks',
renderTo : 'render_remarks',
name : 'remarks',
maxLength : 1000,
maxLengthText : '備考 は 1,000 文字以内で入力してください。',
width : 280,
height : 40
});
// 追加ボタン
var addBtn = new Ext.Button({
id : 'id_add_btn',
renderTo : 'render_add_btn',
name : 'add_btn',
type : 'button',
text : '追加',
disabled : false
});
addBtn.on('click', function () {
onMemberAdd();
});
// クリアボタン
var clearBtn = new Ext.Button({
id : 'id_clearBtn',
renderTo : 'render_clear_btn',
name : 'clear_btn',
type : 'button',
text : 'クリア',
disabled : false
});
clearBtn.on('click', function () {
onInputClear();
});
// グリッドを作成
var rowSelect = new Ext.grid.CheckboxSelectionModel({
singleSelect : null
});
new Ext.grid.EditorGridPanel({
id : 'id_member_view',
renderTo : 'render_member_view',
name : 'member_view',
height : 200,
width : 550,
autoScroll : true,
enableDragDrop : false,
trackMouseOver : true,
stripeRows : true,
loadMask : true,
title : 'メンバー一覧',
store : new Ext.data.SimpleStore({
fields : [
'grid_id',
'grid_guild',
'grid_name',
'grid_remarks'
]
}),
sm : rowSelect,
tbar : [
{text : '選択', handler : function () {
onMemberModify();
}},
'-',
{text : '削除', handler : function () {
onMemberDelete();
}}
],
columns : [
rowSelect
,{ id : 'id_grid_id',
header : 'ID',
dataIndex : 'grid_id',
sortable : true,
align : 'left',
width : 50
},{ id : 'id_grid_guild',
header : 'ギルド',
dataIndex : 'grid_guild',
sortable : true,
align : 'left',
width : 100
},{ id : 'id_grid_name',
header : '名称',
dataIndex : 'grid_name',
sortable : true,
align : 'left',
width : 150
},{ id : 'id_grid_remarks',
header : '備考',
dataIndex : 'grid_remarks',
sortable : true,
align : 'left',
width : 100
}
]
});
onInputClear();
});

/**
* グリッド追加処理
*
* @param
* @return
* @author
* karin
*/
function onMemberAdd() {
var returnMsg;
// 必須入力チェック
returnMsg = checkInputData();
if (0 != returnMsg.length) {
alertErrMsg(returnMsg);
return;
}
// 重複チェック
returnMsg = checkDuplicationData();
if (0 != returnMsg.length) {
alertErrMsg(returnMsg);
return;
}
// メッセージを編集
var infoMsg;
if (isModifyMode()) {
infoMsg = '編集内容を一覧に反映しますか?';
} else {
infoMsg = '入力したユーザを追加しますか?';
}
// 確認メッセージを表示
Ext.MessageBox.show({
title : '登録確認',
msg : infoMsg,
buttons : {ok : '続行',cancel : 'キャンセル'},
icon : Ext.MessageBox.QUESTION,
fn : function (button) {
if (button == 'ok') {
if (isModifyMode()) {
memberModifyToGrid();
} else {
memberAddToGrid();
}
// コントロールの制御
setModifyMode(false);
// 入力エリアをクリアする
onInputClear();
}
}
});
}

/**
* グリッド修正処理
*
* @param
* @return
* @author
* karin
*/
function onMemberModify() {
// 選択されているレコードを取得
var selecteds = Ext.getCmp('id_member_view').getSelectionModel().getSelections();
if (0 == selecteds.length) {
alertErrMsg('ユーザが選択されていません。');
return;
} else if (1 != selecteds.length) {
alertErrMsg('修正ユーザは1名に絞ってください。');
return;
}

// グリッドのデータを入力エリアに反映
Ext.getCmp('id_user_id').setValue(selecteds[0].get('grid_id'));
Ext.getCmp('id_affiliation_guild').setValue(
getGuildId(selecteds[0].get('grid_guild')));
Ext.getCmp('id_user_name').setValue(selecteds[0].get('grid_name'));
Ext.getCmp('id_remarks').setValue(selecteds[0].get('grid_remarks'));

// コントロールの制御
setModifyMode(true);
}

/**
* グリッド削除処理
*
* @param
* @return
* @author
* karin
*/
function onMemberDelete() {
// 選択されているレコードを取得
var selecteds = Ext.getCmp('id_member_view').getSelectionModel().getSelections();
// 選択データありの場合
if (0 < selecteds.length) {
// 一覧から削除
for (var i = 0; i < selecteds.length; i++) {
Ext.getCmp('id_member_view').getStore().remove(selecteds[i]);
}
}
}

/**
* 入力のクリア処理
*
* @param
* @return
* @author
* karin
*/
function onInputClear() {
if (!isModifyMode()) {
// ユーザIDは編集中でない場合だけ
Ext.getCmp('id_user_id').reset();
}
Ext.getCmp('id_affiliation_guild').reset();
Ext.getCmp('id_user_name').reset();
Ext.getCmp('id_remarks').reset();
}

/**
* 入力データをグリッドに追加
*
* @param
* @return
* @author
* karin
*/
function memberAddToGrid() {
// データの取得
var userId = Ext.getCmp('id_user_id').getValue();
var guildName = getGuildName(Ext.getCmp('id_affiliation_guild').getValue());
var userName = Ext.getCmp('id_user_name').getValue();
var remarks = Ext.getCmp('id_remarks').getValue();

// レコードの作成
var data = [
[ userId,
guildName,
userName,
remarks
]
];
// ストアの作成
var store = new Ext.data.SimpleStore({
fields : [
{name : 'grid_id'},
{name : 'grid_guild'},
{name : 'grid_name'},
{name : 'grid_remarks'}
]
});
// 追加データをストアにロード
store.loadData(data);
// 先頭レコードを取得
var rec = store.getAt(0);

// 取得したレコードを追加レコードとしてグリッドに追加
Ext.getCmp('id_member_view').store.add(rec);
}

/**
* 編集データをグリッドに反映
*
* @param
* @return
* @author
* karin
*/
function memberModifyToGrid() {
// データの取得
var userId = Ext.getCmp('id_user_id').getValue();
var guildName = getGuildName(Ext.getCmp('id_affiliation_guild').getValue());
var userName = Ext.getCmp('id_user_name').getValue();
var remarks = Ext.getCmp('id_remarks').getValue();

// 反映先Indexを取得
var updIdx = -1;
Ext.getCmp('id_member_view').store.each(function(targetObj){
if (userId == targetObj.get('grid_id')) {
updIdx = Ext.getCmp('id_member_view').getStore().indexOf(targetObj);
}
});
if (0 > updIdx) {
alertErrMsg('グリッドの更新に失敗しました。');
return;
}

// 編集をグリッドに反映させる
Ext.getCmp('id_member_view').getStore().getAt(updIdx).set('grid_id', userId);
Ext.getCmp('id_member_view').getStore().getAt(updIdx).set('grid_guild', guildName);
Ext.getCmp('id_member_view').getStore().getAt(updIdx).set('grid_name', userName);
Ext.getCmp('id_member_view').getStore().getAt(updIdx).set('grid_remarks', remarks);
}

/**
* 入力チェック
*
* @param
* @return
* エラー文字列
* @author
* karin
*/
function checkInputData() {
// ユーザID必須チェック
if (!Ext.getCmp('id_user_id').validate()) {
return 'ユーザIDが入力されていません。';
}
// 名称必須チェック
if (!Ext.getCmp('id_user_name').validate()) {
return '名称が入力されていません。';
}
return '';
}

/**
* 入力重複チェック
*
* @param
* @return
* エラー文字列
* @author
* karin
*/
function checkDuplicationData() {
var returnMsg = '';

// 編集中は重複チェックは不要
if (isModifyMode()) {
return returnMsg;
}

// IDによって重複チェック
var userId = Ext.getCmp('id_user_id').getValue();
Ext.getCmp('id_member_view').store.each(function(targetObj){
if (userId == targetObj.get('grid_id')) {
returnMsg = targetObj.get('grid_id') + ' は既に登録されています。';
}
});

return returnMsg;
}

/**
* モードによるコントロールの制御
*
* @param
* モードフラグ
* @return
* @author
* karin
*/
function setModifyMode(flg) {
if (flg) {
Ext.getCmp('id_user_id').setDisabled(true);
Ext.getCmp('id_add_btn').setText('変更');
var keys = Ext.getCmp('id_member_view').getTopToolbar().items.keys;
Ext.getCmp(keys[0]).setDisabled(true);
Ext.getCmp(keys[2]).setDisabled(true);
} else {
Ext.getCmp('id_user_id').setDisabled(false);
Ext.getCmp('id_add_btn').setText('追加');
var keys = Ext.getCmp('id_member_view').getTopToolbar().items.keys;
Ext.getCmp(keys[0]).setDisabled(false);
Ext.getCmp(keys[2]).setDisabled(false);
}
}

/**
* 編集中か否かを取得
*
* @param
* @return
* 編集中フラグ true:編集中 false:通常
* @author
* karin
*/
function isModifyMode() {
return Ext.getCmp('id_user_id').disabled;
}

/**
* エラーメッセージ表示
*
* @param
* 表示メッセージ
* @return
* @author
* karin
*/
function alertErrMsg(dspMsg) {
Ext.MessageBox.show({
title : 'エラー',
msg : dspMsg,
buttons : Ext.MessageBox.OK,
icon : Ext.MessageBox.ERROR
});
}

/**
* ギルド名からギルドIDを取得
*
* @param
* ギルド名
* @return
* ギルドID
* @author
* karin
*/
function getGuildId(guildName) {
var srcGuild = guildData;
var objGuild = eval('(' + srcGuild + ')');
for (var i = 0; i < objGuild.src.length; i++) {
if (guildName == objGuild.src[i].value) {
return objGuild.src[i].key;
}
}
return '';
}

/**
* ギルドIDからギルド名を取得
*
* @param
* ギルドID
* @return
* ギルド名
* @author
* karin
*/
function getGuildName(guildId) {
var srcGuild = guildData;
var objGuild = eval('(' + srcGuild + ')');
for (var i = 0; i < objGuild.src.length; i++) {
if (guildId == objGuild.src[i].key) {
return objGuild.src[i].value;
}
}
return '';
}

</script>
</body>
</html>


☆----------☆----------☆----------☆----------☆----------☆

次にExtをダウンロードして解凍してください。
ソースはここからDLできます。
次に6~13行目を解凍したExtに対してパスを通してください
現在(2008/09/25)の最新は2.2ですが、私は2.0.2を使用しています。
Extは下位互換が優れているので、たぶんそのまま動くと思います。
(軽くしか動作確認してません。)
これで準備は完了です。
早速ページを見てみましょう。

ソースの解説をします。
まず始めに。

あくまでサンプルなのでエラー処理とかめっちゃ甘いのは気にしないで!

次に、このサンプルは、入力フォームに入力した内容をグリッドに表示。
編集もできると言うものです。

ネットをめぐると、最初から固定表示でのグリッドやなんかはすぐに見つかります。
が、動的な操作はなかなか無いです。
色々調べつつここまでは作れるようになったって感じです。
詳しい人から見れば、「なんつー冗長なソース書いてんだよ」って感じかもしれませんが、これが今の私の精一杯です(^^;
個人的にグリッドやコンボへのデータのセットがもっと上手い方法があると思うんですが、これ以上は無理でしたorz
あと、C++出身なので、Javascript的なコーディングでないのは勘弁してください。

まぁ、これからExtを始める人や、調べまわってる人の参考にでもなればと思います。
あ、上に書いたように、私自身調べながらのコーディングだったので、これが正規の使い方なんて絶対に思わないでね!

ちなみに、バグってます⊂⌒~⊃。Д。)⊃
必須入力や、入力制限でIDと名前が赤くなるようにしてますが、ほんとはカーソルをあわせるとエラーメッセージが出るはずなのですが、でてくれないです(T T)

いつも気まぐれ、ゲームはどこに行った!?

今回もかりんぽの本職(プログラマー)を垣間見る内容でした(*゚∀゚)
スポンサーサイト

テーマ:雑記 - ジャンル:日記

【2008/09/26 00:23】 | 雑記 | トラックバック(0) | コメント(0) | page top↑
| ホーム | 次ページ
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。