rbbt-rest 1.1.5 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. checksums.yaml +8 -8
  2. data/lib/rbbt/rest/common/cache.rb +33 -14
  3. data/lib/rbbt/rest/common/locate.rb +8 -6
  4. data/lib/rbbt/rest/common/misc.rb +4 -0
  5. data/lib/rbbt/rest/common/render.rb +14 -4
  6. data/lib/rbbt/rest/common/resources.rb +1 -1
  7. data/lib/rbbt/rest/common/table.rb +37 -7
  8. data/lib/rbbt/rest/entity.rb +5 -3
  9. data/lib/rbbt/rest/entity/favourites.rb +4 -1
  10. data/lib/rbbt/rest/entity/helpers.rb +12 -0
  11. data/lib/rbbt/rest/entity/rest.rb +6 -2
  12. data/lib/rbbt/rest/helpers.rb +7 -0
  13. data/lib/rbbt/rest/knowledge_base.rb +338 -0
  14. data/lib/rbbt/rest/knowledge_base/helpers.rb +57 -0
  15. data/lib/rbbt/rest/main.rb +16 -3
  16. data/share/views/compass/_rbbt.sass +11 -0
  17. data/share/views/compass/actions.sass +48 -24
  18. data/share/views/compass/app.sass +72 -50
  19. data/share/views/compass/colors.sass +3 -229
  20. data/share/views/compass/entity_card.sass +44 -108
  21. data/share/views/compass/favourites.sass +17 -72
  22. data/share/views/compass/finder.sass +30 -0
  23. data/share/views/compass/foundation.sass +79 -0
  24. data/share/views/compass/functions.sass +27 -0
  25. data/share/views/compass/help.sass +3 -0
  26. data/share/views/compass/layout.sass +132 -0
  27. data/share/views/compass/rbbt/form.sass +84 -0
  28. data/share/views/compass/rbbt/fragment.sass +7 -0
  29. data/share/views/compass/rbbt/menu.sass +189 -0
  30. data/share/views/compass/rbbt/reveal.sass +46 -0
  31. data/share/views/compass/rbbt/table.sass +169 -0
  32. data/share/views/compass/skeleton.sass +2 -0
  33. data/share/views/compass/skeleton/_dependencies.sass +151 -0
  34. data/share/views/compass/skeleton/_functions.sass +4 -0
  35. data/share/views/compass/skeleton/_mixins.sass +25 -0
  36. data/share/views/compass/skeleton/_vars.sass +72 -0
  37. data/share/views/compass/skeleton/base.sass +333 -0
  38. data/share/views/compass/skeleton/layout.sass +51 -0
  39. data/share/views/compass/skeleton/skeleton.sass +105 -0
  40. data/share/views/compass/solarized.sass +56 -0
  41. data/share/views/compass/style.sass +2 -116
  42. data/share/views/compass/theme.sass +57 -44
  43. data/share/views/compass/top_menu.sass +121 -0
  44. data/share/views/compass/user.sass +7 -0
  45. data/share/views/compass/variables.sass +7 -0
  46. data/share/views/compass/workflow.sass +6 -14
  47. data/share/views/entity_partials/action_controller.haml +7 -4
  48. data/share/views/entity_partials/entity_card.haml +10 -5
  49. data/share/views/entity_partials/entity_list.haml +4 -7
  50. data/share/views/entity_partials/entity_list_card.haml +10 -3
  51. data/share/views/entity_partials/entity_map_card.haml +2 -2
  52. data/share/views/entity_partials/list_container.haml +31 -26
  53. data/share/views/error.haml +5 -7
  54. data/share/views/help.haml +75 -31
  55. data/share/views/help/entity.haml +191 -193
  56. data/share/views/help/workflow.haml +59 -63
  57. data/share/views/job_result.haml +23 -26
  58. data/share/views/layout.haml +41 -61
  59. data/share/views/layout/top_menu.haml +19 -0
  60. data/share/views/layout/top_menu/favourites.haml +45 -0
  61. data/share/views/layout/top_menu/finder.haml +4 -0
  62. data/share/views/layout/top_menu/user.haml +15 -0
  63. data/share/views/public/js/_ajax_replace.js +17 -5
  64. data/share/views/public/js/_ellipsis.js +7 -9
  65. data/share/views/public/js/app.js +50 -2
  66. data/share/views/public/js/foundation/foundation.abide.js +194 -0
  67. data/share/views/public/js/foundation/foundation.alerts.js +52 -0
  68. data/share/views/public/js/foundation/foundation.clearing.js +516 -0
  69. data/share/views/public/js/foundation/foundation.cookie.js +74 -0
  70. data/share/views/public/js/foundation/foundation.dropdown.js +177 -0
  71. data/share/views/public/js/foundation/foundation.forms.js +533 -0
  72. data/share/views/public/js/foundation/foundation.interchange.js +280 -0
  73. data/share/views/public/js/foundation/foundation.joyride.js +850 -0
  74. data/share/views/public/js/foundation/foundation.js +440 -0
  75. data/share/views/public/js/foundation/foundation.magellan.js +135 -0
  76. data/share/views/public/js/foundation/foundation.orbit.js +412 -0
  77. data/share/views/public/js/foundation/foundation.placeholder.js +179 -0
  78. data/share/views/public/js/foundation/foundation.reveal.js +330 -0
  79. data/share/views/public/js/foundation/foundation.section.js +400 -0
  80. data/share/views/public/js/foundation/foundation.tooltips.js +208 -0
  81. data/share/views/public/js/foundation/foundation.topbar.js +300 -0
  82. data/share/views/public/js/foundation/index.js +18 -0
  83. data/share/views/public/js/helpers.js +33 -2
  84. data/share/views/public/js/jquery-ui.js +313 -0
  85. data/share/views/public/js/rbbt/actions.js +264 -0
  86. data/share/views/public/js/{_dom_update.js → rbbt/dom_update.js} +0 -0
  87. data/share/views/public/js/rbbt/favourites.js +425 -0
  88. data/share/views/public/js/rbbt/fragment.js +13 -0
  89. data/share/views/public/js/rbbt/hide.js +60 -0
  90. data/share/views/public/js/rbbt/list.js +117 -0
  91. data/share/views/public/js/{maps.js → rbbt/map.js} +3 -2
  92. data/share/views/public/js/rbbt/menu.js +22 -0
  93. data/share/views/public/js/rbbt/modal.js +96 -0
  94. data/share/views/public/js/{entities.js → rbbt/page_type.js} +12 -9
  95. data/share/views/public/js/rbbt/reveal.js +19 -0
  96. data/share/views/public/js/rbbt/table.js +283 -0
  97. data/share/views/public/js/{workflow.js → rbbt/workflow.js} +0 -0
  98. data/share/views/tasks.haml +14 -15
  99. data/share/views/wait.haml +11 -12
  100. metadata +62 -33
  101. data/share/views/compass/_foundation_setup.sass +0 -74
  102. data/share/views/compass/dom.sass +0 -32
  103. data/share/views/compass/footer.sass +0 -4
  104. data/share/views/compass/form.sass +0 -41
  105. data/share/views/compass/fragment.sass +0 -8
  106. data/share/views/compass/list_container.sass +0 -34
  107. data/share/views/compass/lists.sass +0 -33
  108. data/share/views/compass/offcanvas.sass +0 -66
  109. data/share/views/compass/responsive_table.sass +0 -80
  110. data/share/views/compass/reveal.sass +0 -31
  111. data/share/views/compass/style_mixins.sass +0 -42
  112. data/share/views/compass/table.sass +0 -63
  113. data/share/views/compass/tabs.sass +0 -81
  114. data/share/views/compass/topbar.sass +0 -25
  115. data/share/views/compass/web-fonts.sass +0 -77
  116. data/share/views/layout/favourites.haml +0 -46
  117. data/share/views/layout/header.haml +0 -44
  118. data/share/views/public/js/_fix_tablesorter_science.js +0 -38
  119. data/share/views/public/js/_foundation.js +0 -42
  120. data/share/views/public/js/actions.js +0 -108
  121. data/share/views/public/js/base.js +0 -121
  122. data/share/views/public/js/favourites.js +0 -441
  123. data/share/views/public/js/lists.js +0 -117
  124. data/share/views/public/js/offcanvas.js +0 -35
  125. data/share/views/public/js/reveal.js +0 -48
  126. data/share/views/public/js/tables.js +0 -314
  127. data/share/views/public/js/tabs.js +0 -7
@@ -1,27 +1,24 @@
1
1
  - if job
2
- .row
3
- .twelve.column
4
- = workflow_partial('job_result/job_control', workflow, task, locals)
5
- .row
6
- .twelve.column
7
- - case type
8
- - when :tsv
9
- = workflow_partial('job_result/tsv', workflow, task, locals)
10
- - when :string
11
- = workflow_partial('job_result/string', workflow, task, locals)
12
- - when :integer
13
- = workflow_partial('job_result/integer', workflow, task, locals)
14
- - when :array
15
- = workflow_partial('job_result/array', workflow, task, locals)
16
- - when :boolean
17
- = workflow_partial('job_result/boolean', workflow, task, locals)
18
- - when :binary
19
- = workflow_partial('job_result/binary', workflow, task, locals)
20
- - when :annotations
21
- = workflow_partial('job_result/annotations', workflow, task, locals)
22
- - when :yaml
23
- = workflow_partial('job_result/yaml', workflow, task, locals)
24
- - when :text
25
- = workflow_partial('job_result/text', workflow, task, locals)
26
- - else
27
- - raise "Unsupported result type: #{ type }"
2
+ = workflow_partial('job_result/job_control', workflow, task, locals)
3
+
4
+ - case type
5
+ - when :tsv
6
+ = workflow_partial('job_result/tsv', workflow, task, locals)
7
+ - when :string
8
+ = workflow_partial('job_result/string', workflow, task, locals)
9
+ - when :integer
10
+ = workflow_partial('job_result/integer', workflow, task, locals)
11
+ - when :array
12
+ = workflow_partial('job_result/array', workflow, task, locals)
13
+ - when :boolean
14
+ = workflow_partial('job_result/boolean', workflow, task, locals)
15
+ - when :binary
16
+ = workflow_partial('job_result/binary', workflow, task, locals)
17
+ - when :annotations
18
+ = workflow_partial('job_result/annotations', workflow, task, locals)
19
+ - when :yaml
20
+ = workflow_partial('job_result/yaml', workflow, task, locals)
21
+ - when :text
22
+ = workflow_partial('job_result/text', workflow, task, locals)
23
+ - else
24
+ - raise "Unsupported result type: #{ type }"
@@ -6,8 +6,6 @@
6
6
  /[if IE 9 ] <html class=\"ie9\" lang=\"en\">
7
7
  /[if (gt IE 9)|!(IE)] <!--> <html lang=\"en\">
8
8
 
9
- - $zepto = false
10
-
11
9
  %head
12
10
  %meta{ :charset => "utf-8" }/
13
11
 
@@ -15,66 +13,65 @@
15
13
 
16
14
  %link{:rel => "icon", :type => "image/gif", :href => "/favicon.gif"}/
17
15
 
18
- - title = $title.dup || "Genome Scout"
19
- - case page_type.to_s
20
- - when "entity"
21
- - title << ": " << (entity.respond_to?(:name) ? entity.name || entity : entity)
22
- - when "entity_list"
23
- - title << ": " << list_id
24
- - when "entity_map"
25
- - title << ": " << map_id
26
- - when "entity_action"
27
- - title << ": " << "[#{page_action}]" # << (entity.respond_to?(:name) ? entity.name || entity : entity)
28
- - when "entity_list_action"
29
- - title << ": " << "[#{page_action}]" << list_id
30
- - when "entity_map_action"
31
- - title << ": " << "[#{page_action}]" << map_id
32
-
33
-
34
- %title= title
35
- - record_css '/stylesheets/app'
16
+ %title= $title
17
+
36
18
 
37
19
  - record_css '/plugins/zurb-icons/foundation_icons_general/stylesheets/general_foundicons.css'
20
+ - record_css '/stylesheets/app'
21
+ = serve_css
38
22
 
39
- - if $zepto
40
- - record_js "/js/zepto"
41
- - record_js '/js/deffer'
42
- = serve_js false
43
- - else
44
- - record_js '/js/deffer'
45
- = serve_js
46
- - %w(jquery-2.0.0 jquery.cookie jquery.form).each do |jquery_file|
47
- - record_js File.join('/plugins/jquery/js/', jquery_file)
48
23
 
24
+ - record_js '/js/deffer'
25
+
26
+ // Thid party frameworks
49
27
 
50
28
  - record_js "/plugins/underscore/js/underscore.js"
51
- -# %w(foundation foundation.alerts foundation.cookie foundation.forms foundation.reveal foundation.tooltips foundation.clearing foundation.dropdown foundation.joyride foundation.magellan foundation.placeholder foundation.section foundation.topbar custom.modernizr).each do |file|
52
- - %w(foundation foundation.cookie foundation.reveal foundation.dropdown foundation.section foundation.topbar custom.modernizr).each do |file|
29
+ = serve_js
30
+ - %w(jquery-2.0.0 jquery.cookie jquery.form).each do |jquery_file|
31
+ - record_js File.join('/plugins/jquery/js/', jquery_file)
32
+
33
+ - record_js '/plugins/jquery-ui/js/jquery-ui-1.8.14.custom.min.js'
34
+
35
+ -# %w(foundation foundation.cookie foundation.reveal foundation.dropdown foundation.section foundation.topbar custom.modernizr).each do |file|
53
36
  - record_js "/js/#{ file }"
54
37
 
55
- - record_js '/plugins/jquery.tablesorter/jquery.tablesorter'
38
+ -# record_js '/plugins/jquery.tablesorter/jquery.tablesorter'
56
39
  - record_js '/plugins/jquery.scrollTo/jquery.scrollTo'
57
40
 
58
- - %w(_ajax_replace _foundation _md5 _fix_tablesorter_science helpers _dom_update _ellipsis entities favourites offcanvas actions lists maps tables tabs reveal base workflow app).each do |file|
59
- - record_js "/js/#{ file }"
41
+ - %w(helpers _md5 _ajax_replace _ellipsis).each do |file|
42
+ - record_js "/js-find/#{ file }"
60
43
 
44
+ - %w(dom_update workflow menu fragment favourites page_type modal reveal actions table list map hide).each do |file|
45
+ - record_js "/js-find/rbbt/#{ file }"
61
46
 
62
- = serve_css
47
+ - %w(knowledge_base).each do |file|
48
+ - record_js "/js-find/rbbt/#{ file }"
63
49
 
64
- %body
50
+ - record_js "/js-find/app"
65
51
 
66
- #header
67
- = partial_render('layout/header')
68
52
 
69
- #body
53
+ %body
54
+
55
+ /{{{ CONTENT
56
+ /-----------
57
+ #content
70
58
  - $wait = false
71
59
  = yield
72
60
 
73
- %footer
74
- CNIO
75
61
 
62
+ /{{{ TOP MENU
63
+ /------------
64
+ #top_menu
65
+ = partial_render('layout/top_menu')
66
+
67
+
68
+ #modal
76
69
  #coda
77
70
  = serve_js
71
+ :javascript
72
+ var production = #{production? ? "true" : "false"};
73
+ start_defferred()
74
+
78
75
  - if $wait
79
76
  :javascript
80
77
  var url = window.location.toString();
@@ -84,7 +81,7 @@
84
81
  $.ajax({url: add_parameters(url, '_layout=false'), cache:false,
85
82
  success: function(data, stat, req){
86
83
  if (req.status == 202){
87
- $('#body').html(data)
84
+ $('#content').html(data)
88
85
  window.setTimeout(reload, 7000);
89
86
  }else{
90
87
  window.location = url;
@@ -93,9 +90,9 @@
93
90
 
94
91
  error:function(jqXHR, status, thrownError){
95
92
  if (undefined === jqXHR.responseText || jqXHR.responseText == ''){
96
- $('#body').html('No response. Server down?')
93
+ $('#content').html('No response. Server down?')
97
94
  }else{
98
- $('#body').html(jqXHR.responseText)
95
+ $('#content').html(jqXHR.responseText)
99
96
  }
100
97
  }})
101
98
  }
@@ -103,20 +100,3 @@
103
100
  window.setTimeout(reload, 7000);
104
101
 
105
102
 
106
- #modal1.reveal-modal
107
- .header
108
- .title
109
- .controls
110
- %a(class='link-reveal-modal')
111
- %i.foundicon-right-arrow
112
- %a(class='close-reveal-modal') x
113
- .content
114
- #modal2.reveal-modal
115
- .header
116
- .title
117
- .controls
118
- %a(class='link-reveal-modal')
119
- %i.foundicon-right-arrow
120
- %a(class='close-reveal-modal') x
121
- .content
122
-
@@ -0,0 +1,19 @@
1
+ %ul
2
+ %li.title
3
+ %a(href='/')= $title
4
+
5
+ %li.reload
6
+ %i.general.foundicon-refresh
7
+
8
+ %li.container
9
+
10
+ - if user
11
+ %li.favourites.hide(hide-title="Favs")
12
+ = partial_render('layout/top_menu/favourites')
13
+
14
+ %li.find.hide(hide-title="Find")
15
+ = partial_render('layout/top_menu/finder')
16
+
17
+ %li.user.hide(hide-title="User")
18
+ = partial_render('layout/top_menu/user')
19
+
@@ -0,0 +1,45 @@
1
+
2
+ %dl.rbbt_menu
3
+ %dt.star
4
+ %i.general.foundicon-star
5
+
6
+ %dt.next.entities Entities
7
+ %dd
8
+ %dl.rbbt_vertical_menu
9
+ -# favourite_entities.each do |type, entities|
10
+ %dt.next.type(entity_type="#{ERB::Util.url_encode(type)}")= type
11
+ %dd
12
+ %ul.entities
13
+ - entities.each do |entity|
14
+ %li
15
+ = entity.link
16
+
17
+ %dt.next.lists Lists
18
+ %dd
19
+ %dl.rbbt_vertical_menu
20
+ -# favourite_entity_lists.each do |type, lists|
21
+ %dt.next.type(entity_type="#{ERB::Util.url_encode(type)}")= type
22
+ %dd
23
+ %ul.lists
24
+ - lists.each do |list_id|
25
+ %li
26
+ %a(href="#{Entity::REST.entity_list_url(list_id, type)}")= list_id
27
+
28
+ %dt.next.maps Maps
29
+ %dd
30
+ %dl.rbbt_vertical_menu
31
+ -# favourite_entity_maps.each do |type, columns|
32
+ - columns.each do |column, maps|
33
+ %dt.next.type(entity_type="#{ERB::Util.url_encode(type)}" entity_column="#{ERB::Util.url_encode(column)}")= [type, column] * " - "
34
+ %dd
35
+ %ul.maps
36
+ - maps.each do |map_id|
37
+ %li
38
+ %a(href="#{Entity::REST.entity_map_url(map_id, type, column)}")= map_id
39
+
40
+ %dt.next.new New List
41
+ %dd
42
+ %ul.new_list
43
+ - Entity::REST::REST_ENTITIES.each do |mod|
44
+ %li
45
+ %a(href="#" data-reveal-id='modal1')= mod.to_s
@@ -0,0 +1,4 @@
1
+ %form.collapse(action='/find' method="POST")
2
+ %input(type="text" name="term")
3
+ %button.secondary.radius.button(type="submit") Find
4
+
@@ -0,0 +1,15 @@
1
+ %dl.rbbt_menu
2
+ - if user.nil?
3
+ %dt
4
+ %a(href='/login') Login
5
+ - else
6
+ %dt.next= user
7
+ %dd
8
+ %a(href='/login') Change user
9
+
10
+ %dt.next jobs
11
+ %dd
12
+ %ul.jobs
13
+
14
+ %dt
15
+ %a(href='/help') Help
@@ -61,8 +61,16 @@ function get_ajax(options, complete){
61
61
  }
62
62
  }
63
63
 
64
- console.log(options.data)
64
+ if (undefined === complete){
65
+ options.async = false
66
+ }
67
+
65
68
  response = $.ajax(options)
69
+
70
+ if (undefined !== response.responseJSON){
71
+ return response.responseJSON
72
+ }
73
+
66
74
  if (undefined !== response.responseText){
67
75
  if (response.status == 202){
68
76
  href = options.url
@@ -81,6 +89,7 @@ function get_ajax(options, complete){
81
89
  function replace_object(object, href, embedd, complete){
82
90
  if (embedd === undefined){ embedd = false; }
83
91
 
92
+ object.addClass("embedded").attr('target-href', href)
84
93
  $.ajax({
85
94
  url : href,
86
95
  cache: false,
@@ -116,7 +125,10 @@ function replace_object(object, href, embedd, complete){
116
125
  href = remove_parameter(href, '_update');
117
126
  href = remove_parameter(href, '_');
118
127
  }
119
- object.html(data).addClass("embedded").attr('target-href', href);
128
+ object.addClass("embedded").attr('target-href', href).get(0).innerHTML = data;
129
+ // eval js
130
+ object.find('script').each(function(){eval(this.text = this.text || $(this).text())} );
131
+
120
132
  capture_embedded_form(object);
121
133
  update_rbbt();
122
134
  }else{
@@ -134,13 +146,13 @@ function replace_link(link){
134
146
  replace_object(link, href);
135
147
  }
136
148
 
137
- function update_embedded(object, reload){
149
+ function update_embedded(object, reload, complete){
138
150
  var href = object.attr('target-href');
139
151
  if (reload == true){
140
152
  href = add_parameters(href, '_update=reload');
141
153
  href = add_parameters(href, '_=' + Math.random().toString());
142
154
  }
143
- replace_object(object, href, true);
155
+ replace_object(object, href, true, complete);
144
156
  }
145
157
 
146
158
 
@@ -192,7 +204,7 @@ function capture_embedded_form(object){
192
204
  url = url.replace(/\?.*/, '?' + params);
193
205
  }
194
206
 
195
- embedded.attr('target-href', url)
207
+ embedded.attr('target-href', url).attr('form-params', params)
196
208
 
197
209
  update_embedded(embedded);
198
210
 
@@ -50,13 +50,11 @@ function restore_ellipsis(elem){
50
50
  update_rbbt();
51
51
  }
52
52
 
53
- register_dom_update('a.open_ellipsis', function(link){
54
- link.click(function(){
55
- var link = $(this);
56
- var span = link.parent('span');
57
- var container = span.parent();
58
- restore_ellipsis(container);
59
-
60
- return(false);
61
- })
53
+ $('body').on('click', 'a.open_ellipsis', function(link){
54
+ var link = $(this);
55
+ var span = link.parent('span');
56
+ var container = span.parent();
57
+ restore_ellipsis(container);
58
+
59
+ return(false);
62
60
  })
@@ -1,2 +1,50 @@
1
- setup_rbbt();
2
- $(document).foundation();
1
+ function fit_content(){
2
+ var height = window.innerHeight - $('footer').outerHeight(true);
3
+ $('#content').css('min-height', height)
4
+ }
5
+
6
+ function update_rbbt(){
7
+ update_dom()
8
+
9
+ $('.rbbt_reveal_trigger').reveal()
10
+ $('table').table()
11
+ $('body > #modal').modal()
12
+ $('.action_controller').action_controller()
13
+ $('#top_menu li.favourites').favourites('update_list_selects').favourites('update_map_selects')
14
+
15
+ start_defferred()
16
+ fit_content()
17
+ }
18
+
19
+ $(function(){
20
+
21
+ register_dom_update('#top_menu > ul > li.reload', function(item){
22
+ item.click(function(){
23
+ var url = window.location.toString();
24
+ url = url.replace(/#$/, '');
25
+
26
+ url = remove_parameter(url, '_update');
27
+ url = add_parameters(url, '_update=reload');
28
+
29
+ url = remove_parameter(url, '_');
30
+ url = add_parameters(url, '_=' + Math.random().toString());
31
+
32
+ window.location = url
33
+ return false
34
+ })
35
+ })
36
+
37
+ register_dom_update('dt a.entity_list', function(link){
38
+ link.click(function(){
39
+ window.location = $(this).attr('href')
40
+ return false;
41
+ })
42
+ })
43
+
44
+ $('#top_menu li.favourites').favourites()
45
+
46
+ update_rbbt()
47
+ })
48
+
49
+ // Activate tools
50
+
@@ -0,0 +1,194 @@
1
+ /*jslint unparam: true, browser: true, indent: 2 */
2
+
3
+ ;(function ($, window, document, undefined) {
4
+ 'use strict';
5
+
6
+ Foundation.libs.abide = {
7
+ name : 'abide',
8
+
9
+ version : '4.3.0',
10
+
11
+ settings : {
12
+ live_validate : true,
13
+ focus_on_invalid : true,
14
+ timeout : 1000,
15
+ patterns : {
16
+ alpha: /[a-zA-Z]+/,
17
+ alpha_numeric : /[a-zA-Z0-9]+/,
18
+ integer: /-?\d+/,
19
+ number: /-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?/,
20
+
21
+ // generic password: upper-case, lower-case, number/special character, and min 8 characters
22
+ password : /(?=^.{8,}$)((?=.*\d)|(?=.*\W+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/,
23
+
24
+ // amex, visa, diners
25
+ card : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
26
+ cvv : /^([0-9]){3,4}$/,
27
+
28
+ // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
29
+ email : /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/,
30
+
31
+ url: /(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?/,
32
+ // abc.de
33
+ domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,6}$/,
34
+
35
+ datetime: /([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))/,
36
+ // YYYY-MM-DD
37
+ date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))/,
38
+ // HH:MM:SS
39
+ time : /(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}/,
40
+ dateISO: /\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}/,
41
+ // MM/DD/YYYY
42
+ month_day_year : /(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.](19|20)\d\d/,
43
+
44
+ // #FFF or #FFFFFF
45
+ color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
46
+ }
47
+ },
48
+
49
+ timer : null,
50
+
51
+ init : function (scope, method, options) {
52
+ if (typeof method === 'object') {
53
+ $.extend(true, this.settings, method);
54
+ }
55
+
56
+ if (typeof method !== 'string') {
57
+ if (!this.settings.init) { this.events(); }
58
+
59
+ } else {
60
+ return this[method].call(this, options);
61
+ }
62
+ },
63
+
64
+ events : function () {
65
+ var self = this,
66
+ forms = $('form[data-abide]', this.scope).attr('novalidate', 'novalidate');
67
+
68
+ forms
69
+ .on('submit validate', function (e) {
70
+ return self.validate($(this).find('input, textarea, select').get(), e);
71
+ });
72
+
73
+ this.settings.init = true;
74
+
75
+ if (!this.settings.live_validate) return;
76
+
77
+ forms
78
+ .find('input, textarea, select')
79
+ .on('blur change', function (e) {
80
+ self.validate([this], e);
81
+ })
82
+ .on('keydown', function (e) {
83
+ clearTimeout(self.timer);
84
+ self.timer = setTimeout(function () {
85
+ self.validate([this], e);
86
+ }.bind(this), self.settings.timeout);
87
+ });
88
+ },
89
+
90
+ validate : function (els, e) {
91
+ var validations = this.parse_patterns(els),
92
+ validation_count = validations.length,
93
+ form = $(els[0]).closest('form');
94
+
95
+ while (validation_count--) {
96
+ if (!validations[validation_count] && /submit/.test(e.type)) {
97
+ if (this.settings.focus_on_invalid) els[validation_count].focus();
98
+ form.trigger('invalid');
99
+ $(els[validation_count]).closest('form').attr('data-invalid', '');
100
+ return false;
101
+ }
102
+ }
103
+
104
+ if (/submit/.test(e.type)) {
105
+ form.trigger('valid');
106
+ }
107
+
108
+ form.removeAttr('data-invalid');
109
+
110
+ return true;
111
+ },
112
+
113
+ parse_patterns : function (els) {
114
+ var count = els.length,
115
+ el_patterns = [];
116
+
117
+ for (var i = count - 1; i >= 0; i--) {
118
+ el_patterns.push(this.pattern(els[i]));
119
+ }
120
+
121
+ return this.check_validation_and_apply_styles(el_patterns);
122
+ },
123
+
124
+ pattern : function (el) {
125
+ var type = el.getAttribute('type'),
126
+ required = typeof el.getAttribute('required') === 'string';
127
+
128
+ if (this.settings.patterns.hasOwnProperty(type)) {
129
+ return [el, this.settings.patterns[type], required];
130
+ }
131
+
132
+ var pattern = el.getAttribute('pattern') || '';
133
+
134
+ if (this.settings.patterns.hasOwnProperty(pattern) && pattern.length > 0) {
135
+ return [el, this.settings.patterns[pattern], required];
136
+ } else if (pattern.length > 0) {
137
+ return [el, new RegExp(pattern), required];
138
+ }
139
+
140
+ pattern = /.*/;
141
+
142
+ return [el, pattern, required];
143
+ },
144
+
145
+ check_validation_and_apply_styles : function (el_patterns) {
146
+ var count = el_patterns.length,
147
+ validations = [];
148
+
149
+ for (var i = count - 1; i >= 0; i--) {
150
+ var el = el_patterns[i][0],
151
+ required = el_patterns[i][2],
152
+ value = el.value,
153
+ is_radio = el.type === "radio",
154
+ valid_length = (required) ? (el.value.length > 0) : true;
155
+
156
+ if (is_radio && required) {
157
+ validations.push(this.valid_radio(el, required));
158
+ } else {
159
+ if (el_patterns[i][1].test(value) && valid_length ||
160
+ !required && el.value.length < 1) {
161
+ $(el).removeAttr('data-invalid').parent().removeClass('error');
162
+ validations.push(true);
163
+ } else {
164
+ $(el).attr('data-invalid', '').parent().addClass('error');
165
+ validations.push(false);
166
+ }
167
+ }
168
+ }
169
+
170
+ return validations;
171
+ },
172
+
173
+ valid_radio : function (el, required) {
174
+ var name = el.getAttribute('name'),
175
+ group = document.getElementsByName(name),
176
+ count = group.length,
177
+ valid = false;
178
+
179
+ for (var i=0; i < count; i++) {
180
+ if (group[i].checked) valid = true;
181
+ }
182
+
183
+ for (var i=0; i < count; i++) {
184
+ if (valid) {
185
+ $(group[i]).removeAttr('data-invalid').parent().removeClass('error');
186
+ } else {
187
+ $(group[i]).attr('data-invalid', '').parent().addClass('error');
188
+ }
189
+ }
190
+
191
+ return valid;
192
+ }
193
+ };
194
+ }(Foundation.zj, this, this.document));