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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fef8189f02630e738799f66750c04c1735839c6a
4
- data.tar.gz: 28f428f626cf0297cd6544a946429716b47f353a
3
+ metadata.gz: 53ff9446c8f755df7d9ac559825c389a44d4dab1
4
+ data.tar.gz: 0a567bbcf6b84fc08e3827bbfd1fe2e4d4a09350
5
5
  SHA512:
6
- metadata.gz: 6b3cdd6d5b76a9e02d82e11380b3ff8cf1a63be9f23257092f9ad8e7be736caea26ad17c492f233e8ffa1bc4387363b600370445619b9b69e5f78cb52a1df6b8
7
- data.tar.gz: b7dfdc73f7e60e9c4225bea064a70b5a9bc6faa299c233ec6b04fd4b7398b8818211e2e2041a531bf52b6f2bfc1ae041e76128091287700735b0700d5579fae9
6
+ metadata.gz: 7e5d7e5062b8dd82613c64ff68665fccf1cfc3156c47db9867d431214eab559d83e82fa22d2c799781223bb490fb2f78ab3e962cbd8a990a5405c37fe91dde7e
7
+ data.tar.gz: f1aea9894e9455ea590faeded81547f9d9891e63bfe5db130c0646afae4afa6d1445d176ffaa535d08501fec10f21cf47499c255ac4a3d38cf0e8fd88d35e4ec
data/.codeclimate.yml ADDED
@@ -0,0 +1,6 @@
1
+ engines:
2
+ rubocop:
3
+ enabled: true
4
+ checks:
5
+ Rubocop/Style/StringLiterals:
6
+ enabled: false
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 [`Embedding Modes`](http://docs.typeform.io/docs/embedding-introduction) documentation at Typeform I/O. It has pictures and everything.
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
- `AskAwesomely` 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 either.
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
 
@@ -1,21 +1,19 @@
1
1
  module AskAwesomely
2
2
  class Choice
3
3
 
4
- attr_reader :state, :picture
4
+ include JsonBuilder
5
5
 
6
- def initialize(label:, picture: nil)
7
- @state = OpenStruct.new(label: label.to_s)
8
- @picture = picture && Picture.new(picture)
9
- end
6
+ attr_reader :state
10
7
 
11
- def build_json(context = nil)
12
- @state.image_id = picture && picture.typeform_id
8
+ def initialize(label:, picture: nil)
9
+ @state = OpenStruct.new(
10
+ label: label.to_s,
11
+ )
13
12
 
14
- state.to_h.reduce({}) do |json, (k, v)|
15
- json[k] = v.respond_to?(:call) ? v.call(context) : v
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
@@ -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
- json
62
- end.to_json
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 state
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 build_json(context = nil)
65
- state.to_h.reduce({}) do |json, (k, v)|
66
- json[k] = case
67
- when v.respond_to?(:to_ary) then v.map {|f| f.respond_to?(:build_json) ? f.build_json(context) : f }
68
- when v.respond_to?(:call) then v.call(context)
69
- when v.respond_to?(:build_json) then v.build_json(context)
70
- else
71
- v
72
- end
73
- json
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
@@ -0,0 +1,17 @@
1
+ module AskAwesomely
2
+ class LogicJump
3
+
4
+ include JsonBuilder
5
+
6
+ attr_reader :state
7
+
8
+ def initialize(args)
9
+ @state = OpenStruct.new(
10
+ to: args[:to],
11
+ from: args[:from],
12
+ if_answer: args[:if_answer]
13
+ )
14
+ end
15
+
16
+ end
17
+ end
@@ -33,7 +33,7 @@ module AskAwesomely
33
33
  end
34
34
 
35
35
  def to_json
36
- @structure.build_json
36
+ @structure.to_json
37
37
  end
38
38
 
39
39
  end
@@ -1,3 +1,3 @@
1
1
  module AskAwesomely
2
- VERSION = "0.1.5"
2
+ VERSION = "0.1.6"
3
3
  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.5
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-07 00:00:00.000000000 Z
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