Skip to content

Commit

Permalink
Add support for selectable strings on edit pages
Browse files Browse the repository at this point in the history
Feature:

As an admin
I want to select values from a drop-down
rather than enter them free-form
So that I don't need to worry about data integrity
And so that I have a streamlined experience.

Implementation:

Add `Administrate::Field::Select`
as an option to present string attributes.
The field displays its attribute as a drop-down field on form pages.

Usage in a dashboard:

```ruby
kind: Field::Select.with_options(collection: Customer::KINDS),
```
  • Loading branch information
Jberlinsky authored and c-lliope committed Mar 29, 2016
1 parent e9a7134 commit 3bccdb3
Show file tree
Hide file tree
Showing 12 changed files with 126 additions and 6 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@

### Upcoming Release

* [#422] [FEATURE] Add a `Select` field for displaying a drop-down menu of
options on form pages.
Options:
```ruby
Field::Select.with_options(collection: [:foo, :bar])
```
* [#458] [BUGFIX] Update the custom field generator to match the new HTML
structure of forms

Expand Down
31 changes: 31 additions & 0 deletions app/views/fields/select/_form.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<%#
# Select Index Partial
This partial renders a selectable text attribute,
to be displayed on a resource's edit form page.
## Local variables:
- `f`:
A Rails form generator, used to help create the appropriate input fields.
- `field`:
An instance of [Administrate::Field::Select][1].
A wrapper around the attribute pulled from the database.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Select
%>

<div class="field-unit__label">
<%= f.label field.attribute %>
</div>
<div class="field-unit__field">
<%= f.select(
field.attribute,
options_from_collection_for_select(
field.selectable_options,
:to_s,
:to_s,
field.data.presence,
)
) %>
</div>
16 changes: 16 additions & 0 deletions app/views/fields/select/_index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%#
# Select Index Partial
This partial renders a selectable text attribute,
to be displayed on a resource's index page.
## Local variables:
- `field`:
An instance of [Administrate::Field::Select][1].
A wrapper around the attribute pulled from the database.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Select
%>

<%= field.data %>
16 changes: 16 additions & 0 deletions app/views/fields/select/_show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<%#
# Select Show Partial
This partial renders a selectable text attribute,
to be displayed on a resource's show page.
## Local variables:
- `field`:
An instance of [Administrate::Field::Select][1].
A wrapper around the attribute pulled from the database.
[1]: http://www.rubydoc.info/gems/administrate/Administrate/Field/Select
%>

<%= field.data %>
1 change: 1 addition & 0 deletions docs/customizing_dashboards.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ specify, including:
- `Field::Image`
- `Field::Number`
- `Field::Polymorphic`
- `Field::Select`
- `Field::String`

Each of the `Field` types take a different set of options,
Expand Down
1 change: 1 addition & 0 deletions lib/administrate/base_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
require "administrate/field/image"
require "administrate/field/number"
require "administrate/field/polymorphic"
require "administrate/field/select"
require "administrate/field/string"
require "administrate/field/text"

Expand Down
21 changes: 21 additions & 0 deletions lib/administrate/field/select.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
require_relative "base"

module Administrate
module Field
class Select < Field::Base
def self.searchable?
true
end

def selectable_options
collection
end

private

def collection
@collection ||= options.fetch(:collection, [])
end
end
end
end
8 changes: 7 additions & 1 deletion spec/example_app/app/dashboards/customer_dashboard.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ class CustomerDashboard < Administrate::BaseDashboard
name: Field::String,
orders: Field::HasMany,
updated_at: Field::DateTime,
kind: Field::Select.with_options(collection: Customer::KINDS),
}

COLLECTION_ATTRIBUTES = ATTRIBUTE_TYPES.keys
SHOW_PAGE_ATTRIBUTES = ATTRIBUTE_TYPES.keys - [:name]
FORM_ATTRIBUTES = [:name, :email, :email_subscriber]
FORM_ATTRIBUTES = [
:name,
:email,
:email_subscriber,
:kind,
].freeze

def display_resource(customer)
customer.name
Expand Down
5 changes: 5 additions & 0 deletions spec/example_app/app/models/customer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ class Customer < ActiveRecord::Base
validates :name, presence: true
validates :email, presence: true

KINDS = [
:standard,
:vip,
].freeze

def lifetime_value
orders.map(&:total_price).reduce(0, :+)
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class AddKindToCustomer < ActiveRecord::Migration
def change
add_column :customers, :kind, :string, null: false, default: "standard"
end
end
11 changes: 6 additions & 5 deletions spec/example_app/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20150916011117) do
ActiveRecord::Schema.define(version: 20160119024340) do

# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"

create_table "customers", force: :cascade do |t|
t.string "name", null: false
t.string "email", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name", null: false
t.string "email", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.boolean "email_subscriber"
t.string "kind", default: "standard", null: false
end

create_table "delayed_jobs", force: :cascade do |t|
Expand Down
11 changes: 11 additions & 0 deletions spec/features/edit_page_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,15 @@

expect(page).to have_content("true")
end

it "displays selectable strings as dropdowns", :js do
customer = create(:customer, kind: :standard)

visit edit_admin_customer_path(customer)
select "vip", from: "Kind"
click_on "Update Customer"

expect(page).to have_content("KIND")
expect(page).to have_content("vip")
end
end

0 comments on commit 3bccdb3

Please sign in to comment.