ask_awesomely 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +6 -0
- data/README.md +80 -2
- data/lib/ask_awesomely/choice.rb +9 -11
- data/lib/ask_awesomely/dsl.rb +12 -20
- data/lib/ask_awesomely/field/field.rb +13 -11
- data/lib/ask_awesomely/json_builder.rb +27 -0
- data/lib/ask_awesomely/logic_jump.rb +17 -0
- data/lib/ask_awesomely/typeform.rb +1 -1
- data/lib/ask_awesomely/version.rb +1 -1
- data/lib/ask_awesomely.rb +2 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53ff9446c8f755df7d9ac559825c389a44d4dab1
|
4
|
+
data.tar.gz: 0a567bbcf6b84fc08e3827bbfd1fe2e4d4a09350
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7e5d7e5062b8dd82613c64ff68665fccf1cfc3156c47db9867d431214eab559d83e82fa22d2c799781223bb490fb2f78ab3e962cbd8a990a5405c37fe91dde7e
|
7
|
+
data.tar.gz: f1aea9894e9455ea590faeded81547f9d9891e63bfe5db130c0646afae4afa6d1445d176ffaa535d08501fec10f21cf47499c255ac4a3d38cf0e8fd88d35e4ec
|
data/.codeclimate.yml
ADDED
data/README.md
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
Build Typeforms awesomely. In Ruby.
|
4
4
|
|
5
5
|
[![Gem Version](https://badge.fury.io/rb/ask_awesomely.svg)](http://badge.fury.io/rb/ask_awesomely) [![Build Status](https://travis-ci.org/leemachin/ask_awesomely.svg?branch=master)](https://travis-ci.org/leemachin/ask_awesomely)
|
6
|
+
[![Code Climate](https://codeclimate.com/github/leemachin/ask_awesomely/badges/gpa.svg)](https://codeclimate.com/github/leemachin/ask_awesomely)
|
6
7
|
|
7
8
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
8
9
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
@@ -29,6 +30,8 @@ Build Typeforms awesomely. In Ruby.
|
|
29
30
|
- [Email](#email)
|
30
31
|
- [Website](#website)
|
31
32
|
- [Legal](#legal)
|
33
|
+
- [Logic Jumps](#logic-jumps)
|
34
|
+
- [Conditional Fields](#conditional-fields)
|
32
35
|
- [Common Customisations](#common-customisations)
|
33
36
|
- [Passing Context](#passing-context)
|
34
37
|
- [Rendering the Typeform](#rendering-the-typeform)
|
@@ -349,6 +352,81 @@ field :legal
|
|
349
352
|
end
|
350
353
|
```
|
351
354
|
|
355
|
+
## Logic Jumps
|
356
|
+
|
357
|
+
A logic jump allows you to change the next questions you ask based on the answer of a previous question. For example, you could have a `yes_no` field that shows one question if the answer is 'yes', and a different question if the answer is 'no'. At the time of writing this is the only supported behaviour for logic jumps.
|
358
|
+
|
359
|
+
Check out the [documentation on Logic Jumps](http://docs.typeform.io/docs/logic-jumps) to understand more about how they work.
|
360
|
+
|
361
|
+
In order to set one up, you need to give the relevant fields a reference. In this case, when the user answers 'no' to the first question about their age, it should immediately go to the next question like normal. If they answer 'yes', though, the form should ask them another question to confirm they're not lying about being grown up.
|
362
|
+
|
363
|
+
```ruby
|
364
|
+
field :yes_no do
|
365
|
+
ask "Are you over 18?"
|
366
|
+
required
|
367
|
+
|
368
|
+
ref :is_over_18
|
369
|
+
end
|
370
|
+
|
371
|
+
field :statement do
|
372
|
+
say "You're too young to continue"
|
373
|
+
end
|
374
|
+
|
375
|
+
field :yes_no do
|
376
|
+
ask "Are you *sure* you're over 18?"
|
377
|
+
required
|
378
|
+
|
379
|
+
ref :is_really_over_18?
|
380
|
+
end
|
381
|
+
```
|
382
|
+
|
383
|
+
Notice how the two `yes_no` fields have a reference. These are what we use to define the logic jump:
|
384
|
+
|
385
|
+
```ruby
|
386
|
+
jump from: :is_over_18, to: :is_really_over_18?, if_answer: true
|
387
|
+
|
388
|
+
```
|
389
|
+
|
390
|
+
If you need to change the structure of a Typeform based on your own data and not that supplied in an answer, then continue on to [**Conditional Fields**](#conditional-fields).
|
391
|
+
|
392
|
+
## Conditional Fields
|
393
|
+
|
394
|
+
Consider a form where you ask for the user's email address:
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
class EmailTypeform
|
398
|
+
include AskAwesomely::DSL
|
399
|
+
|
400
|
+
field :email do
|
401
|
+
ask -> (user) { "Hey #{user.name}, what is your email address?" }
|
402
|
+
required
|
403
|
+
end
|
404
|
+
|
405
|
+
# ... more fields
|
406
|
+
end
|
407
|
+
```
|
408
|
+
|
409
|
+
What if you already have the user's email? It makes no sense to repeatedly ask for it, does it? You can tell *Ask Awesomely* to not include this field if a certain condition is met; in this case the user having an email address already.
|
410
|
+
|
411
|
+
```ruby
|
412
|
+
class EmailTypeform
|
413
|
+
include AskAwesomely::DSL
|
414
|
+
|
415
|
+
field :email do
|
416
|
+
ask -> (user) { "Hey #{user.name}, what is your email address?" }
|
417
|
+
required
|
418
|
+
|
419
|
+
skip if: -> (user) { !user.email.nil? }
|
420
|
+
|
421
|
+
# alternatively
|
422
|
+
skip unless: -> (user) { user.email.nil? }
|
423
|
+
end
|
424
|
+
|
425
|
+
# ... more fields
|
426
|
+
end
|
427
|
+
```
|
428
|
+
|
429
|
+
Note that this is not a feature of the Typeform I/O API. These conditions are evaluated at **build time** and not when the form is rendered (as with logic jumps), which means that the field won't be included in the final Typeform at all.
|
352
430
|
|
353
431
|
## Common Customisations
|
354
432
|
|
@@ -427,7 +505,7 @@ end
|
|
427
505
|
|
428
506
|
You can also embed a form straight away if you prefer. `AskAwesomely` generates the correct embed code for you, with the correct URL and Typeform title. The style can be customised with CSS, and you can also tweak some of the output.
|
429
507
|
|
430
|
-
To see what each embedding option looks like, check out the [
|
508
|
+
To see what each embedding option looks like, check out the [**Embedding Modes**](http://docs.typeform.io/docs/embedding-introduction) documentation at Typeform I/O. It has pictures and everything.
|
431
509
|
|
432
510
|
Assuming you have built a Typeform as in the other examples, rendering the embed code is simple:
|
433
511
|
|
@@ -478,7 +556,7 @@ class UserTypeform
|
|
478
556
|
end
|
479
557
|
```
|
480
558
|
|
481
|
-
|
559
|
+
*Ask Awesomely* will warn you if you don't configure this, as Typeform I/O doesn't store the responses for you and they'll be lost in the ether.
|
482
560
|
|
483
561
|
Check the documentation on [results and webhooks](http://docs.typeform.io/docs/results-introduction) to find out more about how this works, what happens when a webhook submission request fails, and how you can deduplicate your submissions.
|
484
562
|
|
data/lib/ask_awesomely/choice.rb
CHANGED
@@ -1,21 +1,19 @@
|
|
1
1
|
module AskAwesomely
|
2
2
|
class Choice
|
3
3
|
|
4
|
-
|
4
|
+
include JsonBuilder
|
5
5
|
|
6
|
-
|
7
|
-
@state = OpenStruct.new(label: label.to_s)
|
8
|
-
@picture = picture && Picture.new(picture)
|
9
|
-
end
|
6
|
+
attr_reader :state
|
10
7
|
|
11
|
-
def
|
12
|
-
@state
|
8
|
+
def initialize(label:, picture: nil)
|
9
|
+
@state = OpenStruct.new(
|
10
|
+
label: label.to_s,
|
11
|
+
)
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
json
|
13
|
+
if picture
|
14
|
+
@state.image_id = proc { Picture.new(picture).typeform_id }
|
17
15
|
end
|
18
16
|
end
|
19
|
-
|
17
|
+
|
20
18
|
end
|
21
19
|
end
|
data/lib/ask_awesomely/dsl.rb
CHANGED
@@ -3,6 +3,7 @@ module AskAwesomely
|
|
3
3
|
|
4
4
|
def self.included(recv)
|
5
5
|
recv.extend(ClassMethods)
|
6
|
+
recv.include(JsonBuilder)
|
6
7
|
end
|
7
8
|
|
8
9
|
module ClassMethods
|
@@ -35,6 +36,11 @@ module AskAwesomely
|
|
35
36
|
_state.fields << Field::Field.of_type(type, &block)
|
36
37
|
end
|
37
38
|
|
39
|
+
def jump(conditions)
|
40
|
+
_state.jumps ||= []
|
41
|
+
_state.jumps << LogicJump.new(conditions)
|
42
|
+
end
|
43
|
+
|
38
44
|
def send_responses_to(url)
|
39
45
|
unless url =~ /\A#{URI::regexp(['http', 'https'])}\z/
|
40
46
|
raise AskAwesomely::InvalidUrlError, "you must use a valid URL for webhooks, e.g https://example.com/webhook"
|
@@ -44,35 +50,21 @@ module AskAwesomely
|
|
44
50
|
end
|
45
51
|
end
|
46
52
|
|
47
|
-
attr_reader :context, :json
|
48
|
-
|
49
|
-
def build_json
|
50
|
-
warn_if_no_webhook_set!
|
51
|
-
|
52
|
-
state.to_h.reduce({}) do |json, (k, v)|
|
53
|
-
json[k] = case
|
54
|
-
when v.respond_to?(:to_ary) then v.map {|f| f.respond_to?(:build_json) ? f.build_json(context) : f }
|
55
|
-
when v.respond_to?(:call) then v.call(context)
|
56
|
-
when v.respond_to?(:build_json) then v.build_json(context)
|
57
|
-
else
|
58
|
-
v
|
59
|
-
end
|
53
|
+
attr_reader :context, :json, :state
|
60
54
|
|
61
|
-
|
62
|
-
|
55
|
+
def to_json
|
56
|
+
warn_if_no_webhook_set
|
57
|
+
build_json(context).to_json
|
63
58
|
end
|
64
59
|
|
65
60
|
private
|
66
61
|
|
67
62
|
def initialize(context = nil)
|
68
63
|
@context = context
|
64
|
+
@state = self.class._state
|
69
65
|
end
|
70
66
|
|
71
|
-
def
|
72
|
-
self.class._state
|
73
|
-
end
|
74
|
-
|
75
|
-
def warn_if_no_webhook_set!
|
67
|
+
def warn_if_no_webhook_set
|
76
68
|
return if state.webhook_submit_url
|
77
69
|
AskAwesomely.configuration.logger.warn(<<-STR.gsub(/^\s*/, ''))
|
78
70
|
Your Typeform has no webhook URL! The responses to this form **will NOT** be saved!
|
@@ -1,6 +1,8 @@
|
|
1
1
|
module AskAwesomely
|
2
2
|
class Field::Field
|
3
3
|
|
4
|
+
prepend JsonBuilder
|
5
|
+
|
4
6
|
VALID_FIELD_TYPES = %i(
|
5
7
|
short_text
|
6
8
|
long_text
|
@@ -61,18 +63,18 @@ module AskAwesomely
|
|
61
63
|
@state.tags = tags
|
62
64
|
end
|
63
65
|
|
64
|
-
def
|
65
|
-
state.
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
66
|
+
def ref(name)
|
67
|
+
@state.ref = name.to_s
|
68
|
+
end
|
69
|
+
|
70
|
+
def skip(condition)
|
71
|
+
if cond_if = condition[:if]
|
72
|
+
@state.skip = -> (context) { cond_if.call(context) == true }
|
73
|
+
end
|
74
|
+
|
75
|
+
if cond_unless = condition[:unless]
|
76
|
+
@state.skip = -> (context) { cond_unless.call(context) != true }
|
74
77
|
end
|
75
78
|
end
|
76
|
-
|
77
79
|
end
|
78
80
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module AskAwesomely
|
2
|
+
module JsonBuilder
|
3
|
+
|
4
|
+
def build_json(context = nil)
|
5
|
+
super if defined?(super)
|
6
|
+
|
7
|
+
state.to_h.reduce({}) do |json, (k, v)|
|
8
|
+
|
9
|
+
next if k == :skip && v.call(context) == true
|
10
|
+
|
11
|
+
json[k] = case
|
12
|
+
when v.respond_to?(:to_ary)
|
13
|
+
v.map {|f| f.respond_to?(:build_json) ? f.build_json(context) : f }
|
14
|
+
.compact
|
15
|
+
when v.respond_to?(:call)
|
16
|
+
v.call(context)
|
17
|
+
when v.respond_to?(:build_json)
|
18
|
+
v.build_json(context)
|
19
|
+
else
|
20
|
+
v
|
21
|
+
end
|
22
|
+
json
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
data/lib/ask_awesomely.rb
CHANGED
@@ -6,6 +6,7 @@ require "aws-sdk"
|
|
6
6
|
require "typhoeus"
|
7
7
|
|
8
8
|
require "ask_awesomely/version"
|
9
|
+
require "ask_awesomely/json_builder"
|
9
10
|
require "ask_awesomely/configuration"
|
10
11
|
require "ask_awesomely/dsl"
|
11
12
|
require "ask_awesomely/field"
|
@@ -15,6 +16,7 @@ require "ask_awesomely/s3"
|
|
15
16
|
require "ask_awesomely/api_client"
|
16
17
|
require "ask_awesomely/typeform"
|
17
18
|
require "ask_awesomely/embeddable"
|
19
|
+
require "ask_awesomely/logic_jump"
|
18
20
|
|
19
21
|
module AskAwesomely
|
20
22
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ask_awesomely
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lee Machin
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10-
|
11
|
+
date: 2015-10-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: aws-sdk
|
@@ -115,6 +115,7 @@ executables: []
|
|
115
115
|
extensions: []
|
116
116
|
extra_rdoc_files: []
|
117
117
|
files:
|
118
|
+
- ".codeclimate.yml"
|
118
119
|
- ".gitignore"
|
119
120
|
- ".rspec"
|
120
121
|
- ".ruby-version"
|
@@ -151,6 +152,8 @@ files:
|
|
151
152
|
- lib/ask_awesomely/field/statement.rb
|
152
153
|
- lib/ask_awesomely/field/website.rb
|
153
154
|
- lib/ask_awesomely/field/yes_no.rb
|
155
|
+
- lib/ask_awesomely/json_builder.rb
|
156
|
+
- lib/ask_awesomely/logic_jump.rb
|
154
157
|
- lib/ask_awesomely/picture.rb
|
155
158
|
- lib/ask_awesomely/s3.rb
|
156
159
|
- lib/ask_awesomely/typeform.rb
|