activeadmin-selleo-cms 0.0.44 → 0.0.45

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. data/app/admin/activeadmin_selleo_cms/form.rb +31 -0
  2. data/app/admin/activeadmin_selleo_cms/form_question.rb +53 -0
  3. data/app/assets/javascripts/active_admin.js +1 -2
  4. data/app/assets/javascripts/activeadmin-selleo-cms/custom.js +20 -1
  5. data/app/assets/javascripts/activeadmin-selleo-cms/forms.js +4 -0
  6. data/app/assets/javascripts/activeadmin-selleo-cms/forms.storage.js +26 -0
  7. data/app/assets/javascripts/activeadmin-selleo-cms/inline-editing.js +1 -1
  8. data/app/assets/javascripts/activeadmin-selleo-cms/jquery.browser.js +43 -0
  9. data/app/assets/javascripts/activeadmin-selleo-cms/jquery.printElement.js +170 -0
  10. data/app/assets/javascripts/activeadmin-selleo-cms/jquery.validate.js +1231 -0
  11. data/app/controllers/forms_controller.rb +32 -0
  12. data/app/mailers/activeadmin_selleo_cms/form_mailer.rb +10 -0
  13. data/app/models/activeadmin_selleo_cms/form.rb +11 -0
  14. data/app/models/activeadmin_selleo_cms/form_question.rb +75 -0
  15. data/app/models/activeadmin_selleo_cms/form_question_option.rb +22 -0
  16. data/app/models/activeadmin_selleo_cms/section.rb +20 -1
  17. data/app/views/activeadmin_selleo_cms/form_mailer/form_submission.html.erb +12 -0
  18. data/app/views/admin/form_questions/_form.html.haml +45 -0
  19. data/app/views/admin/form_questions/create.js.erb +7 -0
  20. data/app/views/admin/form_questions/destroy.js.erb +2 -0
  21. data/app/views/admin/form_questions/update.js.erb +7 -0
  22. data/app/views/admin/forms/_form.html.haml +50 -0
  23. data/app/views/admin/forms/_question.html.haml +8 -0
  24. data/app/views/admin/forms/_question_type.html.haml +6 -0
  25. data/app/views/admin/forms/_questions.html.haml +2 -0
  26. data/app/views/admin/pages/_form.html.haml +5 -2
  27. data/app/views/admin/pages/_translated_fields.html.haml +4 -4
  28. data/app/views/admin/pages/update.js.erb +1 -1
  29. data/app/views/admin/section_translations/_form.html.haml +2 -0
  30. data/app/views/forms/_form.html.erb +29 -0
  31. data/app/views/forms/deliver.html.erb +4 -0
  32. data/app/views/forms/download.pdf.erb +14 -0
  33. data/app/views/pages/show.html.haml +2 -1
  34. data/config/initializers/mime_types.rb +1 -0
  35. data/config/locales/cms.en.yml +1 -0
  36. data/config/routes.rb +7 -0
  37. data/db/migrate/20130625104333_create_activeadmin_selleo_cms_forms.rb +7 -0
  38. data/db/migrate/20130625104427_create_activeadmin_selleo_cms_form_questions.rb +15 -0
  39. data/db/migrate/20130625104459_create_activeadmin_selleo_cms_form_question_options.rb +10 -0
  40. data/lib/activeadmin-selleo-cms/version.rb +1 -1
  41. data/spec/dummy/db/migrate/20130206173233_change_activeadmin_selleo_cms_searches.rb +29 -0
  42. data/spec/dummy/db/migrate/20130207213528_change_activeadmin_selleo_cms_assets.rb +12 -0
  43. data/spec/dummy/db/migrate/20130211151210_create_activeadmin_selleo_cms_related_items.rb +16 -0
  44. data/spec/dummy/db/migrate/20130531154539_add_position_to_assets.rb +9 -0
  45. data/spec/dummy/db/migrate/20130601141800_add_position_to_related_items.rb +9 -0
  46. data/spec/dummy/db/migrate/20130625104333_create_activeadmin_selleo_cms_forms.rb +7 -0
  47. data/spec/dummy/db/migrate/20130625104427_create_activeadmin_selleo_cms_form_questions.rb +15 -0
  48. data/spec/dummy/db/migrate/20130625104459_create_activeadmin_selleo_cms_form_question_options.rb +10 -0
  49. data/spec/dummy/db/schema.rb +45 -4
  50. data/spec/dummy/db/snapshots/test_database.sql +298 -0
  51. data/spec/dummy/log/development.log +1 -0
  52. data/spec/dummy/log/test.log +24524 -0
  53. data/spec/dummy/tmp/cache/assets/C77/340/sprockets%2F06f5481af9739c75a130a117a607f701 +0 -0
  54. data/spec/dummy/tmp/cache/assets/C8B/AF0/sprockets%2F829fd285b34b067b7a65772590b9322f +0 -0
  55. data/spec/dummy/tmp/cache/assets/CA5/480/sprockets%2F662b7f1465cf2231ce74c33a12b49750 +0 -0
  56. data/spec/dummy/tmp/cache/assets/CA7/930/sprockets%2F4160ea0b3fb73ed707d1663757351b91 +0 -0
  57. data/spec/dummy/tmp/cache/assets/CAE/840/sprockets%2F7cbe7330e41e804f2323d41959368bf0 +0 -0
  58. data/spec/dummy/tmp/cache/assets/CD2/9B0/sprockets%2Fcbd8386d355c330321c6091d29fe50a1 +0 -0
  59. data/spec/dummy/tmp/cache/assets/CD4/C50/sprockets%2Fa3fd41a03ba7406d295997bb5223f820 +0 -0
  60. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  61. data/spec/dummy/tmp/cache/assets/CDB/040/sprockets%2Fc732474e67003a4eb840eb44c5ca9385 +0 -0
  62. data/spec/dummy/tmp/cache/assets/CEB/360/sprockets%2F6beae78de744da1a77728164871177e0 +0 -0
  63. data/spec/dummy/tmp/cache/assets/D1B/ED0/sprockets%2F27587b13b847c685fe516cb0b3a9f7b7 +0 -0
  64. data/spec/dummy/tmp/cache/assets/D20/880/sprockets%2Fc3074825fcb4400fc3312e42a0bce4a4 +0 -0
  65. data/spec/dummy/tmp/cache/assets/D27/750/sprockets%2Fd3dc17d4a8d304b11a443003fc3e8f34 +0 -0
  66. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  67. data/spec/dummy/tmp/cache/assets/D38/540/sprockets%2F86e1ad844bc9df4491a2a52b870421db +0 -0
  68. data/spec/dummy/tmp/cache/assets/D40/960/sprockets%2F8302b0f1464044ee7cead2ae929b888d +0 -0
  69. data/spec/dummy/tmp/cache/assets/D42/580/sprockets%2F2f962efaf10652ad49924dd754aa14e8 +0 -0
  70. data/spec/dummy/tmp/cache/assets/D44/6E0/sprockets%2F754ecc8c755a2e4064066fdde3b16d93 +0 -0
  71. data/spec/dummy/tmp/cache/assets/D48/640/sprockets%2F9f4f18d910b678b1d0777e04cdaf6f24 +0 -0
  72. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  73. data/spec/dummy/tmp/cache/assets/D50/2E0/sprockets%2Fc214d1c2014b4b02b9bc8949bbb52ba3 +0 -0
  74. data/spec/dummy/tmp/cache/assets/D55/BA0/sprockets%2Fff0987a90494a8eaf8186ced2b5b1598 +0 -0
  75. data/spec/dummy/tmp/cache/assets/D59/D70/sprockets%2Fed9f0de1b65ae8d7ef89087c83728461 +0 -0
  76. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  77. data/spec/dummy/tmp/cache/assets/D67/F70/sprockets%2Ffbf08b2a6103c6f1e6b66c2e7a39b265 +0 -0
  78. data/spec/dummy/tmp/cache/assets/D69/EA0/sprockets%2F7f4b66b3b7213ae1f9acf3b405d5378a +0 -0
  79. data/spec/dummy/tmp/cache/assets/D6C/C30/sprockets%2Fd2f2464120598c8cbdbe2c7c907bf15c +0 -0
  80. data/spec/dummy/tmp/cache/assets/D72/830/sprockets%2F3c584d2138ad334768e75ac7a5ec6baf +0 -0
  81. data/spec/dummy/tmp/cache/assets/D73/720/sprockets%2Fb2b61c47ea6ed4dec438305d887e36c4 +0 -0
  82. data/spec/dummy/tmp/cache/assets/D93/4C0/sprockets%2F857ecd2092cee11f740b3cf2e373ad2a +0 -0
  83. data/spec/dummy/tmp/cache/assets/DBE/250/sprockets%2F708b3d002eb534df6bded3ad61f12ce6 +0 -0
  84. data/spec/dummy/tmp/cache/assets/DDA/DF0/sprockets%2F51bffc0e5dec087e64d1ecb728e9691e +0 -0
  85. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  86. data/spec/dummy/tmp/cache/assets/DDD/CC0/sprockets%2F7db330b00298cfa8e9afcef4929d6f7e +0 -0
  87. data/spec/dummy/tmp/cache/assets/DDE/420/sprockets%2Ffb8b186d5bf0307f86f65fc787d2adeb +0 -0
  88. data/spec/dummy/tmp/cache/assets/DE0/9B0/sprockets%2F5a0abb50cbd48f9a10db8c1b42b281eb +0 -0
  89. data/spec/dummy/tmp/cache/assets/DF3/1E0/sprockets%2Faf53b7e5f3b91b6730addb22e1b4e8cc +0 -0
  90. data/spec/dummy/tmp/cache/assets/DFE/550/sprockets%2F9c55bb183d3acabead863e2fdd7a9292 +0 -0
  91. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  92. data/spec/dummy/tmp/cache/assets/E16/490/sprockets%2F12edba3de0bbd243b58b0ffc604df43c +0 -0
  93. data/spec/dummy/tmp/cache/assets/E36/860/sprockets%2F78244ec4bfe8bacf1affa0a39e43f8f8 +0 -0
  94. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_all.css.scssc +0 -0
  95. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_buttons.css.scssc +0 -0
  96. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_gradients.css.scssc +0 -0
  97. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_icons.css.scssc +0 -0
  98. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_reset.css.scssc +0 -0
  99. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_rounded.css.scssc +0 -0
  100. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_sections.css.scssc +0 -0
  101. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_shadows.css.scssc +0 -0
  102. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_typography.scssc +0 -0
  103. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_utilities.scssc +0 -0
  104. data/spec/dummy/tmp/cache/sass/09e583e9f1586e2218afa17943c4e98d5d86c0c6/_variables.css.scssc +0 -0
  105. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_compact.scssc +0 -0
  106. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_flex-grid.scssc +0 -0
  107. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_grid-width.scssc +0 -0
  108. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_linear-gradient.scssc +0 -0
  109. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_modular-scale.scssc +0 -0
  110. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_px-to-em.scssc +0 -0
  111. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_radial-gradient.scssc +0 -0
  112. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_tint-shade.scssc +0 -0
  113. data/spec/dummy/tmp/cache/sass/15da70bc7d0da60bc7a0f58553e8f13c7238b9a6/_transition-property-name.scssc +0 -0
  114. data/spec/dummy/tmp/cache/sass/52912b08735a03631875d00219891a582ac39f91/active_admin.css.scssc +0 -0
  115. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_batch_actions.css.scssc +0 -0
  116. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_blank_slates.scssc +0 -0
  117. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_breadcrumbs.scssc +0 -0
  118. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_buttons.scssc +0 -0
  119. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_columns.scssc +0 -0
  120. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_comments.css.scssc +0 -0
  121. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_date_picker.css.scssc +0 -0
  122. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_dropdown_menu.scssc +0 -0
  123. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_flash_messages.css.scssc +0 -0
  124. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_grid.scssc +0 -0
  125. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_index_list.scssc +0 -0
  126. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_links.scssc +0 -0
  127. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_pagination.scssc +0 -0
  128. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_panels.scssc +0 -0
  129. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_popovers.css.scssc +0 -0
  130. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_scopes.scssc +0 -0
  131. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_status_tags.scssc +0 -0
  132. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_table_tools.css.scssc +0 -0
  133. data/spec/dummy/tmp/cache/sass/58755c7eaf517716926b0807287ef35489683c47/_tables.css.scssc +0 -0
  134. data/spec/dummy/tmp/cache/sass/87d9aadf92f082c849eefdb769b1f3014fbe3d80/_bourbon-deprecated-upcoming.scssc +0 -0
  135. data/spec/dummy/tmp/cache/sass/87d9aadf92f082c849eefdb769b1f3014fbe3d80/_bourbon.scssc +0 -0
  136. data/spec/dummy/tmp/cache/sass/8c9ef3f2c30ba84ed465a051544bf8813f35444d/_footer.scssc +0 -0
  137. data/spec/dummy/tmp/cache/sass/8c9ef3f2c30ba84ed465a051544bf8813f35444d/_main_structure.scssc +0 -0
  138. data/spec/dummy/tmp/cache/sass/8c9ef3f2c30ba84ed465a051544bf8813f35444d/_title_bar.scssc +0 -0
  139. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_animation.scssc +0 -0
  140. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_appearance.scssc +0 -0
  141. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_backface-visibility.scssc +0 -0
  142. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_background-image.scssc +0 -0
  143. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_background.scssc +0 -0
  144. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_border-image.scssc +0 -0
  145. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_border-radius.scssc +0 -0
  146. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_box-sizing.scssc +0 -0
  147. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_columns.scssc +0 -0
  148. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_flex-box.scssc +0 -0
  149. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_font-face.scssc +0 -0
  150. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_hidpi-media-query.scssc +0 -0
  151. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_image-rendering.scssc +0 -0
  152. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_inline-block.scssc +0 -0
  153. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_keyframes.scssc +0 -0
  154. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_linear-gradient.scssc +0 -0
  155. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_perspective.scssc +0 -0
  156. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_placeholder.scssc +0 -0
  157. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_radial-gradient.scssc +0 -0
  158. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_transform.scssc +0 -0
  159. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_transition.scssc +0 -0
  160. data/spec/dummy/tmp/cache/sass/99be3aae4664497e61da2511feebeb7d5faf1139/_user-select.scssc +0 -0
  161. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_deprecated-webkit-gradient.scssc +0 -0
  162. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_gradient-positions-parser.scssc +0 -0
  163. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_linear-positions-parser.scssc +0 -0
  164. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_radial-arg-parser.scssc +0 -0
  165. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_radial-positions-parser.scssc +0 -0
  166. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_render-gradients.scssc +0 -0
  167. data/spec/dummy/tmp/cache/sass/a1e1600793faa04b53e432bebf67bf72909214b5/_shape-size-stripper.scssc +0 -0
  168. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_button.scssc +0 -0
  169. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_clearfix.scssc +0 -0
  170. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_font-family.scssc +0 -0
  171. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_hide-text.scssc +0 -0
  172. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_html5-input-types.scssc +0 -0
  173. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_position.scssc +0 -0
  174. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_prefixer.scssc +0 -0
  175. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_retina-image.scssc +0 -0
  176. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_size.scssc +0 -0
  177. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_timing-functions.scssc +0 -0
  178. data/spec/dummy/tmp/cache/sass/a6f44f7e8dc2f75ba4a2b257f37eeda690933a5f/_triangle.scssc +0 -0
  179. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/_base.css.scssc +0 -0
  180. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/_forms.css.scssc +0 -0
  181. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/_header.css.scssc +0 -0
  182. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/_mixins.css.scssc +0 -0
  183. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/_typography.css.scssc +0 -0
  184. data/spec/dummy/tmp/cache/sass/c48301ebc9d8a1da2083df298428b60619d37c44/print.css.scssc +0 -0
  185. data/spec/dummy/tmp/cache/sass/f5b5749bdb16c7c8c955c12688c619c619fa8448/_dashboard.scssc +0 -0
  186. data/spec/dummy/tmp/cache/sass/f5b5749bdb16c7c8c955c12688c619c619fa8448/_logged_out.scssc +0 -0
  187. data/spec/models/activeadmin_selleo_cms/page_spec.rb +0 -4
  188. metadata +336 -2
@@ -0,0 +1,31 @@
1
+ ActiveAdmin.register ActiveadminSelleoCms::Form, as: 'Form' do
2
+ config.batch_actions = false
3
+ config.filters = false
4
+ actions :all, except: [:create]
5
+
6
+ form :partial => "form"
7
+
8
+ index do
9
+ column :title
10
+ default_actions
11
+ end
12
+
13
+ controller do
14
+ respond_to :html, :json
15
+
16
+ def new
17
+ @form = ActiveadminSelleoCms::Form.create(title: "Change me! :)")
18
+ flash[:notice] = "New form has been created! Please change title and add some fields."
19
+ redirect_to edit_admin_form_path(@form)
20
+ end
21
+
22
+ def update
23
+ update! do |success, failure|
24
+ success.html { redirect_to edit_admin_form_path(@form) }
25
+ failure.html { render action: :edit }
26
+ end
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,53 @@
1
+ ActiveAdmin.register ActiveadminSelleoCms::FormQuestion, as: 'FormQuestion' do
2
+ belongs_to :form
3
+ actions :all, except: [:show]
4
+ menu false
5
+
6
+ collection_action :sort, :method => :get do
7
+ params[:ids].split(",").each_with_index do |id, index|
8
+ ActiveadminSelleoCms::FormQuestion.update_all(['position=?', index+1], ['id=?', id.to_i])
9
+ end
10
+ render :nothing => true
11
+ end
12
+
13
+ controller do
14
+
15
+ def new
16
+ set_form
17
+ @form_question = @form.questions.new(question_type: params[:question_type])
18
+ render :partial => 'form', :layout => false
19
+ end
20
+
21
+ def create
22
+ set_form
23
+ @form_question = @form.questions.new(params[:form_question])
24
+ end
25
+
26
+ def edit
27
+ set_form
28
+ set_question
29
+ render :partial => 'form', :layout => false
30
+ end
31
+
32
+ def update
33
+ set_form
34
+ set_question
35
+ @form_question.update_attributes(params[:form_question])
36
+ end
37
+
38
+ def destroy
39
+ set_form
40
+ set_question
41
+ end
42
+
43
+ def set_form
44
+ @form = ActiveadminSelleoCms::Form.find(params[:form_id])
45
+ end
46
+
47
+ def set_question
48
+ @form_question = @form.questions.find(params[:id])
49
+ end
50
+
51
+ end
52
+
53
+ end
@@ -1,9 +1,8 @@
1
1
  //= require 'active_admin/base'
2
2
  //= require 'ckeditor/init'
3
- //= require 'ckeditor/plugins/inlinesave/plugin'
4
3
  //= require 'activeadmin-selleo-cms/custom.js'
5
4
  //= require 'activeadmin-selleo-cms/jquery-ui-timepicker-addon.js'
6
5
  //= require 'jquery.iframe-transport.js'
7
6
  //= require 'jquery.remotipart.js'
8
7
  //= require 'activeadmin-selleo-cms/jquery.Jcrop'
9
- //= require jquery.ui.effect-highlight
8
+ //= require jquery.ui.effect-highlight
@@ -153,4 +153,23 @@ function savePage(){
153
153
  $('body').effect('highlight')
154
154
  }
155
155
  } );
156
- }
156
+ }
157
+
158
+ $(function(){
159
+ if ( (typeof EDITING != "undefined") && (EDITING == true) ) {
160
+ $('section').addClass("editing");
161
+ $('#file-manager').dialog({
162
+ width: 'auto',
163
+ height: 'auto',
164
+ title: 'CMS Editor',
165
+ modal: true,
166
+ autoOpen: false,
167
+ resize: function( event, ui ) {
168
+ $(this).dialog("option", "position", ['center', 'center'] );
169
+ },
170
+ beforeClose: function() {
171
+ window.location = window.location;
172
+ }
173
+ });
174
+ }
175
+ });
@@ -0,0 +1,4 @@
1
+ //= require 'activeadmin-selleo-cms/jquery.validate'
2
+ //= require 'activeadmin-selleo-cms/jquery.printElement'
3
+ //= require 'activeadmin-selleo-cms/forms.storage'
4
+ //= require 'activeadmin-selleo-cms/jquery.browser'
@@ -0,0 +1,26 @@
1
+ function setupCmsForm(form_id) {
2
+ $('#'+form_id+' .required fieldset [type="radio"]:first,[type="checkbox"]:first').attr('required','true');
3
+ $('#'+form_id).validate();
4
+
5
+ $.each($('#' + form_id + ' input, textarea'), function(){
6
+ if ( localStorage[$(this).attr('id')] != undefined ) {
7
+ if ( ($(this).attr('type') == 'checkbox') || ($(this).attr('type') == 'radio') ) {
8
+ $(this).attr('checked', (localStorage[$(this).attr('id')] == "true"));
9
+ } else if ($(this).attr('type') == 'file') {
10
+ // ??
11
+ } else {
12
+ $(this).val(localStorage[$(this).attr('id')]);
13
+ }
14
+ }
15
+ });
16
+
17
+ $('#' + form_id + ' input, textarea').change(function(){
18
+ if ( ($(this).attr('type') == 'checkbox') || ($(this).attr('type') == 'radio') ) {
19
+ localStorage[$(this).attr('id')] = $(this).is(':checked');
20
+ } else if ($(this).attr('type') == 'file') {
21
+ // ??
22
+ } else {
23
+ localStorage[$(this).attr('id')] = $(this).val();
24
+ }
25
+ });
26
+ }
@@ -5,10 +5,10 @@
5
5
  //= require jquery.iframe-transport.js
6
6
  //= require jquery.remotipart.js
7
7
  //= require ckeditor/init
8
- //= require ckeditor/plugins/inlinesave/plugin
9
8
  //= require ckeditor/toolbars
10
9
  //= require activeadmin-selleo-cms/custom
11
10
  //= require activeadmin-selleo-cms/jquery-ui-timepicker-addon
12
11
  //= require activeadmin-selleo-cms/jquery.Jcrop
12
+ //= require jquery.ui.dialog
13
13
  //= require jquery.ui.effect-highlight
14
14
  //= require jquery.ui.tabs
@@ -0,0 +1,43 @@
1
+ /*!
2
+ * jQuery Migrate - v1.2.1 - 2013-05-08
3
+ * https://github.com/jquery/jquery-migrate
4
+ * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors; Licensed MIT
5
+ */
6
+ (function( jQuery, window, undefined ) {
7
+ jQuery.uaMatch = function( ua ) {
8
+ ua = ua.toLowerCase();
9
+
10
+ var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
11
+ /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
12
+ /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
13
+ /(msie) ([\w.]+)/.exec( ua ) ||
14
+ ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
15
+ [];
16
+
17
+ return {
18
+ browser: match[ 1 ] || "",
19
+ version: match[ 2 ] || "0"
20
+ };
21
+ };
22
+
23
+ // Don't clobber any existing jQuery.browser in case it's different
24
+ if ( !jQuery.browser ) {
25
+ matched = jQuery.uaMatch( navigator.userAgent );
26
+ browser = {};
27
+
28
+ if ( matched.browser ) {
29
+ browser[ matched.browser ] = true;
30
+ browser.version = matched.version;
31
+ }
32
+
33
+ // Chrome is Webkit, but Webkit is also Safari.
34
+ if ( browser.chrome ) {
35
+ browser.webkit = true;
36
+ } else if ( browser.webkit ) {
37
+ browser.safari = true;
38
+ }
39
+
40
+ jQuery.browser = browser;
41
+ }
42
+
43
+ })( jQuery, window );
@@ -0,0 +1,170 @@
1
+ /*! jQuery Printelement - v2.0.0 - 2012-04-19
2
+ * https://github.com/erikzaadi/jQuery.printElement
3
+ * Copyright (c) 2012 erikzaadi; Licensed MIT, GPL */
4
+
5
+ (function (window, undefined) {
6
+ var document = window.document;
7
+ var $ = window.jQuery;
8
+ $.fn.printElement = function (options) {
9
+ var mainOptions = $.extend({}, $.fn.printElement.defaults, options);
10
+ //iframe mode is not supported for opera and chrome 3.0 (it prints the entire page).
11
+ //http://www.google.com/support/forum/p/Webmasters/thread?tid=2cb0f08dce8821c3&hl=en
12
+ if (mainOptions.printMode === 'iframe') {
13
+ if ($.browser.opera || (/chrome/.test(navigator.userAgent.toLowerCase()))) {
14
+ mainOptions.printMode = 'popup';
15
+ }
16
+ }
17
+ //Remove previously printed iframe if exists
18
+ $("[id^='printElement_']").remove();
19
+
20
+ return this.each(function () {
21
+ //Support Metadata Plug-in if available
22
+ var opts = $.meta ? $.extend({}, mainOptions, $(this).data()) : mainOptions;
23
+ _printElement($(this), opts);
24
+ });
25
+ };
26
+ $.fn.printElement.defaults = {
27
+ "printMode": 'iframe', //Usage : iframe / popup
28
+ "pageTitle": '', //Print Page Title
29
+ "overrideElementCSS": null,
30
+ /* Can be one of the following 3 options:
31
+ * 1 : boolean (pass true for stripping all css linked)
32
+ * 2 : array of $.fn.printElement.cssElement (s)
33
+ * 3 : array of strings with paths to alternate css files (optimized for print)
34
+ */
35
+ "printBodyOptions": {
36
+ "styleToAdd": 'padding:10px;margin:10px;', //style attributes to add to the body of print document
37
+ "classNameToAdd": '' //css class to add to the body of print document
38
+ },
39
+ "leaveOpen": false, // in case of popup, leave the print page open or not
40
+ "iframeElementOptions": {
41
+ "styleToAdd": 'border:none;position:absolute;width:0px;height:0px;bottom:0px;left:0px;', //style attributes to add to the iframe element
42
+ "classNameToAdd": '' //css class to add to the iframe element
43
+ }
44
+ };
45
+ $.fn.printElement.cssElement = {
46
+ "href": '',
47
+ "media": ''
48
+ };
49
+ function _printElement(element, opts) {
50
+ //Create markup to be printed
51
+ var html = _getMarkup(element, opts);
52
+
53
+ var popupOrIframe = null;
54
+ var documentToWriteTo = null;
55
+ if (opts.printMode.toLowerCase() === 'popup') {
56
+ popupOrIframe = window.open('about:blank', 'printElementWindow', 'width=650,height=440,scrollbars=yes');
57
+ documentToWriteTo = popupOrIframe.document;
58
+ }
59
+ else {
60
+ //The random ID is to overcome a safari bug http://www.cjboco.com.sharedcopy.com/post.cfm/442dc92cd1c0ca10a5c35210b8166882.html
61
+ var printElementID = "printElement_" + (Math.round(Math.random() * 99999)).toString();
62
+ //Native creation of the element is faster..
63
+ var iframe = document.createElement('IFRAME');
64
+ $(iframe).attr({
65
+ style: opts.iframeElementOptions.styleToAdd,
66
+ id: printElementID,
67
+ className: opts.iframeElementOptions.classNameToAdd,
68
+ frameBorder: 0,
69
+ scrolling: 'no',
70
+ src: 'about:blank'
71
+ });
72
+ document.body.appendChild(iframe);
73
+ documentToWriteTo = (iframe.contentWindow || iframe.contentDocument);
74
+ if (documentToWriteTo.document) {
75
+ documentToWriteTo = documentToWriteTo.document;
76
+ }
77
+ iframe = document.frames ? document.frames[printElementID] : document.getElementById(printElementID);
78
+ popupOrIframe = iframe.contentWindow || iframe;
79
+ }
80
+ focus();
81
+ documentToWriteTo.open();
82
+ documentToWriteTo.write(html);
83
+ documentToWriteTo.close();
84
+ _callPrint(popupOrIframe);
85
+ }
86
+
87
+ function _callPrint(element) {
88
+ if (element && element.printPage) {
89
+ element.printPage();
90
+ }
91
+ else {
92
+ setTimeout(function () {
93
+ _callPrint(element);
94
+ }, 50);
95
+ }
96
+ }
97
+
98
+ function _getElementHTMLIncludingFormElements(element) {
99
+ var $element = $(element);
100
+ //Radiobuttons and checkboxes
101
+ $(":checked", $element).each(function () {
102
+ this.setAttribute('checked', 'checked');
103
+ });
104
+ //simple text inputs
105
+ $("input[type='text']", $element).each(function () {
106
+ this.setAttribute('value', $(this).val());
107
+ });
108
+ $("select", $element).each(function () {
109
+ var $select = $(this);
110
+ $("option", $select).each(function () {
111
+ if ($select.val() === $(this).val()){
112
+ this.setAttribute('selected', 'selected');
113
+ }
114
+ });
115
+ });
116
+ $("textarea", $element).each(function () {
117
+ //Thanks http://blog.ekini.net/2009/02/24/jquery-getting-the-latest-textvalue-inside-a-textarea/
118
+ var value = $(this).attr('value');
119
+ //fix for issue 7 (http://plugins.jquery.com/node/13503 and http://github.com/erikzaadi/jQueryPlugins/issues#issue/7)
120
+ if ($.browser.mozilla && this.firstChild) {
121
+ this.firstChild.textContent = value;
122
+ }
123
+ else {
124
+ this.innerHTML = value;
125
+ } });
126
+ //http://dbj.org/dbj/?p=91
127
+ var elementHtml = $('<div></div>').append($element.clone()).html();
128
+ return elementHtml;
129
+ }
130
+
131
+ function _getBaseHref() {
132
+ var port = (window.location.port) ? ':' + window.location.port : '';
133
+ return window.location.protocol + '//' + window.location.hostname + port + window.location.pathname;
134
+ }
135
+
136
+ function _getMarkup(element, opts) {
137
+ var $element = $(element);
138
+ var elementHtml = _getElementHTMLIncludingFormElements(element);
139
+
140
+ var html = [];
141
+ html.push('<html><head><title>' + opts.pageTitle + '</title>');
142
+ if (opts.overrideElementCSS) {
143
+ if (opts.overrideElementCSS.length > 0) {
144
+ for (var x = 0; x < opts.overrideElementCSS.length; x++) {
145
+ var current = opts.overrideElementCSS[x];
146
+ if (typeof (current) === 'string') {
147
+ html.push('<link type="text/css" rel="stylesheet" href="' + current + '" >');
148
+ }
149
+ else {
150
+ html.push('<link type="text/css" rel="stylesheet" href="' + current["href"] + '" media="' + current["media"] + '" >');
151
+ } }
152
+ }
153
+ }
154
+ else {
155
+ $("link", document).filter(function () {
156
+ return $(this).attr("rel").toLowerCase() === "stylesheet";
157
+ }).each(function () {
158
+ html.push('<link type="text/css" rel="stylesheet" href="' + $(this).attr("href") + '" media="' + $(this).attr('media') + '" >');
159
+ });
160
+ }
161
+ //Ensure that relative links work
162
+ html.push('<base href="' + _getBaseHref() + '" />');
163
+ html.push('</head><body style="' + opts.printBodyOptions.styleToAdd + '" class="' + opts.printBodyOptions.classNameToAdd + '">');
164
+ html.push('<div class="' + $element.attr('class') + '">' + elementHtml + '</div>');
165
+ html.push('<script type="text/javascript">function printPage(){focus();print();' + ((!$.browser.opera && !opts.leaveOpen && opts.printMode.toLowerCase() === 'popup') ? 'close();' : '') + '}</script>');
166
+ html.push('</body></html>');
167
+
168
+ return html.join('');
169
+ }
170
+ }(window));
@@ -0,0 +1,1231 @@
1
+ /*!
2
+ * jQuery Validation Plugin 1.11.1
3
+ *
4
+ * http://bassistance.de/jquery-plugins/jquery-plugin-validation/
5
+ * http://docs.jquery.com/Plugins/Validation
6
+ *
7
+ * Copyright 2013 Jörn Zaefferer
8
+ * Released under the MIT license:
9
+ * http://www.opensource.org/licenses/mit-license.php
10
+ */
11
+
12
+ (function($) {
13
+
14
+ $.extend($.fn, {
15
+ // http://docs.jquery.com/Plugins/Validation/validate
16
+ validate: function( options ) {
17
+
18
+ // if nothing is selected, return nothing; can't chain anyway
19
+ if ( !this.length ) {
20
+ if ( options && options.debug && window.console ) {
21
+ console.warn( "Nothing selected, can't validate, returning nothing." );
22
+ }
23
+ return;
24
+ }
25
+
26
+ // check if a validator for this form was already created
27
+ var validator = $.data( this[0], "validator" );
28
+ if ( validator ) {
29
+ return validator;
30
+ }
31
+
32
+ // Add novalidate tag if HTML5.
33
+ this.attr( "novalidate", "novalidate" );
34
+
35
+ validator = new $.validator( options, this[0] );
36
+ $.data( this[0], "validator", validator );
37
+
38
+ if ( validator.settings.onsubmit ) {
39
+
40
+ this.validateDelegate( ":submit", "click", function( event ) {
41
+ if ( validator.settings.submitHandler ) {
42
+ validator.submitButton = event.target;
43
+ }
44
+ // allow suppressing validation by adding a cancel class to the submit button
45
+ if ( $(event.target).hasClass("cancel") ) {
46
+ validator.cancelSubmit = true;
47
+ }
48
+
49
+ // allow suppressing validation by adding the html5 formnovalidate attribute to the submit button
50
+ if ( $(event.target).attr("formnovalidate") !== undefined ) {
51
+ validator.cancelSubmit = true;
52
+ }
53
+ });
54
+
55
+ // validate the form on submit
56
+ this.submit( function( event ) {
57
+ if ( validator.settings.debug ) {
58
+ // prevent form submit to be able to see console output
59
+ event.preventDefault();
60
+ }
61
+ function handle() {
62
+ var hidden;
63
+ if ( validator.settings.submitHandler ) {
64
+ if ( validator.submitButton ) {
65
+ // insert a hidden input as a replacement for the missing submit button
66
+ hidden = $("<input type='hidden'/>").attr("name", validator.submitButton.name).val( $(validator.submitButton).val() ).appendTo(validator.currentForm);
67
+ }
68
+ validator.settings.submitHandler.call( validator, validator.currentForm, event );
69
+ if ( validator.submitButton ) {
70
+ // and clean up afterwards; thanks to no-block-scope, hidden can be referenced
71
+ hidden.remove();
72
+ }
73
+ return false;
74
+ }
75
+ return true;
76
+ }
77
+
78
+ // prevent submit for invalid forms or custom submit handlers
79
+ if ( validator.cancelSubmit ) {
80
+ validator.cancelSubmit = false;
81
+ return handle();
82
+ }
83
+ if ( validator.form() ) {
84
+ if ( validator.pendingRequest ) {
85
+ validator.formSubmitted = true;
86
+ return false;
87
+ }
88
+ return handle();
89
+ } else {
90
+ validator.focusInvalid();
91
+ return false;
92
+ }
93
+ });
94
+ }
95
+
96
+ return validator;
97
+ },
98
+ // http://docs.jquery.com/Plugins/Validation/valid
99
+ valid: function() {
100
+ if ( $(this[0]).is("form")) {
101
+ return this.validate().form();
102
+ } else {
103
+ var valid = true;
104
+ var validator = $(this[0].form).validate();
105
+ this.each(function() {
106
+ valid = valid && validator.element(this);
107
+ });
108
+ return valid;
109
+ }
110
+ },
111
+ // attributes: space seperated list of attributes to retrieve and remove
112
+ removeAttrs: function( attributes ) {
113
+ var result = {},
114
+ $element = this;
115
+ $.each(attributes.split(/\s/), function( index, value ) {
116
+ result[value] = $element.attr(value);
117
+ $element.removeAttr(value);
118
+ });
119
+ return result;
120
+ },
121
+ // http://docs.jquery.com/Plugins/Validation/rules
122
+ rules: function( command, argument ) {
123
+ var element = this[0];
124
+
125
+ if ( command ) {
126
+ var settings = $.data(element.form, "validator").settings;
127
+ var staticRules = settings.rules;
128
+ var existingRules = $.validator.staticRules(element);
129
+ switch(command) {
130
+ case "add":
131
+ $.extend(existingRules, $.validator.normalizeRule(argument));
132
+ // remove messages from rules, but allow them to be set separetely
133
+ delete existingRules.messages;
134
+ staticRules[element.name] = existingRules;
135
+ if ( argument.messages ) {
136
+ settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages );
137
+ }
138
+ break;
139
+ case "remove":
140
+ if ( !argument ) {
141
+ delete staticRules[element.name];
142
+ return existingRules;
143
+ }
144
+ var filtered = {};
145
+ $.each(argument.split(/\s/), function( index, method ) {
146
+ filtered[method] = existingRules[method];
147
+ delete existingRules[method];
148
+ });
149
+ return filtered;
150
+ }
151
+ }
152
+
153
+ var data = $.validator.normalizeRules(
154
+ $.extend(
155
+ {},
156
+ $.validator.classRules(element),
157
+ $.validator.attributeRules(element),
158
+ $.validator.dataRules(element),
159
+ $.validator.staticRules(element)
160
+ ), element);
161
+
162
+ // make sure required is at front
163
+ if ( data.required ) {
164
+ var param = data.required;
165
+ delete data.required;
166
+ data = $.extend({required: param}, data);
167
+ }
168
+
169
+ return data;
170
+ }
171
+ });
172
+
173
+ // Custom selectors
174
+ $.extend($.expr[":"], {
175
+ // http://docs.jquery.com/Plugins/Validation/blank
176
+ blank: function( a ) { return !$.trim("" + $(a).val()); },
177
+ // http://docs.jquery.com/Plugins/Validation/filled
178
+ filled: function( a ) { return !!$.trim("" + $(a).val()); },
179
+ // http://docs.jquery.com/Plugins/Validation/unchecked
180
+ unchecked: function( a ) { return !$(a).prop("checked"); }
181
+ });
182
+
183
+ // constructor for validator
184
+ $.validator = function( options, form ) {
185
+ this.settings = $.extend( true, {}, $.validator.defaults, options );
186
+ this.currentForm = form;
187
+ this.init();
188
+ };
189
+
190
+ $.validator.format = function( source, params ) {
191
+ if ( arguments.length === 1 ) {
192
+ return function() {
193
+ var args = $.makeArray(arguments);
194
+ args.unshift(source);
195
+ return $.validator.format.apply( this, args );
196
+ };
197
+ }
198
+ if ( arguments.length > 2 && params.constructor !== Array ) {
199
+ params = $.makeArray(arguments).slice(1);
200
+ }
201
+ if ( params.constructor !== Array ) {
202
+ params = [ params ];
203
+ }
204
+ $.each(params, function( i, n ) {
205
+ source = source.replace( new RegExp("\\{" + i + "\\}", "g"), function() {
206
+ return n;
207
+ });
208
+ });
209
+ return source;
210
+ };
211
+
212
+ $.extend($.validator, {
213
+
214
+ defaults: {
215
+ messages: {},
216
+ groups: {},
217
+ rules: {},
218
+ errorClass: "error",
219
+ validClass: "valid",
220
+ errorElement: "label",
221
+ focusInvalid: true,
222
+ errorContainer: $([]),
223
+ errorLabelContainer: $([]),
224
+ onsubmit: true,
225
+ ignore: ":hidden",
226
+ ignoreTitle: false,
227
+ onfocusin: function( element, event ) {
228
+ this.lastActive = element;
229
+
230
+ // hide error label and remove error class on focus if enabled
231
+ if ( this.settings.focusCleanup && !this.blockFocusCleanup ) {
232
+ if ( this.settings.unhighlight ) {
233
+ this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass );
234
+ }
235
+ this.addWrapper(this.errorsFor(element)).hide();
236
+ }
237
+ },
238
+ onfocusout: function( element, event ) {
239
+ if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) {
240
+ this.element(element);
241
+ }
242
+ },
243
+ onkeyup: function( element, event ) {
244
+ if ( event.which === 9 && this.elementValue(element) === "" ) {
245
+ return;
246
+ } else if ( element.name in this.submitted || element === this.lastElement ) {
247
+ this.element(element);
248
+ }
249
+ },
250
+ onclick: function( element, event ) {
251
+ // click on selects, radiobuttons and checkboxes
252
+ if ( element.name in this.submitted ) {
253
+ this.element(element);
254
+ }
255
+ // or option elements, check parent select in that case
256
+ else if ( element.parentNode.name in this.submitted ) {
257
+ this.element(element.parentNode);
258
+ }
259
+ },
260
+ highlight: function( element, errorClass, validClass ) {
261
+ if ( element.type === "radio" ) {
262
+ this.findByName(element.name).addClass(errorClass).removeClass(validClass);
263
+ } else {
264
+ $(element).addClass(errorClass).removeClass(validClass);
265
+ }
266
+ },
267
+ unhighlight: function( element, errorClass, validClass ) {
268
+ if ( element.type === "radio" ) {
269
+ this.findByName(element.name).removeClass(errorClass).addClass(validClass);
270
+ } else {
271
+ $(element).removeClass(errorClass).addClass(validClass);
272
+ }
273
+ }
274
+ },
275
+
276
+ // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults
277
+ setDefaults: function( settings ) {
278
+ $.extend( $.validator.defaults, settings );
279
+ },
280
+
281
+ messages: {
282
+ required: "This field is required.",
283
+ remote: "Please fix this field.",
284
+ email: "Please enter a valid email address.",
285
+ url: "Please enter a valid URL.",
286
+ date: "Please enter a valid date.",
287
+ dateISO: "Please enter a valid date (ISO).",
288
+ number: "Please enter a valid number.",
289
+ digits: "Please enter only digits.",
290
+ creditcard: "Please enter a valid credit card number.",
291
+ equalTo: "Please enter the same value again.",
292
+ maxlength: $.validator.format("Please enter no more than {0} characters."),
293
+ minlength: $.validator.format("Please enter at least {0} characters."),
294
+ rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."),
295
+ range: $.validator.format("Please enter a value between {0} and {1}."),
296
+ max: $.validator.format("Please enter a value less than or equal to {0}."),
297
+ min: $.validator.format("Please enter a value greater than or equal to {0}.")
298
+ },
299
+
300
+ autoCreateRanges: false,
301
+
302
+ prototype: {
303
+
304
+ init: function() {
305
+ this.labelContainer = $(this.settings.errorLabelContainer);
306
+ this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm);
307
+ this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer );
308
+ this.submitted = {};
309
+ this.valueCache = {};
310
+ this.pendingRequest = 0;
311
+ this.pending = {};
312
+ this.invalid = {};
313
+ this.reset();
314
+
315
+ var groups = (this.groups = {});
316
+ $.each(this.settings.groups, function( key, value ) {
317
+ if ( typeof value === "string" ) {
318
+ value = value.split(/\s/);
319
+ }
320
+ $.each(value, function( index, name ) {
321
+ groups[name] = key;
322
+ });
323
+ });
324
+ var rules = this.settings.rules;
325
+ $.each(rules, function( key, value ) {
326
+ rules[key] = $.validator.normalizeRule(value);
327
+ });
328
+
329
+ function delegate(event) {
330
+ var validator = $.data(this[0].form, "validator"),
331
+ eventType = "on" + event.type.replace(/^validate/, "");
332
+ if ( validator.settings[eventType] ) {
333
+ validator.settings[eventType].call(validator, this[0], event);
334
+ }
335
+ }
336
+ $(this.currentForm)
337
+ .validateDelegate(":text, [type='password'], [type='file'], select, textarea, " +
338
+ "[type='number'], [type='search'] ,[type='tel'], [type='url'], " +
339
+ "[type='email'], [type='datetime'], [type='date'], [type='month'], " +
340
+ "[type='week'], [type='time'], [type='datetime-local'], " +
341
+ "[type='range'], [type='color'] ",
342
+ "focusin focusout keyup", delegate)
343
+ .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate);
344
+
345
+ if ( this.settings.invalidHandler ) {
346
+ $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler);
347
+ }
348
+ },
349
+
350
+ // http://docs.jquery.com/Plugins/Validation/Validator/form
351
+ form: function() {
352
+ this.checkForm();
353
+ $.extend(this.submitted, this.errorMap);
354
+ this.invalid = $.extend({}, this.errorMap);
355
+ if ( !this.valid() ) {
356
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
357
+ }
358
+ this.showErrors();
359
+ return this.valid();
360
+ },
361
+
362
+ checkForm: function() {
363
+ this.prepareForm();
364
+ for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) {
365
+ this.check( elements[i] );
366
+ }
367
+ return this.valid();
368
+ },
369
+
370
+ // http://docs.jquery.com/Plugins/Validation/Validator/element
371
+ element: function( element ) {
372
+ element = this.validationTargetFor( this.clean( element ) );
373
+ this.lastElement = element;
374
+ this.prepareElement( element );
375
+ this.currentElements = $(element);
376
+ var result = this.check( element ) !== false;
377
+ if ( result ) {
378
+ delete this.invalid[element.name];
379
+ } else {
380
+ this.invalid[element.name] = true;
381
+ }
382
+ if ( !this.numberOfInvalids() ) {
383
+ // Hide error containers on last error
384
+ this.toHide = this.toHide.add( this.containers );
385
+ }
386
+ this.showErrors();
387
+ return result;
388
+ },
389
+
390
+ // http://docs.jquery.com/Plugins/Validation/Validator/showErrors
391
+ showErrors: function( errors ) {
392
+ if ( errors ) {
393
+ // add items to error list and map
394
+ $.extend( this.errorMap, errors );
395
+ this.errorList = [];
396
+ for ( var name in errors ) {
397
+ this.errorList.push({
398
+ message: errors[name],
399
+ element: this.findByName(name)[0]
400
+ });
401
+ }
402
+ // remove items from success list
403
+ this.successList = $.grep( this.successList, function( element ) {
404
+ return !(element.name in errors);
405
+ });
406
+ }
407
+ if ( this.settings.showErrors ) {
408
+ this.settings.showErrors.call( this, this.errorMap, this.errorList );
409
+ } else {
410
+ this.defaultShowErrors();
411
+ }
412
+ },
413
+
414
+ // http://docs.jquery.com/Plugins/Validation/Validator/resetForm
415
+ resetForm: function() {
416
+ if ( $.fn.resetForm ) {
417
+ $(this.currentForm).resetForm();
418
+ }
419
+ this.submitted = {};
420
+ this.lastElement = null;
421
+ this.prepareForm();
422
+ this.hideErrors();
423
+ this.elements().removeClass( this.settings.errorClass ).removeData( "previousValue" );
424
+ },
425
+
426
+ numberOfInvalids: function() {
427
+ return this.objectLength(this.invalid);
428
+ },
429
+
430
+ objectLength: function( obj ) {
431
+ var count = 0;
432
+ for ( var i in obj ) {
433
+ count++;
434
+ }
435
+ return count;
436
+ },
437
+
438
+ hideErrors: function() {
439
+ this.addWrapper( this.toHide ).hide();
440
+ },
441
+
442
+ valid: function() {
443
+ return this.size() === 0;
444
+ },
445
+
446
+ size: function() {
447
+ return this.errorList.length;
448
+ },
449
+
450
+ focusInvalid: function() {
451
+ if ( this.settings.focusInvalid ) {
452
+ try {
453
+ $(this.findLastActive() || this.errorList.length && this.errorList[0].element || [])
454
+ .filter(":visible")
455
+ .focus()
456
+ // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find
457
+ .trigger("focusin");
458
+ } catch(e) {
459
+ // ignore IE throwing errors when focusing hidden elements
460
+ }
461
+ }
462
+ },
463
+
464
+ findLastActive: function() {
465
+ var lastActive = this.lastActive;
466
+ return lastActive && $.grep(this.errorList, function( n ) {
467
+ return n.element.name === lastActive.name;
468
+ }).length === 1 && lastActive;
469
+ },
470
+
471
+ elements: function() {
472
+ var validator = this,
473
+ rulesCache = {};
474
+
475
+ // select all valid inputs inside the form (no submit or reset buttons)
476
+ return $(this.currentForm)
477
+ .find("input, select, textarea")
478
+ .not(":submit, :reset, :image, [disabled]")
479
+ .not( this.settings.ignore )
480
+ .filter(function() {
481
+ if ( !this.name && validator.settings.debug && window.console ) {
482
+ console.error( "%o has no name assigned", this);
483
+ }
484
+
485
+ // select only the first element for each name, and only those with rules specified
486
+ if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) {
487
+ return false;
488
+ }
489
+
490
+ rulesCache[this.name] = true;
491
+ return true;
492
+ });
493
+ },
494
+
495
+ clean: function( selector ) {
496
+ return $(selector)[0];
497
+ },
498
+
499
+ errors: function() {
500
+ var errorClass = this.settings.errorClass.replace(" ", ".");
501
+ return $(this.settings.errorElement + "." + errorClass, this.errorContext);
502
+ },
503
+
504
+ reset: function() {
505
+ this.successList = [];
506
+ this.errorList = [];
507
+ this.errorMap = {};
508
+ this.toShow = $([]);
509
+ this.toHide = $([]);
510
+ this.currentElements = $([]);
511
+ },
512
+
513
+ prepareForm: function() {
514
+ this.reset();
515
+ this.toHide = this.errors().add( this.containers );
516
+ },
517
+
518
+ prepareElement: function( element ) {
519
+ this.reset();
520
+ this.toHide = this.errorsFor(element);
521
+ },
522
+
523
+ elementValue: function( element ) {
524
+ var type = $(element).attr("type"),
525
+ val = $(element).val();
526
+
527
+ if ( type === "radio" || type === "checkbox" ) {
528
+ return $("input[name='" + $(element).attr("name") + "']:checked").val();
529
+ }
530
+
531
+ if ( typeof val === "string" ) {
532
+ return val.replace(/\r/g, "");
533
+ }
534
+ return val;
535
+ },
536
+
537
+ check: function( element ) {
538
+ element = this.validationTargetFor( this.clean( element ) );
539
+
540
+ var rules = $(element).rules();
541
+ var dependencyMismatch = false;
542
+ var val = this.elementValue(element);
543
+ var result;
544
+
545
+ for (var method in rules ) {
546
+ var rule = { method: method, parameters: rules[method] };
547
+ try {
548
+
549
+ result = $.validator.methods[method].call( this, val, element, rule.parameters );
550
+
551
+ // if a method indicates that the field is optional and therefore valid,
552
+ // don't mark it as valid when there are no other rules
553
+ if ( result === "dependency-mismatch" ) {
554
+ dependencyMismatch = true;
555
+ continue;
556
+ }
557
+ dependencyMismatch = false;
558
+
559
+ if ( result === "pending" ) {
560
+ this.toHide = this.toHide.not( this.errorsFor(element) );
561
+ return;
562
+ }
563
+
564
+ if ( !result ) {
565
+ this.formatAndAdd( element, rule );
566
+ return false;
567
+ }
568
+ } catch(e) {
569
+ if ( this.settings.debug && window.console ) {
570
+ console.log( "Exception occurred when checking element " + element.id + ", check the '" + rule.method + "' method.", e );
571
+ }
572
+ throw e;
573
+ }
574
+ }
575
+ if ( dependencyMismatch ) {
576
+ return;
577
+ }
578
+ if ( this.objectLength(rules) ) {
579
+ this.successList.push(element);
580
+ }
581
+ return true;
582
+ },
583
+
584
+ // return the custom message for the given element and validation method
585
+ // specified in the element's HTML5 data attribute
586
+ customDataMessage: function( element, method ) {
587
+ return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase()));
588
+ },
589
+
590
+ // return the custom message for the given element name and validation method
591
+ customMessage: function( name, method ) {
592
+ var m = this.settings.messages[name];
593
+ return m && (m.constructor === String ? m : m[method]);
594
+ },
595
+
596
+ // return the first defined argument, allowing empty strings
597
+ findDefined: function() {
598
+ for(var i = 0; i < arguments.length; i++) {
599
+ if ( arguments[i] !== undefined ) {
600
+ return arguments[i];
601
+ }
602
+ }
603
+ return undefined;
604
+ },
605
+
606
+ defaultMessage: function( element, method ) {
607
+ return this.findDefined(
608
+ this.customMessage( element.name, method ),
609
+ this.customDataMessage( element, method ),
610
+ // title is never undefined, so handle empty string as undefined
611
+ !this.settings.ignoreTitle && element.title || undefined,
612
+ $.validator.messages[method],
613
+ "<strong>Warning: No message defined for " + element.name + "</strong>"
614
+ );
615
+ },
616
+
617
+ formatAndAdd: function( element, rule ) {
618
+ var message = this.defaultMessage( element, rule.method ),
619
+ theregex = /\$?\{(\d+)\}/g;
620
+ if ( typeof message === "function" ) {
621
+ message = message.call(this, rule.parameters, element);
622
+ } else if (theregex.test(message)) {
623
+ message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters);
624
+ }
625
+ this.errorList.push({
626
+ message: message,
627
+ element: element
628
+ });
629
+
630
+ this.errorMap[element.name] = message;
631
+ this.submitted[element.name] = message;
632
+ },
633
+
634
+ addWrapper: function( toToggle ) {
635
+ if ( this.settings.wrapper ) {
636
+ toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) );
637
+ }
638
+ return toToggle;
639
+ },
640
+
641
+ defaultShowErrors: function() {
642
+ var i, elements;
643
+ for ( i = 0; this.errorList[i]; i++ ) {
644
+ var error = this.errorList[i];
645
+ if ( this.settings.highlight ) {
646
+ this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass );
647
+ }
648
+ this.showLabel( error.element, error.message );
649
+ }
650
+ if ( this.errorList.length ) {
651
+ this.toShow = this.toShow.add( this.containers );
652
+ }
653
+ if ( this.settings.success ) {
654
+ for ( i = 0; this.successList[i]; i++ ) {
655
+ this.showLabel( this.successList[i] );
656
+ }
657
+ }
658
+ if ( this.settings.unhighlight ) {
659
+ for ( i = 0, elements = this.validElements(); elements[i]; i++ ) {
660
+ this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass );
661
+ }
662
+ }
663
+ this.toHide = this.toHide.not( this.toShow );
664
+ this.hideErrors();
665
+ this.addWrapper( this.toShow ).show();
666
+ },
667
+
668
+ validElements: function() {
669
+ return this.currentElements.not(this.invalidElements());
670
+ },
671
+
672
+ invalidElements: function() {
673
+ return $(this.errorList).map(function() {
674
+ return this.element;
675
+ });
676
+ },
677
+
678
+ showLabel: function( element, message ) {
679
+ var label = this.errorsFor( element );
680
+ if ( label.length ) {
681
+ // refresh error/success class
682
+ label.removeClass( this.settings.validClass ).addClass( this.settings.errorClass );
683
+ // replace message on existing label
684
+ label.html(message);
685
+ } else {
686
+ // create label
687
+ label = $("<" + this.settings.errorElement + ">")
688
+ .attr("for", this.idOrName(element))
689
+ .addClass(this.settings.errorClass)
690
+ .html(message || "");
691
+ if ( this.settings.wrapper ) {
692
+ // make sure the element is visible, even in IE
693
+ // actually showing the wrapped element is handled elsewhere
694
+ label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent();
695
+ }
696
+ if ( !this.labelContainer.append(label).length ) {
697
+ if ( this.settings.errorPlacement ) {
698
+ this.settings.errorPlacement(label, $(element) );
699
+ } else {
700
+ label.insertAfter(element);
701
+ }
702
+ }
703
+ }
704
+ if ( !message && this.settings.success ) {
705
+ label.text("");
706
+ if ( typeof this.settings.success === "string" ) {
707
+ label.addClass( this.settings.success );
708
+ } else {
709
+ this.settings.success( label, element );
710
+ }
711
+ }
712
+ this.toShow = this.toShow.add(label);
713
+ },
714
+
715
+ errorsFor: function( element ) {
716
+ var name = this.idOrName(element);
717
+ return this.errors().filter(function() {
718
+ return $(this).attr("for") === name;
719
+ });
720
+ },
721
+
722
+ idOrName: function( element ) {
723
+ return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name);
724
+ },
725
+
726
+ validationTargetFor: function( element ) {
727
+ // if radio/checkbox, validate first element in group instead
728
+ if ( this.checkable(element) ) {
729
+ element = this.findByName( element.name ).not(this.settings.ignore)[0];
730
+ }
731
+ return element;
732
+ },
733
+
734
+ checkable: function( element ) {
735
+ return (/radio|checkbox/i).test(element.type);
736
+ },
737
+
738
+ findByName: function( name ) {
739
+ return $(this.currentForm).find("[name='" + name + "']");
740
+ },
741
+
742
+ getLength: function( value, element ) {
743
+ switch( element.nodeName.toLowerCase() ) {
744
+ case "select":
745
+ return $("option:selected", element).length;
746
+ case "input":
747
+ if ( this.checkable( element) ) {
748
+ return this.findByName(element.name).filter(":checked").length;
749
+ }
750
+ }
751
+ return value.length;
752
+ },
753
+
754
+ depend: function( param, element ) {
755
+ return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true;
756
+ },
757
+
758
+ dependTypes: {
759
+ "boolean": function( param, element ) {
760
+ return param;
761
+ },
762
+ "string": function( param, element ) {
763
+ return !!$(param, element.form).length;
764
+ },
765
+ "function": function( param, element ) {
766
+ return param(element);
767
+ }
768
+ },
769
+
770
+ optional: function( element ) {
771
+ var val = this.elementValue(element);
772
+ return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch";
773
+ },
774
+
775
+ startRequest: function( element ) {
776
+ if ( !this.pending[element.name] ) {
777
+ this.pendingRequest++;
778
+ this.pending[element.name] = true;
779
+ }
780
+ },
781
+
782
+ stopRequest: function( element, valid ) {
783
+ this.pendingRequest--;
784
+ // sometimes synchronization fails, make sure pendingRequest is never < 0
785
+ if ( this.pendingRequest < 0 ) {
786
+ this.pendingRequest = 0;
787
+ }
788
+ delete this.pending[element.name];
789
+ if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
790
+ $(this.currentForm).submit();
791
+ this.formSubmitted = false;
792
+ } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) {
793
+ $(this.currentForm).triggerHandler("invalid-form", [this]);
794
+ this.formSubmitted = false;
795
+ }
796
+ },
797
+
798
+ previousValue: function( element ) {
799
+ return $.data(element, "previousValue") || $.data(element, "previousValue", {
800
+ old: null,
801
+ valid: true,
802
+ message: this.defaultMessage( element, "remote" )
803
+ });
804
+ }
805
+
806
+ },
807
+
808
+ classRuleSettings: {
809
+ required: {required: true},
810
+ email: {email: true},
811
+ url: {url: true},
812
+ date: {date: true},
813
+ dateISO: {dateISO: true},
814
+ number: {number: true},
815
+ digits: {digits: true},
816
+ creditcard: {creditcard: true}
817
+ },
818
+
819
+ addClassRules: function( className, rules ) {
820
+ if ( className.constructor === String ) {
821
+ this.classRuleSettings[className] = rules;
822
+ } else {
823
+ $.extend(this.classRuleSettings, className);
824
+ }
825
+ },
826
+
827
+ classRules: function( element ) {
828
+ var rules = {};
829
+ var classes = $(element).attr("class");
830
+ if ( classes ) {
831
+ $.each(classes.split(" "), function() {
832
+ if ( this in $.validator.classRuleSettings ) {
833
+ $.extend(rules, $.validator.classRuleSettings[this]);
834
+ }
835
+ });
836
+ }
837
+ return rules;
838
+ },
839
+
840
+ attributeRules: function( element ) {
841
+ var rules = {};
842
+ var $element = $(element);
843
+ var type = $element[0].getAttribute("type");
844
+
845
+ for (var method in $.validator.methods) {
846
+ var value;
847
+
848
+ // support for <input required> in both html5 and older browsers
849
+ if ( method === "required" ) {
850
+ value = $element.get(0).getAttribute(method);
851
+ // Some browsers return an empty string for the required attribute
852
+ // and non-HTML5 browsers might have required="" markup
853
+ if ( value === "" ) {
854
+ value = true;
855
+ }
856
+ // force non-HTML5 browsers to return bool
857
+ value = !!value;
858
+ } else {
859
+ value = $element.attr(method);
860
+ }
861
+
862
+ // convert the value to a number for number inputs, and for text for backwards compability
863
+ // allows type="date" and others to be compared as strings
864
+ if ( /min|max/.test( method ) && ( type === null || /number|range|text/.test( type ) ) ) {
865
+ value = Number(value);
866
+ }
867
+
868
+ if ( value ) {
869
+ rules[method] = value;
870
+ } else if ( type === method && type !== 'range' ) {
871
+ // exception: the jquery validate 'range' method
872
+ // does not test for the html5 'range' type
873
+ rules[method] = true;
874
+ }
875
+ }
876
+
877
+ // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs
878
+ if ( rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength) ) {
879
+ delete rules.maxlength;
880
+ }
881
+
882
+ return rules;
883
+ },
884
+
885
+ dataRules: function( element ) {
886
+ var method, value,
887
+ rules = {}, $element = $(element);
888
+ for (method in $.validator.methods) {
889
+ value = $element.data("rule-" + method.toLowerCase());
890
+ if ( value !== undefined ) {
891
+ rules[method] = value;
892
+ }
893
+ }
894
+ return rules;
895
+ },
896
+
897
+ staticRules: function( element ) {
898
+ var rules = {};
899
+ var validator = $.data(element.form, "validator");
900
+ if ( validator.settings.rules ) {
901
+ rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {};
902
+ }
903
+ return rules;
904
+ },
905
+
906
+ normalizeRules: function( rules, element ) {
907
+ // handle dependency check
908
+ $.each(rules, function( prop, val ) {
909
+ // ignore rule when param is explicitly false, eg. required:false
910
+ if ( val === false ) {
911
+ delete rules[prop];
912
+ return;
913
+ }
914
+ if ( val.param || val.depends ) {
915
+ var keepRule = true;
916
+ switch (typeof val.depends) {
917
+ case "string":
918
+ keepRule = !!$(val.depends, element.form).length;
919
+ break;
920
+ case "function":
921
+ keepRule = val.depends.call(element, element);
922
+ break;
923
+ }
924
+ if ( keepRule ) {
925
+ rules[prop] = val.param !== undefined ? val.param : true;
926
+ } else {
927
+ delete rules[prop];
928
+ }
929
+ }
930
+ });
931
+
932
+ // evaluate parameters
933
+ $.each(rules, function( rule, parameter ) {
934
+ rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter;
935
+ });
936
+
937
+ // clean number parameters
938
+ $.each(['minlength', 'maxlength'], function() {
939
+ if ( rules[this] ) {
940
+ rules[this] = Number(rules[this]);
941
+ }
942
+ });
943
+ $.each(['rangelength', 'range'], function() {
944
+ var parts;
945
+ if ( rules[this] ) {
946
+ if ( $.isArray(rules[this]) ) {
947
+ rules[this] = [Number(rules[this][0]), Number(rules[this][1])];
948
+ } else if ( typeof rules[this] === "string" ) {
949
+ parts = rules[this].split(/[\s,]+/);
950
+ rules[this] = [Number(parts[0]), Number(parts[1])];
951
+ }
952
+ }
953
+ });
954
+
955
+ if ( $.validator.autoCreateRanges ) {
956
+ // auto-create ranges
957
+ if ( rules.min && rules.max ) {
958
+ rules.range = [rules.min, rules.max];
959
+ delete rules.min;
960
+ delete rules.max;
961
+ }
962
+ if ( rules.minlength && rules.maxlength ) {
963
+ rules.rangelength = [rules.minlength, rules.maxlength];
964
+ delete rules.minlength;
965
+ delete rules.maxlength;
966
+ }
967
+ }
968
+
969
+ return rules;
970
+ },
971
+
972
+ // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true}
973
+ normalizeRule: function( data ) {
974
+ if ( typeof data === "string" ) {
975
+ var transformed = {};
976
+ $.each(data.split(/\s/), function() {
977
+ transformed[this] = true;
978
+ });
979
+ data = transformed;
980
+ }
981
+ return data;
982
+ },
983
+
984
+ // http://docs.jquery.com/Plugins/Validation/Validator/addMethod
985
+ addMethod: function( name, method, message ) {
986
+ $.validator.methods[name] = method;
987
+ $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name];
988
+ if ( method.length < 3 ) {
989
+ $.validator.addClassRules(name, $.validator.normalizeRule(name));
990
+ }
991
+ },
992
+
993
+ methods: {
994
+
995
+ // http://docs.jquery.com/Plugins/Validation/Methods/required
996
+ required: function( value, element, param ) {
997
+ // check if dependency is met
998
+ if ( !this.depend(param, element) ) {
999
+ return "dependency-mismatch";
1000
+ }
1001
+ if ( element.nodeName.toLowerCase() === "select" ) {
1002
+ // could be an array for select-multiple or a string, both are fine this way
1003
+ var val = $(element).val();
1004
+ return val && val.length > 0;
1005
+ }
1006
+ if ( this.checkable(element) ) {
1007
+ return this.getLength(value, element) > 0;
1008
+ }
1009
+ return $.trim(value).length > 0;
1010
+ },
1011
+
1012
+ // http://docs.jquery.com/Plugins/Validation/Methods/email
1013
+ email: function( value, element ) {
1014
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/
1015
+ return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value);
1016
+ },
1017
+
1018
+ // http://docs.jquery.com/Plugins/Validation/Methods/url
1019
+ url: function( value, element ) {
1020
+ // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/
1021
+ return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
1022
+ },
1023
+
1024
+ // http://docs.jquery.com/Plugins/Validation/Methods/date
1025
+ date: function( value, element ) {
1026
+ return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString());
1027
+ },
1028
+
1029
+ // http://docs.jquery.com/Plugins/Validation/Methods/dateISO
1030
+ dateISO: function( value, element ) {
1031
+ return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value);
1032
+ },
1033
+
1034
+ // http://docs.jquery.com/Plugins/Validation/Methods/number
1035
+ number: function( value, element ) {
1036
+ return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value);
1037
+ },
1038
+
1039
+ // http://docs.jquery.com/Plugins/Validation/Methods/digits
1040
+ digits: function( value, element ) {
1041
+ return this.optional(element) || /^\d+$/.test(value);
1042
+ },
1043
+
1044
+ // http://docs.jquery.com/Plugins/Validation/Methods/creditcard
1045
+ // based on http://en.wikipedia.org/wiki/Luhn
1046
+ creditcard: function( value, element ) {
1047
+ if ( this.optional(element) ) {
1048
+ return "dependency-mismatch";
1049
+ }
1050
+ // accept only spaces, digits and dashes
1051
+ if ( /[^0-9 \-]+/.test(value) ) {
1052
+ return false;
1053
+ }
1054
+ var nCheck = 0,
1055
+ nDigit = 0,
1056
+ bEven = false;
1057
+
1058
+ value = value.replace(/\D/g, "");
1059
+
1060
+ for (var n = value.length - 1; n >= 0; n--) {
1061
+ var cDigit = value.charAt(n);
1062
+ nDigit = parseInt(cDigit, 10);
1063
+ if ( bEven ) {
1064
+ if ( (nDigit *= 2) > 9 ) {
1065
+ nDigit -= 9;
1066
+ }
1067
+ }
1068
+ nCheck += nDigit;
1069
+ bEven = !bEven;
1070
+ }
1071
+
1072
+ return (nCheck % 10) === 0;
1073
+ },
1074
+
1075
+ // http://docs.jquery.com/Plugins/Validation/Methods/minlength
1076
+ minlength: function( value, element, param ) {
1077
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1078
+ return this.optional(element) || length >= param;
1079
+ },
1080
+
1081
+ // http://docs.jquery.com/Plugins/Validation/Methods/maxlength
1082
+ maxlength: function( value, element, param ) {
1083
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1084
+ return this.optional(element) || length <= param;
1085
+ },
1086
+
1087
+ // http://docs.jquery.com/Plugins/Validation/Methods/rangelength
1088
+ rangelength: function( value, element, param ) {
1089
+ var length = $.isArray( value ) ? value.length : this.getLength($.trim(value), element);
1090
+ return this.optional(element) || ( length >= param[0] && length <= param[1] );
1091
+ },
1092
+
1093
+ // http://docs.jquery.com/Plugins/Validation/Methods/min
1094
+ min: function( value, element, param ) {
1095
+ return this.optional(element) || value >= param;
1096
+ },
1097
+
1098
+ // http://docs.jquery.com/Plugins/Validation/Methods/max
1099
+ max: function( value, element, param ) {
1100
+ return this.optional(element) || value <= param;
1101
+ },
1102
+
1103
+ // http://docs.jquery.com/Plugins/Validation/Methods/range
1104
+ range: function( value, element, param ) {
1105
+ return this.optional(element) || ( value >= param[0] && value <= param[1] );
1106
+ },
1107
+
1108
+ // http://docs.jquery.com/Plugins/Validation/Methods/equalTo
1109
+ equalTo: function( value, element, param ) {
1110
+ // bind to the blur event of the target in order to revalidate whenever the target field is updated
1111
+ // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
1112
+ var target = $(param);
1113
+ if ( this.settings.onfocusout ) {
1114
+ target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
1115
+ $(element).valid();
1116
+ });
1117
+ }
1118
+ return value === target.val();
1119
+ },
1120
+
1121
+ // http://docs.jquery.com/Plugins/Validation/Methods/remote
1122
+ remote: function( value, element, param ) {
1123
+ if ( this.optional(element) ) {
1124
+ return "dependency-mismatch";
1125
+ }
1126
+
1127
+ var previous = this.previousValue(element);
1128
+ if (!this.settings.messages[element.name] ) {
1129
+ this.settings.messages[element.name] = {};
1130
+ }
1131
+ previous.originalMessage = this.settings.messages[element.name].remote;
1132
+ this.settings.messages[element.name].remote = previous.message;
1133
+
1134
+ param = typeof param === "string" && {url:param} || param;
1135
+
1136
+ if ( previous.old === value ) {
1137
+ return previous.valid;
1138
+ }
1139
+
1140
+ previous.old = value;
1141
+ var validator = this;
1142
+ this.startRequest(element);
1143
+ var data = {};
1144
+ data[element.name] = value;
1145
+ $.ajax($.extend(true, {
1146
+ url: param,
1147
+ mode: "abort",
1148
+ port: "validate" + element.name,
1149
+ dataType: "json",
1150
+ data: data,
1151
+ success: function( response ) {
1152
+ validator.settings.messages[element.name].remote = previous.originalMessage;
1153
+ var valid = response === true || response === "true";
1154
+ if ( valid ) {
1155
+ var submitted = validator.formSubmitted;
1156
+ validator.prepareElement(element);
1157
+ validator.formSubmitted = submitted;
1158
+ validator.successList.push(element);
1159
+ delete validator.invalid[element.name];
1160
+ validator.showErrors();
1161
+ } else {
1162
+ var errors = {};
1163
+ var message = response || validator.defaultMessage( element, "remote" );
1164
+ errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
1165
+ validator.invalid[element.name] = true;
1166
+ validator.showErrors(errors);
1167
+ }
1168
+ previous.valid = valid;
1169
+ validator.stopRequest(element, valid);
1170
+ }
1171
+ }, param));
1172
+ return "pending";
1173
+ }
1174
+
1175
+ }
1176
+
1177
+ });
1178
+
1179
+ // deprecated, use $.validator.format instead
1180
+ $.format = $.validator.format;
1181
+
1182
+ }(jQuery));
1183
+
1184
+ // ajax mode: abort
1185
+ // usage: $.ajax({ mode: "abort"[, port: "uniqueport"]});
1186
+ // if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort()
1187
+ (function($) {
1188
+ var pendingRequests = {};
1189
+ // Use a prefilter if available (1.5+)
1190
+ if ( $.ajaxPrefilter ) {
1191
+ $.ajaxPrefilter(function( settings, _, xhr ) {
1192
+ var port = settings.port;
1193
+ if ( settings.mode === "abort" ) {
1194
+ if ( pendingRequests[port] ) {
1195
+ pendingRequests[port].abort();
1196
+ }
1197
+ pendingRequests[port] = xhr;
1198
+ }
1199
+ });
1200
+ } else {
1201
+ // Proxy ajax
1202
+ var ajax = $.ajax;
1203
+ $.ajax = function( settings ) {
1204
+ var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode,
1205
+ port = ( "port" in settings ? settings : $.ajaxSettings ).port;
1206
+ if ( mode === "abort" ) {
1207
+ if ( pendingRequests[port] ) {
1208
+ pendingRequests[port].abort();
1209
+ }
1210
+ pendingRequests[port] = ajax.apply(this, arguments);
1211
+ return pendingRequests[port];
1212
+ }
1213
+ return ajax.apply(this, arguments);
1214
+ };
1215
+ }
1216
+ }(jQuery));
1217
+
1218
+ // provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation
1219
+ // handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target
1220
+ (function($) {
1221
+ $.extend($.fn, {
1222
+ validateDelegate: function( delegate, type, handler ) {
1223
+ return this.bind(type, function( event ) {
1224
+ var target = $(event.target);
1225
+ if ( target.is(delegate) ) {
1226
+ return handler.apply(target, arguments);
1227
+ }
1228
+ });
1229
+ }
1230
+ });
1231
+ }(jQuery));