Browse Source

Update file

Zhu Jinhui 7 years ago
parent
commit
d123dcd681
100 changed files with 6276 additions and 31 deletions
  1. 40 31
      README.md
  2. 43 0
      demo/private/actions/database/add.php
  3. 61 0
      demo/private/actions/database/creator.php
  4. 68 0
      demo/private/actions/database/rules.php
  5. 76 0
      demo/private/actions/database/table.php
  6. 54 0
      demo/private/actions/database/update.php
  7. 12 0
      demo/private/actions/demo.php
  8. 136 0
      demo/private/configure/database_form_data.rules.php
  9. 165 0
      demo/private/configure/database_form_setting.rules.config.php
  10. 104 0
      demo/private/configure/table.rules.config.php
  11. 302 0
      demo/private/controller/api/database.php
  12. 17 0
      demo/private/controller/database.php
  13. 92 0
      demo/private/controller/dirs.php
  14. 13 0
      demo/private/i18n/CN/common.php
  15. 8 0
      demo/private/i18n/language.php
  16. 594 0
      demo/private/model/table.php
  17. 46 0
      demo/private/view/error.html
  18. 103 0
      demo/private/view/manage/data/add.html
  19. 15 0
      demo/private/view/manage/data/code.html
  20. 0 0
      demo/private/view/manage/data/core.html
  21. 185 0
      demo/private/view/manage/data/creator.html
  22. 22 0
      demo/private/view/manage/data/pages.html
  23. 112 0
      demo/private/view/manage/data/rules.html
  24. 146 0
      demo/private/view/manage/data/table.html
  25. 96 0
      demo/private/view/manage/data/update.html
  26. 85 0
      demo/private/view/manage/folder/dir.html
  27. 57 0
      demo/private/view/manage/folder/file.html
  28. 83 0
      demo/private/view/manage/index.html
  29. 83 0
      demo/private/view/manage/left.html
  30. 93 0
      demo/private/view/manage/login.html
  31. 16 0
      demo/private/view/manage/main.html
  32. 52 0
      demo/private/view/manage/top.html
  33. 17 0
      demo/private/view/tips.html
  34. 6 0
      demo/public/static/css/jquery-ui.min.css
  35. 87 0
      demo/public/static/css/jquery.multiSelect.css
  36. 26 0
      demo/public/static/css/select.css
  37. 310 0
      demo/public/static/css/style.css
  38. 93 0
      demo/public/static/css/sumoselect.css
  39. 5 0
      demo/public/static/formbuilder/demo.css
  40. 220 0
      demo/public/static/formbuilder/form-builder.css
  41. 1354 0
      demo/public/static/formbuilder/form-builder.js
  42. 312 0
      demo/public/static/formbuilder/form-render.css
  43. 248 0
      demo/public/static/formbuilder/form-render.js
  44. BIN
      demo/public/static/formbuilder/images/bg_hr.png
  45. BIN
      demo/public/static/formbuilder/images/blacktocat.png
  46. BIN
      demo/public/static/formbuilder/images/icon_download.png
  47. BIN
      demo/public/static/formbuilder/images/sprite_download.png
  48. BIN
      demo/public/static/formbuilder/img/clipboard-sprite.png
  49. BIN
      demo/public/static/formbuilder/img/frmb-sprite.png
  50. 65 0
      demo/public/static/formbuilder/language/cn.js
  51. 116 0
      demo/public/static/formbuilder/sass/_reset.scss
  52. 351 0
      demo/public/static/formbuilder/sass/_theme.scss
  53. 7 0
      demo/public/static/formbuilder/sass/_variables.scss
  54. 80 0
      demo/public/static/formbuilder/sass/demo.scss
  55. BIN
      demo/public/static/images/001.jpg
  56. BIN
      demo/public/static/images/404.png
  57. BIN
      demo/public/static/images/add.png
  58. BIN
      demo/public/static/images/btnbg.png
  59. BIN
      demo/public/static/images/btnbg1.png
  60. BIN
      demo/public/static/images/btnbg2.png
  61. BIN
      demo/public/static/images/buttonbg.png
  62. BIN
      demo/public/static/images/c01.png
  63. BIN
      demo/public/static/images/c02.png
  64. BIN
      demo/public/static/images/c03.png
  65. BIN
      demo/public/static/images/cbg.png
  66. BIN
      demo/public/static/images/clist.png
  67. BIN
      demo/public/static/images/close.png
  68. BIN
      demo/public/static/images/close1.png
  69. BIN
      demo/public/static/images/cloud.png
  70. BIN
      demo/public/static/images/d01.png
  71. BIN
      demo/public/static/images/d02.png
  72. BIN
      demo/public/static/images/d03.png
  73. BIN
      demo/public/static/images/d04.png
  74. BIN
      demo/public/static/images/d05.png
  75. BIN
      demo/public/static/images/d06.png
  76. BIN
      demo/public/static/images/d07.png
  77. BIN
      demo/public/static/images/diskbg.png
  78. BIN
      demo/public/static/images/dp.png
  79. BIN
      demo/public/static/images/dropdown.blue.active.png
  80. BIN
      demo/public/static/images/dropdown.blue.hover.png
  81. BIN
      demo/public/static/images/dropdown.blue.png
  82. BIN
      demo/public/static/images/dropdown.gif
  83. BIN
      demo/public/static/images/dropdown_active.gif
  84. BIN
      demo/public/static/images/dropdown_hover.gif
  85. BIN
      demo/public/static/images/error.png
  86. BIN
      demo/public/static/images/f01.png
  87. BIN
      demo/public/static/images/f02.png
  88. BIN
      demo/public/static/images/f03.png
  89. BIN
      demo/public/static/images/f04.png
  90. BIN
      demo/public/static/images/f05.png
  91. BIN
      demo/public/static/images/f06.png
  92. BIN
      demo/public/static/images/filetype/7z.gif
  93. BIN
      demo/public/static/images/filetype/Thumbs.db
  94. BIN
      demo/public/static/images/filetype/asp.gif
  95. BIN
      demo/public/static/images/filetype/aspx.gif
  96. BIN
      demo/public/static/images/filetype/bat.gif
  97. BIN
      demo/public/static/images/filetype/bmp.gif
  98. BIN
      demo/public/static/images/filetype/chm.gif
  99. BIN
      demo/public/static/images/filetype/css.gif
  100. BIN
      demo/public/static/images/filetype/db.gif

+ 40 - 31
README.md

@@ -8,16 +8,12 @@
 1、创建项目
    通过命令行进入当前目录,并执行:php -q _cli.php create=yes workspace=../project cache=tmp useDB=1
 	Command line usage:
-	>php -q _cli.php create=yes workspace=../project cache=tmp useDB=1
-	* create: is auto create default:yes;
-	* workspace: workspace
-	* cache : cache dir
-	* useDB : use db or not 
+	>php -q _cli.php 并根据提示完成网站的配置
 	程序将自动创建工作目录,并生成首页及配置相关文件。设置好Web网站目录,开启.htaccess即可直接访问。
 	相关的配置文件见 configure/app.ini及configure/db.ini文件
 
 2、框架的使用
-	1) 命令行运行程序
+	1) 命令行运行程序, 推荐使用short模式
 		仅支持GET方法
 		1. normal模式
 		php -q index.php control=index/action=home/id=100
@@ -31,28 +27,28 @@
 		php -q index.php index/home/100
 		php -q index.php plugins/page/2.html
 	2) 自动加载类
-		new Controller\User(); === require("Controller<?=DS?>User.php"); new Controller\User();
-		new Model\User(); === require("Model<?=DS?>User.php"); new Model\User();
-		new Model\Test\User(); === require("Model<?=DS?>Test<?=DS?>User.php"); new Model\Test\User();
+		new controller\user(); === require("controller<?=DS?>user.php"); new controller\user();
+		new model\user(); === require("model<?=DS?>user.php"); new model\user();
+		new model\test\user(); === require("model<?=DS?>test<?=DS?>user.php"); new model\test\user();
 
 	3) Qii 基本功能:
-		Qii::Instance(className, param1, param2, param3[,...]); === ($class = new className(param1, param2, param3[,...]));
-		Qii::load(className)->method(); === $class->method();
-		Qii::import(fileName); 如果指定的文件无法找到则会在get_include_path()和站点配置文件的[path]的目录中去搜索,直到搜索到一个则停止。
-		Qii::includes(fileName); == include(fileName);
-		Qii::setPrivate($key, $value);保存到私有变量 $_global[$key]中, $value可以为数组,如果是数组的话会将数组合并到已经存在$key的数组中去。
-		Qii::getPrivate($key, $index);获取$_global[$key][$index]的值
-		Qii::setError($condition, $code, $argvs); 检查$condition是否成立,成立就没有错,返回false,否则有错,返回true并将错误信息,详细代码错误$code详情见<?php echo Qii::getPrivate('qii_sys_language');?>。
+		\Qii::getInstance(className, param1, param2, param3[,...]); === ($class = new className(param1, param2, param3[,...]));
+		_loadClass(className)->method(); === $class->method();
+		_require(fileName); 如果指定的文件无法找到则会在get_include_path()和站点配置文件的[path]的目录中去搜索,直到搜索到一个则停止。
+		_include(fileName); == include(fileName);
+		_config($key, $value);保存到私有变量 $_global[$key]中, $value可以为数组,如果是数组的话会将数组合并到已经存在$key的数组中去。
+		_config($key);获取$_global[$key][$index]的值
+		\Qii::setError($condition, $code, $argvs); 检查$condition是否成立,成立就没有错,返回false,否则有错,返回true并将错误信息,详细代码错误$code详情见<?php echo \Qii::getPrivate('qii_sys_language');?>。
 	4) 多域名支持:
 		开启多域名支持,不同域名可以访问不同目录中的controller,在app.ini中的common下添加以下内容,注意:hosts中的内容会覆盖网站中对应的配置
         hosts[0.domain] = test.xxx.wang
-        hosts[0.ext] = test
+        hosts[0.path] = test
 
         hosts[1.domain] = admin.xxx.wang
-        hosts[1.ext] = admin
+        hosts[1.path] = admin
 	5) Module用法示例:
 		第一步,创建一个user的model
-		class user_model extends Model
+		class user extends \Qii\Driver\Model
 		{
 			public function __construct()
 			{
@@ -60,23 +56,35 @@
 			}
 			public function userInfo($uid)
 			{
-				return $this->getRow("SELECT * FROM user WHERE uid = '{$uid}'");
+				reutrn $this->db->where(['uid' => $uid])->selectRow('user');
+				//或者
+				return $this->db->getRow("SELECT * FROM user WHERE uid = '{$uid}'");
+			}
+
+			public function updateUserInfo($uid, $map)
+			{
+				return $this->db->updateObject('user', $map, array('uid' => $uid));
+			}
+
+			public function removeUser($uid)
+			{
+				return $this->db->exec("DELETE FROM user WHERE uid = ". intval($uid));
+				//或
+				return $this->db->where(['uid' => $uid])->deleteRows('user');
 			}
 		}
-		第二步,使用user_model
-		class user_controler extends \Qii\Controller\Abstract
+		第二步,使用user model
+		namespace controler;
+
+		class user extends \Qii\Base\Controller
 		{
 			public function __construct()
 			{
-					$this->Qii('Model');
-					$userClass = new user_module();
-					$userInfo = $userClass->userInfo(10);
+				$userClass = new \model\user();
+				$userInfo = $userClass->userInfo(10);
 
-					或
-					$this->Qii("user_module")->userInfo(10);
-					或
-					$this->Qii("user_module");
-					$this->user_module->userInfo(10);
+				或
+				_loadClass("model\user")->userInfo(10);
 			}
 		}
 	6) ORM的使用示例:
@@ -110,7 +118,8 @@
 			}
 		}
 		第二步,创建User Model:
-		class user_model extends Model
+		namespace model;
+		class user extends \Qii\Driver\Model
 		{
 		    public function __construct()
 		    {

+ 43 - 0
demo/private/actions/database/add.php

@@ -0,0 +1,43 @@
+<?php
+/**
+ * 添加数据
+ * @author Jinhui Zhu <jinhui.zhu@live.cn>2015-09-21
+ *
+ */
+namespace actions\database;
+
+use Qii\Action_Abstract;
+
+class add extends Action_Abstract
+{
+	protected $enableView = true;
+	protected $enableDatabase = true;
+
+	public function __construct()
+	{
+		parent::__construct();
+
+	}
+
+	/**
+	 * 创建规则
+	 * @author Jinhui Zhu 2015-08-23
+	 */
+	public function execute()
+	{
+		$database = $this->_request->get('database');
+		$tableName = $this->_request->get('tableName');
+		if (!$database) throw new \Exception('数据库名不能为空', __LINE__);
+		if (!$tableName) throw new \Exception('数据表名不能为空', __LINE__);
+		$this->_view->assign('database', $database);
+		$this->_view->assign('tableName', $tableName);
+
+
+		$rules = $this->_load->model('table')->getRules($database, $tableName);
+		$fields = array_flip($rules['rules']['fields']);
+		$this->_view->assign('rules', $rules);
+		$this->_view->assign('fields', $fields);
+
+		$this->_view->display('manage/data/add.html');
+	}
+}

+ 61 - 0
demo/private/actions/database/creator.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ * 创建规则
+ * @author Jinhui Zhu <jinhui.zhu@live.cn>2015-09-21
+ *
+ */
+namespace actions\database;
+
+use Qii\Action_Abstract;
+
+class creator extends Action_Abstract
+{
+	protected $enableView = true;
+	protected $enableDatabase = true;
+
+	public function __construct()
+	{
+		parent::__construct();
+	}
+
+	/**
+	 * 创建规则
+	 * @author Jinhui Zhu 2015-08-23
+	 */
+	public function execute()
+	{
+		list($database, $tableName) = array_pad(func_get_args(), 2, '');
+		$loadDatabase = $database ? false : true;
+		$this->_view->assign('loadDatabase', $loadDatabase);
+		$tableName = $this->_request->get('tableName', $tableName);
+		$database = $this->_request->get('database', $database);
+		try {
+			$databases = $this->_load->model('table')->getDatabases();
+			if (!$database && count($database) > 0) $database = $databases[0];
+			$this->_view->assign('databases', $databases);
+			$tables = $this->_load->model('table')->getTableLists($database);
+			if (!$tableName && count($tables) > 0) {
+				$tableName = $tables[0];
+			}
+			$this->_view->assign('tables', $tables);
+			$fields = array();
+			$rules = array();
+			if ($tableName != '') {
+				$fields = $this->_load->model('table')->getFieldsLists($database, $tableName);
+				$rules = $this->_load->model('table')->getRules($database, $tableName);
+				if (!isset($rules['rules'])) $rules['rules'] = array();
+			}
+			$validateRules = isset($rules['rules']['validate']) ? $rules['rules']['validate'] : array();
+			$this->_view->assign('validateRules', $validateRules);
+			$validate = new \Qii\Validate();
+			$this->_view->assign('validate', $validate->getRuleNames());
+			$this->_view->assign('fields', $fields);
+			$this->_view->assign('rules', isset($rules['rules']) ? $rules['rules'] : array());
+			$this->_view->assign('database', $database);
+			$this->_view->assign('tableName', $tableName);
+			$this->_view->display('manage/data/creator.html');
+		} catch (Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+}

+ 68 - 0
demo/private/actions/database/rules.php

@@ -0,0 +1,68 @@
+<?php
+/**
+ * 编辑详细规则
+ * @author Jinhui Zhu <jinhui.zhu@live.cn>2015-09-21
+ *
+ */
+namespace actions\database;
+
+use Qii\Action_Abstract;
+
+class rules extends Action_Abstract
+{
+	protected $enableView = true;
+	protected $enableDatabase = true;
+
+	public function __construct()
+	{
+		parent::__construct();
+
+	}
+
+	/**
+	 * 创建规则
+	 * @author Jinhui Zhu 2015-08-23
+	 */
+	public function execute()
+	{
+		list($database, $tableName) = array_pad(func_get_args(), 2, '');
+		$loadDatabase = $database ? false : true;
+		$this->_view->assign('loadDatabase', $loadDatabase);
+		$tableName = $this->_request->get('tableName', $tableName);
+		$database = $this->_request->get('database', $database);
+		try {
+			$databases = $this->_load->model('table')->getDatabases();
+			if (!$database && count($database) > 0) $database = $databases[0];
+			$this->_view->assign('databases', $databases);
+			$tables = $this->_load->model('table')->getTableLists($database);
+			if (!$tableName && count($tables) > 0) {
+				$tableName = $tables[0];
+			}
+			$this->_view->assign('tables', $tables);
+			$fields = array();
+			$rules = array();
+			$rules['rules'] = array();
+			if ($tableName != '') {
+				$fields = $this->_load->model('table')->getFieldsLists($database, $tableName);
+				$rules = $this->_load->model('table')->getRules($database, $tableName);
+				if (isset($rules['rules'])) $rules['rules'] = $rules['rules'];
+			}
+			$validateRules = isset($rules['rules']['validate']) ? $rules['rules']['validate'] : array();
+			$invalidMessage = isset($rules['rules']['invalidMessage']) ? $rules['rules']['invalidMessage'] : array();
+			$extRules = isset($rules['rules']['extRules']) ? $rules['rules']['extRules'] : array();
+			$this->_view->assign('validateRules', $validateRules);
+			$this->_view->assign('invalidMessage', $invalidMessage);
+			$this->_view->assign('extRules', $extRules);
+
+			$validate = new \Qii\Validate();
+			$this->_view->assign('validate', $validate->getRuleNames());
+			$this->_view->assign('fields', $fields);
+			$this->_view->assign('rules', isset($rules['rules']) ? $rules['rules'] : array());
+			$this->_view->assign('database', $database);
+			$this->_view->assign('tableName', $tableName);
+			$this->_view->display('manage/data/rules.html');
+		} catch (Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+}

+ 76 - 0
demo/private/actions/database/table.php

@@ -0,0 +1,76 @@
+<?php
+/**
+ * 数据管理
+ * @author Jinhui Zhu <jinhui.zhu@live.cn>2015-09-21
+ *
+ */
+namespace actions\database;
+
+use Qii\Action_Abstract;
+
+class table extends Action_Abstract
+{
+	protected $enableView = true;
+	protected $enableDatabase = true;
+
+	public function __construct()
+	{
+		parent::__construct();
+
+	}
+
+	/**
+	 * 创建规则
+	 * @author Jinhui Zhu 2015-08-23
+	 */
+	public function execute()
+	{
+		list($database, $tableName) = array_pad(func_get_args(), 2, '');
+		$loadDatabase = true;
+		$this->_view->assign('controller', $this->_controller);
+		$this->_view->assign('action', $this->_action);
+		try {
+			$this->_view->assign('loadDatabase', $loadDatabase);
+			$database = $this->_request->get('database', $database);
+			$tableName = $this->_request->get('tableName', $tableName);
+			$currentPage = $this->_request->get('currentPage', 1);
+			$databases = array();
+			$tables = array();
+			if ($loadDatabase) {
+				$databases = $this->_load->model('table')->getDatabases();
+				if (!$database && count($database) > 0) $database = $databases[0];
+				if (!$database) throw new \Exception('数据库名不能为空', __LINE__);
+				$tables = $this->_load->model('table')->getTableLists($database);
+				if (!$tableName && count($tables) > 0) {
+					$tableName = $tables[0];
+				}
+			}
+			$this->_view->assign('databases', $databases);
+			$this->_view->assign('tables', $tables);
+
+			$this->_view->assign('database', $database);
+			$this->_view->assign('tableName', $tableName);
+			$data = array();
+			$data['page'] = array();
+			$data['page']['currentPage'] = 1;
+			$data['page']['totalPage'] = 0;
+			$data['page']['total'] = 0;
+			$data['rules'] = array();
+			$data['rules']['end'] = array();
+			$data['rows'] = array();
+			if ($tableName) {
+				$data = $this->_load->model('table')->loadTableData($database, $tableName, $currentPage);
+			}
+			$start = 0;
+			if ($data['page']['currentPage'] >= 6) {
+				$start = $data['page']['currentPage'] - 6;
+			}
+			$this->_view->assign('start', $start);
+			$this->_view->assign('data', $data);
+			$this->_view->assign('pages', $data['page']);
+			$this->_view->display('manage/data/table.html');
+		} catch (Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+}

+ 54 - 0
demo/private/actions/database/update.php

@@ -0,0 +1,54 @@
+<?php
+/**
+ * 更新规则页面
+ * @author Jinhui Zhu <jinhui.zhu@live.cn>2015-09-21
+ *
+ */
+namespace actions\database;
+
+use Qii\Action_Abstract;
+
+class update extends Action_Abstract
+{
+	protected $enableView = true;
+	protected $enableDatabase = true;
+
+	public function __construct()
+	{
+		parent::__construct();
+
+	}
+
+	/**
+	 * 创建规则
+	 * @author Jinhui Zhu 2015-08-23
+	 */
+	public function execute()
+	{
+		try {
+			$database = $this->_request->get('__database');
+			$tableName = $this->_request->get('__tableName');
+			$pri = explode(',', $this->_request->get('__pri', ''));
+			$val = array();
+			foreach ($pri AS $key) {
+				$val[$key] = $this->_request->get($key);
+			}
+			if (!$database || !$tableName || !$pri || !$val) {
+				throw new \Exception('参数不正确', __LINE__);
+			}
+			$rules = $this->_load->model('table')->getRules($database, $tableName);
+
+			$data = $this->_load->model('table')->loadDataFromTable($database, $tableName, $pri, $val);
+			$this->_view->assign('database', $database);
+			$this->_view->assign('tableName', $tableName);
+			$this->_view->assign('pri', $pri);
+			$this->_view->assign('rules', $rules);
+			$this->_view->assign('val', $val);
+			$this->_view->assign('data', $data);
+
+			$this->_view->display('manage/data/update.html');
+		} catch (Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+}

+ 12 - 0
demo/private/actions/demo.php

@@ -0,0 +1,12 @@
+<?php
+namespace actions;
+
+use Qii\Action_Abstract;
+
+class demo extends Action_Abstract
+{
+	public function execute()
+	{
+		print_r(__METHOD__);
+	}
+}

+ 136 - 0
demo/private/configure/database_form_data.rules.php

@@ -0,0 +1,136 @@
+<?php
+return array(
+	'database' => 'test',
+	'tableName' => 'database_form_data',
+	'rules' =>
+		array(
+			'end' =>
+				array(
+					'id' => '1',
+					'form_id' => '1',
+					'form_uniqid' => '1',
+					'form_value' => '1',
+					'status' => '1',
+					'add_time' => '1',
+					'update_time' => '1',
+				),
+			'front' =>
+				array(
+					'id' => '1',
+					'form_id' => '1',
+					'form_uniqid' => '1',
+					'form_value' => '1',
+					'status' => '1',
+					'add_time' => '1',
+					'update_time' => '1',
+				),
+			'alias' =>
+				array(
+					'id' => 'id',
+					'form_id' => 'form_id',
+					'form_uniqid' => 'form_uniqid',
+					'form_value' => 'form_value',
+					'status' => 'status',
+					'add_time' => 'add_time',
+					'update_time' => 'update_time',
+				),
+			'fields' =>
+				array(
+					0 => 'id',
+					1 => 'form_id',
+					2 => 'form_uniqid',
+					3 => 'form_value',
+					4 => 'status',
+					5 => 'add_time',
+					6 => 'update_time',
+				),
+			'length' =>
+				array(
+					'id' => '11',
+					'form_id' => '11',
+					'form_uniqid' => '41',
+					'form_value' => '0',
+					'status' => '1',
+					'add_time' => '11',
+					'update_time' => '11',
+				),
+			'type' =>
+				array(
+					'id' => 'int',
+					'form_id' => 'int',
+					'form_uniqid' => 'char',
+					'form_value' => 'text',
+					'status' => 'tinyint',
+					'add_time' => 'int',
+					'update_time' => 'int',
+				),
+			'null' =>
+				array(
+					'id' => 'no',
+					'form_id' => 'no',
+					'form_uniqid' => 'no',
+					'form_value' => 'no',
+					'status' => 'no',
+					'add_time' => 'yes',
+					'update_time' => 'yes',
+				),
+			'pri' =>
+				array(
+					'id' => '1',
+				),
+			'validate' =>
+				array(
+					'form_id' =>
+						array(
+							0 => 'required',
+						),
+					'form_uniqid' =>
+						array(
+							0 => 'required',
+						),
+					'form_value' =>
+						array(
+							0 => 'required',
+						),
+				),
+			'default' =>
+				array(
+					'id' => '',
+					'form_id' => '',
+					'form_uniqid' => '',
+					'form_value' => '',
+					'status' => '1',
+					'add_time' => '',
+					'update_time' => '',
+				),
+			'save' =>
+				array(
+					'form_id' => '1',
+					'form_uniqid' => '1',
+					'form_value' => '1',
+				),
+			'update' =>
+				array(
+					'form_id' => '1',
+					'form_uniqid' => '1',
+				),
+			'remove' =>
+				array(
+					'form_id' => '1',
+					'form_uniqid' => '1',
+				),
+		),
+	'table' => 'database_form_data',
+	'add_time' => '1454482716',
+	'update_time' => '1454482721',
+	'sql' => 'CREATE TABLE IF NOT EXISTS `database_form_data` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `form_id` int(11) NOT NULL,
+  `form_uniqid` char(41) NOT NULL,
+  `form_value` text NOT NULL,
+  `status` tinyint(1) NOT NULL DEFAULT \\\'1\\\',
+  `add_time` int(11) DEFAULT NULL,
+  `update_time` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;',
+);

+ 165 - 0
demo/private/configure/database_form_setting.rules.config.php

@@ -0,0 +1,165 @@
+<?php
+return array(
+	'database' => 'test',
+	'tableName' => 'database_form_setting',
+	'rules' =>
+		array(
+			'end' =>
+				array(
+					'id' => '1',
+					'uid' => '1',
+					'uniqid' => '1',
+					'mask' => '1',
+					'form' => '1',
+					'form_serialize' => '1',
+					'status' => '1',
+					'add_time' => '1',
+					'update_time' => '1',
+				),
+			'front' =>
+				array(
+					'id' => '1',
+					'uid' => '1',
+					'uniqid' => '1',
+					'mask' => '1',
+					'form' => '1',
+					'form_serialize' => '1',
+					'status' => '1',
+					'add_time' => '1',
+					'update_time' => '1',
+				),
+			'alias' =>
+				array(
+					'id' => 'id',
+					'uid' => 'uid',
+					'uniqid' => 'uniqid',
+					'mask' => '',
+					'form' => 'form',
+					'form_serialize' => 'form_serialize',
+					'status' => 'status',
+					'add_time' => 'add_time',
+					'update_time' => 'update_time',
+				),
+			'fields' =>
+				array(
+					0 => 'id',
+					1 => 'uid',
+					2 => 'uniqid',
+					3 => 'mask',
+					4 => 'form',
+					5 => 'form_serialize',
+					6 => 'status',
+					7 => 'add_time',
+					8 => 'update_time',
+				),
+			'length' =>
+				array(
+					'id' => '11',
+					'uid' => '11',
+					'uniqid' => '41',
+					'mask' => '32',
+					'form' => '0',
+					'form_serialize' => '0',
+					'status' => '1',
+					'add_time' => '11',
+					'update_time' => '11',
+				),
+			'type' =>
+				array(
+					'id' => 'int',
+					'uid' => 'int',
+					'uniqid' => 'char',
+					'mask' => 'char',
+					'form' => 'text',
+					'form_serialize' => 'text',
+					'status' => 'tinyint',
+					'add_time' => 'int',
+					'update_time' => 'int',
+				),
+			'null' =>
+				array(
+					'id' => 'no',
+					'uid' => 'yes',
+					'uniqid' => 'no',
+					'mask' => 'no',
+					'form' => 'yes',
+					'form_serialize' => 'yes',
+					'status' => 'no',
+					'add_time' => 'yes',
+					'update_time' => 'yes',
+				),
+			'pri' =>
+				array(
+					'id' => '1',
+				),
+			'uni' =>
+				array(
+					'uniqid' => '1',
+					'mask' => '1',
+				),
+			'validate' =>
+				array(
+					'uniqid' =>
+						array(
+							0 => 'required',
+						),
+					'form' =>
+						array(
+							0 => 'required',
+						),
+					'form_serialize' =>
+						array(
+							0 => 'required',
+						),
+				),
+			'default' =>
+				array(
+					'id' => '',
+					'uid' => '',
+					'uniqid' => '',
+					'mask' => '',
+					'form' => '',
+					'form_serialize' => '',
+					'status' => '1',
+					'add_time' => '',
+					'update_time' => '',
+				),
+			'update' =>
+				array(
+					'id' => '1',
+					'uniqid' => '1',
+					'mask' => '1',
+					'form' => '1',
+					'form_serialize' => '1',
+				),
+			'remove' =>
+				array(
+					'id' => '1',
+					'uniqid' => '1',
+				),
+			'save' =>
+				array(
+					'uniqid' => '1',
+					'mask' => '1',
+					'form' => '1',
+					'form_serialize' => '1',
+				),
+		),
+	'table' => 'database_form_setting',
+	'add_time' => '1454470879',
+	'update_time' => '1454471891',
+	'sql' => 'CREATE TABLE IF NOT EXISTS `database_form_setting` (
+  `id` int(11) NOT NULL AUTO_INCREMENT,
+  `uid` int(11) DEFAULT NULL,
+  `uniqid` char(41) NOT NULL,
+  `mask` char(32) NOT NULL,
+  `form` text,
+  `form_serialize` text,
+  `status` tinyint(1) NOT NULL DEFAULT \\\'1\\\',
+  `add_time` int(11) DEFAULT NULL,
+  `update_time` int(11) DEFAULT NULL,
+  PRIMARY KEY (`id`),
+  UNIQUE KEY `uniqid_UNIQUE` (`uniqid`),
+  UNIQUE KEY `mask_UNIQUE` (`mask`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;',
+);

+ 104 - 0
demo/private/configure/table.rules.config.php

@@ -0,0 +1,104 @@
+<?php
+return array(
+	'database' => 'test',
+	'tableName' => 'database_table_rules',
+	'rules' => array(
+		'length' => array(
+			'database' => '20',
+			'table' => '20',
+			'rules' => '0',
+			'add_time' => '10',
+			'update_time' => '10'
+		),
+		'type' => array(
+			'database' => 'varchar',
+			'table' => 'varchar',
+			'rules' => 'text',
+			'add_time' => 'int',
+			'update_time' => 'int'
+		),
+		'fields' => array(
+			0 => 'database',
+			1 => 'table',
+			2 => 'rules',
+			3 => 'add_time',
+			4 => 'update_time'
+		),
+		'pri' => array(
+			'database' => '1',
+			'table' => '1'
+		),
+		'alias' => array(
+			'database' => '数据库名',
+			'table' => '数据表',
+			'rules' => '规则',
+			'add_time' => '添加时间',
+			'update_time' => '更新时间'
+		),
+		'front' => array(
+			'database' => '1',
+			'table' => '1',
+			'rules' => '1',
+			'add_time' => '1',
+			'update_time' => '1'
+		),
+		'end' => array(
+			'database' => '1',
+			'table' => '1',
+			'rules' => '1',
+			'add_time' => '1',
+			'update_time' => '1'
+		),
+		'default' => array(
+			'database' => '',
+			'table' => '',
+			'rules' => '',
+			'add_time' => '',
+			'update_time' => ''
+		),
+		'validate' => array(
+			'database' => array(
+				0 => 'required',
+				1 => 'string',
+			),
+			'table' => array(
+				0 => 'required',
+				1 => 'string'
+			),
+			'rules' => array(
+				0 => 'required'
+			)
+		),
+		'update' => array(
+			'database' => '1',
+			'table' => '1',
+			'rules' => '1'
+		),
+		'save' => array(
+			'database' => '1',
+			'table' => '1',
+			'rules' => '1'
+		),
+		'remove' => array(
+			'database' => '1',
+			'table' => '1'
+		),
+		'null' => array(
+			'database' => 'no',
+			'table' => 'no',
+			'rules' => 'no',
+			'add_time' => 'yes',
+			'update_time' => 'yes'
+		)
+	),
+	'add_time' => '1442888805',
+	'update_time' => '1451032338',
+	'sql' => 'CREATE TABLE IF NOT EXISTS `database_table_rules` (
+              `database` varchar(50) NOT NULL,
+              `table` varchar(50) NOT NULL,
+              `rules` text NOT NULL,
+              `add_time` int(10) DEFAULT NULL,
+              `update_time` int(10) DEFAULT NULL,
+              PRIMARY KEY (`database`,`table`)
+            ) ENGINE=InnoDB DEFAULT CHARSET=utf8;'
+);

+ 302 - 0
demo/private/controller/api/database.php

@@ -0,0 +1,302 @@
+<?php
+/**
+ * 提供data_controller类使用的接口
+ */
+namespace controller\api;
+
+use \controller\base;
+
+class database extends base
+{
+	public function __construct()
+	{
+		parent::__construct();
+		$this->_load->model('table')->checkRuleTable();
+	}
+
+	/**
+	 * 保存creator
+	 */
+	public function creatorAction()
+	{
+		$data = array();
+		$database = $this->_request->post('database');
+		$tableName = $this->_request->post('tableName');
+		$rules = $this->_request->post($tableName);
+		if (!$rules) {
+			$data['code'] = 1;
+			echo $this->Json($data);
+			return;
+		}
+		$result = $this->_load->model('table')->saveRules($database, $tableName, $rules);
+		if ($result) {
+			$data['code'] = 0;
+		} else {
+			$data['code'] = 1;
+			$data['error'] = $this->_load->model('table')->tablesError;
+		}
+		$this->echoJson($data);
+	}
+
+	/**
+	 * 编辑详细的规则
+	 */
+	public function rulesAction()
+	{
+		$data = array();
+		$database = $this->_request->post('database');
+		$tableName = $this->_request->post('tableName');
+		$rules = $this->_request->post('rules');
+		if (!$rules) {
+			$data['code'] = 1;
+			echo $this->Json($data);
+			return;
+		}
+		$result = $this->_load->model('table')->updateRules($database, $tableName, $rules);
+		if ($result) {
+			$data['code'] = 0;
+		} else {
+			$data['code'] = 1;
+			$data['error'] = $this->_load->model('table')->tablesError;
+		}
+		$this->echoJson($data);
+	}
+
+	/**
+	 * 获取制定数据库的数据包
+	 */
+	public function tableListsAction()
+	{
+		$tableName = $this->_request->get('tableName', '');
+		$this->echoJson($this->_load->model('table')->getTableLists($this->_load->model('table')->getUseDB(), $tableName));
+	}
+
+	/**
+	 * 获取自定表的字段
+	 */
+	public function fieldsListsAction()
+	{
+		$tableName = $this->_request->get('tableName');
+		$this->echoJson($this->_load->model('table')->getFieldsLists($this->_load->model('table')->getUseDB(), $tableName));
+	}
+
+	/**
+	 * 删除数据表中的数据
+	 */
+	public function tableAction()
+	{
+		$data = array();
+		$database = $this->_request->get('__database', $this->_load->model('table')->getUseDB());
+		$tableName = $this->_request->get('__tableName', '');
+		if (!$database || !$tableName) {
+			$data['code'] = 1;
+			$data['msg'] = '参数不全';
+			echo $this->Json($data);
+			return;
+		}
+
+		$pri = explode(',', $this->_request->get('__pri'));
+
+		$priVal = array();
+		foreach ($pri as $val) {
+			if (!$this->_request->keyExists($_GET, $val)) {
+				$data['code'] = 1;
+				break;
+			}
+			$priVal[$val] = $this->_request->get($val);
+		}
+		$result = $this->_load->model('table')->removeTableData($database, $tableName, $priVal);
+		if ($result) {
+			$data['code'] = 0;
+		} else {
+			$data['code'] = 1;
+			$data['error'] = $this->_load->model('table')->getError() === false ? '删除数据失败' : $this->_load->model('table')->getError();
+		}
+		$this->echoJson($data);
+	}
+
+	/**
+	 * 更新数据表中的数据
+	 */
+	public function updateAction()
+	{
+		try {
+
+			$data = array();
+			$data['code'] = 0;
+			$database = $this->_request->post('__database');
+			$tableName = $this->_request->post('__tableName');
+			$pri = explode(',', $this->_request->post('__pri'));
+
+
+			$fields = $this->_request->post('fields');
+			$priVal = array();
+			foreach ($pri as $val) {
+				if (!$this->_request->keyExists($_POST, $val)) {
+					$data['code'] = 1;
+					break;
+				}
+				$priVal[$val] = $this->_request->post($val);
+			}
+			if ($data['code'] != 1) {
+				$result = $this->_load->model('table')->updateTableData($database, $tableName, $priVal, $fields);
+				if (!$result->isError()) {
+					$data['code'] = 0;
+				} else {
+					$data['code'] = 1;
+					$data['error'] = $result->getResult();
+				}
+			}
+		} catch (Exception $e) {
+			$data['code'] = 1;
+			$data['msg'] = $e->getMessage();
+		}
+
+		$this->echoJson($data);
+	}
+
+
+	/**
+	 * 添加数据表中的数据
+	 */
+	public function addAction()
+	{
+		try {
+
+			$data = array();
+			$data['code'] = 0;
+			$database = $this->_request->post('database');
+			$tableName = $this->_request->post('tableName');
+
+
+			$fields = $this->_request->post('fields');
+			if ($data['code'] != 1) {
+				$result = $this->_load->model('table')->addTableData($database, $tableName, $fields);
+				if ($result->getCode() == 0) {
+					$data['code'] = 0;
+				} else {
+					$data['code'] = 1;
+					$data['error'] = $result->getMessage();
+				}
+			}
+		} catch (Exception $e) {
+			$data['code'] = 1;
+			$data['msg'] = $e->getMessage();
+		}
+
+		$this->echoJson($data);
+	}
+
+	/**
+	 * 下载数据表的配置文件
+	 * @author Jinhui Zhu<jinhui.zhu@live.cn> 2015-09-28 11:16
+	 */
+	public function downloadConfigAction()
+	{
+		$database = $this->_request->get('database');
+		$tableName = $this->_request->get('tableName');
+		try {
+			if (!$database || !$tableName) {
+				$data['code'] = 1;
+				$data['msg'] = '参数不全';
+				throw new Exception($data['msg'], $data['code']);
+			}
+			$result = $this->_load->model('table')->autoRules($database, $tableName);
+			if ($result) {
+				$tableStruct = $this->_load->model('table')->getTableSQL($database, $tableName);
+				$result['sql'] = '';
+				if ($tableStruct['sql']) $result['sql'] = str_replace("'", "\'", $tableStruct['sql']);
+				$downloadStr = "<?php\n\t return " . var_export($result, true) . ';';
+				$this->_load->library('download')->downloadByString($database . '.' . $tableName . '.config.php', $downloadStr);
+			}
+		} catch (Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+
+	/**
+	 * 获取数据表建表URL
+	 * @author Jinhui Zhu <jinhui.zhu@live.cn> 2015-09-28 12:03
+	 *
+	 */
+	public function tableSQLAction()
+	{
+		$database = $this->_request->get('database');
+		$tableName = $this->_request->get('tableName');
+		$data = array();
+		try {
+			$data = $this->_load->model('table')->getTableSQL($database, $tableName);
+			$data['code'] = 0;
+		} catch (Exception $e) {
+			$data['code'] = 1;
+			$data['msg'] = $e->getMessage();
+		}
+		$this->echoJson($data);
+	}
+
+	/**
+	 * 备份数据表及数据
+	 */
+	public function backupAction()
+	{
+		$database = $this->_request->get('database');
+		$tableName = $this->_request->get('tableName');
+		try {
+			$downloadStr = $this->_load->model('table')->backupTable($database, $tableName);
+			$this->_load->library('download')->downloadByString($database . '.' . $tableName . '.sql', $downloadStr);
+		} catch (Exception $e) {
+			$data['code'] = 1;
+			$data['msg'] = $e->getMessage();
+			$this->echoJson($data);
+		}
+	}
+
+	public function restoreAction()
+	{
+		$database = $this->_request->post('database');
+		$tableName = $this->_request->post('tableName');
+		if (!$database || !$tableName || !isset($_FILES['restoreSQL']) ||
+			!isset($_FILES['restoreSQL']['tmp_name']) ||
+			$_FILES['restoreSQL']['tmp_name'] == '' ||
+			$_FILES['restoreSQL']['error'] != UPLOAD_ERR_OK
+		) {
+			$data['code'] = 1;
+			$data['msg'] = '参数或文件错误';
+			$this->echoJson($data);
+			return;
+		}
+		$fileName = $_FILES['restoreSQL']['tmp_name'];
+		$data = $this->_load->model('table')->restore($database, $tableName, $fileName);
+		echo $this->Json($data);
+	}
+
+	public function creatBasicCodeAction()
+	{
+		$database = $this->_request->get('database');
+		$tableName = $this->_request->get('tableName');
+		try {
+			if (!$database || !$tableName) {
+				$data['code'] = 1;
+				$data['msg'] = '参数或文件错误';
+				throw new \Exception($data['msg'], $data['code']);
+			}
+			$rules = $this->_load->model('table')->getRules($database, $tableName);
+			if(!isset($rules['rules']))
+			{
+				$data['code'] = 1;
+				$data['msg'] = '请先设置规则';
+				throw new \Exception($data['msg'], $data['code']);
+			}
+			$privateKeys = 'array(\'' . join('\', \'', array_keys($rules['rules']['pri'])) . '\')';
+			$this->_view->assign('privateKeys', $privateKeys);
+			$code = $this->_load->model('code');
+			$code->setDatabase($database);
+			$code->setClass($tableName);
+			$this->_view->assign('code', $code->output());
+			$sampleCode = $this->_view->fetch('manage/data/code.html');
+			$this->_load->library('download')->downloadByString($tableName . '.php', $sampleCode);
+		} catch (\Exception $e) {
+			$this->showErrorPage($e->getMessage());
+		}
+	}
+}

+ 17 - 0
demo/private/controller/database.php

@@ -0,0 +1,17 @@
+<?php
+namespace controller;
+class database extends base
+{
+	public $actions = array(
+		'creator' => 'actions\database\creator',//创建规则
+		'rules' => 'actions\database\rules',//编辑详细的规则哦
+		'table' => 'actions\database\table',//管理数据表数据
+		'update' => 'actions\database\update',//更新规则页面
+		'add' => 'actions\database\add',//添加数据
+	);
+
+	public function __construct()
+	{
+		parent::__construct();
+	}
+}

+ 92 - 0
demo/private/controller/dirs.php

@@ -0,0 +1,92 @@
+<?php
+namespace controller;
+
+class dirs extends base
+{
+	public $defaultPath = './';
+
+	public function __construct()
+	{
+		parent::__construct();
+		$this->_view->assign('defaultPath', $this->defaultPath);
+	}
+
+	public function indexAction()
+	{
+		$path = $this->_request->get('path', './');
+		if (!is_dir($path)) {
+			$this->showErrorPage('指定文件不存在');
+			return;
+		}
+		$files = \helper\tools::getFolders($path);
+		$usePath = explode('/', $path);
+		$visitPathes = \helper\tools::getVisitPath($path);
+		$this->_view->assign('visitPathes', $visitPathes);
+		$currentPath = array_pop($usePath);
+		$this->_view->assign('currentPath', $currentPath);
+		$this->_view->assign('usePath', join('/', $usePath));
+		$this->_view->assign('files', $files);
+		$this->_view->display('manage/folder/dir.html');
+	}
+
+	/**
+	 * 查看指定文件内容,仅限于php、css、js、cpp、.h、java、python类型文件
+	 */
+	public function fileAction()
+	{
+		$file = $this->_request->get('file');
+		if (!is_file($file)) {
+			$this->showErrorPage($file . '指定文件不存在');
+			return;
+		}
+		//如果是php、css、js、cpp、.h、java、python文件就直接显示内容,否则下载
+		$extension = pathinfo($file, PATHINFO_EXTENSION);
+		if (!in_array($extension, array('php', 'css', 'js', 'html', 'cpp', 'h', 'py', 'java', 'ini'))) {
+			$download = new \Library\download();
+			$download->download($file);
+			return;
+		}
+		$visitPathes = \helper\tools::getVisitPath(pathinfo($file, PATHINFO_DIRNAME));
+		$this->_view->assign('visitPathes', $visitPathes);
+		$this->_view->assign('file', pathinfo($file, PATHINFO_BASENAME));
+		$usePath = pathinfo($file, PATHINFO_DIRNAME);
+		$this->_view->assign('usePath', $usePath);
+		$content = file_get_contents($file);
+		$encode = mb_detect_encoding($content, array('ASCII', 'UTF-8', 'GB2312', 'GBK', 'BIG5'));
+		if ($encode != 'UTF-8') {
+			$content = mb_convert_encoding($content, 'UTF-8', $encode);
+		}
+		$this->_view->assign('code', $content);
+		$this->_view->display('manage/folder/file.html');
+	}
+
+	public function removeAction()
+	{
+		$file = $this->_request->get('file');
+		$isAjax = $this->_request->get('isAjax', 0);
+		if (!\helper\tools::allowRemove($file)) {
+			$isAjax == 1 ? $this->echoJson(array('code' => 1, 'msg' => '此目录或文件不允许删除')) : $this->showTipsPage('此目录或文件不允许删除');
+			return;
+		}
+		$result = \helper\tools::removeFile($file);
+		if ($result) {
+			$isAjax == 1 ? $this->echoJson(array('code' => 0, 'msg' => '删除成功')) : $this->showTipsPage('删除成功');
+			return;
+		}
+		$isAjax == 1 ? $this->echoJson(array('code' => 1, 'msg' => '删除失败')) : $this->showTipsPage('删除失败');
+	}
+
+	/**
+	 * 下载指定文件
+	 */
+	public function downAction()
+	{
+		$file = $this->_request->get('file');
+		if (!is_file($file)) {
+			$this->showErrorPage($file . '指定文件不存在');
+			return;
+		}
+		$download = new \Library\download();
+		$download->download($file);
+	}
+}

+ 13 - 0
demo/private/i18n/CN/common.php

@@ -0,0 +1,13 @@
+<?php
+/**
+ * User: zhujinhui
+ * Date: 15/5/1
+ * Time: 下午9:28
+ */
+return array(
+	1 => '参数错误',
+	2 => '保存数据错误',
+	10001 => '已经存在相关数据',
+	10002 => '未找到相关数据',
+	10003 => '更新数据失败'
+);

+ 8 - 0
demo/private/i18n/language.php

@@ -0,0 +1,8 @@
+<?php
+/**
+ * Created by PhpStorm.
+ * User: zhujinhui
+ * Date: 15/5/1
+ * Time: 下午9:30
+ */
+return 'CN';

+ 594 - 0
demo/private/model/table.php

@@ -0,0 +1,594 @@
+<?php
+/**
+ * 数据表的显示规则
+ *
+ * @author Jinhui Zhu<jinhui.zhu@live.cn> 2015-08-23 10:07
+ */
+namespace Model;
+
+use \Qii\Model;
+use \Qii\Driver\Response;
+
+class table extends Model
+{
+	public $tablesError;
+
+	public function __construct()
+	{
+		parent::__construct();
+		$this->checkRuleTable();
+	}
+	public function getRuleTableInfo()
+	{
+		$table = \Qii\Import::includes('configure/table.rules.config.php');
+		$table['database'] = $this->db->useDB;
+		return $table;
+	}
+	public function checkRuleTable()
+	{
+		$config = $this->getRuleTableInfo();
+		if($config['sql'])
+		{
+			$this->db->exec($config['sql']);
+		}
+	}
+
+	/**
+	 * 获取数据库列表
+	 * @return array
+	 */
+	public function getDatabases()
+	{
+		$databases = array();
+		$sql = "SHOW DATABASES";
+
+		$this->db->setQuery($sql);
+		while ($row = $this->db->fetch()) {
+			if (!in_array($row['Database'], array('information_schema', 'mysql', 'performance_schema', 'test'))) $databases[] = $row['Database'];
+		}
+		return $databases;
+	}
+
+	public function getTableSQL($db, $table)
+	{
+		if (!$db || !$table) {
+			$this->tablesError = '参数不正确';
+			return array('code' => 1, 'msg' => '参数不正确');
+		}
+		$data = array();
+		$data['database'] = $db;
+		$data['table'] = $table;
+		try {
+			$data['code'] = 0;
+			$sql = "SHOW CREATE TABLE {$db}.{$table}";
+			$this->db->setQuery($sql);
+			$row = $this->db->fetch();
+			$createTableSQL = preg_replace('/AUTO_INCREMENT\=[\d]/', 'AUTO_INCREMENT=1', $row['Create Table']);
+			if ($row) $data['sql'] = str_replace("CREATE TABLE ", "CREATE TABLE IF NOT EXISTS ", $createTableSQL) . ';';
+		} catch (Exception $e) {
+			$data['code'] = 1;
+			$data['msg'] = $e->getMessage();
+			$data['sql'] = '';
+		}
+		return $data;
+	}
+
+	/**
+	 * 获取指定数据库中的表名
+	 * @param string $db
+	 * @return array
+	 */
+	public function getTableLists($db = 'istudy', $table = '')
+	{
+		if (!$db) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$tables = array();
+		$sql = "SHOW TABLES IN " . $db;
+		$this->db->setQuery($sql);
+		while ($row = $this->db->fetch()) {
+			$tableName = $row['Tables_in_' . $db];
+			$insert = true;
+			if (!empty($table)) $insert = stristr($tableName, $table) ? true : false;
+			if ($insert) $tables[] = $tableName;
+		}
+		return $tables;
+	}
+
+	/**
+	 * 匹配类型并返回类型字段长度
+	 * @param string $type
+	 * @return Array
+	 */
+	public function parseType($type)
+	{
+		preg_match("/(.*)\(.*?\)/", $type, $matches);
+		$data = array();
+		$data['source'] = $type;
+		$data['type'] = isset($matches[1]) ? $matches[1] : $type;
+		$ext = isset($matches[1]) ? str_replace(array($data['type'] . '(', ')'), '', $type) : 0;
+
+		if ($data['type'] == 'enum') {
+			$data['length'] = 0;
+			$data['sets'] = $ext;
+			$data['setsArray'] = preg_replace("/\"|\'/", "", explode(",", $ext));
+		} else {
+			$data['length'] = (int)$ext;
+		}
+		return $data;
+	}
+
+	/**
+	 * 获取数据库中某个表的字段
+	 * @param string $db
+	 * @param string $table
+	 * @return array 表中的字段列表
+	 */
+	public function getFieldsLists($db = 'istudy', $table)
+	{
+		$fields = array();
+		$sql = 'DESC ' . $db . '.' . $table;
+		$this->db->setQuery($sql);
+		while ($row = $this->db->fetch()) {
+			$val = array();
+			$val['field'] = $row['Field'];
+			$val['null'] = strtolower($row['Null']);
+			$matches = $this->parseType($row['Type']);
+			$val['length'] = 0;
+			$val['type'] = $row['Type'];
+			if (isset($matches['length'])) {
+				$val['length'] = intval($matches['length']);
+				$val['type'] = $matches['type'];
+			}
+			if ($matches['type'] == 'enum') {
+				$val['sets'] = $matches['sets'];
+				$val['setsArray'] = $matches['setsArray'];
+			}
+			$val['length'] = intval($matches['length']);
+			if ($row['Null'] == 'NO') $val['require'] = true;
+			if ($row['Key'] != '') {
+				if ($row['Key'] == 'PRI') $val['pri'] = true;//主键,用于查询用
+				if ($row['Key'] == 'UNI') $val['uni'] = true;
+			}
+			if ($row['Default']) $val['default'] = $row['Default'];
+			if ($row['Extra']) $val['extra'] = $row['Extra'];
+			$fields[$row['Field']] = $val;
+		}
+		return $fields;
+	}
+
+	/**
+	 * 获取指定数据库、数据表的规则
+	 * @param  string $database 数据库
+	 * @param  string $table 数据表
+	 * @return array  返回表的显示规则
+	 */
+	public function getRules($database, $table)
+	{
+		if (!$database || !$table) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$rules = (new \Qii\Driver\Easy())->_initialize();
+		$rules->setPrivateKey(array('database', 'table'));
+		$rules->setRules(new \Qii\Driver\Rules($this->getRuleTableInfo()));
+		$rules->database = $database;
+		$rules->table = $table;
+		$tableRules = $rules->_exist();
+		$tableRule = array();
+		$tableRule['rules'] = array();
+		if (!$tableRules->isError()) {
+			$tableRule = $tableRules->getResult();
+			$rule = isset($tableRule['rules']) ? $tableRule['rules'] : '';
+			if ($rule != '') {
+				$tableRule['rules'] = json_decode($rule, true);
+			} else {
+				$tableRule['rules'] = array();
+			}
+		}
+		$defaultRules = $this->tableRules($database, $table);
+		if ($defaultRules['rules']) $tableRule['rules'] = array_merge($defaultRules['rules'], $tableRule['rules']);
+		return $tableRule;
+	}
+
+	/**
+	 * 保存数据库表的显示规则
+	 * @param  string $database 数据库
+	 * @param  string $table 数据表
+	 * @param  string $rule 显示规则
+	 * @return bool 保存成功或失败
+	 */
+	public function saveRules($database, $table, array $rule)
+	{
+		$rules = (new \Qii\Driver\Easy())->_initialize();
+		$rules->setPrivateKey(array('database', 'table'));
+		$rules->setRules(new \Qii\Driver\Rules($this->getRuleTableInfo()));
+		$rules->database = $database;
+		$rules->table = $table;
+
+		$isExists = $rules->_exist();
+		if ($isExists->isError()) {
+			$this->tablesError = $isExists->getErrors();
+			return false;
+		}
+		if (isset($isExists->getResult()['database'])) {
+			//保存额外的规则,确保更新不影响
+			$databaseRules = $this->getRules($database, $table);
+			if (isset($databaseRules['rules']['invalidMessage']) && is_array($databaseRules['rules']['invalidMessage'])) {
+				$rule['invalidMessage'] = $databaseRules['rules']['invalidMessage'];
+			}
+			if (isset($databaseRules['rules']['extRules']) && is_array($databaseRules['rules']['extRules'])) {
+				$rule['extRules'] = $databaseRules['rules']['extRules'];
+			}
+			$rules->rules = json_encode($rule);
+			$rules->update_time = time();
+			//更新
+			$result = $rules->_update();
+		} else {
+			$rules->rules = json_encode($rule);
+			$rules->add_time = time();
+			$result = $rules->_save();
+		}
+		$result = true;
+		if ($rules->getErrors()) {
+			$result = false;
+			$this->tablesError = $rules->getErrors();
+		}
+		return $result;
+	}
+
+	/**
+	 * 更新数据表规则
+	 *
+	 * @param string $database 数据库名称
+	 * @param string $table 数据表名称
+	 * @param array $rule 规则
+	 * @return bool
+	 */
+	public function updateRules($database, $table, array $rule)
+	{
+		if (!$database || !$table) {
+			$this->tablesError = '参数不正确';
+			return false;
+		}
+		$databaseRules = $this->getRules($database, $table);
+		if (!isset($databaseRules['rules']) || !is_array($databaseRules['rules'])) {
+			$this->tablesError = '规则不存在';
+			return false;
+		}
+		$rule = array_merge($databaseRules['rules'], $rule);
+		$rules = (new \Qii\Driver\Easy())->_initialize();
+		$rules->setPrivateKey(array('database', 'table'));
+		$rules->setRules(new \Qii\Driver\Rules($this->getRuleTableInfo()));
+		$rules->database = $database;
+		$rules->table = $table;
+		$rules->rules = json_encode($rule);
+
+		$isExists = $rules->_exist();
+		if ($isExists->isError()) {
+			$this->tablesError = $isExists->getError();
+			return false;
+		}
+		if ($isExists->getResult()['database']) {
+			$rules->update_time = time();
+			//更新
+			$result = $rules->_update();
+		} else {
+			$rules->add_time = time();
+			$result = $rules->_save();
+		}
+		$result = true;
+		if ($rules->isError()) {
+			$result = false;
+			$this->tablesError = $rules->getErrors();
+		}
+		return $result;
+	}
+
+	/**
+	 * 自动表的规则
+	 *
+	 * @param $database
+	 * @param $tableName
+	 * @return array
+	 */
+	public function tableRules($database, $tableName)
+	{
+		if (!$database || !$tableName) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$data = array();
+		$rules = $this->getFieldsLists($database, $tableName);
+		$data['database'] = $database;
+		$data['tableName'] = $tableName;
+		$data['rules'] = array();
+		$data['rules']['end'] = array();
+		$data['rules']['front'] = array();
+		$data['rules']['alias'] = array();
+		$data['rules']['fields'] = array();
+		foreach ($rules AS $key => $val) {
+			$data['rules']['fields'][] = $key;
+			$data['rules']['end'][$key] = $data['rules']['front'][$key] = 1;
+			$data['rules']['alias'][$key] = $key;
+			$data['rules']['length'][$key] = $val['length'];
+			$data['rules']['type'][$key] = $val['type'];
+			$data['rules']['null'][$key] = $val['null'];
+			if (isset($val['sets'])) $data['rules']['sets'][$key] = $val['sets'];
+			if (isset($val['setsArray'])) $data['rules']['setsArray'][$key] = $val['setsArray'];
+			if (isset($val['pri'])) $data['rules']['pri'][$key] = 1;
+			if (isset($val['uni'])) $data['rules']['uni'][$key] = 1;
+		}
+		if (!isset($data['rules']['validate'])) $data['rules']['validate'] = array();
+		return $data;
+	}
+
+	/**
+	 * 合并表的规则,当没有存储相关规则的时候就用系统默认规则
+	 *
+	 * @param $database
+	 * @param $tableName
+	 * @param $rules
+	 */
+	public function mergeRules($database, $tableName, &$rules)
+	{
+		$tableRules = $this->tableRules($database, $tableName);
+		$rules = array_merge($tableRules, $rules);
+		foreach ($tableRules['rules'] AS $key => $val) {
+			if (!isset($rules['rules'][$key]) || count($rules['rules'][$key]) == 0) $rules['rules'][$key] = $val;
+		}
+		return $rules;
+	}
+
+	/**
+	 * 自动合并数据表规则
+	 *
+	 * @param $database
+	 * @param $tableName
+	 * @return array
+	 */
+	public function autoRules($database, $tableName)
+	{
+		if (!$database || !$tableName) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$rules = $this->getRules($database, $tableName);
+		$this->mergeRules($database, $tableName, $rules);
+		return $rules;
+	}
+
+	/**
+	 * 获取数据表的数据
+	 *
+	 * @param $database 当前数据表
+	 * @param $tableName 当前表名称
+	 * @param int $currentPage 当前页码
+	 * @param int $pageSize 每一页数据条数
+	 * @return mixed
+	 */
+	public function loadTableData($database, $tableName, $currentPage = 1, $pageSize = 12)
+	{
+		if (!$database || !$tableName) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$currentPage = max(1, $currentPage);
+		$start = ($currentPage - 1) * $pageSize;
+		/*
+		$rules = $this->getRules($database, $tableName);
+		//当rules为空的时候,通过数据表结构自动生成规则
+		if(empty($rules['rules']))
+		{
+			$rules = $this->tableRules($database, $tableName);
+		}
+		else
+		{
+			$this->mergeRules($database, $tableName, $rules);
+		}*/
+		$rules = $this->autoRules($database, $tableName);
+		$data = array();
+		$data['rows'] = array();
+		$data['page'] = array('total' => 0, 'currentPage' => 0, 'totalPage' => 0);
+		$data['page']['total'] = $this->db->getOne("SELECT COUNT(*) FROM {$database}.{$tableName}");
+		$data['page']['currentPage'] = $currentPage;
+		$data['page']['totalPage'] = ceil($data['page']['total'] / $pageSize);
+		$sql = "SELECT * FROM {$database}.{$tableName} LIMIT " . $start . ',' . $pageSize;
+		$this->db->setQuery($sql);
+		$rulesCount = isset($rules['rules']['end']) && count($rules['rules']['end']) > 0 ? $rules['rules']['end'] : 0;
+		while ($row = $this->db->fetch()) {
+			$val = array();
+			if ($rulesCount > 0) {
+				foreach ($rules['rules']['end'] AS $key => $field) {
+					if ($field == 1) $val[$key] = $row[$key];
+				}
+			}
+			$updateFields = array();
+			$priKeys = array();
+			foreach ($rules['rules']['pri'] AS $key => $pri) {
+				$priKeys[] = $key;
+				$updateFields[$key] = $row[$key];
+			}
+			//为了避免表中字段跟主要参数冲突,主要参数前边添加两个下划线
+			$updateFields['__pri'] = join(',', $priKeys);
+			$updateFields['__database'] = $database;
+			$updateFields['__tableName'] = $tableName;
+			$val['__updateFields'] = http_build_query($updateFields);
+			$data['rows'][] = $val;
+			unset($val);
+		}
+		$data['rules'] = $rules['rules'];
+		return $data;
+	}
+
+	/**
+	 * 获取表中的数据
+	 * @author Jinhui Zhu 2015-08-26
+	 * @param string $database
+	 * @param string $tableName
+	 * @param string $pri
+	 * @param Array $val
+	 * @return mixed
+	 */
+	public function loadDataFromTable($database, $tableName, $pri, $val)
+	{
+		if (!$database || !$tableName || (!$val && count($val) == 0)) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		return $this->db->whereArray($val)->selectRow($database . '.' . $tableName);
+	}
+
+	/**
+	 * 更新数据表数据
+	 * @param string $database
+	 * @param string $tableName
+	 * @param array $priVal
+	 * @param array $fields
+	 * @return bool
+	 */
+	public function updateTableData($database, $tableName, $priVal, $fields)
+	{
+		if (!$database || !$tableName || !$fields) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$rules = $this->autoRules($database, $tableName);
+		$privateKey = array();
+		if (empty($priVal) && isset($rules['rules']['uni'])) $privateKey = array_keys($rules['rules']['uni']);
+		$table = (new \Qii\Driver\Easy())->_initialize();
+		$table->setPrivateKey($priVal);
+		$table->setRules(new \Qii\Driver\Rules($rules));
+		foreach ($fields AS $key => $val) {
+			$table->{$key} = $val;
+		}
+		return $result = $table->_update();
+	}
+
+	/**
+	 * 删除指定数据表中数据
+	 * 避免删除整张表的数据,验证val,如果为空就不删除
+	 * @param string $database
+	 * @param string $tableName
+	 * @param array $val {key : val}
+	 * @return bool
+	 */
+	public function removeTableData($database, $tableName, $val)
+	{
+		if (empty($val)) {
+			$this->tablesError = '参数不正确';
+			return false;
+		}
+		return $this->db->deleteObject($database . '.' . $tableName, $val);
+	}
+
+	/**
+	 * 向指定数据库中插入数据
+	 *
+	 * @param $database
+	 * @param $tableName
+	 * @param $value
+	 */
+	public function addTableData($database, $tableName, $value)
+	{
+		if (!$database || !$tableName || !$value) {
+			$this->tablesError = '参数不正确';
+			return array();
+		}
+		$rules = $this->autoRules($database, $tableName);
+		//去掉自动privateKey,通过配置文件来做
+		//$privateKey = array();
+		//if(isset($rules['rules']['uni'])) $privateKey = array_keys($rules['rules']['uni']);
+		$table = (new \Qii\Driver\Easy())->_initialize();
+		//$table->setPrivateKey($privateKey);
+		$table->setRules(new \Qii\Driver\Rules($rules));
+		foreach ($value AS $key => $val) {
+			$table->{$key} = $val;
+		}
+		try {
+			$result = $table->_save();
+			if ($result->isError()) {
+				return $result;
+			}
+			return Response::Success('addTableData', '操作成功');
+		} catch (\Exception $e) {
+			$msg = strip_tags($e->getMessage());
+			return Response::Instance(10010, 'addTableData', array('message' => $msg));
+		}
+	}
+
+	/**
+	 * 备份指定数据表
+	 *
+	 * @param $database  数据库名称
+	 * @param $tableName  数据表名称
+	 * @return string
+	 */
+	public function backupTable($database, $tableName)
+	{
+		$sql = "SELECT * FROM {$database}.{$tableName}";
+		$rs = $this->db->setQuery($sql);
+		$data = array();
+		$backupSQL = "USE {$database};\n";
+		$tableSQL = $this->getTableSQL($database, $tableName);
+		if ($tableSQL['sql'] == '') _e('获取数据表错误', __LINE__);
+		$backupSQL .= $tableSQL['sql'];
+		$i = 0;
+		$fields = array();
+		while ($row = $this->db->fetch($rs)) {
+			$fields = array_keys($row);
+			$row = array_map('addslashes', $row);
+			$data[] = '(\'' . join("','", $row) . '\')';
+			if ($i == 500) {
+				//执行一次合并操作
+				$backupSQL .= "\nINSERT INTO {$database}.{$tableName}(`" . join('`, `', $fields) . "`) VALUES " . join(', ', $data) . ";\n";
+				$data = array();
+				$i = 0;
+			} else {
+				$i++;
+			}
+		}
+		if (count($data) > 0) {
+			$backupSQL .= "\nINSERT INTO {$database}.{$tableName}(`" . join('`, `', $fields) . "`) VALUES " . join(', ', $data) . ";\n";
+		}
+		return $backupSQL;
+	}
+
+	/**
+	 * 还原数据
+	 *
+	 * @param $database  数据库名
+	 * @param $tableName  数据表名
+	 * @param $fileName  文件名
+	 * @return array|void
+	 */
+	public function restore($database, $tableName, $fileName)
+	{
+		$data = array();
+		$data['code'] = 1;
+		if (!$data || !$tableName || !$fileName) {
+			$data['msg'] = '参数错误或文件错误';
+			return $data;
+		}
+		$contents = file_get_contents($fileName);
+		$tableSQL = explode(';', $contents);
+		if (count($tableSQL) == 0) {
+			$data['msg'] = '上传的文件无相关据';
+			return $data;
+		}
+		try {
+			foreach ($tableSQL AS $sql) {
+				$sql = trim($sql);
+				if ($sql == '') continue;
+				$this->db->setQuery($sql);
+			}
+			$data['code'] = 0;
+			$data['msg'] = '成功';
+		} catch (\Exception $e) {
+			$data['code'] = $e->getCode();
+			$data['msg'] = strip_tags($e->getMessage());
+		}
+		return $data;
+	}
+}

+ 46 - 0
demo/private/view/error.html

@@ -0,0 +1,46 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>{#if $code == 0#}提示{#else#}出错了{#/if#}</title>
+<link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="{#helper\globals::getJs("jquery")#}"></script>
+
+<script language="javascript">
+	$(function(){
+    $('.error').css({'position':'absolute','left':($(window).width()-490)/2});
+	$(window).resize(function(){  
+    $('.error').css({'position':'absolute','left':($(window).width()-490)/2});
+    })  
+});  
+</script> 
+
+
+</head>
+
+
+<body style="background:#edf6fa;">
+
+	<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+    <li><a href="{#helper\globals::getFullUrl("main/index")#}">首页</a></li>
+    <li>{#if $code == 0#}提示{#else#}错误提示{#/if#}</li>
+    </ul>
+    </div>
+    
+    <div class="error {#if $code == 404#}error404{#/if#}">
+    
+    <h2>{#if $code != 0#}非常遗憾,{#/if#}{#$desc|default:'您访问的页面存在问题!'#}</h2>
+    <p>{#if $code != 0#}看到这个提示,就自认倒霉吧!{#/if#}</p>
+    {#if $code != 0#}
+    <div class="reindex"><a href="{#helper\globals::getFullUrl("/main/index")#}" target="_parent">返回首页
+    {#/if#}
+    </a></div>
+    
+    </div>
+
+
+</body>
+
+</html>

+ 103 - 0
demo/private/view/manage/data/add.html

@@ -0,0 +1,103 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>数据编辑器</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs('xheditor/xheditor-1.2.2.min')#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs('xheditor/xheditor_lang/zh-cn')#}"></script>
+	<script>
+	$(document).ready(function(){
+		$("#modifyForm").submit(function()
+		{
+			$('input').removeClass('input_error');
+			$.post($(this).attr('action'), $(this).serialize(), function(r)
+		    {
+				if(r == null)
+				{
+					$.notify("系统错误,请重试", "error");
+				};
+
+				if(typeof r.code != 'undefined' && r.code == 0)
+		        {
+					$.notify("保存成功", "success");
+		        }
+		        else
+		        {
+					$.notify((r.error || "保存失败"), "error");
+                    if(r.error && r.error.fields)
+                    {
+                        for(var field in r.error.fields)
+                        {
+                            $('input[name="fields['+field+']"]').addClass('input_error');
+                        }
+                    }
+                    if(r.error && r.error.opt && r.error.opt._save)
+                    {
+                    	$.notify(r.error.opt._save, "error");
+                    }
+		        }
+			}, 'json');
+			return false;
+		});
+	});
+	</script>
+</head>
+
+<body>
+
+<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+        <li><a href="{#$pathes.index#}">首页</a></li>
+        <li><a href="{#helper\globals::getFullUrl("database/creator")#}?database={#$database#}&tableName={#$tableName#}">规则管理</a></li>
+        <li><a href="{#$pathes.table#}?database={#$database#}&tableName={#$tableName#}">数据管理</a></li>
+        <li>添加数据</li>
+    </ul>
+</div>
+
+<div class="formbody">
+
+    <div class="formtitle"><span>基本信息</span></div>
+    <form name="modifyForm" id="modifyForm" method="POST" action="{#helper\globals::getFullUrl("api/database/add", ".json")#}?isAjax=1">
+		{#helper\globals::safeForm()#}
+		<input type="hidden" name="database" value="{#$database#}" id="database" />
+		<input type="hidden" name="tableName" value="{#$tableName#}" id="tableName" />
+	    <ul class="forminfo">
+	        {#foreach key=key item=item from=$fields#}
+	        <li><label>{#if isset($rules['rules']['alias'][$key]) && $rules['rules']['alias'][$key] != ''#}{#$rules['rules']['alias'][$key]#}{#else#}{#$key#}{#/if#}</label>
+	            {#if $rules['rules']['type'][$key] == 'mediumtext' || $rules['rules']['type'][$key] == 'text'#}
+	            <textarea name="fields[{#$key#}]" cols="100" rows="20" class="textinput {#if helper\globals::hasHtmlTag($item)#}xheditor{#/if#}"></textarea>
+	            {#else if $rules['rules']['type'][$key] == 'enum'#}
+	            <div class="vocation">
+	            <select class="select1" name="fields[{#$key#}]" id="fields[{#$key#}]">
+	            {#foreach key=set item=sitem from=$rules['rules']['setsArray'][$key]#}
+	            	<option value="{#$sitem#}"  {#if $item == $sitem#}selected{#/if#}>{#$sitem#}</option>
+	            {#/foreach#}
+	            </select>
+	            </div>
+	            {#else#}
+	            <input name="fields[{#$key#}]" type="text" class="dfinput" value="" />
+	            {#/if#}
+	            <i>{#if isset($rules['rules']['length'][$key]) && $rules['rules']['length'][$key] > 0 #}最大长度{#$rules['rules']['length'][$key]#}个字符{#else#}{#/if#}</i></li>
+	        {#/foreach#}
+	        <li><label>&nbsp;</label><input name="submit" type="submit" class="btn" value="确认保存"/></li>
+	    </ul>
+    </form>
+
+</div>
+<script>
+$('.xheditor').xheditor({skin:'nostyle'});
+$(".select1").uedSelect({
+	width : 345			  
+});
+</script>
+
+</body>
+
+</html>

+ 15 - 0
demo/private/view/manage/data/code.html

@@ -0,0 +1,15 @@
+<?php
+namespace Model;
+
+use \Qii\Model;
+
+class {#$code.className#} extends Model
+{
+	public function __construct()
+	{
+		parent::__construct();
+		$this->setRules(new \Qii\Driver\Rules(\Qii\Import::includes('configure/table/{#$code.database#}.{#$code.className#}.config.php')));
+	}
+}
+
+?>

+ 0 - 0
demo/private/view/manage/data/core.html


+ 185 - 0
demo/private/view/manage/data/creator.html

@@ -0,0 +1,185 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>规则生成</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("jquery.multiSelect")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.bgiframe.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.multiSelect")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+
+    <script type="text/javascript">
+            $(document).ready(function(){
+				$(".multi").multiSelect({selectAllText: '选择所有', noneSelected: '请选择', oneOrMoreSelected:'共选择%项'});
+
+				$("#creatorForm").submit( function()
+                {
+					$.post($(this).attr('action'), $(this).serialize(), function(r)
+                    {
+						if(typeof r.code != 'undefined' && r.code == 0)
+                        {
+							$.notify("保存成功", "success");
+                        }
+                        else
+                        {
+							$.notify("保存失败", "error");
+                        }
+					}, 'json');
+					return false;
+				});
+				
+	            $('input[name="download"]').on('click', function(){
+	            	var database = $('input[name="database"]').val();
+	            	var tableName = $('input[name="tableName"]').val();
+	            	var url = '{#helper\globals::getFullUrl("api/database/downloadConfig", ".json")#}?database='+ database + '&tableName='+ tableName;
+	            	window.location.href = url;
+	            });
+                $('input[name="creatBasicCode"]').on('click', function(){
+                    var database = $('input[name="database"]').val();
+                    var tableName = $('input[name="tableName"]').val();
+                    var url = '{#helper\globals::getFullUrl("api/database/creatBasicCode", ".json")#}?database='+ database + '&tableName='+ tableName;
+                    window.location.href = url;
+                });
+            });
+    </script>
+
+
+</head>
+
+
+<body>
+
+{#if $loadDatabase#}
+<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+        <li><a href="{#$pathes.index#}">首页</a></li>
+        <li><a href="{#$pathes.creator#}?database={#$database#}&tableName={#$tableName#}">规则管理</a></li>
+        <li>规则生成器</a></li>
+    </ul>
+</div>
+{#/if#}
+<div class="rightinfo">
+    {#if $loadDatabase#}
+    <div class="tools">
+    	<select id="database" name="database" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/creator")#}?database='+ $('#database').val()}">
+    		<option value="">请选择数据库</option>
+            {#foreach key=key item=item from=$databases#}
+            <option value="{#$item#}" {#if $database == $item#}selected{#/if#}>{#$item#}</option>
+            {#/foreach#}
+    	</select>
+        <select name="tableName" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/creator")#}?tableName='+ this.value +'&database='+ $('#database').val() }">
+            <option>请选择数据表</option>
+            {#foreach key=key item=item from=$tables#}
+            <option value="{#$item#}" {#if $tableName == $item#}selected{#/if#}>{#$item#}</option>
+            {#/foreach#}
+        </select>
+        {#if $tables|count > 0#}
+        <a href="{#helper\globals::getFullUrl("database/table")#}?database={#$database#}&tableName={#$tableName#}">数据管理</a>
+        {#/if#}
+    </div>
+    {#/if#}
+    {#if $fields#}
+    <form name="creatorForm" id="creatorForm" action="{#helper\globals::getFullUrl("api/database/creator", ".json")#}?isAjax=1" method="POST">
+    {#helper\globals::safeForm()#}
+    <input type="hidden" name="tableName" value="{#$tableName#}"  />
+    <input type="hidden" name="database" value="{#$database#}"  />
+    <table class="tablelist">
+        <thead>
+        <tr>
+            <th>字段名</th>
+            <th>显示名</th>
+            <th><input type="checkbox" name="selectFrontAll">前端使用</th>
+            <th><input type="checkbox" name="selectEndAll">后端使用</th>
+            <th>默认值</th>
+            <th>验证类型</th>
+            <th><input type="checkbox" name="selectSaveAll">保存验证</th>
+            <th><input type="checkbox" name="selectSaveAllValid">保存查询字段</th>
+            <th><input type="checkbox" name="selectUpdateAll">更新验证</th>
+            <th><input type="checkbox" name="selectUpdateAllValid">更新查询字段</th>
+            <th><input type="checkbox" name="selectRemoveAll">删除验证</th>
+            <th><input type="checkbox" name="selectRemoveAllValid">删除查询字段</th>
+        </tr>
+        </thead>
+        <tbody>
+        {#foreach item=item key=key from=$fields#}
+    	<input type="hidden" name="{#$tableName#}[length][{#$key#}]" value="{#$item.length#}"  />
+    	<input type="hidden" name="{#$tableName#}[type][{#$key#}]" value="{#$item.type#}"  />
+        <input type="hidden" name="{#$tableName#}[fields][]" value="{#$key#}" />
+    	{#if isset($item.pri)#}<input type="hidden" name="{#$tableName#}[pri][{#$key#}]" value="{#$item.pri#}"  />{#/if#}
+    	{#if isset($item.uni)#}<input type="hidden" name="{#$tableName#}[uni][{#$key#}]" value="{#$item.uni#}"  />{#/if#}
+        <tr>
+            <td>{#$key#}</td>
+            <td><input type="text" name="{#$tableName#}[alias][{#$key#}]" class="dfinputmin" value="{#if isset($rules['alias'][$key])#}{#$rules['alias'][$key]#}{#/if#}" /></td>
+            <td><input class="selectFrontFields" type="checkbox" name="{#$tableName#}[front][{#$key#}]" value="1" {#if isset($rules['front'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectEndFields" type="checkbox" name="{#$tableName#}[end][{#$key#}]" value="1" {#if isset($rules['end'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input type="text" name="{#$tableName#}[default][{#$key#}]" class="dfinputmin" value="{#if isset($rules['default'][$key])#}{#$rules['default'][$key]#}{#elseif isset($item.default)#}{#$item.default#}{#/if#}" /></td>
+            <td>
+			<select id="{#$tableName#}[validate][{#$key#}]" name="{#$tableName#}[validate][{#$key#}]" class="multi" multiple="multiple" size="1">
+                	<option value=""></option>
+                    {#foreach from=$validate key=k item=v#}
+					<option value="{#$k#}"{#if isset($validateRules[$key]) && ($k|in_array:$validateRules[$key])#} selected{#/if#}>{#$v#}</option>
+                    {#/foreach#}
+                </select>
+            </td>
+            <td><input class="selectSaveFields" type="checkbox" name="{#$tableName#}[save][{#$key#}]" value="1" {#if isset($rules['save'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectSaveFieldsValid" type="checkbox" name="{#$tableName#}[saveValid][{#$key#}]" value="1" {#if isset($rules['saveValid'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectUpdateFields" type="checkbox" name="{#$tableName#}[update][{#$key#}]" value="1" {#if isset($rules['update'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectUpdateFieldsValid" type="checkbox" name="{#$tableName#}[updateValid][{#$key#}]" value="1" {#if isset($rules['updateValid'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectRemoveFields" type="checkbox" name="{#$tableName#}[remove][{#$key#}]" value="1" {#if isset($rules['remove'][$key])#} checked="checked"{#/if#} /></td>
+            <td><input class="selectRemoveFieldsValid" type="checkbox" name="{#$tableName#}[removeValid][{#$key#}]" value="1" {#if isset($rules['removeValid'][$key])#} checked="checked"{#/if#} /></td>
+        </tr>
+        {#/foreach#}
+        </tbody>
+    </table>
+
+
+    <div class="pagin">
+        <div class="message">&nbsp;</div>
+        <ul class="paginList">
+           <li><input type="button" name="rulesManager" value="详细规则管理" class="btn" /> <input type="submit" name="submit" value="保存规则" class="btn" /> <input type="button" name="download" value="下载规则" class="btn" /> <input type="button" name="creatBasicCode" value="生成基础代码" class="btn" /></li>
+        </ul>
+    </div>
+    {#/if#}
+	</form>
+</div>
+
+<script type="text/javascript">
+    $('.tablelist tbody tr:odd').addClass('odd');
+    $('input[name="rulesManager"]').on('click', function(){
+    	window.location.href = '{#helper\globals::getFullUrl("database/rules")#}?database={#$database#}&tableName={#$tableName#}';
+    });
+    $('input[name="selectFrontAll"]').on('click', function(){
+    	$('.selectFrontFields').prop('checked', $('input[name="selectFrontAll"]').prop('checked'));
+    });
+    $('input[name="selectEndAll"]').on('click', function(){
+    	$('.selectEndFields').prop('checked', $('input[name="selectEndAll"]').prop('checked'));
+    });
+    $('input[name="selectSaveAll"]').on('click', function(){
+    	$('.selectSaveFields').prop('checked', $('input[name="selectSaveAll"]').prop('checked'));
+    });
+    $('input[name="selectSaveAllValid"]').on('click', function(){
+    	$('.selectSaveFieldsValid').prop('checked', $('input[name="selectSaveAllValid"]').prop('checked'));
+    });
+    $('input[name="selectUpdateAll"]').on('click', function(){
+    	$('.selectUpdateFields').prop('checked', $('input[name="selectUpdateAll"]').prop('checked'));
+    });
+    $('input[name="selectUpdateAllValid"]').on('click', function(){
+    	$('.selectUpdateFieldsValid').prop('checked', $('input[name="selectUpdateAllValid"]').prop('checked'));
+    });
+    $('input[name="selectRemoveAll"]').on('click', function(){
+    	$('.selectRemoveFields').prop('checked', $('input[name="selectRemoveAll"]').prop('checked'));
+    });
+    $('input[name="selectRemoveAllValid"]').on('click', function(){
+    	$('.selectRemoveFieldsValid').prop('checked', $('input[name="selectRemoveAllValid"]').prop('checked'));
+    });
+</script>
+</body>
+
+</html>

+ 22 - 0
demo/private/view/manage/data/pages.html

@@ -0,0 +1,22 @@
+<script type="text/javascript" src="{#helper\globals::getJs("pages")#}"></script>
+<div class="pagin" data-js="page" data-total="{#$pagesData.totalPage#}" data-current="{#$pagesData.currentPage#}" data-ref="{#$pagesRef#}">
+<div class="message">{#if $pagesData.total > 0#}共&nbsp;<i class="blue">{#$pagesData.total#}</i>&nbsp;条记录{#else#}无相关记录{#/if#},当前显示第&nbsp;<i class="blue"><span class="inner" data-page="{#$pagesData.currentPage#}">{#$pagesData.currentPage#}</span>&nbsp;{#if $pagesData.totalPage >= 1#}/&nbsp;<span class="inner" data-page="{#$pagesData.totalPage#}">{#$pagesData.totalPage#}</span>{#/if#}</i>&nbsp;页</div>
+<ul class="paginList">
+    {#if $pagesData.totalPage > 1#}
+    <li class="paginItem" data-page="pre"><a href="javascript:;"><span class="{#if $pagesData.currentPage == 1 || $pagesData.totalPage == 1#}pagepre{#else#}pagepre_highlight{#/if#}"></span></a></li>
+    {#if $pagesData.currentPage - 5 > 1#}
+    <li data-page="less" class="paginItem less"><a href="javascript:;">...</a></li>
+    {#/if#}
+    {#section name="loop" loop=$pagesData.totalPage start=$start max=10 #}
+    <li data-page="{#$smarty.section.loop.index  + 1#}" class="paginItem {#if $smarty.section.loop.index + 1 == $pagesData.currentPage#}current{#/if#}"><a href="javascript:;">{#$smarty.section.loop.index  + 1#}</a></li>
+    {#/section#}
+    {#if $pagesData.totalPage >= $pagesData.currentPage + 10#}
+    <li data-page="more" class="paginItem more"><a href="javascript:;">...</a></li>
+    {#/if#}
+    <li data-page="next" class="paginItem"><a href="javascript:;"><span class="{#if $pagesData.totalPage == 1 || $pagesData.currentPage >= $pagesData.totalPage#}pagenxt{#else#}pagenxt_highlight{#/if#}"></span></a></li>
+    {#/if#}
+</ul>
+</div>
+<script>
+$('[data-js=page]').pages({ref : 'data-ref', total : 'data-total', current : 'data-current'});
+</script>

+ 112 - 0
demo/private/view/manage/data/rules.html

@@ -0,0 +1,112 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>规则管理</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("jquery.multiSelect")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.bgiframe.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.multiSelect")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+
+    <script type="text/javascript">
+            $(document).ready(function(){
+				$(".multi").multiSelect({selectAllText: '选择所有', noneSelected: '请选择', oneOrMoreSelected:'共选择%项'}, function(el){
+
+				});
+
+				$("#creatorForm").submit( function()
+                {
+					$.post($(this).attr('action'), $(this).serialize(), function(r)
+                    {
+						if(typeof r.code != 'undefined' && r.code == 0)
+                        {
+                			$.notify("保存成功", "success");
+                        }
+                        else
+                        {
+                			$.notify("保存失败", "error");
+                        }
+					}, 'json');
+					return false;
+				});
+            });
+    </script>
+
+
+</head>
+
+
+<body>
+
+{#if $loadDatabase#}
+<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+        <li><a href="{#$pathes.index#}">首页</a></li>
+        <li><a href="{#$pathes.creator#}?database={#$database#}&tableName={#$tableName#}">规则管理</a></li>
+        <li>规则管理</li>
+    </ul>
+</div>
+{#/if#}
+<div class="rightinfo">
+    {#if $loadDatabase#}
+    <div class="tools">
+    	<select id="database" name="database" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/rules")#}?database='+ $('#database').val()}">
+    		<option value="">请选择数据库</option>
+            {#foreach key=key item=item from=$databases#}
+            <option value="{#$item#}" {#if $database == $item#}selected{#/if#}>{#$item#}</option>
+            {#/foreach#}
+    	</select>
+        <select name="tableName" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/rules")#}?tableName='+ this.value +'&database='+ $('#database').val() }">
+            <option value="">请选择数据表</option>
+            {#foreach key=key item=item from=$tables#}
+            <option value="{#$item#}" {#if $tableName == $item#}selected{#/if#}>{#$item#}</option>
+            {#/foreach#}
+        </select>
+        {#if $tables|count > 0#}
+        <a href="{#$pathes.table#}?database={#$database#}&tableName={#$tableName#}">数据管理</a>
+        {#/if#}
+    </div>
+    {#/if#}
+    {#if $fields#}
+    <form name="creatorForm" id="creatorForm" action="{#helper\globals::getFullUrl("api/database/rules", ".json")#}?isAjax=1" method="POST">
+    {#helper\globals::safeForm()#}
+    <input type="hidden" name="tableName" value="{#$tableName#}"  />
+    <input type="hidden" name="database" value="{#$database#}"  />
+    <ul class="forminfo">
+        {#foreach key=key item=item from=$validateRules#}
+        <li>
+            <label>{#if isset($rules['alias'][$key])#}{#$rules['alias'][$key]#}{#/if#}</label>
+            {#assign var=item value=$item#}
+            {#foreach key=k item=it from=$item#}
+            {#helper\globals::rules($it, $key, $validate, $invalidMessage, $extRules)#}
+            {#/foreach#}
+        </li>
+        {#foreachelse#}
+        <li><a href="{#$pathes.creator#}?database={#$database#}&tableName={#$tableName#}" class="red bold">请先添加规则,再设置详细规则,点击添加。</a></li>
+        {#/foreach#}
+        <li><label>&nbsp;</label><input name="submit" type="submit" class="btn" value="确认保存"/>  <input type="button" name="download" value="下载规则" class="btn" /></li>
+    </ul>
+    {#/if#}
+	</form>
+</div>
+
+<script type="text/javascript">
+    $('.tablelist tbody tr:odd').addClass('odd');
+
+    $('input[name="download"]').on('click', function(){
+        var database = '{#$database#}';
+        var tableName = '{#$tableName#}';
+        var url = '{#helper\globals::getFullUrl("api/database/downloadConfig", ".json")#}?database='+ database + '&tableName='+ tableName;
+        window.location.href = url;
+    });
+</script>
+</body>
+
+</html>

+ 146 - 0
demo/private/view/manage/data/table.html

@@ -0,0 +1,146 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>数据生成器</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("jquery.multiSelect")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("ajaxfileupload")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.bgiframe.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.multiSelect")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getSourceFullUrl("static/layer/layer.js")#}"></script>
+</head>
+
+
+<body>
+{#if $loadDatabase#}
+<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+        <li><a href="{#$pathes.index#}">首页</a></li>
+        <li><a href="{#helper\globals::getFullUrl("database/creator")#}?database={#$database#}&tableName={#$tableName#}">规则管理</a></li>
+        <li>数据管理</li>
+    </ul>
+</div>
+{#/if#}
+<div class="rightinfo">
+    {#if $loadDatabase#}
+    <div class="tools">
+        <select id="database" name="database" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/table")#}?database='+ $('#database').val()}">
+        <option value="">请选择数据库</option>
+        {#foreach key=key item=item from=$databases#}
+        <option value="{#$item#}" {#if $database == $item#}selected{#/if#}>{#$item#}</option>
+        {#/foreach#}
+        </select>
+        <select name="tableName" onchange="if(this.value != ''){window.location.href = '{#helper\globals::getFullUrl("database/table")#}?tableName='+ this.value +'&database='+ $('#database').val() }">
+        <option value="">请选择数据表</option>
+        {#foreach key=key item=item from=$tables#}
+        <option value="{#$item#}" {#if $tableName == $item#}selected{#/if#}>{#$item#}</option>
+        {#/foreach#}
+        </select>
+        {#if $tables|count > 0#}
+        <a href="{#helper\globals::getFullUrl("database/add")#}?database={#$database#}&tableName={#$tableName#}">添加数据</a>
+        {#/if#}
+    </div>
+    {#/if#}
+    {#if $tableName#}
+    <table class="tablelist">
+        <thead>
+        <tr>
+            {#foreach key=rkey item=ritem from=$data.rules.end#}
+            <th>{#if isset($data.rules.alias[$rkey]) && $data.rules.alias[$rkey] != ''#}{#$data.rules.alias[$rkey]#}{#else#}{#$rkey#}{#/if#}</th>
+            {#/foreach#}
+            {#if !$data.rules#}
+            <th><a href="{#helper\globals::getFullUrl("database/creator")#}?database={#$database#}&tableName={#$tableName#}">请先去数据生成器中生成数据</a></th>
+            {#else#}
+            <th>操作</th>
+            {#/if#}
+        </tr>
+        </thead>
+        <tbody>
+        {#foreach key=key item=item from=$data.rows#}
+        <tr>
+            {#foreach key=rkey item=ritem from=$data.rules.end#}
+            <td>{#if isset($item[$rkey])#}{#$item[$rkey]|strip_tags|trim|htmlspecialchars|truncate:50#}{#else#}&nbsp;{#/if#}</td>
+            {#/foreach#}
+            <td><a data-operate="modify" data-src="{#$item['__updateFields']#}">修改</a> <a data-operate="remove" data-src="{#$item['__updateFields']#}">删除</a></td>
+        </tr>
+        {#/foreach#}
+        </tbody>
+    </table>
+    
+    {#include file="manage/data/pages.html" pagesData=$pages pagesRef="{#helper\globals::getFullUrl("database/$_action")#}?database={#$database#}&tableName={#$tableName#}"#}
+    </form>
+    <div class="pagin">
+        <div class="message">&nbsp;</div>
+        <ul class="paginList">
+            <li>
+                <input type="file" id="fileUpload" name="restoreSQL" value=""/>
+                <input type="button" name="restoreTable" value="还原数据" class="btn" />
+                <input type="button" name="backupTable" value="备份数据" class="btn" />
+            </li>
+        </ul>
+    </div>
+    {#/if#}
+</div>
+
+<script type="text/javascript">
+    $('.tablelist tbody tr:odd').addClass('odd');
+    $('[data-operate=modify]').on('click', function(){
+        var pri = $(this).attr('data-src');
+        var url = '{#helper\globals::getFullUrl("database/update")#}?' + pri;
+        window.location.href = url;
+    });
+    $('[data-operate=remove]').on('click', function(){
+        var pri = $(this).attr('data-src');
+        var url = '{#helper\globals::getFullUrl("api/database/table")#}?operate=remove&database={#$database#}&tableName={#$tableName#}';
+        layer.confirm("数据一旦删除,将无法恢复,请确认", {
+          btn: ['确认','取消'] //按钮
+        }, function(){
+            $.get(url, pri, function(r){
+                    if(typeof r.code != 'undefined' && r.code == 0){
+                        r.code == 0 ? layer.msg('删除成功') : layer.msg(data.msg);
+                        setTimeout(function(){window.location.href = window.location.href;}, 2000);
+                    }else{
+                        layer.msg("删除失败");
+                    }
+                }, 'json');
+        });
+    });
+    $('input[name=backupTable]').on('click', function(){
+    	window.location.href = "{#\helper\globals::getFullUrl('api/database/backup')#}?database={#$database#}&tableName={#$tableName#}";
+    });
+    $('input[name=restoreTable]').on('click', function(){
+        var data = {};
+        data.database = '{#$database#}';
+        data.tableName = '{#$tableName#}';
+        data.security_sid = '{#\Qii::getSecurity()#}'
+        $.ajaxFileUpload({
+            url : '{#\helper\globals::getFullUrl('api/database/restore')#}?random='+ Math.random(),
+            data : data,
+            type : 'POST',
+            secureuri : false,
+            fileElementId : 'fileUpload',
+            dataType : 'json',
+            success : function(msg){
+                if(msg.code == 0){
+                	$.notify("还原成功", "success");
+                	return;
+                }
+                $.notify(msg.msg, "error");
+            },
+            error : function(data, status, e){
+                $.notify("系统错误", "error");
+            }
+        });
+    });
+</script>
+</body>
+
+</html>

+ 96 - 0
demo/private/view/manage/data/update.html

@@ -0,0 +1,96 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>数据编辑器</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs('xheditor/xheditor-1.2.2.min')#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs('xheditor/xheditor_lang/zh-cn')#}"></script>
+	<script>
+	$(document).ready(function(){
+		$("#modifyForm").submit(function()
+		{
+			$.post($(this).attr('action'), $(this).serialize(), function(r)
+		    {
+				if(r == null)
+				{
+					$.notify("系统错误,请重试", "error");
+				};
+				console.log(r);
+
+				if(typeof r.code != 'undefined' && r.code == 0)
+		        {
+					$.notify("保存成功", "success");
+		        }
+		        else
+		        {
+					$.notify("保存失败", "error");
+		        }
+			}, 'json');
+			return false;
+		});
+	});
+	</script>
+</head>
+
+<body>
+
+<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+        <li><a href="{#$pathes.index#}">首页</a></li>
+        <li><a href="{#$pathes.creator#}?database={#$database#}&tableName={#$tableName#}">规则管理</a></li>
+        <li><a href="{#$pathes.table#}?database={#$database#}&tableName={#$tableName#}">数据管理</a></li>
+        <li>数据编辑</li>
+    </ul>
+</div>
+
+<div class="formbody">
+
+    <div class="formtitle"><span>基本信息</span></div>
+    <form name="modifyForm" id="modifyForm" method="POST" action="{#helper\globals::getFullUrl("api/database/update", ".json")#}?isAjax=1">
+		{#helper\globals::safeForm()#}
+		<input type="hidden" name="__database" value="{#$database#}" id="__database" />
+		<input type="hidden" name="__tableName" value="{#$tableName#}" id="__tableName" />
+		<input type="hidden" name="__pri" value="{#$pri|join:","#}" id="__pri" />
+		{#foreach key=key item=item from=$val#}
+		<input type="hidden" name="{#$key#}" value="{#$item#}" />
+		{#/foreach#}
+	    <ul class="forminfo">
+	        {#foreach key=key item=item from=$data#}
+	        <li><label>{#if isset($rules['rules']['alias'][$key]) && $rules['rules']['alias'][$key] != ''#}{#$rules['rules']['alias'][$key]#}{#else#}{#$key#}{#/if#}</label>
+	            {#if isset($rules['rules']['type'][$key]) && ($rules['rules']['type'][$key] == 'mediumtext' || $rules['rules']['type'][$key] == 'text')#}
+	            <textarea name="fields[{#$key#}]" cols="100" rows="20" class="textinput overflow-auto {#if helper\globals::hasHtmlTag($item)#}xheditor{#/if#}">{#$item#}</textarea>
+	            {#else if isset($rules['rules']['type'][$key]) && $rules['rules']['type'][$key] == 'enum'#}
+	            <div class="vocation">
+	            <select class="select1" name="fields[{#$key#}]" id="fields[{#$key#}]">
+	            {#foreach key=set item=sitem from=$rules['rules']['setsArray'][$key]#}
+	            	<option value="{#$sitem#}"  {#if $item == $sitem#}selected{#/if#}>{#$sitem#}</option>
+	            {#/foreach#}
+	            </select>
+	            </div>
+	            {#else#}
+	            <input name="fields[{#$key#}]" type="text" class="dfinput" value="{#$item#}" />
+	            {#/if#}
+	            <i>{#if isset($rules['rules']['length'][$key]) && $rules['rules']['length'][$key] > 0 #}最大长度{#$rules['rules']['length'][$key]#}个字符{#else#}{#/if#}</i></li>
+	        {#/foreach#}
+	        <li><label>&nbsp;</label><input name="submit" type="submit" class="btn" value="确认保存"/></li>
+	    </ul>
+    </form>
+
+</div>
+<script>
+$('.xheditor').xheditor({skin:'nostyle'});
+$(".select1").uedSelect({
+	width : 345			  
+});
+</script>
+
+</body>
+
+</html>

+ 85 - 0
demo/private/view/manage/folder/dir.html

@@ -0,0 +1,85 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>文件管理</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("jquery.multiSelect")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.bgiframe.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.multiSelect")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getSourceFullUrl("static/layer/layer.js")#}"></script>
+</head>
+ <body>
+  <div class="place"> 
+   <span>位置:</span> 
+   <ul class="placeul"> 
+    <li><a href="{#$pathes.index#}">首页</a></li> 
+    <li><a href="{#\helper\globals::getFullUrl('/dirs')#}?path={#$defaultPath#}">文件管理</a></li> 
+    {#foreach item=item from=$visitPathes#}
+    <li><a href="{#$item.url#}">{#$item.name#}</a></li>
+    {#/foreach#}
+   </ul> 
+  </div> 
+  <table class="filetable"> 
+   <thead> 
+    <tr> 
+     <th width="25%">名称</th> 
+     <th width="21%">修改日期</th> 
+     <th width="10%">类型</th> 
+     <th width="6%">大小</th> 
+     <th width="38%">操作</th>
+    </tr> 
+   </thead> 
+   <tbody> 
+   {#foreach item=item from=$files#}
+    <tr data-js="link" data-url="{#$item.url#}"> 
+     <td><img src="{#$item.icon#}" />{#if $item.isImage#}<img src="{#$item.path#}" height="20" style="vertical-align:middle;" />{#/if#}<a href="{#$item.url#}">{#$item.name#}</a></td> 
+     <td>{#$item.updateAt|date_format:'Y-m-d H:i:s'#}</td> 
+     <td>{#if $item.type == 'folder'#}文件夹{#else#}文件{#/if#}</td> 
+     <td class="tdlast">{#$item.size#}</td> 
+     <td><a href="{#$item.url#}">查看</a>  <a data-js="remove" data-ref="{#$item.remove#}">删除</a></td>
+    </tr> 
+    {#foreachelse#}
+    <tr>
+    	<td colspan="5">此文件夹下没有文件</td>
+    </tr>
+    {#/foreach#}
+   </tbody> 
+  </table>
+  <script>
+  $('[data-js=link]').on('click', function(event){
+    if($(event.target).attr('data-js') == 'remove') return;
+  	window.location.href =$(this).attr('data-url');
+  });
+  $('[data-js=remove]').on('click', function(event){
+    var _this = $(this);
+    layer.confirm('确定要删除此文件?', {
+      btn: ['确认','取消'] //按钮
+    }, function(){
+      $.ajax({
+          url : _this.attr('data-ref'),
+          method : 'GET',
+          dataType : 'json',
+          success: function(data){
+            if(typeof data.code != 'undefined'){
+              data.code == 0 ? layer.msg('删除成功') : layer.msg(data.msg);
+              setTimeout(function(){window.location.href=window.location.href;}, 2000);
+            }else{
+              layer.msg(data);
+            }
+          },
+          error : function(){
+            layer.msg('系统错误');
+          }
+      });0 
+    });
+  });
+  </script>
+ </body>
+</html>

+ 57 - 0
demo/private/view/manage/folder/file.html

@@ -0,0 +1,57 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>文件管理</title>
+    <link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("select")#}" rel="stylesheet" type="text/css" />
+    <link href="{#helper\globals::getCss("jquery.multiSelect")#}" rel="stylesheet" type="text/css" />
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.idTabs.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("select-ui.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.bgiframe.min")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("jquery.multiSelect")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+    <link href="{#\helper\globals::getFullUrl('static/js/google-code-prettify/prettify', '.css')#}" type="text/css" rel="stylesheet" />
+    <script type="text/javascript" src="{#\helper\globals::getFullUrl('static/js/google-code-prettify/prettify', '.js')#}"></script>
+    <style>
+    pre span{display:inline;font-size:14px;}
+    pre.prettyprint{border:0px;}
+    </style>
+</head>
+ <body>
+  <div class="place"> 
+   <span>位置:</span> 
+   <ul class="placeul"> 
+    <li><a href="{#$pathes.index#}">首页</a></li> 
+    <li><a href="{#\helper\globals::getFullUrl('/dirs')#}?path={#$defaultPath#}">文件管理</a></li> 
+    {#foreach item=item from=$visitPathes#}
+    <li><a href="{#$item.url#}">{#$item.name#}</a></li>
+    {#/foreach#}
+    <li>{#$file#}</li>
+   </ul> 
+  </div> 
+  <table class="filetable"> 
+   <thead>
+   <tr>
+    <td><h3>&nbsp;&nbsp;&nbsp;&nbsp;文件内容:</h3></td>
+   </tr>
+   </thead> 
+   <tbody>
+   <tr>
+       <td width="100%">
+       <pre class="prettyprint linenums Lang-html">
+{#$code|htmlspecialchars#}
+       </pre>
+       </td>
+   </tr>
+   </tbody> 
+  </table>
+  <script>
+  $(function(){
+  prettyPrint();
+  });
+  </script>
+ </body>
+</html>

+ 83 - 0
demo/private/view/manage/index.html

@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>Dishboard</title>
+<link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+<script type="text/javascript" src="{#helper\globals::getJs("jquery")#}"></script>
+
+</head>
+
+
+<body>
+
+	<div class="place">
+    <span>位置:</span>
+    <ul class="placeul">
+    <li><a href="javascript:;">首页</a></li>
+    </ul>
+    </div>
+    
+    <div class="mainindex">
+    
+    
+    <div class="welinfo">
+    <span><img src="{#helper\globals::getImage("sun.png")#}" alt="天气" /></span>
+    <b>Admin早上好,欢迎使用信息管理系统</b>
+    <a href="#">帐号设置</a>
+    </div>
+    
+    <div class="welinfo">
+    <span><img src="{#helper\globals::getImage("time.png")#}" alt="时间" /></span>
+    <i>您上次登录的时间:2013-10-09 15:22</i> (不是您登录的?<a href="{#\helper\globals::getFullUrl('main/logout')#}" target="_parent">请点这里</a>)
+    </div>
+    
+    <div class="xline"></div>
+    
+    <ul class="iconlist">
+    
+    <li><img src="{#helper\globals::getImage("ico01.png")#}" /><p><a href="#">管理设置</a></p></li>
+    <li><img src="{#helper\globals::getImage("ico02.png")#}" /><p><a href="{#helper\globals::getFullUrl("/database/creator")#}">规则生成器</a></p></li>
+    <li><img src="{#helper\globals::getImage("ico03.png")#}" /><p><a href="{#helper\globals::getFullUrl("/database/rules")#}">详细规则管理</a></p></li>
+    <li><img src="{#helper\globals::getImage("ico04.png")#}" /><p><a href="{#helper\globals::getFullUrl("/database/table")#}">数据管理</a></p></li>
+    <li><img src="{#helper\globals::getImage("ico05.png")#}" /><p><a href="{#helper\globals::getFullUrl("/dirs")#}">目录管理</a></p></li>
+    <li><img src="{#helper\globals::getImage("ico06.png")#}" /><p><a href="{#helper\globals::getFullUrl("/formbuilder")#}">表单生成器</a></p></li>
+            
+    </ul>
+    
+    <div class="ibox"><a class="ibtn" href="{#helper\globals::getFullUrl('shortcut')#}"><img src="{#helper\globals::getImage("iadd.png")#}" />添加新的快捷功能</a></div>
+    
+    <div class="xline"></div>
+    <div class="box"></div>
+    
+    <div class="welinfo">
+    <span><img src="{#helper\globals::getImage("dp.png")#}" alt="提醒" /></span>
+    <b>Uimaker信息管理系统使用指南</b>
+    </div>
+    
+    <ul class="infolist">
+    <li><span>您可以快速进行文章发布管理操作</span><a class="ibtn">发布或管理文章</a></li>
+    <li><span>您可以快速发布产品</span><a class="ibtn">发布或管理产品</a></li>
+    <li><span>您可以进行密码修改、账户设置等操作</span><a class="ibtn">账户管理</a></li>
+    </ul>
+    
+    <div class="xline"></div>
+    
+    <div class="uimakerinfo"><b>查看Uimaker网站使用指南,您可以了解到多种风格的B/S后台管理界面,软件界面设计,图标设计,手机界面等相关信息</b>(<a href="http://www.uimaker.com" target="_blank">www.uimaker.com</a>)</div>
+    
+    <ul class="umlist">
+    <li><a href="#">如何发布文章</a></li>
+    <li><a href="#">如何访问网站</a></li>
+    <li><a href="#">如何管理广告</a></li>
+    <li><a href="#">后台用户设置(权限)</a></li>
+    <li><a href="#">系统设置</a></li>
+    </ul>
+    
+    
+    </div>
+    
+    
+
+</body>
+
+</html>

+ 83 - 0
demo/private/view/manage/left.html

@@ -0,0 +1,83 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+    <title>无标题文档</title>
+    <link href="{#\helper\globals::getCss("style")#}"="" rel="stylesheet" type="text/css" />
+    <script language="JavaScript" src="{#\helper\globals::getJs("jquery")#}"=""></script>
+    <script type="text/javascript">
+            $(function(){
+                //导航切换
+                $(".menuson li").click(function(){
+                    $(".menuson li.active").removeClass("active")
+                    $(this).addClass("active");
+                });
+
+                $('.title').click(function(){
+                    var $ul = $(this).next('ul');
+                    $('dd').find('ul').slideUp();
+                    if($ul.is(':visible')){
+                        $(this).next('ul').slideUp();
+                    }else{
+                        $(this).next('ul').slideDown();
+                    }
+                });
+            })
+    </script>
+</head>
+<body style="background:#f0f9fd;">
+<div class="lefttop">
+    <span></span>管理菜单
+</div>
+<dl class="leftmenu">
+    <dd>
+        <div class="title">
+            <span><img src="{#\helper\globals::getImage("leftico01.png")#}"="" /></span>数据库功能
+        </div>
+        <ul class="menuson">
+            <li><cite></cite><a href="{#helper\globals::getFullUrl("/database/creator")#}" target="rightFrame">规则生成器</a><i></i></li>
+            <li><cite></cite><a href="{#helper\globals::getFullUrl("/database/rules")#}" target="rightFrame">详细规则管理</a><i></i></li>
+            <li><cite></cite><a href="{#helper\globals::getFullUrl("/database/table")#}" target="rightFrame">数据管理</a><i></i></li>
+        </ul>
+    </dd>
+    <dd>
+        <div class="title">
+            <span><img src="{#\helper\globals::getImage("leftico01.png")#}"="" /></span>目录管理
+        </div>
+        <ul class="menuson">
+            <li><cite></cite><a href="{#helper\globals::getFullUrl("/dirs")#}" target="rightFrame">文件管理</a><i></i></li>
+        </ul>
+    </dd>
+    <dd>
+        <div class="title">
+            <span><img src="{#\helper\globals::getImage("leftico02.png")#}"="" /></span>表单工具
+        </div>
+        <ul class="menuson">
+            <li><cite></cite><a href="{#helper\globals::getFullUrl("/formbuilder")#}" target="rightFrame">表单生成器</a><i></i></li>
+        </ul>
+    </dd>
+    <dd>
+        <div class="title">
+            <span><img src="{#\helper\globals::getImage("leftico03.png")#}"="" /></span>编辑器
+        </div>
+        <ul class="menuson">
+            <li><cite></cite><a href="#">自定义</a><i></i></li>
+            <li><cite></cite><a href="#">常用资料</a><i></i></li>
+            <li><cite></cite><a href="#">信息列表</a><i></i></li>
+            <li><cite></cite><a href="#">其他</a><i></i></li>
+        </ul>
+    </dd>
+    <dd>
+        <div class="title">
+            <span><img src="{#\helper\globals::getImage("leftico04.png")#}"="" /></span>日期管理
+        </div>
+        <ul class="menuson">
+            <li><cite></cite><a href="#">自定义</a><i></i></li>
+            <li><cite></cite><a href="#">常用资料</a><i></i></li>
+            <li><cite></cite><a href="#">信息列表</a><i></i></li>
+            <li><cite></cite><a href="#">其他</a><i></i></li>
+        </ul>
+    </dd>
+</dl>
+</body>
+</html>

+ 93 - 0
demo/private/view/manage/login.html

@@ -0,0 +1,93 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>欢迎登录后台管理系统</title>
+<link href="{#helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+<script language="JavaScript" src="{#helper\globals::getJs("jquery")#}"></script>
+<script src="{#helper\globals::getJs("cloud")#}" type="text/javascript"></script>
+    <script type="text/javascript" src="{#helper\globals::getJs("tips")#}"></script>
+	<script type="text/javascript" src="{#helper\globals::getJs("notify-custom.min")#}"></script>
+
+<script language="javascript">
+	$(function(){
+    $('.loginbox').css({'position':'absolute','left':($(window).width()-692)/2});
+	$(window).resize(function(){  
+    $('.loginbox').css({'position':'absolute','left':($(window).width()-692)/2});
+    })  
+});  
+</script> 
+
+</head>
+
+<body style="background-color:#1c77ac; background-image:url(images/light.png); background-repeat:no-repeat; background-position:center top; overflow:hidden;">
+
+
+
+    <div id="mainBody">
+      <div id="cloud1" class="cloud"></div>
+      <div id="cloud2" class="cloud"></div>
+    </div>  
+
+
+<div class="logintop">    
+    <span>欢迎登录后台管理界面平台</span>    
+    <ul>
+	    <li><a href="#">回首页</a></li>
+	    <li><a href="#">帮助</a></li>
+	    <li><a href="#">关于</a></li>
+    </ul>    
+    </div>
+    
+    <div class="loginbody">
+    
+    <span class="systemlogo"></span> 
+       
+    <div class="loginbox">
+    	{#helper\globals::safeForm()#}
+	    <ul>
+		    <li><input name="user" id="user" type="text" class="loginuser" value="admin"  placeholder="请输入用户名" /></li>
+		    <li><input name="password" id="passwrod" type="password" class="loginpwd" placeholder="请输入密码" /></li>
+		    <li><input name="login" type="button" class="loginbtn" value="登录"  /><label><input name="" type="checkbox" value="" checked="checked" />记住密码</label><label><a href="#">忘记密码?</a></label></li>
+	    </ul>
+    </div>
+    <p style="text-align:center;">请在配置文件中设置登录密码</p>
+    </div>
+    <div class="loginbm">2016  <a href="{#$pathes.weburl#}">{#$pathes.weburl#}</a> </div>
+	<script>
+		$('input[name="login"]').on('click', function(){
+			var user = $('input[name="user"]').val();
+			var password = $('input[name="password"]').val();
+			var security_sid = $('input[name="security_sid"]').val();
+			if(user == '' || password == '')
+			{
+				$.notify('用户名和密码不能为空', 'error');
+				return;
+			}
+			$.ajax({
+					url : '{#$pathes.loginCheck#}?isAjax=1',
+					data : {user: user, password : password, security_sid : security_sid},
+					method : 'POST',
+					dataType : 'json',
+					success : function(data)
+					{
+						if(data.code == 0)
+						{
+							$.notify("登录成功", "success", {callback: function(){window.location.href = window.location.href;}});
+						}
+						else
+						{
+							$.notify(data.msg, "error");
+						}
+					},
+					error : function()
+					{
+						$.notify("网络连接失败,请重试", "error");
+					}
+			});
+		});
+	</script>
+    
+</body>
+
+</html>

+ 16 - 0
demo/private/view/manage/main.html

@@ -0,0 +1,16 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>信息管理系统界面</title>
+</head>
+<frameset rows="88,*" cols="*" frameborder="no" border="0" framespacing="0">
+	<frame src="{#\helper\globals::getFullUrl("/menu/top", ".html")#}" name="topFrame" scrolling="No" noresize="noresize" id="topFrame" title="topFrame" />
+  <frameset cols="187,*" frameborder="no" border="0" framespacing="0">
+	  <frame src="{#\helper\globals::getFullUrl("/menu/left", ".html")#}" name="leftFrame" scrolling="No" noresize="noresize" id="leftFrame" title="leftFrame" />
+	  <frame src="{#if $url#}{#$url#}{#else#}{#\helper\globals::getFullUrl("/menu/index", ".html")#}{#/if#}" name="rightFrame" id="rightFrame" title="rightFrame" />
+  </frameset>
+</frameset>
+<noframes><body>
+</body></noframes>
+</html>

+ 52 - 0
demo/private/view/manage/top.html

@@ -0,0 +1,52 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<title>无标题文档</title>
+<link href="{#\helper\globals::getCss("style")#}" rel="stylesheet" type="text/css" />
+<script language="JavaScript" src="{#\helper\globals::getJs("jquery")#}"></script>
+<script type="text/javascript">
+$(function(){	
+	//顶部导航切换
+	$(".nav li a").click(function(){
+		$(".nav li a.selected").removeClass("selected")
+		$(this).addClass("selected");
+	})	
+})	
+</script>
+
+
+</head>
+
+<body style="background:url({#\helper\globals::getImage("topbg.gif")#}) repeat-x;">
+
+    <div class="topleft">
+    <a href="{#\helper\globals::getFullUrl('main/index')#}" target="_parent"><img src="{#\helper\globals::getImage("logo.png")#}" title="系统首页" /></a>
+    </div>
+        
+    <ul class="nav">
+    <li><a href="{#\helper\globals::getFullUrl('menu/index')#}" target="rightFrame" class="selected"><img src="{#\helper\globals::getImage("icon01.png")#}" title="工作台" /><h2>工作台</h2></a></li>
+    <li><a href="imgtable.html" target="rightFrame"><img src="{#\helper\globals::getImage("icon02.png")#}" title="模型管理" /><h2>模型管理</h2></a></li>
+    <li><a href="imglist.html"  target="rightFrame"><img src="{#\helper\globals::getImage("icon03.png")#}" title="模块设计" /><h2>模块设计</h2></a></li>
+    <li><a href="tools.html"  target="rightFrame"><img src="{#\helper\globals::getImage("icon04.png")#}" title="常用工具" /><h2>常用工具</h2></a></li>
+    <li><a href="{#\helper\globals::getFullUrl('dirs')#}" target="rightFrame"><img src="{#\helper\globals::getImage("icon05.png")#}" title="文件管理" /><h2>文件管理</h2></a></li>
+    <li><a href="{#\helper\globals::getFullUrl('main/setting')#}"  target="rightFrame"><img src="{#\helper\globals::getImage("icon06.png")#}" title="系统设置" /><h2>系统设置</h2></a></li>
+    </ul>
+            
+    <div class="topright">    
+    <ul>
+    <li><span><img src="{#\helper\globals::getImage("help.png")#}" title="帮助"  class="helpimg"/></span><a href="#">帮助</a></li>
+    <li><a href="#">关于</a></li>
+    <li><a href="{#\helper\globals::getFullUrl('main/logout')#}" target="_parent">退出</a></li>
+    </ul>
+     
+    <div class="user">
+    <span>{#$admin.user#}</span>
+    <i>消息</i>
+    <b>0</b>
+    </div>    
+    
+    </div>
+
+</body>
+</html>

+ 17 - 0
demo/private/view/tips.html

@@ -0,0 +1,17 @@
+    <div class="tip">
+        <div class="tiptop"><span>提示信息</span><a></a></div>
+
+        <div class="tipinfo">
+            <span><img src="{#helper\globals::getImage("ticon.png")#}" /></span>
+            <div class="tipright">
+                <p>是否确认对信息的修改 ?</p>
+                <cite>如果是请点击确定按钮 ,否则请点取消。</cite>
+            </div>
+        </div>
+
+        <div class="tipbtn">
+            <input name="" type="button"  class="sure" value="确定" />&nbsp;
+            <input name="" type="button"  class="cancel" value="取消" />
+        </div>
+
+    </div>

File diff suppressed because it is too large
+ 6 - 0
demo/public/static/css/jquery-ui.min.css


+ 87 - 0
demo/public/static/css/jquery.multiSelect.css

@@ -0,0 +1,87 @@
+a.multiSelect {
+	background: #FFF url(../images/dropdown.blue.png) right center no-repeat;
+	border: solid 1px #BBB;
+	padding-right: 20px;
+	position: relative;
+	cursor: default;
+	text-decoration: none;
+	color: black;
+	display: -moz-inline-stack;
+	display: inline-block;
+	vertical-align: top;
+}
+
+a.multiSelect:link, a.multiSelect:visited, a.multiSelect:hover, a.multiSelect:active {
+	color: black;
+	text-decoration: none;
+}
+
+a.multiSelect span
+{
+	margin: 1px 0px 1px 3px;
+	overflow: hidden;
+	display: -moz-inline-stack;
+	display: inline-block;
+	white-space: nowrap;
+	line-height:15px;
+	text-indent:0px;
+}
+
+a.multiSelect.hover {
+	background-image: url(../images/dropdown.blue.hover.png);
+}
+
+a.multiSelect.active, 
+a.multiSelect.focus {
+	border: inset 1px #000;
+}
+
+a.multiSelect.active {
+	background-image: url(../images/dropdown.blue.active.png);
+}
+
+.multiSelectOptions {
+	margin-top: -1px;
+	overflow-y: auto;
+	overflow-x: hidden;
+	border: solid 1px #B2B2B2;
+	background: #FFF;
+}
+
+.multiSelectOptions LABEL {
+	padding: 0px 2px;
+	display: block;
+	white-space: nowrap;
+}
+
+.multiSelectOptions LABEL.optGroup
+{
+	font-weight: bold;
+}
+
+.multiSelectOptions .optGroupContainer LABEL
+{
+	padding-left: 10px;
+}
+
+.multiSelectOptions.optGroupHasCheckboxes .optGroupContainer LABEL
+{
+	padding-left: 18px;
+}
+
+.multiSelectOptions input{
+	vertical-align: middle;
+}
+
+.multiSelectOptions LABEL.checked {
+	background-color: #dce5f8;
+}
+
+.multiSelectOptions LABEL.selectAll {
+	border-bottom: dotted 1px #CCC;
+}
+
+.multiSelectOptions LABEL.hover {
+	background-color: #3399ff;
+	color: white;
+}

+ 26 - 0
demo/public/static/css/select.css

@@ -0,0 +1,26 @@
+/***** 输入框(无边框悬停状态) *****/
+.uew-select .uew-select-value{height:32px;padding:0 5px; margin-top:0px; margin-bottom:12px;line-height:32px;font-family:Tahoma,'微软雅黑','宋体';*font-family:'微软雅黑','宋体';color:#000;resize:none;border-width:1px;border-style:solid;border-color:#a7b5bc #ced9df #ced9df #a7b5bc;}
+.uew-border-flag,.uew-border-flag,textarea.uew-border-flag,.uew-select .uew-select-value.uew-border-flag{border-width:1px;border-style:solid;border-color:#bababa #e9e9e9 #e9e9e9 #bababa;}
+/***** 下拉框 *****/
+.uew-select{position:relative;}
+.uew-select .uew-select-value{z-index:1;position:relative;padding-right:20px;background:#fff;font-size:12px; text-indent:5px;background:url(../images/inputbg.gif) repeat-x;_background:none;_border:none;}
+.uew-select-value em{font-style:normal;}
+.uew-select .uew-icon{position:absolute;right:5px;top:10px;}
+.uew-select select{z-index:2;position:absolute;top:3px;_top:6px;cursor:pointer; height:28px;}
+/***** 去除聚焦虚线框 *****/
+a:focus,input[type=checkbox]:focus,input[type=radio]:focus,button:focus,.uew-select select{outline:none;}
+.uew-select select{opacity:0;filter:alpha(opacity=0);}
+option{overflow:auto;outline:none;}
+
+/*----------------------------------*
+ * 	组件公用图标库         				*
+ *----------------------------------*/
+.uew-icon,.ue-state-default .uew-icon{display:inline-block;width:16px;height:16px;background-image:url(../images/uew_icon.png);}
+.ue-state-hover .uew-icon{background-image:url(../images/uew_icon_hover.png);}
+.uew-icon-triangle-1-s{background-position:-80px 0;}
+
+.vocation,.usercity{float:left;}
+.cityleft{float:left; padding-right:10px;_padding-right:15px;}
+.cityright{float:left;}
+
+

+ 310 - 0
demo/public/static/css/style.css

@@ -0,0 +1,310 @@
+@charset "utf-8";
+/* CSS Document */
+/***
+ * uimaker
+ * http://www.uimaker.com
+ * e-mail: admin@uimaker.com
+ */
+*{font-size:9pt;border:0;margin:0;padding:0;}
+body{font-family:'微软雅黑'; margin:0 auto;min-width:980px;}
+ul{display:block;margin:0;padding:0;list-style:none;height:auto;overflow:hidden;}
+li{display:block;margin:0;padding:0;list-style: none;height:auto;overflow:hidden;}
+img{border:0;}
+dl,dt,dd,span{margin:0;padding:0;display:block;}
+a,a:focus{text-decoration:none;color:#000;outline:none;blr:expression(this.onFocus=this.blur());}
+a:hover{color:#00a4ac;text-decoration:none;}
+table{border-collapse:collapse;border-spacing: 0;}
+cite{font-style:normal;}
+h2{font-weight:normal;}
+
+/*cloud*/
+
+#mainBody {width:100%;height:100%;position:absolute;z-index:-1;}
+.cloud {position:absolute;top:0px;left:0px;width:100%;height:100%;background:url(../images/cloud.png) no-repeat;z-index:1;opacity:0.5;}
+#cloud2 {z-index:2;}
+
+
+/*login*/
+.logintop{height:47px; position:absolute; top:0; background:url(../images/loginbg1.png) repeat-x;z-index:100; width:100%;}
+.logintop span{color:#fff; line-height:47px; background:url(../images/loginsj.png) no-repeat 21px 18px; text-indent:44px; color:#afc5d2; float:left;}
+.logintop ul{float:right; padding-right:30px;}
+.logintop ul li{float:left; margin-left:20px; line-height:47px;}
+.logintop ul li a{color:#afc5d2;}
+.logintop ul li a:hover{color:#fff;}
+.loginbody{background:url(../images/loginbg3.png) no-repeat center center; width:100%; height:585px; overflow:hidden; position:absolute; top:47px;}
+.systemlogo{background:url(../images/loginlogo.png) no-repeat center;width:100%; height:71px; margin-top:75px;}
+.loginbox{width:692px; height:336px; background:url(../images/logininfo.png) no-repeat; margin-top:30px;}
+.loginbox ul{margin-top:88px; margin-left:285px;}
+.loginbox ul li{margin-bottom:25px;}
+.loginbox ul li label{color:#687f92; padding-left:25px;}
+.loginbox ul li label a{color:#687f92;}
+.loginbox ul li label a:hover{color:#3d96c9;}
+.loginbox ul li label input{margin-right:5px;}
+.loginuser{width:299px; height:48px; background:url(../images/loginuser.png) no-repeat; border:none; line-height:48px; padding-left:44px; font-size:14px; font-weight:bold;}
+.loginpwd{width:299px; height:48px; background:url(../images/loginpassword.png) no-repeat; border:none;line-height:48px; padding-left:44px; font-size:14px; color:#90a2bc;}
+.loginbtn{width:111px;height:35px; background:url(../images/buttonbg.png) repeat-x; font-size:14px; font-weight:bold; color:#fff;cursor:pointer; line-height:35px;}
+.loginbm{height:50px; line-height:50px; text-align:center; background:url(../images/loginbg2.png) repeat-x;position:absolute; bottom:0; width:100%; color:#0b3a58;}
+.loginbm a{font-weight:bold;color:#0b3a58;}
+.loginbm a:hover{color:#fff;}
+
+
+/*top.html*/
+.header{height:88px;}
+.topleft{height:88px;background:url(../images/topleft.jpg) no-repeat;float:left; width:300px;}
+.topleft img{margin-top:12px;margin-left:10px;}
+.topright{height:88px;background:url(../images/topright.jpg) no-repeat right;float:right;}
+.nav{float:left;}
+.nav li{float:left;width:87px;height:88px; text-align:center;}
+.nav li a{display:block;width:87px;height:88px;-moz-transition: none; transition: background-color 0.3s linear; -moz-transition: background-color 0.3s linear; -webkit-transition: background-color 0.3s linear; -o-transition: background-color 0.3s linear; }
+.nav li a.selected{background:url(../images/navbg.png) no-repeat;}
+.nav li a:hover{display:block;background:#000;color:#fff;background: none repeat scroll 0% 0% rgb(43, 127, 181);}
+.nav li img{margin-top:10px;}
+.nav li a{display:block;}
+.nav a h2{font-size:14px;color:#d6e8f1;}
+.nav a:hover h2{color:#fff;}
+.topright ul{padding-top:15px; float:right; padding-right:12px;}
+.topright ul li{float:left; padding-left:9px; padding-right:9px; background:url(../images/line.gif) no-repeat right;}
+.topright ul li:last-child{background:none;}
+.topright ul li a{font-size:13px; color:#e9f2f7;}
+.topright ul li a:hover{color:#fff;}
+.topright ul li span{margin-top:2px;float:left;padding-right:3px;}
+.user{height:30px;background:url(../images/ub1.png) repeat-x;clear:both;margin-top:10px;float:right; margin-right:12px;border-radius:30px; behavior:url(js/pie.htc); white-space:nowrap;position:relative;}
+.user span{display:inline-block;padding-right:10px; background:url(../images/user.png) no-repeat 15px 10px; line-height:30px; font-size:14px;color:#b8ceda; padding-left:20px; padding-left:35px;}
+.user b{display:inline-block;width:20px;height:18px; background:url(../images/msg.png);text-align:center; font-weight:normal; color:#fff;font-size:14px;margin-right:13px; margin-top:7px; line-height:18px;}
+.user i{display:inline-block;margin-right:5px;font-style:normal;line-height:30px; font-size:14px;color:#b8ceda;}
+
+/*left.html*/
+.lefttop{background:url(../images/lefttop.gif) repeat-x;height:40px;color:#fff;font-size:14px;line-height:40px;}
+.lefttop span{margin-left:8px; margin-top:10px;margin-right:8px; background:url(../images/leftico.png) no-repeat; width:20px; height:21px;float:left;}
+.leftmenu{width:187px;padding-bottom: 9999px;margin-bottom: -9999px; overflow:hidden; background:url(../images/leftline.gif) repeat-y right;}
+.leftmenu dd{background:url(../images/leftmenubg.gif) repeat-x;line-height:35px;font-weight:bold;font-size:14px;border-right:solid 1px #b7d5df;}
+.leftmenu dd span{float:left;margin:10px 8px 0 12px;}
+.leftmenu dd .menuson{display:none;}
+.leftmenu dd:first-child .menuson{display:block;}
+.menuson {line-height:30px; font-weight:normal; }
+.menuson li{cursor:pointer;}
+.menuson li.active{position:relative; background:url(../images/libg.png) repeat-x; line-height:30px; color:#fff;}
+.menuson li cite{display:block; float:left; margin-left:32px; background:url(../images/list.gif) no-repeat; width:16px; height:16px; margin-top:7px;}
+.menuson li.active cite{background:url(../images/list1.gif) no-repeat;}
+.menuson li.active i{display:block; background:url(../images/sj.png) no-repeat; width:6px; height:11px; position:absolute; right:0;z-index:10000; top:9px; right:-1px;}
+.menuson li a{ display:block; *display:inline; *padding-top:5px;}
+.menuson li.active a{color:#fff;}
+.title{cursor:pointer;}
+
+
+/*right.html*/
+.place{height:40px; background:url(../images/righttop.gif) repeat-x;}
+.place span{line-height:40px; font-weight:bold;float:left; margin-left:12px;}
+.placeul li{float:left; line-height:40px; padding-left:7px; padding-right:12px; background:url(../images/rlist.gif) no-repeat right;}
+.placeul li:last-child{background:none;}
+.rightinfo{padding:8px;}
+.tools{clear:both; height:35px; margin-bottom:8px;}
+.toolbar{float:left;}
+.toolbar li{background:url(../images/toolbg.gif) repeat-x; line-height:33px; height:33px; border:solid 1px #d3dbde; float:left; padding-right:10px; margin-right:5px;border-radius: 3px; behavior:url(js/pie.htc); cursor:pointer;}
+.toolbar li span{float:left; margin-left:10px; margin-right:5px; margin-top:5px;}
+.toolbar1{float:right;}
+.toolbar1 li{background:url(../images/toolbg.gif) repeat-x; line-height:33px; height:33px; border:solid 1px #d3dbde; float:left; padding-right:10px; margin-left:5px;border-radius: 3px; behavior:url(js/pie.htc);}
+.toolbar1 li span{float:left; margin-left:10px; margin-right:5px; margin-top:5px;}
+.tablelist{border:solid 1px #cbcbcb; width:100%; clear:both;white-space:nowrap;}
+.tablelist th{background:url(../images/th.gif) repeat-x; height:34px; line-height:34px; border-bottom:solid 1px #b6cad2; text-indent:11px; text-align:left;}
+.tablelist td{line-height:35px; text-indent:11px; border-right: dotted 1px #c7c7c7;}
+.tablelink{color:#056dae;}
+.tablelist tbody tr.odd{background:#f5f8fa;}
+.tablelist tbody tr:hover{background:#e5ebee;}
+.sort{padding-left:3px;}
+
+/*page*/
+.pagin{position:relative;margin-top:10px;padding:0 12px;height:35px;}
+.pagin .blue{color:#056dae;font-style:normal;}
+.pagin .paginList{position:absolute;right:12px;top:0;}
+.pagin .paginList .paginItem{float:left;}
+.pagin .paginList .paginItem a{float:left;width:31px;height:28px;border:1px solid #DDD; text-align:center;line-height:30px;border-left:none;color:#3399d5;}
+.pagin .paginList .paginItem:first-child a{border-left:1px solid #DDD;}
+.pagin .paginList .paginItem:first-child a{border-bottom-left-radius:5px;border-top-left-radius:5px;}
+.pagin .paginList .paginItem:last-child a{border-bottom-right-radius:5px;border-top-right-radius:5px;}
+.pagin .paginList .paginItem.current,.pagin .paginList .paginItem.current a{background:#f5f5f5; cursor:default;color:#737373;}
+.pagin .paginList .paginItem:hover{background:#f5f5f5;}
+.pagin .paginList .paginItem.more,.pagin .paginList .paginItem.more a:hover{ cursor:default;}
+.pagin .paginList .paginItem.more:hover{background:#FFF;}
+.pagin .paginList .paginItem.more a{color:#737373;}
+.pagepre{background:url(../images/pre.gif) no-repeat center center; width:31px; height:28px;}
+.pagenxt{background:url(../images/next.gif) no-repeat center center; width:31px; height:28px;}
+.pagepre_highlight{background:url(../images/pre_highlight.gif) no-repeat center center; width:31px; height:28px;}
+.pagenxt_highlight{background:url(../images/next_highlight.gif) no-repeat center center; width:31px; height:28px;}
+
+/*index*/
+.mainindex{padding:20px; overflow:hidden;}
+.welinfo{height:32px; line-height:32px; padding-bottom:8px;}
+.welinfo span{float:left;}
+.welinfo b{padding-left:8px;}
+.welinfo a{padding-left:15px;color:#3186c8;}
+.welinfo a:hover{color:#F60;}
+.welinfo i{font-style:normal; padding-left:8px;}
+.xline{border-bottom:solid 1px #dfe9ee; height:5px;}
+.iconlist{padding-left:40px; overflow:hidden;}
+.iconlist li{text-align:center; float:left; margin-right:25px; margin-top:25px;}
+.iconlist li p{line-height:25px;}
+.ibox{clear:both; padding-left:40px; padding-top:18px; overflow:hidden; padding-bottom:18px;}
+.ibtn{background:url(../images/ibtnbg.png) repeat-x;border:solid 1px #bfcfe1; height:23px; line-height:23px; display:block; float:left; padding:0 15px; cursor:pointer;}
+.ibtn img{margin-top:5px; float:left; padding-right:7px;}
+.box{height:15px;}
+.infolist{padding-left:40px; padding-bottom:15px;}
+.infolist li{ line-height:25px; height:25px; margin-bottom:8px;}
+.infolist li span{float:left; display:block; margin-right:10px;}
+.uimakerinfo{padding-left:40px; background:url(../images/search.png) no-repeat 10px 15px; padding-top:15px; padding-bottom:20px;}
+.umlist{padding-left:40px;}
+.umlist li{float:left; background:url(../images/ulist.png) no-repeat 0 3px; padding-left:10px; margin-right:15px;}
+
+
+/*default*/
+.mainbox{padding:8px;position:relative;}
+.mainleft{padding-right:298px;}
+.leftinfo{border:#d3dbde solid 1px; height:290px;}
+.mainright{width:298px;position:absolute; top:8px; right:8px;}
+.dflist{border:#d3dbde solid 1px; width:288px; height:290px; float:right;}
+.dflist1{border:#d3dbde solid 1px; width:288px; height:238px; float:right; margin-top:8px;}
+.listtitle{background:url(../images/tbg.png) repeat-x; height:36px; line-height:36px; border-bottom:solid 1px #d3dbde; text-indent:14px; font-weight:bold; font-size:14px;}
+.more1{float:right; font-weight:normal;color:#307fb1; padding-right:17px;}
+.maintj{text-align:center;}
+.newlist{padding-left:14px; padding-top:15px;}
+.newlist li{line-height:25px; background:url(../images/list2.png) no-repeat 0px 8px; text-indent:11px;}
+.newlist i{width:80px; display:block; float:left; font-style:normal;}
+.newlist b{font-weight:normal; color:#7b7b7b; padding-left:10px;}
+.leftinfos{height:238px;margin-top:8px;}
+.infoleft{border:#d3dbde solid 1px; float:left;height:238px;}
+.inforight{border:#d3dbde solid 1px; float:right;height:238px; }
+.tooli{padding:30px 20px;}
+.tooli li{float:left;padding-left:15px; padding-right:15px;margin-bottom:20px;}
+.tooli li span{text-align:center;}
+.tooli li p{line-height:35px; text-align:center;}
+
+
+/*form*/
+.formbody{padding:10px 18px;}
+.formtitle{border-bottom:solid 1px #d0dee5; line-height:35px; position:relative; height:35px; margin-bottom:28px;}
+.formtitle span{font-weight:bold;font-size:14px; border-bottom:solid 3px #66c9f3;float:left; position:absolute; z-index:100; bottom:-1px; padding:0 3px; height:30px; line-height:30px;}
+.forminfo{padding-left:23px;}
+.forminfo li{margin-bottom:13px; clear:both;}
+.forminfo li label{width:86px;line-height:34px; display:block; float:left;}
+.forminfo li i{color:#7f7f7f; padding-left:20px; font-style:normal;}
+.forminfo li cite{display:block; padding-top:10px;}
+.dfinput{width:345px; height:32px; line-height:32px; border-top:solid 1px #a7b5bc; border-left:solid 1px #a7b5bc; border-right:solid 1px #ced9df; border-bottom:solid 1px #ced9df; background:url(../images/inputbg.gif) repeat-x; text-indent:10px;}
+.dfinputmin{width:200px; height:20px; line-height:20px; border-top:solid 1px #a7b5bc; border-left:solid 1px #a7b5bc; border-right:solid 1px #ced9df; border-bottom:solid 1px #ced9df; background:url(../images/inputbg.gif) repeat-x; text-indent:10px;}
+.textinput{border-top:solid 1px #a7b5bc; border-left:solid 1px #a7b5bc; border-right:solid 1px #ced9df; border-bottom:solid 1px #ced9df; background:url(../images/inputbg.gif) repeat-x; padding:10px; width:504px; height:135px; line-height:20px; overflow:hidden;}
+.btn{width:137px;height:35px; background:url(../images/btnbg.png) no-repeat; font-size:14px;font-weight:bold;color:#fff; cursor:pointer;}
+
+
+/*tip*/
+.tip{width:485px; height:260px; position:absolute;top:10%; left:30%;background:#fcfdfd;box-shadow:1px 8px 10px 1px #9b9b9b;border-radius:1px;behavior:url(js/pie.htc); display:none; z-index:111111;}
+.tiptop{height:40px; line-height:40px; background:url(../images/tcbg.gif)  repeat-x; cursor:pointer;}
+.tiptop span{font-size:14px; font-weight:bold; color:#fff;float:left; text-indent:20px;}
+.tiptop a{display:block; background:url(../images/close.png) no-repeat; width:22px; height:22px;float:right;margin-right:7px; margin-top:10px; cursor:pointer;}
+.tiptop a:hover{background:url(../images/close1.png) no-repeat;}
+.tipinfo{padding-top:30px;margin-left:65px; height:95px;}
+.tipinfo span{width:95px; height:95px;float:left;}
+.tipright{float:left;padding-top:15px; padding-left:10px;}
+.tipright p{font-size:14px; font-weight:bold; line-height:35px;}
+.tipright cite{color:#858686;}
+.tipbtn{margin-top:25px; margin-left:125px;}
+.sure ,.cancel{width:96px; height:35px; line-height:35px; color:#fff; background:url(../images/btnbg1.png) repeat-x; font-size:14px; font-weight:bold;border-radius: 3px; cursor:pointer;}
+.cancel{background:url(../images/btnbg2.png) repeat-x;color:#000;font-weight:normal;}
+
+/*tools*/
+.toolsli{clear:both; overflow:hidden; margin-bottom:20px;}
+.toollist{margin-left:20px; overflow:hidden; float:left;}
+.toollist li{width:66px; text-align:center; float:left; margin-right:32px;}
+.toollist li a{width:65px; height:65px; background:#fafbfb; border-right:solid 1px #dbdbdb;border-bottom:solid 1px #dbdbdb; display:block;}
+.toollist li a:hover{background:#eef4f7;border-right:solid 1px #d0d5d7;border-bottom:solid 1px #d0d5d7;}
+.toollist li h2{line-height:35px;}
+.tooladd{margin-top:25px; width:20px; height:20px; float:left; display:block;}
+
+/*error 404*/
+.error{background:url(../images/error.png) no-repeat; width:490px; height:220px;margin-top:75px;}
+.error404{background:url(../images/404.png) no-repeat; width:490px; height:220px;margin-top:75px;padding-top:65px;}
+.error h2{font-size:22px; padding-left:154px;}
+.error p{padding-left:154px; line-height:35px;color:#717678;}
+.reindex{padding-left:154px;}
+.reindex a{width:115px; height:35px; font-size:14px; font-weight:bold; color:#fff; background:#3c95c8; display:block; line-height:35px; text-align:center;border-radius: 3px; behavior:url(js/pie.htc);margin-top:20px;}
+
+/*computer*/
+.comtitle{padding:20px; clear:both;}
+.comtitle span{width:10px;height:10px; background:url(../images/clist.png) no-repeat; float:left; background:#fff; padding-top:3px;}
+.comtitle h2{font-size:14px; display:block; float:left;color:#2a3e93; background:#fff; padding-left:5px; padding-right:8px;}
+.rline{border-bottom:solid 1px #e5ecf0; height:10px; margin-left:50px;}
+.disklist{padding-left:20px; padding-right:20px;}
+.disklist li{width:275px;_width:270px;float:left; margin-right:10px;px;height:70px; cursor:pointer; margin-bottom:5px;border:solid 1px #fff;}
+.disklist li a{color:#000;}
+.disklist li:hover{background:#fcfcfc; border:solid 1px #e5ecf0;}
+.dleft{background:url(../images/c02.png) no-repeat; height:50px; margin-left:12px; float:left; width:50px; margin-top:15px;}
+.dleft1{background:url(../images/c01.png) no-repeat; height:50px; margin-left:12px; float:left; width:50px; margin-top:15px;}
+.dleft2{background:url(../images/c03.png) no-repeat; height:50px; margin-left:12px; float:left; width:50px; margin-top:15px;}
+.dright{float:left; margin-left:10px; margin-top:5px;}
+.dright h3{font-weight:normal; padding-top:15px;}
+.dright p{color:#949494;}
+.dinfo{width:189px;height:15px; background:url(../images/diskbg.png) no-repeat; margin-top:5px; margin-bottom:5px;}
+.dinfo span{background:url(../images/cbg.png) repeat-x; height:15px;}
+.filetable{width:100%;}
+.filetable thead tr{background:#f5f9fb; line-height:35px;}
+.filetable thead tr th{text-align:left; text-indent:15px;font-weight:normal;color:#597190;}
+.filetable tbody tr td{text-indent:15px; line-height:23px;}
+.filetable tbody tr td img {margin-right:5px;}
+.tdlast{text-align:right;}
+.filetable tbody tr:hover{background:#f5f8fa; cursor:pointer;}
+
+/*imglist*/
+.imglist{clear:both; overflow:hidden; margin-bottom:20px; margin-left:5px;}
+.imglist li{width:188px; border:solid 1px #fff;height:199px;float:left; margin-right:8px; margin-bottom:10px; cursor:pointer;}
+.imglist li:hover{border:solid 1px #d7e4ea;}
+.imglist li span{width:168px; height:126px; margin:8px;}
+.imglist li h2{text-align:center; line-height:25px;}
+.imglist li p{text-align:center; line-height:17px; background:url(../images/line1.png) center center no-repeat;}
+.imglist li p a{color:#1f7cb6;}
+.imglist li p a:hover{color:#F60;}
+
+/*imgtable*/
+.imgtable{width:100%;border:solid 1px #cbcbcb; }
+.imgtable th{background:url(../images/th.gif) repeat-x; height:34px; line-height:34px; border-bottom:solid 1px #b6cad2; text-indent:21px; text-align:left;}
+.imgtable td{line-height:20px; text-indent:21px; border-right: dotted 1px #c7c7c7;}
+.imgtable td img{margin:10px 20px 10px 0;}
+.imgtable td p{color:#919191;}
+.imgtable td i{font-style:normal; color:#ea2020;}
+.imgtd{text-indent:0;}
+.imgtable tbody tr.odd{background:#f5f8fa;}
+.imgtable tbody tr:hover{background:#e5ebee;}
+
+/*tab*/
+.itab{height:36px; border-bottom:solid 1px #d0dee5; position:relative; border-left:solid 1px #d3dbde;}
+.itab ul li{float:left;height:37px; line-height:37px; background:url(../images/itabbg.png) repeat-x; border-right:solid 1px #d3dbde;}
+.itab ul li a{font-size:14px; color:#000; padding-left:25px; padding-right:25px;}
+.itab ul li a.selected{ height:37px; display:block; background:url(../images/itabbg1.png) repeat-x; font-weight:bold;}
+.tabson{margin:18px 0px;}
+.formtext{height:45px; padding-left:25px; line-height:20px; color:#848383;}
+.formtext b{color:#d70101;}
+.forminfo b{color:#ea2020; padding-left:3px;}
+
+/*class*/
+.classlist li{float:left;margin-right:10px;margin-bottom:10px;padding:12px;border:1px solid #ebebeb; background:#fcfcfc;}
+.classlist li:hover{border:1px solid #3eafe0; cursor:pointer;}
+.classlist li span{float:left;margin-right:18px;border:3px solid #fff;}
+.classlist li .lright{float:left;width:150px;}
+.classlist li .lright h2{font-size:12px; font-weight:bold;line-height:30px;}
+.classlist li .lright p{line-height:20px;}
+.enter{display:block;margin-top:5px;width:94px;height:30px;color:#fff;background:#3eafe0;font-weight:bold; border-radius:2px; text-align:center;line-height:30px; cursor:pointer;}
+.enter:hover{color:#fff; background:#d98c1d;}
+.clear{clear:both;}
+
+/*seachform*/
+.seachform{ height:42px;}
+.seachform li{float:left; margin-right:15px;}
+.seachform li label{padding-right:10px; float:left; line-height:32px;}
+.scinput{width:150px; height:32px; line-height:32px; border-top:solid 1px #a7b5bc; border-left:solid 1px #a7b5bc; border-right:solid 1px #ced9df; border-bottom:solid 1px #ced9df; background:url(../images/inputbg.gif) repeat-x; text-indent:10px;}
+.scbtn{width:85px;height:35px; background:url(../images/btnbg.png) no-repeat center; font-size:14px;font-weight:bold;color:#fff; cursor:pointer;border-radius:3px; behavior:url(js/pie.htc);}
+span.inner{display:inline;}
+
+.display_left{float:left;display:block;margin:5px 0px;}
+.forminfo li label.w160{width:160px;}
+
+.red{color:red;}
+.bold{font-weight:bold;}
+.input_error{border-color:red;}
+.overflow-auto{overflow:auto;}

+ 93 - 0
demo/public/static/css/sumoselect.css

@@ -0,0 +1,93 @@
+.SumoSelect p,div,ul,li{padding:0px; margin:0px;font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;color:#444;font-size:13px;}
+
+
+.SumoSelect p {margin: 0;}
+.SlectBox { width: 200px; padding: 5px 8px;}
+
+/*this is applied on that hidden select. DO NOT USE display:none; or visiblity:hidden; and Do not override any of these properties. */
+.SelectClass { position: absolute; top: 0px; left: 0px; right: 0px; height: 100%; width: 100%; border: none; z-index: 1; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter: alpha(opacity=0); -moz-opacity: 0; -khtml-opacity: 0; opacity: 0; }
+
+    .SumoSelect > .optWrapper > .options > li label, .SumoSelect > .CaptionCont { user-select: none; -o-user-select: none; -moz-user-select: none; -khtml-user-select: none; -webkit-user-select: none; }
+
+.SumoSelect { display: inline-block; position: relative;outline:none;}
+.SumoSelect:focus > .CaptionCont,.SumoSelect:hover > .CaptionCont {box-shadow: 0px 0px 2px #7799D0;border-color: #7799D0;}
+    .SumoSelect > .CaptionCont { position: relative; border: 1px solid #A4A4A4; min-height: 14px; background-color: #fff;border-radius:2px;margin:0px;}
+        .SumoSelect > .CaptionCont > span { display: block; padding-right: 30px; text-overflow: ellipsis; white-space: nowrap; overflow: hidden;cursor:default;}
+            /*placeholder style*/
+            .SumoSelect > .CaptionCont > span.placeholder { color: #ccc; font-style: italic; }
+
+        .SumoSelect > .CaptionCont > label { position: absolute; top: 0px; right: 0px; bottom: 0px; width: 30px;}
+            .SumoSelect > .CaptionCont > label > i { background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAANCAYAAABy6+R8AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3wMdBhAJ/fwnjwAAAGFJREFUKM9jYBh+gBFKuzEwMKQwMDB8xaOWlYGB4T4DA0MrsuapDAwM//HgNwwMDDbYTJuGQ8MHBgYGJ1xOYGNgYJiBpuEpAwODHSF/siDZ+ISBgcGClEDqZ2Bg8B6CkQsAPRga0cpRtDEAAAAASUVORK5CYII=');
+                background-position: center center; width: 16px; height: 16px; display: block; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px; margin: auto;background-repeat: no-repeat;opacity: 0.8;}
+
+    .SumoSelect > .optWrapper { top: 30px; width: 100%; position: absolute; left: 0; opacity: 0; visibility: hidden; transition: opacity 200ms ease-out, top 200ms ease-out, visibility 200ms ease-out; -webkit-transition: opacity 200ms ease-out, top 200ms ease-out, visibility 200ms ease-out; -moz-transition: opacity 200ms ease-out, top 200ms ease-out, visibility 200ms ease-out; -ms-transition: opacity 200ms ease-out, top 200ms ease-out, visibility 200ms ease-out; -o-transition: opacity 200ms ease-out, top 200ms ease-out, visibility 200ms ease-out; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; z-index: -100; background: #fff; border: 1px solid #ddd; box-shadow: 2px 3px 3px rgba(0, 0, 0, 0.11); border-radius: 3px;overflow: hidden;}
+        .SumoSelect > .optWrapper.open { top: 35px; visibility: visible; opacity: 1; z-index: 1000; }
+
+        .SumoSelect > .optWrapper > .options { list-style: none; display: block; padding: 0px; margin: 0px; overflow: auto; border-radius: 2px;
+         /*Set the height of pop up here (only for desktop mode)*/
+            max-height: 250px;
+             /*height*/ }
+        .SumoSelect > .optWrapper.isFloating > .options {max-height: 100%;box-shadow: 0px 0px 100px #595959;}
+        .SumoSelect > .optWrapper > .options > li { padding: 6px 6px; border-bottom: 1px solid #F3F3F3; position: relative; }
+            .SumoSelect > .optWrapper > .options > li:first-child { border-radius: 2px 2px 0px 0px; }
+            .SumoSelect > .optWrapper > .options > li:last-child { border-bottom: none; border-radius: 0px 0px 2px 2px; }
+            .SumoSelect > .optWrapper > .options > li:hover { background-color: #E4E4E4; }
+            .SumoSelect > .optWrapper > .options > li.sel{background-color: #a1c0e4;}
+
+            .SumoSelect > .optWrapper > .options > li label { text-overflow: ellipsis; white-space: nowrap; overflow: hidden; display: block;cursor: pointer;}
+            .SumoSelect > .optWrapper > .options > li span { display: none; }
+
+        /*Floating styles*/
+        .SumoSelect > .optWrapper.isFloating { position: fixed; top: 0px; left: 0px; right: 0px; width: 90%; bottom: 0px; margin: auto; max-height: 90%; }
+
+    /*Hover*/
+    /*.SumoSelect:hover > .CaptionCont > label { background-color: #F1F1F1; }*/
+
+    /*disabled state*/
+    .SumoSelect > .optWrapper > .options > li.disabled { background-color: inherit;pointer-events: none;}
+        .SumoSelect > .optWrapper > .options > li.disabled * { -ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=50)"; /* IE 5-7 */ filter: alpha(opacity=50); /* Netscape */ -moz-opacity: 0.5; /* Safari 1.x */ -khtml-opacity: 0.5; /* Good browsers */ opacity: 0.5; }
+
+
+    /*styling for multiple select*/
+    .SumoSelect > .optWrapper.multiple > .options > li { padding-left: 35px;cursor: pointer;}
+        .SumoSelect > .optWrapper.multiple > .options > li span,
+        .SumoSelect .select-all > span{position:absolute;display:block;width:30px;top:0px;bottom:0px;margin-left:-35px;}
+            .SumoSelect > .optWrapper.multiple > .options > li span i,
+            .SumoSelect .select-all > span i{position: absolute;margin: auto;left: 0px;right: 0px;top: 0px;bottom: 0px;width: 14px;height: 14px;border: 1px solid #AEAEAE;border-radius: 2px;box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.15);background-color: #fff;}
+.SumoSelect > .optWrapper > .MultiControls { display: none; border-top: 1px solid #ddd; background-color: #fff; box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.13); border-radius: 0px 0px 3px 3px; }
+    .SumoSelect > .optWrapper.multiple.isFloating > .MultiControls { display: block; margin-top: 5px; position: absolute; bottom: 0px; width: 100%; }
+
+    .SumoSelect > .optWrapper.multiple.okCancelInMulti > .MultiControls { display: block; }
+        .SumoSelect > .optWrapper.multiple.okCancelInMulti > .MultiControls > p { padding: 6px; }
+
+    .SumoSelect > .optWrapper.multiple > .MultiControls > p { display: inline-block; cursor: pointer; padding: 12px; width: 50%; box-sizing: border-box; text-align: center; }
+        .SumoSelect > .optWrapper.multiple > .MultiControls > p:hover { background-color: #f1f1f1; }
+        .SumoSelect > .optWrapper.multiple > .MultiControls > p.btnOk { border-right: 1px solid #DBDBDB; border-radius: 0px 0px 0px 3px; }
+        .SumoSelect > .optWrapper.multiple > .MultiControls > p.btnCancel { border-radius: 0px 0px 3px 0px; }
+    /*styling for select on popup mode*/
+    .SumoSelect > .optWrapper.isFloating > .options > li { padding: 12px 6px; }
+
+    /*styling for only multiple select on popup mode*/
+    .SumoSelect > .optWrapper.multiple.isFloating > .options > li { padding-left: 35px; }
+    .SumoSelect > .optWrapper.multiple.isFloating { padding-bottom: 43px; }
+    /*selected state
+    .SumoSelect > .optWrapper.multiple > .options > li.selected span i:after,
+    .SumoSelect .select-all.selected > span i:after{content: '';position: absolute;width: 11px;height: 11px;top: 2px;left: 2px;background-color: rgb(17, 169, 17);border-radius: 2px;box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.15);}
+    */
+    .SumoSelect > .optWrapper.multiple > .options > li.selected span i,
+    .SumoSelect .select-all.selected > span i,
+    .SumoSelect .select-all.partial > span i{background-color: rgb(17, 169, 17);box-shadow: none;border-color: transparent;background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAGCAYAAAD+Bd/7AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNXG14zYAAABMSURBVAiZfc0xDkAAFIPhd2Kr1WRjcAExuIgzGUTIZ/AkImjSofnbNBAfHvzAHjOKNzhiQ42IDFXCDivaaxAJd0xYshT3QqBxqnxeHvhunpu23xnmAAAAAElFTkSuQmCC');background-repeat: no-repeat;background-position: center center;}
+    /*disabled state*/
+    .SumoSelect.disabled { opacity: 0.7;cursor: not-allowed;}
+     .SumoSelect.disabled > .CaptionCont{border-color:#ccc;box-shadow:none;}
+
+    /**Select all button**/
+    .SumoSelect .select-all{border-radius: 3px 3px 0px 0px;position: relative;border-bottom: 1px solid #ddd;background-color: #fff;padding: 8px 0px 3px 35px;height: 20px;}
+    .SumoSelect .select-all > span i{cursor:pointer;}
+    .SumoSelect .select-all.partial > span i{background-color:#ccc;}
+
+
+
+     /*styling for optgroups*/
+    .SumoSelect > .optWrapper > .options > li.optGroup { padding-left: 5px; text-decoration: underline; }
+

File diff suppressed because it is too large
+ 5 - 0
demo/public/static/formbuilder/demo.css


File diff suppressed because it is too large
+ 220 - 0
demo/public/static/formbuilder/form-builder.css


+ 1354 - 0
demo/public/static/formbuilder/form-builder.js

@@ -0,0 +1,1354 @@
+/*
+formBuilder - git@github.com:kevinchappell/formBuilder.git
+Version: 1.6.2
+Author: Kevin Chappell <kevin.b.chappell@gmail.com>
+*/
+'use strict';
+
+(function($) {
+    'use strict';
+
+    var Toggle = function Toggle(element, options) {
+
+        var defaults = {
+            theme: 'fresh',
+            labels: {
+                off: 'Off',
+                on: 'On'
+            }
+        };
+
+        var opts = $.extend(defaults, options),
+        $kcToggle = $('<div class="kc-toggle"/>').insertAfter(element).append(element);
+
+        $kcToggle.toggleClass('on', element.is(':checked'));
+
+        var kctOn = '<div class="kct-on">' + opts.labels.on + '</div>',
+        kctOff = '<div class="kct-off">' + opts.labels.off + '</div>',
+        kctHandle = '<div class="kct-handle"></div>',
+        kctInner = '<div class="kct-inner">' + kctOn + kctHandle + kctOff + '</div>';
+
+        $kcToggle.append(kctInner);
+
+        $kcToggle.click(function() {
+            element.attr('checked', !element.attr('checked'));
+            $(this).toggleClass('on');
+        });
+    };
+
+    $.fn.kcToggle = function(options) {
+        var toggle = this;
+        return toggle.each(function() {
+            var element = $(this);
+            if (element.data('kcToggle')) {
+                return;
+            }
+            var kcToggle = new Toggle(element, options);
+            element.data('kcToggle', kcToggle);
+        });
+    };
+})(jQuery);
+'use strict';
+
+(function($) {
+    'use strict';
+    var FormBuilder = function FormBuilder(element, options) {
+
+        var defaults = {
+            // Uneditable fields or other content you would like to
+            // appear before and after regular fields.
+            disableFields: {
+                // before: '<h2>Header</h2>',
+                // after: '<h3>Footer</h3>'
+            },
+            // array of objects with fields values
+            // ex:
+            // defaultFields: [{
+            //   label: 'First Name',
+            //   name: 'first-name',
+            //   required: 'true',
+            //   description: 'Your first name',
+            //   type: 'text'
+            // }, {
+            //   label: 'Phone',
+            //   name: 'phone',
+            //   description: 'How can we reach you?',
+            //   type: 'text'
+            // }],
+            defaultFields: [],
+            roles: {
+                1 : 'Administrator'
+            },
+            showWarning: false,
+            serializePrefix: 'frmb',
+            messages: {
+                add: 'Add Item',
+                allowSelect: 'Allow Select',
+                autocomplete: 'Autocomplete',
+                cannotBeEmpty: 'This field cannot be empty',
+                checkboxGroup: 'Checkbox Group',
+                checkbox: 'Checkbox',
+                checkboxes: 'Checkboxes',
+                clearAllMessage: 'Are you sure you want to remove all items?',
+                clearAll: 'Clear All',
+                close: 'Close',
+                copy: 'Copy To Clipboard',
+                dateField: 'Date Field',
+                description: 'Help Text',
+                descriptionField: 'Description',
+                devMode: 'Developer Mode',
+                disableFields: 'These fields cannot be moved.',
+                editNames: 'Edit Names',
+                editorTitle: 'Form Elements',
+                editXML: 'Edit XML',
+                fieldVars: 'Field Variables',
+                fieldRemoveWarning: 'Are you sure you want to remove this field?',
+                getStarted: 'Drag a field from the right to this area',
+                hide: 'Edit',
+                hidden: 'Hidden Input',
+                label: 'Label',
+                labelEmpty: 'Field Label cannot be empty',
+                limitRole: 'Limit access to one or more of the following roles:',
+                mandatory: 'Mandatory',
+                maxLength: 'Max Length',
+                minOptionMessage: 'This field requires a minimum of 2 options',
+                name: 'Name',
+                no: 'No',
+                off: 'Off',
+                on: 'On',
+                optional: 'optional',
+                optionLabelPlaceholder: 'Label',
+                optionValuePlaceholder: 'Value',
+                optionEmpty: 'Option value required',
+                paragraph: 'Paragraph',
+                preview: 'Preview',
+                radioGroup: 'Radio Group',
+                radio: 'Radio',
+                removeMessage: 'Remove Element',
+                remove: '&#215;',
+                required: 'Required',
+                richText: 'Rich Text Editor',
+                roles: 'Access',
+                save: 'Save Template',
+                selectOptions: 'Select Items',
+                select: 'Select',
+                selectionsMessage: 'Allow Multiple Selections',
+                text: 'Text Field',
+                textLabel: 'Title',
+                textIntroduce: 'Description',
+                toggle: 'Toggle',
+                warning: 'Warning!',
+                viewXML: 'View XML',
+                yes: 'Yes',
+                defaultValue : 'Default Value',
+            }
+        };
+
+        var startIndex, doCancel, _helpers = {};
+
+        /**
+     * Callback for when a drag begins
+     * @param  {object} event
+     * @param  {object} ui
+     */
+        _helpers.startMoving = function(event, ui) {
+            event = event;
+            ui.item.addClass('moving');
+            startIndex = $('li', this).index(ui.item);
+        };
+
+        /**
+     * Callback for when a drag ends
+     * @param  {object} event
+     * @param  {object} ui
+     */
+        _helpers.stopMoving = function(event, ui) {
+            event = event;
+            ui.item.removeClass('moving');
+            if (doCancel) {
+                $(ui.sender).sortable('cancel');
+                $(this).sortable('cancel');
+            }
+        };
+
+     /**
+      * Make strings safe to be used as classes
+      * @param  {string} str string to be converted
+      * @return {string}     converter string
+     */
+        _helpers.safename = function(str) {
+            return str.replace(/\s/g, '-').replace(/[^a-zA-Z0-9\-\_]/g, '').toLowerCase();
+        };
+
+     /**
+      * Strips non-numbers from a number only input
+      * @param  {string} str string with possible number
+      * @return {string}     string without numbers
+     */
+        _helpers.forceNumber = function(str) {
+            return str.replace(/[^0-9]/g, '');
+        };
+
+        /**
+     * hide and show mouse tracking tooltips, only used for disabled
+     * fields in the editor.
+     * @todo   remove or refactor to make better use
+     * @param  {object} tt jQuery option with nexted tooltip
+     * @return {void}
+     */
+        _helpers.initTooltip = function(tt) {
+            var tooltip = tt.find('.tooltip');
+            tt.mouseenter(function() {
+                if (tooltip.outerWidth() > 200) {
+                    tooltip.addClass('max-width');
+                }
+                tooltip.css('left', tt.width() + 14);
+                tooltip.stop(true, true).fadeIn('fast');
+            }).mouseleave(function() {
+                tt.find('.tooltip').stop(true, true).fadeOut('fast');
+            });
+            tooltip.hide();
+        };
+
+        // saves the field data to our canvas (elem)
+        _helpers.save = function() {
+            $sortableFields.children('li').not('.disabled').each(function() {
+                _helpers.updatePreview($(this));
+            });
+            elem.val($sortableFields.toXML());
+        };
+
+        // updatePreview will generate the preview for radio and checkbox groups
+        _helpers.updatePreview = function(field) {
+            var fieldClass = field.attr('class'),
+            $prevHolder = $('.prev-holder', field);
+
+            if (fieldClass.indexOf('ui-sortable-handle') !== -1) {
+                return;
+            }
+
+            fieldClass = fieldClass.replace(' form-field', '');
+
+            var preview, previewData = {
+                type: fieldClass,
+                label: $('.fld-label', field).val()
+            };
+
+            if (fieldClass === 'checkbox') {
+                previewData.toggle = $('.checkbox-toggle', field).is(':checked');
+            }
+
+            if (fieldClass.match(/(select|checkbox-group|radio-group)/)) {
+                previewData.values = [];
+
+                $('.sortable-options li', field).each(function() {
+                    var option = {};
+                    option.selected = $('.select-option', $(this)).is(':checked');
+                    option.value = $('.option-value', $(this)).val();
+                    option.label = $('.option-label', $(this)).val();
+
+                    previewData.values.push(option);
+                });
+            }
+            preview = fieldPreview(previewData);
+
+            $prevHolder.html(preview);
+
+            $('input[toggle]', $prevHolder).kcToggle();
+        };
+
+        // update preview to label
+        _helpers.updateMultipleSelect = function() {
+            $sortableFields.delegate('input[name="multiple"]', 'change',
+            function() {
+                var options = $(this).parents('.fields:eq(0)').find('.sortable-options input.select-option');
+                if (this.checked) {
+                    options.each(function() {
+                        $(this).prop('type', 'checkbox');
+                    });
+                } else {
+                    options.each(function() {
+                        $(this).removeAttr('checked').prop('type', 'radio');
+                    });
+                }
+            });
+        };
+
+        _helpers.htmlEncode = function(value) {
+            return $('<div/>').text(value).html();
+        };
+
+        _helpers.htmlDecode = function(value) {
+            return $('<div/>').html(value).text();
+        };
+
+        _helpers.validateForm = function() {
+            var errors = [];
+            // check for empty field labels
+            $('input[name="label"], input[type="text"].option', $sortableFields).each(function() {
+                if ($(this).val() === '') {
+                    var field = $(this).parents('li.form-field'),
+                    fieldAttr = $(this);
+                    errors.push({
+                        field: field,
+                        error: opts.messages.labelEmpty,
+                        attribute: fieldAttr
+                    });
+                }
+            });
+
+            // @todo add error = { noVal: opts.messages.labelEmpty }
+            if (errors.length) {
+                alert('Error: ' + errors[0].error);
+                $('html, body').animate({
+                    scrollTop: errors[0].field.offset().top
+                },
+                1000,
+                function() {
+                    var targetID = $('.toggle-form', errors[0].field).attr('id');
+                    $('.toggle-form', errors[0].field).addClass('open').parent().next('.prev-holder').slideUp(250);
+                    $('#' + targetID + '-fld').slideDown(250,
+                    function() {
+                        errors[0].attribute.addClass('error');
+                    });
+                });
+            }
+        };
+
+        _helpers.disabledTT = function(field) {
+            var title = field.attr('data-tooltip');
+            if (title) {
+                field.removeAttr('title').data('tip_text', title);
+                var tt = $('<p/>', {
+                    'class': 'frmb-tt'
+                }).html(title);
+                field.append(tt);
+                tt.css({
+                    top: -tt.outerHeight(),
+                    left: -15
+                });
+                field.mouseleave(function() {
+                    $(this).attr('data-tooltip', field.data('tip_text'));
+                    $('.frmb-tt').remove();
+                });
+            }
+        };
+
+        var opts = $.extend(defaults, options),
+        elem = $(element),
+        frmbID = 'frmb-' + $('ul[id^=frmb-]').length++;
+
+        var field = '',
+        lastID = 1,
+        boxID = frmbID + '-control-box';
+
+        // create array of field objects to cycle through
+        var frmbFields = [{
+            label: opts.messages.text,
+            attrs: {
+                type: 'text',
+                className: 'text-input',
+                name: 'text-input'
+            }
+        },
+        {
+            label: opts.messages.select,
+            attrs: {
+                type: 'select',
+                className: 'select',
+                name: 'select'
+            }
+        },
+        {
+            label: opts.messages.richText,
+            attrs: {
+                type: 'rich-text',
+                className: 'rich-text',
+                name: 'rich-text'
+            }
+        },
+        {
+            label: opts.messages.radioGroup,
+            attrs: {
+                type: 'radio-group',
+                className: 'radio-group',
+                name: 'radio-group'
+            }
+        },
+        {
+            label: opts.messages.hidden,
+            attrs: {
+                type: 'hidden',
+                className: 'hidden-input',
+                name: 'hidden-input'
+            }
+        },
+        {
+            label: opts.messages.dateField,
+            attrs: {
+                type: 'date',
+                className: 'calendar',
+                name: 'date-input'
+            }
+        },
+        {
+            label: opts.messages.checkboxGroup,
+            attrs: {
+                type: 'checkbox-group',
+                className: 'checkbox-group',
+                name: 'checkbox-group'
+            }
+        },
+        {
+            label: opts.messages.checkbox,
+            attrs: {
+                type: 'checkbox',
+                className: 'checkbox',
+                name: 'checkbox'
+            }
+        },
+        {
+            label: opts.messages.autocomplete,
+            attrs: {
+                type: 'autocomplete',
+                className: 'autocomplete',
+                name: 'autocomplete'
+            }
+        },
+        {
+            label: opts.messages.textLabel,
+            attrs: {
+                type: 'text-label',
+                className: 'text-label',
+                name: 'text'
+            }
+        }];
+
+        // Create draggable fields for formBuilder
+        var cbUL = $('<ul/>', {
+            id: boxID,
+            'class': 'frmb-control'
+        });
+
+        // Loop through
+        for (var i = frmbFields.length - 1; i >= 0; i--) {
+            var $field = $('<li/>', {
+                'class': 'icon-' + frmbFields[i].attrs.className,
+                'type': frmbFields[i].type,
+                'name': frmbFields[i].className,
+                'label': frmbFields[i].label
+            });
+            for (var attr in frmbFields[i]) {
+                if (frmbFields[i].hasOwnProperty(attr)) {
+                    $field.data(attr, frmbFields[i][attr]);
+                }
+            }
+            $field.html(frmbFields[i].label).appendTo(cbUL);
+        }
+
+        // Build our headers and action links
+        var cbHeader = $('<h4/>').html(opts.messages.editorTitle),
+        viewXML = $('<a/>', {
+            id: frmbID + '-export-xml',
+            text: opts.messages.viewXML,
+            href: '#',
+            'class': 'view-xml'
+        }),
+        allowSelect = $('<a/>', {
+            id: frmbID + '-allow-select',
+            text: opts.messages.allowSelect,
+            href: '#',
+            'class': 'allow-select'
+        }).prop('checked', 'checked'),
+        editXML = $('<a/>', {
+            id: frmbID + '-edit-xml',
+            text: opts.messages.editXML,
+            href: '#',
+            'class': 'edit-xml'
+        }),
+        editNames = $('<a/>', {
+            id: frmbID + '-edit-names',
+            text: opts.messages.editNames,
+            href: '#',
+            'class': 'edit-names'
+        }),
+        clearAll = $('<a/>', {
+            id: frmbID + '-clear-all',
+            text: opts.messages.clearAll,
+            href: '#',
+            'class': 'clear-all'
+        }),
+        saveAll = $('<div/>', {
+            id: frmbID + '-save',
+            href: '#',
+            'class': 'save-btn-wrap',
+            title: opts.messages.save
+        }).html('<a class="save fb-button primary"><span>' + opts.messages.save + '</span></a>'),
+        actionLinksInner = $('<div/>', {
+            id: frmbID + '-action-links-inner',
+            'class': 'action-links-inner'
+        }).append(editXML, ' | ', editNames, ' | ', allowSelect, ' | ', clearAll, ' |&nbsp;'),
+        devMode = $('<span/>', {
+            'class': 'dev-mode-link'
+        }).html(opts.messages.devMode + ' ' + opts.messages.off),
+        actionLinks = $('<div/>', {
+            id: frmbID + '-action-links',
+            'class': 'action-links'
+        }).append(actionLinksInner, devMode);
+
+        // Sortable fields
+        var $sortableFields = $('<ul/>').attr('id', frmbID).addClass('frmb').sortable({
+            cursor: 'move',
+            opacity: 0.9,
+            beforeStop: function beforeStop(event, ui) {
+                var lastIndex = $('> li', $sortableFields).length - 1,
+                curIndex = ui.placeholder.index();
+                doCancel = curIndex <= 1 || curIndex === lastIndex;
+            },
+            start: _helpers.startMoving,
+            stop: _helpers.stopMoving,
+            cancel: 'input, .disabled, .sortable-options, .add, .btn, .no-drag',
+            // items: 'li:not(.no-fields)',
+            receive: function receive(event, ui) {
+                // if (doCancel) {
+                //   $('li:nth-child(' + curIndex + ')', $(this)).remove();
+                // }
+            },
+            placeholder: 'frmb-placeholder'
+        });
+
+        // ControlBox with different fields
+        cbUL.sortable({
+            helper: 'clone',
+            opacity: 0.9,
+            connectWith: $sortableFields,
+            cursor: 'move',
+            placeholder: 'ui-state-highlight',
+            start: _helpers.startMoving,
+            stop: _helpers.stopMoving,
+            revert: 150,
+            change: function change(event, ui) {
+                //fix the logic on this to only hide placeholder for disabledFields.before and after
+                // if (ui.placeholder.index() === 0 || ui.placeholder.index() === $('> li', $sortableFields).last().index()) {
+                //   $(ui.placeholder).hide();
+                // } else {
+                //   $(ui.placeholder).show();
+                // }
+            },
+            remove: function remove(event, ui) {
+                if (startIndex === 0) {
+                    cbUL.prepend(ui.item);
+                } else {
+                    $('li:nth-child(' + startIndex + ')', cbUL).after(ui.item);
+                }
+            },
+            beforeStop: function beforeStop(event, ui) {
+                var lastIndex = $('> li', $sortableFields).length - 1,
+                curIndex = ui.placeholder.index();
+                doCancel = curIndex <= 1 || curIndex === lastIndex ? true: false;
+                if (ui.placeholder.parent().hasClass('frmb-control')) {
+                    doCancel = true;
+                }
+            },
+            update: function update(event, ui) {
+                // _helpers.stopMoving;
+                elem.stopIndex = $('li', $sortableFields).index(ui.item) === 0 ? '0': $('li', $sortableFields).index(ui.item);
+                if ($('li', $sortableFields).index(ui.item) < 0) {
+                    $(this).sortable('cancel');
+                } else {
+                    prepFieldVars($(ui.item[0]), true);
+                }
+            },
+            receive: function receive(event, ui) {
+                if (ui.sender.hasClass('frmb') || ui.sender.hasClass('frmb-control')) {
+                    $(ui.sender).sortable('cancel');
+                }
+            }
+        });
+
+        var $stageWrap = $('<div/>', {
+            id: frmbID + '-stage-wrap',
+            'class': 'stage-wrap'
+        });
+
+        var $formWrap = $('<div/>', {
+            id: frmbID + '-form-wrap',
+            'class': 'form-wrap'
+        });
+
+        elem.before($stageWrap).appendTo($stageWrap);
+
+        // Replace the textarea with sortable list.
+        //elem.before($sortableFields).parent().prepend(frmbHeader).addClass('frmb-wrap').append(actionLinks, viewXML, saveAll);
+        var cbWrap = $('<div/>', {
+            id: frmbID + '-cb-wrap',
+            'class': 'cb-wrap'
+        }).append(cbHeader, cbUL);
+
+        $stageWrap.append($sortableFields, cbWrap, actionLinks, viewXML, saveAll);
+        $stageWrap.before($formWrap);
+        $formWrap.append($stageWrap, cbWrap);
+
+        var doSave = function doSave() {
+            if ($(this).parents('li.disabled').length === 0) {
+                if ($(this).name === 'label' && $(this).val() === '') {
+                    return alert('Error: ' + opts.messages.labelEmpty);
+                }
+                _helpers.save();
+            }
+        };
+
+        // Not pretty but we need to save a lot so users don't have to keep clicking a save button
+        $('input, select', $sortableFields).on('change', doSave);
+        $('input, select', $sortableFields).on('blur', doSave);
+
+        // Parse saved XML template data
+        elem.getTemplate = function() {
+            var xml = elem.val() !== '' ? $.parseXML(elem.val()) : false,
+            fields = $(xml).find('field');
+
+            if (fields.length > 0) {
+                fields.each(function() {
+                    prepFieldVars($(this));
+                });
+            } else if (!xml) {
+                // Load default fields if none are set
+                if (opts.defaultFields.length) {
+                    for (var i = opts.defaultFields.length - 1; i >= 0; i--) {
+                        appendNewField(opts.defaultFields[i]);
+                    }
+                } else {
+                    $stageWrap.addClass('empty').attr('data-content', opts.messages.getStarted);
+                }
+                disabledBeforeAfter();
+            }
+        };
+
+        var disabledBeforeAfter = function disabledBeforeAfter() {
+            var li = '<li class="disabled __POSITION__">__CONTENT__</li>';
+            if (opts.disableFields.before && !$('.disabled.before', $sortableFields).length) {
+                $sortableFields.prepend(li.replace('__POSITION__', 'before').replace('__CONTENT__', opts.disableFields.before));
+            }
+            if (opts.disableFields.after && !$('.disabled.after', $sortableFields).length) {
+                $sortableFields.append(li.replace('__POSITION__', 'after').replace('__CONTENT__', opts.disableFields.after));
+            }
+        };
+
+        var nameAttr = function nameAttr(field) {
+            var epoch = new Date().getTime();
+            return field.data('attrs').name + '-' + epoch;
+        };
+
+        var prepFieldVars = function prepFieldVars($field, isNew) {
+            isNew = isNew || false;
+            var fieldAttrs = $field.data('attrs') || {},
+            fType = fieldAttrs.type || $field.attr('type'),
+            isMultiple = fType.match(/(select|checkbox-group|radio-group)/),
+            values = {};
+
+            values.label = _helpers.htmlEncode($field.attr('label'));
+            values.name = isNew ? nameAttr($field) : fieldAttrs.name || $field.attr('name');
+            values.name = typeof values.name == 'undefined' ? '' : values.name;
+            values.defaultVal = $field.attr('defaultVal') !== undefined ? _helpers.htmlEncode($field.attr('defaultVal')) : '';
+            values.role = $field.attr('role');
+            values.required = $field.attr('required');
+            values.maxLength = $field.attr('max-length');
+            values.toggle = $field.attr('toggle');
+            values.type = fType;
+            values.description = $field.attr('description') !== undefined ? _helpers.htmlEncode($field.attr('description')) : '';
+            values.introduce = $field.attr('introduce') !== undefined ? _helpers.htmlEncode($field.attr('introduce')) : '';
+            if (isMultiple) {
+                values.multiple = true;
+                values.values = [];
+                $field.children().each(function(i) {
+                    var value = {
+                        label: $(this).text(),
+                        value: $(this).attr('value'),
+                        selected: $field.attr('default') === i ? true: false
+                    };
+                    values.values.push(value);
+                });
+            }
+
+            appendNewField(values);
+            $stageWrap.removeClass('empty');
+            disabledBeforeAfter();
+        };
+
+        // multi-line textarea
+        var appendTextarea = function appendTextarea(values) {
+            appendFieldLi(opts.messages.richText, advFields(values), values);
+        };
+
+        var appendInput = function appendInput(values) {
+            var type = values.type || 'text';
+            appendFieldLi(opts.messages[type], advFields(values), values);
+        };
+        var textLabel = function textLabel(values) {
+            var type = values.type || 'text';
+            values.introduce = values.introduce || opts.messages.textIntroduce;
+            appendFieldLi(opts.messages[type], advFields(values), values);
+        }
+        // add select dropdown
+        var appendSelectList = function appendSelectList(values) {
+
+            if (!values.values || !values.values.length) {
+                values.values = [{
+                    selected: 'false',
+                    label: 'Option 1',
+                    value: 'option-1'
+                },
+                {
+                    selected: 'false',
+                    label: 'Option 2',
+                    value: 'option-2'
+                }];
+            }
+
+            var field = '',
+            name = _helpers.safename(values.name),
+            multiDisplay = values.type === 'checkbox-group' ? 'none': 'none';
+
+            field += advFields(values);
+            field += '<div class="false-label">' + opts.messages.selectOptions + '</div>';
+            field += '<div class="fields">';
+
+            field += '<div class="allow-multi" style="display:' + multiDisplay + '">';
+            field += '<input type="checkbox" id="multiple_' + lastID + '" name="multiple"' + (values.multiple ? 'checked="checked"': '') + '>';
+            field += '<label class="multiple" for="multiple_' + lastID + '">' + opts.messages.selectionsMessage + '</label>';
+            field += '</div>';
+            field += '<ol class="sortable-options">';
+            for (i = 0; i < values.values.length; i++) {
+                field += selectFieldOptions(values.values[i], name, values.values[i].selected, values.multiple);
+            }
+            field += '</ol>';
+            field += '<div class="field_actions"><a href="#" class="add add_opt"><strong>' + opts.messages.add + '</strong></a> | <a href="#" class="close_field">' + opts.messages.close + '</a></div>';
+            field += '</div>';
+            appendFieldLi(opts.messages.select, field, values);
+
+            $('.sortable-options').sortable(); // making the dynamically added option fields sortable.
+        };
+
+        var appendNewField = function appendNewField(values) {
+            if (values === undefined) {
+                values = '';
+            }
+
+            // TODO: refactor to move functions into this object
+            var appendFieldType = {
+                // 'text': appendTextInput(values),
+                // 'checkbox': appendCheckbox(values),
+                // 'select': appendSelectList(values),
+                // 'textarea': appendTextarea(values),
+                'text-label': textLabel,
+                '2': appendInput,
+                'date': appendInput,
+                'autocomplete': appendInput,
+                'checkbox': appendInput,
+                'select': appendSelectList,
+                'rich-text': appendTextarea,
+                'textarea': appendTextarea,
+                'radio-group': appendSelectList,
+                'checkbox-group': appendSelectList,
+                'text': appendInput,
+                'hidden': appendInput
+            };
+
+            if (typeof appendFieldType[values.type] === 'function') {
+                appendFieldType[values.type](values);
+            }
+        };
+
+        /**
+     * Build the editable properties for the field
+     * @param  {object} values configuration object for advanced fields
+     * @return {string}        markup for advanced fields
+     */
+        var advFields = function advFields(values) {
+            var advFields = '',
+            key, roles = values.role !== undefined ? values.role.split(',') : [];
+            var fieldLabel = $('<div>', {
+                'class': 'frm-fld label-wrap'
+            });
+            $('<label/>').html(opts.messages.label + ' *').appendTo(fieldLabel);
+            $('<input>', {
+                type: 'text',
+                name: 'label',
+                value: values.label,
+                'class': 'fld-label'
+            }).appendTo(fieldLabel);
+            advFields += fieldLabel[0].outerHTML;
+
+            var fieldDesc = $('<div>', {
+                'class': 'frm-fld description-wrap'
+            });
+            $('<label/>').html(opts.messages.description + ' *').appendTo(fieldDesc);
+
+            if (values.type == 'text-label') { //text-label
+                advFields += '<div class="frm-fld description-wrap"><label>' + opts.messages.textIntroduce + '</label>';
+                advFields += '<input type="text" name="introduce" value="' + values.introduce + '" class="fld-introduce" id="introduce-' + lastID + '" /></div>';
+            }
+            if (values.type != 'text-label') {
+                advFields += '<div class="frm-fld description-wrap"><label>' + opts.messages.description + '</label>';
+                advFields += '<input type="text" name="description" value="' + values.description + '" class="fld-description" id="description-' + lastID + '" /></div>';
+                advFields += '<div class="frm-fld name-wrap"><label>' + opts.messages.name + ' <span class="required">*</span></label>';
+                advFields += '<input type="text" name="name" value="' + values.name + '" class="fld-name" id="title-' + lastID + '" /></div>';
+            }
+
+            advFields += '<div class="frm-fld access-wrap"><label>' + opts.messages.roles + '</label>';
+
+            advFields += '<input type="checkbox" name="enable_roles" value="" ' + (values.role !== undefined ? 'checked': '') + ' id="enable_roles-' + lastID + '"/> <label for="enable_roles-' + lastID + '" class="roles_label">' + opts.messages.limitRole + '</label>';
+            advFields += '<div class="frm-fld available-roles" ' + (values.role !== undefined ? 'style="display:block"': '') + '>';
+            for (key in opts.roles) {
+                if ($.inArray(key, ['date', '4']) === -1) {
+                    advFields += '<input type="checkbox" name="roles[]" value="' + key + '" id="fld-' + lastID + '-roles-' + key + '" ' + ($.inArray(key, roles) !== -1 ? 'checked': '') + ' class="roles-field" /><label for="fld-' + lastID + '-roles-' + key + '">' + opts.roles[key] + '</label><br/>';
+                }
+            }
+            advFields += '</div></div>';
+
+            // if field type is not checkbox, checkbox/radio group or select list, add max length
+            if ($.inArray(values.type, ['checkbox', 'select', 'checkbox-group', 'date', 'autocomplete', 'radio-group', 'text-label']) < 0) {
+                advFields += '<div class="frm-fld"><label class="max-length-label">' + opts.messages.maxLength + '</label>';
+                advFields += '<input type="text" name="max-length" max-length="4" value="' + (values.maxLength !== undefined ? values.maxLength: '') + '" class="fld-max-length" id="max-length-' + lastID + '" /></div>';
+            }
+
+            return advFields;
+        };
+
+        // Append the new field to the editor
+        var appendFieldLi = function appendFieldLi(title, field, values) {
+            var label = $(field).find('input[name="label"]').val() !== '' ? $(field).find('input[name="label"]').val() : title;
+            var defaultVal = typeof values.defaultVal != 'undefined' ? values.defaultVal : '';
+            var introduce = $(field).find('input[name="introduce"]').val() !== '' ? $(field).find('input[name="introduce"]').val() : '';
+            var li = '',
+            delBtn = '<a id="del_' + lastID + '" class="del-button btn delete-confirm" href="#" title="' + opts.messages.removeMessage + '">' + opts.messages.remove + '</a>',
+            toggleBtn = '<a id="frm-' + lastID + '" class="toggle-form btn icon-pencil" href="#" title="' + opts.messages.hide + '"></a> ',
+            required = values.required,
+            toggle = values.toggle || undefined,
+            tooltip = values.description !== '' ? '<span class="tooltip-element" tooltip="' + values.description + '">?</span>': '';
+
+            li += '<li id="frm-' + lastID + '-item" class="' + values.type + ' form-field">';
+            li += '<div class="legend">';
+            li += delBtn;
+            li += '<span id="txt-title-' + lastID + '" class="field-label">' + label + '</span>' + tooltip + '<span class="required-asterisk" ' + (required === 'true' ? 'style="display:inline"': '') + '> *</span>' + toggleBtn;
+            li += '</div>';
+            if (values.type == 'text-label') {
+                li += '<div class="frm-fld">';
+                li += '<label class="field-introduce">' + introduce + '</label>';
+                li += '</div>';
+            }
+            li += '<div class="prev-holder">' + fieldPreview(values) + '</div>';
+            li += '<div id="frm-' + lastID + '-fld" class="frm-holder">';
+            li += '<div class="form-elements">';
+
+            if (values.type != 'text-label') {
+                li += '<div class="frm-fld">';
+                li += '<label>&nbsp;</label>';
+                li += '<input class="required" type="checkbox" value="1" name="required-' + lastID + '" id="required-' + lastID + '"' + (required === 'true' ? ' checked="checked"': '') + ' /><label class="required_label" for="required-' + lastID + '">' + opts.messages.required + '</label>';
+
+                if (values.type === 'checkbox') {
+                    li += '<div class="frm-fld">';
+                    li += '<label>&nbsp;</label>';
+                    li += '<input class="checkbox-toggle" type="checkbox" value="1" name="toggle-' + lastID + '" id="toggle-' + lastID + '"' + (toggle === 'true' ? ' checked="checked"': '') + ' /><label class="toggle-label" for="toggle-' + lastID + '">' + opts.messages.toggle + '</label>';
+                    li += '</div>';
+                }
+                li += '</div>';
+            }
+
+            if (values.type == 'hidden') {
+                li += '<div class="frm-fld">';
+                li += '<label class="field-defaultVal">'+opts.messages.defaultValue+'</label>';
+                li += '<input type="text" class="fld-defaultVal" name="defaultVal" id="defaultVal-'+lastID+'" value="'+ defaultVal +'" />';
+                li += '</div>';
+            }
+            li += field;
+            li += '</div>';
+            li += '</div>';
+            li += '</li>';
+
+            if (elem.stopIndex) {
+                $('li', $sortableFields).eq(elem.stopIndex).after(li);
+            } else {
+                $sortableFields.append(li);
+            }
+
+            $(document.getElementById('frm-' + lastID + '-item')).hide().slideDown(250);
+
+            lastID++;
+            _helpers.save();
+        };
+
+        /**
+     * Generate preview markup
+     * @param  {object} attrs
+     * @return {string}       preview markup for field
+     */
+        var fieldPreview = function fieldPreview(attrs) {
+            var i, preview = '',
+            epoch = new Date().getTime();
+            switch (attrs.type) {
+            case 'textarea':
+                preview = '<' + attrs.type + '></' + attrs.type + '>';
+                break;
+            case 'select':
+                var options;
+                attrs.values.reverse();
+                for (i = attrs.values.length - 1; i >= 0; i--) {
+                    options += '<option value="' + attrs.values[i].value + '">' + attrs.values[i].label + '</option>';
+                }
+                preview = '<' + attrs.type + ' class="no-drag">' + options + '</' + attrs.type + '>';
+                break;
+            case 'checkbox-group':
+            case 'radio-group':
+                var type = attrs.type.replace('-group', '');
+                attrs.values.reverse();
+                for (i = attrs.values.length - 1; i >= 0; i--) {
+                    preview += '<div class="inner-checkbox"><input type="' + type + '" id="' + type + '-' + epoch + '-' + i + '" value="' + attrs.values[i].value + '" /><label for="' + type + '-' + epoch + '-' + i + '">' + attrs.values[i].label + '</label></div>';
+                }
+                break;
+            case 'text':
+            case 'password':
+            case 'hidden':
+            case 'email':
+            case 'date':
+            case 'checkbox':
+                var toggle = attrs.toggle ? 'toggle': '';
+                preview = '<input type="' + attrs.type + '" ' + toggle + ' placeholder="">';
+                break;
+            case 'autocomplete':
+                preview = '<input class="ui-autocomplete-input" autocomplete="on" placeholder="">';
+                break;
+            default:
+                preview = '<' + attrs.type + '></' + attrs.type + '>';
+            }
+
+            return preview;
+        };
+
+        // Select field html, since there may be multiple
+        var selectFieldOptions = function selectFieldOptions(values, name, selected, multipleSelect) {
+            var selectedType = multipleSelect ? 'checkbox': 'radio';
+
+            if (typeof values !== 'object') {
+                values = {
+                    label: '',
+                    value: ''
+                };
+            } else {
+                values.label = values.label || '';
+                values.value = values.value || '';
+            }
+
+            field = '<li>';
+            field += '<input type="' + selectedType + '" ' + selected + ' class="select-option" name="' + name + '" />';
+            field += '<input type="text" class="option-label" placeholder="' + opts.messages.optionLabelPlaceholder + '" value="' + values.label + '" />';
+            field += '<input type="text" class="option-value" placeholder="' + opts.messages.optionValuePlaceholder + '" value="' + values.value + '" />';
+            field += '<a href="#" class="remove btn" title="' + opts.messages.removeMessage + '">' + opts.messages.remove + '</a>';
+            field += '</li>';
+
+            return field;
+        };
+
+        // ---------------------- UTILITIES ---------------------- //
+        // delete options
+        $sortableFields.delegate('.remove', 'click',
+        function(e) {
+            e.preventDefault();
+            var optionsCount = $(this).parents('.sortable-options:eq(0)').children('li').length;
+            if (optionsCount <= 2) {
+                alert('Error: ' + opts.messages.minOptionMessage);
+            } else {
+                $(this).parent('li').slideUp('250',
+                function() {
+                    $(this).remove();
+                });
+            }
+        });
+
+        // toggle fields
+        $sortableFields.on('click', '.toggle-form',
+        function(e) {
+            e.preventDefault();
+            var targetID = $(this).attr('id');
+            $(this).toggleClass('open').parent().next('.prev-holder').slideToggle(250);
+            $(document.getElementById(targetID + '-fld')).slideToggle(250,
+            function() {
+                _helpers.save();
+            });
+        });
+
+        // update preview to label
+        $sortableFields.delegate('input[name="label"]', 'keyup',
+        function() {
+            $('.field-label', $(this).closest('li')).text($(this).val());
+        });
+
+        $sortableFields.delegate('input[name="introduce"]', 'keyup',
+        function() {
+            $('.field-introduce', $(this).closest('li')).text($(this).val());
+        });
+        $sortableFields.delegate('input[name="defaultVal"]', 'keyup',
+        function() {
+            _helpers.save();
+        });
+        // remove error styling when users tries to correct mistake
+        $sortableFields.delegate('input.error', 'keyup',
+        function() {
+            $(this).removeClass('error');
+        });
+
+        // update preview for description
+        $sortableFields.delegate('input[name="description"]', 'keyup',
+        function() {
+            var closestToolTip = $('.tooltip-element', $(this).closest('li'));
+            if ($(this).val() !== '') {
+                if (!closestToolTip.length) {
+                    var tt = '<span class="tooltip-element" tooltip="' + $(this).val() + '">?</span>';
+                    $('.toggle-form', $(this).closest('li')).before(tt);
+                    // _helpers.initTooltip(tt);
+                } else {
+                    closestToolTip.attr('tooltip', $(this).val()).css('display', 'inline-block');
+                }
+            } else {
+                if (closestToolTip.length) {
+                    closestToolTip.css('display', 'none');
+                }
+            }
+        });
+
+        _helpers.updateMultipleSelect();
+
+        // format name attribute
+        $sortableFields.delegate('input[name="name"]', 'keyup',
+        function() {
+            $(this).val(_helpers.safename($(this).val()));
+            if ($(this).val() === '') {
+                $(this).addClass('field_error').attr('placeholder', opts.messages.cannotBeEmpty);
+            } else {
+                $(this).removeClass('field_error');
+            }
+        });
+
+        $sortableFields.delegate('input.fld-max-length', 'keyup',
+        function() {
+            $(this).val(_helpers.forceNumber($(this).val()));
+        });
+
+        // Delete field
+        $sortableFields.delegate('.delete-confirm', 'click',
+        function(e) {
+            e.preventDefault();
+
+            // lets see if the user really wants to remove this field... FOREVER
+            var fieldWarnH3 = $('<h3/>').html('<span></span>' + opts.messages.warning),
+            deleteID = $(this).attr('id').replace(/del_/, ''),
+            delBtn = $(this),
+            $field = $(document.getElementById('frm-' + deleteID + '-item')),
+            toolTipPageX = delBtn.offset().left - $(window).scrollLeft(),
+            toolTipPageY = delBtn.offset().top - $(window).scrollTop();
+
+            if (opts.showWarning) {
+                jQuery('<div />').append(fieldWarnH3, opts.messages.fieldRemoveWarning).dialog({
+                    modal: true,
+                    resizable: false,
+                    width: 300,
+                    dialogClass: 'ite-warning',
+                    open: function open() {
+                        $('.ui-widget-overlay').css({
+                            'opacity': 0.0
+                        });
+                    },
+                    position: [toolTipPageX - 282, toolTipPageY - 178],
+                    buttons: [{
+                        text: opts.messages.yes,
+                        click: function click() {
+                            $field.slideUp(250,
+                            function() {
+                                $(this).remove();
+                                _helpers.save();
+                            });
+                            $(this).dialog('close');
+                        }
+                    },
+                    {
+                        text: opts.messages.no,
+                        'class': 'cancel',
+                        click: function click() {
+                            $(this).dialog('close');
+                        }
+                    }]
+                });
+            } else {
+                $field.slideUp(250,
+                function() {
+                    $(this).remove();
+                    _helpers.save();
+                });
+            }
+
+            if ($('.form-field', $sortableFields).length === 1) {
+                $stageWrap.addClass('empty');
+            }
+        });
+
+        // Attach a callback to toggle required asterisk
+        $sortableFields.delegate('input.required', 'click',
+        function() {
+            var requiredAsterisk = $(this).parents('li.form-field').find('.required-asterisk');
+            requiredAsterisk.toggle();
+        });
+
+        // Attach a callback to toggle roles visibility
+        $sortableFields.delegate('input[name="enable_roles"]', 'click',
+        function() {
+            var roles = $(this).siblings('div.available-roles'),
+            enableRolesCB = $(this);
+            roles.slideToggle(250,
+            function() {
+                if (!enableRolesCB.is(':checked')) {
+                    $('input[type="checkbox"]', roles).removeAttr('checked');
+                }
+            });
+        });
+
+        // Attach a callback to add new checkboxes
+        $sortableFields.delegate('.add_ck', 'click',
+        function() {
+            $(this).parent().before(selectFieldOptions());
+            return false;
+        });
+
+        $sortableFields.delegate('li.disabled .form-element', 'mouseenter',
+        function() {
+            _helpers.disabledTT($(this));
+        });
+
+        // Attach a callback to add new options
+        $sortableFields.delegate('.add_opt', 'click',
+        function(e) {
+            e.preventDefault();
+            var isMultiple = $(this).parents('.fields').first().find('input[name="multiple"]')[0].checked,
+            name = $(this).parents('.fields').find('.select-option:eq(0)').attr('name');
+            $(this).parents('.fields').first().find('.sortable-options').append(selectFieldOptions(false, name, false, isMultiple));
+            _helpers.updateMultipleSelect();
+        });
+
+        // Attach a callback to close link
+        $sortableFields.delegate('.close_field', 'click',
+        function(e) {
+            e.preventDefault();
+            $(this).parents('li.form-field').find('.toggle-form').trigger('click');
+        });
+
+        // Attach a callback to add new radio fields
+        $sortableFields.delegate('.add_rd', 'click',
+        function(e) {
+            e.preventDefault();
+            $(this).parent().before(selectFieldOptions(false, $(this).parents('.frm-holder').attr('id')));
+        });
+
+        $('.form-elements .fields .remove, .frmb .del-button').on('hover',
+        function() {
+            $(this).parents('li.form-field').toggleClass('delete');
+        });
+
+        // View XML
+        $(document.getElementById(frmbID + '-export-xml')).click(function(e) {
+            e.preventDefault();
+            var xml = elem.val(),
+            $pre = $('<pre />').text(xml);
+            $pre.dialog({
+                resizable: false,
+                modal: true,
+                width: 720,
+                dialogClass: 'frmb-xml',
+                overlay: {
+                    color: '#333333'
+                }
+            });
+        });
+
+        // Clear all fields in form editor
+        $(document.getElementById(frmbID + '-clear-all')).click(function(e) {
+            e.preventDefault();
+            if (window.confirm(opts.messages.clearAllMessage)) {
+                $sortableFields.empty();
+                elem.val('');
+                _helpers.save();
+                var values = {
+                    label: [opts.messages.descriptionField],
+                    name: ['content'],
+                    required: 'true',
+                    description: opts.messages.mandatory
+                };
+
+                appendNewField(values);
+                $sortableFields.prepend(opts.disableFields.before);
+                $sortableFields.append(opts.disableFields.after);
+            }
+        });
+
+        // Save Idea Template
+        $(document.getElementById(frmbID + '-save')).click(function(e) {
+            if ($(this).find('.ldkInlineEdit').length === 0) {
+                e.preventDefault();
+                if (!$stageWrap.hasClass('edit-xml')) {
+                    _helpers.save();
+                }
+                _helpers.validateForm(e);
+            }
+        });
+
+        var triggerDevMode = false,
+        keys = [],
+        devCode = '68,69,86';
+        // Super secret Developer Tools
+        $('.save.fb-button').mouseover(function() {
+            triggerDevMode = true;
+        }).mouseout(function() {
+            triggerDevMode = false;
+        });
+        $(document.documentElement).keydown(function(e) {
+            keys.push(e.keyCode);
+            if (keys.toString().indexOf(devCode) >= 0) {
+                $('.action-links').toggle();
+                $('.view-xml').toggle();
+                keys = [];
+            }
+        });
+        // Toggle Developer Mode
+        $('.dev-mode-link').click(function(e) {
+            e.preventDefault();
+            var dml = $(this);
+            $stageWrap.toggleClass('dev-mode');
+            dml.parent().css('opacity', 1);
+            if ($stageWrap.hasClass('dev-mode')) {
+                dml.siblings('.action-links-inner').css('width', '100%');
+                dml.html(opts.messages.devMode + ' ' + opts.messages.on).css('color', '#8CC63F');
+            } else {
+                dml.siblings('.action-links-inner').css('width', 0);
+                dml.html(opts.messages.devMode + ' ' + opts.messages.off).css('color', '#666666');
+                triggerDevMode = false;
+                $('.action-links').toggle();
+                $('.view-xml').toggle();
+            }
+        });
+
+        // Toggle Edit Names
+        $(document.getElementById(frmbID + '-edit-names')).click(function(e) {
+            e.preventDefault();
+            $(this).toggleClass('active');
+            $('.name-wrap', $sortableFields).slideToggle(250,
+            function() {
+                $stageWrap.toggleClass('edit-names');
+            });
+        });
+
+        // Toggle Allow Select
+        $(document.getElementById(frmbID + '-allow-select')).click(function(e) {
+            e.preventDefault();
+            $(this).toggleClass('active');
+            $('.allow-multi, .select-option', $sortableFields).slideToggle(250,
+            function() {
+                $stageWrap.toggleClass('allow-select');
+            });
+        });
+
+        // Toggle Edit XML
+        $(document.getElementById(frmbID + '-edit-xml')).click(function(e) {
+            e.preventDefault();
+            $(this).toggleClass('active');
+            $('textarea.idea-template').show();
+            $('.template-textarea-wrap').slideToggle(250);
+            $stageWrap.toggleClass('edit-xml');
+        });
+
+        elem.parent().find('p[id*="ideaTemplate"]').remove();
+        elem.wrap('<div class="template-textarea-wrap"/>');
+        elem.getTemplate();
+    };
+
+    $.fn.formBuilder = function(options) {
+        var form = this;
+        return form.each(function() {
+            var element = $(this);
+            if (element.data('formBuilder')) {
+                return;
+            }
+            var formBuilder = new FormBuilder(this, options);
+            element.data('formBuilder', formBuilder);
+        });
+    };
+})(jQuery);
+
+// toXML is a jQuery plugin that turns our form editor into XML
+(function($) {
+    'use strict';
+    $.fn.toXML = function(options) {
+        var defaults = {
+            prepend: '',
+            attributes: ['class']
+        };
+        var opts = $.extend(defaults, options);
+
+        var serialStr = '';
+
+        // Begin the core plugin
+        this.each(function() {
+            var liCount = 0;
+            var c = 1;
+
+            if ($(this).children().length >= 1) {
+                serialStr += '<form-template>\n\t<fields>';
+
+                // build new xml
+                $(this).children().each(function() {
+                    var $field = $(this);
+                    if (! ($field.hasClass('moving') || $field.hasClass('disabled'))) {
+                        for (var att = 0; att < opts.attributes.length; att++) {
+                            var required = $('input.required', $field).is(':checked') ? 'required="true" ': 'required="false" ',
+                            multipleChecked = $('input[name="multiple"]', $field).is(':checked'),
+                            multiple = multipleChecked ? 'style="multiple" ': '',
+                            t = $field.attr(opts.attributes[att]).replace(' form-field', ''),
+                            // field type
+                            multipleField = t.match(/(select|checkbox-group|radio-group)/),
+                            type = 'type="' + t + '" ',
+                            fName = $('input.fld-name', $field).length > 0 ? ('name="' + $('input.fld-name', $field).val() + '" ') : '',
+                            fLabel = 'label="' + $('input.fld-label', $field).val() + '" ',
+                            roleVals = $.map($('input.roles-field:checked', $field),
+                            function(n) {
+                                return n.value;
+                            }).join(','),
+                            roles = roleVals !== '' ? 'role="' + roleVals + '" ': '',
+
+                            desc = $('input.fld-description', $field).length > 0 ? ('description="' + $('input.fld-description', $field).val() + '" ') : '',
+                            introduce = $('input.fld-introduce', $field).length > 0 ? ('introduce="' + $('input.fld-introduce', $field).val() + '" ') : '',
+							defaultVal = $('input.fld-defaultVal', $field).length > 0 ? ('defaultVal="' + $('input.fld-defaultVal', $field).val() + '" ') : '',
+                            maxLengthVal = $('input.fld-max-length', $field).val(),
+                            maxLength = 'max-length="' + (maxLengthVal !== undefined ? maxLengthVal: '') + '" ',
+                            fSlash = !multipleField ? '/': '';
+                            var fToggle = $('.checkbox-toggle', $field).is(':checked') ? 'toggle="true" ': '';
+
+                            serialStr += '\n\t\t<field ' + fName + fLabel + defaultVal + fToggle + multiple + roles + desc + introduce + (maxLengthVal !== '' ? maxLengthVal !== undefined ? maxLength: '': '') + required + type + fSlash +'>';
+                            if (multipleField) {
+                                c = 1;
+                                $('.sortable-options li', $field).each(function() {
+                                    var $option = $(this),
+                                    optionValue = 'value="' + $('.option-value', $option).val() + '"',
+                                    optionLabel = $('.option-label', $option).val(),
+                                    selected = $('.select-option', $option).is(':checked') ? ' selected="true"': '';
+                                    serialStr += '\n\t\t\t<option' + selected + ' ' + optionValue + '>' + optionLabel + '</option>';
+                                    c++;
+                                });
+                                serialStr += '\n\t\t</field>';
+                            }
+                        }
+                    }
+                    liCount++;
+                });
+                serialStr += '\n\t</fields>\n</form-template>';
+            } // if "$(this).children().length >= 1"
+        });
+        return serialStr;
+    };
+})(jQuery);

+ 312 - 0
demo/public/static/formbuilder/form-render.css

@@ -0,0 +1,312 @@
+/*
+formBuilder - git@github.com:kevinchappell/formBuilder.git
+Version: 1.6.2
+Author: Kevin Chappell <kevin.b.chappell@gmail.com>
+*/
+* {
+	box-sizing: border-box;
+}
+
+button,
+input,
+select,
+textarea {
+	font-family: inherit;
+	font-size: inherit;
+	line-height: inherit;
+}
+
+input {
+	line-height: normal;
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+	margin: 0;
+	font: inherit;
+	color: inherit;
+}
+
+textarea {
+	overflow: auto;
+}
+
+button,
+input,
+select,
+textarea {
+	font-family: inherit;
+	font-size: inherit;
+	line-height: inherit;
+}
+
+.btn-group {
+	position: relative;
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.btn-group > .btn {
+	position: relative;
+	float: left;
+}
+
+.btn {
+	display: inline-block;
+	padding: 6px 12px;
+	margin-bottom: 0;
+	font-size: 14px;
+	font-weight: 400;
+	line-height: 1.42857143;
+	text-align: center;
+	white-space: nowrap;
+	vertical-align: middle;
+	-ms-touch-action: manipulation;
+	touch-action: manipulation;
+	cursor: pointer;
+	-webkit-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+	background-image: none;
+	border: 1px solid transparent;
+	border-radius: 4px;
+}
+
+.btn.btn-default {
+	color: #333;
+	background-color: #fff;
+	border-color: #ccc;
+}
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group {
+	margin-left: -1px;
+}
+
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+	border-top-left-radius: 0;
+	border-bottom-left-radius: 0;
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+	border-top-right-radius: 0;
+	border-bottom-right-radius: 0;
+}
+
+.btn-group-vertical > .btn.active,
+.btn-group-vertical > .btn:active,
+.btn-group-vertical > .btn:focus,
+.btn-group-vertical > .btn:hover,
+.btn-group > .btn.active,
+.btn-group > .btn:active,
+.btn-group > .btn:focus,
+.btn-group > .btn:hover {
+	z-index: 2;
+}
+
+.btn-primary {
+	color: #fff;
+	background-color: #337ab7;
+	border-color: #2e6da4;
+}
+
+.btn-danger {
+	color: #fff;
+	background-color: #d9534f;
+	border-color: #d43f3a;
+}
+
+.btn-default {
+	color: #333;
+	background-color: #fff;
+	border-color: #ccc;
+}
+
+.btn-primary:hover {
+	color: #fff;
+	background-color: #286090;
+	border-color: #204d74;
+}
+
+.input-group .form-control:last-child,
+.input-group-addon:last-child,
+.input-group-btn:first-child > .btn-group:not(:first-child) > .btn,
+.input-group-btn:first-child > .btn:not(:first-child),
+.input-group-btn:last-child > .btn,
+.input-group-btn:last-child > .btn-group > .btn,
+.input-group-btn:last-child > .dropdown-toggle {
+	border-top-left-radius: 0;
+	border-bottom-left-radius: 0;
+}
+
+.input-group .form-control,
+.input-group-addon,
+.input-group-btn {
+	display: table-cell;
+}
+
+.input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+	height: 46px;
+	padding: 10px 16px;
+	font-size: 18px;
+	line-height: 1.3333333;
+	border-radius: 6px;
+}
+
+.input-group .form-control {
+	position: relative;
+	z-index: 2;
+	float: left;
+	width: 100%;
+	margin-bottom: 0;
+}
+
+.input-group {
+	position: relative;
+	display: table;
+	border-collapse: separate;
+}
+
+.form-control,
+output {
+	font-size: 14px;
+	line-height: 1.42857143;
+	color: #555;
+	display: block;
+}
+
+textarea.form-control {
+	height: auto;
+}
+
+.form-control {
+	height: 34px;
+	display: block;
+	width: 100%;
+	padding: 6px 12px;
+	font-size: 14px;
+	line-height: 1.42857143;
+	color: #555;
+	background-color: #fff;
+	background-image: none;
+	border: 1px solid #ccc;
+	border-radius: 4px;
+	box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+	-webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+	transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;
+}
+
+.form-group {
+	margin-bottom: 15px;
+	height: auto;
+	overflow: hidden;
+}
+
+.btn,
+.form-control {
+	background-image: none;
+}
+
+.kc-toggle {
+	position: relative;
+	margin: 4px 0 0 2px;
+	width: 60px;
+	height: 21px;
+	border-radius: 3px;
+	cursor: pointer;
+	overflow: hidden;
+	display: inline-block;
+	background: #e9e9e9;
+	border: 1px solid #cbcbcb;
+	vertical-align: bottom;
+	-webkit-touch-callout: none;
+	-webkit-user-select: none;
+	-khtml-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+}
+
+.kc-toggle .kct-inner {
+	position: absolute;
+	top: 0;
+	left: -28px;
+	width: 115px;
+	height: 100%;
+	-webkit-transition: left 150ms ease;
+	transition: left 150ms ease;
+}
+
+.kc-toggle.on .kct-inner {
+	background: #e2e2e2;
+	background: -webkit-linear-gradient(top, #e2e2e2 0%, #ffffff 100%);
+	background: linear-gradient(to bottom, #e2e2e2 0%, #ffffff 100%);
+	left: 0;
+}
+
+.kc-toggle input {
+	display: none;
+	position: absolute;
+	z-index: -1;
+	opacity: 0;
+	margin: 0;
+	padding: 0;
+	width: 100%;
+	height: 100%;
+}
+
+.kc-toggle
+.kct-on {
+	color: #12a912;
+}
+
+.kct-off {
+	color: #666;
+}
+
+.kct-on, .kct-off, .kct-handle {
+	width: 28px;
+	height: 100%;
+	font-family: Arial, Tahoma, sans-serif;
+	font-size: 12px;
+	text-align: center;
+	line-height: 22px;
+	font-weight: bold;
+	float: left;
+}
+
+.kct-on, .kct-off {
+	position: relative;
+}
+
+.kct-handle {
+	position: relative;
+	height: 17px;
+	background: #ffffff;
+	background: -webkit-linear-gradient(top, #ffffff 0%, #cecece 100%);
+	background: linear-gradient(to bottom, #ffffff 0%, #cecece 100%);
+	border: 1px solid #999;
+	font-weight: 100;
+	color: #4b4b4b;
+	text-shadow: none;
+	border-radius: 3px;
+	margin: 1px;
+}
+
+.inner-checkbox {
+	float: left;
+	display: block;
+	height: auto;
+	overflow: hidden;
+	padding-right: 5px;
+	line-height: 25px;
+}

+ 248 - 0
demo/public/static/formbuilder/form-render.js

@@ -0,0 +1,248 @@
+/*
+formBuilder - git@github.com:kevinchappell/formBuilder.git
+Version: 1.6.2
+Author: Kevin Chappell <kevin.b.chappell@gmail.com>
+*/
+'use strict';
+
+(function($) {
+    'use strict';
+
+    var Toggle = function Toggle(element, options) {
+
+        var defaults = {
+            theme: 'fresh',
+            labels: {
+                off: 'Off',
+                on: 'On'
+            }
+        };
+
+        var opts = $.extend(defaults, options),
+        $kcToggle = $('<div class="kc-toggle"/>').insertAfter(element).append(element);
+
+        $kcToggle.toggleClass('on', element.is(':checked'));
+
+        var kctOn = '<div class="kct-on">' + opts.labels.on + '</div>',
+        kctOff = '<div class="kct-off">' + opts.labels.off + '</div>',
+        kctHandle = '<div class="kct-handle"></div>',
+        kctInner = '<div class="kct-inner">' + kctOn + kctHandle + kctOff + '</div>';
+
+        $kcToggle.append(kctInner);
+
+        $kcToggle.click(function() {
+            element.attr('checked', !element.attr('checked'));
+            $(this).toggleClass('on');
+        });
+    };
+
+    $.fn.kcToggle = function(options) {
+        var toggle = this;
+        return toggle.each(function() {
+            var element = $(this);
+            if (element.data('kcToggle')) {
+                return;
+            }
+            var kcToggle = new Toggle(element, options);
+            element.data('kcToggle', kcToggle);
+        });
+    };
+})(jQuery);
+// render the formBuilder XML into html
+'use strict';
+
+(function($) {
+    'use strict';
+    $.fn.formRender = function(options) {
+        var $template = $(this),
+        defaults = {
+            destroyTemplate: true,
+            // @todo
+            container: false
+        },
+        _helpers = {};
+
+        var opts = $.extend(defaults, options);
+
+     /**
+     * Generate markup wrapper where needed
+     * @param  {string} type
+     * @param  {object} attrs
+     * @param  {string} content we wrap this
+     * @return {string}
+     */
+        _helpers.markup = function(type) {
+            var attrs = arguments.length <= 1 || arguments[1] === undefined ? {}: arguments[1];
+            var content = arguments.length <= 2 || arguments[2] === undefined ? '': arguments[2];
+
+            attrs = _helpers.attrString(attrs);
+            content = Array.isArray(content) ? content.join('') : content;
+            var inlineElems = ['input'],
+            template = inlineElems.indexOf(type) === -1 ? '<' + type + ' ' + attrs + '>' + content + '</' + type + '>': '<' + type + ' ' + attrs + '/>';
+            return template;
+        };
+
+     /**
+     * Generate preview markup
+     * @param  {object} field
+     * @return {string}       preview markup for field
+     * @todo
+     */
+        _helpers.fieldRender = function(field) {
+            var fieldMarkup = '',
+            fieldLabel = '',
+            optionsMarkup = '';
+            var fieldAttrs = _helpers.parseAttrs(field.attributes),
+            fieldDesc = fieldAttrs.description,
+            // @todo
+            fieldOptions = $('option', field);
+            fieldAttrs.id = fieldAttrs.name;
+        	console.log(fieldAttrs);
+        	var defaultVal = typeof fieldAttrs.defaultVal != 'undefined' ? fieldAttrs.defaultVal : '';
+            if (fieldAttrs.type !== 'checkbox') {
+                fieldAttrs['class'] = 'form-control';
+            }
+
+            if (fieldAttrs.type !== 'hidden') {
+                fieldLabel = '<label for="' + fieldAttrs.id + '">' + fieldAttrs.label + '</label>';
+            }
+
+            if (fieldAttrs.required === 'false') {
+                delete fieldAttrs.required;
+            } else {
+                fieldAttrs.required = null;
+                fieldAttrs['aria-required'] = 'true';
+            }
+
+            delete fieldAttrs.label;
+            delete fieldAttrs.description;
+
+            var fieldAttrsString = _helpers.attrString(fieldAttrs);
+
+            switch (fieldAttrs.type) {
+            case 'textarea':
+            case 'rich-text':
+                delete fieldAttrs.type;
+                delete fieldAttrs.value;
+                fieldMarkup = fieldLabel + '<textarea ' + fieldAttrsString + '></textarea>';
+                break;
+            case 'select':
+                fieldAttrs.type = fieldAttrs.type.replace('-group', '');
+
+                if (fieldOptions.length) {
+                    fieldOptions.each(function(index, el) {
+                        var optionAttrs = _helpers.parseAttrs(el.attributes),
+                        optionAttrsString = _helpers.attrString(optionAttrs),
+                        optionText = el.innerHTML || el.innerContent || el.innerText || el.childNodes[0].nodeValue || el.value;
+
+                        optionsMarkup += '<option ' + optionAttrsString + '>' + optionText + '</option>';
+                    });
+                }
+                fieldMarkup = fieldLabel + '<select ' + fieldAttrsString + '>' + optionsMarkup + '</select>';
+                break;
+            case 'checkbox-group':
+            case 'radio-group':
+                fieldAttrs.type = fieldAttrs.type.replace('-group', '');
+                delete fieldAttrs['class'];
+
+                if (fieldOptions.length) { (function() {
+                        var optionName = fieldAttrs.name + '[]';
+                        fieldOptions.each(function(index, el) {
+                            var optionAttrs = $.extend(fieldAttrs, _helpers.parseAttrs(el.attributes));
+                            optionAttrs.name = optionName;
+                            optionAttrs.id = fieldAttrs.id + '-' + index;
+                            var optionAttrsString = _helpers.attrString(optionAttrs),
+                            optionText = el.innerHTML || el.innerContent || el.innerText || el.childNodes[0].nodeValue || el.value;
+
+                            optionsMarkup += '<div class="inner-checkbox"><input ' + optionAttrsString + ' /> <label for="' + optionAttrs.id + '">' + optionText + '</label></div>';
+                        });
+                    })();
+                }
+                fieldMarkup = fieldLabel + '<div class="' + fieldAttrs.type + '-group">' + optionsMarkup + '</div>';
+                break;
+            case 'text':
+            case 'password':
+            case 'email':
+            case 'hidden':
+            case 'date':
+            case 'autocomplete':
+                fieldMarkup = fieldLabel + ' <input ' + fieldAttrsString + ' value="'+defaultVal+'">';
+                break;
+            case 'checkbox':
+                fieldMarkup = '<input ' + fieldAttrsString + '> ' + fieldLabel;
+
+                if (fieldAttrs.toggle) {
+                    setTimeout(function() {
+                        $(document.getElementById(fieldAttrs.id)).kcToggle();
+                    },
+                    100);
+                }
+                break;
+            case 'text-label':
+                fieldMarkup = fieldLabel + '<div class="frm-fld"><label class="field-introduce">' + fieldAttrs.introduce + '</label></div>';
+                break;
+            default:
+                fieldMarkup = '<' + fieldAttrs.type + '></' + fieldAttrs.type + '>';
+            }
+
+            if (fieldAttrs.type !== 'hidden') {
+                fieldMarkup = _helpers.markup('div', {
+                    'class': 'form-group'
+                },
+                fieldMarkup);
+            }
+
+            return fieldMarkup;
+        };
+
+        _helpers.attrString = function(attrs) {
+            var attributes = [];
+            for (var attr in attrs) {
+                if (attrs.hasOwnProperty(attr)) {
+                    var attrVal = attrs[attr] ? '="' + attrs[attr] + '"': '';
+                    attributes.push(attr + attrVal);
+                }
+            }
+            return attributes.join(' ');
+        };
+
+        _helpers.parseAttrs = function(attrNodes) {
+            var fieldAttrs = {};
+            for (var attr in attrNodes) {
+                if (attrNodes.hasOwnProperty(attr)) {
+                    fieldAttrs[attrNodes[attr]['nodeName']] = attrNodes[attr]['nodeValue'];
+                }
+            }
+            return fieldAttrs;
+        };
+
+        // Begin the core plugin
+        this.each(function() {
+            var rendered = [];
+
+            var formData = $.parseXML($template.val()),
+            fields = $('field', formData),
+            settings = $('settings', formData); // @todo
+            if (!formData) {
+                alert('No formData. Add some fields and try again');
+                return false;
+            }
+
+            // generate field markup if we have fields
+            if (fields.length) {
+                fields.each(function(index, field) {
+                    index = index;
+                    rendered.push(_helpers.fieldRender(field));
+                });
+            }
+
+            var output = rendered.join('');
+
+            if (opts.container && opts.container.length) {
+                opts.container.html(output);
+            } else {
+                $template.replaceWith(output);
+            }
+        });
+    };
+})(jQuery);

BIN
demo/public/static/formbuilder/images/bg_hr.png


BIN
demo/public/static/formbuilder/images/blacktocat.png


BIN
demo/public/static/formbuilder/images/icon_download.png


BIN
demo/public/static/formbuilder/images/sprite_download.png


BIN
demo/public/static/formbuilder/img/clipboard-sprite.png


BIN
demo/public/static/formbuilder/img/frmb-sprite.png


+ 65 - 0
demo/public/static/formbuilder/language/cn.js

@@ -0,0 +1,65 @@
+var formbuilder = {};
+formbuilder.language = {};
+formbuilder.language.cn = {
+  				messages:{
+			        add: '添加',
+			        allowSelect: '允许选择',
+			        autocomplete: '自动完成',
+			        cannotBeEmpty: '此表单域不能为空',
+			        checkboxGroup: '多选列表',
+			        checkbox: '选项框',
+			        checkboxes: '多选框',
+			        clearAllMessage: '确定要移除所有项?',
+			        clearAll: '清除所有',
+			        close: '关闭',
+			        copy: '拷贝到粘贴板',
+			        dateField: '日期表单',
+			        description: '帮助',
+			        descriptionField: '描述',
+			        devMode: '开发模式',
+			        disableFields: '表单不能移除.',
+			        editNames: '编辑名字',
+			        editorTitle: '表单元素Form Elements',
+			        editXML: '编辑XML',
+			        fieldVars: '表单值',
+			        fieldRemoveWarning: '去顶要移除此表单元素?',
+			        getStarted: '拖动右侧表单元素到此区域',
+			        hide: '编辑',
+			        hidden: '隐藏输入框',
+			        label: '标签',
+			        labelEmpty: '标签元素不能为空',
+			        limitRole: '权限:',
+			        mandatory: 'Mandatory',
+			        maxLength: '最大长度',
+			        minOptionMessage: '此表单需要最少两个选项',
+			        name: '名字',
+			        no: 'No',
+			        off: 'Off',
+			        on: 'On',
+			        optional: 'optional',
+			        optionLabelPlaceholder: '标签',
+			        optionValuePlaceholder: '值',
+			        optionEmpty: '选项值不能为空',
+			        paragraph: 'Paragraph',
+			        preview: '预览',
+			        radioGroup: '单选',
+			        radio: '单选',
+			        removeMessage: '移除元素',
+			        remove: '&#215;',
+			        required: '必选',
+			        richText: '编辑框',
+			        roles: '权限',
+			        save: '预览模板',
+			        selectOptions: '选项',
+			        select: '选项',
+			        selectionsMessage: '允许多选',
+			        text: '文本域',
+			        textLabel: '标题',
+			        textIntroduce : '描述',
+			        toggle: '切换',
+			        warning: '警告!',
+			        viewXML: '查看 XML',
+			        yes: 'Yes',
+			        defaultValue : '默认值',
+  				}
+  };

+ 116 - 0
demo/public/static/formbuilder/sass/_reset.scss

@@ -0,0 +1,116 @@
+/*******************************************************************************
+MeyerWeb Reset
+*******************************************************************************/
+
+html,
+body,
+div,
+span,
+applet,
+object,
+iframe,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+p,
+blockquote,
+pre,
+a,
+abbr,
+acronym,
+address,
+big,
+cite,
+code,
+del,
+dfn,
+em,
+img,
+ins,
+kbd,
+q,
+s,
+samp,
+small,
+strike,
+strong,
+sub,
+sup,
+tt,
+var,
+b,
+u,
+i,
+center,
+dl,
+dt,
+dd,
+ol,
+ul,
+li,
+fieldset,
+form,
+label,
+legend,
+table,
+caption,
+tbody,
+tfoot,
+thead,
+tr,
+th,
+td,
+article,
+aside,
+canvas,
+details,
+embed,
+figure,
+figcaption,
+footer,
+header,
+hgroup,
+menu,
+nav,
+output,
+ruby,
+section,
+summary,
+time,
+mark,
+audio,
+video {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	font: inherit;
+	vertical-align: baseline;
+}
+/* HTML5 display-role reset for older browsers */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+menu,
+nav,
+section {
+	display: block;
+}
+
+ol,
+ul {
+	list-style: none;
+}
+
+table {
+	border-collapse: collapse;
+	border-spacing: 0;
+}

+ 351 - 0
demo/public/static/formbuilder/sass/_theme.scss

@@ -0,0 +1,351 @@
+/*******************************************************************************
+Slate Theme for GitHub Pages
+by Jason Costello, @jsncostello
+*******************************************************************************/
+
+/*******************************************************************************
+Theme Styles
+*******************************************************************************/
+
+body {
+	box-sizing: border-box;
+	color: #373737;
+	background: #212121;
+	font-size: 14px;
+	font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif;
+	line-height: 1.42857143;
+	-webkit-font-smoothing: antialiased;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+	margin: 10px 0;
+	font-weight: 700;
+	color: #222222;
+	font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif;
+	letter-spacing: -1px;
+}
+
+h1 {
+	font-size: 36px;
+	font-weight: 700;
+}
+
+h2 {
+	padding-bottom: 10px;
+	font-size: 32px;
+	background: url("images/bg_hr.png") repeat-x bottom;
+}
+
+h3 {
+	font-size: 24px;
+}
+
+h4 {
+	font-size: 21px;
+}
+
+h5 {
+	font-size: 18px;
+}
+
+h6 {
+	font-size: 16px;
+}
+
+p {
+	margin: 10px 0 15px 0;
+}
+
+footer p {
+	color: #f2f2f2;
+}
+
+a {
+	text-decoration: none;
+	color: $highlight-color;
+	text-shadow: none;
+	transition: color 0.5s ease;
+	transition: text-shadow 0.5s ease;
+}
+
+a:hover,
+a:focus {
+	text-decoration: underline;
+}
+
+em {
+	font-style: italic;
+}
+
+strong {
+	font-weight: bold;
+}
+
+p img {
+	display: inline;
+	margin: 0;
+	padding: 0;
+	vertical-align: middle;
+	text-align: center;
+	border: none;
+}
+
+pre,
+code {
+	width: 100%;
+	color: #222;
+	background-color: $white;
+	font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace;
+	font-size: 14px;
+	border-radius: 2px;
+}
+
+pre {
+	width: 98%;
+	padding: 1%;
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+	overflow: auto;
+	white-space: pre-wrap;
+}
+
+code {
+	padding: 1%;
+	width: 98%;
+	margin: 0 3px;
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
+}
+
+pre code {
+	display: block;
+	box-shadow: none;
+}
+
+blockquote {
+	color: #666;
+	margin-bottom: 20px;
+	padding: 0 0 0 20px;
+	border-left: 3px solid #bbb;
+}
+
+ul,
+ol,
+dl {
+	margin-bottom: 15px;
+}
+
+ul {
+	list-style-position: inside;
+	list-style: disc;
+	padding-left: 20px;
+}
+
+ol {
+	list-style-position: inside;
+	list-style: decimal;
+	padding-left: 20px;
+}
+
+dl dt {
+	font-weight: bold;
+}
+
+dl dd {
+	padding-left: 20px;
+	font-style: italic;
+}
+
+dl p {
+	padding-left: 20px;
+	font-style: italic;
+}
+
+hr {
+	height: 1px;
+	margin-bottom: 5px;
+	border: none;
+	background: url("images/bg_hr.png") repeat-x center;
+}
+
+table {
+	border: 1px solid #373737;
+	margin-bottom: 20px;
+	text-align: left;
+}
+
+th {
+	font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif;
+	padding: 10px;
+	background: #373737;
+	color: $white;
+}
+
+td {
+	padding: 10px;
+	border: 1px solid #373737;
+}
+
+form {}
+
+/*******************************************************************************
+Full-Width Styles
+*******************************************************************************/
+
+.outer {
+	width: 100%;
+}
+
+.inner {
+	position: relative;
+	max-width: 1080px;
+	padding: 20px 10px;
+	margin: 0 auto;
+}
+
+#forkme_banner {
+	display: block;
+	position: absolute;
+	top: 0;
+	right: 10px;
+	z-index: 10;
+	padding: 10px 50px 10px 10px;
+	color: #fff;
+	background: url("images/blacktocat.png") $highlight-color no-repeat 95% 50%;
+	font-weight: 700;
+	box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
+	border-bottom-left-radius: 2px;
+	border-bottom-right-radius: 2px;
+}
+
+#header_wrap {
+	background: linear-gradient(to bottom, #373737, #212121);
+}
+
+#header_wrap .inner {
+	padding: 50px 10px 30px 10px;
+}
+
+#project_title {
+	margin: 0;
+	color: #fff;
+	font-size: 42px;
+	font-weight: 700;
+	text-shadow: #111 0px 0px 10px;
+}
+
+#project_tagline {
+	color: #fff;
+	font-size: 24px;
+	font-weight: 300;
+	background: none;
+	text-shadow: #111 0px 0px 10px;
+}
+
+#downloads {
+	position: absolute;
+	width: 210px;
+	z-index: 10;
+	bottom: -40px;
+	right: 0;
+	height: 70px;
+	background: url("images/icon_download.png") no-repeat 0% 90%;
+}
+
+.zip_download_link {
+	display: block;
+	float: right;
+	width: 90px;
+	height: 70px;
+	text-indent: -5000px;
+	overflow: hidden;
+	background: url(images/sprite_download.png) no-repeat bottom left;
+}
+
+.tar_download_link {
+	display: block;
+	float: right;
+	width: 90px;
+	height: 70px;
+	text-indent: -5000px;
+	overflow: hidden;
+	background: url(images/sprite_download.png) no-repeat bottom right;
+	margin-left: 10px;
+}
+
+.zip_download_link:hover {
+	background: url(images/sprite_download.png) no-repeat top left;
+}
+
+.tar_download_link:hover {
+	background: url(images/sprite_download.png) no-repeat top right;
+}
+
+#main_content_wrap {
+	background: #f2f2f2;
+	border-top: 1px solid #111;
+	border-bottom: 1px solid #111;
+}
+
+#footer_wrap {
+	background: #212121;
+}
+
+/*******************************************************************************
+Small Device Styles
+*******************************************************************************/
+
+@media screen and (max-width: 480px) {
+	body {
+		font-size: 14px;
+	}
+
+	#downloads {
+		display: none;
+	}
+
+	.inner {
+		min-width: 320px;
+		max-width: 480px;
+	}
+
+	#project_title {
+		font-size: 32px;
+	}
+
+	h1 {
+		font-size: 28px;
+	}
+
+	h2 {
+		font-size: 24px;
+	}
+
+	h3 {
+		font-size: 21px;
+	}
+
+	h4 {
+		font-size: 18px;
+	}
+
+	h5 {
+		font-size: 14px;
+	}
+
+	h6 {
+		font-size: 12px;
+	}
+
+	code,
+	pre {
+		min-width: 320px;
+		max-width: 480px;
+		font-size: 11px;
+		width: 98%;
+		padding: 1%;
+	}
+}

+ 7 - 0
demo/public/static/formbuilder/sass/_variables.scss

@@ -0,0 +1,7 @@
+$highlight-color: #0090ff;
+$color: darken($highlight-color, 20%);
+$border-color: #999;
+$off-white: #fefefe;
+$white: #fff;
+$black: #000;
+$green: #00BC63;

+ 80 - 0
demo/public/static/formbuilder/sass/demo.scss

@@ -0,0 +1,80 @@
+@import "variables";
+@import "reset";
+@import "theme";
+
+.donate-plea {
+  width: 50%;
+  float: left;
+  text-align: left;
+
+  form {
+    float: left;
+    margin-bottom: 10px;
+  }
+}
+
+.copyright {
+  float: right;
+  text-align: right;
+}
+
+header {}
+
+.badges {
+  margin-top: -30px;
+}
+
+.social {
+  margin-top: -40px;
+
+  .chicklets {
+    text-indent: -9999px;
+  }
+}
+
+em {
+  color: $border-color;
+  display: block;
+}
+
+fieldset {
+  border: 1px solid $border-color;
+  background: $off-white;
+  padding: 20px;
+  margin: 20px 0;
+}
+
+legend {
+  border: 1px solid $border-color;
+  background: $off-white;
+  padding: 5px 10px;
+}
+
+#rendered-form {
+  clear: both;
+  float: left;
+  width: 62%;
+  margin-right: 2%;
+
+  .form-group {
+    > label {
+      font-weight: 700;
+      font-size: 1.1em;
+    }
+  }
+}
+
+.render-description {
+  width: 36%;
+  float: right;
+}
+
+#main_content {
+  hr {
+    clear: both;
+  }
+}
+
+.build-form {
+  margin-bottom: 30px;
+}

BIN
demo/public/static/images/001.jpg


BIN
demo/public/static/images/404.png


BIN
demo/public/static/images/add.png


BIN
demo/public/static/images/btnbg.png


BIN
demo/public/static/images/btnbg1.png


BIN
demo/public/static/images/btnbg2.png


BIN
demo/public/static/images/buttonbg.png


BIN
demo/public/static/images/c01.png


BIN
demo/public/static/images/c02.png


BIN
demo/public/static/images/c03.png


BIN
demo/public/static/images/cbg.png


BIN
demo/public/static/images/clist.png


BIN
demo/public/static/images/close.png


BIN
demo/public/static/images/close1.png


BIN
demo/public/static/images/cloud.png


BIN
demo/public/static/images/d01.png


BIN
demo/public/static/images/d02.png


BIN
demo/public/static/images/d03.png


BIN
demo/public/static/images/d04.png


BIN
demo/public/static/images/d05.png


BIN
demo/public/static/images/d06.png


BIN
demo/public/static/images/d07.png


BIN
demo/public/static/images/diskbg.png


BIN
demo/public/static/images/dp.png


BIN
demo/public/static/images/dropdown.blue.active.png


BIN
demo/public/static/images/dropdown.blue.hover.png


BIN
demo/public/static/images/dropdown.blue.png


BIN
demo/public/static/images/dropdown.gif


BIN
demo/public/static/images/dropdown_active.gif


BIN
demo/public/static/images/dropdown_hover.gif


BIN
demo/public/static/images/error.png


BIN
demo/public/static/images/f01.png


BIN
demo/public/static/images/f02.png


BIN
demo/public/static/images/f03.png


BIN
demo/public/static/images/f04.png


BIN
demo/public/static/images/f05.png


BIN
demo/public/static/images/f06.png


BIN
demo/public/static/images/filetype/7z.gif


BIN
demo/public/static/images/filetype/Thumbs.db


BIN
demo/public/static/images/filetype/asp.gif


BIN
demo/public/static/images/filetype/aspx.gif


BIN
demo/public/static/images/filetype/bat.gif


BIN
demo/public/static/images/filetype/bmp.gif


BIN
demo/public/static/images/filetype/chm.gif


BIN
demo/public/static/images/filetype/css.gif


BIN
demo/public/static/images/filetype/db.gif


Some files were not shown because too many files changed in this diff