"Refreshing" a widget from a controller

43 views
Skip to first unread message

Troy Rosenberg

unread,
Feb 3, 2014, 5:29:22 PM2/3/14
to cells-an...@googlegroups.com
I am attempting to use Apotomo to update a widget through a controller action.

In my controller I am calling the action like so:

def destroy
# ...
apotomo_root.find_widget(:account_actions_dropdown).trigger(:update_current_account)
respond_to do |format|
format.json { render json: { message: message } }
end
end

this controller action is being invoke via an AJAX call:

$.ajax
url: "#{@href.replace("#", "")}/all"
type: "POST"
dataType: "json"
data:
_method: "delete"
ids: aSelected
all: all_selected
text: text
success: (data) ->
fieldsTable.fnDraw()
hide_loading()
$("html, body").animate({ scrollTop: $('.navbar-fixed-top')[0].offsetTop }, "slow");
create_flash(data['message'])

the goal is to delete elements from a DataTables table and redraw the table without having to refresh the page.

We also need to update out navigation menu, this is where we are attempting to use Apotomo.

class AccountActionsDropdownWidget < Apotomo::Widget
helper ApplicationHelper
include Devise::Controllers::Helpers
 
helper_method :current_user
helper_method :current_account
helper_method :current_account_name
 
responds_to_event :update_current_account, with: :update_current_account
 
def display
puts 'Displaying'
p current_account
render
end
 
def account_required_actions
render if current_account
end
 
def update_current_account
puts "Updating current account."
replace state: :display
end
 
private
 
def current_account
current_user.try(:current_account)
end
 
def current_account_name
current_account ? current_account.account_name : 'Account Name:'
end
end

when following along in the logs are through debugger the display action is being rendered but the interface does not change.

Updating current account.
Displaying
Account Load (0.6ms)
# ActiveRecord output...
Rendered app/widgets/account_actions_dropdown/account_required_actions.html.erb (13.6ms)
Rendered text template (0.0ms)
Rendered app/widgets/account_actions_dropdown/display.html.erb (19.0ms)
Rendered text template (0.0ms)

I have tried different methods in my update_current_account_trigger such as update, I have also tried render_state from the controller.

This gist should be more readable.

Any advice would be appreciated.

Thank you,
Troy 


Nick Sutterer

unread,
Feb 3, 2014, 7:41:42 PM2/3/14
to cells-an...@googlegroups.com
So you wanna trigger the event manually for the widget? Usually, this should happen via the widget's UI, e.g. when you press a link the respective event gets triggered in the widget, it re-renders and sends back the JS.

To do that manually, you might try this:

widget = apotomo_root.find_widget(:account_actions_dropdown)
widget.trigger(:update_current_account)
widget.page_updates #=> this is the output generated by the event.


--
Sie erhalten diese Nachricht, weil Sie Mitglied der Google Groups-Gruppe "Cells and Apotomo" sind.
Um Ihr Abonnement für diese Gruppe zu beenden und keine E-Mails mehr von dieser Gruppe zu erhalten, senden Sie eine E-Mail an cells-and-apot...@googlegroups.com.
Weitere Optionen: https://groups.google.com/groups/opt_out

Troy Rosenberg

unread,
Feb 4, 2014, 5:36:52 PM2/4/14
to cells-an...@googlegroups.com
Using widget.page_updates in the controller did not seem to do it for us.

What we ended up doing that worked was adding a callback in the initial AJAX request (that was made to AccountContoller#destroy).

This callback worked two different ways.

The first time we had it make an ajax request similar to http://localhost:3000/dashboard/render_event_response?source=twitter&type=submit&text=Hey (from here) replacing the necessary data (e.g. source=account and type=update_current_account).

this worked.

We then successfully tried adding a hidden form to our display view:

  <%= form_tag url_for_event(:update_current_account), method: :post, remote: true do %>
  <% end %>

which we then triggered in our CoffeeScript like so:

updateAccountActionsDropdown = () ->
    $('#account_actions_dropdown form').trigger('submit.rails')


We are not 100% sure why it went into the widget but only worked with the exact request but this seems to have worked.

Thank you for the help and great work +Nick

Nick Sutterer

unread,
Feb 4, 2014, 8:22:29 PM2/4/14
to cells-an...@googlegroups.com
Hm, that seems odd. You should be able to trigger an event on a widget in the controller and then access the generated JS/HTML in widget.page_updates. What's in your page_updates after triggering the event in the controller?

Nick Sutterer

unread,
Feb 4, 2014, 8:23:39 PM2/4/14
to cells-an...@googlegroups.com
Oh, of course, you still need to send back/process the generated JS/HTML yourself if you trigger events in the controller. Only when an event is triggered by the UI (using url_for_event) this is done automatically.

Troy Rosenberg

unread,
Feb 5, 2014, 8:26:28 AM2/5/14
to cells-an...@googlegroups.com
widget.page_updates was returning an empty array for me after triggering the even in the controller. 

Nick Sutterer

unread,
Feb 5, 2014, 4:18:03 PM2/5/14
to cells-an...@googlegroups.com
It should be an array of rendered JS/HTML. I think you have to to apotomo_root.page_updates.

Troy Rosenberg

unread,
Feb 6, 2014, 10:23:38 AM2/6/14
to cells-an...@googlegroups.com
apotomo_root.page_updates is also returning an empty array.

[39, 48] in.../app/controllers/accounts_controller.rb
   39    def destroy
   40      resp = AccountRemover.new(current_user, ids_to_delete, params['text'].to_sym).remove_accounts
   41      widget = apotomo_root.find_widget(:account_actions_dropdown)
   42      widget.trigger(:update_current_account)
   43      debugger
=> 44      widget.page_updates #=> this is the output generated by the event.
   45      respond_to do |format|
   46        format.html {  }
   47        format.json { render json: generate_destroy_flash_message(resp) }
   48        format.js { render nothing: true }
(rdb:1) p  apotomo_root.page_updates
[]
(rdb:1) p widget.page_updates
[]

Nick Sutterer

unread,
Feb 6, 2014, 4:10:57 PM2/6/14
to cells-an...@googlegroups.com
Are you sure the trigger does invoke the desired state? Please paste the widget code.

Troy Rosenberg

unread,
Feb 7, 2014, 3:17:37 PM2/7/14
to cells-an...@googlegroups.com
the logs show the puts statements:

Updating current account.
Displaying
Account Load (0.6ms)
# ActiveRecord output...
Rendered app/widgets/account_actions_dropdown/account_required_actions.html.erb (13.6ms)
Rendered text template (0.0ms)
Rendered app/widgets/account_actions_dropdown/display.html.erb (19.0ms)
Rendered text template (0.0ms)

I've also tried replace view: :display

This gist should have all relevant code.

Nick Sutterer

unread,
Feb 9, 2014, 6:25:40 PM2/9/14
to cells-an...@googlegroups.com
I added a test and it works: https://github.com/apotonick/apotomo/blob/e74a65b4c7dfc7e20b8cf665d2f6f9f25128b19e/test/rails/rails_integration_test.rb#L79

It doesn't really matter if you use render, replace, or update, they all just generate a string of JS/HTML that gets than added to page_updates.

The #destroy action should look like the following:

def destroy
# ...
apotomo_root.find_widget(:account_actions_dropdown).trigger(:update_current_account)
respond_to do |format|
format.json { render json: { message: apotomo_root.page_updates.join("") } }
end
end

Troy Rosenberg

unread,
Feb 14, 2014, 10:30:22 AM2/14/14
to cells-an...@googlegroups.com
I apologize for the delayed response; I finally had some time to revisit this today and it looks like everything is working correctly now.

Thank you very much for all of your help and support.

I have updated my gist to show what I have ended up doing, hopefully this will serve to help someone in the future.

Thank you,

Troy

Nick Sutterer

unread,
Feb 16, 2014, 4:18:02 PM2/16/14
to cells-an...@googlegroups.com
Awesome, Troy. I'm intrigued to know what was wrong with the page_updates? Anyway, good work.
Reply all
Reply to author
Forward
0 new messages