knockout_forms-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +14 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +203 -0
- data/Rakefile +2 -0
- data/knockout_forms-rails.gemspec +26 -0
- data/lib/assets/javascripts/knockout-forms.rails.js +33 -0
- data/lib/knockout_forms/rails.rb +15 -0
- data/lib/knockout_forms/rails/form_builder.rb +82 -0
- data/lib/knockout_forms/rails/helpers/form_helper.rb +17 -0
- data/lib/knockout_forms/rails/version.rb +5 -0
- metadata +124 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4d733f242bb995739e41da161277091e2f707972
|
4
|
+
data.tar.gz: 9f1e588416553454d9d17e8224098982e5d8fa03
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88754d82d026c355c610ef71bc6e13436fcf1770b8f7dd88820cf4bccdf7c8e7f2527a7f5c69093cf8f91214ba0d3aa695f3a28c05811b8d89239e2713146fac
|
7
|
+
data.tar.gz: df37feb8697a0bf138db112e177a8ad32ca3b82eddf91f807479e1bcaf131390ef20a99115694c57f6283aa5f85557424fa3e64ef5316157162cd2794c3c29f0
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Santiago Palladino
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
# KnockoutForms::Rails
|
2
|
+
|
3
|
+
Knockoutjs powered form builder for Rails. This gem provides a `knockout_form_for` helper that creates forms automatically bound to a viewmodel created for your model via the mapping plugin.
|
4
|
+
|
5
|
+
## Why?
|
6
|
+
|
7
|
+
There was a large gap between how Rails standard forms and knockoutjs based forms are written: where the former make use of handy form builders, the latter require the markdown the be manually set up and wired with `data-bind` attributes, even if the viewmodel is rather simple.
|
8
|
+
|
9
|
+
This gem intends to bridge this gap by allowing a Rails form to be easily converted in a knockoutjs aware one, by allowing you to keep using form builders while automatically handling data binding under the covers.
|
10
|
+
|
11
|
+
That being said, the gem provides several endpoints for customisation, making it easy to insert your custom logic whenever needed.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'knockout_forms-rails'
|
19
|
+
```
|
20
|
+
|
21
|
+
And add the following directive to your Javascript manifest file (application.js):
|
22
|
+
|
23
|
+
```javascript
|
24
|
+
//= require knockout-forms.rails
|
25
|
+
```
|
26
|
+
|
27
|
+
## Dependencies
|
28
|
+
|
29
|
+
This gem requires both knockoutjs and the knockoutjs mapping plugin. The easiest way to do this is via the [knockoutjs-rails gem](https://github.com/jswanner/knockoutjs-rails); though it is not listed as a dependency in case you want to manage your javascript libraries somehow else.
|
30
|
+
|
31
|
+
## Example application
|
32
|
+
|
33
|
+
There is an [example application](https://github.com/spalladino/knockout_forms-rails-example) available with a simple [User form](https://github.com/spalladino/knockout_forms-rails-example/blob/master/app/views/users/_form.html.erb) and a complex [Questionnaire form](https://github.com/spalladino/knockout_forms-rails-example/blob/master/app/views/questionnaires/_form.html.erb) with a N-to-1 relation to Questions.
|
34
|
+
|
35
|
+
## Usage
|
36
|
+
|
37
|
+
This gem provides a `KnockoutForms::Rails::FormBuilder` class, accessible via the `knockout_form_for` method, which must be bound invoking the javascript `ko.form(f)` method with a reference to it.
|
38
|
+
|
39
|
+
### Basic usage
|
40
|
+
|
41
|
+
The easiest example is to use the `knockout_form_for` helper instead of a regular form, and invoke `ko.form()` on page load for the form you want to bind. For example, given a simple `user` model:
|
42
|
+
|
43
|
+
```haml
|
44
|
+
= knockout_form_for(@user) do |f|
|
45
|
+
|
46
|
+
.form-group
|
47
|
+
= f.label :name
|
48
|
+
= f.text_field :name
|
49
|
+
|
50
|
+
.form-group
|
51
|
+
= f.label :registered
|
52
|
+
= f.check_box :registered
|
53
|
+
|
54
|
+
.form-group{"data-bind" => "visible: registered"}
|
55
|
+
= f.label :email
|
56
|
+
= f.text_field :email
|
57
|
+
|
58
|
+
.actions
|
59
|
+
= f.submit class: 'btn btn-primary'
|
60
|
+
```
|
61
|
+
|
62
|
+
The `data-bind` with value `visible: registered` on the `email` field. This will display the email field only if the registered property is set to true.
|
63
|
+
|
64
|
+
The gem automatically creates a viewmodel for you based on the `user` model via the mapping plugin, bind it to the form, and set `value` bindings for all inputs.
|
65
|
+
|
66
|
+
To ensure `ko-forms` are always initialized, you can use this script:
|
67
|
+
|
68
|
+
```coffeescript
|
69
|
+
$ ->
|
70
|
+
$('.ko-form').each ->
|
71
|
+
ko.form this
|
72
|
+
```
|
73
|
+
|
74
|
+
### Providing your own viewmodel
|
75
|
+
|
76
|
+
You can use your own viewmodel with your custom functions instead of an empty object. There are a few ways of doing this:
|
77
|
+
|
78
|
+
- The easiest way is to simple define a javascript class in the global scope with the same name as the model, which will be picked up by the `ko.form()` function:
|
79
|
+
|
80
|
+
|
81
|
+
class @Questionnaire
|
82
|
+
preview:
|
83
|
+
alert "Questionnaire: #{@title()}"
|
84
|
+
|
85
|
+
|
86
|
+
You can then invoke the `preview` function in your viewmodel class from `click` handler, or using the `action` method in the form builder:
|
87
|
+
|
88
|
+
= f.action 'Preview question', 'preview'
|
89
|
+
|
90
|
+
- The other option is to manually provide a reference to the class in the `ko.form()` method invocation:
|
91
|
+
|
92
|
+
class Questionnaire
|
93
|
+
preview:
|
94
|
+
alert "Questionnaire: #{@title()}"
|
95
|
+
|
96
|
+
$ ->
|
97
|
+
form = $('.questionnaire-ko-form')[0]
|
98
|
+
ko.form form, class: Questionnaire
|
99
|
+
|
100
|
+
- Alternatively, you can provide your own already populated viewmodel instance, in which case the `model` information will not be used and the mapping plugin will not be required. Just pass a `viewmodel` option to the `ko.form` function to do this:
|
101
|
+
|
102
|
+
questionnaire = new Questionnaire()
|
103
|
+
ko.form form, viewmodel: questionnaire
|
104
|
+
|
105
|
+
- Furthermore, you can skip using the `ko.form` function altogether and simply run a simple `ko.applyBindings` to the form using a viewmodel of your choice.
|
106
|
+
|
107
|
+
### Mapping options
|
108
|
+
|
109
|
+
A custom mapping for your viewmodel can be provided as well. This will be passed directly as an argument to the `ko.mapping.fromJSON` invocation used to populate your viewmodel. It can be specified in the following ways:
|
110
|
+
|
111
|
+
- If you have supplied a viewmodel class and it has a `mapping` attribute, then it will be used automatically:
|
112
|
+
|
113
|
+
class Questionnaire
|
114
|
+
@mapping:
|
115
|
+
copy: ["description"]
|
116
|
+
|
117
|
+
- As an option to the `ko.form` method:
|
118
|
+
|
119
|
+
ko.form form, mapping: myCustomMapping
|
120
|
+
|
121
|
+
### Model data
|
122
|
+
|
123
|
+
The model used to populate the knockout viewmodel is the result of a `to_json` call to the Rails model. If there are certain properties you want to include that are not ActiveRecord fields, you need to specify that when creating the form.
|
124
|
+
|
125
|
+
- Add the fields to be included as a `model_options` option in the `knockout_form_for` declaration:
|
126
|
+
|
127
|
+
model_options: { include: :custom_field }
|
128
|
+
|
129
|
+
- Or directly specify the model you want to be used via `model`:
|
130
|
+
|
131
|
+
model: @questionnaire.to_json({ include: :custom_field })
|
132
|
+
|
133
|
+
Keep in mind that the model information is not required if you specify your own viewmodel via the `viewmodel` option in the `ko.form` invocation.
|
134
|
+
|
135
|
+
### Nested forms
|
136
|
+
|
137
|
+
Nested 1-to-N forms can be easily set up, and was one of the main drivers in the development of this gem. They do require some custom options to be properly handled, which are listed next. Refer to the questionnaire form (a questionnaire has_many questions) in the example application for a complete reference.
|
138
|
+
|
139
|
+
- Child elements must be included in the `model` when serializing it to populate the viewmodel, otherwise the children will not be included when editing an instance of the parent:
|
140
|
+
|
141
|
+
model_options: { include: :questions }
|
142
|
+
|
143
|
+
- In order to use custom viewmodel classes for both the parent and child elements, a custom mapping needs to be set up:
|
144
|
+
|
145
|
+
class @Question
|
146
|
+
|
147
|
+
class @Questionnaire
|
148
|
+
@mapping:
|
149
|
+
questions:
|
150
|
+
create: (opts) ->
|
151
|
+
ko.mapping.fromJS(opts.data, {}, new Question())
|
152
|
+
|
153
|
+
This will instruct the knockout mapping plugin to use a new instance of Question for each question in questionnaire that needs to be populated.
|
154
|
+
|
155
|
+
- The `fields_for` method in the form builder is overriden so it will use a `foreach` binding to display one template for each child. A `hidden_field` for the `id` must be included to keep track of existing instances.
|
156
|
+
|
157
|
+
= f.fields_for :questions do |g|
|
158
|
+
|
159
|
+
%h3 Question
|
160
|
+
= g.hidden_field :id
|
161
|
+
|
162
|
+
.form-group
|
163
|
+
= g.label :text
|
164
|
+
= g.text_field :text
|
165
|
+
|
166
|
+
Inside the `fields_for` body, all the markdown will be rendered once per question, and will be bound to the corresponding instance.
|
167
|
+
|
168
|
+
- A method `add_item` is provided in the form builder for convenience, which will attempt to automatically add an empty instance of the specified child viewmodel, populated from an empty child using the mapping plugin:
|
169
|
+
|
170
|
+
= f.add_item :questions, label: "Add new question", viewmodel: 'Question'
|
171
|
+
|
172
|
+
The usage of this helper is complete optional, as adding new items to the collection can be handled manually, by writing your own `addQuestion` function in the `Questionnaire` class and invoking it as:
|
173
|
+
|
174
|
+
= f.action "Add new question", 'addQuestion'
|
175
|
+
|
176
|
+
- As with all nested forms, remember to include the `accepts_nested_attibutes_for` option in your model, so the `fields_for` generated parameters will work correctly, which need to be permitted in the controller as well.
|
177
|
+
|
178
|
+
### Using your own form builder
|
179
|
+
|
180
|
+
All methods in the form builder are provided in a mixin `KnockoutForms::Rails::FormBuilder::Methods` which you can include to your own FormBuilder to have it render knockout based forms.
|
181
|
+
|
182
|
+
## Internals
|
183
|
+
|
184
|
+
The `KnockoutForms::Rails::FormBuilder` is the core of this gem. It overrides standard input helpers by adding a `data-bind` mapping to either their value or checked state, so they are automatically bound to the viewmodel attributes.
|
185
|
+
|
186
|
+
The input helpers currently supported are the following, you are welcome to send a pull request with your own:
|
187
|
+
|
188
|
+
- `text_field`
|
189
|
+
- `number_field `
|
190
|
+
- `hidden_field`
|
191
|
+
- `check_box `
|
192
|
+
- `radio_button`
|
193
|
+
- `select`
|
194
|
+
|
195
|
+
The counterpart of the form builder is the javascript code that binds it: the `knockout-forms.rails.js` script contains the `ko.form` function that either directly binds the form to the chosen viewmodel, or creates the viewmodel using the `model` JSON representation and the mapping plugin.
|
196
|
+
|
197
|
+
## Contributing
|
198
|
+
|
199
|
+
1. Fork it ( https://github.com/manastech/knockout_forms-rails/fork )
|
200
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
201
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
202
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
203
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'knockout_forms/rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "knockout_forms-rails"
|
8
|
+
spec.version = KnockoutForms::Rails::VERSION
|
9
|
+
spec.authors = ["Santiago Palladino"]
|
10
|
+
spec.email = ["spalladino@manas.com.ar"]
|
11
|
+
spec.summary = %q{Knockout-js powered Rails form builder}
|
12
|
+
spec.description = %q{Provides a Rails form builder to seamlessly setup a Knockout-js based view model on your forms.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.5"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
|
24
|
+
spec.add_runtime_dependency "railties", [">= 3.1", "< 5"]
|
25
|
+
spec.add_runtime_dependency "actionview", [">= 3", "< 5"]
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
(function() {
|
2
|
+
var _global = this;
|
3
|
+
ko.form = function(target, opts) {
|
4
|
+
|
5
|
+
var options = opts || {},
|
6
|
+
form = target,
|
7
|
+
klazz = options.class || form.getAttribute('data-viewmodel'),
|
8
|
+
model = options.model || form.getAttribute('data-model'),
|
9
|
+
viewmodel,
|
10
|
+
mapping;
|
11
|
+
|
12
|
+
// Get constructor function based on name
|
13
|
+
if (typeof(klazz) == 'string') {
|
14
|
+
klazz = _global[klazz];
|
15
|
+
}
|
16
|
+
|
17
|
+
// Use viewmodel from options or create a new one
|
18
|
+
if (options.viewmodel) {
|
19
|
+
viewmodel = options.viewmodel;
|
20
|
+
} else if (klazz){
|
21
|
+
viewmodel = new klazz;
|
22
|
+
mapping = klazz.mapping || options.mapping || {};
|
23
|
+
ko.mapping.fromJSON(model, mapping, viewmodel);
|
24
|
+
} else {
|
25
|
+
mapping = options.mapping || {};
|
26
|
+
viewmodel = ko.mapping.fromJSON(model, mapping);
|
27
|
+
}
|
28
|
+
|
29
|
+
// Apply ko bindings
|
30
|
+
ko.applyBindings(viewmodel, target);
|
31
|
+
|
32
|
+
};
|
33
|
+
})(this);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "knockout_forms/rails/version"
|
2
|
+
require "knockout_forms/rails/form_builder"
|
3
|
+
require "knockout_forms/rails/helpers/form_helper"
|
4
|
+
|
5
|
+
module KnockoutForms
|
6
|
+
module Rails
|
7
|
+
class Engine < ::Rails::Engine
|
8
|
+
initializer 'knockout_forms-rails.initialize' do
|
9
|
+
ActiveSupport.on_load(:action_view) do
|
10
|
+
include KnockoutForms::Rails::Helpers::FormHelper
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
module KnockoutForms
|
2
|
+
|
3
|
+
module Rails
|
4
|
+
|
5
|
+
class FormBuilder < ActionView::Helpers::FormBuilder
|
6
|
+
|
7
|
+
module Methods
|
8
|
+
|
9
|
+
# Define attribute to bind based on input kind
|
10
|
+
MAPPINGS = {
|
11
|
+
value: %W(text_field number_field hidden_field),
|
12
|
+
checked: %W(check_box radio_button)
|
13
|
+
}
|
14
|
+
|
15
|
+
def self.included(form)
|
16
|
+
# Wrap all input fields so they add a KO value data bind
|
17
|
+
MAPPINGS.each do |bind, fields|
|
18
|
+
fields.each do |field_name|
|
19
|
+
form.send(:define_method, field_name) do |name, *args|
|
20
|
+
opts = args.extract_options!
|
21
|
+
opts['data-bind'] = "#{bind}: #{name}" unless opts.delete(:bind) == false
|
22
|
+
super(name, *(args << opts))
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Handle select differently due to the html opts
|
29
|
+
def select(method, choices = nil, options = {}, html_options = {}, &block)
|
30
|
+
html_options['data-bind'] = "value: #{method}" unless options.delete(:bind) == false
|
31
|
+
super(method, choices, options, html_options, &block)
|
32
|
+
end
|
33
|
+
|
34
|
+
def fields_for(collection_name, options={}, &block)
|
35
|
+
empty_child = options[:empty] || object.association(collection_name).klass.new
|
36
|
+
collection = options[:collection] || collection_name
|
37
|
+
# Run fields_for with a single empty child that will act as the KO template for each item
|
38
|
+
# and use foreach data bind to delegate the iteration to KO
|
39
|
+
@template.content_tag(:div,
|
40
|
+
super(collection_name, [empty_child], options.merge(child_index: ""), &block),
|
41
|
+
:'data-bind' => "foreach: #{collection}",
|
42
|
+
:'data-collection' => collection,
|
43
|
+
:'class' => "children-collection #{collection}-collection")
|
44
|
+
end
|
45
|
+
|
46
|
+
def add_item(collection_name, options={})
|
47
|
+
child_klass = object.association(collection_name).klass
|
48
|
+
empty_child = child_klass.new
|
49
|
+
|
50
|
+
label = options.delete(:label) || "Add new #{child_klass.model_name.singular}"
|
51
|
+
viewmodel_collection = options.delete(:collection) || collection_name
|
52
|
+
viewmodel = options.delete(:child_class) || child_klass.name
|
53
|
+
|
54
|
+
# Create an empty child to inject attributes via KO mapping
|
55
|
+
model = empty_child.to_json
|
56
|
+
|
57
|
+
# Create new child viewmodel augmented with model attributes and
|
58
|
+
# automatically add to viewmodel collection on click
|
59
|
+
click_handler = options[:handler] || <<-JS_HANDLER
|
60
|
+
function(data, event) {
|
61
|
+
var viewmodel = new #{viewmodel}(data);
|
62
|
+
ko.mapping.fromJS(#{model}, {}, viewmodel);
|
63
|
+
#{viewmodel_collection}.push(viewmodel);
|
64
|
+
};
|
65
|
+
JS_HANDLER
|
66
|
+
|
67
|
+
action(label, click_handler, options)
|
68
|
+
end
|
69
|
+
|
70
|
+
def action(label, action, options={})
|
71
|
+
@template.link_to(label, '#', options.merge('data-bind' => "click: #{action}"))
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
include Methods
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module KnockoutForms::Rails::Helpers
|
2
|
+
module FormHelper
|
3
|
+
|
4
|
+
def knockout_form_for(object, options={}, &block)
|
5
|
+
options[:builder] ||= KnockoutForms::Rails::FormBuilder
|
6
|
+
|
7
|
+
html = (options[:html] ||= {})
|
8
|
+
|
9
|
+
html[:'class'] ||= "ko-form"
|
10
|
+
html[:'data-model'] ||= (options.delete(:model) || object.to_json(options.delete(:model_options) || {}))
|
11
|
+
html[:'data-viewmodel'] ||= object.class.to_s
|
12
|
+
|
13
|
+
form_for(object, options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: knockout_forms-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Santiago Palladino
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-10-13 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: railties
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.1'
|
48
|
+
- - "<"
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '5'
|
51
|
+
type: :runtime
|
52
|
+
prerelease: false
|
53
|
+
version_requirements: !ruby/object:Gem::Requirement
|
54
|
+
requirements:
|
55
|
+
- - ">="
|
56
|
+
- !ruby/object:Gem::Version
|
57
|
+
version: '3.1'
|
58
|
+
- - "<"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '5'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: actionview
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '3'
|
68
|
+
- - "<"
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '5'
|
71
|
+
type: :runtime
|
72
|
+
prerelease: false
|
73
|
+
version_requirements: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '3'
|
78
|
+
- - "<"
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '5'
|
81
|
+
description: Provides a Rails form builder to seamlessly setup a Knockout-js based
|
82
|
+
view model on your forms.
|
83
|
+
email:
|
84
|
+
- spalladino@manas.com.ar
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- ".gitignore"
|
90
|
+
- Gemfile
|
91
|
+
- LICENSE.txt
|
92
|
+
- README.md
|
93
|
+
- Rakefile
|
94
|
+
- knockout_forms-rails.gemspec
|
95
|
+
- lib/assets/javascripts/knockout-forms.rails.js
|
96
|
+
- lib/knockout_forms/rails.rb
|
97
|
+
- lib/knockout_forms/rails/form_builder.rb
|
98
|
+
- lib/knockout_forms/rails/helpers/form_helper.rb
|
99
|
+
- lib/knockout_forms/rails/version.rb
|
100
|
+
homepage: ''
|
101
|
+
licenses:
|
102
|
+
- MIT
|
103
|
+
metadata: {}
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
requirements: []
|
119
|
+
rubyforge_project:
|
120
|
+
rubygems_version: 2.2.2
|
121
|
+
signing_key:
|
122
|
+
specification_version: 4
|
123
|
+
summary: Knockout-js powered Rails form builder
|
124
|
+
test_files: []
|