e9_vendors 0.0.1 → 0.0.2
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.
- data/app/controllers/e9_vendors/vendor_members_controller.rb +4 -1
- data/app/decorators/vendor_member_decorator.rb +4 -4
- data/app/models/vendor_category.rb +3 -1
- data/app/views/e9_vendors/settings/_form.html.haml +5 -2
- data/config/locales/{vendorboon.en.yml → e9_vendors.en.yml} +16 -17
- data/config/routes.rb +3 -1
- data/lib/e9_vendors/version.rb +1 -1
- data/lib/generators/e9_vendors/install_generator.rb +1 -1
- data/lib/generators/e9_vendors/templates/{javascript.js → javascripts/e9_vendors.js} +0 -0
- data/lib/generators/e9_vendors/templates/javascripts/widget.js +839 -0
- metadata +4 -3
|
@@ -23,7 +23,10 @@ class E9Vendors::VendorMembersController < Admin::ResourceController
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def update
|
|
26
|
-
update!
|
|
26
|
+
update! do |success, failure|
|
|
27
|
+
success.html { redirect_to collection_path }
|
|
28
|
+
failure.html { render :edit }
|
|
29
|
+
end
|
|
27
30
|
end
|
|
28
31
|
|
|
29
32
|
def destroy
|
|
@@ -7,7 +7,7 @@ class VendorMemberDecorator < VendorsDecorator
|
|
|
7
7
|
:address_1 => model.address_1,
|
|
8
8
|
:address_2 => model.address_2,
|
|
9
9
|
:admin_notes => model.admin_notes,
|
|
10
|
-
:categories => VendorCategoryDecorator.decorate(VendorCategory.widget_visible),
|
|
10
|
+
:categories => VendorCategoryDecorator.decorate(VendorCategory.widget_visible.ordered),
|
|
11
11
|
:city => model.city,
|
|
12
12
|
:contact_email => model.contact_email,
|
|
13
13
|
:contact_full_name => model.contact_full_name,
|
|
@@ -19,9 +19,9 @@ class VendorMemberDecorator < VendorsDecorator
|
|
|
19
19
|
:state => model.state,
|
|
20
20
|
:vendors => VendorProxyDecorator.decorate(model.vendor_proxies.widget_visible),
|
|
21
21
|
:website => model.website,
|
|
22
|
-
:widget_form_text => config_render(:
|
|
23
|
-
:widget_form_title => config_render(:
|
|
24
|
-
:widget_title => config_render(:
|
|
22
|
+
:widget_form_text => config_render(:e9_vendors_widget_form_text),
|
|
23
|
+
:widget_form_title => config_render(:e9_vendors_widget_form_title),
|
|
24
|
+
:widget_title => config_render(:e9_vendors_widget_title),
|
|
25
25
|
:zipcode => model.zipcode
|
|
26
26
|
}
|
|
27
27
|
end
|
|
@@ -6,9 +6,11 @@ class VendorCategory < ActiveRecord::Base
|
|
|
6
6
|
validates :name, :presence => true
|
|
7
7
|
|
|
8
8
|
scope :widget_visible, lambda {
|
|
9
|
-
joins(:vendors => :vendor_proxies) & VendorProxy.widget_visible
|
|
9
|
+
joins(:vendors => :vendor_proxies).group('vendor_categories.id') & VendorProxy.widget_visible
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
scope :ordered, lambda { order(:position) }
|
|
13
|
+
|
|
12
14
|
# On updates, all members are touched, ensuring that widget JSON requests
|
|
13
15
|
# for the associations are pulling the most recent information
|
|
14
16
|
after_save :on => :update do
|
|
@@ -5,11 +5,14 @@
|
|
|
5
5
|
%legend
|
|
6
6
|
= help_label(:widget_settings, :e9_vendors_widget_settings, :key => :e9_vendors_widget_help, :header => 'Variable Help')
|
|
7
7
|
.field
|
|
8
|
-
= f.label :e9_vendors_widget_title
|
|
8
|
+
= f.label :e9_vendors_widget_title
|
|
9
9
|
= f.text_field :e9_vendors_widget_title
|
|
10
10
|
.field
|
|
11
|
-
= f.label :e9_vendors_widget_form_title
|
|
11
|
+
= f.label :e9_vendors_widget_form_title
|
|
12
12
|
= f.text_field :e9_vendors_widget_form_title
|
|
13
|
+
.field
|
|
14
|
+
= f.label :e9_vendors_widget_form_text
|
|
15
|
+
= f.text_area :e9_vendors_widget_form_text
|
|
13
16
|
- if e9_user?
|
|
14
17
|
.field
|
|
15
18
|
= f.label :e9_vendors_logo_size, nil, :class => :req
|
|
@@ -11,16 +11,7 @@ en:
|
|
|
11
11
|
vendor:
|
|
12
12
|
vendor_category: Category
|
|
13
13
|
discount_percentage: Default Member Discount
|
|
14
|
-
|
|
15
|
-
e9_vendors_email_to: Email To
|
|
16
|
-
e9_vendors_email_from: Email From
|
|
17
|
-
e9_vendors_email_subject: Email Subject
|
|
18
|
-
e9_vendors_email_intro: Email Introduction
|
|
19
|
-
e9_vendors_widget_title: Widget Title
|
|
20
|
-
e9_vendors_widget_form_title: Widget Form Title
|
|
21
|
-
e9_vendors_widget_form_text: Form Introduction
|
|
22
|
-
e9_vendors_widget_settings: Widget Settings
|
|
23
|
-
e9_vendors_widget_help: |
|
|
14
|
+
interpolation_instructions: |
|
|
24
15
|
<h3>Variables usable in short and long descriptions:</h3>
|
|
25
16
|
<ul>
|
|
26
17
|
<li>{{member_name}}</li>
|
|
@@ -35,7 +26,21 @@ en:
|
|
|
35
26
|
<li>{{vendor_sales_phone}}</li>
|
|
36
27
|
<li>{{vendor_sales_title}}</li>
|
|
37
28
|
</ul>
|
|
38
|
-
|
|
29
|
+
settings:
|
|
30
|
+
e9_vendors_email_to: Email To
|
|
31
|
+
e9_vendors_email_from: Email From
|
|
32
|
+
e9_vendors_email_subject: Email Subject
|
|
33
|
+
e9_vendors_email_intro: Email Introduction
|
|
34
|
+
e9_vendors_widget_title: Widget Title
|
|
35
|
+
e9_vendors_widget_form_title: Widget Subtitle
|
|
36
|
+
e9_vendors_widget_form_text: Widget Description
|
|
37
|
+
e9_vendors_widget_settings: Widget Settings
|
|
38
|
+
e9_vendors_widget_help: |
|
|
39
|
+
<h3>Variables usable in all fields:</h3>
|
|
40
|
+
<ul>
|
|
41
|
+
<li>{{member_name}}</li>
|
|
42
|
+
<li>{{member_nickname}}</li>
|
|
43
|
+
</ul>
|
|
39
44
|
e9:
|
|
40
45
|
e9_vendors:
|
|
41
46
|
vendor_members:
|
|
@@ -53,9 +58,3 @@ en:
|
|
|
53
58
|
settings:
|
|
54
59
|
index_title: Vendors Settings
|
|
55
60
|
vendorboon_widget_settings_legend: Widget Settings
|
|
56
|
-
widget_interpolation_instructions: |
|
|
57
|
-
<h3>Variables usable in all fields:</h3>
|
|
58
|
-
<ul>
|
|
59
|
-
<li>{{member_name}}</li>
|
|
60
|
-
<li>{{member_nickname}}</li>
|
|
61
|
-
</ul>
|
data/config/routes.rb
CHANGED
|
@@ -4,6 +4,8 @@ Rails.application.routes.draw do
|
|
|
4
4
|
admin_path= "admin/#{base_path}"
|
|
5
5
|
|
|
6
6
|
scope :path => admin_path, :module => :e9_vendors do
|
|
7
|
+
get :root, :to => redirect("/#{admin_path}/vendors")
|
|
8
|
+
|
|
7
9
|
resource :settings, :only => [:show, :update], :as => :e9_vendors_settings
|
|
8
10
|
|
|
9
11
|
resources :vendor_categories, :path => :categories do
|
|
@@ -34,5 +36,5 @@ Rails.application.routes.draw do
|
|
|
34
36
|
end
|
|
35
37
|
end
|
|
36
38
|
|
|
37
|
-
get "/#{base_path}/members/:id", :as => :
|
|
39
|
+
get "/#{base_path}/members/:id", :as => :public_vendor_member, :to => 'e9_vendors/vendor_members#show'
|
|
38
40
|
end
|
data/lib/e9_vendors/version.rb
CHANGED
|
File without changes
|
|
@@ -0,0 +1,839 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* e9Digital vendor widget - http://www.e9digital.com
|
|
3
|
+
* Copyright (C) 2011 e9Digital
|
|
4
|
+
* Author: Travis Cox
|
|
5
|
+
*
|
|
6
|
+
* For the documented source see http://www.e9digital.com/javascripts/vwidget.js
|
|
7
|
+
*
|
|
8
|
+
* Basic Usage:
|
|
9
|
+
<script type="text/javascript" src="http://%{Your Host}/assets/vwidget.js"></script>
|
|
10
|
+
<script type="text/javascript">
|
|
11
|
+
new E9.VWidget({
|
|
12
|
+
code: "your provided widget code"
|
|
13
|
+
}).render();
|
|
14
|
+
</script>
|
|
15
|
+
*
|
|
16
|
+
* In addition to "code" several other options are available, including callbacks
|
|
17
|
+
* which provide access to the Widget and its generated HTML, these documentation
|
|
18
|
+
* for these options can be found at the above url.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @namespace E9 VWidget public namespace
|
|
23
|
+
*/
|
|
24
|
+
E9 = window.E9 || {};
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
(function() {
|
|
28
|
+
if (E9 && E9.VWidget) return;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @constructor
|
|
32
|
+
* @param {Object} opts the configuration options for the page
|
|
33
|
+
*/
|
|
34
|
+
E9.VWidget = function(opts) {
|
|
35
|
+
this.init(opts);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
E9.VWidget.jsonP = function(url, callback) {
|
|
39
|
+
var script = document.createElement('script');
|
|
40
|
+
script.type = 'text/javascript';
|
|
41
|
+
script.src = url;
|
|
42
|
+
|
|
43
|
+
var head = document.getElementsByTagName('head')[0];
|
|
44
|
+
head.insertBefore(script, head.firstChild);
|
|
45
|
+
|
|
46
|
+
callback(script);
|
|
47
|
+
return script;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
var
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
Developed by Robert Nyman, http://www.robertnyman.com
|
|
54
|
+
Code/licensing: http://code.google.com/p/getelementsbyclassname/
|
|
55
|
+
*/
|
|
56
|
+
getElementsByClassName = function (className, tag, elm){
|
|
57
|
+
if (document.getElementsByClassName) {
|
|
58
|
+
getElementsByClassName = function (className, tag, elm) {
|
|
59
|
+
elm = elm || document;
|
|
60
|
+
var elements = elm.getElementsByClassName(className),
|
|
61
|
+
nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
|
|
62
|
+
returnElements = [],
|
|
63
|
+
current;
|
|
64
|
+
for(var i=0, il=elements.length; i<il; i+=1){
|
|
65
|
+
current = elements[i];
|
|
66
|
+
if(!nodeName || nodeName.test(current.nodeName)) {
|
|
67
|
+
returnElements.push(current);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
return returnElements;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
else if (document.evaluate) {
|
|
74
|
+
getElementsByClassName = function (className, tag, elm) {
|
|
75
|
+
tag = tag || "*";
|
|
76
|
+
elm = elm || document;
|
|
77
|
+
var classes = className.split(" "),
|
|
78
|
+
classesToCheck = "",
|
|
79
|
+
xhtmlNamespace = "http://www.w3.org/1999/xhtml",
|
|
80
|
+
namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
|
|
81
|
+
returnElements = [],
|
|
82
|
+
elements,
|
|
83
|
+
node;
|
|
84
|
+
for(var j=0, jl=classes.length; j<jl; j+=1){
|
|
85
|
+
classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
|
|
89
|
+
}
|
|
90
|
+
catch (e) {
|
|
91
|
+
elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
|
|
92
|
+
}
|
|
93
|
+
while ((node = elements.iterateNext())) {
|
|
94
|
+
returnElements.push(node);
|
|
95
|
+
}
|
|
96
|
+
return returnElements;
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
getElementsByClassName = function (className, tag, elm) {
|
|
101
|
+
tag = tag || "*";
|
|
102
|
+
elm = elm || document;
|
|
103
|
+
var classes = className.split(" "),
|
|
104
|
+
classesToCheck = [],
|
|
105
|
+
elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
|
|
106
|
+
current,
|
|
107
|
+
returnElements = [],
|
|
108
|
+
match;
|
|
109
|
+
for(var k=0, kl=classes.length; k<kl; k+=1){
|
|
110
|
+
classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
|
|
111
|
+
}
|
|
112
|
+
for(var l=0, ll=elements.length; l<ll; l+=1){
|
|
113
|
+
current = elements[l];
|
|
114
|
+
match = false;
|
|
115
|
+
for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
|
|
116
|
+
match = classesToCheck[m].test(current.className);
|
|
117
|
+
if (!match) {
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (match) {
|
|
122
|
+
returnElements.push(current);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return returnElements;
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
return getElementsByClassName(className, tag, elm);
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
// basic implementation to get the y position
|
|
132
|
+
// of an element (the page attempts to scroll to it after form completion)
|
|
133
|
+
getYPos = function(el) {
|
|
134
|
+
var pos = 0;
|
|
135
|
+
try {
|
|
136
|
+
if (el.offsetParent) {
|
|
137
|
+
do {
|
|
138
|
+
pos += el.offsetTop;
|
|
139
|
+
} while (el = el.offsetParent);
|
|
140
|
+
}
|
|
141
|
+
} catch (e) {
|
|
142
|
+
} finally {
|
|
143
|
+
return pos;
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
|
|
147
|
+
/*
|
|
148
|
+
* helper function to check if an object is "empty"
|
|
149
|
+
*/
|
|
150
|
+
isEmpty = function(obj) {
|
|
151
|
+
for(var i in obj) { if (obj.hasOwnProperty(i)){return false;}}
|
|
152
|
+
return true;
|
|
153
|
+
},
|
|
154
|
+
|
|
155
|
+
/*
|
|
156
|
+
* helper function to check for IE
|
|
157
|
+
*/
|
|
158
|
+
browser = function() {
|
|
159
|
+
var rv = 999,
|
|
160
|
+
ua = navigator.userAgent,
|
|
161
|
+
re = new RegExp("MSIE ([0-9]+[\.0-9]{0,})");
|
|
162
|
+
|
|
163
|
+
if (re.exec(ua) != null) rv = parseFloat( RegExp.$1 );
|
|
164
|
+
|
|
165
|
+
return { version: rv };
|
|
166
|
+
},
|
|
167
|
+
|
|
168
|
+
isFirebug = function() {
|
|
169
|
+
var retv = false;
|
|
170
|
+
try {
|
|
171
|
+
retv = window.hasOwnProperty('console');
|
|
172
|
+
} catch(e) {
|
|
173
|
+
} finally {
|
|
174
|
+
return retv;
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
|
|
178
|
+
head = function() {
|
|
179
|
+
return document.getElementsByTagName("head")[0];
|
|
180
|
+
},
|
|
181
|
+
|
|
182
|
+
addHeadElement = function(el) {
|
|
183
|
+
head().appendChild(el);
|
|
184
|
+
},
|
|
185
|
+
|
|
186
|
+
removeHeadElement = function(el) {
|
|
187
|
+
head().removeChild(el);
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
/*
|
|
191
|
+
* helper function to create element tags.
|
|
192
|
+
* attrs accepts a hash of attributes or a string id
|
|
193
|
+
*
|
|
194
|
+
* writes a singleton tag unless content is passed.
|
|
195
|
+
* to force a closing tag with no content, pass an empty string.
|
|
196
|
+
*/
|
|
197
|
+
tag = function(element, attrs, content) {
|
|
198
|
+
if (!attrs) attrs = {};
|
|
199
|
+
|
|
200
|
+
var html = '<' + element;
|
|
201
|
+
if (typeof attrs == 'string') {
|
|
202
|
+
html += ' id="' + attrs + '"';
|
|
203
|
+
} else {
|
|
204
|
+
for (var attr in attrs) {
|
|
205
|
+
html += ' '+attr+'="'+attrs[attr]+'"';
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (typeof content == 'string') {
|
|
210
|
+
html += '>'+content+'</' + element + '>';
|
|
211
|
+
} else {
|
|
212
|
+
html += '/>';
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return html;
|
|
216
|
+
},
|
|
217
|
+
|
|
218
|
+
/*
|
|
219
|
+
* helper function to create divs, simple interface to #tag
|
|
220
|
+
*/
|
|
221
|
+
div = function(attrs, content) {
|
|
222
|
+
return tag('div', attrs, content);
|
|
223
|
+
},
|
|
224
|
+
|
|
225
|
+
boolCheckbox = function(default_value, attrs, label) {
|
|
226
|
+
attrs['type'] = 'checkbox';
|
|
227
|
+
attrs['checked'] = 'checked';
|
|
228
|
+
attrs['value'] = '0';
|
|
229
|
+
attrs['style'] = 'display:none;visibility:hidden';
|
|
230
|
+
|
|
231
|
+
var retv = tag('input', attrs);
|
|
232
|
+
|
|
233
|
+
if (!default_value) delete attrs['checked'];
|
|
234
|
+
delete attrs['style'];
|
|
235
|
+
attrs['value'] = '1';
|
|
236
|
+
|
|
237
|
+
retv += tag('input', attrs);
|
|
238
|
+
|
|
239
|
+
if (label) retv += tag('label', {'class':'vb-label'}, label);
|
|
240
|
+
|
|
241
|
+
return retv;
|
|
242
|
+
},
|
|
243
|
+
|
|
244
|
+
timestamp = function() {
|
|
245
|
+
return new Date().getTime();
|
|
246
|
+
},
|
|
247
|
+
|
|
248
|
+
wait = function(options) {
|
|
249
|
+
options.success = options.success || function() {};
|
|
250
|
+
options.until = options.until || function() { return false; };
|
|
251
|
+
options.error = options.error || function() {};
|
|
252
|
+
options.timeout = options.timeout || 5000;
|
|
253
|
+
options.interval = options.interval || 2;
|
|
254
|
+
|
|
255
|
+
var start = timestamp(), elapsed, now;
|
|
256
|
+
|
|
257
|
+
window.setTimeout(function() {
|
|
258
|
+
now = timestamp();
|
|
259
|
+
elapsed = now - start;
|
|
260
|
+
|
|
261
|
+
if (options.until(elapsed)) {
|
|
262
|
+
options.success();
|
|
263
|
+
return false;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (now >= start + options.timeout) {
|
|
267
|
+
options.error();
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
window.setTimeout(arguments.callee, options.interval);
|
|
272
|
+
}, options.interval)
|
|
273
|
+
},
|
|
274
|
+
|
|
275
|
+
resetForm = function() {
|
|
276
|
+
var form = document.getElementById('vb-form'),
|
|
277
|
+
inputs = form.getElementsByTagName('input');
|
|
278
|
+
|
|
279
|
+
for (var i=0;i<inputs.length;i++) {
|
|
280
|
+
if(inputs[i].type == 'text') { inputs[i].value = ''; }
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
E9.VWidget.COUNT = 0;
|
|
285
|
+
E9.VWidget.ERROR_MESSAGE = '\
|
|
286
|
+
<h3 id="vb-timeout-message">Error loading content.</h3>\
|
|
287
|
+
<p>The vendor list is down for scheduled maintenance. Please check back soon.</p>';
|
|
288
|
+
|
|
289
|
+
E9.VWidget.prototype = function () {
|
|
290
|
+
var
|
|
291
|
+
|
|
292
|
+
// recaptcha key is unchangeable client side as it corresponds to
|
|
293
|
+
// the private key held on the server
|
|
294
|
+
recaptchaPublicKey = "6LfGdMASAAAAAHfYpORJWsFUtqJGM7WhxMElUMlo",
|
|
295
|
+
|
|
296
|
+
defaults = {
|
|
297
|
+
/**
|
|
298
|
+
* The url of vendorboon.
|
|
299
|
+
*
|
|
300
|
+
* This is overridable mainly for testing purposes. It is one of the
|
|
301
|
+
* two variables included in the output of the generated widget code and
|
|
302
|
+
* shouldn't be changed under normal circumstances.
|
|
303
|
+
*/
|
|
304
|
+
url: 'http://www.vendorboon.com',
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* The element ID of the div where the widget should be written.
|
|
308
|
+
*
|
|
309
|
+
* The init process first looks for an existing element by this ID.
|
|
310
|
+
* If found it will use it as the base HTML element where the widget is
|
|
311
|
+
* written. If not found, it will create it in place wherever
|
|
312
|
+
* E9.VWidget#render is called, with the ID defined here.
|
|
313
|
+
*
|
|
314
|
+
* This means there are two ways to call VWidget#render:
|
|
315
|
+
*
|
|
316
|
+
* A. Inline:
|
|
317
|
+
* <div id="foo">
|
|
318
|
+
* <script type="text/javascript">
|
|
319
|
+
* new E9.VWidget({
|
|
320
|
+
* code: 'yourcode'
|
|
321
|
+
* }).render();
|
|
322
|
+
* </script>
|
|
323
|
+
* </div>
|
|
324
|
+
*
|
|
325
|
+
* B. Deferred:
|
|
326
|
+
* <div id="foo"></div>
|
|
327
|
+
* ...
|
|
328
|
+
* <script type="text/javascript">
|
|
329
|
+
* new E9.VWidget({
|
|
330
|
+
* code: 'yourcode',
|
|
331
|
+
* elementId: 'foo'
|
|
332
|
+
* }).render();
|
|
333
|
+
* </script>
|
|
334
|
+
*
|
|
335
|
+
* In case A, the widget will be written in place where it is called.
|
|
336
|
+
* In case B, the widget will be written inside the div "foo" that
|
|
337
|
+
* already exists. In this way you could defer the loading til the end
|
|
338
|
+
* of the page, or in, for example, the jQuery.ready handler;
|
|
339
|
+
*
|
|
340
|
+
* Note that in case B, if elementId is passed but does not exist,
|
|
341
|
+
* the widget will still write itself in place, but inside an element
|
|
342
|
+
* with the ID passed.
|
|
343
|
+
*/
|
|
344
|
+
elementId: 'vb-widget-container',
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* By default the widget prepends a stylesheet link to <head> which
|
|
348
|
+
* contains widget specific styles (plus an additional IE stylesheet if
|
|
349
|
+
* an IE browser is detected).
|
|
350
|
+
*
|
|
351
|
+
* Passing this as false prevents the style load from happening.
|
|
352
|
+
*/
|
|
353
|
+
styles: true,
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* A callback which occurs at the end of the init process, before render.
|
|
357
|
+
* At this point the widget is fully configured, but waiting on initial
|
|
358
|
+
* response from the server before rendering HTML.
|
|
359
|
+
*
|
|
360
|
+
* To manipulate HTML you should not use this, but onRender
|
|
361
|
+
*
|
|
362
|
+
* @param {Function} widget The E9.VWidget instance being created
|
|
363
|
+
*/
|
|
364
|
+
onInit: function(widget) {},
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* A callback which occurs after the HTML has been rendered, immediately
|
|
368
|
+
* before it is made visible. At this point you have access to all the
|
|
369
|
+
* HTML generated by the widget, referenced by the widget property 'element'.
|
|
370
|
+
*
|
|
371
|
+
* @param {Function} widget the E9.VWidget instance being created
|
|
372
|
+
*/
|
|
373
|
+
onRender: function(widget) {},
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* Callback that occurs on timeout error. You may override this if, e.g.
|
|
377
|
+
* you wanted to change the error message or HTML.
|
|
378
|
+
*/
|
|
379
|
+
onError: function(widget) {},
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* the timeout to wait for a response from the vendorboon server before displaying
|
|
383
|
+
* an error.
|
|
384
|
+
*/
|
|
385
|
+
timeout: 10000,
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* the timeout to wait for a response from the google recaptcha server before displaying
|
|
389
|
+
* an error.
|
|
390
|
+
*/
|
|
391
|
+
recaptcha_timeout: 10000,
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* The html tag used for widget headings. The class of these elements
|
|
395
|
+
* is 'vb-heading', regardless of the tag.
|
|
396
|
+
*/
|
|
397
|
+
headingTag: 'h2',
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* The html tag used for widget subheadings. The class of these elements
|
|
401
|
+
* is 'vb-subheading', regardless of the tag.
|
|
402
|
+
*/
|
|
403
|
+
subheadingTag: 'h3',
|
|
404
|
+
|
|
405
|
+
/**
|
|
406
|
+
* The text of the "Show Description" links which show or hide the long
|
|
407
|
+
* description for each vendor.
|
|
408
|
+
*/
|
|
409
|
+
showDescText: 'View More Info',
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* The recaptcha theme used.
|
|
413
|
+
*
|
|
414
|
+
* Accepted options: red, white, blackglass, clean
|
|
415
|
+
*
|
|
416
|
+
* For details, see:
|
|
417
|
+
* http://code.google.com/apis/recaptcha/docs/customization.html
|
|
418
|
+
*
|
|
419
|
+
*/
|
|
420
|
+
recaptchaTheme: 'white'
|
|
421
|
+
};
|
|
422
|
+
|
|
423
|
+
return {
|
|
424
|
+
init: function(opts) {
|
|
425
|
+
var that = this, html;
|
|
426
|
+
|
|
427
|
+
if (!opts) opts = {};
|
|
428
|
+
|
|
429
|
+
this.url = opts.url || defaults.url;
|
|
430
|
+
|
|
431
|
+
// if url is protocol relative, prepend protocol
|
|
432
|
+
if (/^\/\//.test(this.url)) {
|
|
433
|
+
this.url = location.protocol + this.url;
|
|
434
|
+
|
|
435
|
+
// else if we're https, ensure the url is
|
|
436
|
+
} else if (location.protocol.match(/^https/)) {
|
|
437
|
+
this.url = this.url.replace(/^http:/, 'https:');
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// cut trailing / from url if present
|
|
441
|
+
if (/\/$/.test(this.url)) this.url = this.url.substr(0, this.url.length - 1);
|
|
442
|
+
|
|
443
|
+
// defines a callback in case of more than one widget on a page (unlikely)...
|
|
444
|
+
this.callback = 'cb' + ++E9.VWidget.COUNT;
|
|
445
|
+
|
|
446
|
+
// and defines a global callback on E9.VWidget for jsonp
|
|
447
|
+
E9.VWidget[this.callback] = function(response) {
|
|
448
|
+
clearTimeout(that.jsonRequestTimer);
|
|
449
|
+
that.renderHtmlFromResponse(response);
|
|
450
|
+
that.removeScriptElement();
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// code must be passed
|
|
454
|
+
if (!opts.code) {
|
|
455
|
+
html = tag('h3', {'class':'vb-error'}, 'E9.VWidget requires that you pass a code identifying yourself as a member');
|
|
456
|
+
} else {
|
|
457
|
+
html = tag('h3', {'class':'vb-loading'}, 'Loading...');
|
|
458
|
+
this.scriptUrl = this.url + '/directory/members/' + opts.code + '.json?jsonp=E9.VWidget.' + this.callback;
|
|
459
|
+
this.formUrl = this.url + '/contact_requests.json';
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/* form is currently off */
|
|
463
|
+
this.showForm = false;
|
|
464
|
+
|
|
465
|
+
this.recaptchaPublicKey = recaptchaPublicKey;
|
|
466
|
+
this.recaptchaTheme = opts.recaptchaTheme || defaults.recaptchaTheme;
|
|
467
|
+
this.recaptcha_timeout = opts.recaptcha_timeout || defaults.recaptcha_timeout;
|
|
468
|
+
|
|
469
|
+
this.styles = opts.hasOwnProperty('styles') ? opts.styles : true
|
|
470
|
+
this.timeout = opts.timeout || defaults.timeout;
|
|
471
|
+
this.elementId = opts.elementId || defaults.elementId;
|
|
472
|
+
this.onRender = opts.onRender || defaults.onRender;
|
|
473
|
+
this.onInit = opts.onInit || defaults.onInit;
|
|
474
|
+
this.timeout = opts.timeout || defaults.timeout;
|
|
475
|
+
this.headingTag = opts.headingTag || defaults.headingTag;
|
|
476
|
+
this.subheadingTag = opts.subheadingTag || defaults.subheadingTag;
|
|
477
|
+
this.showDescText = opts.showDescText || defaults.showDescText;
|
|
478
|
+
|
|
479
|
+
this.element = document.getElementById(this.elementId);
|
|
480
|
+
if (!this.element) {
|
|
481
|
+
document.write(div(this.elementId, ''));
|
|
482
|
+
this.element = document.getElementById(this.elementId);
|
|
483
|
+
}
|
|
484
|
+
if (opts.width) this.element.style.width = opts.width;
|
|
485
|
+
if (opts.height) this.element.style.height = opts.height;
|
|
486
|
+
this.element.innerHTML = html;
|
|
487
|
+
|
|
488
|
+
this.onInit(this);
|
|
489
|
+
},
|
|
490
|
+
|
|
491
|
+
removeScriptElement: function() {
|
|
492
|
+
removeHeadElement(this.scriptElement);
|
|
493
|
+
},
|
|
494
|
+
|
|
495
|
+
addReCAPTCHAScript: function() {
|
|
496
|
+
var script = document.createElement('script');
|
|
497
|
+
script.type = 'text/javascript';
|
|
498
|
+
// NOTE protocol relative recaptcha url
|
|
499
|
+
script.src = "//www.google.com/recaptcha/api/js/recaptcha_ajax.js";
|
|
500
|
+
|
|
501
|
+
var head = document.getElementsByTagName('head')[0];
|
|
502
|
+
head.insertBefore(script, head.firstChild);
|
|
503
|
+
},
|
|
504
|
+
|
|
505
|
+
displayReCAPTCHA: function() {
|
|
506
|
+
Recaptcha.create(this.recaptchaPublicKey, "vb-recaptcha", {
|
|
507
|
+
theme: this.recaptchaTheme,
|
|
508
|
+
callback: function() {}
|
|
509
|
+
});
|
|
510
|
+
},
|
|
511
|
+
|
|
512
|
+
addStylesheets: function() {
|
|
513
|
+
var link = document.createElement("link");
|
|
514
|
+
link.href = this.url + "/stylesheets/vb-widget.css";
|
|
515
|
+
link.rel = "stylesheet";
|
|
516
|
+
link.type = "text/css";
|
|
517
|
+
addHeadElement(link);
|
|
518
|
+
|
|
519
|
+
if (browser().version < 8) {
|
|
520
|
+
link = document.createElement("link");
|
|
521
|
+
link.href = this.url + "/stylesheets/vb-widget-ie.css";
|
|
522
|
+
link.rel = "stylesheet";
|
|
523
|
+
link.type = "text/css";
|
|
524
|
+
addHeadElement(link);
|
|
525
|
+
}
|
|
526
|
+
},
|
|
527
|
+
|
|
528
|
+
setTimeout: function(e) {
|
|
529
|
+
var that = this;
|
|
530
|
+
this.jsonRequestTimer = window.setTimeout(function() {
|
|
531
|
+
that.element.innerHTML = E9.VWidget.ERROR_MESSAGE;
|
|
532
|
+
}, this.timeout);
|
|
533
|
+
},
|
|
534
|
+
|
|
535
|
+
getFieldElements: function() {
|
|
536
|
+
var elements = new Array();
|
|
537
|
+
try {
|
|
538
|
+
elements.push(document.getElementById('vb-form-name'));
|
|
539
|
+
elements.push(document.getElementById('vb-form-phone'));
|
|
540
|
+
elements.push(document.getElementById('vb-form-email'));
|
|
541
|
+
} catch(e) {
|
|
542
|
+
} finally {
|
|
543
|
+
return elements;
|
|
544
|
+
}
|
|
545
|
+
},
|
|
546
|
+
|
|
547
|
+
getShowLinks: function() {
|
|
548
|
+
var showlinks = new Array();
|
|
549
|
+
try {
|
|
550
|
+
var links = document.getElementById('vb-vendor-list').getElementsByTagName('a');
|
|
551
|
+
for(var i=0;i<links.length;i++) {
|
|
552
|
+
if(links[i].name == 'vb-ldl') { showlinks.push(links[i]); }
|
|
553
|
+
}
|
|
554
|
+
} catch (e) {
|
|
555
|
+
} finally {
|
|
556
|
+
return showlinks;
|
|
557
|
+
}
|
|
558
|
+
},
|
|
559
|
+
|
|
560
|
+
renderHtmlFromResponse: function(response) {
|
|
561
|
+
if (isFirebug()) console.dir(response);
|
|
562
|
+
|
|
563
|
+
if (response && typeof response === 'object' && response.type == 'contact-request' || response.type == 'member') {
|
|
564
|
+
var that = this, html = '';
|
|
565
|
+
|
|
566
|
+
if (response.type == 'contact-request') {
|
|
567
|
+
// reload the captcha no matter what, it's not good for a 2nd pass.
|
|
568
|
+
Recaptcha.reload();
|
|
569
|
+
|
|
570
|
+
// re-enable the submit button if it was disabled on press
|
|
571
|
+
var submit = document.getElementById('vb-form-submit');
|
|
572
|
+
if (submit) { submit.removeAttribute('disabled'); }
|
|
573
|
+
|
|
574
|
+
var m = document.getElementById('vb-feedback');
|
|
575
|
+
|
|
576
|
+
if (isEmpty(response.errors)) {
|
|
577
|
+
m.className = 'vb-feedback vb-feedback-success';
|
|
578
|
+
resetForm();
|
|
579
|
+
|
|
580
|
+
html = 'Your request has been submitted.';
|
|
581
|
+
} else {
|
|
582
|
+
var field;
|
|
583
|
+
m.className = 'vb-feedback vb-feedback-error';
|
|
584
|
+
for (var e in response.errors) {
|
|
585
|
+
if (field = document.getElementById('vb-form-' + e)) {
|
|
586
|
+
field.className = 'vb-field vb-field-error';
|
|
587
|
+
}
|
|
588
|
+
html += div({'class':'vb-feedback-error-field'}, response.errors[e])
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
m.innerHTML = html;
|
|
593
|
+
m.style.display = 'block';
|
|
594
|
+
|
|
595
|
+
window.scrollTo(0, getYPos(m));
|
|
596
|
+
} else {
|
|
597
|
+
response = response.resource;
|
|
598
|
+
|
|
599
|
+
// TODO these html buffer variables are a bit chaotic...
|
|
600
|
+
var vc, vendor, contentHtml = '', formHtml = '', formHtmlInner, fHtml, cHtml, vHtml, vHtmlInner;
|
|
601
|
+
|
|
602
|
+
var vendorlist = '', optionList = '';
|
|
603
|
+
|
|
604
|
+
optionList += tag('option', {'value': 0}, 'All');
|
|
605
|
+
response.categories.forEach(function(c) {
|
|
606
|
+
optionList += tag('option', {'value': c.id }, c.name);
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
contentHtml += tag(that.subheadingTag, {'id':'vb-contact-form-heading','class':'vb-subheading'}, response.widget_form_title);
|
|
610
|
+
contentHtml += tag('select', {'id':'vb-category-select'}, optionList);
|
|
611
|
+
contentHtml += div({'class':'vb-text'}, response.widget_form_text);
|
|
612
|
+
|
|
613
|
+
response.vendors.forEach(function(vendor) {
|
|
614
|
+
vHtml = '';
|
|
615
|
+
formHtmlInner = '';
|
|
616
|
+
|
|
617
|
+
// next if vendor is not present or it shouldn't display
|
|
618
|
+
if (!vendor || !vendor.display_on_widget) return;
|
|
619
|
+
|
|
620
|
+
vHtmlInner = '';
|
|
621
|
+
|
|
622
|
+
// logo
|
|
623
|
+
if (vendor.logo) {
|
|
624
|
+
vHtmlInner += div({'class':'vb-vendor-logo'}, tag('img', {'src':vendor.logo}));
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
var cbHtml = '', vendorClass = 'vb-vendor';
|
|
628
|
+
|
|
629
|
+
// title
|
|
630
|
+
cbHtml += div({'class':'vb-vendor-name'}, vendor.name);
|
|
631
|
+
|
|
632
|
+
// short desc & link
|
|
633
|
+
cbHtml += div({'class':'vb-vendor-short-description'},
|
|
634
|
+
vendor.short_description + ' ' +
|
|
635
|
+
tag('a', {'data-id':vendor.id, 'class':'vb-show-desc-link', 'name':'vb-ldl', href:'javascript:;'}, that.showDescText)
|
|
636
|
+
);
|
|
637
|
+
|
|
638
|
+
// long desc
|
|
639
|
+
cbHtml += div({'style':'display:none', 'class':'vb-vendor-long-description', 'id':'vb-ld'+vendor.id}, vendor.long_description);
|
|
640
|
+
|
|
641
|
+
vHtmlInner += div({'class':'vb-vendor-content'}, cbHtml);
|
|
642
|
+
|
|
643
|
+
vendor.categories.forEach(function(cat) {
|
|
644
|
+
vendorClass += ' vb-c' + cat.id;
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
// wrap it up
|
|
648
|
+
vendorlist += div({'class': vendorClass}, vHtmlInner);
|
|
649
|
+
|
|
650
|
+
// continue if there is no contact form, or vendor shouldn't display on it
|
|
651
|
+
if (!that.showForm || !vendor.display_on_widget_contact_form) return;
|
|
652
|
+
|
|
653
|
+
// otherwise add them
|
|
654
|
+
formHtmlInner += div({'class':'vb-field'},
|
|
655
|
+
tag('input', {
|
|
656
|
+
'name':'contact_request[vendor_detail_ids][]',
|
|
657
|
+
'type':'checkbox',
|
|
658
|
+
'value':vendor.id,
|
|
659
|
+
'checked':'checked'
|
|
660
|
+
}) +
|
|
661
|
+
tag('label', {'class':'vb-label'}, vendor.name)
|
|
662
|
+
);
|
|
663
|
+
|
|
664
|
+
if (formHtmlInner.length) {
|
|
665
|
+
fHtml = div({'class':'vb-vendor-category-name'}, vc),
|
|
666
|
+
fHtml += div({'class':'vb-vendors'}, formHtmlInner);
|
|
667
|
+
formHtml += div({'class':'vb-vendor-category'}, fHtml);
|
|
668
|
+
}
|
|
669
|
+
});
|
|
670
|
+
|
|
671
|
+
contentHtml += div({'id':'vb-vendor-list'}, vendorlist);
|
|
672
|
+
|
|
673
|
+
if (that.showForm) {
|
|
674
|
+
// if vendors were added to formHtml, wrap them in fieldset
|
|
675
|
+
if (formHtml.length) {
|
|
676
|
+
formHtml =
|
|
677
|
+
tag('fieldset', {'class':'vb-fieldset vb-checkbox'},
|
|
678
|
+
tag('legend', 'vb-fieldset-legend', 'Vendors') +
|
|
679
|
+
formHtml
|
|
680
|
+
)
|
|
681
|
+
;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
formHtml += div({'class':'vb-field', 'id':'vb-form-name'},
|
|
685
|
+
tag('label', {'class':'vb-label vb-req'}, 'Full Name *') +
|
|
686
|
+
tag('input', { 'name':'contact_request[name]', 'type':'text' })
|
|
687
|
+
);
|
|
688
|
+
|
|
689
|
+
formHtml += div({'class':'vb-field', 'id':'vb-form-email'},
|
|
690
|
+
tag('label', {'class':'vb-label vb-req'}, 'Contact Email *') +
|
|
691
|
+
tag('input', { 'name':'contact_request[email]', 'type':'text' })
|
|
692
|
+
);
|
|
693
|
+
|
|
694
|
+
formHtml += div({'class':'vb-field', 'id':'vb-form-phone'},
|
|
695
|
+
tag('label', {'class':'vb-label'}, 'Contact Phone') +
|
|
696
|
+
tag('input', { 'name':'contact_request[phone]', 'type':'text' })
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
formHtml += div("vb-recaptcha", '');
|
|
700
|
+
|
|
701
|
+
formHtml += div({'class':'vb-actions'},
|
|
702
|
+
tag('input', {
|
|
703
|
+
'id':'vb-form-submit',
|
|
704
|
+
'name':'vb-form-submit',
|
|
705
|
+
'type':'submit',
|
|
706
|
+
'value':'Submit'
|
|
707
|
+
})
|
|
708
|
+
);
|
|
709
|
+
|
|
710
|
+
contentHtml += div({'id':'vb-form'}, formHtml);
|
|
711
|
+
contentHtml += div({'id':'vb-feedback', 'class':'vb-feedback', 'style':'display:none'}, '');
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
html += tag(that.headingTag, {'id':'vb-heading','class':'vb-heading'}, response.widget_title);
|
|
715
|
+
html += div('vb-content', contentHtml);
|
|
716
|
+
|
|
717
|
+
// hide the element so it can be manipulated by onRender
|
|
718
|
+
this.element.style.display = 'none';
|
|
719
|
+
|
|
720
|
+
this.element.innerHTML = div('vb-widget', html);
|
|
721
|
+
|
|
722
|
+
var select = document.getElementById('vb-category-select'),
|
|
723
|
+
el = this.element,
|
|
724
|
+
vendors = document.getElementsByClassName('vb-vendor', 'div', el);
|
|
725
|
+
|
|
726
|
+
function toggleViz(v, els) {
|
|
727
|
+
for (i in els) {
|
|
728
|
+
if (els.hasOwnProperty(i)) els[i].style.display = v ? 'block' : 'none';
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
select.onchange = function() {
|
|
733
|
+
if (this.value == '0') {
|
|
734
|
+
toggleViz(true, vendors);
|
|
735
|
+
} else {
|
|
736
|
+
toggleViz(false, vendors);
|
|
737
|
+
toggleViz(true, getElementsByClassName('vb-c'+this.value, 'div', el));
|
|
738
|
+
}
|
|
739
|
+
}
|
|
740
|
+
|
|
741
|
+
var showlink, showlinks = this.getShowLinks();
|
|
742
|
+
for (var i=0;i<showlinks.length;i++) {
|
|
743
|
+
showlink = showlinks[i];
|
|
744
|
+
|
|
745
|
+
showlink['element'] = document.getElementById('vb-ld' + showlink.attributes['data-id'].value);
|
|
746
|
+
|
|
747
|
+
showlink.onclick = function() {
|
|
748
|
+
this.element.style.display = this.element.style.display == 'none' ? 'block' : 'none';
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
showlink.onmouseover = function() {
|
|
752
|
+
window.status = 'Toggle full description';
|
|
753
|
+
return true;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
if (this.showForm) {
|
|
758
|
+
var form = document.getElementById('vb-form'),
|
|
759
|
+
submit = document.getElementById('vb-form-submit');
|
|
760
|
+
|
|
761
|
+
submit.onclick = function(e) {
|
|
762
|
+
this.setAttribute("disabled", "disabled");
|
|
763
|
+
|
|
764
|
+
var fields = that.getFieldElements();
|
|
765
|
+
for(var i=0;i<fields.length;i++) {
|
|
766
|
+
fields[i].className = 'vb-field';
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
var inputs = form.getElementsByTagName('input');
|
|
770
|
+
|
|
771
|
+
var formData = '', formLen = inputs.length;
|
|
772
|
+
for(var i=0;i<formLen;i++) {
|
|
773
|
+
if(!inputs[i].name) continue;
|
|
774
|
+
if(inputs[i].type == 'submit') continue;
|
|
775
|
+
if(inputs[i].type != 'checkbox' || inputs[i].checked) {
|
|
776
|
+
formData += inputs[i].name + '=' + encodeURIComponent(inputs[i].value)
|
|
777
|
+
}
|
|
778
|
+
formData += '&';
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
formData += 'jsonp=E9.VWidget.' + that.callback;
|
|
782
|
+
|
|
783
|
+
that.setTimeout();
|
|
784
|
+
E9.VWidget.jsonP(that.formUrl + '?' + formData, function(el) {
|
|
785
|
+
that.scriptElement = el;
|
|
786
|
+
});
|
|
787
|
+
|
|
788
|
+
return false;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
this.displayReCAPTCHA();
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
this.onRender(this);
|
|
795
|
+
this.element.style.display = 'block';
|
|
796
|
+
}
|
|
797
|
+
} else {
|
|
798
|
+
this.element.style.display = 'none';
|
|
799
|
+
this.element.innerHTML = E9.VWidget.ERROR_MESSAGE;
|
|
800
|
+
this.onError(this);
|
|
801
|
+
this.element.style.display = 'block';
|
|
802
|
+
}
|
|
803
|
+
},
|
|
804
|
+
|
|
805
|
+
/**
|
|
806
|
+
* @access public
|
|
807
|
+
* @return {Object} self
|
|
808
|
+
*/
|
|
809
|
+
render: function() {
|
|
810
|
+
that = this;
|
|
811
|
+
|
|
812
|
+
if (this.styles) {
|
|
813
|
+
this.addStylesheets();
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (this.scriptUrl) {
|
|
817
|
+
function loadJSON() {
|
|
818
|
+
that.setTimeout();
|
|
819
|
+
E9.VWidget.jsonP(that.scriptUrl, function(el) { that.scriptElement = el; });
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
if (this.showForm) {
|
|
823
|
+
this.addReCAPTCHAScript();
|
|
824
|
+
wait({
|
|
825
|
+
timeout : that.recaptcha_timeout,
|
|
826
|
+
until : function(elapsed) { return typeof Recaptcha !== 'undefined'; },
|
|
827
|
+
error : function() { that.element.innerHTML = E9.VWidget.ERROR_MESSAGE; },
|
|
828
|
+
success : loadJSON
|
|
829
|
+
});
|
|
830
|
+
} else {
|
|
831
|
+
loadJSON();
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
return this;
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}();
|
|
838
|
+
})();
|
|
839
|
+
|
metadata
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: e9_vendors
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease:
|
|
5
|
-
version: 0.0.
|
|
5
|
+
version: 0.0.2
|
|
6
6
|
platform: ruby
|
|
7
7
|
authors:
|
|
8
8
|
- Travis Cox
|
|
@@ -85,7 +85,7 @@ files:
|
|
|
85
85
|
- app/views/e9_vendors/vendors/index.html.haml
|
|
86
86
|
- app/views/e9_vendors/vendors/index.js.erb
|
|
87
87
|
- app/views/e9_vendors/vendors/new.html.haml
|
|
88
|
-
- config/locales/
|
|
88
|
+
- config/locales/e9_vendors.en.yml
|
|
89
89
|
- config/routes.rb
|
|
90
90
|
- e9_vendors.gemspec
|
|
91
91
|
- lib/e9_vendors.rb
|
|
@@ -93,7 +93,8 @@ files:
|
|
|
93
93
|
- lib/e9_vendors/model.rb
|
|
94
94
|
- lib/e9_vendors/version.rb
|
|
95
95
|
- lib/generators/e9_vendors/install_generator.rb
|
|
96
|
-
- lib/generators/e9_vendors/templates/
|
|
96
|
+
- lib/generators/e9_vendors/templates/javascripts/e9_vendors.js
|
|
97
|
+
- lib/generators/e9_vendors/templates/javascripts/widget.js
|
|
97
98
|
- lib/generators/e9_vendors/templates/migration.rb
|
|
98
99
|
- lib/generators/e9_vendors/templates/stylesheets/vb-widget-ie.scss
|
|
99
100
|
- lib/generators/e9_vendors/templates/stylesheets/vb-widget.scss
|