diff --git a/app/controller/admin/Client.php b/app/controller/admin/Client.php index 9ea5a1b1..f33367f2 100644 --- a/app/controller/admin/Client.php +++ b/app/controller/admin/Client.php @@ -23,9 +23,9 @@ class Client extends Admin{ 'query' => $this->request->param() )); - $data = $res->toArray(); + $data['list'] = $res; $data['page'] = $res->render(); - $this->data = $data; + $this->data['data'] = $data; return $this->data; } diff --git a/app/controller/admin/Config.php b/app/controller/admin/Config.php index ca3413af..f2e9057e 100644 --- a/app/controller/admin/Config.php +++ b/app/controller/admin/Config.php @@ -52,7 +52,16 @@ class Config extends Admin { */ public function group(ConfigModel $config) { if ($this->request->isAjax()) { - $this->data['code'] = 1; + $data = $this->request->param(); + $result = $config->updateConfig($data); + + if (false !== $result) { + $this->data['code'] = 0; + $this->data['msg'] = "更新成功!"; + }else{ + $this->data['code'] = 1; + $this->data['msg'] = $config->error; + } return $this->data; } else { $id = $this->request->param('id', 1); diff --git a/app/model/Config.php b/app/model/Config.php index 601dbb02..7e546c96 100644 --- a/app/model/Config.php +++ b/app/model/Config.php @@ -9,35 +9,35 @@ namespace app\model; -use think\Model; use think\facade\Cache; +use think\Model; /** -* 设置模型 -*/ -class Config extends Model{ - + * 设置模型 + */ +class Config extends Model { + protected $type = array( - 'id' => 'integer', + 'id' => 'integer', ); - protected $auto = array('name', 'update_time', 'status'=>1); + protected $auto = array('name', 'update_time', 'status' => 1); protected $insert = array('create_time'); - protected function setNameAttr($value){ - return strtolower($value); - } + protected function setNameAttr($value) { + return strtolower($value); + } - protected function getTypeTextAttr($value, $data){ - $config = Cache::get('system_config'); - $type = $config['config_type_list']; - $type_text = explode(',', $type[$data['type']]); - return $type_text[0]; - } + protected function getTypeTextAttr($value, $data) { + $config = Cache::get('system_config'); + $type = $config['config_type_list']; + $type_text = explode(',', $type[$data['type']]); + return $type_text[0]; + } - public function lists(){ - $map = array('status' => 1); - $res = $this->where($map)->field('type,name,value')->select(); + public function lists() { + $map = array('status' => 1); + $res = $this->where($map)->field('type,name,value')->select(); $config = array(); foreach ($res->toArray() as $value) { @@ -46,54 +46,66 @@ class Config extends Model{ return $config; } + public function updateConfig($data) { + if (empty($data['config'])) { + $this->error = "无更新"; + return false; + } + foreach ($data['config'] as $key => $value) { + self::update(['value' => $value], ['name' => $key], ['value']); + } + Cache::set('system_config', null); + return true; + } + /** * 根据配置类型解析配置 * @param integer $type 配置类型 * @param string $value 配置值 * @author 麦当苗儿 */ - private function parse($type, $value){ + private function parse($type, $value) { switch ($type) { - case 'textarea': //解析数组 + case 'textarea': //解析数组 $array = preg_split('/[,;\r\n]+/', trim($value, ",;\r\n")); - if(strpos($value,':')){ - $value = array(); + if (strpos($value, ':')) { + $value = array(); foreach ($array as $val) { $list = explode(':', $val); - if(isset($list[2])){ - $value[$list[0]] = $list[1].','.$list[2]; - }else{ - $value[$list[0]] = $list[1]; + if (isset($list[2])) { + $value[$list[0]] = $list[1] . ',' . $list[2]; + } else { + $value[$list[0]] = $list[1]; } } - }else{ - $value = $array; + } else { + $value = $array; } break; } return $value; } - public function getThemesList(){ - $files = array(); - $files['pc'] = $this->getList('pc'); + public function getThemesList() { + $files = array(); + $files['pc'] = $this->getList('pc'); $files['mobile'] = $this->getList('mobile'); return $files; } - protected function getList($type){ + protected function getList($type) { $path = './template/'; - $file = opendir($path); + $file = opendir($path); while (false !== ($filename = readdir($file))) { if (!in_array($filename, array('.', '..'))) { $files = $path . $filename . '/info.php'; if (is_file($files)) { - $info = include($files); + $info = include $files; if (isset($info['type']) && $info['type'] == $type) { $info['id'] = $filename; $info['img'] = '/template/' . $filename . '/' . $info['img']; - $list[] = $info; - }else{ + $list[] = $info; + } else { continue; } } diff --git a/app/model/Content.php b/app/model/Content.php index 060665bc..1683e284 100644 --- a/app/model/Content.php +++ b/app/model/Content.php @@ -3,7 +3,8 @@ namespace app\model; use think\Model; -class Content extends Model -{ +class Content extends Model { + // 定义默认的表后缀(默认查询中文数据) + protected $suffix = ''; } \ No newline at end of file diff --git a/app/view/admin/base.html b/app/view/admin/base.html index 6c7cdc83..d35e0d3e 100644 --- a/app/view/admin/base.html +++ b/app/view/admin/base.html @@ -4,16 +4,17 @@ -SentCMS后台管理系统-{$meta['title']|default="后台首页"} +SentCMS后台管理系统-{$meta_title|default="后台首页"} + {block name="style"}{/block} -
+
+
{include file="admin/setting"} - + + + + + {block name="script"} \ No newline at end of file diff --git a/public/static/admin/css/theme_styles.css b/public/static/admin/css/theme_styles.css index 2ba83c9c..8fac632d 100644 --- a/public/static/admin/css/theme_styles.css +++ b/public/static/admin/css/theme_styles.css @@ -11,7 +11,7 @@ textarea{resize:none; min-height: 80px;} } }body { color:#212121; - background:url("../../images/whitey.jpg") repeat scroll 0 0 #fff; + background:url("../images/whitey.jpg") repeat scroll 0 0 #fff; background-size:220px 220px; } h1,h2,h3,h4,h5,h6 { diff --git a/public/static/admin/js/app.js b/public/static/admin/js/app.js index ef59ec9a..41be962b 100644 --- a/public/static/admin/js/app.js +++ b/public/static/admin/js/app.js @@ -1,12 +1,12 @@ $(function($) { + var storage, fail, uid; try { - uid = new Date; - (storage = window.localStorage).setItem(uid, uid); + uid = new Date; (storage = window.localStorage).setItem(uid, uid); fail = storage.getItem(uid) != uid; storage.removeItem(uid); fail && (storage = false); - } catch (e) {} + } catch(e) {} if (storage) { try { var usedSkin = localStorage.getItem('config-skin'); @@ -14,73 +14,44 @@ $(function($) { $('#skin-colors .skin-changer').removeClass('active'); $('#skin-colors .skin-changer[data-skin="' + usedSkin + '"]').addClass('active'); } - var fixedHeader = localStorage.getItem('config-fixed-header'); - if (fixedHeader == 'fixed-header') { - $('body').addClass(fixedHeader); - $('#config-fixed-header').prop('checked', true); - } - var fixedFooter = localStorage.getItem('config-fixed-footer'); - if (fixedFooter == 'fixed-footer') { - $('body').addClass(fixedFooter); - $('#config-fixed-footer').prop('checked', true); + + //固定头部、左侧菜单以及底部版权信息 + $('body').addClass('fixed-header'); + $('body').addClass('fixed-footer'); + $('body').addClass('fixed-leftmenu'); + if ($('#page-wrapper').hasClass('nav-small')) { + $('#page-wrapper').removeClass('nav-small'); } + + $('.fixed-leftmenu #col-left').nanoScroller({ + alwaysVisible: true, + iOSNativeScrolling: false, + preventPageScrolling: true, + contentClass: 'col-left-nano-content' + }); + var boxedLayout = localStorage.getItem('config-boxed-layout'); if (boxedLayout == 'boxed-layout') { $('body').addClass(boxedLayout); $('#config-boxed-layout').prop('checked', true); } - var rtlLayout = localStorage.getItem('config-rtl-layout'); - if (rtlLayout == 'rtl') { - $('body').addClass(rtlLayout); - $('#config-rtl-layout').prop('checked', true); - } - var fixedLeftmenu = localStorage.getItem('config-fixed-leftmenu'); - if (fixedLeftmenu == 'fixed-leftmenu') { - $('body').addClass(fixedLeftmenu); - $('#config-fixed-sidebar').prop('checked', true); - if ($('#page-wrapper').hasClass('nav-small')) { - $('#page-wrapper').removeClass('nav-small'); - } - $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: true, - iOSNativeScrolling: false, - preventPageScrolling: true, - contentClass: 'col-left-nano-content' - }); - } - } catch (e) { + var sidebarSamll = localStorage.getItem('config-sidebar-samll'); + if (sidebarSamll == 'sidebar-samll') { + $('#config-sidebar-samll').prop('checked', true); + $('#page-wrapper').addClass('nav-small'); + } else { + $('#page-wrapper').removeClass('nav-small'); + }; + } catch(e) { console.log(e); } } - $('#config-tool-cog').on('click', function() { + $('#config-tool-cog').on('click', + function() { $('#config-tool').toggleClass('closed'); }); - $('#config-fixed-header').on('change', function() { - var fixedHeader = ''; - if ($(this).is(':checked')) { - $('body').addClass('fixed-header'); - fixedHeader = 'fixed-header'; - } else { - $('body').removeClass('fixed-header'); - if ($('#config-fixed-sidebar').is(':checked')) { - $('#config-fixed-sidebar').prop('checked', false); - $('#config-fixed-sidebar').trigger('change'); - location.reload(); - } - } - writeStorage(storage, 'config-fixed-header', fixedHeader); - }); - $('#config-fixed-footer').on('change', function() { - var fixedFooter = ''; - if ($(this).is(':checked')) { - $('body').addClass('fixed-footer'); - fixedFooter = 'fixed-footer'; - } else { - $('body').removeClass('fixed-footer'); - } - writeStorage(storage, 'config-fixed-footer', fixedFooter); - }); - $('#config-boxed-layout').on('change', function() { + $('#config-boxed-layout').on('change', + function() { var boxedLayout = ''; if ($(this).is(':checked')) { $('body').addClass('boxed-layout'); @@ -90,59 +61,42 @@ $(function($) { } writeStorage(storage, 'config-boxed-layout', boxedLayout); }); - $('#config-rtl-layout').on('change', function() { - var rtlLayout = ''; + + $('#config-sidebar-samll').on('change',function(){ + var sidebarSamll = ''; if ($(this).is(':checked')) { - rtlLayout = 'rtl'; - } else {} - writeStorage(storage, 'config-rtl-layout', rtlLayout); - location.reload(); - }); - $('#config-fixed-sidebar').on('change', function() { - var fixedSidebar = ''; - if ($(this).is(':checked')) { - if (!$('#config-fixed-header').is(':checked')) { - $('#config-fixed-header').prop('checked', true); - $('#config-fixed-header').trigger('change'); - } - if ($('#page-wrapper').hasClass('nav-small')) { - $('#page-wrapper').removeClass('nav-small'); - } - $('body').addClass('fixed-leftmenu'); - fixedSidebar = 'fixed-leftmenu'; - $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: true, - iOSNativeScrolling: false, - preventPageScrolling: true, - contentClass: 'col-left-nano-content' - }); - writeStorage(storage, 'config-fixed-leftmenu', fixedSidebar); + $('#page-wrapper').addClass('nav-small'); + sidebarSamll = 'sidebar-samll'; + writeStorage(storage, 'config-sidebar-samll', sidebarSamll); } else { - $('body').removeClass('fixed-leftmenu'); - writeStorage(storage, 'config-fixed-leftmenu', fixedSidebar); + $('#page-wrapper').removeClass('nav-small'); + writeStorage(storage, 'config-sidebar-samll', sidebarSamll); location.reload(); } - }); + }) if (!storage) { - $('#config-fixed-header').prop('checked', false); - $('#config-fixed-footer').prop('checked', false); - $('#config-fixed-sidebar').prop('checked', false); $('#config-boxed-layout').prop('checked', false); - $('#config-rtl-layout').prop('checked', false); + $('#config-sidebar-samll').prop('checked', false); } - $('#skin-colors .skin-changer').on('click', function() { + $('#skin-colors .skin-changer').on('click', + function() { $('body').removeClassPrefix('theme-'); $('body').addClass($(this).data('skin')); $('#skin-colors .skin-changer').removeClass('active'); $(this).addClass('active'); writeStorage(storage, 'config-skin', $(this).data('skin')); }); + + + //合并自script.js setTimeout(function() { $('#content-wrapper > .row').css({ opacity: 1 }); - }, 200); - $('#sidebar-nav,#nav-col-submenu').on('click', '.dropdown-toggle', function(e) { + }, + 200); + $('#sidebar-nav,#nav-col-submenu').on('click', '.dropdown-toggle', + function(e) { e.preventDefault(); var $item = $(this).parent(); if (!$item.hasClass('open')) { @@ -156,7 +110,8 @@ $(function($) { $item.children('.submenu').slideUp('fast'); } }); - $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav .dropdown-toggle', function(e) { + $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav .dropdown-toggle', + function(e) { if ($(document).width() >= 992) { var $item = $(this).parent(); if ($('body').hasClass('fixed-leftmenu')) { @@ -173,7 +128,8 @@ $(function($) { $item.children('.submenu').slideDown('fast'); } }); - $('body').on('mouseleave', '#page-wrapper.nav-small #sidebar-nav > .nav-pills > li', function(e) { + $('body').on('mouseleave', '#page-wrapper.nav-small #sidebar-nav > .nav-pills > li', + function(e) { if ($(document).width() >= 992) { var $item = $(this); if ($item.hasClass('open')) { @@ -184,12 +140,14 @@ $(function($) { $item.removeClass('open'); } }); - $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav a:not(.dropdown-toggle)', function(e) { + $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav a:not(.dropdown-toggle)', + function(e) { if ($('body').hasClass('fixed-leftmenu')) { $('#nav-col-submenu').html(''); } }); - $('body').on('mouseleave', '#page-wrapper.nav-small #nav-col', function(e) { + $('body').on('mouseleave', '#page-wrapper.nav-small #nav-col', + function(e) { if ($('body').hasClass('fixed-leftmenu')) { $('#nav-col-submenu').html(''); } @@ -197,12 +155,10 @@ $(function($) { $('#make-small-nav').click(function(e) { $('#page-wrapper').toggleClass('nav-small'); }); - setContentBody(); $(window).smartresize(function() { if ($(document).width() <= 991) { $('#page-wrapper').removeClass('nav-small'); } - setContentBody(); }); $('.mobile-search').click(function(e) { e.preventDefault(); @@ -215,18 +171,30 @@ $(function($) { container.removeClass('active'); } }); + $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: false, + alwaysVisible: true, iOSNativeScrolling: false, preventPageScrolling: true, contentClass: 'col-left-nano-content' }); + $("[data-toggle='tooltip']").each(function(index, el) { $(el).tooltip({ placement: $(this).data("placement") || 'top' }); }); }); +function writeStorage(storage, key, value) { + if (storage) { + try { + localStorage.setItem(key, value); + } catch(e) { + console.log(e); + } + } +} + $.fn.removeClassPrefix = function(prefix) { this.each(function(i, el) { var classes = el.className.split(" ").filter(function(c) { @@ -235,14 +203,12 @@ $.fn.removeClassPrefix = function(prefix) { el.className = classes.join(" "); }); return this; -}; -(function($, sr) { +}; (function($, sr) { var debounce = function(func, threshold, execAsap) { var timeout; return function debounced() { var obj = this, - args = arguments; - + args = arguments; function delayed() { if (!execAsap) func.apply(obj, args); timeout = null; @@ -257,28 +223,46 @@ $.fn.removeClassPrefix = function(prefix) { }; })(jQuery, 'smartresize'); -function writeStorage(storage, key, value) { - if (storage) { - try { - localStorage.setItem(key, value); - } catch (e) { - console.log(e); - } +function helpIntro(){ + var placementRight = 'right'; + var placementLeft = 'left'; + + if ($('body').hasClass('rtl')) { + placementRight = 'left'; + placementLeft = 'right'; } -} -$.fn.removeClassPrefix = function(prefix) { - this.each(function(i, el) { - var classes = el.className.split(" ").filter(function(c) { - return c.lastIndexOf(prefix, 0) !== 0; - }); - el.className = classes.join(" "); - }); - return this; -}; + + // Define the tour! + var tour = { + id: "Cube-intro", + steps: [ + { + target: 'make-small-nav', + title: "设置小菜单按钮", + content: "点击小菜单可以把左侧菜单变成小菜单,增大右侧操作区域!", + placement: "bottom", + zindex: 999, + xOffset: -8 + }, + { + target: 'config-tool-options', + title: "后台配置工具", + content: "配置后台主题色彩,定制头部、左侧菜单以及底部信息", + placement: placementLeft, + zindex: 999, + fixedElement: true, + xOffset: -55 + }, + { + target: 'sidebar-nav', + title: "左侧导航区域", + content: "左侧功能导航区域。", + placement: placementRight + } + ], + showPrevButton: true + }; -function setContentBody() { - header_height = $('header#header-navbar').height(); - if ($(window).height() - header_height - 50 > $('#content-wrapper').height()) { - $('#content-wrapper').height($(window).height() - header_height - 50); - } + // Start the tour! + hopscotch.startTour(tour); } \ No newline at end of file diff --git a/public/static/admin/js/backend.js b/public/static/admin/js/backend.js index 1484b9c9..a0d70863 100644 --- a/public/static/admin/js/backend.js +++ b/public/static/admin/js/backend.js @@ -1,290 +1,20 @@ -define(['jquery', 'hopscotch'], function($, hopscotch){ +define(['jquery'], function($){ var Backend = { - - writeStorage: function(storage, key, value) { - if (storage) { - try { - localStorage.setItem(key, value); - } catch (e) { - console.log(e); - } - } - }, - - helpIntro: function(){ - var placementRight = 'right'; - var placementLeft = 'left'; + init: function(){ - if ($('body').hasClass('rtl')) { - placementRight = 'left'; - placementLeft = 'right'; - } - - // Define the tour! - var tour = { - id: "Cube-intro", - steps: [ - { - target: 'make-small-nav', - title: "设置小菜单按钮", - content: "点击小菜单可以把左侧菜单变成小菜单,增大右侧操作区域!", - placement: "bottom", - zindex: 999, - xOffset: -8 - }, - { - target: 'config-tool-options', - title: "后台配置工具", - content: "配置后台主题色彩,定制头部、左侧菜单以及底部信息", - placement: placementLeft, - zindex: 999, - fixedElement: true, - xOffset: -55 - }, - { - target: 'sidebar-nav', - title: "左侧导航区域", - content: "左侧功能导航区域。", - placement: placementRight - } - ], - showPrevButton: true - }; - - console.log(hopscotch); - // Start the tour! - hopscotch.startTour(tour); }, - - init: function () { - $('.hopscotch').on('click', function(){ - Backend.helpIntro() + setBodySize: function(){ + var height = $(window).height(); + if ($('#content-wrapper').height() < height) { + $('#content-wrapper').height($(window).height()-120); + } + $(window).resize(function(){ + Backend.setBodySize(); }) - - var storage, fail, uid; - try { - uid = new Date; - (storage = window.localStorage).setItem(uid, uid); - fail = storage.getItem(uid) != uid; - storage.removeItem(uid); - fail && (storage = false); - } catch (e) {} - if (storage) { - try { - var usedSkin = localStorage.getItem('config-skin'); - if (usedSkin != '') { - $('#skin-colors .skin-changer').removeClass('active'); - $('#skin-colors .skin-changer[data-skin="' + usedSkin + '"]').addClass('active'); - } - var fixedHeader = localStorage.getItem('config-fixed-header'); - if (fixedHeader == 'fixed-header') { - $('body').addClass(fixedHeader); - $('#config-fixed-header').prop('checked', true); - } - var fixedFooter = localStorage.getItem('config-fixed-footer'); - if (fixedFooter == 'fixed-footer') { - $('body').addClass(fixedFooter); - $('#config-fixed-footer').prop('checked', true); - } - var boxedLayout = localStorage.getItem('config-boxed-layout'); - if (boxedLayout == 'boxed-layout') { - $('body').addClass(boxedLayout); - $('#config-boxed-layout').prop('checked', true); - } - var rtlLayout = localStorage.getItem('config-rtl-layout'); - if (rtlLayout == 'rtl') { - $('body').addClass(rtlLayout); - $('#config-rtl-layout').prop('checked', true); - } - var fixedLeftmenu = localStorage.getItem('config-fixed-leftmenu'); - if (fixedLeftmenu == 'fixed-leftmenu') { - $('body').addClass(fixedLeftmenu); - $('#config-fixed-sidebar').prop('checked', true); - if ($('#page-wrapper').hasClass('nav-small')) { - $('#page-wrapper').removeClass('nav-small'); - } - $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: true, - iOSNativeScrolling: false, - preventPageScrolling: true, - contentClass: 'col-left-nano-content' - }); - } - } catch (e) { - console.log(e); - } - } - $('#config-tool-cog').on('click', function() { - $('#config-tool').toggleClass('closed'); - }); - $('#config-fixed-header').on('change', function() { - var fixedHeader = ''; - if ($(this).is(':checked')) { - $('body').addClass('fixed-header'); - fixedHeader = 'fixed-header'; - } else { - $('body').removeClass('fixed-header'); - if ($('#config-fixed-sidebar').is(':checked')) { - $('#config-fixed-sidebar').prop('checked', false); - $('#config-fixed-sidebar').trigger('change'); - location.reload(); - } - } - Backend.writeStorage(storage, 'config-fixed-header', fixedHeader); - }); - $('#config-fixed-footer').on('change', function() { - var fixedFooter = ''; - if ($(this).is(':checked')) { - $('body').addClass('fixed-footer'); - fixedFooter = 'fixed-footer'; - } else { - $('body').removeClass('fixed-footer'); - } - Backend.writeStorage(storage, 'config-fixed-footer', fixedFooter); - }); - $('#config-boxed-layout').on('change', function() { - var boxedLayout = ''; - if ($(this).is(':checked')) { - $('body').addClass('boxed-layout'); - boxedLayout = 'boxed-layout'; - } else { - $('body').removeClass('boxed-layout'); - } - Backend.writeStorage(storage, 'config-boxed-layout', boxedLayout); - }); - $('#config-rtl-layout').on('change', function() { - var rtlLayout = ''; - if ($(this).is(':checked')) { - rtlLayout = 'rtl'; - } else {} - Backend.writeStorage(storage, 'config-rtl-layout', rtlLayout); - location.reload(); - }); - $('#config-fixed-sidebar').on('change', function() { - var fixedSidebar = ''; - if ($(this).is(':checked')) { - if (!$('#config-fixed-header').is(':checked')) { - $('#config-fixed-header').prop('checked', true); - $('#config-fixed-header').trigger('change'); - } - if ($('#page-wrapper').hasClass('nav-small')) { - $('#page-wrapper').removeClass('nav-small'); - } - $('body').addClass('fixed-leftmenu'); - fixedSidebar = 'fixed-leftmenu'; - $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: true, - iOSNativeScrolling: false, - preventPageScrolling: true, - contentClass: 'col-left-nano-content' - }); - Backend.writeStorage(storage, 'config-fixed-leftmenu', fixedSidebar); - } else { - $('body').removeClass('fixed-leftmenu'); - Backend.writeStorage(storage, 'config-fixed-leftmenu', fixedSidebar); - location.reload(); - } - }); - if (!storage) { - $('#config-fixed-header').prop('checked', false); - $('#config-fixed-footer').prop('checked', false); - $('#config-fixed-sidebar').prop('checked', false); - $('#config-boxed-layout').prop('checked', false); - $('#config-rtl-layout').prop('checked', false); - } - $('#skin-colors .skin-changer').on('click', function() { - $('body').removeClassPrefix('theme-'); - $('body').addClass($(this).data('skin')); - $('#skin-colors .skin-changer').removeClass('active'); - $(this).addClass('active'); - Backend.writeStorage(storage, 'config-skin', $(this).data('skin')); - }); - setTimeout(function() { - $('#content-wrapper > .row').css({ - opacity: 1 - }); - }, 200); - $('#sidebar-nav,#nav-col-submenu').on('click', '.dropdown-toggle', function(e) { - e.preventDefault(); - var $item = $(this).parent(); - if (!$item.hasClass('open')) { - $item.parent().find('.open .submenu').slideUp('fast'); - $item.parent().find('.open').toggleClass('open'); - } - $item.toggleClass('open'); - if ($item.hasClass('open')) { - $item.children('.submenu').slideDown('fast'); - } else { - $item.children('.submenu').slideUp('fast'); - } - }); - $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav .dropdown-toggle', function(e) { - if ($(document).width() >= 992) { - var $item = $(this).parent(); - if ($('body').hasClass('fixed-leftmenu')) { - var topPosition = $item.position().top; - if ((topPosition + 4 * $(this).outerHeight()) >= $(window).height()) { - topPosition -= 6 * $(this).outerHeight(); - } - $('#nav-col-submenu').html($item.children('.submenu').clone()); - $('#nav-col-submenu > .submenu').css({ - 'top': topPosition - }); - } - $item.addClass('open'); - $item.children('.submenu').slideDown('fast'); - } - }); - $('body').on('mouseleave', '#page-wrapper.nav-small #sidebar-nav > .nav-pills > li', function(e) { - if ($(document).width() >= 992) { - var $item = $(this); - if ($item.hasClass('open')) { - $item.find('.open .submenu').slideUp('fast'); - $item.find('.open').removeClass('open'); - $item.children('.submenu').slideUp('fast'); - } - $item.removeClass('open'); - } - }); - $('body').on('mouseenter', '#page-wrapper.nav-small #sidebar-nav a:not(.dropdown-toggle)', function(e) { - if ($('body').hasClass('fixed-leftmenu')) { - $('#nav-col-submenu').html(''); - } - }); - $('body').on('mouseleave', '#page-wrapper.nav-small #nav-col', function(e) { - if ($('body').hasClass('fixed-leftmenu')) { - $('#nav-col-submenu').html(''); - } - }); - $('#make-small-nav').click(function(e) { - $('#page-wrapper').toggleClass('nav-small'); - }); - - $('.mobile-search').click(function(e) { - e.preventDefault(); - $('.mobile-search').addClass('active'); - $('.mobile-search form input.form-control').focus(); - }); - $(document).mouseup(function(e) { - var container = $('.mobile-search'); - if (!container.is(e.target) && container.has(e.target).length === 0) { - container.removeClass('active'); - } - }); - $('.fixed-leftmenu #col-left').nanoScroller({ - alwaysVisible: false, - iOSNativeScrolling: false, - preventPageScrolling: true, - contentClass: 'col-left-nano-content' - }); - $("[data-toggle='tooltip']").each(function(index, el) { - $(el).tooltip({ - placement: $(this).data("placement") || 'top' - }); - }); } } + Backend.setBodySize(); Backend.init(); //默认初始化执行的代码 return Backend; }) \ No newline at end of file diff --git a/public/static/admin/js/main.js b/public/static/admin/js/main.js index 7212f7fd..64031133 100644 --- a/public/static/admin/js/main.js +++ b/public/static/admin/js/main.js @@ -1,5 +1,5 @@ require.config({ - urlArgs: "v=" + '4.0.0', + urlArgs: "v=" + Date(), packages: [ { name: 'moment', @@ -19,7 +19,6 @@ require.config({ 'echarts': 'echarts.min', 'echarts-theme': 'echarts-theme', - "vue":'/static/libs/vue/dist/vue.min', "jquery":'/static/libs/jquery/jquery.min', "nanoscroller":"/static/libs/nanoscroller/jquery.nanoscroller.min", "slimscroll":"/static/js/jquery.slimscroll.min", @@ -63,59 +62,59 @@ require.config({ deps: ['jquery'], exports: '$.fn.extend' }, - 'bootstrap': ['jquery'], - 'bootstrap-table': { - deps: [ - 'bootstrap', -// 'css!/static/libs/bootstrap-table/dist/bootstrap-table.min.css' - ], - exports: '$.fn.bootstrapTable' - }, - 'bootstrap-table-lang': { - deps: ['bootstrap-table'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'bootstrap-table-export': { - deps: ['bootstrap-table', 'tableexport'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'bootstrap-table-mobile': { - deps: ['bootstrap-table'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'bootstrap-table-advancedsearch': { - deps: ['bootstrap-table'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'bootstrap-table-commonsearch': { - deps: ['bootstrap-table'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'bootstrap-table-template': { - deps: ['bootstrap-table', 'template'], - exports: '$.fn.bootstrapTable.defaults' - }, - 'tableexport': { - deps: ['jquery'], - exports: '$.fn.extend' - }, - 'bootstrap-datetimepicker': [ - 'moment/locale/zh-cn.js', -// 'css!/static/libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css', - ], -// 'bootstrap-select': ['css!/static/libs/bootstrap-select/dist/css/bootstrap-select.min.css',], - 'bootstrap-select-lang': ['bootstrap-select'], -// 'toastr': ['css!/static/libs/toastr/toastr.min.css'], - 'jstree': ['css!/static/libs/jstree/dist/themes/default/style.css',], - 'plupload': { - deps: ['/static/libs/plupload/js/moxie.min.js'], - exports: "plupload" - }, -// 'layer': ['css!/static/libs/fastadmin-layer/dist/theme/default/layer.css'], -// 'validator-core': ['css!/static/libs/nice-validator/dist/jquery.validator.css'], - 'validator-lang': ['validator-core'], -// 'selectpage': ['css!/static/libs/fastadmin-selectpage/selectpage.css'], - 'citypicker': ['citypicker-data', 'css!/static/libs/fastadmin-citypicker/dist/css/city-picker.css'] + 'bootstrap': ['jquery'], + 'bootstrap-table': { + deps: [ + 'bootstrap', + 'css!/static/libs/bootstrap-table/dist/bootstrap-table.min.css' + ], + exports: '$.fn.bootstrapTable' + }, + 'bootstrap-table-lang': { + deps: ['bootstrap-table'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'bootstrap-table-export': { + deps: ['bootstrap-table', 'tableexport'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'bootstrap-table-mobile': { + deps: ['bootstrap-table'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'bootstrap-table-advancedsearch': { + deps: ['bootstrap-table'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'bootstrap-table-commonsearch': { + deps: ['bootstrap-table'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'bootstrap-table-template': { + deps: ['bootstrap-table', 'template'], + exports: '$.fn.bootstrapTable.defaults' + }, + 'tableexport': { + deps: ['jquery'], + exports: '$.fn.extend' + }, + 'bootstrap-datetimepicker': [ + 'moment/locale/zh-cn.js', + 'css!/static/libs/eonasdan-bootstrap-datetimepicker/build/css/bootstrap-datetimepicker.min.css', + ], + 'bootstrap-select': ['css!/static/libs/bootstrap-select/dist/css/bootstrap-select.min.css',], + 'bootstrap-select-lang': ['bootstrap-select'], + 'toastr': ['css!/static/libs/toastr/toastr.min.css'], + 'jstree': ['css!/static/libs/jstree/dist/themes/default/style.css',], + 'plupload': { + deps: ['/static/libs/plupload/js/moxie.min.js'], + exports: "plupload" + }, + 'layer': ['css!/static/libs/fastadmin-layer/dist/theme/default/layer.css'], + 'validator-core': ['css!/static/libs/nice-validator/dist/jquery.validator.css'], + 'validator-lang': ['validator-core'], + 'selectpage': ['css!/static/libs/fastadmin-selectpage/selectpage.css'], + 'citypicker': ['citypicker-data', 'css!/static/libs/fastadmin-citypicker/dist/css/city-picker.css'], }, baseUrl:"/static/js/", map: { @@ -128,7 +127,7 @@ require.config({ charset: 'utf-8' // 文件编码 }); -require(['jquery', 'nanoscroller', 'bootstrap', 'sent'], function($, undefined, undefined, Sent){ +require(['jquery', 'sent'], function($, Sent){ $(function($) { require(['backend', 'backend-init', 'addons'], function (Backend, undefined, Addons) { // 避免目录冲突 @@ -150,23 +149,5 @@ require(['jquery', 'nanoscroller', 'bootstrap', 'sent'], function($, undefined, }) } }) - - $.fn.removeClassPrefix = function(prefix) { - this.each(function(i, el) { - var classes = el.className.split(" ").filter(function(c) { - return c.lastIndexOf(prefix, 0) !== 0; - }); - el.className = classes.join(" "); - }); - return this; - }; - }); - - function setContentBody() { - header_height = $('header#header-navbar').height(); - if ($(window).height() - header_height - 50 > $('#content-wrapper').height()) { - $('#content-wrapper').height($(window).height() - header_height - 50); - } - } - + }) }) \ No newline at end of file diff --git a/public/static/admin/js/module/index.js b/public/static/admin/js/module/index.js index 0bc55705..a4e4e79c 100644 --- a/public/static/admin/js/module/index.js +++ b/public/static/admin/js/module/index.js @@ -1,7 +1,15 @@ -define(['vue'],function(Vue){ +define(['vue', 'iview'],function(Vue, iView){ var controller = { clear: function(){ - var vm = new Vue(); + var vm = new Vue({ + el:'.vue-main', + data:{ + value:'' + }, + created(){ + this.$Message.success('这是一条成功的提示'); + } + }); } } diff --git a/public/static/js/require-form.js b/public/static/js/require-form.js new file mode 100644 index 00000000..1da12ce3 --- /dev/null +++ b/public/static/js/require-form.js @@ -0,0 +1,179 @@ +define(['jquery', 'sent', 'validator'], function($, Sent, Validator){ + var Form = { + events: { + validator: function (form, success, error, submit) { + if (!form.is("form")){ + return; + } + //绑定表单事件 + form.validator($.extend({ + valid: function (ret) { + var that = this, submitBtn = $("button.submit-btn", form); + that.holdSubmit(true); + submitBtn.addClass("disabled"); + //验证通过提交表单 + var submitResult = Form.api.submit($(ret), function (data, ret) { + that.holdSubmit(false); + submitBtn.removeClass("disabled"); + if (false === $(this).triggerHandler("success.form", [data, ret])) { + return false; + } + if (typeof success === 'function') { + if (false === success.call($(this), data, ret)) { + return false; + } + } + //提示及关闭当前窗口 + var msg = ret.hasOwnProperty("msg") && ret.msg !== "" ? ret.msg : 'Operation completed'; + parent.Toastr.success(msg); + parent.$(".btn-refresh").trigger("click"); + var index = parent.Layer.getFrameIndex(window.name); + parent.Layer.close(index); + return false; + }, function(data, ret){ + that.holdSubmit(false); + if (false === $(this).triggerHandler("error.form", [data, ret])) { + return false; + } + submitBtn.removeClass("disabled"); + if (typeof error === 'function') { + if (false === error.call($(this), data, ret)) { + return false; + } + } + }, submit) + //如果提交失败则释放锁定 + if (!submitResult) { + that.holdSubmit(false); + submitBtn.removeClass("disabled"); + } + return false; + } + }, form.data("validator-options") || {})) + + //移除提交按钮的disabled类 + $(".layer-footer [type=submit],.fixed-footer [type=submit],.normal-footer [type=submit]", form).removeClass("disabled"); + }, + cxselect: function (form) { + //绑定cxselect元素事件 + if ($("[data-toggle='cxselect']", form).size() > 0) { + require(['cxselect'], function () { + $.cxSelect.defaults.jsonName = 'name'; + $.cxSelect.defaults.jsonValue = 'value'; + $.cxSelect.defaults.jsonSpace = 'data'; + $("[data-toggle='cxselect']", form).cxSelect(); + }); + } + }, + switcher: function (form) { + form.on("click", "[data-toggle='switcher']", function () { + if ($(this).hasClass("disabled")) { + return false; + } + var input = $(this).prev("input"); + input = $(this).data("input-id") ? $("#" + $(this).data("input-id")) : input; + if (input.size() > 0) { + var yes = $(this).data("yes"); + var no = $(this).data("no"); + if (input.val() == yes) { + input.val(no); + $("i", this).addClass("fa-flip-horizontal text-gray"); + } else { + input.val(yes); + $("i", this).removeClass("fa-flip-horizontal text-gray"); + } + input.trigger('change'); + } + return false; + }); + }, + bindevent: function (form) { + + }, + }, + api:{ + submit: function (form, success, error, submit) { + if (form.size() === 0) { + Toastr.error("表单未初始化完成,无法提交"); + return false; + } + if (typeof submit === 'function') { + if (false === submit.call(form, success, error)) { + return false; + } + } + var type = form.attr("method") ? form.attr("method").toUpperCase() : 'GET'; + type = type && (type === 'GET' || type === 'POST') ? type : 'GET'; + url = form.attr("action"); + url = url ? url : location.href; + //修复当存在多选项元素时提交的BUG + var params = {}; + var multipleList = $("[name$='[]']", form); + if (multipleList.size() > 0) { + var postFields = form.serializeArray().map(function (obj) { + return $(obj).prop("name"); + }); + $.each(multipleList, function (i, j) { + if (postFields.indexOf($(this).prop("name")) < 0) { + params[$(this).prop("name")] = ''; + } + }); + } + //调用Ajax请求方法 + Sent.api.ajax({ + type: type, + url: url, + data: form.serialize() + (Object.keys(params).length > 0 ? '&' + $.param(params) : ''), + dataType: 'json', + complete: function (xhr) { + var token = xhr.getResponseHeader('__token__'); + if (token) { + $("input[name='__token__']", form).val(token); + } + } + }, function (data, ret) { + $('.form-group', form).removeClass('has-feedback has-success has-error'); + if (data && typeof data === 'object') { + //刷新客户端token + if (typeof data.token !== 'undefined') { + $("input[name='__token__']", form).val(data.token); + } + //调用客户端事件 + if (typeof data.callback !== 'undefined' && typeof data.callback === 'function') { + data.callback.call(form, data); + } + } + if (typeof success === 'function') { + if (false === success.call(form, data, ret)) { + return false; + } + } + }, function (data, ret) { + if (data && typeof data === 'object' && typeof data.token !== 'undefined') { + $("input[name='__token__']", form).val(data.token); + } + if (typeof error === 'function') { + if (false === error.call(form, data, ret)) { + return false; + } + } + }); + return true; + }, + bindevent: function (form, success, error, submit) { + form = typeof form === 'object' ? form : $(form); + + var events = Form.events; + + events.bindevent(form); + + events.validator(form, success, error, submit); + + events.cxselect(form); + events.switcher(form); + } + } + } + + return Form; +}) \ No newline at end of file diff --git a/public/static/js/sent.js b/public/static/js/sent.js index 76339780..3edf0dfe 100644 --- a/public/static/js/sent.js +++ b/public/static/js/sent.js @@ -1,10 +1,268 @@ -define(['jquery'], function($){ +define(['jquery', 'toastr','layer'], function($, Toastr, Layer){ var Sent = { + config: { + //toastr默认配置 + toastr: { + "closeButton": true, + "debug": false, + "newestOnTop": false, + "progressBar": false, + "positionClass": "toast-top-center", + "preventDuplicates": false, + "onclick": null, + "showDuration": "300", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": "fadeIn", + "hideMethod": "fadeOut" + } + }, init: function () { - + + //公共代码 + //配置Toastr的参数 + Toastr.options = Sent.config.toastr; + }, + + events: { + //请求成功的回调 + onAjaxSuccess: function (ret, onAjaxSuccess) { + var data = typeof ret.data !== 'undefined' ? ret.data : null; + var msg = typeof ret.msg !== 'undefined' && ret.msg ? ret.msg : 'Operation completed'; + + if (typeof onAjaxSuccess === 'function') { + var result = onAjaxSuccess.call(this, data, ret); + if (result === false) + return; + } + Toastr.success(msg); + }, + //请求错误的回调 + onAjaxError: function (ret, onAjaxError) { + var data = typeof ret.data !== 'undefined' ? ret.data : null; + if (typeof onAjaxError === 'function') { + var result = onAjaxError.call(this, data, ret); + if (result === false) { + return; + } + } + Toastr.error(ret.msg); + }, + //服务器响应数据后 + onAjaxResponse: function (response) { + try { + var ret = typeof response === 'object' ? response : JSON.parse(response); + if (!ret.hasOwnProperty('code')) { + $.extend(ret, {code: -2, msg: response, data: null}); + } + } catch (e) { + var ret = {code: -1, msg: e.message, data: null}; + } + return ret; + } + }, + + api: { + //发送Ajax请求 + ajax: function (options, success, error) { + options = typeof options === 'string' ? {url: options} : options; + var index; + if (typeof options.loading === 'undefined' || options.loading) { + index = Layer.load(options.loading || 0); + } + options = $.extend({ + type: "POST", + dataType: "json", + success: function (ret) { + index && Layer.close(index); + ret = Sent.events.onAjaxResponse(ret); + if (ret.code === 0) { + Sent.events.onAjaxSuccess(ret, success); + } else { + Sent.events.onAjaxError(ret, error); + } + }, + error: function (xhr) { + index && Layer.close(index); + var ret = {code: xhr.status, msg: xhr.statusText, data: null}; + Sent.events.onAjaxError(ret, error); + } + }, options); + $.ajax(options); + }, + //查询Url参数 + query: function (name, url) { + if (!url) { + url = window.location.href; + } + name = name.replace(/[\[\]]/g, "\\$&"); + var regex = new RegExp("[?&/]" + name + "([=/]([^&#/?]*)|&|#|$)"), + results = regex.exec(url); + if (!results) + return null; + if (!results[2]) + return ''; + return decodeURIComponent(results[2].replace(/\+/g, " ")); + }, + //打开一个弹出窗口 + open: function (url, title, options) { + title = options && options.title ? options.title : (title ? title : ""); + //url = Sent.api.fixurl(url); + url = url + (url.indexOf("?") > -1 ? "&" : "?") + "dialog=1"; + var area = Sent.config.openArea != undefined ? Sent.config.openArea : [$(window).width() > 800 ? '800px' : '95%', $(window).height() > 600 ? '600px' : '95%']; + options = $.extend({ + type: 2, + title: title, + shadeClose: true, + shade: false, + maxmin: true, + moveOut: true, + area: area, + content: url, + zIndex: Layer.zIndex, + success: function (layero, index) { + var that = this; + //存储callback事件 + $(layero).data("callback", that.callback); + //$(layero).removeClass("layui-layer-border"); + Layer.setTop(layero); + try { + var frame = Layer.getChildFrame('html', index); + var layerfooter = frame.find(".layer-footer"); + Sent.api.layerfooter(layero, index, that); + + //绑定事件 + if (layerfooter.size() > 0) { + // 监听窗口内的元素及属性变化 + // Firefox和Chrome早期版本中带有前缀 + var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; + if (MutationObserver) { + // 选择目标节点 + var target = layerfooter[0]; + // 创建观察者对象 + var observer = new MutationObserver(function (mutations) { + Sent.api.layerfooter(layero, index, that); + mutations.forEach(function (mutation) { + }); + }); + // 配置观察选项: + var config = {attributes: true, childList: true, characterData: true, subtree: true} + // 传入目标节点和观察选项 + observer.observe(target, config); + // 随后,你还可以停止观察 + // observer.disconnect(); + } + } + } catch (e) { + + } + if ($(layero).height() > $(window).height()) { + //当弹出窗口大于浏览器可视高度时,重定位 + Layer.style(index, { + top: 0, + height: $(window).height() + }); + } + } + }, options ? options : {}); + if ($(window).width() < 480 || (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream && top.$(".tab-pane.active").size() > 0)) { + options.area = [top.$(".tab-pane.active").width() + "px", top.$(".tab-pane.active").height() + "px"]; + options.offset = [top.$(".tab-pane.active").scrollTop() + "px", "0px"]; + } + return Layer.open(options); + }, + //关闭窗口并回传数据 + close: function (data) { + var index = parent.Layer.getFrameIndex(window.name); + var callback = parent.$("#layui-layer" + index).data("callback"); + //再执行关闭 + parent.Layer.close(index); + //再调用回传函数 + if (typeof callback === 'function') { + callback.call(undefined, data); + } + }, + layerfooter: function (layero, index, that) { + var frame = Layer.getChildFrame('html', index); + var layerfooter = frame.find(".layer-footer"); + if (layerfooter.size() > 0) { + $(".layui-layer-footer", layero).remove(); + var footer = $("
").addClass('layui-layer-btn layui-layer-footer'); + footer.html(layerfooter.html()); + if ($(".row", footer).size() === 0) { + $(">", footer).wrapAll("
"); + } + footer.insertAfter(layero.find('.layui-layer-content')); + //绑定事件 + footer.on("click", ".btn", function () { + if ($(this).hasClass("disabled") || $(this).parent().hasClass("disabled")) { + return; + } + var index = footer.find('.btn').index(this); + $(".btn:eq(" + index + ")", layerfooter).trigger("click"); + }); + + var titHeight = layero.find('.layui-layer-title').outerHeight() || 0; + var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0; + //重设iframe高度 + $("iframe", layero).height(layero.height() - titHeight - btnHeight); + } + //修复iOS下弹出窗口的高度和iOS下iframe无法滚动的BUG + if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) { + var titHeight = layero.find('.layui-layer-title').outerHeight() || 0; + var btnHeight = layero.find('.layui-layer-btn').outerHeight() || 0; + $("iframe", layero).parent().css("height", layero.height() - titHeight - btnHeight); + $("iframe", layero).css("height", "100%"); + } + }, + success: function (options, callback) { + var type = typeof options === 'function'; + if (type) { + callback = options; + } + return Layer.msg('Operation completed', $.extend({ + offset: 0, icon: 1 + }, type ? {} : options), callback); + }, + error: function (options, callback) { + var type = typeof options === 'function'; + if (type) { + callback = options; + } + return Layer.msg('Operation failed', $.extend({ + offset: 0, icon: 2 + }, type ? {} : options), callback); + }, + msg: function (message, url) { + var callback = typeof url === 'function' ? url : function () { + if (typeof url !== 'undefined' && url) { + location.href = url; + } + }; + Layer.msg(message, { + time: 2000 + }, callback); + }, + toastr: Toastr, + layer: Layer } + }; + + if($('form').length > 0){ + require(['form'], function(Form){ + Form.api.bindevent($("form")); + }) } + //将Layer暴露到全局中去 + window.Layer = Layer; + //将Toastr暴露到全局中去 + window.Toastr = Toastr; + //将Fast渲染至全局 + window.Sent = Sent; Sent.init(); //默认初始化执行的代码 return Sent; diff --git a/public/static/libs/hopscotch/hopscotch.css b/public/static/libs/hopscotch/hopscotch.css new file mode 100644 index 00000000..fb542a1f --- /dev/null +++ b/public/static/libs/hopscotch/hopscotch.css @@ -0,0 +1 @@ +.animated{-webkit-animation-fill-mode:both;-moz-animation-fill-mode:both;-ms-animation-fill-mode:both;-o-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:1s;-moz-animation-duration:1s;-ms-animation-duration:1s;-o-animation-duration:1s;animation-duration:1s;}@-webkit-keyframes fadeInUp{0%{opacity:0;-webkit-transform:translateY(20px);}100%{opacity:1;-webkit-transform:translateY(0);}}@-moz-keyframes fadeInUp{0%{opacity:0;-moz-transform:translateY(20px);}100%{opacity:1;-moz-transform:translateY(0);}}@-o-keyframes fadeInUp{0%{opacity:0;-o-transform:translateY(20px);}100%{opacity:1;-o-transform:translateY(0);}}@keyframes fadeInUp{0%{opacity:0;transform:translateY(20px);}100%{opacity:1;transform:translateY(0);}}.fade-in-up{-webkit-animation-name:fadeInUp;-moz-animation-name:fadeInUp;-o-animation-name:fadeInUp;animation-name:fadeInUp;}@-webkit-keyframes fadeInDown{0%{opacity:0;-webkit-transform:translateY(-20px);}100%{opacity:1;-webkit-transform:translateY(0);}}@-moz-keyframes fadeInDown{0%{opacity:0;-moz-transform:translateY(-20px);}100%{opacity:1;-moz-transform:translateY(0);}}@-o-keyframes fadeInDown{0%{opacity:0;-ms-transform:translateY(-20px);}100%{opacity:1;-ms-transform:translateY(0);}}@keyframes fadeInDown{0%{opacity:0;transform:translateY(-20px);}100%{opacity:1;transform:translateY(0);}}.fade-in-down{-webkit-animation-name:fadeInDown;-moz-animation-name:fadeInDown;-o-animation-name:fadeInDown;animation-name:fadeInDown;}@-webkit-keyframes fadeInRight{0%{opacity:0;-webkit-transform:translateX(-20px);}100%{opacity:1;-webkit-transform:translateX(0);}}@-moz-keyframes fadeInRight{0%{opacity:0;-moz-transform:translateX(-20px);}100%{opacity:1;-moz-transform:translateX(0);}}@-o-keyframes fadeInRight{0%{opacity:0;-o-transform:translateX(-20px);}100%{opacity:1;-o-transform:translateX(0);}}@keyframes fadeInRight{0%{opacity:0;transform:translateX(-20px);}100%{opacity:1;transform:translateX(0);}}.fade-in-right{-webkit-animation-name:fadeInRight;-moz-animation-name:fadeInRight;-o-animation-name:fadeInRight;animation-name:fadeInRight;}@-webkit-keyframes fadeInLeft{0%{opacity:0;-webkit-transform:translateX(20px);}100%{opacity:1;-webkit-transform:translateX(0);}}@-moz-keyframes fadeInLeft{0%{opacity:0;-moz-transform:translateX(20px);}100%{opacity:1;-moz-transform:translateX(0);}}@-o-keyframes fadeInLeft{0%{opacity:0;-o-transform:translateX(20px);}100%{opacity:1;-o-transform:translateX(0);}}@keyframes fadeInLeft{0%{opacity:0;transform:translateX(20px);}100%{opacity:1;transform:translateX(0);}}.fade-in-left{-webkit-animation-name:fadeInLeft;-moz-animation-name:fadeInLeft;-o-animation-name:fadeInLeft;animation-name:fadeInLeft;}div.hopscotch-bubble .hopscotch-nav-button{font-weight:bold;border-width:1px;border-style:solid;cursor:pointer;margin:0;overflow:visible;text-decoration:none!important;width:auto;padding:0 10px;height:26px;line-height:24px;font-size:12px;*zoom:1;white-space:nowrap;display:-moz-inline-stack;display:inline-block;*vertical-align:auto;zoom:1;*display:inline;vertical-align:middle;-moz-border-radius:3px;-ms-border-radius:3px;-o-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;}div.hopscotch-bubble .hopscotch-nav-button:hover{*zoom:1;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.25);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.25);box-shadow:0 1px 3px rgba(0,0,0,0.25);}div.hopscotch-bubble .hopscotch-nav-button:active{-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.25) inset;-moz-box-shadow:0 1px 2px rgba(0,0,0,0.25) inset;box-shadow:0 1px 2px rgba(0,0,0,0.25) inset;}div.hopscotch-bubble .hopscotch-nav-button.next{border-color:#1b5480;color:#fff;margin:0 0 0 10px;text-shadow:0 1px 1px rgba(0,0,0,0.35);background-color:#287bbc;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#287bbc',endColorstr='#23639a');background-image:-webkit-gradient(linear,50% 0%,50% 100%,color-stop(0%,#287bbc),color-stop(100%,#23639a));background-image:-webkit-linear-gradient(top,#287bbc 0%,#23639a 100%);background-image:-moz-linear-gradient(top,#287bbc 0%,#23639a 100%);background-image:-o-linear-gradient(top,#287bbc 0%,#23639a 100%);background-image:linear-gradient(top,#287bbc 0%,#23639a 100%);}div.hopscotch-bubble .hopscotch-nav-button.next:hover{background-color:#2672ae;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#2672ae',endColorstr='#1e4f7e');background-image:-webkit-gradient(linear,50% 0%,50% 100%,color-stop(0%,#2672ae),color-stop(100%,#1e4f7e));background-image:-webkit-linear-gradient(top,#2672ae 0%,#1e4f7e 100%);background-image:-moz-linear-gradient(top,#2672ae 0%,#1e4f7e 100%);background-image:-o-linear-gradient(top,#2672ae 0%,#1e4f7e 100%);background-image:linear-gradient(top,#2672ae 0%,#1e4f7e 100%);}div.hopscotch-bubble .hopscotch-nav-button.prev{border-color:#a7a7a7;color:#444;text-shadow:0 1px 1px rgba(255,255,255,0.75);background-color:#f2f2f2;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#e9e9e9');background-image:-webkit-gradient(linear,50% 0%,50% 100%,color-stop(0%,#f2f2f2),color-stop(100%,#e9e9e9));background-image:-webkit-linear-gradient(top,#f2f2f2 0%,#e9e9e9 100%);background-image:-moz-linear-gradient(top,#f2f2f2 0%,#e9e9e9 100%);background-image:-o-linear-gradient(top,#f2f2f2 0%,#e9e9e9 100%);background-image:linear-gradient(top,#f2f2f2 0%,#e9e9e9 100%);}div.hopscotch-bubble .hopscotch-nav-button.prev:hover{background-color:#e8e8e8;filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#FFE8E8E8',endColorstr='#FFA9A9A9');background-image:-webkit-gradient(linear,50% 0%,50% 100%,color-stop(0%,#e8e8e8),color-stop(13%,#e3e3e3),color-stop(32%,#d7d7d7),color-stop(71%,#b9b9b9),color-stop(100%,#a9a9a9));background-image:-webkit-linear-gradient(top,#e8e8e8 0%,#e3e3e3 13%,#d7d7d7 32%,#b9b9b9 71%,#a9a9a9 100%);background-image:-moz-linear-gradient(top,#e8e8e8 0%,#e3e3e3 13%,#d7d7d7 32%,#b9b9b9 71%,#a9a9a9 100%);background-image:-o-linear-gradient(top,#e8e8e8 0%,#e3e3e3 13%,#d7d7d7 32%,#b9b9b9 71%,#a9a9a9 100%);background-image:linear-gradient(top,#e8e8e8 0%,#e3e3e3 13%,#d7d7d7 32%,#b9b9b9 71%,#a9a9a9 100%);}div.hopscotch-bubble{background-color:#ffffff;border:5px solid #000000;border:5px solid rgba(0,0,0,0.5);border-radius:3px;font-size:13px;position:absolute;z-index:999999;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-moz-background-clip:padding;-webkit-background-clip:padding;background-clip:padding-box;}div.hopscotch-bubble *{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;}div.hopscotch-bubble.animate{-moz-transition-property:top,left;-moz-transition-duration:1s;-moz-transition-timing-function:ease-in-out;-ms-transition-property:top,left;-ms-transition-duration:1s;-ms-transition-timing-function:ease-in-out;-o-transition-property:top,left;-o-transition-duration:1s;-o-transition-timing-function:ease-in-out;-webkit-transition-property:top,left;-webkit-transition-duration:1s;-webkit-transition-timing-function:ease-in-out;transition-property:top,left;transition-duration:1s;transition-timing-function:ease-in-out;}div.hopscotch-bubble.invisible{opacity:0;}div.hopscotch-bubble.hide,div.hopscotch-bubble .hide,div.hopscotch-bubble .hide-all{display:none;}div.hopscotch-bubble h3{font-size:16px;font-weight:600;line-height:19px;margin:-1px 15px 0 0;padding:0;border:none;}div.hopscotch-bubble .hopscotch-bubble-container{padding:15px;position:relative;text-align:left;-webkit-font-smoothing:antialiased;}div.hopscotch-bubble .hopscotch-content{font-weight:normal;line-height:1.4;margin:-5px 0 11px;padding-top:8px;}div.hopscotch-bubble .hopscotch-bubble-content{margin:0 0 0 40px;}div.hopscotch-bubble.no-number .hopscotch-bubble-content{margin:0;}div.hopscotch-bubble .hopscotch-bubble-close{color:#000;display:block;height:8px;line-height:8px;padding:4px 7px;position:absolute;right:0;text-decoration:none;top:0;width:8px;}div.hopscotch-bubble .hopscotch-bubble-close:hover{color:#3498db;}div.hopscotch-bubble .hopscotch-bubble-close.hide,div.hopscotch-bubble .hopscotch-bubble-close.hide-all{display:none;}div.hopscotch-bubble .hopscotch-bubble-number{background:#2ecc71;color:#fff;display:block;float:left;font-size:17px;font-weight:bold;line-height:30px;padding:0;text-align:center;width:30px;height:30px;-moz-border-radius:50%;-webkit-border-radius:50%;border-radius:50%;}div.hopscotch-bubble .hopscotch-bubble-arrow-container{position:absolute;width:34px;height:34px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container .hopscotch-bubble-arrow,div.hopscotch-bubble .hopscotch-bubble-arrow-container .hopscotch-bubble-arrow-border{width:0;height:0;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.up{top:-22px;left:10px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.up .hopscotch-bubble-arrow{border-bottom:17px solid #ffffff;border-left:17px solid transparent;border-right:17px solid transparent;position:relative;top:-10px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.up .hopscotch-bubble-arrow-border{border-bottom:17px solid #000000;border-bottom:17px solid rgba(0,0,0,0.5);border-left:17px solid transparent;border-right:17px solid transparent;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.down{bottom:-39px;left:10px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.down .hopscotch-bubble-arrow{border-top:17px solid #ffffff;border-left:17px solid transparent;border-right:17px solid transparent;position:relative;top:-24px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.down .hopscotch-bubble-arrow-border{border-top:17px solid #000000;border-top:17px solid rgba(0,0,0,0.5);border-left:17px solid transparent;border-right:17px solid transparent;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.left{top:10px;left:-22px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.left .hopscotch-bubble-arrow{border-bottom:17px solid transparent;border-right:17px solid #ffffff;border-top:17px solid transparent;position:relative;left:7px;top:-34px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.left .hopscotch-bubble-arrow-border{border-right:17px solid #000000;border-right:17px solid rgba(0,0,0,0.5);border-bottom:17px solid transparent;border-top:17px solid transparent;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.right{top:10px;right:-39px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.right .hopscotch-bubble-arrow{border-bottom:17px solid transparent;border-left:17px solid #ffffff;border-top:17px solid transparent;position:relative;left:-7px;top:-34px;}div.hopscotch-bubble .hopscotch-bubble-arrow-container.right .hopscotch-bubble-arrow-border{border-left:17px solid #000000;border-left:17px solid rgba(0,0,0,0.5);border-bottom:17px solid transparent;border-top:17px solid transparent;}div.hopscotch-bubble .hopscotch-actions{margin:10px 0 0;text-align:right;} \ No newline at end of file diff --git a/public/static/libs/hopscotch/hopscotch.js b/public/static/libs/hopscotch/hopscotch.js new file mode 100644 index 00000000..50c40b00 --- /dev/null +++ b/public/static/libs/hopscotch/hopscotch.js @@ -0,0 +1,179 @@ +(function(context,namespace){var Hopscotch,HopscotchBubble,HopscotchCalloutManager,HopscotchI18N,customI18N,customRenderer,customEscape,templateToUse='bubble_default',Sizzle=window.Sizzle||null,utils,callbacks,helpers,winLoadHandler,defaultOpts,winHopscotch=context[namespace],undefinedStr='undefined',waitingToStart=false,hasJquery=(typeof window.jQuery!==undefinedStr),hasSessionStorage=false,isStorageWritable=false,document=window.document;try{if(typeof window.sessionStorage!==undefinedStr){hasSessionStorage=true;sessionStorage.setItem('hopscotch.test.storage','ok');sessionStorage.removeItem('hopscotch.test.storage');isStorageWritable=true;}}catch(err){} +defaultOpts={smoothScroll:true,scrollDuration:1000,scrollTopMargin:200,showCloseButton:true,showPrevButton:false,showNextButton:true,bubbleWidth:280,bubblePadding:15,arrowWidth:20,skipIfNoElement:true,cookieName:'hopscotch.tour.state'};if(winHopscotch){return;} +if(!Array.isArray){Array.isArray=function(obj){return Object.prototype.toString.call(obj)==='[object Array]';};} +winLoadHandler=function(){if(waitingToStart){winHopscotch.startTour();}};utils={addClass:function(domEl,classToAdd){var domClasses,classToAddArr,setClass,i,len;if(!domEl.className){domEl.className=classToAdd;} +else{classToAddArr=classToAdd.split(/\s+/);domClasses=' '+ domEl.className+' ';for(i=0,len=classToAddArr.length;i0)),showNext:utils.valOrDefault(step.showNextButton,this.opt.showNextButton),showCTA:utils.valOrDefault((step.showCTAButton&&step.ctaLabel),false),ctaLabel:step.ctaLabel,showClose:utils.valOrDefault(this.opt.showCloseButton,true)},step:{num:idx,isLast:utils.valOrDefault(isLast,false),title:(step.title||''),content:(step.content||''),placement:step.placement,padding:utils.valOrDefault(step.padding,this.opt.bubblePadding),width:utils.getPixelValue(step.width)||this.opt.bubbleWidth,customData:(step.customData||{})},tour:{isTour:this.opt.isTourBubble,numSteps:totalSteps,unsafe:utils.valOrDefault(unsafe,false),customData:(customTourData||{})}};if(typeof tourSpecificRenderer==='function'){el.innerHTML=tourSpecificRenderer(opts);} +else if(typeof tourSpecificRenderer==='string'){if(!hopscotch.templates||(typeof hopscotch.templates[tourSpecificRenderer]!=='function')){throw'Bubble rendering failed - template "'+ tourSpecificRenderer+'" is not a function.';} +el.innerHTML=hopscotch.templates[tourSpecificRenderer](opts);} +else if(customRenderer){el.innerHTML=customRenderer(opts);} +else{if(!hopscotch.templates||(typeof hopscotch.templates[templateToUse]!=='function')){throw'Bubble rendering failed - template "'+ templateToUse+'" is not a function.';} +el.innerHTML=hopscotch.templates[templateToUse](opts);} +children=el.children;numChildren=children.length;for(i=0;i=currTour.steps.length){step=null;} +else{step=currTour.steps[currStepNum];} +return step;},targetClickNextFn=function(){self.nextStep();},adjustWindowScroll=function(cb){var bubble=getBubble(),bubbleEl=bubble.element,bubbleTop=utils.getPixelValue(bubbleEl.style.top),bubbleBottom=bubbleTop+ utils.getPixelValue(bubbleEl.offsetHeight),targetEl=utils.getStepTarget(getCurrStep()),targetBounds=targetEl.getBoundingClientRect(),targetElTop=targetBounds.top+ utils.getScrollTop(),targetElBottom=targetBounds.bottom+ utils.getScrollTop(),targetTop=(bubbleToptargetElBottom)?bubbleBottom:targetElBottom,windowTop=utils.getScrollTop(),windowBottom=windowTop+ utils.getWindowHeight(),scrollToVal=targetTop- getOption('scrollTopMargin'),scrollEl,yuiAnim,yuiEase,direction,scrollIncr,scrollTimeout,scrollTimeoutFn;if(targetTop>=windowTop&&(targetTop<=windowTop+ getOption('scrollTopMargin')||targetBottom<=windowBottom)){if(cb){cb();}} +else if(!getOption('smoothScroll')){window.scrollTo(0,scrollToVal);if(cb){cb();}} +else{if(typeof YAHOO!==undefinedStr&&typeof YAHOO.env!==undefinedStr&&typeof YAHOO.env.ua!==undefinedStr&&typeof YAHOO.util!==undefinedStr&&typeof YAHOO.util.Scroll!==undefinedStr){scrollEl=YAHOO.env.ua.webkit?document.body:document.documentElement;yuiEase=YAHOO.util.Easing?YAHOO.util.Easing.easeOut:undefined;yuiAnim=new YAHOO.util.Scroll(scrollEl,{scroll:{to:[0,scrollToVal]}},getOption('scrollDuration')/1000, yuiEase); +yuiAnim.onComplete.subscribe(cb);yuiAnim.animate();} +else if(hasJquery){jQuery('body, html').animate({scrollTop:scrollToVal},getOption('scrollDuration'),cb);} +else{if(scrollToVal<0){scrollToVal=0;} +direction=(windowTop>targetTop)?-1:1;scrollIncr=Math.abs(windowTop- scrollToVal)/ (getOption('scrollDuration')/10); +scrollTimeoutFn=function(){var scrollTop=utils.getScrollTop(),scrollTarget=scrollTop+(direction*scrollIncr);if((direction>0&&scrollTarget>=scrollToVal)||(direction<0&&scrollTarget<=scrollToVal)){scrollTarget=scrollToVal;if(cb){cb();} +window.scrollTo(0,scrollTarget);return;} +window.scrollTo(0,scrollTarget);if(utils.getScrollTop()===scrollTop){if(cb){cb();} +return;} +setTimeout(scrollTimeoutFn,10);};scrollTimeoutFn();}}},goToStepWithTarget=function(direction,cb){var target,step,goToStepFn;if(currStepNum+ direction>=0&&currStepNum+ direction0){wasMultiPage=origStep.multipage;} +else{wasMultiPage=(currStepNum>0&&currTour.steps[currStepNum-1].multipage);} +changeStepCb=function(stepNum){var doShowFollowingStep;if(stepNum===-1){return this.endTour(true);} +if(doCallbacks){if(direction>0){doShowFollowingStep=utils.invokeEventCallbacks('next',origStep.onNext);} +else{doShowFollowingStep=utils.invokeEventCallbacks('prev',origStep.onPrev);}} +if(stepNum!==currStepNum){return;} +if(wasMultiPage){utils.setState(getOption('cookieName'),currTour.id+':'+ currStepNum,1);return;} +doShowFollowingStep=utils.valOrDefault(doShowFollowingStep,true);if(doShowFollowingStep){this.showStep(stepNum);} +else{this.endTour(false);}};if(!wasMultiPage&&getOption('skipIfNoElement')){goToStepWithTarget(direction,function(stepNum){changeStepCb.call(self,stepNum);});} +else if(currStepNum+ direction>=0&&currStepNum+ direction=currTour.steps.length){throw'Specified step number out of bounds.';} +currStepNum=stepNum;} +if(!utils.documentIsReady()){waitingToStart=true;return this;} +if(typeof currStepNum==="undefined"&&currTour.id===cookieTourId&&typeof cookieTourStep!==undefinedStr){currStepNum=cookieTourStep;} +else if(!currStepNum){currStepNum=0;} +findStartingStep(currStepNum,function(stepNum){var target=(stepNum!==-1)&&utils.getStepTarget(currTour.steps[stepNum]);if(!target){self.endTour(false,false);return;} +utils.invokeEventCallbacks('start');bubble=getBubble();bubble.hide(false);self.isActive=true;if(!utils.getStepTarget(getCurrStep())){utils.invokeEventCallbacks('error');if(getOption('skipIfNoElement')){self.nextStep(false);}} +else{self.showStep(stepNum);}});return this;};this.showStep=function(stepNum){var step=currTour.steps[stepNum];if(step.delay){setTimeout(function(){showStepHelper(stepNum);},step.delay);} +else{showStepHelper(stepNum);} +return this;};this.prevStep=function(doCallbacks){changeStep.call(this,doCallbacks,-1);return this;};this.nextStep=function(doCallbacks){var step=getCurrStep(),targetEl=utils.getStepTarget(step);if(step.nextOnTargetClick){utils.removeEvtListener(targetEl,'click',targetClickNextFn);} +changeStep.call(this,doCallbacks,1);return this;};this.endTour=function(clearState,doCallbacks){var bubble=getBubble();clearState=utils.valOrDefault(clearState,true);doCallbacks=utils.valOrDefault(doCallbacks,true);currStepNum=0;cookieTourStep=undefined;bubble.hide();if(clearState){utils.clearState(getOption('cookieName'));} +if(this.isActive){this.isActive=false;if(currTour&&doCallbacks){utils.invokeEventCallbacks('end');}} +this.removeCallbacks(null,true);this.resetDefaultOptions();currTour=null;return this;};this.getCurrTour=function(){return currTour;};this.getCurrTarget=function(){return utils.getStepTarget(getCurrStep());};this.getCurrStepNum=function(){return currStepNum;};this.refreshBubblePosition=function(){bubble.setPosition(getCurrStep());return this;};this.listen=function(evtType,cb,isTourCb){if(evtType){callbacks[evtType].push({cb:cb,fromTour:isTourCb});} +return this;};this.unlisten=function(evtType,cb){var evtCallbacks=callbacks[evtType],i,len;for(i=0,len=evtCallbacks.length;i"\']','g'),function(match){if(match=='&'){return'&'} +if(match=='<'){return'<'} +if(match=='>'){return'>'} +if(match=='"'){return'"'} +if(match=="'"){return'''}});} +this["hopscotch"]=this["hopscotch"]||{};this["hopscotch"]["templates"]=this["hopscotch"]["templates"]||{};this["hopscotch"]["templates"]["bubble_default"]=function(obj){obj||(obj={});var __t,__p='',__e=_.escape,__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')} +with(obj){function optEscape(str,unsafe){if(unsafe){return _.escape(str);} +return str;};__p+='\n
\n ';if(tour.isTour){;__p+=''+ +((__t=(i18n.stepNum))==null?'':__t)+'';};__p+='\n
\n ';if(step.title!==''){;__p+='

'+ +((__t=(optEscape(step.title,tour.unsafe)))==null?'':__t)+'

';};__p+='\n ';if(step.content!==''){;__p+='
'+ +((__t=(optEscape(step.content,tour.unsafe)))==null?'':__t)+'
';};__p+='\n
\n
\n ';if(buttons.showPrev){;__p+='';};__p+='\n ';if(buttons.showCTA){;__p+='';};__p+='\n ';if(buttons.showNext){;__p+='';};__p+='\n
\n ';if(buttons.showClose){;__p+='';};__p+='\n
\n
\n
\n
\n
';} +return __p};}());}(window,'hopscotch')); \ No newline at end of file