rademade_admin 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (270) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +34 -0
  4. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.eot +0 -0
  5. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.svg +228 -0
  6. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.ttf +0 -0
  7. data/app/assets/fonts/rademade_admin/glyphicons-halflings-regular.woff +0 -0
  8. data/app/assets/images/rademade_admin/backgrounds/back-blue.jpg +0 -0
  9. data/app/assets/images/rademade_admin/backgrounds/back-green.jpg +0 -0
  10. data/app/assets/images/rademade_admin/backgrounds/back-orange.png +0 -0
  11. data/app/assets/images/rademade_admin/backgrounds/blueish.jpg +0 -0
  12. data/app/assets/images/rademade_admin/backgrounds/select-bg.png +0 -0
  13. data/app/assets/images/rademade_admin/datatables/back_disabled.png +0 -0
  14. data/app/assets/images/rademade_admin/datatables/back_enabled.png +0 -0
  15. data/app/assets/images/rademade_admin/datatables/back_enabled_hover.png +0 -0
  16. data/app/assets/images/rademade_admin/datatables/forward_disabled.png +0 -0
  17. data/app/assets/images/rademade_admin/datatables/forward_enabled.png +0 -0
  18. data/app/assets/images/rademade_admin/datatables/forward_enabled_hover.png +0 -0
  19. data/app/assets/images/rademade_admin/datatables/sort_asc.png +0 -0
  20. data/app/assets/images/rademade_admin/datatables/sort_asc_disabled.png +0 -0
  21. data/app/assets/images/rademade_admin/datatables/sort_both.png +0 -0
  22. data/app/assets/images/rademade_admin/datatables/sort_desc.png +0 -0
  23. data/app/assets/images/rademade_admin/datatables/sort_desc_disabled.png +0 -0
  24. data/app/assets/images/rademade_admin/icons/btn-attach.png +0 -0
  25. data/app/assets/images/rademade_admin/icons/btn-setting.png +0 -0
  26. data/app/assets/images/rademade_admin/icons/btn-shuffle.png +0 -0
  27. data/app/assets/images/rademade_admin/icons/btn-tool.png +0 -0
  28. data/app/assets/images/rademade_admin/icons/buble.png +0 -0
  29. data/app/assets/images/rademade_admin/icons/glyphicons-halflings-white.png +0 -0
  30. data/app/assets/images/rademade_admin/icons/glyphicons-halflings.png +0 -0
  31. data/app/assets/images/rademade_admin/icons/ico-arrow-black.png +0 -0
  32. data/app/assets/images/rademade_admin/icons/ico-gallery-edit.png +0 -0
  33. data/app/assets/images/rademade_admin/icons/ico-gallery-trash.png +0 -0
  34. data/app/assets/images/rademade_admin/icons/ico-mail.png +0 -0
  35. data/app/assets/images/rademade_admin/icons/ico-phone.png +0 -0
  36. data/app/assets/images/rademade_admin/icons/ico-table-delete.png +0 -0
  37. data/app/assets/images/rademade_admin/icons/ico-table-edit.png +0 -0
  38. data/app/assets/images/rademade_admin/icons/ico-table-new.png +0 -0
  39. data/app/assets/images/rademade_admin/icons/lens.png +0 -0
  40. data/app/assets/images/rademade_admin/icons/skin-nav-bullets.png +0 -0
  41. data/app/assets/images/rademade_admin/icons/table-icons.png +0 -0
  42. data/app/assets/images/rademade_admin/icons/table-img.png +0 -0
  43. data/app/assets/images/rademade_admin/jquery-ui/animated-overlay.gif +0 -0
  44. data/app/assets/images/rademade_admin/jquery-ui/slider-handler.png +0 -0
  45. data/app/assets/images/rademade_admin/jquery-ui/slider-handler2.png +0 -0
  46. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  47. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  48. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_flat_10_000000_40x100.png +0 -0
  49. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  50. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  51. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_glass_65_ffffff_1x400.png +0 -0
  52. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  53. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  54. data/app/assets/images/rademade_admin/jquery-ui/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  55. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_222222_256x240.png +0 -0
  56. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_228ef1_256x240.png +0 -0
  57. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ef8c08_256x240.png +0 -0
  58. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffd27a_256x240.png +0 -0
  59. data/app/assets/images/rademade_admin/jquery-ui/ui-icons_ffffff_256x240.png +0 -0
  60. data/app/assets/images/rademade_admin/logos/logo-white.png +0 -0
  61. data/app/assets/images/rademade_admin/logos/logo.png +0 -0
  62. data/app/assets/images/rademade_admin/notifier-loader-clean.gif +0 -0
  63. data/app/assets/images/rademade_admin/notifier-loader-plastic.gif +0 -0
  64. data/app/assets/images/rademade_admin/placeholders/new-gallery-img.png +0 -0
  65. data/app/assets/images/rademade_admin/placeholders/no-img-gallery.png +0 -0
  66. data/app/assets/images/rademade_admin/select2/select2.png +0 -0
  67. data/app/assets/images/rademade_admin/select2/select2x2.png +0 -0
  68. data/app/assets/images/rademade_admin/select2/spinner.gif +0 -0
  69. data/app/assets/images/rademade_admin/uniform/bg-input-focus.png +0 -0
  70. data/app/assets/images/rademade_admin/uniform/bg-input.png +0 -0
  71. data/app/assets/images/rademade_admin/uniform/sprite.png +0 -0
  72. data/app/assets/javascripts/rademade_admin.coffee +14 -0
  73. data/app/assets/javascripts/rademade_admin/app/app.coffee +1 -0
  74. data/app/assets/javascripts/rademade_admin/app/common/dnd-sort.coffee +42 -0
  75. data/app/assets/javascripts/rademade_admin/app/common/pagination.coffee +6 -0
  76. data/app/assets/javascripts/rademade_admin/app/common/related-index.coffee +54 -0
  77. data/app/assets/javascripts/rademade_admin/app/common/relation-list.coffee +109 -0
  78. data/app/assets/javascripts/rademade_admin/app/common/sort-list.coffee +47 -0
  79. data/app/assets/javascripts/rademade_admin/app/common/uploader.coffee +53 -0
  80. data/app/assets/javascripts/rademade_admin/app/form-popup/collection.coffee +20 -0
  81. data/app/assets/javascripts/rademade_admin/app/form-popup/initializer.coffee +43 -0
  82. data/app/assets/javascripts/rademade_admin/app/form-popup/model.coffee +4 -0
  83. data/app/assets/javascripts/rademade_admin/app/form-popup/view.coffee +57 -0
  84. data/app/assets/javascripts/rademade_admin/app/forms/insert.coffee +7 -0
  85. data/app/assets/javascripts/rademade_admin/app/forms/login.coffee +4 -0
  86. data/app/assets/javascripts/rademade_admin/app/forms/remove.coffee +6 -0
  87. data/app/assets/javascripts/rademade_admin/app/notifier/initialize.js +31 -0
  88. data/app/assets/javascripts/rademade_admin/detail_admin/theme.js +56 -0
  89. data/app/assets/javascripts/rademade_admin/form/form-ajax-submit.coffee +153 -0
  90. data/app/assets/javascripts/rademade_admin/form/library/jquery.form-serialize.js +54 -0
  91. data/app/assets/javascripts/rademade_admin/form/library/jquery.form.js +1121 -0
  92. data/app/assets/javascripts/rademade_admin/form/library/jquery.formrestrict.js +27 -0
  93. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.js +1231 -0
  94. data/app/assets/javascripts/rademade_admin/form/library/jquery.validate.messages_ru.js +27 -0
  95. data/app/assets/javascripts/rademade_admin/library/backbone.js +1581 -0
  96. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.datepicker.js +989 -0
  97. data/app/assets/javascripts/rademade_admin/library/bootstrap/bootstrap.js +1992 -0
  98. data/app/assets/javascripts/rademade_admin/library/ckeditor/config.js +12 -0
  99. data/app/assets/javascripts/rademade_admin/library/jquery/jquery-ui-1.10.4.custom.min.js +6 -0
  100. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.dataTables.js +12099 -0
  101. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.js +2960 -0
  102. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.resize.js +60 -0
  103. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.flot.stack.js +188 -0
  104. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.knob.js +661 -0
  105. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.tablednd.js +1 -0
  106. data/app/assets/javascripts/rademade_admin/library/jquery/jquery.uniform.min.js +1 -0
  107. data/app/assets/javascripts/rademade_admin/library/notifier.custom.js +431 -0
  108. data/app/assets/javascripts/rademade_admin/library/notifier.custom.min.js +15 -0
  109. data/app/assets/javascripts/rademade_admin/library/underscore.js +1276 -0
  110. data/app/assets/javascripts/rademade_admin/library/wysihtml5-0.3.0.js +9463 -0
  111. data/app/assets/stylesheets/rademade_admin.css +14 -0
  112. data/app/assets/stylesheets/rademade_admin/base.scss.erb +23 -0
  113. data/app/assets/stylesheets/rademade_admin/bootstrap/bootstrap-overrides.css.erb +341 -0
  114. data/app/assets/stylesheets/rademade_admin/bootstrap/bootstrap.css.erb +5911 -0
  115. data/app/assets/stylesheets/rademade_admin/bootstrap/main.scss.erb +78 -0
  116. data/app/assets/stylesheets/rademade_admin/detail_admin/chart-showcase.scss.erb +33 -0
  117. data/app/assets/stylesheets/rademade_admin/detail_admin/datatables.scss.erb +3 -0
  118. data/app/assets/stylesheets/rademade_admin/detail_admin/elements.scss.erb +665 -0
  119. data/app/assets/stylesheets/rademade_admin/detail_admin/error.scss.erb +19 -0
  120. data/app/assets/stylesheets/rademade_admin/detail_admin/form-showcase.scss.erb +87 -0
  121. data/app/assets/stylesheets/rademade_admin/detail_admin/form-wizard.scss.erb +261 -0
  122. data/app/assets/stylesheets/rademade_admin/detail_admin/gallery.scss.erb +106 -0
  123. data/app/assets/stylesheets/rademade_admin/detail_admin/grids.scss.erb +21 -0
  124. data/app/assets/stylesheets/rademade_admin/detail_admin/icons.scss.erb +115 -0
  125. data/app/assets/stylesheets/rademade_admin/detail_admin/index.scss.erb +290 -0
  126. data/app/assets/stylesheets/rademade_admin/detail_admin/layout.scss.erb +523 -0
  127. data/app/assets/stylesheets/rademade_admin/detail_admin/new-user.scss.erb +49 -0
  128. data/app/assets/stylesheets/rademade_admin/detail_admin/personal-info.scss.erb +144 -0
  129. data/app/assets/stylesheets/rademade_admin/detail_admin/popup.scss.erb +3 -0
  130. data/app/assets/stylesheets/rademade_admin/detail_admin/signin.scss.erb +128 -0
  131. data/app/assets/stylesheets/rademade_admin/detail_admin/tables.scss.erb +195 -0
  132. data/app/assets/stylesheets/rademade_admin/detail_admin/ui-elements.scss.erb +177 -0
  133. data/app/assets/stylesheets/rademade_admin/detail_admin/user-list.scss.erb +112 -0
  134. data/app/assets/stylesheets/rademade_admin/detail_admin/user-profile.scss.erb +169 -0
  135. data/app/assets/stylesheets/rademade_admin/detail_admin/web-app-icons.scss.erb +25 -0
  136. data/app/assets/stylesheets/rademade_admin/edit.css +7 -0
  137. data/app/assets/stylesheets/rademade_admin/file-upload.scss.erb +12 -0
  138. data/app/assets/stylesheets/rademade_admin/lib/bootstrap.datepicker.css.erb +302 -0
  139. data/app/assets/stylesheets/rademade_admin/lib/jquery-ui-1.10.2.custom.css.erb +544 -0
  140. data/app/assets/stylesheets/rademade_admin/lib/morris.css.erb +2 -0
  141. data/app/assets/stylesheets/rademade_admin/lib/select2.css.erb +513 -0
  142. data/app/assets/stylesheets/rademade_admin/lib/uniform.default.css.erb +366 -0
  143. data/app/assets/stylesheets/rademade_admin/notifier.custom.css.erb +661 -0
  144. data/app/assets/stylesheets/rademade_admin/scaffolds.scss.erb +32 -0
  145. data/app/controllers/rademade_admin/abstract_controller.rb +24 -0
  146. data/app/controllers/rademade_admin/admin_users_controller.rb +16 -0
  147. data/app/controllers/rademade_admin/application_controller.rb +7 -0
  148. data/app/controllers/rademade_admin/dashboard_controller.rb +16 -0
  149. data/app/controllers/rademade_admin/model_controller.rb +122 -0
  150. data/app/controllers/rademade_admin/sessions_controller.rb +22 -0
  151. data/app/helpers/rademade_admin/field_helper.rb +27 -0
  152. data/app/helpers/rademade_admin/form_helper.rb +63 -0
  153. data/app/helpers/rademade_admin/menu_helper.rb +45 -0
  154. data/app/helpers/rademade_admin/name_helper.rb +17 -0
  155. data/app/helpers/rademade_admin/upload_preview_helper.rb +59 -0
  156. data/app/helpers/rademade_admin/uri_helper.rb +104 -0
  157. data/app/inputs/rademade_admin/admin_file_input.rb +70 -0
  158. data/app/inputs/rademade_admin/admin_select_input.rb +81 -0
  159. data/app/inputs/rademade_admin/admin_textarea_input.rb +5 -0
  160. data/app/inputs/rademade_admin/boolean_input.rb +13 -0
  161. data/app/models/rademade_admin/ability.rb +39 -0
  162. data/app/models/rademade_admin/user.rb +6 -0
  163. data/app/serializers/autocomplete_serializer.rb +46 -0
  164. data/app/services/form_builder.rb +3 -0
  165. data/app/services/loader_service.rb +7 -0
  166. data/app/services/login.rb +18 -0
  167. data/app/services/login/error.rb +17 -0
  168. data/app/services/model_controller/instance_options.rb +38 -0
  169. data/app/services/model_controller/linker.rb +49 -0
  170. data/app/services/model_controller/model_options.rb +39 -0
  171. data/app/services/model_controller/notifier.rb +40 -0
  172. data/app/services/model_controller/templates.rb +27 -0
  173. data/app/services/saver.rb +69 -0
  174. data/app/services/search/conditions/abstract.rb +53 -0
  175. data/app/services/search/conditions/autocomplete.rb +44 -0
  176. data/app/services/search/conditions/list.rb +35 -0
  177. data/app/services/search/query_adapter/abstract.rb +54 -0
  178. data/app/services/search/query_adapter/active_record.rb +33 -0
  179. data/app/services/search/query_adapter/mongoid.rb +33 -0
  180. data/app/services/search/searcher.rb +19 -0
  181. data/app/services/sortable_service.rb +37 -0
  182. data/app/services/video_service.rb +22 -0
  183. data/app/views/layouts/rademade_admin.html.erb +13 -0
  184. data/app/views/rademade_admin/_blocks/_form_control.html.erb +5 -0
  185. data/app/views/rademade_admin/_blocks/_header.html.erb +30 -0
  186. data/app/views/rademade_admin/_blocks/_menu.html.erb +41 -0
  187. data/app/views/rademade_admin/_blocks/_pagination.html.erb +18 -0
  188. data/app/views/rademade_admin/_blocks/_sub_menu.html.erb +19 -0
  189. data/app/views/rademade_admin/_blocks/sub_menu/_link.html.erb +5 -0
  190. data/app/views/rademade_admin/_layouts/inner.html.erb +37 -0
  191. data/app/views/rademade_admin/_layouts/inner/form.html.erb +15 -0
  192. data/app/views/rademade_admin/_layouts/inner/index_table.html.erb +59 -0
  193. data/app/views/rademade_admin/_layouts/inner/related_index_table.html.erb +55 -0
  194. data/app/views/rademade_admin/abstract/_form.html.erb +10 -0
  195. data/app/views/rademade_admin/abstract/edit.html.erb +9 -0
  196. data/app/views/rademade_admin/abstract/form.html.erb +1 -0
  197. data/app/views/rademade_admin/abstract/index.html.erb +77 -0
  198. data/app/views/rademade_admin/abstract/new.html.erb +9 -0
  199. data/app/views/rademade_admin/abstract/related_index.html.erb +78 -0
  200. data/app/views/rademade_admin/dashboard/index.html.erb +9 -0
  201. data/app/views/rademade_admin/dashboard/login.html.erb +31 -0
  202. data/config/initializers/devise.rb +250 -0
  203. data/config/initializers/routes.rb +3 -0
  204. data/config/locales/devise.en.yml +59 -0
  205. data/config/routes.rb +17 -0
  206. data/lib/rademade_admin.rb +26 -0
  207. data/lib/rademade_admin/configuration.rb +17 -0
  208. data/lib/rademade_admin/engine.rb +22 -0
  209. data/lib/rademade_admin/file_info_formatter.rb +12 -0
  210. data/lib/rademade_admin/hrml_buffer.rb +14 -0
  211. data/lib/rademade_admin/model/configuration.rb +52 -0
  212. data/lib/rademade_admin/model/configuration/fields.rb +33 -0
  213. data/lib/rademade_admin/model/data_adapter.rb +59 -0
  214. data/lib/rademade_admin/model/data_adapter/active_record.rb +53 -0
  215. data/lib/rademade_admin/model/data_adapter/mongoid.rb +49 -0
  216. data/lib/rademade_admin/model/graph.rb +36 -0
  217. data/lib/rademade_admin/model/info.rb +106 -0
  218. data/lib/rademade_admin/model/reflection.rb +31 -0
  219. data/lib/rademade_admin/model/reflection/data.rb +47 -0
  220. data/lib/rademade_admin/model/reflection/uploader.rb +18 -0
  221. data/lib/rademade_admin/routing.rb +3 -0
  222. data/lib/rademade_admin/routing/mapper.rb +42 -0
  223. data/lib/rademade_admin/routing/resource.rb +6 -0
  224. data/lib/rademade_admin/sortable.rb +12 -0
  225. data/lib/rademade_admin/uploader/photo.rb +13 -0
  226. data/lib/rademade_admin/uploader/video.rb +11 -0
  227. data/lib/rademade_admin/user.rb +16 -0
  228. data/lib/rademade_admin/version.rb +3 -0
  229. data/lib/tasks/rademade_admin_tasks.rake +4 -0
  230. data/test/dummy/README.rdoc +28 -0
  231. data/test/dummy/Rakefile +6 -0
  232. data/test/dummy/app/assets/javascripts/application.js +13 -0
  233. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  234. data/test/dummy/app/controllers/application_controller.rb +5 -0
  235. data/test/dummy/app/controllers/rademade_admin/posts_controller.rb +9 -0
  236. data/test/dummy/app/controllers/rademade_admin/users_controller.rb +14 -0
  237. data/test/dummy/app/helpers/application_helper.rb +2 -0
  238. data/test/dummy/app/models/post.rb +9 -0
  239. data/test/dummy/app/models/user.rb +7 -0
  240. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  241. data/test/dummy/bin/bundle +3 -0
  242. data/test/dummy/bin/rails +4 -0
  243. data/test/dummy/bin/rake +4 -0
  244. data/test/dummy/config.ru +4 -0
  245. data/test/dummy/config/application.rb +29 -0
  246. data/test/dummy/config/boot.rb +5 -0
  247. data/test/dummy/config/environment.rb +5 -0
  248. data/test/dummy/config/environments/development.rb +29 -0
  249. data/test/dummy/config/environments/production.rb +80 -0
  250. data/test/dummy/config/environments/test.rb +36 -0
  251. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  252. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  253. data/test/dummy/config/initializers/inflections.rb +16 -0
  254. data/test/dummy/config/initializers/mime_types.rb +5 -0
  255. data/test/dummy/config/initializers/rademade_admin.rb +3 -0
  256. data/test/dummy/config/initializers/secret_token.rb +12 -0
  257. data/test/dummy/config/initializers/session_store.rb +3 -0
  258. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  259. data/test/dummy/config/locales/en.yml +23 -0
  260. data/test/dummy/config/mongoid.yml +6 -0
  261. data/test/dummy/config/routes.rb +8 -0
  262. data/test/dummy/db/development.sqlite3 +0 -0
  263. data/test/dummy/public/404.html +58 -0
  264. data/test/dummy/public/422.html +58 -0
  265. data/test/dummy/public/500.html +57 -0
  266. data/test/dummy/public/favicon.ico +0 -0
  267. data/test/integration/navigation_test.rb +10 -0
  268. data/test/rademade_admin_test.rb +7 -0
  269. data/test/test_helper.rb +15 -0
  270. metadata +691 -0
@@ -0,0 +1,7 @@
1
+ $(document).on 'ready page:load', ->
2
+
3
+ $('.insert-item-form').on
4
+ 'ajax-submit-done': (event , data)->
5
+ $(this)
6
+ .attr('action', data.form_action)
7
+ .append('<input name="_method" type="hidden" value="patch">')
@@ -0,0 +1,4 @@
1
+ $(document).on 'ready page:load', ->
2
+
3
+ $('#login-form').on
4
+ 'ajax-submit-done': -> window.location.reload()
@@ -0,0 +1,6 @@
1
+ $(document).on 'ready page:load', ->
2
+
3
+ $('.delete-item-form').on
4
+ 'ajax-before-submit': (event, submitStart) -> submitStart() if confirm 'Do you really want delete this record?',
5
+ 'ajax-submit-done': -> $(this).closest('tr').fadeOut 300
6
+
@@ -0,0 +1,31 @@
1
+ $(document).on('ready page:load', function(){
2
+ window.notifier = new Backbone.Notifier({ // defaults
3
+ el: 'body', // container for notification (default: 'body')
4
+ baseCls: 'notifier',// css classes prefix, should match css file. Change to solve conflicts.
5
+ theme: 'clean',// default theme for notifications (available: 'plastic'/'clean').
6
+ types: ['warning', 'error', 'info', 'success'],// available notification styles
7
+ type: null, // default notification type (null/'warning'/'error'/'info'/'success')
8
+ dialog: false, // whether display the notification with a title bar and a dialog style.
9
+ // - sets 'hideOnClick' to false, unless defined otherwise
10
+ // - sets 'position' to 'center', unless defined otherwise
11
+ // - sets 'ms' to null, unless defined otherwise
12
+ modal: false, // whether to dark and block the UI behind the notification (default: false)
13
+ message: '', // default message content
14
+ title: undefined,// default notification title, if defined, causes the notification to be
15
+ // 'dialog' (unless dialog is 'false')
16
+ closeBtn: false, // whether to display an enabled close button on notification
17
+ ms: 5000, // milliseconds before hiding (null || false => no timeout) (default: 10000)
18
+ 'class': null, // additional css class
19
+ hideOnClick: true,// whether to hide the notifications on mouse click (default: true)
20
+ loader: false, // whether to display loader animation in notifications (default: false)
21
+ destroy: false,// notification or selector of notifications to hide on show (default: false)
22
+ opacity: 1, // notification's opacity (default: 1)
23
+ offsetY: 0, // distance between the notifications and the top/bottom edge (default: 0)
24
+ fadeInMs: 500, // duration (milliseconds) of notification's fade-in effect (default: 500)
25
+ fadeOutMs: 500, // duration (milliseconds) of notification's fade-out effect (default: 500)
26
+ position: 'top',// default notifications position ('top' / 'center' / 'bottom')
27
+ zIndex: 10000, // minimal z-index for notifications
28
+ screenOpacity: 0.5,// opacity of dark screen background that goes behind for modals (0 to 1)
29
+ width: undefined// notification's width ('auto' if not set)
30
+ });
31
+ });
@@ -0,0 +1,56 @@
1
+ $(function(){
2
+
3
+ function setupTheme() {
4
+
5
+ var $menu = $("#sidebar-nav");
6
+
7
+ // sidebar menu dropdown toggle
8
+ $("#dashboard-menu .dropdown-toggle").click(function (e) {
9
+ e.preventDefault();
10
+ var $item = $(this).parent();
11
+ $item.toggleClass("active");
12
+ if ($item.hasClass("active")) {
13
+ $item.find(".submenu").slideDown("fast");
14
+ } else {
15
+ $item.find(".submenu").slideUp("fast");
16
+ }
17
+ });
18
+
19
+
20
+ // mobile side-menu slide toggler
21
+ $("body").click(function () {
22
+ if ($(this).hasClass("menu")) {
23
+ $(this).removeClass("menu");
24
+ }
25
+ });
26
+
27
+ $menu.click(function (e) {
28
+ e.stopPropagation();
29
+ });
30
+
31
+ $("#menu-toggler").click(function (e) {
32
+ e.stopPropagation();
33
+ $("body").toggleClass("menu");
34
+ });
35
+
36
+ $(window).resize(function () {
37
+ $(this).width() > 769 && $("body.menu").removeClass("menu")
38
+ });
39
+
40
+
41
+ // build all tooltips from data-attributes
42
+ $("[data-toggle='tooltip']").each(function (index, el) {
43
+ $(el).tooltip({
44
+ placement: $(this).data("placement") || 'top'
45
+ });
46
+ });
47
+
48
+
49
+ // quirk to fix dark skin sidebar menu because of B3 border-box
50
+ if ($menu.height() > $(".content").height()) {
51
+ $("html").addClass("small");
52
+ }
53
+ }
54
+
55
+ $(document).on('ready page:load', setupTheme);
56
+ });
@@ -0,0 +1,153 @@
1
+ window.FormAjaxSubmit = ($form) ->
2
+ @_$form = $form
3
+ @_validationObject = null
4
+ @_sending = false
5
+
6
+ (->
7
+
8
+ #@trigger ['ajax-before-submit', 'ajax-submit-done', 'ajax-submit-fail', 'ajax-submit-always']
9
+
10
+ FormAjaxSubmit::init = ->
11
+
12
+ validation_data = @__getValidationData()
13
+ @__loadValidationRules validation_data
14
+ @_validationObject = @_$form.validate(validation_data)
15
+
16
+ FormAjaxSubmit::displayFieldErrors = (errors) ->
17
+ messages = {}
18
+
19
+ $.each errors, (field, message) =>
20
+ messages['data[' + field + ']'] = message
21
+
22
+ unless $.isEmptyObject(messages)
23
+ try
24
+ @_validationObject.showErrors messages
25
+ catch e
26
+ @displayGlobalErrors messages
27
+ return true
28
+ false
29
+
30
+ FormAjaxSubmit::displayGlobalErrors = (errors) ->
31
+ $.each errors, (i, error) ->
32
+ #todo show global errors
33
+
34
+
35
+ FormAjaxSubmit::.__loadValidationRules = (validation_data) ->
36
+ #TODO load custom validation
37
+
38
+
39
+ FormAjaxSubmit::__getValidationData = ->
40
+ _self = this
41
+
42
+ highlight: (element) ->
43
+ $(element).parent().removeClass('success').addClass 'error'
44
+
45
+ unhighlight: (element) ->
46
+ $(element).parent().removeClass('error').addClass 'success'
47
+
48
+ submitHandler: ->
49
+ return if _self._sending
50
+ lazySubmitHandler = -> _self._submitHandler()
51
+ if _self.handlerExist('ajax-before-submit')
52
+ _self.trigger('ajax-before-submit', [ lazySubmitHandler ])
53
+ else
54
+ lazySubmitHandler.call()
55
+ return false
56
+
57
+
58
+ FormAjaxSubmit::__processFormError = (data) ->
59
+ showFieldErrors = @displayFieldErrors(data.errors)
60
+ console.log showFieldErrors unless showFieldErrors
61
+
62
+ FormAjaxSubmit::__removeFormErrors = ->
63
+ @_$form.find('.error-message').remove()
64
+
65
+ FormAjaxSubmit::_submitHandler = ->
66
+ for instance of CKEDITOR.instances
67
+ CKEDITOR.instances[instance].updateElement()
68
+
69
+ @_sending = true
70
+ _self = this
71
+ items = @_$form.serializeObject()
72
+
73
+ # Workaround for select2 values serialization
74
+ # It finds all 'array' members of data hash,
75
+ # and splits their values by ',', cleaning all
76
+ # non-space characters.
77
+ for memb of items.data
78
+ array = items.data[memb]
79
+ if $.isArray(array)
80
+ newArray = []
81
+
82
+ for val in array
83
+ cleanVal = val.replace(/\s+/g,'')
84
+ if cleanVal.length > 0
85
+ newArray = $.merge(newArray, cleanVal.split(','))
86
+
87
+ items.data[memb] = if newArray.length is 0 then [''] else newArray
88
+
89
+ $.ajax(
90
+ url: @_$form.attr('action')
91
+ type: @_$form.attr('method')
92
+ data: items
93
+ dataType: 'json'
94
+ ).done((data) ->
95
+ _self.trigger('ajax-submit-done', [data])
96
+ $(document).trigger('ajax-submit-done', [data]) #rm_todo remove global events
97
+ _self.__removeFormErrors()
98
+ ).fail((response) ->
99
+ try
100
+ data = JSON.parse( response.responseText )
101
+ _self.trigger('ajax-submit-fail', [data])
102
+ _self.__processFormError( data )
103
+ #rm_todo error catching.
104
+ #rm_todo extract fail process method
105
+ ).always((response) ->
106
+ data = if (response.responseJSON) then response.responseJSON else response
107
+ window.notifier.notify(message: data.message) if data.message
108
+ _self.trigger('ajax-submit-always', [data])
109
+ _self._sending = false
110
+ )
111
+
112
+ FormAjaxSubmit::trigger = ->
113
+ @_$form.triggerHandler.apply(@_$form, arguments)
114
+
115
+ FormAjaxSubmit::handlerExist = (name)->
116
+ jQuery._data( @_$form[0] ).events[ name ]
117
+
118
+ @
119
+ )()
120
+
121
+ formatingErrors = ->
122
+ $.validator.setDefaults showErrors: (errorMap, errorList) ->
123
+
124
+ $.each errorList, (index, error) ->
125
+
126
+ $(error.element).parent().children('.error-message').remove()
127
+
128
+ if $.isArray(error.message)
129
+ message = error.message.join('<br>')
130
+ else
131
+ message = error.message
132
+
133
+ notify = $([
134
+ '<span class="error-message">'
135
+ message
136
+ '<i class="ico error-buble"></i>'
137
+ '</span>'
138
+ ].join(''))
139
+
140
+ $(error.element).after notify
141
+ return
142
+
143
+ return
144
+
145
+ setupFormSubmit = ->
146
+
147
+ formatingErrors.call()
148
+
149
+ $('form').each (i, form) ->
150
+ (new FormAjaxSubmit($(form))).init()
151
+
152
+ $ ->
153
+ $(document).on 'ready page:load', setupFormSubmit
@@ -0,0 +1,54 @@
1
+ (function ($) {
2
+
3
+ return $.fn.serializeObject = function () {
4
+
5
+ var json, patterns, push_counters, _this = this;
6
+ json = {};
7
+ push_counters = {};
8
+ patterns = {
9
+ validate: /^[_a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
10
+ key: /[a-zA-Z0-9_]+|(?=\[\])/g,
11
+ push: /^$/,
12
+ fixed: /^\d+$/,
13
+ named: /^[a-zA-Z0-9_]+$/
14
+ };
15
+
16
+ this.build = function (base, key, value) {
17
+ base[key] = value;
18
+ return base;
19
+ };
20
+
21
+ this.push_counter = function (key) {
22
+ if (push_counters[key] === void 0) {
23
+ push_counters[key] = 0;
24
+ }
25
+ return push_counters[key]++;
26
+ };
27
+
28
+ $.each($(this).serializeArray(), function (i, elem) {
29
+ var k, keys, merge, re, reverse_key;
30
+ if (!patterns.validate.test(elem.name)) {
31
+ return;
32
+ }
33
+ keys = elem.name.match(patterns.key);
34
+ merge = elem.value;
35
+ reverse_key = elem.name;
36
+ while ((k = keys.pop()) !== void 0) {
37
+ if (patterns.push.test(k)) {
38
+ re = new RegExp("\\[" + k + "\\]$");
39
+ reverse_key = reverse_key.replace(re, '');
40
+ merge = _this.build([], _this.push_counter(reverse_key), merge);
41
+ } else if (patterns.fixed.test(k)) {
42
+ merge = _this.build([], k, merge);
43
+ } else if (patterns.named.test(k)) {
44
+ merge = _this.build({}, k, merge);
45
+ }
46
+ }
47
+ return json = $.extend(true, json, merge);
48
+ });
49
+
50
+ return json;
51
+
52
+ };
53
+
54
+ })(jQuery);
@@ -0,0 +1,1121 @@
1
+ /*!
2
+ * jQuery Form Plugin
3
+ * version: 3.20 (20-NOV-2012)
4
+ * @requires jQuery v1.5 or later
5
+ *
6
+ * Examples and documentation at: http://malsup.com/jquery/form/
7
+ * Project repository: https://github.com/malsup/form
8
+ * Dual licensed under the MIT and GPL licenses:
9
+ * http://malsup.github.com/mit-license.txt
10
+ * http://malsup.github.com/gpl-license-v2.txt
11
+ */
12
+ /*global ActiveXObject alert */
13
+ ;(function($) {
14
+ "use strict";
15
+
16
+ /*
17
+ Usage Note:
18
+ -----------
19
+ Do not use both ajaxSubmit and ajaxForm on the same form. These
20
+ functions are mutually exclusive. Use ajaxSubmit if you want
21
+ to bind your own submit handler to the form. For example,
22
+
23
+ $(document).ready(function() {
24
+ $('#myForm').on('submit', function(e) {
25
+ e.preventDefault(); // <-- important
26
+ $(this).ajaxSubmit({
27
+ target: '#output'
28
+ });
29
+ });
30
+ });
31
+
32
+ Use ajaxForm when you want the plugin to manage all the event binding
33
+ for you. For example,
34
+
35
+ $(document).ready(function() {
36
+ $('#myForm').ajaxForm({
37
+ target: '#output'
38
+ });
39
+ });
40
+
41
+ You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
42
+ form does not have to exist when you invoke ajaxForm:
43
+
44
+ $('#myForm').ajaxForm({
45
+ delegation: true,
46
+ target: '#output'
47
+ });
48
+
49
+ When using ajaxForm, the ajaxSubmit function will be invoked for you
50
+ at the appropriate time.
51
+ */
52
+
53
+ /**
54
+ * Feature detection
55
+ */
56
+ var feature = {};
57
+ feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
58
+ feature.formdata = window.FormData !== undefined;
59
+
60
+ /**
61
+ * ajaxSubmit() provides a mechanism for immediately submitting
62
+ * an HTML form using AJAX.
63
+ */
64
+ $.fn.ajaxSubmit = function(options) {
65
+ /*jshint scripturl:true */
66
+
67
+ // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
68
+ if (!this.length) {
69
+ log('ajaxSubmit: skipping submit process - no element selected');
70
+ return this;
71
+ }
72
+
73
+ var method, action, url, $form = this;
74
+
75
+ if (typeof options == 'function') {
76
+ options = { success: options };
77
+ }
78
+
79
+ method = this.attr('method');
80
+ action = this.attr('action');
81
+ url = (typeof action === 'string') ? $.trim(action) : '';
82
+ url = url || window.location.href || '';
83
+ if (url) {
84
+ // clean url (don't include hash vaue)
85
+ url = (url.match(/^([^#]+)/)||[])[1];
86
+ }
87
+
88
+ options = $.extend(true, {
89
+ url: url,
90
+ success: $.ajaxSettings.success,
91
+ type: method || 'GET',
92
+ iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
93
+ }, options);
94
+
95
+ // hook for manipulating the form data before it is extracted;
96
+ // convenient for use with rich editors like tinyMCE or FCKEditor
97
+ var veto = {};
98
+ this.trigger('form-pre-serialize', [this, options, veto]);
99
+ if (veto.veto) {
100
+ log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
101
+ return this;
102
+ }
103
+
104
+ // provide opportunity to alter form data before it is serialized
105
+ if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
106
+ log('ajaxSubmit: submit aborted via beforeSerialize callback');
107
+ return this;
108
+ }
109
+
110
+ var traditional = options.traditional;
111
+ if ( traditional === undefined ) {
112
+ traditional = $.ajaxSettings.traditional;
113
+ }
114
+
115
+ var elements = [];
116
+ var qx, a = this.formToArray(options.semantic, elements);
117
+ if (options.data) {
118
+ options.extraData = options.data;
119
+ qx = $.param(options.data, traditional);
120
+ }
121
+
122
+ // give pre-submit callback an opportunity to abort the submit
123
+ if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
124
+ log('ajaxSubmit: submit aborted via beforeSubmit callback');
125
+ return this;
126
+ }
127
+
128
+ // fire vetoable 'validate' event
129
+ this.trigger('form-submit-validate', [a, this, options, veto]);
130
+ if (veto.veto) {
131
+ log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
132
+ return this;
133
+ }
134
+
135
+ var q = $.param(a, traditional);
136
+ if (qx) {
137
+ q = ( q ? (q + '&' + qx) : qx );
138
+ }
139
+ if (options.type.toUpperCase() == 'GET') {
140
+ options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
141
+ options.data = null; // data is null for 'get'
142
+ }
143
+ else {
144
+ options.data = q; // data is the query string for 'post'
145
+ }
146
+
147
+ var callbacks = [];
148
+ if (options.resetForm) {
149
+ callbacks.push(function() { $form.resetForm(); });
150
+ }
151
+ if (options.clearForm) {
152
+ callbacks.push(function() { $form.clearForm(options.includeHidden); });
153
+ }
154
+
155
+ // perform a load on the target only if dataType is not provided
156
+ if (!options.dataType && options.target) {
157
+ var oldSuccess = options.success || function(){};
158
+ callbacks.push(function(data) {
159
+ var fn = options.replaceTarget ? 'replaceWith' : 'html';
160
+ $(options.target)[fn](data).each(oldSuccess, arguments);
161
+ });
162
+ }
163
+ else if (options.success) {
164
+ callbacks.push(options.success);
165
+ }
166
+
167
+ options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
168
+ var context = options.context || this ; // jQuery 1.4+ supports scope context
169
+ for (var i=0, max=callbacks.length; i < max; i++) {
170
+ callbacks[i].apply(context, [data, status, xhr || $form, $form]);
171
+ }
172
+ };
173
+
174
+ // are there files to upload?
175
+
176
+ // [value] (issue #113), also see comment:
177
+ // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
178
+ var fileInputs = $('input[type=file]:enabled[value!=""]', this);
179
+
180
+ var hasFileInputs = fileInputs.length > 0;
181
+ var mp = 'multipart/form-data';
182
+ var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
183
+
184
+ var fileAPI = feature.fileapi && feature.formdata;
185
+ log("fileAPI :" + fileAPI);
186
+ var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
187
+
188
+ var jqxhr;
189
+
190
+ // options.iframe allows user to force iframe mode
191
+ // 06-NOV-09: now defaulting to iframe mode if file input is detected
192
+ if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
193
+ // hack to fix Safari hang (thanks to Tim Molendijk for this)
194
+ // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
195
+ if (options.closeKeepAlive) {
196
+ $.get(options.closeKeepAlive, function() {
197
+ jqxhr = fileUploadIframe(a);
198
+ });
199
+ }
200
+ else {
201
+ jqxhr = fileUploadIframe(a);
202
+ }
203
+ }
204
+ else if ((hasFileInputs || multipart) && fileAPI) {
205
+ jqxhr = fileUploadXhr(a);
206
+ }
207
+ else {
208
+ jqxhr = $.ajax(options);
209
+ }
210
+
211
+ $form.removeData('jqxhr').data('jqxhr', jqxhr);
212
+
213
+ // clear element array
214
+ for (var k=0; k < elements.length; k++)
215
+ elements[k] = null;
216
+
217
+ // fire 'notify' event
218
+ this.trigger('form-submit-notify', [this, options]);
219
+ return this;
220
+
221
+ // utility fn for deep serialization
222
+ function deepSerialize(extraData){
223
+ var serialized = $.param(extraData).split('&');
224
+ var len = serialized.length;
225
+ var result = {};
226
+ var i, part;
227
+ for (i=0; i < len; i++) {
228
+ part = serialized[i].split('=');
229
+ result[decodeURIComponent(part[0])] = decodeURIComponent(part[1]);
230
+ }
231
+ return result;
232
+ }
233
+
234
+ // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
235
+ function fileUploadXhr(a) {
236
+ var formdata = new FormData();
237
+
238
+ for (var i=0; i < a.length; i++) {
239
+ formdata.append(a[i].name, a[i].value);
240
+ }
241
+
242
+ if (options.extraData) {
243
+ var serializedData = deepSerialize(options.extraData);
244
+ for (var p in serializedData)
245
+ if (serializedData.hasOwnProperty(p))
246
+ formdata.append(p, serializedData[p]);
247
+ }
248
+
249
+ options.data = null;
250
+
251
+ var s = $.extend(true, {}, $.ajaxSettings, options, {
252
+ contentType: false,
253
+ processData: false,
254
+ cache: false,
255
+ type: method || 'POST'
256
+ });
257
+
258
+ if (options.uploadProgress) {
259
+ // workaround because jqXHR does not expose upload property
260
+ s.xhr = function() {
261
+ var xhr = jQuery.ajaxSettings.xhr();
262
+ if (xhr.upload) {
263
+ xhr.upload.onprogress = function(event) {
264
+ var percent = 0;
265
+ var position = event.loaded || event.position; /*event.position is deprecated*/
266
+ var total = event.total;
267
+ if (event.lengthComputable) {
268
+ percent = Math.ceil(position / total * 100);
269
+ }
270
+ options.uploadProgress(event, position, total, percent);
271
+ };
272
+ }
273
+ return xhr;
274
+ };
275
+ }
276
+
277
+ s.data = null;
278
+ var beforeSend = s.beforeSend;
279
+ s.beforeSend = function(xhr, o) {
280
+ o.data = formdata;
281
+ if(beforeSend)
282
+ beforeSend.call(this, xhr, o);
283
+ };
284
+ return $.ajax(s);
285
+ }
286
+
287
+ // private function for handling file uploads (hat tip to YAHOO!)
288
+ function fileUploadIframe(a) {
289
+ var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
290
+ var useProp = !!$.fn.prop;
291
+ var deferred = $.Deferred();
292
+
293
+ if ($('[name=submit],[id=submit]', form).length) {
294
+ // if there is an input with a name or id of 'submit' then we won't be
295
+ // able to invoke the submit fn on the form (at least not x-browser)
296
+ alert('Error: Form elements must not have name or id of "submit".');
297
+ deferred.reject();
298
+ return deferred;
299
+ }
300
+
301
+ if (a) {
302
+ // ensure that every serialized input is still enabled
303
+ for (i=0; i < elements.length; i++) {
304
+ el = $(elements[i]);
305
+ if ( useProp )
306
+ el.prop('disabled', false);
307
+ else
308
+ el.removeAttr('disabled');
309
+ }
310
+ }
311
+
312
+ s = $.extend(true, {}, $.ajaxSettings, options);
313
+ s.context = s.context || s;
314
+ id = 'jqFormIO' + (new Date().getTime());
315
+ if (s.iframeTarget) {
316
+ $io = $(s.iframeTarget);
317
+ n = $io.attr('name');
318
+ if (!n)
319
+ $io.attr('name', id);
320
+ else
321
+ id = n;
322
+ }
323
+ else {
324
+ $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
325
+ $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
326
+ }
327
+ io = $io[0];
328
+
329
+
330
+ xhr = { // mock object
331
+ aborted: 0,
332
+ responseText: null,
333
+ responseXML: null,
334
+ status: 0,
335
+ statusText: 'n/a',
336
+ getAllResponseHeaders: function() {},
337
+ getResponseHeader: function() {},
338
+ setRequestHeader: function() {},
339
+ abort: function(status) {
340
+ var e = (status === 'timeout' ? 'timeout' : 'aborted');
341
+ log('aborting upload... ' + e);
342
+ this.aborted = 1;
343
+ // #214
344
+ if (io.contentWindow.document.execCommand) {
345
+ try { // #214
346
+ io.contentWindow.document.execCommand('Stop');
347
+ } catch(ignore) {}
348
+ }
349
+ $io.attr('src', s.iframeSrc); // abort op in progress
350
+ xhr.error = e;
351
+ if (s.error)
352
+ s.error.call(s.context, xhr, e, status);
353
+ if (g)
354
+ $.event.trigger("ajaxError", [xhr, s, e]);
355
+ if (s.complete)
356
+ s.complete.call(s.context, xhr, e);
357
+ }
358
+ };
359
+
360
+ g = s.global;
361
+ // trigger ajax global events so that activity/block indicators work like normal
362
+ if (g && 0 === $.active++) {
363
+ $.event.trigger("ajaxStart");
364
+ }
365
+ if (g) {
366
+ $.event.trigger("ajaxSend", [xhr, s]);
367
+ }
368
+
369
+ if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
370
+ if (s.global) {
371
+ $.active--;
372
+ }
373
+ deferred.reject();
374
+ return deferred;
375
+ }
376
+ if (xhr.aborted) {
377
+ deferred.reject();
378
+ return deferred;
379
+ }
380
+
381
+ // add submitting element to data if we know it
382
+ sub = form.clk;
383
+ if (sub) {
384
+ n = sub.name;
385
+ if (n && !sub.disabled) {
386
+ s.extraData = s.extraData || {};
387
+ s.extraData[n] = sub.value;
388
+ if (sub.type == "image") {
389
+ s.extraData[n+'.x'] = form.clk_x;
390
+ s.extraData[n+'.y'] = form.clk_y;
391
+ }
392
+ }
393
+ }
394
+
395
+ var CLIENT_TIMEOUT_ABORT = 1;
396
+ var SERVER_ABORT = 2;
397
+
398
+ function getDoc(frame) {
399
+ var doc = frame.contentWindow ? frame.contentWindow.document : frame.contentDocument ? frame.contentDocument : frame.document;
400
+ return doc;
401
+ }
402
+
403
+ // Rails CSRF hack (thanks to Yvan Barthelemy)
404
+ var csrf_token = $('meta[name=csrf-token]').attr('content');
405
+ var csrf_param = $('meta[name=csrf-param]').attr('content');
406
+ if (csrf_param && csrf_token) {
407
+ s.extraData = s.extraData || {};
408
+ s.extraData[csrf_param] = csrf_token;
409
+ }
410
+
411
+ // take a breath so that pending repaints get some cpu time before the upload starts
412
+ function doSubmit() {
413
+ // make sure form attrs are set
414
+ var t = $form.attr('target'), a = $form.attr('action');
415
+
416
+ // update form attrs in IE friendly way
417
+ form.setAttribute('target',id);
418
+ if (!method) {
419
+ form.setAttribute('method', 'POST');
420
+ }
421
+ if (a != s.url) {
422
+ form.setAttribute('action', s.url);
423
+ }
424
+
425
+ // ie borks in some cases when setting encoding
426
+ if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
427
+ $form.attr({
428
+ encoding: 'multipart/form-data',
429
+ enctype: 'multipart/form-data'
430
+ });
431
+ }
432
+
433
+ // support timout
434
+ if (s.timeout) {
435
+ timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
436
+ }
437
+
438
+ // look for server aborts
439
+ function checkState() {
440
+ try {
441
+ var state = getDoc(io).readyState;
442
+ log('state = ' + state);
443
+ if (state && state.toLowerCase() == 'uninitialized')
444
+ setTimeout(checkState,50);
445
+ }
446
+ catch(e) {
447
+ log('Server abort: ' , e, ' (', e.name, ')');
448
+ cb(SERVER_ABORT);
449
+ if (timeoutHandle)
450
+ clearTimeout(timeoutHandle);
451
+ timeoutHandle = undefined;
452
+ }
453
+ }
454
+
455
+ // add "extra" data to form if provided in options
456
+ var extraInputs = [];
457
+ try {
458
+ if (s.extraData) {
459
+ for (var n in s.extraData) {
460
+ if (s.extraData.hasOwnProperty(n)) {
461
+ // if using the $.param format that allows for multiple values with the same name
462
+ if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
463
+ extraInputs.push(
464
+ $('<input type="hidden" name="'+s.extraData[n].name+'">').attr('value',s.extraData[n].value)
465
+ .appendTo(form)[0]);
466
+ } else {
467
+ extraInputs.push(
468
+ $('<input type="hidden" name="'+n+'">').attr('value',s.extraData[n])
469
+ .appendTo(form)[0]);
470
+ }
471
+ }
472
+ }
473
+ }
474
+
475
+ if (!s.iframeTarget) {
476
+ // add iframe to doc and submit the form
477
+ $io.appendTo('body');
478
+ if (io.attachEvent)
479
+ io.attachEvent('onload', cb);
480
+ else
481
+ io.addEventListener('load', cb, false);
482
+ }
483
+ setTimeout(checkState,15);
484
+ form.submit();
485
+ }
486
+ finally {
487
+ // reset attrs and remove "extra" input elements
488
+ form.setAttribute('action',a);
489
+ if(t) {
490
+ form.setAttribute('target', t);
491
+ } else {
492
+ $form.removeAttr('target');
493
+ }
494
+ $(extraInputs).remove();
495
+ }
496
+ }
497
+
498
+ if (s.forceSync) {
499
+ doSubmit();
500
+ }
501
+ else {
502
+ setTimeout(doSubmit, 10); // this lets dom updates render
503
+ }
504
+
505
+ var data, doc, domCheckCount = 50, callbackProcessed;
506
+
507
+ function cb(e) {
508
+ if (xhr.aborted || callbackProcessed) {
509
+ return;
510
+ }
511
+ try {
512
+ doc = getDoc(io);
513
+ }
514
+ catch(ex) {
515
+ log('cannot access response document: ', ex);
516
+ e = SERVER_ABORT;
517
+ }
518
+ if (e === CLIENT_TIMEOUT_ABORT && xhr) {
519
+ xhr.abort('timeout');
520
+ deferred.reject(xhr, 'timeout');
521
+ return;
522
+ }
523
+ else if (e == SERVER_ABORT && xhr) {
524
+ xhr.abort('server abort');
525
+ deferred.reject(xhr, 'error', 'server abort');
526
+ return;
527
+ }
528
+
529
+ if (!doc || doc.location.href == s.iframeSrc) {
530
+ // response not received yet
531
+ if (!timedOut)
532
+ return;
533
+ }
534
+ if (io.detachEvent)
535
+ io.detachEvent('onload', cb);
536
+ else
537
+ io.removeEventListener('load', cb, false);
538
+
539
+ var status = 'success', errMsg;
540
+ try {
541
+ if (timedOut) {
542
+ throw 'timeout';
543
+ }
544
+
545
+ var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
546
+ log('isXml='+isXml);
547
+ if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
548
+ if (--domCheckCount) {
549
+ // in some browsers (Opera) the iframe DOM is not always traversable when
550
+ // the onload callback fires, so we loop a bit to accommodate
551
+ log('requeing onLoad callback, DOM not available');
552
+ setTimeout(cb, 250);
553
+ return;
554
+ }
555
+ // let this fall through because server response could be an empty document
556
+ //log('Could not access iframe DOM after mutiple tries.');
557
+ //throw 'DOMException: not available';
558
+ }
559
+
560
+ //log('response detected');
561
+ var docRoot = doc.body ? doc.body : doc.documentElement;
562
+ xhr.responseText = docRoot ? docRoot.innerHTML : null;
563
+ xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
564
+ if (isXml)
565
+ s.dataType = 'xml';
566
+ xhr.getResponseHeader = function(header){
567
+ var headers = {'content-type': s.dataType};
568
+ return headers[header];
569
+ };
570
+ // support for XHR 'status' & 'statusText' emulation :
571
+ if (docRoot) {
572
+ xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
573
+ xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
574
+ }
575
+
576
+ var dt = (s.dataType || '').toLowerCase();
577
+ var scr = /(json|script|text)/.test(dt);
578
+ if (scr || s.textarea) {
579
+ // see if user embedded response in textarea
580
+ var ta = doc.getElementsByTagName('textarea')[0];
581
+ if (ta) {
582
+ xhr.responseText = ta.value;
583
+ // support for XHR 'status' & 'statusText' emulation :
584
+ xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
585
+ xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
586
+ }
587
+ else if (scr) {
588
+ // account for browsers injecting pre around json response
589
+ var pre = doc.getElementsByTagName('pre')[0];
590
+ var b = doc.getElementsByTagName('body')[0];
591
+ if (pre) {
592
+ xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
593
+ }
594
+ else if (b) {
595
+ xhr.responseText = b.textContent ? b.textContent : b.innerText;
596
+ }
597
+ }
598
+ }
599
+ else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
600
+ xhr.responseXML = toXml(xhr.responseText);
601
+ }
602
+
603
+ try {
604
+ data = httpData(xhr, dt, s);
605
+ }
606
+ catch (e) {
607
+ status = 'parsererror';
608
+ xhr.error = errMsg = (e || status);
609
+ }
610
+ }
611
+ catch (e) {
612
+ log('error caught: ',e);
613
+ status = 'error';
614
+ xhr.error = errMsg = (e || status);
615
+ }
616
+
617
+ if (xhr.aborted) {
618
+ log('upload aborted');
619
+ status = null;
620
+ }
621
+
622
+ if (xhr.status) { // we've set xhr.status
623
+ status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
624
+ }
625
+
626
+ // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
627
+ if (status === 'success') {
628
+ if (s.success)
629
+ s.success.call(s.context, data, 'success', xhr);
630
+ deferred.resolve(xhr.responseText, 'success', xhr);
631
+ if (g)
632
+ $.event.trigger("ajaxSuccess", [xhr, s]);
633
+ }
634
+ else if (status) {
635
+ if (errMsg === undefined)
636
+ errMsg = xhr.statusText;
637
+ if (s.error)
638
+ s.error.call(s.context, xhr, status, errMsg);
639
+ deferred.reject(xhr, 'error', errMsg);
640
+ if (g)
641
+ $.event.trigger("ajaxError", [xhr, s, errMsg]);
642
+ }
643
+
644
+ if (g)
645
+ $.event.trigger("ajaxComplete", [xhr, s]);
646
+
647
+ if (g && ! --$.active) {
648
+ $.event.trigger("ajaxStop");
649
+ }
650
+
651
+ if (s.complete)
652
+ s.complete.call(s.context, xhr, status);
653
+
654
+ callbackProcessed = true;
655
+ if (s.timeout)
656
+ clearTimeout(timeoutHandle);
657
+
658
+ // clean up
659
+ setTimeout(function() {
660
+ if (!s.iframeTarget)
661
+ $io.remove();
662
+ xhr.responseXML = null;
663
+ }, 100);
664
+ }
665
+
666
+ var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
667
+ if (window.ActiveXObject) {
668
+ doc = new ActiveXObject('Microsoft.XMLDOM');
669
+ doc.async = 'false';
670
+ doc.loadXML(s);
671
+ }
672
+ else {
673
+ doc = (new DOMParser()).parseFromString(s, 'text/xml');
674
+ }
675
+ return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
676
+ };
677
+ var parseJSON = $.parseJSON || function(s) {
678
+ /*jslint evil:true */
679
+ return window['eval']('(' + s + ')');
680
+ };
681
+
682
+ var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
683
+
684
+ var ct = xhr.getResponseHeader('content-type') || '',
685
+ xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
686
+ data = xml ? xhr.responseXML : xhr.responseText;
687
+
688
+ if (xml && data.documentElement.nodeName === 'parsererror') {
689
+ if ($.error)
690
+ $.error('parsererror');
691
+ }
692
+ if (s && s.dataFilter) {
693
+ data = s.dataFilter(data, type);
694
+ }
695
+ if (typeof data === 'string') {
696
+ if (type === 'json' || !type && ct.indexOf('json') >= 0) {
697
+ data = parseJSON(data);
698
+ } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
699
+ $.globalEval(data);
700
+ }
701
+ }
702
+ return data;
703
+ };
704
+
705
+ return deferred;
706
+ }
707
+ };
708
+
709
+ /**
710
+ * ajaxForm() provides a mechanism for fully automating form submission.
711
+ *
712
+ * The advantages of using this method instead of ajaxSubmit() are:
713
+ *
714
+ * 1: This method will include coordinates for <input type="image" /> elements (if the element
715
+ * is used to submit the form).
716
+ * 2. This method will include the submit element's name/value data (for the element that was
717
+ * used to submit the form).
718
+ * 3. This method binds the submit() method to the form for you.
719
+ *
720
+ * The options argument for ajaxForm works exactly as it does for ajaxSubmit. ajaxForm merely
721
+ * passes the options argument along after properly binding events for submit elements and
722
+ * the form itself.
723
+ */
724
+ $.fn.ajaxForm = function(options) {
725
+ options = options || {};
726
+ options.delegation = options.delegation && $.isFunction($.fn.on);
727
+
728
+ // in jQuery 1.3+ we can fix mistakes with the ready state
729
+ if (!options.delegation && this.length === 0) {
730
+ var o = { s: this.selector, c: this.context };
731
+ if (!$.isReady && o.s) {
732
+ log('DOM not ready, queuing ajaxForm');
733
+ $(function() {
734
+ $(o.s,o.c).ajaxForm(options);
735
+ });
736
+ return this;
737
+ }
738
+ // is your DOM ready? http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
739
+ log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
740
+ return this;
741
+ }
742
+
743
+ if ( options.delegation ) {
744
+ $(document)
745
+ .off('submit.form-plugin', this.selector, doAjaxSubmit)
746
+ .off('click.form-plugin', this.selector, captureSubmittingElement)
747
+ .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
748
+ .on('click.form-plugin', this.selector, options, captureSubmittingElement);
749
+ return this;
750
+ }
751
+
752
+ return this.ajaxFormUnbind()
753
+ .bind('submit.form-plugin', options, doAjaxSubmit)
754
+ .bind('click.form-plugin', options, captureSubmittingElement);
755
+ };
756
+
757
+ // private event handlers
758
+ function doAjaxSubmit(e) {
759
+ /*jshint validthis:true */
760
+ var options = e.data;
761
+ if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
762
+ e.preventDefault();
763
+ $(this).ajaxSubmit(options);
764
+ }
765
+ }
766
+
767
+ function captureSubmittingElement(e) {
768
+ /*jshint validthis:true */
769
+ var target = e.target;
770
+ var $el = $(target);
771
+ if (!($el.is("[type=submit],[type=image]"))) {
772
+ // is this a child element of the submit el? (ex: a span within a button)
773
+ var t = $el.closest('[type=submit]');
774
+ if (t.length === 0) {
775
+ return;
776
+ }
777
+ target = t[0];
778
+ }
779
+ var form = this;
780
+ form.clk = target;
781
+ if (target.type == 'image') {
782
+ if (e.offsetX !== undefined) {
783
+ form.clk_x = e.offsetX;
784
+ form.clk_y = e.offsetY;
785
+ } else if (typeof $.fn.offset == 'function') {
786
+ var offset = $el.offset();
787
+ form.clk_x = e.pageX - offset.left;
788
+ form.clk_y = e.pageY - offset.top;
789
+ } else {
790
+ form.clk_x = e.pageX - target.offsetLeft;
791
+ form.clk_y = e.pageY - target.offsetTop;
792
+ }
793
+ }
794
+ // clear form vars
795
+ setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
796
+ }
797
+
798
+
799
+ // ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
800
+ $.fn.ajaxFormUnbind = function() {
801
+ return this.unbind('submit.form-plugin click.form-plugin');
802
+ };
803
+
804
+ /**
805
+ * formToArray() gathers form element data into an array of objects that can
806
+ * be passed to any of the following ajax functions: $.get, $.post, or load.
807
+ * Each object in the array has both a 'name' and 'value' property. An example of
808
+ * an array for a simple login form might be:
809
+ *
810
+ * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
811
+ *
812
+ * It is this array that is passed to pre-submit callback functions provided to the
813
+ * ajaxSubmit() and ajaxForm() methods.
814
+ */
815
+ $.fn.formToArray = function(semantic, elements) {
816
+ var a = [];
817
+ if (this.length === 0) {
818
+ return a;
819
+ }
820
+
821
+ var form = this[0];
822
+ var els = semantic ? form.getElementsByTagName('*') : form.elements;
823
+ if (!els) {
824
+ return a;
825
+ }
826
+
827
+ var i,j,n,v,el,max,jmax;
828
+ for(i=0, max=els.length; i < max; i++) {
829
+ el = els[i];
830
+ n = el.name;
831
+ if (!n) {
832
+ continue;
833
+ }
834
+
835
+ if (semantic && form.clk && el.type == "image") {
836
+ // handle image inputs on the fly when semantic == true
837
+ if(!el.disabled && form.clk == el) {
838
+ a.push({name: n, value: $(el).val(), type: el.type });
839
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
840
+ }
841
+ continue;
842
+ }
843
+
844
+ v = $.fieldValue(el, true);
845
+ if (v && v.constructor == Array) {
846
+ if (elements)
847
+ elements.push(el);
848
+ for(j=0, jmax=v.length; j < jmax; j++) {
849
+ a.push({name: n, value: v[j]});
850
+ }
851
+ }
852
+ else if (feature.fileapi && el.type == 'file' && !el.disabled) {
853
+ if (elements)
854
+ elements.push(el);
855
+ var files = el.files;
856
+ if (files.length) {
857
+ for (j=0; j < files.length; j++) {
858
+ a.push({name: n, value: files[j], type: el.type});
859
+ }
860
+ }
861
+ else {
862
+ // #180
863
+ a.push({ name: n, value: '', type: el.type });
864
+ }
865
+ }
866
+ else if (v !== null && typeof v != 'undefined') {
867
+ if (elements)
868
+ elements.push(el);
869
+ a.push({name: n, value: v, type: el.type, required: el.required});
870
+ }
871
+ }
872
+
873
+ if (!semantic && form.clk) {
874
+ // input type=='image' are not found in elements array! handle it here
875
+ var $input = $(form.clk), input = $input[0];
876
+ n = input.name;
877
+ if (n && !input.disabled && input.type == 'image') {
878
+ a.push({name: n, value: $input.val()});
879
+ a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
880
+ }
881
+ }
882
+ return a;
883
+ };
884
+
885
+ /**
886
+ * Serializes form data into a 'submittable' string. This method will return a string
887
+ * in the format: name1=value1&amp;name2=value2
888
+ */
889
+ $.fn.formSerialize = function(semantic) {
890
+ //hand off to jQuery.param for proper encoding
891
+ return $.param(this.formToArray(semantic));
892
+ };
893
+
894
+ /**
895
+ * Serializes all field elements in the jQuery object into a query string.
896
+ * This method will return a string in the format: name1=value1&amp;name2=value2
897
+ */
898
+ $.fn.fieldSerialize = function(successful) {
899
+ var a = [];
900
+ this.each(function() {
901
+ var n = this.name;
902
+ if (!n) {
903
+ return;
904
+ }
905
+ var v = $.fieldValue(this, successful);
906
+ if (v && v.constructor == Array) {
907
+ for (var i=0,max=v.length; i < max; i++) {
908
+ a.push({name: n, value: v[i]});
909
+ }
910
+ }
911
+ else if (v !== null && typeof v != 'undefined') {
912
+ a.push({name: this.name, value: v});
913
+ }
914
+ });
915
+ //hand off to jQuery.param for proper encoding
916
+ return $.param(a);
917
+ };
918
+
919
+ /**
920
+ * Returns the value(s) of the element in the matched set. For example, consider the following form:
921
+ *
922
+ * <form><fieldset>
923
+ * <input name="A" type="text" />
924
+ * <input name="A" type="text" />
925
+ * <input name="B" type="checkbox" value="B1" />
926
+ * <input name="B" type="checkbox" value="B2"/>
927
+ * <input name="C" type="radio" value="C1" />
928
+ * <input name="C" type="radio" value="C2" />
929
+ * </fieldset></form>
930
+ *
931
+ * var v = $('input[type=text]').fieldValue();
932
+ * // if no values are entered into the text inputs
933
+ * v == ['','']
934
+ * // if values entered into the text inputs are 'foo' and 'bar'
935
+ * v == ['foo','bar']
936
+ *
937
+ * var v = $('input[type=checkbox]').fieldValue();
938
+ * // if neither checkbox is checked
939
+ * v === undefined
940
+ * // if both checkboxes are checked
941
+ * v == ['B1', 'B2']
942
+ *
943
+ * var v = $('input[type=radio]').fieldValue();
944
+ * // if neither radio is checked
945
+ * v === undefined
946
+ * // if first radio is checked
947
+ * v == ['C1']
948
+ *
949
+ * The successful argument controls whether or not the field element must be 'successful'
950
+ * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
951
+ * The default value of the successful argument is true. If this value is false the value(s)
952
+ * for each element is returned.
953
+ *
954
+ * Note: This method *always* returns an array. If no valid value can be determined the
955
+ * array will be empty, otherwise it will contain one or more values.
956
+ */
957
+ $.fn.fieldValue = function(successful) {
958
+ for (var val=[], i=0, max=this.length; i < max; i++) {
959
+ var el = this[i];
960
+ var v = $.fieldValue(el, successful);
961
+ if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
962
+ continue;
963
+ }
964
+ if (v.constructor == Array)
965
+ $.merge(val, v);
966
+ else
967
+ val.push(v);
968
+ }
969
+ return val;
970
+ };
971
+
972
+ /**
973
+ * Returns the value of the field element.
974
+ */
975
+ $.fieldValue = function(el, successful) {
976
+ var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
977
+ if (successful === undefined) {
978
+ successful = true;
979
+ }
980
+
981
+ if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
982
+ (t == 'checkbox' || t == 'radio') && !el.checked ||
983
+ (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
984
+ tag == 'select' && el.selectedIndex == -1)) {
985
+ return null;
986
+ }
987
+
988
+ if (tag == 'select') {
989
+ var index = el.selectedIndex;
990
+ if (index < 0) {
991
+ return null;
992
+ }
993
+ var a = [], ops = el.options;
994
+ var one = (t == 'select-one');
995
+ var max = (one ? index+1 : ops.length);
996
+ for(var i=(one ? index : 0); i < max; i++) {
997
+ var op = ops[i];
998
+ if (op.selected) {
999
+ var v = op.value;
1000
+ if (!v) { // extra pain for IE...
1001
+ v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
1002
+ }
1003
+ if (one) {
1004
+ return v;
1005
+ }
1006
+ a.push(v);
1007
+ }
1008
+ }
1009
+ return a;
1010
+ }
1011
+ return $(el).val();
1012
+ };
1013
+
1014
+ /**
1015
+ * Clears the form data. Takes the following actions on the form's input fields:
1016
+ * - input text fields will have their 'value' property set to the empty string
1017
+ * - select elements will have their 'selectedIndex' property set to -1
1018
+ * - checkbox and radio inputs will have their 'checked' property set to false
1019
+ * - inputs of type submit, button, reset, and hidden will *not* be effected
1020
+ * - button elements will *not* be effected
1021
+ */
1022
+ $.fn.clearForm = function(includeHidden) {
1023
+ return this.each(function() {
1024
+ $('input,select,textarea', this).clearFields(includeHidden);
1025
+ });
1026
+ };
1027
+
1028
+ /**
1029
+ * Clears the selected form elements.
1030
+ */
1031
+ $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
1032
+ var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
1033
+ return this.each(function() {
1034
+ var t = this.type, tag = this.tagName.toLowerCase();
1035
+ if (re.test(t) || tag == 'textarea') {
1036
+ this.value = '';
1037
+ }
1038
+ else if (t == 'checkbox' || t == 'radio') {
1039
+ this.checked = false;
1040
+ }
1041
+ else if (tag == 'select') {
1042
+ this.selectedIndex = -1;
1043
+ }
1044
+ else if (includeHidden) {
1045
+ // includeHidden can be the value true, or it can be a selector string
1046
+ // indicating a special test; for example:
1047
+ // $('#myForm').clearForm('.special:hidden')
1048
+ // the above would clean hidden inputs that have the class of 'special'
1049
+ if ( (includeHidden === true && /hidden/.test(t)) ||
1050
+ (typeof includeHidden == 'string' && $(this).is(includeHidden)) )
1051
+ this.value = '';
1052
+ }
1053
+ });
1054
+ };
1055
+
1056
+ /**
1057
+ * Resets the form data. Causes all form elements to be reset to their original value.
1058
+ */
1059
+ $.fn.resetForm = function() {
1060
+ return this.each(function() {
1061
+ // guard against an input with the name of 'reset'
1062
+ // note that IE reports the reset function as an 'object'
1063
+ if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
1064
+ this.reset();
1065
+ }
1066
+ });
1067
+ };
1068
+
1069
+ /**
1070
+ * Enables or disables any matching elements.
1071
+ */
1072
+ $.fn.enable = function(b) {
1073
+ if (b === undefined) {
1074
+ b = true;
1075
+ }
1076
+ return this.each(function() {
1077
+ this.disabled = !b;
1078
+ });
1079
+ };
1080
+
1081
+ /**
1082
+ * Checks/unchecks any matching checkboxes or radio buttons and
1083
+ * selects/deselects and matching option elements.
1084
+ */
1085
+ $.fn.selected = function(select) {
1086
+ if (select === undefined) {
1087
+ select = true;
1088
+ }
1089
+ return this.each(function() {
1090
+ var t = this.type;
1091
+ if (t == 'checkbox' || t == 'radio') {
1092
+ this.checked = select;
1093
+ }
1094
+ else if (this.tagName.toLowerCase() == 'option') {
1095
+ var $sel = $(this).parent();
1096
+ if (select && $sel[0] && $sel[0].type == 'select-one') {
1097
+ // deselect all other options
1098
+ $sel.find('option').selected(false);
1099
+ }
1100
+ this.selected = select;
1101
+ }
1102
+ });
1103
+ };
1104
+
1105
+ // expose debug var
1106
+ $.fn.ajaxSubmit.debug = false;
1107
+
1108
+ // helper fn for console logging
1109
+ function log() {
1110
+ if (!$.fn.ajaxSubmit.debug)
1111
+ return;
1112
+ var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
1113
+ if (window.console && window.console.log) {
1114
+ window.console.log(msg);
1115
+ }
1116
+ else if (window.opera && window.opera.postError) {
1117
+ window.opera.postError(msg);
1118
+ }
1119
+ }
1120
+
1121
+ })(jQuery);