Skip to content

Commit

Permalink
Merge pull request #152 from basemate/resolving_issue_140
Browse files Browse the repository at this point in the history
Resolving issue 140
  • Loading branch information
jonasjabari committed Sep 5, 2019
2 parents 43237d6 + 66eea9a commit 759f9fe
Show file tree
Hide file tree
Showing 10 changed files with 292 additions and 141 deletions.
3 changes: 3 additions & 0 deletions app/concepts/matestack/ui/core/async/async.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ const componentDef = {
}
}
}
if(this.componentConfig["init_show"] == true){
this.showing = true
}
},
beforeDestroy: function() {
const self = this
Expand Down
93 changes: 90 additions & 3 deletions docs/components/async.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,13 @@ end

**Note:** The `rerender_on` option lets you rerender parts of your UI asynchronously, which is cool. But please consider that, if not configured differently, it a) is **not** _lazily loaded_ and b) does get displayed on initial pageload.

Lazy (or defered) loading is a feature we're working on right now, for details see [here](https://github.com/basemate/matestack-ui-core/issues/58).
Lazy (or defered) loading can be configured like shown [here](#defer).

If you want to hide the async component on initial pageload and display it later on, read below as this option (`show_on`) is already implemented (and can be combined with `rerender_on`)!
If you want to simply hide the async component on initial pageload and display it later on, read below how to use `show_on`, which can be combined with `rerender_on`.

### Show_on

The `show_on` option lets us define an event on which the component gets shown.
The `show_on` option lets us define an event on which the component gets shown. The content is still rendered on init pageload, but simply hidden in the browser until the event is emitted. If you want to have proper deferred loading, please refer to [defer](#defer)

```ruby
async show_on: 'my_event' do
Expand Down Expand Up @@ -66,6 +66,30 @@ async hide_after: 1000 do
end
```

### Shown_on/Hide_on Combination

If you combine `shown_on` and `hide_on`, you can toggel the view state of the `async` component explicitly.

By default, the content is initially hidden until the show event is emitted when `shown_on` is applied.

```ruby
async shown_on: "my_show_event", hide_on: 'my_hide_event' do
div id: 'my-div' do
plain 'You will not see me after the event'
end
end
```

If you want to display the content initially, simply add `init_show: true`

```ruby
async shown_on: "my_show_event", hide_on: 'my_hide_event', init_show: true do
div id: 'my-div' do
plain 'You will not see me after the event'
end
end
```

### Defer

The `defer` option may be used in two ways:
Expand Down Expand Up @@ -203,6 +227,69 @@ end

As expected, the timestamp is only visible _before_ our event was fired and is hidden/invisible _after_ the event!

### Example 3.1: Rerender/Show/Hide Combination for inline editing

Imagine, you want to create an inline edit form. Using a combination of `show_on`, `hide_on`, `init_show:true` and `rerender_on` allows you to implement this easily like shown below:


```ruby
class ExamplePage < Matestack::Ui::Page

def prepare
@my_model = MyModel.find(42)
end

def response
components {
partial :show_value
partial :show_form
}
end

def show_value
partial {
async rerender_on: "item_updated", show_on: "item_updated", hide_on: "update_item", init_show: true do
onclick emit: "update_item" do
plain @my_model.title
end
end
}
end

def show_form
partial {
async rerender_on: "item_updated", show_on: "update_item", hide_on: "item_updated" do
form some_form_config, :include do
form_input key: :title, type: :text
form_submit do
button text: "save"
end
end
onclick emit: "item_updated" do
button text: "abort"
end
end
}
end

def some_form_config
{
for: @my_model,
method: :post,
path: :inline_form_action_path, #or any other rails route
params: {
id: @my_model.id
},
success:{
emit: "item_updated"
}
}
end

end
```
If you click on the attribute value, the form gets shown. After successful form submission, the form gets hidden again and only the simple value is shown.

### Example 4: Hide after show on event

On our example page, we wrap a simple timestamp in an async component and tell it to show up when the event `my_event` gets triggered and be hidden after 1000ms.
Expand Down
18 changes: 18 additions & 0 deletions spec/dummy/app/controllers/my_app_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ def collection
responder_for(Pages::MyApp::Collection)
end

def inline_edit
responder_for(Pages::MyApp::InlineEdit)
end

def some_action
render json: {}, status: :ok
end
Expand All @@ -47,6 +51,20 @@ def form_action
end
end

def inline_form_action
@dummy_model = DummyModel.find(params[:id])
@dummy_model.update(dummy_model_params)
if @dummy_model.errors.any?
render json: {
errors: @dummy_model.errors,
message: "Test Model could not be saved!"
}, status: :unproccessable_entity
else
broadcast "test_model_created"
render json: @dummy_model, status: :created
end
end

def delete_dummy_model
@dummy_model = DummyModel.find(params[:id])
if @dummy_model.destroy
Expand Down
3 changes: 3 additions & 0 deletions spec/dummy/app/matestack/apps/my_app.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ def navigation_section
transition path: :collection_path do
button text: "Collection"
end
transition path: :inline_edit_path do
button text: "Inline Edit"
end
end
}
end
Expand Down
58 changes: 58 additions & 0 deletions spec/dummy/app/matestack/pages/my_app/inline_edit.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
class Pages::MyApp::InlineEdit < Matestack::Ui::Page

def prepare
@my_model = DummyModel.last
end

def response
components {
heading size: 2, text: "Inline Edit"

partial :show_value
partial :show_form
}
end

def show_value
partial {
async rerender_on: "item_updated", show_on: "item_updated", hide_on: "update_item", init_show: true do
onclick emit: "update_item" do
plain @my_model.title
plain "(click me)"
end
end
}
end

def show_form
partial {
async rerender_on: "item_updated", show_on: "update_item", hide_on: "item_updated" do
form some_form_config, :include do
form_input key: :title, type: :text
form_submit do
button text: "save"
end
end
onclick emit: "item_updated" do
button text: "abort"
end
end
}
end

def some_form_config
{
for: @my_model,
method: :post,
path: :inline_form_action_path,
params: {
id: @my_model.id
},
success:{
emit: "item_updated"
}
}
end


end
4 changes: 4 additions & 0 deletions spec/dummy/app/matestack/pages/my_app/my_first_page.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
class Pages::MyApp::MyFirstPage < Matestack::Ui::Page

def prepare
@my_model = DummyModel.last
end

def response
components {
heading size: 2, text: "This is Page 1"
Expand Down
2 changes: 2 additions & 0 deletions spec/dummy/config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
get 'my_fifth_page', to: 'my_app#my_fifth_page'
get 'my_sixth_page', to: 'my_app#my_sixth_page'
get 'collection', to: 'my_app#collection'
get 'inline_edit', to: 'my_app#inline_edit'

post 'some_action', to: 'my_app#some_action'
post 'form_action', to: 'my_app#form_action'
post 'inline_form_action/:id', to: 'my_app#inline_form_action', as: "inline_form_action"

delete 'delete_dummy_model', to: 'my_app#delete_dummy_model'
end
Expand Down
61 changes: 60 additions & 1 deletion spec/usage/components/async_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,66 @@ def response
expect(page).not_to have_selector "#my-div"
end

it "Example 3 - hide after show on event" do
it "Example 3.1 - Show on / Hide on combination init not shown by default" do

class ExamplePage < Matestack::Ui::Page

def response
components {
async show_on: "my_show_event", hide_on: "my_hide_event" do
div id: "my-div" do
plain "#{DateTime.now.strftime('%Q')}"
end
end
}
end

end

visit "/example"

expect(page).not_to have_selector "#my-div"

page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_show_event")')

expect(page).to have_selector "#my-div"

page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_hide_event")')

expect(page).not_to have_selector "#my-div"
end

it "Example 3.2 - Show on / Hide on combination init shown if configured" do

class ExamplePage < Matestack::Ui::Page

def response
components {
async show_on: "my_show_event", hide_on: "my_hide_event", init_show: true do
div id: "my-div" do
plain "#{DateTime.now.strftime('%Q')}"
end
end
}
end

end

visit "/example"

expect(page).to have_selector "#my-div"

page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_hide_event")')

expect(page).not_to have_selector "#my-div"

page.execute_script('MatestackUiCore.matestackEventHub.$emit("my_show_event")')

expect(page).to have_selector "#my-div"
end


it "Example 3.3 - hide after show on event" do

class ExamplePage < Matestack::Ui::Page

Expand Down
Loading

0 comments on commit 759f9fe

Please sign in to comment.