PageRenderTime 50ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/Honolo_Code_FF/Honolo_Code/Honolo.UI/obj/Debug/Package/PackageTmp/Scripts/jquery.formbuilder.js

http://project-manh-lan.googlecode.com/
JavaScript | 485 lines | 432 code | 0 blank | 53 comment | 44 complexity | 5510b310b2be409cffa7148c2aea222e MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0, LGPL-2.1
  1. /**
  2. * jQuery Form Builder Plugin
  3. * Copyright (c) 2009 Mike Botsko, Botsko.net LLC (http://www.botsko.net)
  4. * http://www.botsko.net/blog/2009/04/jquery-form-builder-plugin/
  5. * Originally designed for AspenMSM, a CMS product from Trellis Development
  6. * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
  7. * Copyright notice and license must remain intact for legal use
  8. */
  9. (function ($) {
  10. $.fn.formbuilder = function (options) {
  11. // Extend the configuration options with user-provided
  12. var defaults = {
  13. save_url: false,
  14. load_url: false,
  15. control_box_target: false,
  16. serialize_prefix: 'frmb',
  17. messages: {
  18. save: "Save",
  19. add_new_field: "Add New Field...",
  20. text: "Text Field",
  21. title: "Title",
  22. paragraph: "Paragraph",
  23. checkboxes: "Checkboxes",
  24. radio: "Radio",
  25. select: "Select List",
  26. text_field: "Text Field",
  27. label: "Label",
  28. paragraph_field: "Paragraph Field",
  29. select_options: "Select Options",
  30. add: "Add",
  31. checkbox_group: "Checkbox Group",
  32. remove_message: "Are you sure you want to remove this element?",
  33. remove: "Remove",
  34. radio_group: "Radio Group",
  35. selections_message: "Allow Multiple Selections",
  36. hide: "Hide",
  37. required: "Required",
  38. show: "Show"
  39. }
  40. };
  41. var opts = $.extend(defaults, options);
  42. var frmb_id = 'frmb-' + $('ul[id^=frmb-]').length++;
  43. return this.each(function () {
  44. var ul_obj = $(this).append('<ul id="' + frmb_id + '" class="frmb"></ul>').find('ul');
  45. var field = '', field_type = '', last_id = 1, help, form_db_id;
  46. // Add a unique class to the current element
  47. $(ul_obj).addClass(frmb_id);
  48. // load existing form data
  49. if (opts.load_url) {
  50. $.getJSON(opts.load_url, function (json) {
  51. form_db_id = json.form_id;
  52. fromJson(json.form_structure);
  53. });
  54. }
  55. // Create form control select box and add into the editor
  56. var controlBox = function (target) {
  57. var select = '';
  58. var box_content = '';
  59. var save_button = '';
  60. var box_id = frmb_id + '-control-box';
  61. var save_id = frmb_id + '-save-button';
  62. // Add the available options
  63. select += '<option value="0">' + opts.messages.add_new_field + '</option>';
  64. select += '<option value="input_text">' + opts.messages.text + '</option>';
  65. select += '<option value="textarea">' + opts.messages.paragraph + '</option>';
  66. select += '<option value="checkbox">' + opts.messages.checkboxes + '</option>';
  67. select += '<option value="radio">' + opts.messages.radio + '</option>';
  68. select += '<option value="select">' + opts.messages.select + '</option>';
  69. // Build the control box and search button content
  70. box_content = '<select id="' + box_id + '" class="frmb-control">' + select + '</select>';
  71. save_button = '<input type="submit" id="' + save_id + '" class="frmb-submit" value="' + opts.messages.save + '"/>';
  72. // Insert the control box into page
  73. if (!target) {
  74. $(ul_obj).before(box_content);
  75. } else {
  76. $(target).append(box_content);
  77. }
  78. // Insert the search button
  79. $(ul_obj).after(save_button);
  80. // Set the form save action
  81. $('#' + save_id).click(function () {
  82. save();
  83. return false;
  84. });
  85. // Add a callback to the select element
  86. $('#' + box_id).change(function () {
  87. appendNewField($(this).val());
  88. $(this).val(0).blur();
  89. // This solves the scrollTo dependency
  90. $('html, body').animate({
  91. scrollTop: $('#frm-' + (last_id - 1) + '-item').offset().top
  92. }, 500);
  93. return false;
  94. });
  95. } (opts.control_box_target);
  96. // Json parser to build the form builder
  97. var fromJson = function (json) {
  98. var values = '';
  99. var options = false;
  100. // Parse json
  101. $(json).each(function () {
  102. // checkbox type
  103. if (this.cssClass === 'checkbox') {
  104. options = [this.title];
  105. values = [];
  106. $.each(this.values, function () {
  107. values.push([this.value, this.baseline]);
  108. });
  109. }
  110. // radio type
  111. else if (this.cssClass === 'radio') {
  112. options = [this.title];
  113. values = [];
  114. $.each(this.values, function () {
  115. values.push([this.value, this.baseline]);
  116. });
  117. }
  118. // select type
  119. else if (this.cssClass === 'select') {
  120. options = [this.title, this.multiple];
  121. values = [];
  122. $.each(this.values, function () {
  123. values.push([this.value, this.baseline]);
  124. });
  125. }
  126. else {
  127. values = [this.values];
  128. }
  129. appendNewField(this.cssClass, values, options, this.required);
  130. });
  131. };
  132. // Wrapper for adding a new field
  133. var appendNewField = function (type, values, options, required) {
  134. field = '';
  135. field_type = type;
  136. if (typeof (values) === 'undefined') {
  137. values = '';
  138. }
  139. switch (type) {
  140. case 'input_text':
  141. appendTextInput(values, required);
  142. break;
  143. case 'textarea':
  144. appendTextarea(values, required);
  145. break;
  146. case 'checkbox':
  147. appendCheckboxGroup(values, options, required);
  148. break;
  149. case 'radio':
  150. appendRadioGroup(values, options, required);
  151. break;
  152. case 'select':
  153. appendSelectList(values, options, required);
  154. break;
  155. }
  156. };
  157. // single line input type="text"
  158. var appendTextInput = function (values, required) {
  159. field += '<label>' + opts.messages.label + '</label>';
  160. field += '<input class="fld-title" id="title-' + last_id + '" type="text" value="' + values + '" />';
  161. help = '';
  162. appendFieldLi(opts.messages.text, field, required, help);
  163. };
  164. // multi-line textarea
  165. var appendTextarea = function (values, required) {
  166. field += '<label>' + opts.messages.label + '</label>';
  167. field += '<input type="text" value="' + values + '" />';
  168. help = '';
  169. appendFieldLi(opts.messages.paragraph_field, field, required, help);
  170. };
  171. // adds a checkbox element
  172. var appendCheckboxGroup = function (values, options, required) {
  173. var title = '';
  174. if (typeof (options) === 'object') {
  175. title = options[0];
  176. }
  177. field += '<div class="chk_group">';
  178. field += '<div class="frm-fld"><label>' + opts.messages.title + '</label>';
  179. field += '<input type="text" name="title" value="' + title + '" /></div>';
  180. field += '<div class="false-label">' + opts.messages.select_options + '</div>';
  181. field += '<div class="fields">';
  182. if (typeof (values) === 'object') {
  183. for (i = 0; i < values.length; i++) {
  184. field += checkboxFieldHtml(values[i]);
  185. }
  186. }
  187. else {
  188. field += checkboxFieldHtml('');
  189. }
  190. field += '<div class="add-area"><a href="#" class="add add_ck">' + opts.messages.add + '</a></div>';
  191. field += '</div>';
  192. field += '</div>';
  193. help = '';
  194. appendFieldLi(opts.messages.checkbox_group, field, required, help);
  195. };
  196. // Checkbox field html, since there may be multiple
  197. var checkboxFieldHtml = function (values) {
  198. var checked = false;
  199. var value = '';
  200. if (typeof (values) === 'object') {
  201. value = values[0];
  202. checked = (values[1] === 'false' || values[1] === 'undefined') ? false : true;
  203. }
  204. field = '';
  205. field += '<div>';
  206. field += '<input type="checkbox"' + (checked ? ' checked="checked"' : '') + ' />';
  207. field += '<input type="text" value="' + value + '" />';
  208. field += '<a href="#" class="remove" title="' + opts.messages.remove_message + '">' + opts.messages.remove + '</a>';
  209. field += '</div>';
  210. return field;
  211. };
  212. // adds a radio element
  213. var appendRadioGroup = function (values, options, required) {
  214. var title = '';
  215. if (typeof (options) === 'object') {
  216. title = options[0];
  217. }
  218. field += '<div class="rd_group">';
  219. field += '<div class="frm-fld"><label>' + opts.messages.title + '</label>';
  220. field += '<input type="text" name="title" value="' + title + '" /></div>';
  221. field += '<div class="false-label">' + opts.messages.select_options + '</div>';
  222. field += '<div class="fields">';
  223. if (typeof (values) === 'object') {
  224. for (i = 0; i < values.length; i++) {
  225. field += radioFieldHtml(values[i], 'frm-' + last_id + '-fld');
  226. }
  227. }
  228. else {
  229. field += radioFieldHtml('', 'frm-' + last_id + '-fld');
  230. }
  231. field += '<div class="add-area"><a href="#" class="add add_rd">' + opts.messages.add + '</a></div>';
  232. field += '</div>';
  233. field += '</div>';
  234. help = '';
  235. appendFieldLi(opts.messages.radio_group, field, required, help);
  236. };
  237. // Radio field html, since there may be multiple
  238. var radioFieldHtml = function (values, name) {
  239. var checked = false;
  240. var value = '';
  241. if (typeof (values) === 'object') {
  242. value = values[0];
  243. checked = (values[1] === 'false' || values[1] === 'undefined') ? false : true;
  244. }
  245. field = '';
  246. field += '<div>';
  247. field += '<input type="radio"' + (checked ? ' checked="checked"' : '') + ' name="radio_' + name + '" />';
  248. field += '<input type="text" value="' + value + '" />';
  249. field += '<a href="#" class="remove" title="' + opts.messages.remove_message + '">' + opts.messages.remove + '</a>';
  250. field += '</div>';
  251. return field;
  252. };
  253. // adds a select/option element
  254. var appendSelectList = function (values, options, required) {
  255. var multiple = false;
  256. var title = '';
  257. if (typeof (options) === 'object') {
  258. title = options[0];
  259. multiple = options[1] === 'true' ? true : false;
  260. }
  261. field += '<div class="opt_group">';
  262. field += '<div class="frm-fld"><label>' + opts.messages.title + '</label>';
  263. field += '<input type="text" name="title" value="' + title + '" /></div>';
  264. field += '';
  265. field += '<div class="false-label">' + opts.messages.select_options + '</div>';
  266. field += '<div class="fields">';
  267. field += '<input type="checkbox" name="multiple"' + (multiple ? 'checked="checked"' : '') + '>';
  268. field += '<label class="auto">' + opts.messages.selections_message + '</label>';
  269. if (typeof (values) === 'object') {
  270. for (i = 0; i < values.length; i++) {
  271. field += selectFieldHtml(values[i], multiple);
  272. }
  273. }
  274. else {
  275. field += selectFieldHtml('', multiple);
  276. }
  277. field += '<div class="add-area"><a href="#" class="add add_opt">' + opts.messages.add + '</a></div>';
  278. field += '</div>';
  279. field += '</div>';
  280. help = '';
  281. appendFieldLi(opts.messages.select, field, required, help);
  282. };
  283. // Select field html, since there may be multiple
  284. var selectFieldHtml = function (values, multiple) {
  285. if (multiple) {
  286. return checkboxFieldHtml(values);
  287. }
  288. else {
  289. return radioFieldHtml(values);
  290. }
  291. };
  292. // Appends the new field markup to the editor
  293. var appendFieldLi = function (title, field_html, required, help) {
  294. if (required) {
  295. required = required === 'checked' ? true : false;
  296. }
  297. var li = '';
  298. li += '<li id="frm-' + last_id + '-item" class="' + field_type + '">';
  299. li += '<div class="legend">';
  300. li += '<a id="frm-' + last_id + '" class="toggle-form" href="#">' + opts.messages.hide + '</a> ';
  301. li += '<a id="del_' + last_id + '" class="del-button delete-confirm" href="#" title="' + opts.messages.remove_message + '"><span>' + opts.messages.remove + '</span></a>';
  302. li += '<strong id="txt-title-' + last_id + '">' + title + '</strong></div>';
  303. li += '<div id="frm-' + last_id + '-fld" class="frm-holder">';
  304. li += '<div class="frm-elements">';
  305. li += '<div class="frm-fld"><label for="required-' + last_id + '">' + opts.messages.required + '</label>';
  306. li += '<input class="required" type="checkbox" value="1" name="required-' + last_id + '" id="required-' + last_id + '"' + (required ? ' checked="checked"' : '') + ' /></div>';
  307. li += field;
  308. li += '</div>';
  309. li += '</div>';
  310. li += '</li>';
  311. $(ul_obj).append(li);
  312. $('#frm-' + last_id + '-item').hide();
  313. $('#frm-' + last_id + '-item').animate({
  314. opacity: 'show',
  315. height: 'show'
  316. }, 'slow');
  317. last_id++;
  318. };
  319. // handle field delete links
  320. $('.remove').live('click', function () {
  321. $(this).parent('div').animate({
  322. opacity: 'hide',
  323. height: 'hide',
  324. marginBottom: '0px'
  325. }, 'fast', function () {
  326. $(this).remove();
  327. });
  328. return false;
  329. });
  330. // handle field display/hide
  331. $('.toggle-form').live('click', function () {
  332. var target = $(this).attr("id");
  333. if ($(this).html() === opts.messages.hide) {
  334. $(this).removeClass('open').addClass('closed').html(opts.messages.show);
  335. $('#' + target + '-fld').animate({
  336. opacity: 'hide',
  337. height: 'hide'
  338. }, 'slow');
  339. return false;
  340. }
  341. if ($(this).html() === opts.messages.show) {
  342. $(this).removeClass('closed').addClass('open').html(opts.messages.hide);
  343. $('#' + target + '-fld').animate({
  344. opacity: 'show',
  345. height: 'show'
  346. }, 'slow');
  347. return false;
  348. }
  349. return false;
  350. });
  351. // handle delete confirmation
  352. $('.delete-confirm').live('click', function () {
  353. var delete_id = $(this).attr("id").replace(/del_/, '');
  354. if (confirm($(this).attr('title'))) {
  355. $('#frm-' + delete_id + '-item').animate({
  356. opacity: 'hide',
  357. height: 'hide',
  358. marginBottom: '0px'
  359. }, 'slow', function () {
  360. $(this).remove();
  361. });
  362. }
  363. return false;
  364. });
  365. // Attach a callback to add new checkboxes
  366. $('.add_ck').live('click', function () {
  367. $(this).parent().before(checkboxFieldHtml());
  368. return false;
  369. });
  370. // Attach a callback to add new options
  371. $('.add_opt').live('click', function () {
  372. $(this).parent().before(selectFieldHtml('', false));
  373. return false;
  374. });
  375. // Attach a callback to add new radio fields
  376. $('.add_rd').live('click', function () {
  377. $(this).parent().before(radioFieldHtml(false, $(this).parents('.frm-holder').attr('id')));
  378. return false;
  379. });
  380. // saves the serialized data to the server
  381. var save = function () {
  382. if (opts.save_url) {
  383. $.ajax({
  384. type: "POST",
  385. url: opts.save_url,
  386. data: $(ul_obj).serializeFormList({
  387. prepend: opts.serialize_prefix
  388. }) + "&form_id=" + form_db_id,
  389. success: function () { }
  390. });
  391. }
  392. };
  393. });
  394. };
  395. })(jQuery);
  396. /**
  397. * jQuery Form Builder List Serialization Plugin
  398. * Copyright (c) 2009 Mike Botsko, Botsko.net LLC (http://www.botsko.net)
  399. * Originally designed for AspenMSM, a CMS product from Trellis Development
  400. * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
  401. * Copyright notice and license must remain intact for legal use
  402. * Modified from the serialize list plugin
  403. * http://www.botsko.net/blog/2009/01/jquery_serialize_list_plugin/
  404. */
  405. (function ($) {
  406. $.fn.serializeFormList = function (options) {
  407. // Extend the configuration options with user-provided
  408. var defaults = {
  409. prepend: 'ul',
  410. is_child: false,
  411. attributes: ['class']
  412. };
  413. var opts = $.extend(defaults, options);
  414. if (!opts.is_child) {
  415. opts.prepend = '&' + opts.prepend;
  416. }
  417. var serialStr = '';
  418. // Begin the core plugin
  419. this.each(function () {
  420. var ul_obj = this;
  421. var li_count = 0;
  422. var c = 1;
  423. $(this).children().each(function () {
  424. for (att = 0; att < opts.attributes.length; att++) {
  425. var key = (opts.attributes[att] === 'class' ? 'cssClass' : opts.attributes[att]);
  426. serialStr += opts.prepend + '[' + li_count + '][' + key + ']=' + encodeURIComponent($(this).attr(opts.attributes[att]));
  427. // append the form field values
  428. if (opts.attributes[att] === 'class') {
  429. serialStr += opts.prepend + '[' + li_count + '][required]=' + encodeURIComponent($('#' + $(this).attr('id') + ' input.required').attr('checked'));
  430. switch ($(this).attr(opts.attributes[att])) {
  431. case 'input_text':
  432. serialStr += opts.prepend + '[' + li_count + '][values]=' + encodeURIComponent($('#' + $(this).attr('id') + ' input[type=text]').val());
  433. break;
  434. case 'textarea':
  435. serialStr += opts.prepend + '[' + li_count + '][values]=' + encodeURIComponent($('#' + $(this).attr('id') + ' input[type=text]').val());
  436. break;
  437. case 'checkbox':
  438. c = 1;
  439. $('#' + $(this).attr('id') + ' input[type=text]').each(function () {
  440. if ($(this).attr('name') === 'title') {
  441. serialStr += opts.prepend + '[' + li_count + '][title]=' + encodeURIComponent($(this).val());
  442. }
  443. else {
  444. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][value]=' + encodeURIComponent($(this).val());
  445. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][baseline]=' + $(this).prev().attr('checked');
  446. }
  447. c++;
  448. });
  449. break;
  450. case 'radio':
  451. c = 1;
  452. $('#' + $(this).attr('id') + ' input[type=text]').each(function () {
  453. if ($(this).attr('name') === 'title') {
  454. serialStr += opts.prepend + '[' + li_count + '][title]=' + encodeURIComponent($(this).val());
  455. }
  456. else {
  457. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][value]=' + encodeURIComponent($(this).val());
  458. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][baseline]=' + $(this).prev().attr('checked');
  459. }
  460. c++;
  461. });
  462. break;
  463. case 'select':
  464. c = 1;
  465. serialStr += opts.prepend + '[' + li_count + '][multiple]=' + $('#' + $(this).attr('id') + ' input[name=multiple]').attr('checked');
  466. $('#' + $(this).attr('id') + ' input[type=text]').each(function () {
  467. if ($(this).attr('name') === 'title') {
  468. serialStr += opts.prepend + '[' + li_count + '][title]=' + encodeURIComponent($(this).val());
  469. }
  470. else {
  471. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][value]=' + encodeURIComponent($(this).val());
  472. serialStr += opts.prepend + '[' + li_count + '][values][' + c + '][baseline]=' + $(this).prev().attr('checked');
  473. }
  474. c++;
  475. });
  476. break;
  477. }
  478. }
  479. }
  480. li_count++;
  481. });
  482. });
  483. return (serialStr);
  484. };
  485. })(jQuery);