Develop and Download Open Source Software

Browse Subversion Repository

Contents of /js/domain.js

Parent Directory Parent Directory | Revision Log Revision Log


Revision 33 - (show annotations) (download) (as text)
Sun Jan 17 13:57:47 2010 UTC (14 years, 4 months ago) by berupon
File MIME type: application/x-javascript
File size: 14427 byte(s)
ItemListを他の画面でも使いまわしたいので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 renderDoubleList = (function () {
219 var tmp = new EJS({url: 'js/doublelist.ejs'});
220 return function (lhs, rhs) {
221 var str = tmp.render(
222 {
223 'lhs' : lhs,
224 'rhs' : rhs
225 }
226 );
227 return str;
228 }
229 })();
230
231 var app = (function () {
232
233 /// private ///
234 Application = function () {
235
236 this.title = "SimpleLightWeb";
237 this.pageTitle = "";
238
239 // 擬似ページの読込時に呼び出すコールバック。
240 this.pageLoadHandler = null;
241
242 // 擬似ページの破棄時に呼び出すコールバック。戻り値が有る場合はcookieに保存
243 this.pageUnloadHandler = null;
244
245 // Modal PopUp 用の処理
246 this.showPopup = function () {
247 popup.show();
248 };
249
250 this.hidePopup = function () {
251 popup.hide();
252 };
253
254 this.setPopup = function (elem) {
255 popup.elem.appendChild(elem);
256 };
257
258 // 入力補助等のevent handlers設定
259 this.setHelpers = function () {
260 setAutoFocus();
261 draggable.attach();
262 ResizableColumns();
263 assignBehaviours();
264 };
265
266 this.getPathFromLocationHash = function () {
267 var url = location.hash;
268 return url.substr(1, url.length);
269 };
270
271 // prototype.js の String.toQueryParams は = で右辺に値を設定していないとパラメータとして拾ってくれないので自作。
272 this.getHashParams = function () {
273 var hash = this.getPathFromLocationHash();
274 var paraPos = hash.indexOf('?');
275 if (paraPos < 1) {
276 return {};
277 }else {
278 var paraStr = hash.substr(paraPos+1, hash.length);
279 var params = paraStr.split('&');
280 var ret = {};
281 for (var i=0; i<params.length; ++i) {
282 var para = params[i];
283 var pair = para.split('=');
284 for (var j=0; j<pair.length; ++j) {
285 pair[j] = decodeURIComponent(pair[j]);
286 }
287 if (pair.length == 1) {
288 ret[pair[0]] = null;
289 }else if (pair.length == 2) {
290 ret[pair[0]] = pair[1];
291 }
292 }
293 return ret;
294 }
295 }
296
297 // hash指定によるページ切り替え処理
298 // this routine understands relative path
299 this.moveLocation = function (path) {
300 var curHash = location.hash;
301 if (path.substr(0,1) == '/') {
302 location.hash = path.substr(1,path.length);
303 }else {
304 var upLevel = 0;
305 while (1) {
306 if (path.substr(0, 3) == '../') {
307 ++upLevel;
308 path = path.substr(3, path.length);
309 }else {
310 break;
311 }
312 }
313 var curPath = location.hash;
314 curPath = curPath.substr(1, curPath.length);
315 var parts = curPath.split('/');
316 parts = parts.slice(0, parts.length - (upLevel+1));
317 var newPath = parts.join('/');
318 if (newPath) {
319 newPath += '/';
320 }
321 newPath += path;
322 location.hash = newPath;
323 }
324 };
325
326 this.ajaxRequest = function (url, method, parameters, onSuccess, onFailure) {
327 ajaxRequest(url, method, parameters, onSuccess, onFailure);
328 };
329
330 // postによるデータ登録処理。エラー時にメッセージ表示を行うElementを用意する事。
331 var okToPost = true;
332 this.postRequest = function (params, newLocation) {
333 if (!okToPost) {
334 alert("ただいま結果待ちな為送信出来ません。");
335 return;
336 }
337 if (params instanceof HTMLFormElement) {
338 params = Form.serialize(params, true);
339 }
340 // alert(Object.toJSON(params));
341 this.ajaxRequest(
342 null,
343 'post',
344 params,
345 function(transport) {
346 var ret = transport.responseJSON;
347 if (!ret)
348 {
349 alert(transport.responseText);
350 }
351 if (ret.errors.length) {
352 $("messages").innerHTML = ret.errors.join("<BR>");
353 $("error").appear({ duration: 0.6 });
354 }else {
355 if (Object.isFunction(newLocation)) {
356 newLocation(ret);
357 }else {
358 if (newLocation == undefined) {
359 newLocation = "list";
360 }
361 this.moveLocation(newLocation);
362 }
363 }
364 okToPost = true;
365 }.bind(this),
366 function () {
367 alert('Something went wrong...')
368 okToPost = true;
369 }
370 );
371 okToPost = false;
372 };
373
374 // template文字列は指定要素の最初の要素であるHTML comment中にあるという前提。
375 this.templateUpdate = function (templateEl, updateEl, data, setupFunc) {
376 if (!templateEl || !updateEl) {
377 return;
378 }
379 var st = new Date();
380 // to workaround IE and WebKit bug. do not directly set innerHTML.
381 while (updateEl.firstChild) {
382 updateEl.removeChild(updateEl.firstChild);
383 }
384 var comment = templateEl.firstChild;
385 var src = comment.data;
386 src = modifyTemplate(src, data);
387 var template = new EJS({text: src});
388 var newdiv = document.createElement("div");
389 newdiv.innerHTML = template.render(data);
390 // setupFunc can process newly created elements before rendering. (this speeds up page redndering)
391 if (setupFunc) {
392 setupFunc(newdiv);
393 }
394 updateEl.appendChild(newdiv);
395 // updateEl.appear({ duration: 0.1 });
396 var et = new Date();
397 //a(et-st);
398
399 };
400
401 };
402 var self = new Application();
403
404 var box = null;
405 var contents = null;
406 Event.observe(window, "load", function () {
407 contents = $('contents');
408 var timerID = setInterval(checkLocationHash, 10);
409 });
410 var draggable = new Draggable();
411 var popup = new ModalPopUp();
412
413 var pageUrl = null;
414 function ajaxRequest(url, method, parameters, onSuccess, onFailure) {
415 if (url == null) {
416 url = self.getPathFromLocationHash();
417 }
418 var launchURL = pageUrl;
419 new Ajax.Request(
420 url,
421 {
422 "method" : method,
423 "parameters" : parameters,
424 "onSuccess": function(transport) {
425 try {
426 if (pageUrl == launchURL) {
427 onSuccess(transport);
428 }
429 }catch (e) {
430 a(e);
431 }
432 },
433 "onFailure": function () {
434 if (onFailure) {
435 try {
436 onFailure();
437 }catch (e) {
438 alert(e);
439 }
440 }
441 }
442 }
443 );
444 }
445
446 // 画面設定処理
447 function setPage(html) {
448 self.pageLoadHandler = null;
449 box = createNodeWithScript(html);
450 contents.appendChild(box);
451 var loc = self.getPathFromLocationHash();
452 if (self.pageLoadHandler) {
453 self.pageLoadHandler(box);
454 }
455 document.title = self.title + ' ' + self.pageTitle;
456 $("title").innerHTML = self.pageTitle;
457 // $("breadcrumbs").innerHTML = loc.split('/').join(' / ');
458 var navisrc = $("navisrc");
459 $("navi").innerHTML = navisrc.innerHTML;
460 navisrc.innerHTML = '';
461 self.setHelpers();
462 }
463
464 // AJAXによる画面データ読込処理
465 var pageCache = {};
466 function loadPage(dest, params) {
467 if (dest in pageCache) {
468 var html = pageCache[dest];
469 pageUrl = dest;
470 setPage(html);
471 }else {
472 self.ajaxRequest(
473 dest,
474 'get',
475 params,
476 function(transport) {
477 var html = transport.responseText;
478 pageCache[dest] = html;
479 pageUrl = dest;
480 setPage(html);
481 },
482 function () {
483 alert("ページ読み込み失敗");
484 }
485 );
486 }
487 }
488
489 // location.hash を監視して変更されていたらpathに相当する画面のデータを設定する。
490 var prevHash = "nullpo";
491 function checkLocationHash() {
492 if (location.hash != prevHash) {
493 if (box) {
494 popup.hide();
495 popup.clear();
496 if (self.pageUnloadHandler) {
497 var ret = self.pageUnloadHandler();
498 if (ret) {
499 dumpCookie(prevHash, ret);
500 }
501 }
502 contents.removeChild(box);
503 self.pageUnloadHandler = null;
504 }
505 prevHash = location.hash;
506 if (location.hash == "" || location.hash == "#") {
507 loadPage("menu" + ".html", {});
508 }else {
509 var pagePath = location.hash.substr(1, location.hash.length);
510 var paraPos = pagePath.indexOf('?');
511 if (paraPos >= 1) {
512 pagePath = pagePath.substr(0, paraPos);
513 }
514 loadPage(pagePath + ".html", {});
515 }
516 }
517 }
518
519 return self;
520
521 })();
522
523 // debug用のalert関数
524 function a(p) {
525 if (typeof p == "object") {
526 alert(Object.toJSON(p));
527 }else {
528 alert(p);
529 }
530 }
531
532 // TODO: 起動時にAjaxでServerから読み取る。
533 var prefectures = {
534 1 : '北海道',
535 2 : '青森県',
536 3 : '岩手県',
537 4 : '宮城県',
538 5 : '秋田県',
539 6 : '山形県',
540 7 : '福島県',
541 8 : '茨城県',
542 9 : '栃木県',
543 10 : '群馬県',
544 11 : '埼玉県',
545 12 : '千葉県',
546 13 : '東京都',
547 14 : '神奈川県',
548 15 : '新潟県',
549 16 : '富山県',
550 17 : '石川県',
551 18 : '福井県',
552 19 : '山梨県',
553 20 : '長野県',
554 21 : '岐阜県',
555 22 : '静岡県',
556 23 : '愛知県',
557 24 : '三重県',
558 25 : '滋賀県',
559 26 : '京都府',
560 27 : '大阪府',
561 28 : '兵庫県',
562 29 : '奈良県',
563 30 : '和歌山県',
564 31 : '鳥取県',
565 32 : '島根県',
566 33 : '岡山県',
567 34 : '広島県',
568 35 : '山口県',
569 36 : '徳島県',
570 37 : '香川県',
571 38 : '愛媛県',
572 39 : '高知県',
573 40 : '福岡県',
574 41 : '佐賀県',
575 42 : '長崎県',
576 43 : '熊本県',
577 44 : '大分県',
578 45 : '宮崎県',
579 46 : '鹿児島県',
580 47 : '沖縄県'
581 };

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