OSDN Git Service

elFinder最新版追加。
[magic3/magic3.git] / scripts / m3admin2.0.2.js
1 /**
2  * Magic3管理機能用JavaScriptライブラリ
3  *
4  * JavaScript 1.5
5  *
6  * LICENSE: This source file is licensed under the terms of the GNU General Public License.
7  *
8  * @package    Magic3 Framework
9  * @author     平田直毅(Naoki Hirata) <naoki@aplo.co.jp>
10  * @copyright  Copyright 2006-2018 Magic3 Project.
11  * @license    http://www.gnu.org/copyleft/gpl.html  GPL License
12  * @version    SVN: $Id$
13  * @link       http://www.magic3.org
14  */
15 // ライブラリ用変数
16 var _m3Url;
17 var _m3AccessPoint;             // アクセスポイント(空=PC,m=携帯,s=スマートフォン)
18 var _m3SetUrlCallback;  // リンク作成用コールバック
19 var _m3ContentEdited;           // 入力コンテンツが変更されたかどうか
20 var _m3CheckContentEdit;        // 入力コンテンツの変更をチェックするかどうか
21 var _m3ShowWidgetTool;          // ウィジェットツールを表示するかどうか
22 var _m3ConfigWindowMinHeight = 600;                     // 設定画面の高さ最小値
23
24 // 親ウィンドウを更新
25 function m3UpdateParentWindow()
26 {
27         var href =      window.opener.location.href.split('#');
28         window.opener.location.href = href[0];
29         //window.opener.location.href = window.opener.location.href;
30 }
31 // 設定ウィンドウから親ウィンドウを更新
32 function m3UpdateParentWindowByConfig(serial)
33 {
34         if (window.opener){
35                 if (window.opener.m3UpdateByConfig) window.opener.m3UpdateByConfig(serial);
36                 if (window.opener.m3UpdateByChildWindow) window.opener.m3UpdateByChildWindow(serial);
37         }
38         if (window.parent != window.self){      // 呼び出し元がiframeの場合のみ実行
39                 // iframeから親フレームを更新
40                 if (window.parent.m3UpdateByChildWindow) window.parent.m3UpdateByChildWindow(serial);
41                 
42                 // iframeから起動元ウィンドウを更新
43                 if (window.parent.opener && window.parent.opener.m3UpdateByConfig) window.parent.opener.m3UpdateByConfig(serial);
44         }
45 }
46 // 親ウィンドウサイズを調整
47 function m3AdjustParentWindow()
48 {
49         if (window.parent){
50                 if (window.parent.m3AdjustWindow) window.parent.m3AdjustWindow();
51         }
52 }
53 // ウィンドウサイズ調整
54 function m3AdjustHeight(obj, min)
55 {
56         var name = obj.name;
57         
58         if (!name) name = 0;
59
60         var app = navigator.appName.charAt(0);
61         var height = min;
62         if(navigator.userAgent.indexOf('Safari') != -1){
63                 height = parent.frames[name].document.body.scrollHeight + 80;
64         }else if (app == "N"){
65                 height = parent.frames[name].document.height +80;
66         } else {
67                 try {
68                         height = parent.frames[name].document.body.scrollHeight + 80;
69                 } catch (e){}
70         }
71         if (height > min){
72                 obj.height = height;
73         } else {
74                 obj.height = min;
75         }
76 }
77 // 一般ウィンドウ表示
78 function m3ShowStandardWindow(url)
79 {
80         if (M3_CONFIG_WINDOW_OPEN_TYPE == 0){
81                 window.open(url, "", "toolbar=no,menubar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1050,height=900");
82         } else {
83                 window.open(url, "");
84         }
85 }
86 // 設定用ウィンドウ表示
87 function m3ShowConfigWindow(widgetId, configId, serial)
88 {
89         if (M3_CONFIG_WINDOW_OPEN_TYPE == 0){
90                 window.open(M3_DEFAULT_ADMIN_URL + "?cmd=configwidget&openby=other&widget=" + widgetId + 
91                                         "&_defconfig=" + configId + "&_defserial=" + serial, "config_" + widgetId,
92                                         "toolbar=no,menubar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1050,height=900");
93         } else {
94                 window.open(M3_DEFAULT_ADMIN_URL + "?cmd=configwidget&openby=other&widget=" + widgetId + 
95                                         "&_defconfig=" + configId + "&_defserial=" + serial, "config_" + widgetId);
96         }
97 }
98 // テンプレート設定用ウィンドウ表示
99 function m3ShowTemplateConfigWindow(templateId)
100 {
101         window.open(M3_DEFAULT_ADMIN_URL + "?cmd=configtemplate&openby=other&template=" + templateId, "configtemplate_" + templateId);
102 }
103 // ウィジェット表示微調整用ウィンドウ表示
104 function m3ShowAdjustWindow(configId, serial, pageId, pageSubId)
105 {
106         if (M3_CONFIG_WINDOW_OPEN_TYPE == 0){
107                 window.open(M3_DEFAULT_ADMIN_URL + "?task=adjustwidget&openby=simple" + 
108                                         "&_defconfig=" + configId + "&_defserial=" + serial + "&_page=" + pageId + "&_sub=" + pageSubId, "adjust_" + serial,
109                                         "toolbar=no,menubar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1050,height=900");
110         } else {
111                 window.open(M3_DEFAULT_ADMIN_URL + "?task=adjustwidget&openby=simple" + 
112                                         "&_defconfig=" + configId + "&_defserial=" + serial + "&_page=" + pageId + "&_sub=" + pageSubId, "adjust_" + serial);
113         }
114 }
115 // 各種端末用プレビューウィンドウ表示
116 function m3ShowPreviewWindow(type, url)
117 {
118         var width, height;
119         
120         switch (type){
121                 case 0:         // PC用
122                 default:
123                         // 小画面デバイス最適化の場合はタブで表示
124                         if (M3_SMALL_DEVICE_OPTIMIZE){
125                                 window.open(url, "");
126                                 return;
127                         }
128                 
129                         width = 1000;
130                         height = 800;
131                         break;
132                 case 1:         // 携帯用
133                         width = 240;
134                         height = 320;
135                         break;
136                 case 2:         // スマートフォン用
137                         width = 320;
138                         height = 480;
139                         break;
140         }
141         window.open(url, "", "toolbar=no,menubar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=" + width + ",height=" + height);
142 }
143 /**
144  * 管理画面用部品
145  *
146  * @return なし
147  */
148 function m3LoadOptionUI()
149 {
150         // ダイアログ用設定
151         $('.modal-header').addClass('bg-primary');              // タイトル背景色
152         if (typeof(BootstrapDialog) != "undefined"){
153                 BootstrapDialog.DEFAULT_TEXTS['CANCEL'] = 'キャンセル';
154         }
155
156         // 処理中ダイアログ準備
157         m3PrepareProcessModal();
158 }
159 /**
160  * 処理中ダイアログ表示
161  *
162  * @return なし
163  */
164 function m3ShowProcessModal()
165 {
166         // 画面上のフォーカスを外す
167         $('input,textarea,select').blur();
168         
169         $('#processing-modal').modal('show');
170 }
171 /**
172  * 処理中ダイアログ非表示
173  *
174  * @return なし
175  */
176 function m3HideProcessModal()
177 {
178         $('#processing-modal').modal('hide');
179 }
180 /**
181  * 処理中ダイアログ準備
182  *
183  * @return なし
184  */
185 function m3PrepareProcessModal()
186 {
187         // ダイアログ作成
188         if ($('#processing-modal').size() == 0){                // ダイアログが存在しない場合
189                 var modal  = '<div class="modal modal-processing fade" id="processing-modal" role="dialog" aria-hidden="true" style="display:none;">';
190                         modal += '<div class="modal-dialog">';
191                         modal += '<div class="modal-content">';
192                         modal += '<div class="modal-body">';
193                         modal += '<div class="text-center">';
194                         modal += '<img src="' + M3_ROOT_URL + '/images/system/processing.gif" class="icon" />';
195                         modal += '<h4>処理中</h4>';
196                         modal += '</div>';
197                         modal += '</div>';
198                         modal += '</div>';
199                         modal += '</div>';
200                         modal += '</div>';
201                 $("body").append(modal);
202         }
203 }
204 /**
205  * アラートを表示
206  *
207  * @param string type                   アラートタイプ(空文字列,info,notice,success,failure,warinig,error)
208  * @param string message                メッセージ
209  * @param function      after_callback  コールバック関数
210  * @param string title                  タイトル
211  * @return なし
212  */
213 function m3Alert(type, message, after_callback, title)
214 {
215         var dialogType;
216         var config = {};
217         
218         switch (type){
219         case '':
220                 dialogType = BootstrapDialog.TYPE_DEFAULT;
221                 break;
222         case 'info':
223                 dialogType = BootstrapDialog.TYPE_INFO;
224                 break;
225         case 'notice':
226                 dialogType = BootstrapDialog.TYPE_PRIMARY;
227                 break;
228         case 'success':
229                 dialogType = BootstrapDialog.TYPE_SUCCESS;
230                 break;
231         case 'failure':
232                 dialogType = BootstrapDialog.TYPE_WARNING;
233                 break;
234         case 'warning':
235                 dialogType = BootstrapDialog.TYPE_WARNING;
236                 break;
237         case 'danger':
238                 dialogType = BootstrapDialog.TYPE_DANGER;
239                 break;
240         case 'error':
241                 dialogType = BootstrapDialog.TYPE_DANGER;
242                 break;
243         }
244         config['type'] = dialogType;
245         config['message'] = message;
246         if (!title){
247                 switch (type){
248                 case '':
249                         break;
250                 case 'info':
251                         title = '情報';
252                         break;
253                 case 'notice':
254                         title = '注意';
255                         break;
256                 case 'success':
257                         title = '成功';
258                         break;
259                 case 'failure':
260                         title = '失敗';
261                         break;
262                 case 'warning':
263                         title = "警告";
264                         break;
265                 case 'danger':
266                         title = '危険';
267                         break;
268                 case 'error':
269                         title = 'エラー';
270                         break;
271                 }
272         }
273         if (title) config['title'] = title;
274         if (after_callback) config['callback'] = function(result){ after_callback(); };
275         
276         BootstrapDialog.alert(config);
277 }
278 /**
279  * 確認画面を表示
280  *
281  * @param string type                   アラートタイプ(空文字列,info,notice,success,failure,warinig,error)
282  * @param string message                メッセージ
283  * @param function      callback        ボタンが押されときのコールバック関数(第1引数1にOK(true),キャンセル(false)が渡る。)
284  * @param string title                  タイトル
285  * @return なし
286  */
287 function m3Confirm(type, message, callback, title)
288 {
289         var dialogType;
290         var config = {};
291         
292         switch (type){
293         case '':
294         default:
295                 //dialogType = BootstrapDialog.TYPE_DEFAULT;
296                 dialogType = BootstrapDialog.TYPE_INFO;
297                 break;
298         case 'info':
299                 dialogType = BootstrapDialog.TYPE_INFO;
300                 break;
301         case 'notice':
302                 dialogType = BootstrapDialog.TYPE_PRIMARY;
303                 break;
304         case 'success':
305                 dialogType = BootstrapDialog.TYPE_SUCCESS;
306                 break;
307         case 'failure':
308                 dialogType = BootstrapDialog.TYPE_WARNING;
309                 break;
310         case 'waring':
311                 dialogType = BootstrapDialog.TYPE_WARNING;
312                 break;
313         case 'error':
314                 dialogType = BootstrapDialog.TYPE_DANGER;
315                 break;
316         }
317
318         if (!title){
319                 switch (type){
320                 case '':
321                 default:
322                         title = '確認';
323                         break;
324                 case 'info':
325                         title = '情報';
326                         break;
327                 case 'notice':
328                         title = '注意';
329                         break;
330                 case 'success':
331                         title = '成功';
332                         break;
333                 case 'failure':
334                         title = '失敗';
335                         break;
336                 case 'warning':
337                         title="警告";
338                         break;
339                 case 'danger':
340                         title = 'エラー';
341                         break;
342                 }
343         }
344         
345         new BootstrapDialog({
346                 type: dialogType,
347                 title: title,
348                 message: message,
349                 closable: false,
350                 data: {
351                         'callback': callback
352                 },
353                 buttons: [{
354                         label: BootstrapDialog.DEFAULT_TEXTS.CANCEL,
355                         action: function(dialog) {
356                                 typeof dialog.getData('callback') === 'function' && dialog.getData('callback')(false);
357                                 dialog.close();
358                         }
359                 }, {
360                         label: BootstrapDialog.DEFAULT_TEXTS.OK,
361                         cssClass: 'btn-primary',
362                         action: function(dialog) {
363                                 typeof dialog.getData('callback') === 'function' && dialog.getData('callback')(true);
364                                 dialog.close();
365                         }
366                 }]
367         }).open();
368 }
369 /**
370  * ファイルブラウザを表示
371  *
372  * @param function      seturl_callback コールバック関数
373  * @return なし
374  */
375 function m3OpenFileBrowser(seturl_callback)
376 {
377         $('<div />').dialog({
378                 title: "ファイルを選択",
379                 modal: true,
380                 width: $(window).width() * M3_FILEBROWSER_WIDTH_RATIO,
381                 open: function(){
382                         $(this).parent().css("padding", "0px");
383                         $(this).css("padding", "0px");
384                 },
385                 create: function(event, ui){
386                         $(this).elfinder({
387                                 url : M3_ROOT_URL + '/scripts/elfinder-' + M3_FILEBROWSER_VER + '/php/connector.php?dirtype=file',
388                                 height: '500px',
389                                 lang: 'ja',
390                                 resizable: false,
391                                 ui: ['toolbar', 'places', 'tree', 'path', 'stat'],
392                                 getFileCallback: function(url){
393                                         seturl_callback(url.url);
394                                         $('.ui-dialog-titlebar-close[role="button"]').click();
395                                 }
396                         }).elfinder('instance');
397                 }
398         });
399 }
400 /**
401  * 画像ファイルブラウザを表示
402  *
403  * @param function      seturl_callback コールバック関数
404  * @return なし
405  */
406 function m3OpenImageFileBrowser(seturl_callback)
407 {
408         $('<div />').dialog({
409                 title: "画像を選択",
410                 modal: true,
411                 width: $(window).width() * M3_FILEBROWSER_WIDTH_RATIO,
412                 open: function(){
413                         $(this).parent().css("padding", "0px");
414                         $(this).css("padding", "0px");
415                 },
416                 create: function(event, ui){
417                         $(this).elfinder({
418                                 url : M3_ROOT_URL + '/scripts/elfinder-' + M3_FILEBROWSER_VER + '/php/connector.php?dirtype=image',
419                                 height: '500px',
420                                 lang: 'ja',
421                                 resizable: false,
422                                 ui: ['toolbar', 'places', 'tree', 'path', 'stat'],
423                                 getFileCallback: function(url){
424                                         seturl_callback(url.url);
425                                         $('.ui-dialog-titlebar-close[role="button"]').click();
426                                 }
427                         }).elfinder('instance');
428                 }
429         });
430 }
431 /**
432  * Flashファイルブラウザを表示
433  *
434  * @param function      seturl_callback コールバック関数
435  * @return なし
436  */
437 function m3OpenFlashFileBrowser(seturl_callback)
438 {
439         $('<div />').dialog({
440                 title: "Flashを選択",
441                 modal: true,
442                 width: $(window).width() * M3_FILEBROWSER_WIDTH_RATIO,
443                 open: function(){
444                         $(this).parent().css("padding", "0px");
445                         $(this).css("padding", "0px");
446                 },
447                 create: function(event, ui){
448                         $(this).elfinder({
449                                 url : M3_ROOT_URL + '/scripts/elfinder-' + M3_FILEBROWSER_VER + '/php/connector.php?dirtype=flash',
450                                 height: '500px',
451                                 lang: 'ja',
452                                 resizable: false,
453                                 ui: ['toolbar', 'places', 'tree', 'path', 'stat'],
454                                 getFileCallback: function(url){
455                                         seturl_callback(url.url);
456                                         $('.ui-dialog-titlebar-close[role="button"]').click();
457                                 }
458                         }).elfinder('instance');
459                 }
460         });
461 }
462 /**
463  * TextAreaをHTMLエディターに変更
464  *
465  * @param string id                     TextAreaタグのIDまたはname
466  * @param bool  isMobile        携帯用のツールバー表示
467  * @return なし
468  */
469 function m3_setHtmlEditor(id, isMobile)
470 {
471         var oFCKeditor          = new FCKeditor(id);
472         oFCKeditor.BasePath     = M3_ROOT_URL + '/scripts/fckeditor2.6.6/';
473         oFCKeditor.Config['CustomConfigurationsPath'] = M3_ROOT_URL + '/scripts/m3/fckconfig.js';
474         if (isMobile == null || isMobile == false){
475                 oFCKeditor.ToolbarSet   = "M3Default";                  // ツールバーリソース名
476         } else {
477                 oFCKeditor.ToolbarSet   = "M3MobileDefault";    // ツールバーリソース名
478         }
479         oFCKeditor.Width        = "100%";
480         oFCKeditor.Height       = "100%";
481         oFCKeditor.Value        = 'This is some <strong>sample text<\/strong>. You are using <a href="http://www.fckeditor.net/">FCKeditor<\/a>.';
482         oFCKeditor.ReplaceTextarea();
483 }
484 /**
485  * TextAreaをWYSIWYGエディターに変更
486  *
487  * @param string id                             TextAreaタグのIDまたはname
488  * @param int height                    エディター領域の高さ
489  * @param bool toolbarVisible   ツールバーを表示するかどうか
490  * @param string barType                ツールバータイプ(full=全項目,layout=レイアウト用,small=小画面デバイス用)
491  * @param int width                             エディター領域の幅
492  * @return なし
493  */
494 function m3SetWysiwygEditor(id, height, toolbarVisible, barType, width)
495 {
496         // CKEditor v 4.4のiPhone,AndroidのWebブラウザのアクセス制限を解除(2017/1/21)
497         if ( !CKEDITOR.env.ie || CKEDITOR.env.version > 7 ) CKEDITOR.env.isCompatible = true;
498         
499         // アクセスポイントの設定
500         _m3SetAccessPoint(M3_CONFIG_WIDGET_DEVICE_TYPE);
501                 
502         if (M3_WYSIWYG_EDITOR == 'ckeditor'){
503                 var config = {};
504                 
505                 config['customConfig'] = M3_ROOT_URL + '/scripts/m3/ckconfig.js';
506                 if (height) config['height'] = height;
507                 if (width) config['width'] = width;
508                 if (toolbarVisible != null && !toolbarVisible) config['toolbarStartupExpanded'] = false;
509                 
510                 if (barType){
511                         switch (barType){
512                         case 'full':
513                         default:
514                                 config['toolbar'] = 'Full';
515                                 if (typeof(M3_CONFIG_WIDGET_CKEDITOR_CSS_FILES) != "undefined") config['contentsCss'] = M3_CONFIG_WIDGET_CKEDITOR_CSS_FILES;
516                                 break;
517                         case 'layout':
518                                 config['toolbar'] = 'Layout';
519                                 if (typeof(M3_CONFIG_WIDGET_CKEDITOR_LAYOUT_CSS_FILES) != "undefined") config['contentsCss'] = M3_CONFIG_WIDGET_CKEDITOR_LAYOUT_CSS_FILES;
520                                 break;
521                         case 'small':
522                                 config['toolbar'] = 'Small';
523                                 break;
524                         }
525                 } else {
526                         config['toolbar'] = 'Full';
527                         if (typeof(M3_CONFIG_WIDGET_CKEDITOR_CSS_FILES) != "undefined") config['contentsCss'] = M3_CONFIG_WIDGET_CKEDITOR_CSS_FILES;
528                 }
529                 CKEDITOR.replace(id, config);
530         } else {
531                 var oFCKeditor          = new FCKeditor(id);
532                 oFCKeditor.BasePath     = M3_ROOT_URL + '/scripts/fckeditor2.6.6/';
533                 oFCKeditor.Config['CustomConfigurationsPath'] = M3_ROOT_URL + '/scripts/m3/fckconfig.js';
534                 oFCKeditor.ToolbarSet   = "M3Default";                  // ツールバーリソース名
535                 if (height) oFCKeditor.Height = String(height) + 'px';
536                 oFCKeditor.Value        = 'This is some <strong>sample text<\/strong>. You are using <a href="http://www.fckeditor.net/">FCKeditor<\/a>.';
537                 oFCKeditor.ReplaceTextarea();
538         }
539 }
540 /**
541  * TextAreaをスクリプト編集エディターに変更
542  *
543  * @param string id                     TextAreaタグのIDまたはname
544  * @param int height            エディター領域の高さ
545  * @return なし
546  */
547 function m3SetScriptEditor(id, height)
548 {
549         if (typeof CodeMirror == 'undefined') return;
550         
551         var obj;
552         obj = document.getElementById(id);
553         if (!obj) obj = document.getElementsByName(id);
554         if (!obj) alert(id + "not found.");
555         var editor = CodeMirror.fromTextArea(obj, {
556                 mode: "javascript",
557                 lineNumbers: true,
558                 matchBrackets: true,
559                 extraKeys: {"Enter": "newlineAndIndentContinueComment"}
560         });
561         if (height) editor.setSize('100%', height);
562 /*      if (M3_WYSIWYG_EDITOR == 'ckeditor'){
563                 var config = {};
564                 config['customConfig'] = M3_ROOT_URL + '/scripts/m3/ckconfig_script.js';
565                 if (height) config['height'] = height;
566                 CKEDITOR.replace(id, config);
567         } else {
568         }*/
569 }
570 /**
571  * CKEditorツールバー機能の直接実行準備
572  *
573  * @return なし
574  */
575 function m3LoadCKTools()
576 {
577         var dummyCKParent = $('#_dummy_ck_parent');
578         if (!dummyCKParent[0]){
579                 var dummyHtml = '<div id="_dummy_ck_parent"><textarea type="text" id="_dummy_ckeditor" ></textarea></div>';
580                 $("body").append(dummyHtml);
581         }
582         dummyCKParent = $('#_dummy_ck_parent');
583
584         var config = {};
585 //      config['customConfig'] = M3_ROOT_URL + '/scripts/m3/ckconfig_direct.js';
586         config['customConfig'] = M3_ROOT_URL + '/scripts/m3/ckconfig.js';
587         config['extraPlugins'] = 'linkinfo';
588         CKEDITOR.replace('_dummy_ckeditor', config);
589         dummyCKParent.hide();
590 }
591 /**
592  * URL作成用のアクセスポイントを設定
593  *
594  * @param int deviceType                                デバイスタイプ(0=PC,1=携帯,2=スマートフォン)
595  * @return なし
596  */
597 function _m3SetAccessPoint(deviceType)
598 {
599         // アクセスポイント(空=PC,m=携帯,s=スマートフォン)取得
600         var accessPoint;
601         switch (deviceType){
602                 case 0:         // PC用
603                 default:
604                         accessPoint = '';
605                         break;
606                 case 1:         // 携帯用
607                         accessPoint = 'm';
608                         break;
609                 case 2:         // スマートフォン用
610                         accessPoint = 's';
611                         break;
612         }
613         _m3AccessPoint = accessPoint;
614 }
615 /**
616  * リンク用のURLを作成
617  *
618  * @param int deviceType                                デバイスタイプ(0=PC,1=携帯,2=スマートフォン)
619  * @param string url                                    URL初期値
620  * @param function      seturl_callback         コールバック関数
621  * @return なし
622  */
623 function m3CreateLinkUrl(deviceType, url, seturl_callback)
624 {
625         // アクセスポイント(空=PC,m=携帯,s=スマートフォン)取得
626         var accessPoint;
627         switch (deviceType){
628                 case 0:         // PC用
629                 default:
630                         accessPoint = '';
631                         break;
632                 case 1:         // 携帯用
633                         accessPoint = 'm';
634                         break;
635                 case 2:         // スマートフォン用
636                         accessPoint = 's';
637                         break;
638         }
639         _m3AccessPoint = accessPoint;
640         _m3Url = url;
641         _m3SetUrlCallback = seturl_callback;
642         
643         var dummyCKParent = $('#_dummy_ck_parent');
644         dummyCKParent.show();                   // IE8バグ回避用
645         CKEDITOR.instances['_dummy_ckeditor'].execCommand( 'linkinfo' );
646         dummyCKParent.hide();                   // IE8バグ回避用
647 }
648 /**
649  * 「前へ」ボタンのクリックイベントにコールバックを設定
650  *
651  * @param function      callback        コールバック関数
652  * @param string    param               コールバック用パラメータ
653  * @return なし
654  */
655 function m3SetPrevButtonEvent(callback, param)
656 {
657         if (typeof(callback) == 'function'){
658                 $('#m3configprev').click(function(){
659                         callback(param);
660                 });
661                 $('.m3configprev').show();
662         }
663 }
664 /**
665  * 「次へ」ボタンのクリックイベントにコールバックを設定
666  *
667  * @param function      callback        コールバック関数
668  * @param string    param               コールバック用パラメータ
669  * @return なし
670  */
671 function m3SetNextButtonEvent(callback, param)
672 {
673         if (typeof(callback) == 'function'){
674                 $('#m3confignext').click(function(){
675                         callback(param);
676                 });
677                 $('.m3confignext').show();
678         }
679 }
680 /**
681  * 入力データ編集中のページ離脱を防止
682  *
683  * @return なし
684  */
685 function m3SetSafeContentEdit()
686 {
687         _m3ContentEdited = false;               // 入力コンテンツが変更されたかどうか
688         _m3CheckContentEdit = true;     // 入力コンテンツの変更をチェックするかどうか
689         
690         $(window).bind("beforeunload", function(){
691                 // CKEditorの入力内容の変更を確認
692                 var ckeChanged = false;
693                 if (typeof CKEDITOR !== 'undefined' && CKEDITOR.instances){
694                         for (instance in CKEDITOR.instances){
695                                 ckeChanged = CKEDITOR.instances[instance].checkDirty();
696                                 if (ckeChanged) break;
697                         }
698                 }
699
700                 if (_m3CheckContentEdit && (_m3ContentEdited || ckeChanged)){
701                         _m3CheckContentEdit = false;
702                         setTimeout(function(){
703                                 _m3CheckContentEdit = true;
704                         }, 10);
705                         return "このページを離れようとしています。";
706                 }
707         });
708 /*      $("form input, form select, form textarea").change(function(){
709                 _m3ContentEdited = true;
710         });*/
711         // Firefox対応(2015/12/1)
712         $("form input:not(.noeditcheck), form select, form textarea").change(function(){
713                 _m3ContentEdited = true;
714         });
715 }
716 /**
717  * 入力データ編集中のページ離脱を許可
718  *
719  * @return なし
720  */
721 function m3CancelSafeContentEdit()
722 {
723         $(window).unbind("beforeunload");
724 }
725 /**
726  * ヘルプを設定
727  *
728  * @param object parentObj              親オブジェクトまたはタグID
729  * @return なし
730  */
731 function m3SetHelp(parentObj)
732 {
733         if (parentObj){
734                 if (typeof parentObj == 'string'){
735                         parentObj = $('#' + parentObj);
736                 }
737             if (jQuery().cluetip){
738                         parentObj.find('span.m3help').cluetip({ splitTitle: '|', cluezIndex: 2000, hoverIntent:{ sensitivity:1, interval:500, timeout:0 }});
739                         parentObj.find('div.m3help').cluetip({ splitTitle: '|', cluezIndex: 2000, hoverIntent:{ sensitivity:1, interval:500, timeout:0 }});
740                 }
741             if (jQuery().tooltip) parentObj.find('[rel=m3help]').tooltip({ 'delay': { show: 1000, hide: 0 }});
742         } else {
743             if (jQuery().cluetip){
744                         $('span.m3help').cluetip({ splitTitle: '|', cluezIndex: 2000, hoverIntent:{ sensitivity:1, interval:500, timeout:0 }});
745                         $('div.m3help').cluetip({ splitTitle: '|', cluezIndex: 2000, hoverIntent:{ sensitivity:1, interval:500, timeout:0 }});
746                 }
747             if (jQuery().tooltip) $('[rel=m3help]').tooltip({ 'delay': { show: 1000, hide: 0 }});
748         }
749 }
750 /**
751  * ファイル選択ボタンを設定
752  *
753  * @return なし
754  */
755 function m3SetFileSelectButton()
756 {
757         $('.btn-file :file').on('fileselect', function(event, numFiles, label){
758                 var input = $(this).parents('.input-group').find(':text'),
759                         log = numFiles > 1 ? numFiles + ' files selected' : label;
760                 
761                 if (input.length){
762                         input.val(log);
763                 } else {
764                         if (log) alert(log);
765                 }
766         });
767         
768         $(document).on('change', '.btn-file :file', function(){
769             var input = $(this),
770                 numFiles = input.get(0).files ? input.get(0).files.length : 1,
771                 label = input.val().replace(/\\/g, '/').replace(/.*\//, '');
772             input.trigger('fileselect', [numFiles, label]);
773         });
774 }
775 /**
776  * 設定入力用テーブルのカラー設定
777  *
778  * @param object  object                        テーブルオブジェクトまたはテーブルID文字列
779  * @return なし
780  */
781 function m3SetConfigTable(object)
782 {
783         var tableObj;           // テーブルオブジェクト
784         
785         if (typeof object == 'string'){
786                 //tableObj = document.getElementById(object);
787                 tableObj = $('#' + object);
788         } else {
789                 tableObj = object;
790         }
791         // カラー設定
792         tableObj.addClass('table table-condensed table-bordered table-striped m3config_table');
793         tableObj.find('th').addClass('info');           // ヘッダ部
794         
795         tableObj.find('textarea').addClass('form-control');
796         tableObj.find('select').addClass('form-control');
797         tableObj.find('input[type=text]').addClass('form-control');
798         tableObj.find('input[type=password]').addClass('form-control');
799 }
800 /**
801  * 設定入力用サブテーブルのカラー設定
802  *
803  * @param object  object                        テーブルオブジェクトまたはテーブルID文字列
804  * @return なし
805  */
806 function m3SetConfigSubTable(object)
807 {
808         var tableObj;           // テーブルオブジェクト
809         
810         if (typeof object == 'string'){
811                 //tableObj = document.getElementById(object);
812                 tableObj = $('#' + object);
813         } else {
814                 tableObj = object;
815         }
816         // カラー設定
817         tableObj.addClass('table table-condensed table-bordered table-striped');
818         tableObj.find('th').addClass('info');           // ヘッダ部
819         
820         tableObj.find('select').addClass('form-control');
821         tableObj.find('input[type=text]').addClass('form-control');
822 }
823 /**
824  * モーダル入力用テーブルのカラー設定
825  *
826  * @param object  object                        テーブルオブジェクトまたはテーブルID文字列
827  * @return なし
828  */
829 function m3SetModalTable(object)
830 {
831         var tableObj;           // テーブルオブジェクト
832         
833         if (typeof object == 'string'){
834                 tableObj = document.getElementById(object);
835         } else {
836                 tableObj = object;
837         }
838         // カラー設定
839         $(tableObj).addClass('table table-condensed table-bordered table-striped m3config_modal_table');
840         $(tableObj).find('th').addClass('info');                // ヘッダ部
841 }
842 /**
843  * テーブルに行の並び替え機能を追加
844  *
845  * @param object   object                       テーブルオブジェクトまたはテーブルID文字列
846  * @param function reorder_callback     並び替え時コールバック関数
847  * @return bool                                         true=作成成功、false=作成失敗
848  */
849 function m3SetDragDropTable(object, reorder_callback)
850 {
851         if (!jQuery().tableDnD) return false;
852         
853         var tableObj;           // テーブルオブジェクト
854         
855         if (typeof object == 'string'){
856                 tableObj = $('#' + object);
857         } else {
858                 tableObj = object;
859         }
860
861         // 行のIDを設定
862         tableObj.find('tr').attr('id',function(i){
863                 return 'm3drag_rowid_' + i;
864         });
865         
866         // ドラッグ&ドロップテーブル作成
867         tableObj.tableDnD({
868                 onDrop: function(table, row){
869                         _setupDragDropTable(tableObj, reorder_callback);
870                 },
871                 dragHandle: ".m3drag_handle"
872         });
873         tableObj.find('tr.m3drag_row').hover(function(){
874                 $(this.cells[0]).addClass('m3drag_current');
875         }, function() {
876                 $(this.cells[0]).removeClass('m3drag_current');
877         });
878         
879         // 画像項目削除処理
880         tableObj.find('tr .m3drag_delrow').off('click').on('click', function(){
881                 var rowObj = $(this);
882
883                 m3Confirm('waring', '項目を削除しますか?', function(result){
884                         if (result){
885                             rowObj.parents('.m3drag_row').fadeTo(400, 0, function(){
886                                 $(this).remove();
887                 
888                                         _setupDragDropTable(tableObj, reorder_callback);
889                             });
890                         }
891                 });
892                 
893         return false;
894         });
895         // インデックスNo再設定
896         _setupDragDropTable(tableObj, reorder_callback);
897         
898         // スタイル再設定
899         m3SetConfigSubTable(tableObj);
900         
901         // HELP追加
902         m3SetHelp(tableObj);
903         
904         return true;
905 }
906 /**
907  * 行の並び替えテーブル用関数
908  *
909  * @param object  object                テーブルオブジェクトまたはテーブルID文字列
910  * @param function      callback        コールバック関数
911  * @return なし
912  */
913 function _setupDragDropTable(object, callback)
914 {
915         // インデックスNo再設定
916         object.find('tr .m3drag_rowno').each(function(index){
917                 $(this).text(index + 1);
918         });
919         
920         // コールバック関数を実行
921         if (typeof(callback) == 'function') callback();
922 }
923 /**
924  * ドラッグ&ドロップファイルアップロード機能を作成
925  *
926  * @param string    id                  表示領域タグID
927  * @param string    url                 アップロード先URL
928  * @param function      callback        成功時コールバック関数
929  * @param string    extensions  アップロード許可するファイルの拡張子を「,」区切りで列挙
930  * @return bool                                 true=作成成功、false=作成失敗
931  */
932 function m3CreateDragDropUploadFile(id, url, callback, extensions)
933 {
934         if (!jQuery().uploadFile) return false;
935         
936         if (!extensions) extensions = 'png,gif,jpg,jpeg';
937         
938         var artisteerStyle = false;
939         var bootstrapStyle = true;
940         
941         $('#' + id).uploadFile({
942                 url: url,
943                 allowedTypes: extensions,
944                 showFileCounter: false,         // ファイルNoなし
945                 showProgress: true,
946                 artisteerStyle: artisteerStyle,
947                 bootstrapStyle: bootstrapStyle,
948                 stripedBar: true,
949                 uploadStr: '',
950                 dragDropStr: '',
951                 returnType: 'json',
952                 customErrorKeyStr: 'error',
953                 abortStr: '中断',
954                 cancelStr: 'キャンセル',
955                 deletelStr: '削除',
956                 doneStr: '完了',
957                 onSuccess:function(files, data)
958                 {
959                         if (typeof(callback) == 'function') callback(files, data);
960                 }
961         });
962         return true;
963 }
964 /**
965  * ウィジェットツールの準備
966  *
967  * @param string switchButtonClass                      切り替えボタンのクラス
968  * @return なし
969  */
970 function m3SetupWidgetTool(switchButtonClass)
971 {
972         $('.' + switchButtonClass).each(function ()
973         {
974                 // Settings
975                 var $widget = $(this);
976                 var $button = $widget.find('button');
977                 var $checkbox = $widget.find('input:checkbox');
978                 var color = $button.data('color'),
979                         settings = {
980                                 on: {
981                                         icon: 'glyphicon glyphicon-check'
982                                 },
983                                 off: {
984                                         icon: 'glyphicon glyphicon-unchecked'
985                                 }
986                         };
987
988                 // Event Handlers
989                 $button.on('click', function ()
990                 {
991                         // チェックボックスの状態を変更し、ボタンを再描画
992                         $checkbox.prop('checked', !$checkbox.is(':checked'));
993 //                      $checkbox.triggerHandler('change');
994                         updateButton();
995                         
996                         // ウィジェットツールの表示制御
997                         updateWidgetTool();
998                 });
999                 $checkbox.on('change', function ()
1000                 {
1001                         updateButton();
1002                 });
1003
1004                 // ボタン更新
1005                 function updateButton()
1006                 {
1007                         var isChecked = $checkbox.is(':checked');
1008
1009                         // Set the button's state
1010                         $button.data('state', (isChecked) ? "on" : "off");
1011
1012                         // Set the button's icon
1013                         $button.find('.state-icon').removeClass().addClass('state-icon ' + settings[$button.data('state')].icon);
1014
1015                         // Update the button's color
1016                         if (isChecked){
1017                                 $button.removeClass('btn-default').addClass('btn-' + color + ' active');
1018                         } else {
1019                                 $button.removeClass('btn-' + color + ' active').addClass('btn-default');
1020                         }
1021                 }
1022
1023                 // ウィジェットツールの表示制御
1024                 function updateWidgetTool()
1025                 {
1026                         var isChecked = $checkbox.is(':checked');
1027                         if (isChecked){
1028                                 _m3ShowWidgetTool = true;               // ウィジェットツールを表示するかどうか
1029                                 
1030                                 // クッキーに状態を保存
1031                                 $.cookie('M3WIDGETTOOL', 'on', { expires: 30 });
1032                         } else {
1033                                 _m3ShowWidgetTool = false;              // ウィジェットツールを表示するかどうか
1034                                 
1035                                 // クッキーに状態を保存
1036                                 $.cookie('M3WIDGETTOOL', 'off', { expires: 30 });
1037                         }
1038                 }
1039                 
1040                 // Initialization
1041                 function init(){
1042                         // ボタン初期化
1043                         var status = $.cookie('M3WIDGETTOOL');
1044                         if (status == "undefined") status = 'on';               // 初期値設定
1045                         if (status == 'on'){
1046                                 $checkbox.prop('checked', true);
1047                         } else {
1048                                 $checkbox.prop('checked', false);
1049                         }
1050                         updateWidgetTool();
1051                         
1052                         // ボタン表示
1053                         updateButton();
1054
1055                         // Inject the icon if applicable
1056                         if ($button.find('.state-icon').length == 0){
1057                                 $button.prepend('<i class="state-icon ' + settings[$button.data('state')].icon + '"></i> ');
1058                         }
1059                 }
1060                 init();
1061         });
1062 }
1063 /**
1064  * 拡張表示機能を作成
1065  *
1066  * @param string showButtonId           表示ボタンのタグID
1067  * @param string hideButtonId           非表示ボタンのタグID
1068  * @param string optionAreaClass        表示制御する領域のクラス
1069  * @param bool isShow                           拡張領域の初期状態(true=表示、false=非表示)
1070  * @return なし
1071  */
1072 function m3CreateOptionButton(showButtonId, hideButtonId, optionAreaClass, isShow)
1073 {
1074         // オプション入力制御
1075         if (isShow){
1076                 $('.' + optionAreaClass).slideDown(300);
1077                 $('#' + showButtonId).css({'display':'none'});
1078                 $('#' + hideButtonId).css({'display':'block'});
1079         } else {
1080                 $('.' + optionAreaClass).slideUp(300);
1081                 $('#' + showButtonId).css({'display':'block'});
1082                 $('#' + hideButtonId).css({'display':'none'});
1083         }
1084         
1085         $('#' + showButtonId).click(function(){
1086                 $('.' + optionAreaClass).slideDown(300);
1087                 $('#' + showButtonId).css({'display':'none'});
1088                 $('#' + hideButtonId).css({'display':'block'});
1089                 
1090                 // 画面サイズ調整
1091                 m3AdjustParentWindow();
1092                 return false;
1093         });
1094         $('#' + hideButtonId).click(function(){
1095                 $('.' + optionAreaClass).slideUp(300);
1096                 $('#' + showButtonId).css({'display':'block'});
1097                 $('#' + hideButtonId).css({'display':'none'});
1098                 
1099                 // 画面サイズ調整
1100                 m3AdjustParentWindow();
1101                 return false;
1102         });
1103 }
1104 /**
1105  * 管理画面初期処理
1106  *
1107  * @return なし
1108  */
1109 $(function(){
1110         //** jQuery Scroll to Top Control script- (c) Dynamic Drive DHTML code library: http://www.dynamicdrive.com.
1111         //** Available/ usage terms at http://www.dynamicdrive.com (March 30th, 09')
1112         //** v1.1 (April 7th, 09'):
1113         //** 1) Adds ability to scroll to an absolute position (from top of page) or specific element on the page instead.
1114         //** 2) Fixes scroll animation not working in Opera. 
1115         var scrolltotop = {
1116                 //startline: Integer. Number of pixels from top of doc scrollbar is scrolled before showing control
1117                 //scrollto: Keyword (Integer, or "Scroll_to_Element_ID"). How far to scroll document up when control is clicked on (0=top).
1118                 setting: {startline:100, scrollto: 0, scrollduration:1000, fadeduration:[500, 100]},
1119                 controlHTML: '<img src="' + M3_ROOT_URL + '/images/system/gotop48.png" style="width:48px; height:48px" />', //HTML for control, which is auto wrapped in DIV w/ ID="topcontrol"
1120                 controlattrs: {offsetx:5, offsety:5}, //offset of control relative to right/ bottom of window corner
1121                 anchorkeyword: '#top', //Enter href value of HTML anchors on the page that should also act as "Scroll Up" links
1122
1123                 state: {isvisible:false, shouldvisible:false},
1124
1125                 scrollup:function(){
1126                         if (!this.cssfixedsupport) //if control is positioned using JavaScript
1127                                 this.$control.css({ opacity:0 }); //hide control immediately after clicking it
1128                         var dest = isNaN(this.setting.scrollto) ? this.setting.scrollto : parseInt(this.setting.scrollto);
1129                         if (typeof dest == "string" && $('#'+dest).length == 1) //check element set by string exists
1130                                 dest=$('#'+dest).offset().top;
1131                         else
1132                                 dest=0;
1133                         this.$body.animate({ scrollTop: dest }, this.setting.scrollduration);
1134                 },
1135
1136                 keepfixed:function(){
1137                         var $window=$(window);
1138                         var controlx=$window.scrollLeft() + $window.width() - this.$control.width() - this.controlattrs.offsetx;
1139                         var controly=$window.scrollTop() + $window.height() - this.$control.height() - this.controlattrs.offsety;
1140                         this.$control.css({ left:controlx+'px', top:controly+'px' });
1141                 },
1142
1143                 togglecontrol:function(){
1144                         var scrolltop = $(window).scrollTop();
1145                         if (!this.cssfixedsupport) this.keepfixed();
1146                         this.state.shouldvisible = (scrolltop >= this.setting.startline) ? true : false;
1147                         if (this.state.shouldvisible && !this.state.isvisible){
1148                                 this.$control.stop().animate({ opacity:1 }, this.setting.fadeduration[0]);
1149                                 this.state.isvisible = true;
1150                         }
1151                         else if (this.state.shouldvisible == false && this.state.isvisible){
1152                                 this.$control.stop().animate({ opacity:0 }, this.setting.fadeduration[1]);
1153                                 this.state.isvisible = false;
1154                         }
1155                 },
1156         
1157                 init:function(){
1158                         $(document).ready(function($){
1159                                 var mainobj = scrolltotop;
1160                                 var iebrws = document.all;
1161                                 mainobj.cssfixedsupport = !iebrws || iebrws && document.compatMode == "CSS1Compat" && window.XMLHttpRequest; //not IE or IE7+ browsers in standards mode
1162                                 mainobj.$body = (window.opera) ? (document.compatMode == "CSS1Compat" ? $('html') : $('body')) : $('html,body');
1163                                 mainobj.$control = $('<div id="topcontrol">' + mainobj.controlHTML + '</div>')
1164                                         .css({ position:mainobj.cssfixedsupport ? 'fixed' : 'absolute', bottom:mainobj.controlattrs.offsety, right:mainobj.controlattrs.offsetx, opacity:0, cursor:'pointer' })
1165                                         .attr({ title:'先頭へスクロール' })
1166                                         .click(function(){ mainobj.scrollup(); return false; })
1167                                         .appendTo('body');
1168                                 if (document.all && !window.XMLHttpRequest && mainobj.$control.text() != '') //loose check for IE6 and below, plus whether control contains any text
1169                                         mainobj.$control.css({ width:mainobj.$control.width() }); //IE6- seems to require an explicit width on a DIV containing text
1170                                 mainobj.togglecontrol();
1171                                 $('a[href="' + mainobj.anchorkeyword + '"]').click(function(){
1172                                         mainobj.scrollup();
1173                                         return false;
1174                                 });
1175                                 $(window).bind('scroll resize', function(e){
1176                                         mainobj.togglecontrol();
1177                                 });
1178                         });
1179                 }
1180         }
1181         scrolltotop.init();
1182         
1183         // 管理画面用部品
1184         m3LoadOptionUI();
1185         
1186         // 最後にヘルプ作成
1187         $(window).load( function(){ m3SetHelp(); });
1188 });