rails_marketplace 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (334) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +20 -20
  3. data/README.rdoc +2 -2
  4. data/Rakefile +37 -37
  5. data/app/assets/javascripts/rails_marketplace/application.js +46 -46
  6. data/app/assets/javascripts/rails_marketplace/catalog.coffee +3 -3
  7. data/app/assets/javascripts/rails_marketplace/flash.js +6 -6
  8. data/app/assets/javascripts/rails_marketplace/footermanifest.js +1 -1
  9. data/app/assets/javascripts/rails_marketplace/js/autocomplete/countries.js +266 -266
  10. data/app/assets/javascripts/rails_marketplace/js/autocomplete/jquery.autocomplete.js +986 -986
  11. data/app/assets/javascripts/rails_marketplace/js/bootstrap.min.js +6 -6
  12. data/app/assets/javascripts/rails_marketplace/js/calendar/fullcalendar.min.js +8 -8
  13. data/app/assets/javascripts/rails_marketplace/js/chartjs/chart.min.js +13 -13
  14. data/app/assets/javascripts/rails_marketplace/js/colorpicker/bootstrap-colorpicker.min.js +1087 -1087
  15. data/app/assets/javascripts/rails_marketplace/js/colorpicker/docs.js +17 -17
  16. data/app/assets/javascripts/rails_marketplace/js/cropping/cropper.min.js +9 -9
  17. data/app/assets/javascripts/rails_marketplace/js/cropping/main.js +321 -321
  18. data/app/assets/javascripts/rails_marketplace/js/cropping/main2.js +160 -160
  19. data/app/assets/javascripts/rails_marketplace/js/custom.js +379 -379
  20. data/app/assets/javascripts/rails_marketplace/js/datatables/buttons.bootstrap.min.css +1 -1
  21. data/app/assets/javascripts/rails_marketplace/js/datatables/buttons.bootstrap.min.js +6 -6
  22. data/app/assets/javascripts/rails_marketplace/js/datatables/buttons.html5.min.js +22 -22
  23. data/app/assets/javascripts/rails_marketplace/js/datatables/buttons.print.min.js +4 -4
  24. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.bootstrap.js +8 -8
  25. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.buttons.min.js +36 -36
  26. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.fixedHeader.min.js +17 -17
  27. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.keyTable.min.js +18 -18
  28. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.responsive.min.js +25 -25
  29. data/app/assets/javascripts/rails_marketplace/js/datatables/dataTables.scroller.min.js +26 -26
  30. data/app/assets/javascripts/rails_marketplace/js/datatables/fixedHeader.bootstrap.min.css +1 -1
  31. data/app/assets/javascripts/rails_marketplace/js/datatables/jquery.dataTables.min.css +333 -333
  32. data/app/assets/javascripts/rails_marketplace/js/datatables/jquery.dataTables.min.js +166 -166
  33. data/app/assets/javascripts/rails_marketplace/js/datatables/json/scroller-demo.json +2501 -2501
  34. data/app/assets/javascripts/rails_marketplace/js/datatables/jszip.min.js +14 -14
  35. data/app/assets/javascripts/rails_marketplace/js/datatables/pdfmake.min.js +21 -21
  36. data/app/assets/javascripts/rails_marketplace/js/datatables/responsive.bootstrap.min.css +1 -1
  37. data/app/assets/javascripts/rails_marketplace/js/datatables/responsive.bootstrap.min.js +7 -7
  38. data/app/assets/javascripts/rails_marketplace/js/datatables/scroller.bootstrap.min.css +1 -1
  39. data/app/assets/javascripts/rails_marketplace/js/dropzone/dropzone.js +1 -1
  40. data/app/assets/javascripts/rails_marketplace/js/easypie/jquery.easypiechart.min.js +9 -9
  41. data/app/assets/javascripts/rails_marketplace/js/echart/echarts-all.js +35 -35
  42. data/app/assets/javascripts/rails_marketplace/js/echart/green.js +212 -212
  43. data/app/assets/javascripts/rails_marketplace/js/editor/bootstrap-wysiwyg.js +200 -200
  44. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-apollo.js +2 -2
  45. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-basic.js +3 -3
  46. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-clj.js +18 -18
  47. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-css.js +2 -2
  48. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-dart.js +3 -3
  49. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-erlang.js +2 -2
  50. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-go.js +1 -1
  51. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-hs.js +2 -2
  52. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-lisp.js +3 -3
  53. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-llvm.js +1 -1
  54. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-lua.js +2 -2
  55. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-matlab.js +6 -6
  56. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-ml.js +2 -2
  57. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-mumps.js +2 -2
  58. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-n.js +4 -4
  59. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-pascal.js +3 -3
  60. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-proto.js +1 -1
  61. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-r.js +2 -2
  62. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-rd.js +1 -1
  63. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-scala.js +2 -2
  64. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-sql.js +2 -2
  65. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-tcl.js +3 -3
  66. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-tex.js +1 -1
  67. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-vb.js +2 -2
  68. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-vhdl.js +3 -3
  69. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-wiki.js +2 -2
  70. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-xq.js +3 -3
  71. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/lang-yaml.js +2 -2
  72. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/prettify.js +30 -30
  73. data/app/assets/javascripts/rails_marketplace/js/editor/external/google-code-prettify/run_prettify.js +34 -34
  74. data/app/assets/javascripts/rails_marketplace/js/editor/external/jquery.hotkeys.js +99 -99
  75. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.js +1 -1
  76. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.orderBars.js +200 -200
  77. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.pie.js +820 -820
  78. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.resize.js +57 -57
  79. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.stack.js +188 -188
  80. data/app/assets/javascripts/rails_marketplace/js/flot/jquery.flot.tooltip.min.js +11 -11
  81. data/app/assets/javascripts/rails_marketplace/js/gauge/gauge.min.js +1 -1
  82. data/app/assets/javascripts/rails_marketplace/js/gauge/gauge_demo.js +21 -21
  83. data/app/assets/javascripts/rails_marketplace/js/icheck/icheck.min.js +11 -11
  84. data/app/assets/javascripts/rails_marketplace/js/input_mask/jquery.inputmask.js +1 -1
  85. data/app/assets/javascripts/rails_marketplace/js/jquery.min.js +5 -5
  86. data/app/assets/javascripts/rails_marketplace/js/maps/gdp-data.js +184 -184
  87. data/app/assets/javascripts/rails_marketplace/js/maps/jquery-jvectormap-2.0.3.min.js +2 -2
  88. data/app/assets/javascripts/rails_marketplace/js/moment/moment.min.js +6 -6
  89. data/app/assets/javascripts/rails_marketplace/js/moris/example.js +127 -127
  90. data/app/assets/javascripts/rails_marketplace/js/moris/morris.min.js +7 -7
  91. data/app/assets/javascripts/rails_marketplace/js/moris/raphael-min.js +11 -11
  92. data/app/assets/javascripts/rails_marketplace/js/notify/pnotify.buttons.js +132 -132
  93. data/app/assets/javascripts/rails_marketplace/js/notify/pnotify.nonblock.js +151 -151
  94. data/app/assets/javascripts/rails_marketplace/js/nprogress.js +476 -476
  95. data/app/assets/javascripts/rails_marketplace/js/pace/pace.min.js +1 -1
  96. data/app/assets/javascripts/rails_marketplace/js/parsley/parsley.min.js +8 -8
  97. data/app/assets/javascripts/rails_marketplace/js/progressbar/bootstrap-progressbar.min.js +1 -1
  98. data/app/assets/javascripts/rails_marketplace/js/select/select2.full.js +1 -1
  99. data/app/assets/javascripts/rails_marketplace/js/sidebar/classie.js +80 -80
  100. data/app/assets/javascripts/rails_marketplace/js/sidebar/component.css +569 -569
  101. data/app/assets/javascripts/rails_marketplace/js/sidebar/modernizr.custom.js +3 -3
  102. data/app/assets/javascripts/rails_marketplace/js/sidebar/sidebarEffects.js +62 -62
  103. data/app/assets/javascripts/rails_marketplace/js/skycons/skycons.min.js +1 -1
  104. data/app/assets/javascripts/rails_marketplace/js/sparkline/jquery.sparkline.min.js +4 -4
  105. data/app/assets/javascripts/rails_marketplace/js/textarea/autosize.min.js +5 -5
  106. data/app/assets/javascripts/rails_marketplace/less/custom.css +6355 -6355
  107. data/app/assets/javascripts/rails_marketplace/marketplace.js +17 -17
  108. data/app/assets/javascripts/rails_marketplace/welcome.coffee +3 -3
  109. data/app/assets/stylesheets/rails_marketplace/application.scss +30 -30
  110. data/app/assets/stylesheets/rails_marketplace/catalog.scss +131 -131
  111. data/app/assets/stylesheets/rails_marketplace/css/animate.min.css +11 -11
  112. data/app/assets/stylesheets/rails_marketplace/css/bootstrap.min.css +5 -5
  113. data/app/assets/stylesheets/rails_marketplace/css/calendar/fullcalendar.css +1116 -1116
  114. data/app/assets/stylesheets/rails_marketplace/css/calendar/fullcalendar.min.css +4 -4
  115. data/app/assets/stylesheets/rails_marketplace/css/calendar/fullcalendar.print.css +208 -208
  116. data/app/assets/stylesheets/rails_marketplace/css/colorpicker/bootstrap-colorpicker.min.css +8 -8
  117. data/app/assets/stylesheets/rails_marketplace/css/custom.css +5347 -5347
  118. data/app/assets/stylesheets/rails_marketplace/css/datatables/css/demo_page.css +103 -103
  119. data/app/assets/stylesheets/rails_marketplace/css/datatables/css/demo_table.css +258 -258
  120. data/app/assets/stylesheets/rails_marketplace/css/datatables/css/demo_table_jui.css +500 -500
  121. data/app/assets/stylesheets/rails_marketplace/css/datatables/css/jquery.dataTables.css +221 -221
  122. data/app/assets/stylesheets/rails_marketplace/css/datatables/css/jquery.dataTables_themeroller.css +244 -244
  123. data/app/assets/stylesheets/rails_marketplace/css/datatables/tools/css/dataTables.tableTools.css +336 -336
  124. data/app/assets/stylesheets/rails_marketplace/css/editor/index.css +42 -42
  125. data/app/assets/stylesheets/rails_marketplace/css/floatexamples.css +21 -21
  126. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/_all.css +529 -529
  127. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/aero.css +52 -52
  128. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/blue.css +52 -52
  129. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/flat.css +52 -52
  130. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/green.css +52 -52
  131. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/grey.css +52 -52
  132. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/orange.css +52 -52
  133. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/pink.css +52 -52
  134. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/purple.css +52 -52
  135. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/red.css +52 -52
  136. data/app/assets/stylesheets/rails_marketplace/css/icheck/flat/yellow.css +52 -52
  137. data/app/assets/stylesheets/rails_marketplace/css/ion.rangeSlider.css +146 -146
  138. data/app/assets/stylesheets/rails_marketplace/css/ion.rangeSlider.skinFlat.css +106 -106
  139. data/app/assets/stylesheets/rails_marketplace/css/maps/jquery-jvectormap-2.0.3.css +135 -135
  140. data/app/assets/stylesheets/rails_marketplace/css/normalize.css +421 -421
  141. data/app/assets/stylesheets/rails_marketplace/css/nprogress.css +74 -74
  142. data/app/assets/stylesheets/rails_marketplace/css/progressbar/bootstrap-progressbar-3.3.0.css +161 -161
  143. data/app/assets/stylesheets/rails_marketplace/css/select/select2.min.css +403 -403
  144. data/app/assets/stylesheets/rails_marketplace/fonts/css/font-awesome.css +2086 -2086
  145. data/app/assets/stylesheets/rails_marketplace/fonts/css/font-awesome.min.css +4 -4
  146. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/FontAwesome.otf +0 -0
  147. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/fontawesome-webfont.eot +0 -0
  148. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/fontawesome-webfont.svg +654 -654
  149. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/fontawesome-webfont.ttf +0 -0
  150. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/fontawesome-webfont.woff +0 -0
  151. data/app/assets/stylesheets/rails_marketplace/fonts/fonts/fontawesome-webfont.woff2 +0 -0
  152. data/app/assets/stylesheets/rails_marketplace/fonts/glyphicons-halflings-regular.eot +0 -0
  153. data/app/assets/stylesheets/rails_marketplace/fonts/glyphicons-halflings-regular.svg +287 -287
  154. data/app/assets/stylesheets/rails_marketplace/fonts/glyphicons-halflings-regular.ttf +0 -0
  155. data/app/assets/stylesheets/rails_marketplace/fonts/glyphicons-halflings-regular.woff +0 -0
  156. data/app/assets/stylesheets/rails_marketplace/fonts/glyphicons-halflings-regular.woff2 +0 -0
  157. data/app/assets/stylesheets/rails_marketplace/fonts/less/animated.less +34 -34
  158. data/app/assets/stylesheets/rails_marketplace/fonts/less/bordered-pulled.less +25 -25
  159. data/app/assets/stylesheets/rails_marketplace/fonts/less/core.less +12 -12
  160. data/app/assets/stylesheets/rails_marketplace/fonts/less/fixed-width.less +6 -6
  161. data/app/assets/stylesheets/rails_marketplace/fonts/less/font-awesome.less +17 -17
  162. data/app/assets/stylesheets/rails_marketplace/fonts/less/icons.less +697 -697
  163. data/app/assets/stylesheets/rails_marketplace/fonts/less/larger.less +13 -13
  164. data/app/assets/stylesheets/rails_marketplace/fonts/less/list.less +19 -19
  165. data/app/assets/stylesheets/rails_marketplace/fonts/less/mixins.less +26 -26
  166. data/app/assets/stylesheets/rails_marketplace/fonts/less/path.less +15 -15
  167. data/app/assets/stylesheets/rails_marketplace/fonts/less/rotated-flipped.less +20 -20
  168. data/app/assets/stylesheets/rails_marketplace/fonts/less/spinning.less +29 -29
  169. data/app/assets/stylesheets/rails_marketplace/fonts/less/stacked.less +20 -20
  170. data/app/assets/stylesheets/rails_marketplace/fonts/less/variables.less +708 -708
  171. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_animated.scss +34 -34
  172. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_bordered-pulled.scss +25 -25
  173. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_core.scss +12 -12
  174. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_fixed-width.scss +6 -6
  175. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_icons.scss +697 -697
  176. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_larger.scss +13 -13
  177. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_list.scss +19 -19
  178. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_mixins.scss +26 -26
  179. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_path.scss +15 -15
  180. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_rotated-flipped.scss +20 -20
  181. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_spinning.scss +29 -29
  182. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_stacked.scss +20 -20
  183. data/app/assets/stylesheets/rails_marketplace/fonts/scss/_variables.scss +708 -708
  184. data/app/assets/stylesheets/rails_marketplace/fonts/scss/font-awesome.scss +17 -17
  185. data/app/assets/stylesheets/rails_marketplace/images/loading.gif +0 -0
  186. data/app/assets/stylesheets/rails_marketplace/marketplace.scss +19 -19
  187. data/app/assets/stylesheets/rails_marketplace/pace.css +76 -76
  188. data/app/assets/stylesheets/rails_marketplace/welcome.scss +3 -3
  189. data/app/assets/stylesheets/scaffold.css +56 -56
  190. data/app/controllers/rails_marketplace/admin_controller.rb +150 -150
  191. data/app/controllers/rails_marketplace/application_controller.rb +4 -4
  192. data/app/controllers/rails_marketplace/catalog_controller.rb +171 -171
  193. data/app/controllers/rails_marketplace/seller_controller.rb +180 -180
  194. data/app/helpers/rails_marketplace/admin_helper.rb +16 -16
  195. data/app/helpers/rails_marketplace/application_helper.rb +4 -4
  196. data/app/helpers/rails_marketplace/catalog_helper.rb +4 -4
  197. data/app/helpers/rails_marketplace/plainpage_helper.rb +4 -4
  198. data/app/helpers/rails_marketplace/seller_helper.rb +15 -15
  199. data/app/models/rails_marketplace/admin.rb +9 -9
  200. data/app/models/rails_marketplace/admin_setting.rb +13 -13
  201. data/app/models/rails_marketplace/cart.rb +48 -48
  202. data/app/models/rails_marketplace/cart_product.rb +6 -6
  203. data/app/models/rails_marketplace/category.rb +21 -21
  204. data/app/models/rails_marketplace/category_product.rb +5 -5
  205. data/app/models/rails_marketplace/customer.rb +5 -5
  206. data/app/models/rails_marketplace/order.rb +21 -21
  207. data/app/models/rails_marketplace/order_product.rb +6 -6
  208. data/app/models/rails_marketplace/product.rb +33 -33
  209. data/app/models/rails_marketplace/seller.rb +12 -12
  210. data/app/models/rails_marketplace/seller_setting.rb +5 -5
  211. data/app/views/layouts/rails_marketplace/application.html.erb +37 -37
  212. data/app/views/layouts/rails_marketplace/seller_central.html.erb +58 -58
  213. data/app/views/layouts/rails_marketplace/super_admin.html.erb +58 -58
  214. data/app/views/rails_marketplace/admin/add_category.html.erb +63 -63
  215. data/app/views/rails_marketplace/admin/categories.html.erb +50 -50
  216. data/app/views/rails_marketplace/admin/category_products.html.erb +54 -54
  217. data/app/views/rails_marketplace/admin/dashboard.html.erb +49 -49
  218. data/app/views/rails_marketplace/admin/edit_category.html.erb +63 -63
  219. data/app/views/rails_marketplace/admin/login_form.html.erb +19 -19
  220. data/app/views/rails_marketplace/admin/products.html.erb +54 -54
  221. data/app/views/rails_marketplace/admin/seller_products.html.erb +54 -54
  222. data/app/views/rails_marketplace/admin/sellers.html.erb +48 -48
  223. data/app/views/rails_marketplace/admin/settings_form.html.erb +38 -38
  224. data/app/views/rails_marketplace/admin/signup_form.html.erb +24 -24
  225. data/app/views/rails_marketplace/catalog/cart.html.erb +80 -80
  226. data/app/views/rails_marketplace/catalog/category_products.html.erb +52 -52
  227. data/app/views/rails_marketplace/catalog/checkout.html.erb +207 -207
  228. data/app/views/rails_marketplace/catalog/checkout_success.html.erb +14 -14
  229. data/app/views/rails_marketplace/catalog/index.html.erb +0 -0
  230. data/app/views/rails_marketplace/catalog/product_detail.html.erb +87 -87
  231. data/app/views/rails_marketplace/partials/_admin_sidenav.html.erb +80 -80
  232. data/app/views/rails_marketplace/partials/_admin_topnav.html.erb +111 -111
  233. data/app/views/rails_marketplace/partials/_footer.html.erb +19 -19
  234. data/app/views/rails_marketplace/partials/_menu.html.erb +41 -41
  235. data/app/views/rails_marketplace/partials/_sidenav.html.erb +77 -77
  236. data/app/views/rails_marketplace/partials/_topnav.html.erb +105 -105
  237. data/app/views/rails_marketplace/seller/add_bulk_products.html.erb +0 -0
  238. data/app/views/rails_marketplace/seller/add_product.html.erb +66 -66
  239. data/app/views/rails_marketplace/seller/dashboard.html.erb +50 -50
  240. data/app/views/rails_marketplace/seller/edit_product.html.erb +68 -68
  241. data/app/views/rails_marketplace/seller/login_form.html.erb +36 -36
  242. data/app/views/rails_marketplace/seller/order_details.html.erb +69 -69
  243. data/app/views/rails_marketplace/seller/orders.html.erb +68 -68
  244. data/app/views/rails_marketplace/seller/products.html.erb +55 -55
  245. data/app/views/rails_marketplace/seller/settings_general.html.erb +64 -64
  246. data/app/views/rails_marketplace/seller/settings_payment.html.erb +34 -34
  247. data/app/views/rails_marketplace/seller/settings_shipping.html.erb +34 -34
  248. data/app/views/rails_marketplace/seller/settings_tax.html.erb +34 -34
  249. data/app/views/rails_marketplace/seller/signup_form.html.erb +27 -27
  250. data/app/views/rails_marketplace/seller/step_two.html.erb +16 -16
  251. data/app/views/rails_marketplace/shared/_admin_error_messages.html.erb +11 -11
  252. data/app/views/rails_marketplace/shared/_product_error_messages.html.erb +11 -11
  253. data/app/views/rails_marketplace/shared/_seller_error_messages.html.erb +11 -11
  254. data/config/routes.rb +58 -58
  255. data/db/migrate/20161013194852_create_sellers.rb +13 -13
  256. data/db/migrate/20161013195006_create_customers.rb +13 -13
  257. data/db/migrate/20161013195758_create_orders.rb +8 -8
  258. data/db/migrate/20161014013032_create_category_products.rb +10 -10
  259. data/db/migrate/20161014013058_create_order_products.rb +13 -13
  260. data/db/migrate/20161017185755_create_admins.rb +12 -12
  261. data/db/migrate/20161017232347_create_products.rb +14 -14
  262. data/db/migrate/20161019012043_add_reference_product_seller.rb +5 -5
  263. data/db/migrate/20161019013502_change_data_type_images_files.rb +6 -6
  264. data/db/migrate/20161019022020_add_reference_order_customers.rb +5 -5
  265. data/db/migrate/20161109191644_create_categories.rb +15 -15
  266. data/db/migrate/20161110021043_create_friendly_id_slugs.rb +15 -15
  267. data/db/migrate/20161110021131_add_slug_to_category.rb +6 -6
  268. data/db/migrate/20161110024118_add_slug_to_product.rb +6 -6
  269. data/db/migrate/20161111001446_create_carts.rb +8 -8
  270. data/db/migrate/20161111004451_create_cart_products.rb +12 -12
  271. data/db/migrate/20161115013956_add_currency_format_to_price.rb +6 -6
  272. data/db/migrate/20161115015227_monetize_product.rb +5 -5
  273. data/db/migrate/20161115032905_add_stripe_key_to_admin.rb +6 -6
  274. data/db/migrate/20161124015608_add_order_fields.rb +16 -16
  275. data/db/migrate/20161207193917_add_seller_to_orders.rb +6 -6
  276. data/db/migrate/20161208012601_add_price_to_cart_products.rb +6 -6
  277. data/db/migrate/20161208013402_add_money_to_cart_products.rb +6 -6
  278. data/db/migrate/20170217183953_create_seller_settings.rb +29 -29
  279. data/db/migrate/20170218003202_create_admin_settings.rb +24 -24
  280. data/db/migrate/20170224230449_create_stripe_managed_accounts.rb +9 -9
  281. data/db/migrate/20170224233736_add_stripe_to_admin_settings.rb +9 -9
  282. data/db/migrate/20170224235259_add_id_to_settings.rb +6 -6
  283. data/db/migrate/20170225002939_delete_stripe_accounts.rb +8 -8
  284. data/db/migrate/20170225003252_add_stripe_account_id_to_seller_settings.rb +5 -5
  285. data/lib/rails_marketplace.rb +4 -4
  286. data/lib/rails_marketplace/engine.rb +9 -9
  287. data/lib/rails_marketplace/version.rb +3 -3
  288. data/lib/tasks/rails_marketplace_tasks.rake +4 -4
  289. data/spec/controllers/rails_marketplace/catalog_controller_spec.rb +75 -75
  290. data/spec/dummy/README.rdoc +28 -28
  291. data/spec/dummy/Rakefile +6 -6
  292. data/spec/dummy/app/assets/javascripts/application.js +13 -13
  293. data/spec/dummy/app/assets/stylesheets/application.css +15 -15
  294. data/spec/dummy/app/controllers/application_controller.rb +5 -5
  295. data/spec/dummy/app/helpers/application_helper.rb +2 -2
  296. data/spec/dummy/app/views/layouts/application.html.erb +14 -14
  297. data/spec/dummy/bin/bundle +3 -3
  298. data/spec/dummy/bin/rails +4 -4
  299. data/spec/dummy/bin/rake +4 -4
  300. data/spec/dummy/bin/setup +29 -29
  301. data/spec/dummy/config.ru +4 -4
  302. data/spec/dummy/config/application.rb +32 -32
  303. data/spec/dummy/config/boot.rb +5 -5
  304. data/spec/dummy/config/database.yml +25 -25
  305. data/spec/dummy/config/environment.rb +5 -5
  306. data/spec/dummy/config/environments/development.rb +41 -41
  307. data/spec/dummy/config/environments/production.rb +79 -79
  308. data/spec/dummy/config/environments/test.rb +42 -42
  309. data/spec/dummy/config/initializers/assets.rb +11 -11
  310. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
  311. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -3
  312. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -4
  313. data/spec/dummy/config/initializers/inflections.rb +16 -16
  314. data/spec/dummy/config/initializers/mime_types.rb +4 -4
  315. data/spec/dummy/config/initializers/session_store.rb +3 -3
  316. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
  317. data/spec/dummy/config/locales/en.yml +23 -23
  318. data/spec/dummy/config/routes.rb +4 -4
  319. data/spec/dummy/config/secrets.yml +22 -22
  320. data/spec/dummy/db/schema.rb +194 -194
  321. data/spec/dummy/log/development.log +889 -889
  322. data/spec/dummy/log/test.log +1229 -1229
  323. data/spec/dummy/public/404.html +67 -67
  324. data/spec/dummy/public/422.html +67 -67
  325. data/spec/dummy/public/500.html +66 -66
  326. data/spec/dummy/public/favicon.ico +0 -0
  327. data/spec/helpers/rails_marketplace/catalog_helper_spec.rb +17 -17
  328. data/spec/routing/rails_marketplace/catalog_routing_spec.rb +44 -44
  329. data/spec/spec_helper.rb +44 -44
  330. data/spec/views/rails_marketplace/catalog/edit.html.erb_spec.rb +15 -15
  331. data/spec/views/rails_marketplace/catalog/index.html.erb_spec.rb +15 -15
  332. data/spec/views/rails_marketplace/catalog/new.html.erb_spec.rb +15 -15
  333. data/spec/views/rails_marketplace/catalog/show.html.erb_spec.rb +12 -12
  334. metadata +37 -38
@@ -1,986 +1,986 @@
1
- /**
2
- * Ajax Autocomplete for jQuery, version 1.2.27
3
- * (c) 2015 Tomas Kirda
4
- *
5
- * Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
6
- * For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
7
- */
8
-
9
- /*jslint browser: true, white: true, plusplus: true, vars: true */
10
- /*global define, window, document, jQuery, exports, require */
11
-
12
- // Expose plugin as an AMD module if AMD loader is present:
13
- (function (factory) {
14
- 'use strict';
15
- if (typeof define === 'function' && define.amd) {
16
- // AMD. Register as an anonymous module.
17
- define(['jquery'], factory);
18
- } else if (typeof exports === 'object' && typeof require === 'function') {
19
- // Browserify
20
- factory(require('jquery'));
21
- } else {
22
- // Browser globals
23
- factory(jQuery);
24
- }
25
- }(function ($) {
26
- 'use strict';
27
-
28
- var
29
- utils = (function () {
30
- return {
31
- escapeRegExChars: function (value) {
32
- return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
33
- },
34
- createNode: function (containerClass) {
35
- var div = document.createElement('div');
36
- div.className = containerClass;
37
- div.style.position = 'absolute';
38
- div.style.display = 'none';
39
- return div;
40
- }
41
- };
42
- }()),
43
-
44
- keys = {
45
- ESC: 27,
46
- TAB: 9,
47
- RETURN: 13,
48
- LEFT: 37,
49
- UP: 38,
50
- RIGHT: 39,
51
- DOWN: 40
52
- };
53
-
54
- function Autocomplete(el, options) {
55
- var noop = function () { },
56
- that = this,
57
- defaults = {
58
- ajaxSettings: {},
59
- autoSelectFirst: false,
60
- appendTo: document.body,
61
- serviceUrl: null,
62
- lookup: null,
63
- onSelect: null,
64
- width: 'auto',
65
- minChars: 1,
66
- maxHeight: 300,
67
- deferRequestBy: 0,
68
- params: {},
69
- formatResult: Autocomplete.formatResult,
70
- delimiter: null,
71
- zIndex: 9999,
72
- type: 'GET',
73
- noCache: false,
74
- onSearchStart: noop,
75
- onSearchComplete: noop,
76
- onSearchError: noop,
77
- preserveInput: false,
78
- containerClass: 'autocomplete-suggestions',
79
- tabDisabled: false,
80
- dataType: 'text',
81
- currentRequest: null,
82
- triggerSelectOnValidInput: true,
83
- preventBadQueries: true,
84
- lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
85
- return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
86
- },
87
- paramName: 'query',
88
- transformResult: function (response) {
89
- return typeof response === 'string' ? $.parseJSON(response) : response;
90
- },
91
- showNoSuggestionNotice: false,
92
- noSuggestionNotice: 'No results',
93
- orientation: 'bottom',
94
- forceFixPosition: false
95
- };
96
-
97
- // Shared variables:
98
- that.element = el;
99
- that.el = $(el);
100
- that.suggestions = [];
101
- that.badQueries = [];
102
- that.selectedIndex = -1;
103
- that.currentValue = that.element.value;
104
- that.intervalId = 0;
105
- that.cachedResponse = {};
106
- that.onChangeInterval = null;
107
- that.onChange = null;
108
- that.isLocal = false;
109
- that.suggestionsContainer = null;
110
- that.noSuggestionsContainer = null;
111
- that.options = $.extend({}, defaults, options);
112
- that.classes = {
113
- selected: 'autocomplete-selected',
114
- suggestion: 'autocomplete-suggestion'
115
- };
116
- that.hint = null;
117
- that.hintValue = '';
118
- that.selection = null;
119
-
120
- // Initialize and set options:
121
- that.initialize();
122
- that.setOptions(options);
123
- }
124
-
125
- Autocomplete.utils = utils;
126
-
127
- $.Autocomplete = Autocomplete;
128
-
129
- Autocomplete.formatResult = function (suggestion, currentValue) {
130
- // Do not replace anything if there current value is empty
131
- if (!currentValue) {
132
- return suggestion.value;
133
- }
134
-
135
- var pattern = '(' + utils.escapeRegExChars(currentValue) + ')';
136
-
137
- return suggestion.value
138
- .replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>')
139
- .replace(/&/g, '&amp;')
140
- .replace(/</g, '&lt;')
141
- .replace(/>/g, '&gt;')
142
- .replace(/"/g, '&quot;')
143
- .replace(/&lt;(\/?strong)&gt;/g, '<$1>');
144
- };
145
-
146
- Autocomplete.prototype = {
147
-
148
- killerFn: null,
149
-
150
- initialize: function () {
151
- var that = this,
152
- suggestionSelector = '.' + that.classes.suggestion,
153
- selected = that.classes.selected,
154
- options = that.options,
155
- container;
156
-
157
- // Remove autocomplete attribute to prevent native suggestions:
158
- that.element.setAttribute('autocomplete', 'off');
159
-
160
- that.killerFn = function (e) {
161
- if ($(e.target).closest('.' + that.options.containerClass).length === 0) {
162
- that.killSuggestions();
163
- that.disableKillerFn();
164
- }
165
- };
166
-
167
- // html() deals with many types: htmlString or Element or Array or jQuery
168
- that.noSuggestionsContainer = $('<div class="autocomplete-no-suggestion"></div>')
169
- .html(this.options.noSuggestionNotice).get(0);
170
-
171
- that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
172
-
173
- container = $(that.suggestionsContainer);
174
-
175
- container.appendTo(options.appendTo);
176
-
177
- // Only set width if it was provided:
178
- if (options.width !== 'auto') {
179
- container.width(options.width);
180
- }
181
-
182
- // Listen for mouse over event on suggestions list:
183
- container.on('mouseover.autocomplete', suggestionSelector, function () {
184
- that.activate($(this).data('index'));
185
- });
186
-
187
- // Deselect active element when mouse leaves suggestions container:
188
- container.on('mouseout.autocomplete', function () {
189
- that.selectedIndex = -1;
190
- container.children('.' + selected).removeClass(selected);
191
- });
192
-
193
- // Listen for click event on suggestions list:
194
- container.on('click.autocomplete', suggestionSelector, function () {
195
- that.select($(this).data('index'));
196
- });
197
-
198
- that.fixPositionCapture = function () {
199
- if (that.visible) {
200
- that.fixPosition();
201
- }
202
- };
203
-
204
- $(window).on('resize.autocomplete', that.fixPositionCapture);
205
-
206
- that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); });
207
- that.el.on('keyup.autocomplete', function (e) { that.onKeyUp(e); });
208
- that.el.on('blur.autocomplete', function () { that.onBlur(); });
209
- that.el.on('focus.autocomplete', function () { that.onFocus(); });
210
- that.el.on('change.autocomplete', function (e) { that.onKeyUp(e); });
211
- that.el.on('input.autocomplete', function (e) { that.onKeyUp(e); });
212
- },
213
-
214
- onFocus: function () {
215
- var that = this;
216
-
217
- that.fixPosition();
218
-
219
- if (that.el.val().length >= that.options.minChars) {
220
- that.onValueChange();
221
- }
222
- },
223
-
224
- onBlur: function () {
225
- this.enableKillerFn();
226
- },
227
-
228
- abortAjax: function () {
229
- var that = this;
230
- if (that.currentRequest) {
231
- that.currentRequest.abort();
232
- that.currentRequest = null;
233
- }
234
- },
235
-
236
- setOptions: function (suppliedOptions) {
237
- var that = this,
238
- options = that.options;
239
-
240
- $.extend(options, suppliedOptions);
241
-
242
- that.isLocal = $.isArray(options.lookup);
243
-
244
- if (that.isLocal) {
245
- options.lookup = that.verifySuggestionsFormat(options.lookup);
246
- }
247
-
248
- options.orientation = that.validateOrientation(options.orientation, 'bottom');
249
-
250
- // Adjust height, width and z-index:
251
- $(that.suggestionsContainer).css({
252
- 'max-height': options.maxHeight + 'px',
253
- 'width': options.width + 'px',
254
- 'z-index': options.zIndex
255
- });
256
- },
257
-
258
-
259
- clearCache: function () {
260
- this.cachedResponse = {};
261
- this.badQueries = [];
262
- },
263
-
264
- clear: function () {
265
- this.clearCache();
266
- this.currentValue = '';
267
- this.suggestions = [];
268
- },
269
-
270
- disable: function () {
271
- var that = this;
272
- that.disabled = true;
273
- clearInterval(that.onChangeInterval);
274
- that.abortAjax();
275
- },
276
-
277
- enable: function () {
278
- this.disabled = false;
279
- },
280
-
281
- fixPosition: function () {
282
- // Use only when container has already its content
283
-
284
- var that = this,
285
- $container = $(that.suggestionsContainer),
286
- containerParent = $container.parent().get(0);
287
- // Fix position automatically when appended to body.
288
- // In other cases force parameter must be given.
289
- if (containerParent !== document.body && !that.options.forceFixPosition) {
290
- return;
291
- }
292
-
293
- // Choose orientation
294
- var orientation = that.options.orientation,
295
- containerHeight = $container.outerHeight(),
296
- height = that.el.outerHeight(),
297
- offset = that.el.offset(),
298
- styles = { 'top': offset.top, 'left': offset.left };
299
-
300
- if (orientation === 'auto') {
301
- var viewPortHeight = $(window).height(),
302
- scrollTop = $(window).scrollTop(),
303
- topOverflow = -scrollTop + offset.top - containerHeight,
304
- bottomOverflow = scrollTop + viewPortHeight - (offset.top + height + containerHeight);
305
-
306
- orientation = (Math.max(topOverflow, bottomOverflow) === topOverflow) ? 'top' : 'bottom';
307
- }
308
-
309
- if (orientation === 'top') {
310
- styles.top += -containerHeight;
311
- } else {
312
- styles.top += height;
313
- }
314
-
315
- // If container is not positioned to body,
316
- // correct its position using offset parent offset
317
- if(containerParent !== document.body) {
318
- var opacity = $container.css('opacity'),
319
- parentOffsetDiff;
320
-
321
- if (!that.visible){
322
- $container.css('opacity', 0).show();
323
- }
324
-
325
- parentOffsetDiff = $container.offsetParent().offset();
326
- styles.top -= parentOffsetDiff.top;
327
- styles.left -= parentOffsetDiff.left;
328
-
329
- if (!that.visible){
330
- $container.css('opacity', opacity).hide();
331
- }
332
- }
333
-
334
- // -2px to account for suggestions border.
335
- if (that.options.width === 'auto') {
336
- styles.width = (that.el.outerWidth() - 2) + 'px';
337
- }
338
-
339
- $container.css(styles);
340
- },
341
-
342
- enableKillerFn: function () {
343
- var that = this;
344
- $(document).on('click.autocomplete', that.killerFn);
345
- },
346
-
347
- disableKillerFn: function () {
348
- var that = this;
349
- $(document).off('click.autocomplete', that.killerFn);
350
- },
351
-
352
- killSuggestions: function () {
353
- var that = this;
354
- that.stopKillSuggestions();
355
- that.intervalId = window.setInterval(function () {
356
- if (that.visible) {
357
- that.el.val(that.currentValue);
358
- that.hide();
359
- }
360
-
361
- that.stopKillSuggestions();
362
- }, 50);
363
- },
364
-
365
- stopKillSuggestions: function () {
366
- window.clearInterval(this.intervalId);
367
- },
368
-
369
- isCursorAtEnd: function () {
370
- var that = this,
371
- valLength = that.el.val().length,
372
- selectionStart = that.element.selectionStart,
373
- range;
374
-
375
- if (typeof selectionStart === 'number') {
376
- return selectionStart === valLength;
377
- }
378
- if (document.selection) {
379
- range = document.selection.createRange();
380
- range.moveStart('character', -valLength);
381
- return valLength === range.text.length;
382
- }
383
- return true;
384
- },
385
-
386
- onKeyPress: function (e) {
387
- var that = this;
388
-
389
- // If suggestions are hidden and user presses arrow down, display suggestions:
390
- if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) {
391
- that.suggest();
392
- return;
393
- }
394
-
395
- if (that.disabled || !that.visible) {
396
- return;
397
- }
398
-
399
- switch (e.which) {
400
- case keys.ESC:
401
- that.el.val(that.currentValue);
402
- that.hide();
403
- break;
404
- case keys.RIGHT:
405
- if (that.hint && that.options.onHint && that.isCursorAtEnd()) {
406
- that.selectHint();
407
- break;
408
- }
409
- return;
410
- case keys.TAB:
411
- if (that.hint && that.options.onHint) {
412
- that.selectHint();
413
- return;
414
- }
415
- if (that.selectedIndex === -1) {
416
- that.hide();
417
- return;
418
- }
419
- that.select(that.selectedIndex);
420
- if (that.options.tabDisabled === false) {
421
- return;
422
- }
423
- break;
424
- case keys.RETURN:
425
- if (that.selectedIndex === -1) {
426
- that.hide();
427
- return;
428
- }
429
- that.select(that.selectedIndex);
430
- break;
431
- case keys.UP:
432
- that.moveUp();
433
- break;
434
- case keys.DOWN:
435
- that.moveDown();
436
- break;
437
- default:
438
- return;
439
- }
440
-
441
- // Cancel event if function did not return:
442
- e.stopImmediatePropagation();
443
- e.preventDefault();
444
- },
445
-
446
- onKeyUp: function (e) {
447
- var that = this;
448
-
449
- if (that.disabled) {
450
- return;
451
- }
452
-
453
- switch (e.which) {
454
- case keys.UP:
455
- case keys.DOWN:
456
- return;
457
- }
458
-
459
- clearInterval(that.onChangeInterval);
460
-
461
- if (that.currentValue !== that.el.val()) {
462
- that.findBestHint();
463
- if (that.options.deferRequestBy > 0) {
464
- // Defer lookup in case when value changes very quickly:
465
- that.onChangeInterval = setInterval(function () {
466
- that.onValueChange();
467
- }, that.options.deferRequestBy);
468
- } else {
469
- that.onValueChange();
470
- }
471
- }
472
- },
473
-
474
- onValueChange: function () {
475
- var that = this,
476
- options = that.options,
477
- value = that.el.val(),
478
- query = that.getQuery(value);
479
-
480
- if (that.selection && that.currentValue !== query) {
481
- that.selection = null;
482
- (options.onInvalidateSelection || $.noop).call(that.element);
483
- }
484
-
485
- clearInterval(that.onChangeInterval);
486
- that.currentValue = value;
487
- that.selectedIndex = -1;
488
-
489
- // Check existing suggestion for the match before proceeding:
490
- if (options.triggerSelectOnValidInput && that.isExactMatch(query)) {
491
- that.select(0);
492
- return;
493
- }
494
-
495
- if (query.length < options.minChars) {
496
- that.hide();
497
- } else {
498
- that.getSuggestions(query);
499
- }
500
- },
501
-
502
- isExactMatch: function (query) {
503
- var suggestions = this.suggestions;
504
-
505
- return (suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase());
506
- },
507
-
508
- getQuery: function (value) {
509
- var delimiter = this.options.delimiter,
510
- parts;
511
-
512
- if (!delimiter) {
513
- return value;
514
- }
515
- parts = value.split(delimiter);
516
- return $.trim(parts[parts.length - 1]);
517
- },
518
-
519
- getSuggestionsLocal: function (query) {
520
- var that = this,
521
- options = that.options,
522
- queryLowerCase = query.toLowerCase(),
523
- filter = options.lookupFilter,
524
- limit = parseInt(options.lookupLimit, 10),
525
- data;
526
-
527
- data = {
528
- suggestions: $.grep(options.lookup, function (suggestion) {
529
- return filter(suggestion, query, queryLowerCase);
530
- })
531
- };
532
-
533
- if (limit && data.suggestions.length > limit) {
534
- data.suggestions = data.suggestions.slice(0, limit);
535
- }
536
-
537
- return data;
538
- },
539
-
540
- getSuggestions: function (q) {
541
- var response,
542
- that = this,
543
- options = that.options,
544
- serviceUrl = options.serviceUrl,
545
- params,
546
- cacheKey,
547
- ajaxSettings;
548
-
549
- options.params[options.paramName] = q;
550
- params = options.ignoreParams ? null : options.params;
551
-
552
- if (options.onSearchStart.call(that.element, options.params) === false) {
553
- return;
554
- }
555
-
556
- if ($.isFunction(options.lookup)){
557
- options.lookup(q, function (data) {
558
- that.suggestions = data.suggestions;
559
- that.suggest();
560
- options.onSearchComplete.call(that.element, q, data.suggestions);
561
- });
562
- return;
563
- }
564
-
565
- if (that.isLocal) {
566
- response = that.getSuggestionsLocal(q);
567
- } else {
568
- if ($.isFunction(serviceUrl)) {
569
- serviceUrl = serviceUrl.call(that.element, q);
570
- }
571
- cacheKey = serviceUrl + '?' + $.param(params || {});
572
- response = that.cachedResponse[cacheKey];
573
- }
574
-
575
- if (response && $.isArray(response.suggestions)) {
576
- that.suggestions = response.suggestions;
577
- that.suggest();
578
- options.onSearchComplete.call(that.element, q, response.suggestions);
579
- } else if (!that.isBadQuery(q)) {
580
- that.abortAjax();
581
-
582
- ajaxSettings = {
583
- url: serviceUrl,
584
- data: params,
585
- type: options.type,
586
- dataType: options.dataType
587
- };
588
-
589
- $.extend(ajaxSettings, options.ajaxSettings);
590
-
591
- that.currentRequest = $.ajax(ajaxSettings).done(function (data) {
592
- var result;
593
- that.currentRequest = null;
594
- result = options.transformResult(data, q);
595
- that.processResponse(result, q, cacheKey);
596
- options.onSearchComplete.call(that.element, q, result.suggestions);
597
- }).fail(function (jqXHR, textStatus, errorThrown) {
598
- options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
599
- });
600
- } else {
601
- options.onSearchComplete.call(that.element, q, []);
602
- }
603
- },
604
-
605
- isBadQuery: function (q) {
606
- if (!this.options.preventBadQueries){
607
- return false;
608
- }
609
-
610
- var badQueries = this.badQueries,
611
- i = badQueries.length;
612
-
613
- while (i--) {
614
- if (q.indexOf(badQueries[i]) === 0) {
615
- return true;
616
- }
617
- }
618
-
619
- return false;
620
- },
621
-
622
- hide: function () {
623
- var that = this,
624
- container = $(that.suggestionsContainer);
625
-
626
- if ($.isFunction(that.options.onHide) && that.visible) {
627
- that.options.onHide.call(that.element, container);
628
- }
629
-
630
- that.visible = false;
631
- that.selectedIndex = -1;
632
- clearInterval(that.onChangeInterval);
633
- $(that.suggestionsContainer).hide();
634
- that.signalHint(null);
635
- },
636
-
637
- suggest: function () {
638
- if (this.suggestions.length === 0) {
639
- if (this.options.showNoSuggestionNotice) {
640
- this.noSuggestions();
641
- } else {
642
- this.hide();
643
- }
644
- return;
645
- }
646
-
647
- var that = this,
648
- options = that.options,
649
- groupBy = options.groupBy,
650
- formatResult = options.formatResult,
651
- value = that.getQuery(that.currentValue),
652
- className = that.classes.suggestion,
653
- classSelected = that.classes.selected,
654
- container = $(that.suggestionsContainer),
655
- noSuggestionsContainer = $(that.noSuggestionsContainer),
656
- beforeRender = options.beforeRender,
657
- html = '',
658
- category,
659
- formatGroup = function (suggestion, index) {
660
- var currentCategory = suggestion.data[groupBy];
661
-
662
- if (category === currentCategory){
663
- return '';
664
- }
665
-
666
- category = currentCategory;
667
-
668
- return '<div class="autocomplete-group"><strong>' + category + '</strong></div>';
669
- };
670
-
671
- if (options.triggerSelectOnValidInput && that.isExactMatch(value)) {
672
- that.select(0);
673
- return;
674
- }
675
-
676
- // Build suggestions inner HTML:
677
- $.each(that.suggestions, function (i, suggestion) {
678
- if (groupBy){
679
- html += formatGroup(suggestion, value, i);
680
- }
681
-
682
- html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
683
- });
684
-
685
- this.adjustContainerWidth();
686
-
687
- noSuggestionsContainer.detach();
688
- container.html(html);
689
-
690
- if ($.isFunction(beforeRender)) {
691
- beforeRender.call(that.element, container);
692
- }
693
-
694
- that.fixPosition();
695
- container.show();
696
-
697
- // Select first value by default:
698
- if (options.autoSelectFirst) {
699
- that.selectedIndex = 0;
700
- container.scrollTop(0);
701
- container.children('.' + className).first().addClass(classSelected);
702
- }
703
-
704
- that.visible = true;
705
- that.findBestHint();
706
- },
707
-
708
- noSuggestions: function() {
709
- var that = this,
710
- container = $(that.suggestionsContainer),
711
- noSuggestionsContainer = $(that.noSuggestionsContainer);
712
-
713
- this.adjustContainerWidth();
714
-
715
- // Some explicit steps. Be careful here as it easy to get
716
- // noSuggestionsContainer removed from DOM if not detached properly.
717
- noSuggestionsContainer.detach();
718
- container.empty(); // clean suggestions if any
719
- container.append(noSuggestionsContainer);
720
-
721
- that.fixPosition();
722
-
723
- container.show();
724
- that.visible = true;
725
- },
726
-
727
- adjustContainerWidth: function() {
728
- var that = this,
729
- options = that.options,
730
- width,
731
- container = $(that.suggestionsContainer);
732
-
733
- // If width is auto, adjust width before displaying suggestions,
734
- // because if instance was created before input had width, it will be zero.
735
- // Also it adjusts if input width has changed.
736
- // -2px to account for suggestions border.
737
- if (options.width === 'auto') {
738
- width = that.el.outerWidth() - 2;
739
- container.width(width > 0 ? width : 300);
740
- }
741
- },
742
-
743
- findBestHint: function () {
744
- var that = this,
745
- value = that.el.val().toLowerCase(),
746
- bestMatch = null;
747
-
748
- if (!value) {
749
- return;
750
- }
751
-
752
- $.each(that.suggestions, function (i, suggestion) {
753
- var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0;
754
- if (foundMatch) {
755
- bestMatch = suggestion;
756
- }
757
- return !foundMatch;
758
- });
759
-
760
- that.signalHint(bestMatch);
761
- },
762
-
763
- signalHint: function (suggestion) {
764
- var hintValue = '',
765
- that = this;
766
- if (suggestion) {
767
- hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length);
768
- }
769
- if (that.hintValue !== hintValue) {
770
- that.hintValue = hintValue;
771
- that.hint = suggestion;
772
- (this.options.onHint || $.noop)(hintValue);
773
- }
774
- },
775
-
776
- verifySuggestionsFormat: function (suggestions) {
777
- // If suggestions is string array, convert them to supported format:
778
- if (suggestions.length && typeof suggestions[0] === 'string') {
779
- return $.map(suggestions, function (value) {
780
- return { value: value, data: null };
781
- });
782
- }
783
-
784
- return suggestions;
785
- },
786
-
787
- validateOrientation: function(orientation, fallback) {
788
- orientation = $.trim(orientation || '').toLowerCase();
789
-
790
- if($.inArray(orientation, ['auto', 'bottom', 'top']) === -1){
791
- orientation = fallback;
792
- }
793
-
794
- return orientation;
795
- },
796
-
797
- processResponse: function (result, originalQuery, cacheKey) {
798
- var that = this,
799
- options = that.options;
800
-
801
- result.suggestions = that.verifySuggestionsFormat(result.suggestions);
802
-
803
- // Cache results if cache is not disabled:
804
- if (!options.noCache) {
805
- that.cachedResponse[cacheKey] = result;
806
- if (options.preventBadQueries && result.suggestions.length === 0) {
807
- that.badQueries.push(originalQuery);
808
- }
809
- }
810
-
811
- // Return if originalQuery is not matching current query:
812
- if (originalQuery !== that.getQuery(that.currentValue)) {
813
- return;
814
- }
815
-
816
- that.suggestions = result.suggestions;
817
- that.suggest();
818
- },
819
-
820
- activate: function (index) {
821
- var that = this,
822
- activeItem,
823
- selected = that.classes.selected,
824
- container = $(that.suggestionsContainer),
825
- children = container.find('.' + that.classes.suggestion);
826
-
827
- container.find('.' + selected).removeClass(selected);
828
-
829
- that.selectedIndex = index;
830
-
831
- if (that.selectedIndex !== -1 && children.length > that.selectedIndex) {
832
- activeItem = children.get(that.selectedIndex);
833
- $(activeItem).addClass(selected);
834
- return activeItem;
835
- }
836
-
837
- return null;
838
- },
839
-
840
- selectHint: function () {
841
- var that = this,
842
- i = $.inArray(that.hint, that.suggestions);
843
-
844
- that.select(i);
845
- },
846
-
847
- select: function (i) {
848
- var that = this;
849
- that.hide();
850
- that.onSelect(i);
851
- },
852
-
853
- moveUp: function () {
854
- var that = this;
855
-
856
- if (that.selectedIndex === -1) {
857
- return;
858
- }
859
-
860
- if (that.selectedIndex === 0) {
861
- $(that.suggestionsContainer).children().first().removeClass(that.classes.selected);
862
- that.selectedIndex = -1;
863
- that.el.val(that.currentValue);
864
- that.findBestHint();
865
- return;
866
- }
867
-
868
- that.adjustScroll(that.selectedIndex - 1);
869
- },
870
-
871
- moveDown: function () {
872
- var that = this;
873
-
874
- if (that.selectedIndex === (that.suggestions.length - 1)) {
875
- return;
876
- }
877
-
878
- that.adjustScroll(that.selectedIndex + 1);
879
- },
880
-
881
- adjustScroll: function (index) {
882
- var that = this,
883
- activeItem = that.activate(index);
884
-
885
- if (!activeItem) {
886
- return;
887
- }
888
-
889
- var offsetTop,
890
- upperBound,
891
- lowerBound,
892
- heightDelta = $(activeItem).outerHeight();
893
-
894
- offsetTop = activeItem.offsetTop;
895
- upperBound = $(that.suggestionsContainer).scrollTop();
896
- lowerBound = upperBound + that.options.maxHeight - heightDelta;
897
-
898
- if (offsetTop < upperBound) {
899
- $(that.suggestionsContainer).scrollTop(offsetTop);
900
- } else if (offsetTop > lowerBound) {
901
- $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta);
902
- }
903
-
904
- if (!that.options.preserveInput) {
905
- that.el.val(that.getValue(that.suggestions[index].value));
906
- }
907
- that.signalHint(null);
908
- },
909
-
910
- onSelect: function (index) {
911
- var that = this,
912
- onSelectCallback = that.options.onSelect,
913
- suggestion = that.suggestions[index];
914
-
915
- that.currentValue = that.getValue(suggestion.value);
916
-
917
- if (that.currentValue !== that.el.val() && !that.options.preserveInput) {
918
- that.el.val(that.currentValue);
919
- }
920
-
921
- that.signalHint(null);
922
- that.suggestions = [];
923
- that.selection = suggestion;
924
-
925
- if ($.isFunction(onSelectCallback)) {
926
- onSelectCallback.call(that.element, suggestion);
927
- }
928
- },
929
-
930
- getValue: function (value) {
931
- var that = this,
932
- delimiter = that.options.delimiter,
933
- currentValue,
934
- parts;
935
-
936
- if (!delimiter) {
937
- return value;
938
- }
939
-
940
- currentValue = that.currentValue;
941
- parts = currentValue.split(delimiter);
942
-
943
- if (parts.length === 1) {
944
- return value;
945
- }
946
-
947
- return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value;
948
- },
949
-
950
- dispose: function () {
951
- var that = this;
952
- that.el.off('.autocomplete').removeData('autocomplete');
953
- that.disableKillerFn();
954
- $(window).off('resize.autocomplete', that.fixPositionCapture);
955
- $(that.suggestionsContainer).remove();
956
- }
957
- };
958
-
959
- // Create chainable jQuery plugin:
960
- $.fn.autocomplete = $.fn.devbridgeAutocomplete = function (options, args) {
961
- var dataKey = 'autocomplete';
962
- // If function invoked without argument return
963
- // instance of the first matched element:
964
- if (arguments.length === 0) {
965
- return this.first().data(dataKey);
966
- }
967
-
968
- return this.each(function () {
969
- var inputElement = $(this),
970
- instance = inputElement.data(dataKey);
971
-
972
- if (typeof options === 'string') {
973
- if (instance && typeof instance[options] === 'function') {
974
- instance[options](args);
975
- }
976
- } else {
977
- // If instance already exists, destroy it:
978
- if (instance && instance.dispose) {
979
- instance.dispose();
980
- }
981
- instance = new Autocomplete(this, options);
982
- inputElement.data(dataKey, instance);
983
- }
984
- });
985
- };
986
- }));
1
+ /**
2
+ * Ajax Autocomplete for jQuery, version 1.2.27
3
+ * (c) 2015 Tomas Kirda
4
+ *
5
+ * Ajax Autocomplete for jQuery is freely distributable under the terms of an MIT-style license.
6
+ * For details, see the web site: https://github.com/devbridge/jQuery-Autocomplete
7
+ */
8
+
9
+ /*jslint browser: true, white: true, plusplus: true, vars: true */
10
+ /*global define, window, document, jQuery, exports, require */
11
+
12
+ // Expose plugin as an AMD module if AMD loader is present:
13
+ (function (factory) {
14
+ 'use strict';
15
+ if (typeof define === 'function' && define.amd) {
16
+ // AMD. Register as an anonymous module.
17
+ define(['jquery'], factory);
18
+ } else if (typeof exports === 'object' && typeof require === 'function') {
19
+ // Browserify
20
+ factory(require('jquery'));
21
+ } else {
22
+ // Browser globals
23
+ factory(jQuery);
24
+ }
25
+ }(function ($) {
26
+ 'use strict';
27
+
28
+ var
29
+ utils = (function () {
30
+ return {
31
+ escapeRegExChars: function (value) {
32
+ return value.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
33
+ },
34
+ createNode: function (containerClass) {
35
+ var div = document.createElement('div');
36
+ div.className = containerClass;
37
+ div.style.position = 'absolute';
38
+ div.style.display = 'none';
39
+ return div;
40
+ }
41
+ };
42
+ }()),
43
+
44
+ keys = {
45
+ ESC: 27,
46
+ TAB: 9,
47
+ RETURN: 13,
48
+ LEFT: 37,
49
+ UP: 38,
50
+ RIGHT: 39,
51
+ DOWN: 40
52
+ };
53
+
54
+ function Autocomplete(el, options) {
55
+ var noop = function () { },
56
+ that = this,
57
+ defaults = {
58
+ ajaxSettings: {},
59
+ autoSelectFirst: false,
60
+ appendTo: document.body,
61
+ serviceUrl: null,
62
+ lookup: null,
63
+ onSelect: null,
64
+ width: 'auto',
65
+ minChars: 1,
66
+ maxHeight: 300,
67
+ deferRequestBy: 0,
68
+ params: {},
69
+ formatResult: Autocomplete.formatResult,
70
+ delimiter: null,
71
+ zIndex: 9999,
72
+ type: 'GET',
73
+ noCache: false,
74
+ onSearchStart: noop,
75
+ onSearchComplete: noop,
76
+ onSearchError: noop,
77
+ preserveInput: false,
78
+ containerClass: 'autocomplete-suggestions',
79
+ tabDisabled: false,
80
+ dataType: 'text',
81
+ currentRequest: null,
82
+ triggerSelectOnValidInput: true,
83
+ preventBadQueries: true,
84
+ lookupFilter: function (suggestion, originalQuery, queryLowerCase) {
85
+ return suggestion.value.toLowerCase().indexOf(queryLowerCase) !== -1;
86
+ },
87
+ paramName: 'query',
88
+ transformResult: function (response) {
89
+ return typeof response === 'string' ? $.parseJSON(response) : response;
90
+ },
91
+ showNoSuggestionNotice: false,
92
+ noSuggestionNotice: 'No results',
93
+ orientation: 'bottom',
94
+ forceFixPosition: false
95
+ };
96
+
97
+ // Shared variables:
98
+ that.element = el;
99
+ that.el = $(el);
100
+ that.suggestions = [];
101
+ that.badQueries = [];
102
+ that.selectedIndex = -1;
103
+ that.currentValue = that.element.value;
104
+ that.intervalId = 0;
105
+ that.cachedResponse = {};
106
+ that.onChangeInterval = null;
107
+ that.onChange = null;
108
+ that.isLocal = false;
109
+ that.suggestionsContainer = null;
110
+ that.noSuggestionsContainer = null;
111
+ that.options = $.extend({}, defaults, options);
112
+ that.classes = {
113
+ selected: 'autocomplete-selected',
114
+ suggestion: 'autocomplete-suggestion'
115
+ };
116
+ that.hint = null;
117
+ that.hintValue = '';
118
+ that.selection = null;
119
+
120
+ // Initialize and set options:
121
+ that.initialize();
122
+ that.setOptions(options);
123
+ }
124
+
125
+ Autocomplete.utils = utils;
126
+
127
+ $.Autocomplete = Autocomplete;
128
+
129
+ Autocomplete.formatResult = function (suggestion, currentValue) {
130
+ // Do not replace anything if there current value is empty
131
+ if (!currentValue) {
132
+ return suggestion.value;
133
+ }
134
+
135
+ var pattern = '(' + utils.escapeRegExChars(currentValue) + ')';
136
+
137
+ return suggestion.value
138
+ .replace(new RegExp(pattern, 'gi'), '<strong>$1<\/strong>')
139
+ .replace(/&/g, '&amp;')
140
+ .replace(/</g, '&lt;')
141
+ .replace(/>/g, '&gt;')
142
+ .replace(/"/g, '&quot;')
143
+ .replace(/&lt;(\/?strong)&gt;/g, '<$1>');
144
+ };
145
+
146
+ Autocomplete.prototype = {
147
+
148
+ killerFn: null,
149
+
150
+ initialize: function () {
151
+ var that = this,
152
+ suggestionSelector = '.' + that.classes.suggestion,
153
+ selected = that.classes.selected,
154
+ options = that.options,
155
+ container;
156
+
157
+ // Remove autocomplete attribute to prevent native suggestions:
158
+ that.element.setAttribute('autocomplete', 'off');
159
+
160
+ that.killerFn = function (e) {
161
+ if ($(e.target).closest('.' + that.options.containerClass).length === 0) {
162
+ that.killSuggestions();
163
+ that.disableKillerFn();
164
+ }
165
+ };
166
+
167
+ // html() deals with many types: htmlString or Element or Array or jQuery
168
+ that.noSuggestionsContainer = $('<div class="autocomplete-no-suggestion"></div>')
169
+ .html(this.options.noSuggestionNotice).get(0);
170
+
171
+ that.suggestionsContainer = Autocomplete.utils.createNode(options.containerClass);
172
+
173
+ container = $(that.suggestionsContainer);
174
+
175
+ container.appendTo(options.appendTo);
176
+
177
+ // Only set width if it was provided:
178
+ if (options.width !== 'auto') {
179
+ container.width(options.width);
180
+ }
181
+
182
+ // Listen for mouse over event on suggestions list:
183
+ container.on('mouseover.autocomplete', suggestionSelector, function () {
184
+ that.activate($(this).data('index'));
185
+ });
186
+
187
+ // Deselect active element when mouse leaves suggestions container:
188
+ container.on('mouseout.autocomplete', function () {
189
+ that.selectedIndex = -1;
190
+ container.children('.' + selected).removeClass(selected);
191
+ });
192
+
193
+ // Listen for click event on suggestions list:
194
+ container.on('click.autocomplete', suggestionSelector, function () {
195
+ that.select($(this).data('index'));
196
+ });
197
+
198
+ that.fixPositionCapture = function () {
199
+ if (that.visible) {
200
+ that.fixPosition();
201
+ }
202
+ };
203
+
204
+ $(window).on('resize.autocomplete', that.fixPositionCapture);
205
+
206
+ that.el.on('keydown.autocomplete', function (e) { that.onKeyPress(e); });
207
+ that.el.on('keyup.autocomplete', function (e) { that.onKeyUp(e); });
208
+ that.el.on('blur.autocomplete', function () { that.onBlur(); });
209
+ that.el.on('focus.autocomplete', function () { that.onFocus(); });
210
+ that.el.on('change.autocomplete', function (e) { that.onKeyUp(e); });
211
+ that.el.on('input.autocomplete', function (e) { that.onKeyUp(e); });
212
+ },
213
+
214
+ onFocus: function () {
215
+ var that = this;
216
+
217
+ that.fixPosition();
218
+
219
+ if (that.el.val().length >= that.options.minChars) {
220
+ that.onValueChange();
221
+ }
222
+ },
223
+
224
+ onBlur: function () {
225
+ this.enableKillerFn();
226
+ },
227
+
228
+ abortAjax: function () {
229
+ var that = this;
230
+ if (that.currentRequest) {
231
+ that.currentRequest.abort();
232
+ that.currentRequest = null;
233
+ }
234
+ },
235
+
236
+ setOptions: function (suppliedOptions) {
237
+ var that = this,
238
+ options = that.options;
239
+
240
+ $.extend(options, suppliedOptions);
241
+
242
+ that.isLocal = $.isArray(options.lookup);
243
+
244
+ if (that.isLocal) {
245
+ options.lookup = that.verifySuggestionsFormat(options.lookup);
246
+ }
247
+
248
+ options.orientation = that.validateOrientation(options.orientation, 'bottom');
249
+
250
+ // Adjust height, width and z-index:
251
+ $(that.suggestionsContainer).css({
252
+ 'max-height': options.maxHeight + 'px',
253
+ 'width': options.width + 'px',
254
+ 'z-index': options.zIndex
255
+ });
256
+ },
257
+
258
+
259
+ clearCache: function () {
260
+ this.cachedResponse = {};
261
+ this.badQueries = [];
262
+ },
263
+
264
+ clear: function () {
265
+ this.clearCache();
266
+ this.currentValue = '';
267
+ this.suggestions = [];
268
+ },
269
+
270
+ disable: function () {
271
+ var that = this;
272
+ that.disabled = true;
273
+ clearInterval(that.onChangeInterval);
274
+ that.abortAjax();
275
+ },
276
+
277
+ enable: function () {
278
+ this.disabled = false;
279
+ },
280
+
281
+ fixPosition: function () {
282
+ // Use only when container has already its content
283
+
284
+ var that = this,
285
+ $container = $(that.suggestionsContainer),
286
+ containerParent = $container.parent().get(0);
287
+ // Fix position automatically when appended to body.
288
+ // In other cases force parameter must be given.
289
+ if (containerParent !== document.body && !that.options.forceFixPosition) {
290
+ return;
291
+ }
292
+
293
+ // Choose orientation
294
+ var orientation = that.options.orientation,
295
+ containerHeight = $container.outerHeight(),
296
+ height = that.el.outerHeight(),
297
+ offset = that.el.offset(),
298
+ styles = { 'top': offset.top, 'left': offset.left };
299
+
300
+ if (orientation === 'auto') {
301
+ var viewPortHeight = $(window).height(),
302
+ scrollTop = $(window).scrollTop(),
303
+ topOverflow = -scrollTop + offset.top - containerHeight,
304
+ bottomOverflow = scrollTop + viewPortHeight - (offset.top + height + containerHeight);
305
+
306
+ orientation = (Math.max(topOverflow, bottomOverflow) === topOverflow) ? 'top' : 'bottom';
307
+ }
308
+
309
+ if (orientation === 'top') {
310
+ styles.top += -containerHeight;
311
+ } else {
312
+ styles.top += height;
313
+ }
314
+
315
+ // If container is not positioned to body,
316
+ // correct its position using offset parent offset
317
+ if(containerParent !== document.body) {
318
+ var opacity = $container.css('opacity'),
319
+ parentOffsetDiff;
320
+
321
+ if (!that.visible){
322
+ $container.css('opacity', 0).show();
323
+ }
324
+
325
+ parentOffsetDiff = $container.offsetParent().offset();
326
+ styles.top -= parentOffsetDiff.top;
327
+ styles.left -= parentOffsetDiff.left;
328
+
329
+ if (!that.visible){
330
+ $container.css('opacity', opacity).hide();
331
+ }
332
+ }
333
+
334
+ // -2px to account for suggestions border.
335
+ if (that.options.width === 'auto') {
336
+ styles.width = (that.el.outerWidth() - 2) + 'px';
337
+ }
338
+
339
+ $container.css(styles);
340
+ },
341
+
342
+ enableKillerFn: function () {
343
+ var that = this;
344
+ $(document).on('click.autocomplete', that.killerFn);
345
+ },
346
+
347
+ disableKillerFn: function () {
348
+ var that = this;
349
+ $(document).off('click.autocomplete', that.killerFn);
350
+ },
351
+
352
+ killSuggestions: function () {
353
+ var that = this;
354
+ that.stopKillSuggestions();
355
+ that.intervalId = window.setInterval(function () {
356
+ if (that.visible) {
357
+ that.el.val(that.currentValue);
358
+ that.hide();
359
+ }
360
+
361
+ that.stopKillSuggestions();
362
+ }, 50);
363
+ },
364
+
365
+ stopKillSuggestions: function () {
366
+ window.clearInterval(this.intervalId);
367
+ },
368
+
369
+ isCursorAtEnd: function () {
370
+ var that = this,
371
+ valLength = that.el.val().length,
372
+ selectionStart = that.element.selectionStart,
373
+ range;
374
+
375
+ if (typeof selectionStart === 'number') {
376
+ return selectionStart === valLength;
377
+ }
378
+ if (document.selection) {
379
+ range = document.selection.createRange();
380
+ range.moveStart('character', -valLength);
381
+ return valLength === range.text.length;
382
+ }
383
+ return true;
384
+ },
385
+
386
+ onKeyPress: function (e) {
387
+ var that = this;
388
+
389
+ // If suggestions are hidden and user presses arrow down, display suggestions:
390
+ if (!that.disabled && !that.visible && e.which === keys.DOWN && that.currentValue) {
391
+ that.suggest();
392
+ return;
393
+ }
394
+
395
+ if (that.disabled || !that.visible) {
396
+ return;
397
+ }
398
+
399
+ switch (e.which) {
400
+ case keys.ESC:
401
+ that.el.val(that.currentValue);
402
+ that.hide();
403
+ break;
404
+ case keys.RIGHT:
405
+ if (that.hint && that.options.onHint && that.isCursorAtEnd()) {
406
+ that.selectHint();
407
+ break;
408
+ }
409
+ return;
410
+ case keys.TAB:
411
+ if (that.hint && that.options.onHint) {
412
+ that.selectHint();
413
+ return;
414
+ }
415
+ if (that.selectedIndex === -1) {
416
+ that.hide();
417
+ return;
418
+ }
419
+ that.select(that.selectedIndex);
420
+ if (that.options.tabDisabled === false) {
421
+ return;
422
+ }
423
+ break;
424
+ case keys.RETURN:
425
+ if (that.selectedIndex === -1) {
426
+ that.hide();
427
+ return;
428
+ }
429
+ that.select(that.selectedIndex);
430
+ break;
431
+ case keys.UP:
432
+ that.moveUp();
433
+ break;
434
+ case keys.DOWN:
435
+ that.moveDown();
436
+ break;
437
+ default:
438
+ return;
439
+ }
440
+
441
+ // Cancel event if function did not return:
442
+ e.stopImmediatePropagation();
443
+ e.preventDefault();
444
+ },
445
+
446
+ onKeyUp: function (e) {
447
+ var that = this;
448
+
449
+ if (that.disabled) {
450
+ return;
451
+ }
452
+
453
+ switch (e.which) {
454
+ case keys.UP:
455
+ case keys.DOWN:
456
+ return;
457
+ }
458
+
459
+ clearInterval(that.onChangeInterval);
460
+
461
+ if (that.currentValue !== that.el.val()) {
462
+ that.findBestHint();
463
+ if (that.options.deferRequestBy > 0) {
464
+ // Defer lookup in case when value changes very quickly:
465
+ that.onChangeInterval = setInterval(function () {
466
+ that.onValueChange();
467
+ }, that.options.deferRequestBy);
468
+ } else {
469
+ that.onValueChange();
470
+ }
471
+ }
472
+ },
473
+
474
+ onValueChange: function () {
475
+ var that = this,
476
+ options = that.options,
477
+ value = that.el.val(),
478
+ query = that.getQuery(value);
479
+
480
+ if (that.selection && that.currentValue !== query) {
481
+ that.selection = null;
482
+ (options.onInvalidateSelection || $.noop).call(that.element);
483
+ }
484
+
485
+ clearInterval(that.onChangeInterval);
486
+ that.currentValue = value;
487
+ that.selectedIndex = -1;
488
+
489
+ // Check existing suggestion for the match before proceeding:
490
+ if (options.triggerSelectOnValidInput && that.isExactMatch(query)) {
491
+ that.select(0);
492
+ return;
493
+ }
494
+
495
+ if (query.length < options.minChars) {
496
+ that.hide();
497
+ } else {
498
+ that.getSuggestions(query);
499
+ }
500
+ },
501
+
502
+ isExactMatch: function (query) {
503
+ var suggestions = this.suggestions;
504
+
505
+ return (suggestions.length === 1 && suggestions[0].value.toLowerCase() === query.toLowerCase());
506
+ },
507
+
508
+ getQuery: function (value) {
509
+ var delimiter = this.options.delimiter,
510
+ parts;
511
+
512
+ if (!delimiter) {
513
+ return value;
514
+ }
515
+ parts = value.split(delimiter);
516
+ return $.trim(parts[parts.length - 1]);
517
+ },
518
+
519
+ getSuggestionsLocal: function (query) {
520
+ var that = this,
521
+ options = that.options,
522
+ queryLowerCase = query.toLowerCase(),
523
+ filter = options.lookupFilter,
524
+ limit = parseInt(options.lookupLimit, 10),
525
+ data;
526
+
527
+ data = {
528
+ suggestions: $.grep(options.lookup, function (suggestion) {
529
+ return filter(suggestion, query, queryLowerCase);
530
+ })
531
+ };
532
+
533
+ if (limit && data.suggestions.length > limit) {
534
+ data.suggestions = data.suggestions.slice(0, limit);
535
+ }
536
+
537
+ return data;
538
+ },
539
+
540
+ getSuggestions: function (q) {
541
+ var response,
542
+ that = this,
543
+ options = that.options,
544
+ serviceUrl = options.serviceUrl,
545
+ params,
546
+ cacheKey,
547
+ ajaxSettings;
548
+
549
+ options.params[options.paramName] = q;
550
+ params = options.ignoreParams ? null : options.params;
551
+
552
+ if (options.onSearchStart.call(that.element, options.params) === false) {
553
+ return;
554
+ }
555
+
556
+ if ($.isFunction(options.lookup)){
557
+ options.lookup(q, function (data) {
558
+ that.suggestions = data.suggestions;
559
+ that.suggest();
560
+ options.onSearchComplete.call(that.element, q, data.suggestions);
561
+ });
562
+ return;
563
+ }
564
+
565
+ if (that.isLocal) {
566
+ response = that.getSuggestionsLocal(q);
567
+ } else {
568
+ if ($.isFunction(serviceUrl)) {
569
+ serviceUrl = serviceUrl.call(that.element, q);
570
+ }
571
+ cacheKey = serviceUrl + '?' + $.param(params || {});
572
+ response = that.cachedResponse[cacheKey];
573
+ }
574
+
575
+ if (response && $.isArray(response.suggestions)) {
576
+ that.suggestions = response.suggestions;
577
+ that.suggest();
578
+ options.onSearchComplete.call(that.element, q, response.suggestions);
579
+ } else if (!that.isBadQuery(q)) {
580
+ that.abortAjax();
581
+
582
+ ajaxSettings = {
583
+ url: serviceUrl,
584
+ data: params,
585
+ type: options.type,
586
+ dataType: options.dataType
587
+ };
588
+
589
+ $.extend(ajaxSettings, options.ajaxSettings);
590
+
591
+ that.currentRequest = $.ajax(ajaxSettings).done(function (data) {
592
+ var result;
593
+ that.currentRequest = null;
594
+ result = options.transformResult(data, q);
595
+ that.processResponse(result, q, cacheKey);
596
+ options.onSearchComplete.call(that.element, q, result.suggestions);
597
+ }).fail(function (jqXHR, textStatus, errorThrown) {
598
+ options.onSearchError.call(that.element, q, jqXHR, textStatus, errorThrown);
599
+ });
600
+ } else {
601
+ options.onSearchComplete.call(that.element, q, []);
602
+ }
603
+ },
604
+
605
+ isBadQuery: function (q) {
606
+ if (!this.options.preventBadQueries){
607
+ return false;
608
+ }
609
+
610
+ var badQueries = this.badQueries,
611
+ i = badQueries.length;
612
+
613
+ while (i--) {
614
+ if (q.indexOf(badQueries[i]) === 0) {
615
+ return true;
616
+ }
617
+ }
618
+
619
+ return false;
620
+ },
621
+
622
+ hide: function () {
623
+ var that = this,
624
+ container = $(that.suggestionsContainer);
625
+
626
+ if ($.isFunction(that.options.onHide) && that.visible) {
627
+ that.options.onHide.call(that.element, container);
628
+ }
629
+
630
+ that.visible = false;
631
+ that.selectedIndex = -1;
632
+ clearInterval(that.onChangeInterval);
633
+ $(that.suggestionsContainer).hide();
634
+ that.signalHint(null);
635
+ },
636
+
637
+ suggest: function () {
638
+ if (this.suggestions.length === 0) {
639
+ if (this.options.showNoSuggestionNotice) {
640
+ this.noSuggestions();
641
+ } else {
642
+ this.hide();
643
+ }
644
+ return;
645
+ }
646
+
647
+ var that = this,
648
+ options = that.options,
649
+ groupBy = options.groupBy,
650
+ formatResult = options.formatResult,
651
+ value = that.getQuery(that.currentValue),
652
+ className = that.classes.suggestion,
653
+ classSelected = that.classes.selected,
654
+ container = $(that.suggestionsContainer),
655
+ noSuggestionsContainer = $(that.noSuggestionsContainer),
656
+ beforeRender = options.beforeRender,
657
+ html = '',
658
+ category,
659
+ formatGroup = function (suggestion, index) {
660
+ var currentCategory = suggestion.data[groupBy];
661
+
662
+ if (category === currentCategory){
663
+ return '';
664
+ }
665
+
666
+ category = currentCategory;
667
+
668
+ return '<div class="autocomplete-group"><strong>' + category + '</strong></div>';
669
+ };
670
+
671
+ if (options.triggerSelectOnValidInput && that.isExactMatch(value)) {
672
+ that.select(0);
673
+ return;
674
+ }
675
+
676
+ // Build suggestions inner HTML:
677
+ $.each(that.suggestions, function (i, suggestion) {
678
+ if (groupBy){
679
+ html += formatGroup(suggestion, value, i);
680
+ }
681
+
682
+ html += '<div class="' + className + '" data-index="' + i + '">' + formatResult(suggestion, value) + '</div>';
683
+ });
684
+
685
+ this.adjustContainerWidth();
686
+
687
+ noSuggestionsContainer.detach();
688
+ container.html(html);
689
+
690
+ if ($.isFunction(beforeRender)) {
691
+ beforeRender.call(that.element, container);
692
+ }
693
+
694
+ that.fixPosition();
695
+ container.show();
696
+
697
+ // Select first value by default:
698
+ if (options.autoSelectFirst) {
699
+ that.selectedIndex = 0;
700
+ container.scrollTop(0);
701
+ container.children('.' + className).first().addClass(classSelected);
702
+ }
703
+
704
+ that.visible = true;
705
+ that.findBestHint();
706
+ },
707
+
708
+ noSuggestions: function() {
709
+ var that = this,
710
+ container = $(that.suggestionsContainer),
711
+ noSuggestionsContainer = $(that.noSuggestionsContainer);
712
+
713
+ this.adjustContainerWidth();
714
+
715
+ // Some explicit steps. Be careful here as it easy to get
716
+ // noSuggestionsContainer removed from DOM if not detached properly.
717
+ noSuggestionsContainer.detach();
718
+ container.empty(); // clean suggestions if any
719
+ container.append(noSuggestionsContainer);
720
+
721
+ that.fixPosition();
722
+
723
+ container.show();
724
+ that.visible = true;
725
+ },
726
+
727
+ adjustContainerWidth: function() {
728
+ var that = this,
729
+ options = that.options,
730
+ width,
731
+ container = $(that.suggestionsContainer);
732
+
733
+ // If width is auto, adjust width before displaying suggestions,
734
+ // because if instance was created before input had width, it will be zero.
735
+ // Also it adjusts if input width has changed.
736
+ // -2px to account for suggestions border.
737
+ if (options.width === 'auto') {
738
+ width = that.el.outerWidth() - 2;
739
+ container.width(width > 0 ? width : 300);
740
+ }
741
+ },
742
+
743
+ findBestHint: function () {
744
+ var that = this,
745
+ value = that.el.val().toLowerCase(),
746
+ bestMatch = null;
747
+
748
+ if (!value) {
749
+ return;
750
+ }
751
+
752
+ $.each(that.suggestions, function (i, suggestion) {
753
+ var foundMatch = suggestion.value.toLowerCase().indexOf(value) === 0;
754
+ if (foundMatch) {
755
+ bestMatch = suggestion;
756
+ }
757
+ return !foundMatch;
758
+ });
759
+
760
+ that.signalHint(bestMatch);
761
+ },
762
+
763
+ signalHint: function (suggestion) {
764
+ var hintValue = '',
765
+ that = this;
766
+ if (suggestion) {
767
+ hintValue = that.currentValue + suggestion.value.substr(that.currentValue.length);
768
+ }
769
+ if (that.hintValue !== hintValue) {
770
+ that.hintValue = hintValue;
771
+ that.hint = suggestion;
772
+ (this.options.onHint || $.noop)(hintValue);
773
+ }
774
+ },
775
+
776
+ verifySuggestionsFormat: function (suggestions) {
777
+ // If suggestions is string array, convert them to supported format:
778
+ if (suggestions.length && typeof suggestions[0] === 'string') {
779
+ return $.map(suggestions, function (value) {
780
+ return { value: value, data: null };
781
+ });
782
+ }
783
+
784
+ return suggestions;
785
+ },
786
+
787
+ validateOrientation: function(orientation, fallback) {
788
+ orientation = $.trim(orientation || '').toLowerCase();
789
+
790
+ if($.inArray(orientation, ['auto', 'bottom', 'top']) === -1){
791
+ orientation = fallback;
792
+ }
793
+
794
+ return orientation;
795
+ },
796
+
797
+ processResponse: function (result, originalQuery, cacheKey) {
798
+ var that = this,
799
+ options = that.options;
800
+
801
+ result.suggestions = that.verifySuggestionsFormat(result.suggestions);
802
+
803
+ // Cache results if cache is not disabled:
804
+ if (!options.noCache) {
805
+ that.cachedResponse[cacheKey] = result;
806
+ if (options.preventBadQueries && result.suggestions.length === 0) {
807
+ that.badQueries.push(originalQuery);
808
+ }
809
+ }
810
+
811
+ // Return if originalQuery is not matching current query:
812
+ if (originalQuery !== that.getQuery(that.currentValue)) {
813
+ return;
814
+ }
815
+
816
+ that.suggestions = result.suggestions;
817
+ that.suggest();
818
+ },
819
+
820
+ activate: function (index) {
821
+ var that = this,
822
+ activeItem,
823
+ selected = that.classes.selected,
824
+ container = $(that.suggestionsContainer),
825
+ children = container.find('.' + that.classes.suggestion);
826
+
827
+ container.find('.' + selected).removeClass(selected);
828
+
829
+ that.selectedIndex = index;
830
+
831
+ if (that.selectedIndex !== -1 && children.length > that.selectedIndex) {
832
+ activeItem = children.get(that.selectedIndex);
833
+ $(activeItem).addClass(selected);
834
+ return activeItem;
835
+ }
836
+
837
+ return null;
838
+ },
839
+
840
+ selectHint: function () {
841
+ var that = this,
842
+ i = $.inArray(that.hint, that.suggestions);
843
+
844
+ that.select(i);
845
+ },
846
+
847
+ select: function (i) {
848
+ var that = this;
849
+ that.hide();
850
+ that.onSelect(i);
851
+ },
852
+
853
+ moveUp: function () {
854
+ var that = this;
855
+
856
+ if (that.selectedIndex === -1) {
857
+ return;
858
+ }
859
+
860
+ if (that.selectedIndex === 0) {
861
+ $(that.suggestionsContainer).children().first().removeClass(that.classes.selected);
862
+ that.selectedIndex = -1;
863
+ that.el.val(that.currentValue);
864
+ that.findBestHint();
865
+ return;
866
+ }
867
+
868
+ that.adjustScroll(that.selectedIndex - 1);
869
+ },
870
+
871
+ moveDown: function () {
872
+ var that = this;
873
+
874
+ if (that.selectedIndex === (that.suggestions.length - 1)) {
875
+ return;
876
+ }
877
+
878
+ that.adjustScroll(that.selectedIndex + 1);
879
+ },
880
+
881
+ adjustScroll: function (index) {
882
+ var that = this,
883
+ activeItem = that.activate(index);
884
+
885
+ if (!activeItem) {
886
+ return;
887
+ }
888
+
889
+ var offsetTop,
890
+ upperBound,
891
+ lowerBound,
892
+ heightDelta = $(activeItem).outerHeight();
893
+
894
+ offsetTop = activeItem.offsetTop;
895
+ upperBound = $(that.suggestionsContainer).scrollTop();
896
+ lowerBound = upperBound + that.options.maxHeight - heightDelta;
897
+
898
+ if (offsetTop < upperBound) {
899
+ $(that.suggestionsContainer).scrollTop(offsetTop);
900
+ } else if (offsetTop > lowerBound) {
901
+ $(that.suggestionsContainer).scrollTop(offsetTop - that.options.maxHeight + heightDelta);
902
+ }
903
+
904
+ if (!that.options.preserveInput) {
905
+ that.el.val(that.getValue(that.suggestions[index].value));
906
+ }
907
+ that.signalHint(null);
908
+ },
909
+
910
+ onSelect: function (index) {
911
+ var that = this,
912
+ onSelectCallback = that.options.onSelect,
913
+ suggestion = that.suggestions[index];
914
+
915
+ that.currentValue = that.getValue(suggestion.value);
916
+
917
+ if (that.currentValue !== that.el.val() && !that.options.preserveInput) {
918
+ that.el.val(that.currentValue);
919
+ }
920
+
921
+ that.signalHint(null);
922
+ that.suggestions = [];
923
+ that.selection = suggestion;
924
+
925
+ if ($.isFunction(onSelectCallback)) {
926
+ onSelectCallback.call(that.element, suggestion);
927
+ }
928
+ },
929
+
930
+ getValue: function (value) {
931
+ var that = this,
932
+ delimiter = that.options.delimiter,
933
+ currentValue,
934
+ parts;
935
+
936
+ if (!delimiter) {
937
+ return value;
938
+ }
939
+
940
+ currentValue = that.currentValue;
941
+ parts = currentValue.split(delimiter);
942
+
943
+ if (parts.length === 1) {
944
+ return value;
945
+ }
946
+
947
+ return currentValue.substr(0, currentValue.length - parts[parts.length - 1].length) + value;
948
+ },
949
+
950
+ dispose: function () {
951
+ var that = this;
952
+ that.el.off('.autocomplete').removeData('autocomplete');
953
+ that.disableKillerFn();
954
+ $(window).off('resize.autocomplete', that.fixPositionCapture);
955
+ $(that.suggestionsContainer).remove();
956
+ }
957
+ };
958
+
959
+ // Create chainable jQuery plugin:
960
+ $.fn.autocomplete = $.fn.devbridgeAutocomplete = function (options, args) {
961
+ var dataKey = 'autocomplete';
962
+ // If function invoked without argument return
963
+ // instance of the first matched element:
964
+ if (arguments.length === 0) {
965
+ return this.first().data(dataKey);
966
+ }
967
+
968
+ return this.each(function () {
969
+ var inputElement = $(this),
970
+ instance = inputElement.data(dataKey);
971
+
972
+ if (typeof options === 'string') {
973
+ if (instance && typeof instance[options] === 'function') {
974
+ instance[options](args);
975
+ }
976
+ } else {
977
+ // If instance already exists, destroy it:
978
+ if (instance && instance.dispose) {
979
+ instance.dispose();
980
+ }
981
+ instance = new Autocomplete(this, options);
982
+ inputElement.data(dataKey, instance);
983
+ }
984
+ });
985
+ };
986
+ }));