-
Notifications
You must be signed in to change notification settings - Fork 68
That’s separating markup and HTML, e.g. not putting JS into an onclick
attribute but in a detached observer.
Apotomo does not implement UJS with any magic but provides some tools for having clean separation.
Assuming we got the following mouse widget, which will initially display a button. When clicked, it re-renders the button showing the time the button was clicked.
class MouseWidget < Apotomo::StatefulWidget def display respond_to_event :squeak, :with => :squeak render end def squeak @time = Time.now render :view => :display # reuse the display view. end end
The widget view provides the method widget_javascript
that accepts a script block. Basically that just generates a <script...>
container.
The view mouse_widget/display.html.haml
might look like this.
= h1 "Squeaked at #{@time}!" = submit_tag "Squeak!", :id => 'click-me' - widget_javascript do $('click-me').on('click', function(event) { = "new Xhr('#{url_for_event :click}').send();" });
which renders to
<div id="mouse"> <h1>Squeaked at !</h1> <input id="click-me" name="commit" type="submit" value="Squeak!" /> <script type="text/javascript"> $('click-me').on('click', function(event) { new Xhr('/dashboard/render_event_response?source=click_me&type=click').send(); }); </script> </div>
The first time the widget is rendered, it will inject the script into the page. However, when clicked, it will re-inject the script again since the squeak method reuses that view.
One way would be to suppress script rendering in the squeak state. The state method would be changed as follows.
def squeak @time = Time.now render :view => :display, :suppress_js => true end
The output of squeak would be just
<div id="mouse"> <h1>Squeaked at 02:40:33!</h1> <input id="click-me" name="commit" type="submit" value="Squeak!" /> </div>
Another way is to put the scripts in a separate file, which could look like that.
".widget".on('click', function(event) { new Xhr( $(this).get('data-event-url') ).send(); });
The JavaScript code is extracted to its own file whereas the widget view only contains the markup and some configuration.
= h1 "Squeaked at #{@time}!" = submit_tag "Squeak!", :class => 'widget', 'data-event-url' => url_for_event(:click)
Thanks to Nikolay V. Nemshilov [MadRabbit], the author of RightJS who spent hours explaining me all the bits and bytes of different JavaScript frameworks, UJS and inline JavaScript.