- ROR Lab. Season 3 - 70 Biweekly Lecture Working with Javascript in Rails 2014-09-16 SeungKyun Nam
Agenda Ajax: Introduction Unobtrusive Javascript Built-in Helpers Ajax: Server-Side Concerns Turbolinks
Ajax: Introduction What is Ajax: Asynchronous Javascript and XML
Ajax: Introduction The origin of the term called 'Ajax' by Adaptive Path Blog post: Ajax: but ... A New Approach to Web Applications
Ajax: Introduction Understanding Request-Response Cycle
Ajax: Introduction Classic Model vs AJax Model
Ajax: Introduction Synchronous Model vs Asynchronous Model
Ajax: Introduction Defining Ajax Presentation: XHTML and CSS - HTML5 and CSS3 Document Object Model Data: XML and XSLT - (mostly JSON) Carrier: XMLHttpRequest Binding everything together: Javascript
Ajax: Introduction Sample Code // COFFEESCRIPT $.ajax(url: /test/lorem).done (html) - $(#results).append html // Generated JAVASCRIPT (function() { $.ajax({ url: /test/lorem }).done(function(html) { return $(#results).append(html); }); }).call(this);
Ajax: Introduction Demo
Unobtrusive Javascript Three main goals To separate JavaScript from HTML markup, as well as keeping modules of JavaScript independent of other modules. Unobtrusive JavaScript should degrade gracefully - all content should be available without all or any of the JavaScript running successfully. Unobtrusive JavaScript should not degrade the accessibility of the HTML, and ideally should improve it, whether the user has personal disabilities or are using an unusual, or unusually configured, browser.
Tip: To complie CoffeeScript without top-level function safety wrapper # Compile the Javascript without the top-level function safety wrapper # CoffeeScript Option -b or --bare Tilt::CoffeeScriptTemplate.default_bare = true config/environment.rb
Traditional Way Inline Javascript a href=# onclick=this.style.backgroundColor='#009900';this.style.color='#FFFFFF' Paint it green /a
Traditional (Better) Way Using Functions paintIt = (element, backgroundColor, textColor) - element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor a href=# onclick=paintIt(this, '#990000')Paint it red/a a href=# onclick=paintIt(this, '#009900', '#FFFFFF')Paint it green/a
Unobtrusive Way paintIt = (element, backgroundColor, textColor) - element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor $ - $(a[data-background-color]).click - backgroundColor = $(this).data(background-color) textColor = $(this).data[text-color] paintIt(this, backgroundColor, textColor) a href=# data-background-color=#990000Paint it red/a a href=# data-background-color=#009900 data-text-color=#FFFFFFPaint it green/a a href=# data-background-color=#000099 data-text-color=#FFFFFFPaint it blue/a
Unobtrusive Javascript Demo
Built-in Helpers Rails Ajax helpers are in two parts Javascript half - rails.js Ruby half - add appropriate tags to DOM
form_for %= form_for(@post, remote: true) do |f| % ... % end % !-- Generated HTML -- form accept-charset=UTF-8 action=/posts class=new_post data-remote=true id=new_post method=post ... /form
form_for Adding Ajax Event $(document).ready - $(#new_post).on(ajax:success), (e, data, status, xhr) - $(#new_post).append xhr.responseText ).bind ajax:error, (e, data, status, error) - $(#new_post).append pERROR/p
form_tag %= form_tag('/posts', remote: true) %
link_to %= link_to a post, @post, remote: true % !-- Generated HTML -- a href=/posts/1 data-remote=truea post/a
link_to Adding Ajax Event %= link_to Delete Post, @post, remote: true, method: :delete % $ - $(a[data-remote]).on ajax:success, (e, data, status, xhr) - alert The post was deleted.
button_to %= button_to A post, @post, remote: true % !-- Generated HTML -- form action=/posts/1 class=button_to data-remote=true method=post divinput type=submit value=A post/div /form
Built-in Helpers Demo
Server-Side Concerns
Server-Side Concerns by Example class UsersController ApplicationController def index @users = User.all @user = User.new end # ... end bUsers/b ul id=users li /li /ul br br app/views/users/index.html.erb app/controllers/users_controller.rb li /li app/views/users/_user.html.erb
Server-Side Concerns by Example # ... def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.js {} format.json { render json: @user, status: :created, location: @user } else format.html { render action: new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end # ... app/controllers/users_controller.rb
Server-Side Concerns by Example $(%= escape_javascript(render @user) %).appendTo(#users) app/views/users/create.js.erb
Server-Side Concerns Demo
Turbolinks Rails 4 Default Turbolinks Gem Uses Ajax to speed up page rendering PushState
Turbolinks How it works attaches a click handler to all a tags check if browser supports PushState if so, make an Ajax request parse the response replace the entire body change the URL using PushState
PushState a part of HTML5 History-API !doctype html html head titlePushState Example/title script language=javascript
Using Turbolinks # Turbolinks makes following links in your web application faster. # Read more: https://github.com/rails/turbolinks gem 'turbolinks' Gemfile //= require turbolinks app/assets/javascripts/applications.js
Turbolinks To disable Turbolinks for certain links a href=... data-no-turbolinksNo turbo links here/a. using data-no-turbolinks attribute
Turbolinks Troubleshooting $(document).ready - alert page has loaded! # This event will not work because of Turbolinks $(document).on page:change, - alert page has loaded! # This will work!
Turbolinks Demo
Thank you

Working with Javascript in Rails

  • 1.
    - ROR Lab.Season 3 - 70 Biweekly Lecture Working with Javascript in Rails 2014-09-16 SeungKyun Nam
  • 2.
    Agenda Ajax: Introduction Unobtrusive Javascript Built-in Helpers Ajax: Server-Side Concerns Turbolinks
  • 3.
    Ajax: Introduction Whatis Ajax: Asynchronous Javascript and XML
  • 4.
    Ajax: Introduction Theorigin of the term called 'Ajax' by Adaptive Path Blog post: Ajax: but ... A New Approach to Web Applications
  • 5.
    Ajax: Introduction UnderstandingRequest-Response Cycle
  • 6.
    Ajax: Introduction ClassicModel vs AJax Model
  • 7.
    Ajax: Introduction SynchronousModel vs Asynchronous Model
  • 8.
    Ajax: Introduction DefiningAjax Presentation: XHTML and CSS - HTML5 and CSS3 Document Object Model Data: XML and XSLT - (mostly JSON) Carrier: XMLHttpRequest Binding everything together: Javascript
  • 9.
    Ajax: Introduction SampleCode // COFFEESCRIPT $.ajax(url: /test/lorem).done (html) - $(#results).append html // Generated JAVASCRIPT (function() { $.ajax({ url: /test/lorem }).done(function(html) { return $(#results).append(html); }); }).call(this);
  • 10.
  • 11.
    Unobtrusive Javascript Threemain goals To separate JavaScript from HTML markup, as well as keeping modules of JavaScript independent of other modules. Unobtrusive JavaScript should degrade gracefully - all content should be available without all or any of the JavaScript running successfully. Unobtrusive JavaScript should not degrade the accessibility of the HTML, and ideally should improve it, whether the user has personal disabilities or are using an unusual, or unusually configured, browser.
  • 12.
    Tip: To complieCoffeeScript without top-level function safety wrapper # Compile the Javascript without the top-level function safety wrapper # CoffeeScript Option -b or --bare Tilt::CoffeeScriptTemplate.default_bare = true config/environment.rb
  • 13.
    Traditional Way InlineJavascript a href=# onclick=this.style.backgroundColor='#009900';this.style.color='#FFFFFF' Paint it green /a
  • 14.
    Traditional (Better) Way Using Functions paintIt = (element, backgroundColor, textColor) - element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor a href=# onclick=paintIt(this, '#990000')Paint it red/a a href=# onclick=paintIt(this, '#009900', '#FFFFFF')Paint it green/a
  • 15.
    Unobtrusive Way paintIt= (element, backgroundColor, textColor) - element.style.backgroundColor = backgroundColor if textColor? element.style.color = textColor $ - $(a[data-background-color]).click - backgroundColor = $(this).data(background-color) textColor = $(this).data[text-color] paintIt(this, backgroundColor, textColor) a href=# data-background-color=#990000Paint it red/a a href=# data-background-color=#009900 data-text-color=#FFFFFFPaint it green/a a href=# data-background-color=#000099 data-text-color=#FFFFFFPaint it blue/a
  • 16.
  • 17.
    Built-in Helpers RailsAjax helpers are in two parts Javascript half - rails.js Ruby half - add appropriate tags to DOM
  • 18.
    form_for %= form_for(@post,remote: true) do |f| % ... % end % !-- Generated HTML -- form accept-charset=UTF-8 action=/posts class=new_post data-remote=true id=new_post method=post ... /form
  • 19.
    form_for Adding AjaxEvent $(document).ready - $(#new_post).on(ajax:success), (e, data, status, xhr) - $(#new_post).append xhr.responseText ).bind ajax:error, (e, data, status, error) - $(#new_post).append pERROR/p
  • 20.
  • 21.
    link_to %= link_toa post, @post, remote: true % !-- Generated HTML -- a href=/posts/1 data-remote=truea post/a
  • 22.
    link_to Adding AjaxEvent %= link_to Delete Post, @post, remote: true, method: :delete % $ - $(a[data-remote]).on ajax:success, (e, data, status, xhr) - alert The post was deleted.
  • 23.
    button_to %= button_toA post, @post, remote: true % !-- Generated HTML -- form action=/posts/1 class=button_to data-remote=true method=post divinput type=submit value=A post/div /form
  • 24.
  • 25.
  • 26.
    Server-Side Concerns byExample class UsersController ApplicationController def index @users = User.all @user = User.new end # ... end bUsers/b ul id=users li /li /ul br br app/views/users/index.html.erb app/controllers/users_controller.rb li /li app/views/users/_user.html.erb
  • 27.
    Server-Side Concerns byExample # ... def create @user = User.new(params[:user]) respond_to do |format| if @user.save format.html { redirect_to @user, notice: 'User was successfully created.' } format.js {} format.json { render json: @user, status: :created, location: @user } else format.html { render action: new } format.json { render json: @user.errors, status: :unprocessable_entity } end end end # ... app/controllers/users_controller.rb
  • 28.
    Server-Side Concerns byExample $(%= escape_javascript(render @user) %).appendTo(#users) app/views/users/create.js.erb
  • 29.
  • 30.
    Turbolinks Rails 4Default Turbolinks Gem Uses Ajax to speed up page rendering PushState
  • 31.
    Turbolinks How itworks attaches a click handler to all a tags check if browser supports PushState if so, make an Ajax request parse the response replace the entire body change the URL using PushState
  • 32.
    PushState a partof HTML5 History-API !doctype html html head titlePushState Example/title script language=javascript
  • 33.
    Using Turbolinks #Turbolinks makes following links in your web application faster. # Read more: https://github.com/rails/turbolinks gem 'turbolinks' Gemfile //= require turbolinks app/assets/javascripts/applications.js
  • 34.
    Turbolinks To disableTurbolinks for certain links a href=... data-no-turbolinksNo turbo links here/a. using data-no-turbolinks attribute
  • 35.
    Turbolinks Troubleshooting $(document).ready- alert page has loaded! # This event will not work because of Turbolinks $(document).on page:change, - alert page has loaded! # This will work!
  • 36.
  • 37.