Develop and Download Open Source Software

Browse Subversion Repository

Contents of /js/domain.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 34 - (show annotations) (download) (as text)
Mon Jan 18 04:50:55 2010 UTC (14 years, 4 months ago) by berupon
File MIME type: application/x-javascript
File size: 14918 byte(s)
ListBoxを左右二つ並べて項目の移動を行うインターフェースと処理をまとめてWidget化
1
2 // Copyright (c) 2009 Katsuhisa Yuasa <berupon [at] gmail.com>
3 // License http://www.opensource.org/licenses/mit-license.html
4
5 // このファイルにはシステム固有の処理を配置する。
6
7 if (!behaviourAssignors) {
8 var behaviourAssignors = {};
9 }
10
11 behaviourAssignors['number'] = function (elem) {
12 Event.observe(
13 elem,
14 'keypress',
15 // nonnegative_integers
16 function (event) {
17 var char = pressedChar(event);
18 var unmatched = (char && !char.match(/\d/));
19 cancelEvent(event, unmatched);
20 }
21 );
22 }
23
24 behaviourAssignors['integer'] = function (elem) {
25 Event.observe(
26 elem,
27 'keypress',
28 function (event) {
29 var char = pressedChar(event);
30 var unmatched = (char && !char.match(/[\-0-9]/));
31 cancelEvent(event, unmatched);
32 }
33 );
34 }
35
36 behaviourAssignors['word'] = function (elem) {
37 Event.observe(
38 elem,
39 'keypress',
40 function (event) {
41 var char = pressedChar(event);
42 var unmatched = (char && !char.match(/\w/));
43 cancelEvent(event, unmatched);
44 }
45 );
46 }
47
48 behaviourAssignors['date'] = function (elem) {
49 Event.observe(
50 elem,
51 'keypress',
52 function (event) {
53 var char = pressedChar(event);
54 var unmatched = (char && !char.match(/\d/) && char != '/');
55 cancelEvent(event, unmatched);
56 }
57 );
58 elem.maxLength = 10;
59 }
60
61 behaviourAssignors['slip_code'] = function (elem) {
62 Event.observe(
63 elem,
64 'keypress',
65 function(event) {
66 var char = pressedChar(event);
67 var unmatched = (char && !char.match(/[a-zA-Z0-9\-]/));
68 cancelEvent(event, unmatched);
69 }
70 );
71 }
72
73 behaviourAssignors['sales_code'] = function (elem) {
74 Event.observe(
75 elem,
76 'keypress',
77 function(event) {
78 var char = pressedChar(event);
79 var unmatched = (char && !char.match(/[a-zA-Z0-9]/));
80 cancelEvent(event, unmatched);
81 }
82 );
83 }
84
85 // CheckBoxの親要素をクリックしたらCheckBoxのクリックと同様の効果にする処理。
86 // behaviourAssignor は Formの要素にしか働かないので関数で用意。
87 function selectInnerCheckBox(e) {
88 var check = $A(Event.element(e).childNodes).filter(function(elem) { return elem.tagName == "INPUT" && elem.getAttribute("type") == "checkbox"; });
89 if (check.length) {
90 check[0].checked = !check[0].checked;
91 }
92 }
93
94 function setAutoFocus() {
95 var cnt = document.forms.length;
96 for (var i=0; i<cnt; ++i) {
97 var form = document.forms[i];
98 var cnt2 = form.elements.length;
99 for (var j=0; j<cnt2; ++j) {
100 var elem = form.elements[j];
101 if (elem.attributes.getNamedItem("autofocus")) {
102 if (document.activeElement == elem) {
103 return;
104 }
105 var e = elem;
106 do {
107 if (e.style) {
108 if (0
109 || (e.style.display && e.style.display == 'none')
110 || (e.style.visibility && e.style.visibility == 'hidden')
111 ) {
112 return;
113 }
114 }
115 }while (e = e.parentNode);
116 elem.focus();
117 elem.select();
118 return;
119 }
120 }
121 }
122 }
123
124 Event.observe(window, "load", setAutoFocus);
125
126 function toDateFormat(num) {
127 if (num.match(/\d{8,8}/)) {
128 var year = "00" + Math.floor(num / 10000);
129 var remain = num % 10000;
130 var month = "00" + Math.floor(remain / 100);
131 var day = "00" + remain % 100;
132 var ret = "" // damn Automatic Semicolon Insertion ;;
133 + year.substr(year.length-4, 4)
134 + "/"
135 + month.substr(month.length-2, 2)
136 + "/"
137 + day.substr(day.length-2, 2)
138 ;
139 return ret;
140 }else {
141 return num;
142 }
143 }
144
145 function clearForm(id) {
146 var form = Event.findElement(windowEvent()).form;
147 clearFormElementsValues(form, id);
148 }
149
150 Ajax.Responders.register({
151 onCreate: function() {
152 $("loading").appear({ duration: 0.1 });
153 },
154 onComplete: function() {
155 $("loading").fade({ duration: 0.5 });
156 }
157 });
158
159 // cookie中の指定した名前の値をObjectとして取り出し。JSON形式で格納されている事前提。
160 function digestCookie(key) {
161 var pieces = document.cookie.split('; ');
162 for (var i=0; i<pieces.length; ++i) {
163 var piece = pieces[i];
164 var pair = piece.split('=');
165 if (pair[0] == key) {
166 return unescape(pair[1]).evalJSON();
167 }
168 }
169 return {};
170 }
171
172 // cookieに指定した名前で値を保存。JSON形式で格納。
173 function dumpCookie(key, value) {
174 if (!Object.isString(value)) {
175 value = Object.toJSON(value);
176 }
177 var str = key + '=' + escape(value) + ";";
178 var d = new Date();
179 // future yet unknown XD
180 d.setYear(2012);
181 d.setMonth(12);
182 d.setDate(21);
183 str += "expires=" + d.toGMTString() + ";";
184 document.cookie = str;
185 }
186
187 // TODO: rename to DualSelect routines
188 function resetGridSetting(visibles, hiddens, cols) {
189 visibles.options.length = 0;
190 hiddens.options.length = 0;
191 for (var i=0; i<cols.length; ++i) {
192 var col = cols[i];
193 visibles.options[i] = new Option(col.text, col.value);
194 }
195 }
196
197 function setGridSetting(visibles, hiddens, defaultCols, cols) {
198 visibles.options.length = 0;
199 hiddens.options.length = 0;
200 for (var i=0; i<defaultCols.length; ++i) {
201 var col = defaultCols[i];
202 var found = false;
203 for (var j=0; j<cols.length; ++j) {
204 if (cols[j] == col.value) {
205 found = true;
206 break;
207 }
208 }
209 var el = found ? visibles : hiddens;
210 el.options[el.options.length] = new Option(col.text, col.value);
211 }
212 }
213
214 function getGridSetting(visibles) {
215 return collectMember(visibles.options, 'value');
216 }
217
218 syncLoad = (function() {
219
220 var cache = {};
221
222 return function (url, useCache) {
223 if (useCache && url in cache) {
224 return cache[url];
225 }
226
227 var ret = false;
228 new Ajax.Request(
229 url,
230 {
231 "method" : "get",
232 "parameters" : {},
233 "onSuccess": function(transport) {
234 ret = transport.responseText;
235 cache[url] = ret;
236 },
237 "onFailure": function () {
238 ret = false;
239 },
240 "asynchronous" : false
241 }
242 );
243 return ret;
244 }
245 })();
246
247 renderDoubleList = (function () {
248 var tmp = new EJS({url: 'js/doublelist.ejs'});
249 return function (lhs, rhs) {
250 var str = tmp.render(
251 {
252 'lhs' : lhs,
253 'rhs' : rhs
254 }
255 );
256 return str;
257 }
258 })();
259
260 var app = (function () {
261
262 /// private ///
263 Application = function () {
264
265 this.title = "SimpleLightWeb";
266 this.pageTitle = "";
267
268 // 擬似ページの読込時に呼び出すコールバック。
269 this.pageLoadHandler = null;
270
271 // 擬似ページの破棄時に呼び出すコールバック。戻り値が有る場合はcookieに保存
272 this.pageUnloadHandler = null;
273
274 // Modal PopUp 用の処理
275 this.showPopup = function () {
276 popup.show();
277 };
278
279 this.hidePopup = function () {
280 popup.hide();
281 };
282
283 this.setPopup = function (elem) {
284 popup.elem.appendChild(elem);
285 };
286
287 // 入力補助等のevent handlers設定
288 this.setHelpers = function () {
289 setAutoFocus();
290 draggable.attach();
291 ResizableColumns();
292 assignBehaviours();
293 };
294
295 this.getPathFromLocationHash = function () {
296 var url = location.hash;
297 return url.substr(1, url.length);
298 };
299
300 // prototype.js の String.toQueryParams は = で右辺に値を設定していないとパラメータとして拾ってくれないので自作。
301 this.getHashParams = function () {
302 var hash = this.getPathFromLocationHash();
303 var paraPos = hash.indexOf('?');
304 if (paraPos < 1) {
305 return {};
306 }else {
307 var paraStr = hash.substr(paraPos+1, hash.length);
308 var params = paraStr.split('&');
309 var ret = {};
310 for (var i=0; i<params.length; ++i) {
311 var para = params[i];
312 var pair = para.split('=');
313 for (var j=0; j<pair.length; ++j) {
314 pair[j] = decodeURIComponent(pair[j]);
315 }
316 if (pair.length == 1) {
317 ret[pair[0]] = null;
318 }else if (pair.length == 2) {
319 ret[pair[0]] = pair[1];
320 }
321 }
322 return ret;
323 }
324 }
325
326 // hash指定によるページ切り替え処理
327 // this routine understands relative path
328 this.moveLocation = function (path) {
329 var curHash = location.hash;
330 if (path.substr(0,1) == '/') {
331 location.hash = path.substr(1,path.length);
332 }else {
333 var upLevel = 0;
334 while (1) {
335 if (path.substr(0, 3) == '../') {
336 ++upLevel;
337 path = path.substr(3, path.length);
338 }else {
339 break;
340 }
341 }
342 var curPath = location.hash;
343 curPath = curPath.substr(1, curPath.length);
344 var parts = curPath.split('/');
345 parts = parts.slice(0, parts.length - (upLevel+1));
346 var newPath = parts.join('/');
347 if (newPath) {
348 newPath += '/';
349 }
350 newPath += path;
351 location.hash = newPath;
352 }
353 };
354
355 this.ajaxRequest = function (url, method, parameters, onSuccess, onFailure) {
356 ajaxRequest(url, method, parameters, onSuccess, onFailure);
357 };
358
359 // postによるデータ登録処理。エラー時にメッセージ表示を行うElementを用意する事。
360 var okToPost = true;
361 this.postRequest = function (params, newLocation) {
362 if (!okToPost) {
363 alert("ただいま結果待ちな為送信出来ません。");
364 return;
365 }
366 if (params instanceof HTMLFormElement) {
367 params = Form.serialize(params, true);
368 }
369 // alert(Object.toJSON(params));
370 this.ajaxRequest(
371 null,
372 'post',
373 params,
374 function(transport) {
375 var ret = transport.responseJSON;
376 if (!ret)
377 {
378 alert(transport.responseText);
379 }
380 if (ret.errors.length) {
381 $("messages").innerHTML = ret.errors.join("<BR>");
382 $("error").appear({ duration: 0.6 });
383 }else {
384 if (Object.isFunction(newLocation)) {
385 newLocation(ret);
386 }else {
387 if (newLocation == undefined) {
388 newLocation = "list";
389 }
390 this.moveLocation(newLocation);
391 }
392 }
393 okToPost = true;
394 }.bind(this),
395 function () {
396 alert('Something went wrong...')
397 okToPost = true;
398 }
399 );
400 okToPost = false;
401 };
402
403 // template文字列は指定要素の最初の要素であるHTML comment中にあるという前提。
404 this.templateUpdate = function (templateEl, updateEl, data, setupFunc) {
405 if (!templateEl || !updateEl) {
406 return;
407 }
408 var st = new Date();
409 // to workaround IE and WebKit bug. do not directly set innerHTML.
410 while (updateEl.firstChild) {
411 updateEl.removeChild(updateEl.firstChild);
412 }
413 var comment = templateEl.firstChild;
414 var src = comment.data;
415 src = modifyTemplate(src, data);
416 var template = new EJS({text: src});
417 var newdiv = document.createElement("div");
418 newdiv.innerHTML = template.render(data);
419 // setupFunc can process newly created elements before rendering. (this speeds up page redndering)
420 if (setupFunc) {
421 setupFunc(newdiv);
422 }
423 updateEl.appendChild(newdiv);
424 // updateEl.appear({ duration: 0.1 });
425 var et = new Date();
426 //a(et-st);
427
428 };
429
430 };
431 var self = new Application();
432
433 var box = null;
434 var contents = null;
435 Event.observe(window, "load", function () {
436 contents = $('contents');
437 var timerID = setInterval(checkLocationHash, 10);
438 });
439 var draggable = new Draggable();
440 var popup = new ModalPopUp();
441
442 var pageUrl = null;
443 function ajaxRequest(url, method, parameters, onSuccess, onFailure) {
444 if (url == null) {
445 url = self.getPathFromLocationHash();
446 }
447 var launchURL = pageUrl;
448 new Ajax.Request(
449 url,
450 {
451 "method" : method,
452 "parameters" : parameters,
453 "onSuccess": function(transport) {
454 try {
455 if (pageUrl == launchURL) {
456 onSuccess(transport);
457 }
458 }catch (e) {
459 a(e);
460 }
461 },
462 "onFailure": function () {
463 if (onFailure) {
464 try {
465 onFailure();
466 }catch (e) {
467 alert(e);
468 }
469 }
470 }
471 }
472 );
473 }
474
475 // 画面設定処理
476 function setPage(html) {
477 self.pageLoadHandler = null;
478 box = createNodeWithScript(html);
479 contents.appendChild(box);
480 var loc = self.getPathFromLocationHash();
481 if (self.pageLoadHandler) {
482 self.pageLoadHandler(box);
483 }
484 document.title = self.title + ' ' + self.pageTitle;
485 $("title").innerHTML = self.pageTitle;
486 // $("breadcrumbs").innerHTML = loc.split('/').join(' / ');
487 var navisrc = $("navisrc");
488 $("navi").innerHTML = navisrc.innerHTML;
489 navisrc.innerHTML = '';
490 self.setHelpers();
491 }
492
493 // AJAXによる画面データ読込処理
494 var pageCache = {};
495 function loadPage(dest, params) {
496 if (dest in pageCache) {
497 var html = pageCache[dest];
498 pageUrl = dest;
499 setPage(html);
500 }else {
501 self.ajaxRequest(
502 dest,
503 'get',
504 params,
505 function(transport) {
506 var html = transport.responseText;
507 pageCache[dest] = html;
508 pageUrl = dest;
509 setPage(html);
510 },
511 function () {
512 alert("ページ読み込み失敗");
513 }
514 );
515 }
516 }
517
518 // location.hash を監視して変更されていたらpathに相当する画面のデータを設定する。
519 var prevHash = "nullpo";
520 function checkLocationHash() {
521 if (location.hash != prevHash) {
522 if (box) {
523 popup.hide();
524 popup.clear();
525 if (self.pageUnloadHandler) {
526 var ret = self.pageUnloadHandler();
527 if (ret) {
528 dumpCookie(prevHash, ret);
529 }
530 }
531 contents.removeChild(box);
532 self.pageUnloadHandler = null;
533 }
534 prevHash = location.hash;
535 if (location.hash == "" || location.hash == "#") {
536 loadPage("menu" + ".html", {});
537 }else {
538 var pagePath = location.hash.substr(1, location.hash.length);
539 var paraPos = pagePath.indexOf('?');
540 if (paraPos >= 1) {
541 pagePath = pagePath.substr(0, paraPos);
542 }
543 loadPage(pagePath + ".html", {});
544 }
545 }
546 }
547
548 return self;
549
550 })();
551
552 // debug用のalert関数
553 function a(p) {
554 if (typeof p == "object") {
555 alert(Object.toJSON(p));
556 }else {
557 alert(p);
558 }
559 }
560
561 // TODO: 起動時にAjaxでServerから読み取る。
562 var prefectures = {
563 1 : '北海道',
564 2 : '青森県',
565 3 : '岩手県',
566 4 : '宮城県',
567 5 : '秋田県',
568 6 : '山形県',
569 7 : '福島県',
570 8 : '茨城県',
571 9 : '栃木県',
572 10 : '群馬県',
573 11 : '埼玉県',
574 12 : '千葉県',
575 13 : '東京都',
576 14 : '神奈川県',
577 15 : '新潟県',
578 16 : '富山県',
579 17 : '石川県',
580 18 : '福井県',
581 19 : '山梨県',
582 20 : '長野県',
583 21 : '岐阜県',
584 22 : '静岡県',
585 23 : '愛知県',
586 24 : '三重県',
587 25 : '滋賀県',
588 26 : '京都府',
589 27 : '大阪府',
590 28 : '兵庫県',
591 29 : '奈良県',
592 30 : '和歌山県',
593 31 : '鳥取県',
594 32 : '島根県',
595 33 : '岡山県',
596 34 : '広島県',
597 35 : '山口県',
598 36 : '徳島県',
599 37 : '香川県',
600 38 : '愛媛県',
601 39 : '高知県',
602 40 : '福岡県',
603 41 : '佐賀県',
604 42 : '長崎県',
605 43 : '熊本県',
606 44 : '大分県',
607 45 : '宮崎県',
608 46 : '鹿児島県',
609 47 : '沖縄県'
610 };

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26