How To Add jQuery and Ajax To Your Rails App

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today in the studio I'll show you how to add a dash of JavaScript to your rails app hey folks Mike Clark here with the pragmatics studio and today we're gonna spice up a rails app with a few dashes of JavaScript well add some effects with jQuery and also send an ajax request now if you're already comfortable with rails but you're new to JavaScript well this is what your appetite for what's possible if you already know JavaScript and jQuery this will show you how to start working with it in rails there's gonna be a lot of fun so let's go ahead and get started our application lets users list items for sale now the springs finally here it's time to clean out that garage for example here's a fun looking unicycle that's in pretty good condition and we just see that we've got the unicycles description and it looks like three folks left a comment for us down below here and then we have a forum below that for submitting a new comment now this is a pretty good start but we actually don't want to show all these comments by default when we load the page instead we want to hide the comments and then if you click on this comment link we want to toggle all the comments in the comment form on and off and we can do all that dynamically with JavaScript so let's start by looking at the structure of this page over in the rails template okay so I'm in the app views directory the item subdirectory and we've got the show dot HTML DRB and here's our template right here here's that link for the comments and currently it doesn't go anywhere and then we've got a section down below it called a comment section so a section ID comment section there and then we've got an ordered list with the ID of comments and inside that you notice we rendered this collection of comments which is in the add comments instance variable and by convention what rails is going to do here is for every object that's in that collection because it's a comment object it's gonna look for a partial to render and we have that partial up in-app use comments underscore comment HTML Rd RB it's gonna call that partial for every object in the collection so if we look in that we noticed it's just one line item and then inside of this template we can use the comment local variable which will have the next comment that's in that collection so you can think of this as just looping through the collection and rendering that partial for each object in the collection and then down below that we have our comment form and the forum post to the create action of the it's controller if any of this is unfamiliar you might want to check out our rails level one online course we go over all this stuff and a whole bunch more so in doing any sort of JavaScript it really helps to start with a good structure where you've got things like sections and IDs and then things partitioned out into different partials like this so we've got a good start here so our first task is just to hide this comment area this entire section and we can do that with some CSS we don't need any JavaScript to do this I'm going to go over to the assets directory inside of Style Sheets I've got a bunch of style sheets in here one of them specific the comments comments that s CSS I'm just gonna add a CSS rule here it's gonna be a rule for the HTML element that has the ID comments - section that's the ID that was in the template and we'll set its display to none that's how we hide that then if we reload our page while the comments disappear that's exactly what we want so our next task is we need to show the comments when we click on this comments link so let's go have a look at that link again so here's the link back over in the show template and by default rails uses a technique called unobtrusive javascript to attach javascript tĂȘte elements inside of the dom that's the structure of the HTML page and to make that work we need some way to identify this link in the dom and we're gonna do that is we're gonna add an ID to this link the ID is gonna be called comments - link now it's time to write some JavaScript and our JavaScript goes up in the app assets Java scripts directory we have one file in there right now application j/s this is a manifest file that basically lists all the JavaScript that we want inside of our rails application you notice by default it's requiring the jQuery library as well as the jQuery UJS that's unobtrusive javascript we've got the turbolinks library and also you notice this directive that says require underscore tree dot or dot is the current directory so it's going to look for any JavaScript files that are in this directory and go ahead and include them in the manifest so all the files in the directory will then get packaged up in a single file and it'll be minified and compressed in production which means that it'll get downloaded on the first page load and then it'll be cached every time after that so any files we put in here will ultimately get loaded into our browser so we're gonna create a new file in here and I'm gonna call it comments because I'm working on comment stuff normally you might give this a j/s extension if you want to write straight JavaScript that's the way to go but rails actually prefers CoffeeScript which is just a lightweight language a more elegant way to write JavaScript that compiles down into JavaScript code and I much prefer it over writing just straight JavaScript so we're gonna give it the doc coffee extension so the first thing we need to do here is make sure that the document is fully loaded before running any JavaScript have to wait for all the elements on the page to be there before we can do anything with them to do that we're gonna use some jQuery and the jQuery method that you're probably gonna use most often is this dollar method and it takes some parameters you could think of this like a Swiss Army knife for hacking through the Dom it always returns a jQuery object based on the parameters that we give it in this particular case we're gonna give it the document so we said we want the document expressed as a jQuery object and then we could call methods on that jQuery object I'm gonna call the on method the on method here takes two parameters the first parameter is the event that we want to listen for we're gonna listen for the event page colon change and the second parameter is a function we want to run when that event is triggered the way we do functions in CoffeeScript is just this - arrow like that it'll define the function body in a minute now this is slightly different than the standard way in jQuery to wait for the document to be ready this page change event is a little bit different than that the reason we're using that here's rails plays some tricks to speed up page rendering when links are clicked inside of our app it does that using turbo links so this is the recommended way to wait for the page to be ready it'll get fired when the page is fully loaded and it's also fired when rails loads pages behind the scenes using turbo links so this is the way to go okay so when the page is ready we need to attach an event handler to when the element with the ID comments link is clicked so the first thing we need to do is just find that link inside of the Dom we use the dollar method again to do that this time we're going to give it a CSS selector as the string the selector we're interested in is comment - link the idea is comments - link like that if this was a class we would use dot but we set it up as an ID inside of that template so it's comments link that's going to find that inside of the Dom and then return it as the jQuery object we can then call a method on that jQuery object to click method because we're interested in click events the click method doesn't take two parameters notice the comma we have up here before the arrow so we just give it an arrow all at once is a function now it's important to point out that whitespace is significant in CoffeeScript so when we go to define this function we need to indent this another two spaces because we're giving statements that we want to have run when this click event happens in this particular case we're just gonna put up an alert that says clicked right so for whitespace notice we were indented two spaces there that's part of this function and we're indented two spaces up here that's part of that on methods function definition so CoffeeScript looks at the indentation to figure out which statements go with which functions you got to be a little bit careful about that okay let's try this out back over in the browser if we click on comments now while we get an alert box saying that it was clicked so now we know do we have everything hooked up okay so now we want to actually toggle this comment section we would need that comment section to show up when we click on this link so back over here in our CoffeeScript file instead of doing an alert what we want to do is find that comment section we can use the dollar function to do that it's called comments section that's the ID we gave to that section in the template and here we can call the toggle method now there's also a show and hide method but again we want to toggle this on and off and jQuery conveniently provides a toggle method to do that and all that does is toggle the visibility of the element in this case it's the comment section element by changing the CSS display property for us now back over on the page if I click on the comments here oh you we've got our three comments back with our comment form at the bottom I click it again the whole comment section goes away so that's exactly what we want now if we want to get a little bit fancy we might want to sort of feed these in you notice that it's a little bit abrupt when it kind of pops that in there like that so let's go back over here we can actually use the function fade toggle jQuery has a lot of really nice effect method built into it with that one now if we click on comments you notice it kind of fades into view here and when we uncheck it well it fades back out again so that just gives it a little bit more visual appeal now one more thing we might want to do here is be polite to put the cursor in this text box right here as soon as the comments are shown that way we're ready to type our first comment and that's pretty easy to do back over on our CoffeeScript file we're just going to add another statement to this clickhandler function and in this case what we want to do is go find that text area well by convention rails assigns an ID to the text area based on the model name and the attribute name that that text area is for and in this case the model name is comment and the attribute is called body so it's common underscore body in this case that's just the rails convention and then we can call the focus method on that so when our link is clicked we're gonna fade toggle and also set a focus in that text area like over here if we hit our comments we go down to the bottom notice that the cursor is already blinking in the text area and we're ready to write our first comment so let's go ahead and do that I'm gonna use the comment where are the handlebars I'm gonna hit post comment you notice we got a full-page reload and the comment section closed back up again because well we've got that displayed property set to none so it closed up the comments when we this page was reloaded so this is typically what happens when we post a form it's a synchronous request the request goes down to the server in this case the server is creating a new comment then is redirecting back to the browser to tell it to show the items show page and then the browser issues a new request and we have a full page reload but what we really want to do here is issue a request asynchronously a so called Ajax request we're going to use JavaScript inside of the browser to send that request down to the server the server's going to create the comment just like at norm but instead of sending back a redirect or issuing a redirect it's actually going to generate some JavaScript that will append the comment to our existing comment list and it's gonna send that JavaScript back down in the browser the browser is gonna evaluate that JavaScript which will update or modify the Dom to put that new comment on the list so we'll have an asynchronous request happening behind the scenes and then dynamically updating the page when the request is done so let's give that a shot so the first thing we need to do back over in our show template is set up this form to submit this request ajaxify or asynchronously the way we can do that is use an option on form 4 called remote and we're just going to set it to true and this tells rails to send the post requests asynchronously and expect a JavaScript response we're using the option on the forum for helper but this option is also available on the link to and the button to helpers so now that we have this ajaxify form the next step is to implement the functionality on the server to respond to the requests appropriately we do that by going over into our controllers directory this is the comments controller that's creating the comment and that's where this form is posting and we've got a create action right here and right now we're just redirecting to that item so we're handling an HTML response by doing that sort of redirect but we don't want to do a redirect when the form is asking for JavaScript back this only works for the standard HTML way of doing things so to respond to a JavaScript request we're gonna add what's called a respond to block so method and rails respond underscore - it takes a block and by convention the block parameter is usually called format let's just stick that right in there and then end like that and this respond to block lets us respond to whatever the client wants so in the case of HTML will take format HTML then what we want to do is this redirect so we use another block here we say alright if the client wants HTML then run this block of code which is going to do the redirect in our case we want some JavaScript back so if the format is JavaScript format j/s then we run or respond differently but instead of giving it a block here we're just gonna let the go ahead and fall through and do the default rendering that's built into rails and that means this is going to render a file in the Commons directory and the file is going to be called create which is the same name as the action JSE RB so let's go ahead and go create that file it's in our app views it's gonna be in the common subdirectory it's called create dot now normally it would be create each team LD RB we're gonna use the ER be templating system to generate HTML but in this case we're going to use the ARB templating system to generate JavaScript so it's create jsg RB and in this file we need to generate JavaScript code that it's going to append some HTML to the end of our list of comments so we're gonna start with our jquery function dollar we're gonna get our comments ordered list remember it has the ID of comments and then we're gonna call the append method on that and what are we gonna pin well we want to append some HTML right here what HTML should it be well we want to append the snippet of HTML that shows Danu Comet that's the comment that just got created and that comment is stored in the @ comment instance variable but we need to render that somehow we need a list item that shows that comment so how are we gonna do that well conveniently we already have a template that renders the HTML for a comment it's over here in our comment app views comments subdirectory its underscore comment on each team lr d RB this is the partial that renders one comment remember we use this partial when we're showing all the comments over here in our items we have this render at comments and i said by convention rails is going to call the partial underscore comment for every object that's in that collection and inside of that partial we just generate one line item well that's exactly what we want to do here we just want to render this one comment so because we're in an ARB template here generating javascript we can use standard ER be syntax less than percent equals render at comment by convention rails will look for that comp that comment partial we just looked at to render the comment this is JavaScript were rendering we need to put it inside of quotes that's what the append method once and also we need to escape whatever rendered HTML comes back so we get valid JavaScript we can do that very easily using the je method there now this is a standard JavaScript file we're generating JavaScript not CoffeeScript so we need a semicolon at the end of this line so I saved everything off now back over in the browser I need to reload because we changed that form for helper remember click on comments there's our comments we've got our field down below I'm just gonna add a new comment here did you lose the other wheel post a comment and look at that it just gets appended to the list we don't have a full reload of the page at all so we've got our ajaxify forum posting back to our server asynchronous requests and then we've get this dynamic update happening inside of the page which is pretty cool now one small problem you notice though is we're left with the last comment in that text area box would be really nice to just clear that out when we post a new comment and that's easy to fix back over here where we're generating some JavaScript I just need to get a hold of that text area will use our dollar function to do that again and this is called comment body that's the rails convention of that ID and then we have a Val function that's the value that's inside of that element and we're just gonna set it to an empty string now we'll post a new comment someone stole half your bike go ahead and post it there's the comment gets appended to the list and our text area field is now blank so just stepping back for a minute we're using ARB to generate JavaScript on the server that then gets run inside of the browser that's really powerful now before we wrap up there's one more problem we need to fix and to demonstrate the problem I'm gonna go over to a different item here I classify listing over to this bamboo fly rod it's got a really long description here if you go down here it's got a comment link if you click on the comment notice it pops this way back up to the top of the page we see the form got put in down here but every time we click on this thing we get popped up at the top of the page there and that's kind of annoying now the reason that's happening is because of the way that this link to here works even though we have a click handler that's set up that runs JavaScript when this link is clicked the link also does what all things do when we click it it wants to follow whatever the href is in the link in this particular case we've got it set up with just this hash sign now that's just a blank anchor and it refers to the current page so the default behavior when we click on a link is going to be the scroll to the top of that current page it's a fairly easy fix all we need to do is prevent the default link behavior from happening and that's going to happen back in the original file we created at the very beginning of this this comments dot coffee now this doesn't involve any Ajax this is just some JavaScript we wrote to dynamically change the page and remember we have this click handler setup on the comments link well the click handler will actually give us the event that triggered that this is a parameter to this function here the way CoffeeScript works is the parameter comes before the actual arrow which is a little bit difficult to get used to but just something to keep in mind so this is a parameter to the function down here and inside of the function we can take that event and call prevent default on it and that's a function and this simply tells the event object to prevent the browser's default action back on from our browser now if we go to bamboo fly rod and we click on comments well you notice it didn't jump back up to the top of the page it just stayed right there so it's a pretty easy fix it's pretty amazing what you can do with a few lines of JavaScript and the rails conventions now this is just the tip of the iceberg but I hope it helps you get started have fun with it and feel free to leave a comment below we'll see you next time
Info
Channel: The Pragmatic Studio
Views: 25,633
Rating: undefined out of 5
Keywords: Ruby On Rails (Software), Ajax (Programming Language), JQuery (Software)
Id: K-sns5tNdTY
Channel Id: undefined
Length: 19min 30sec (1170 seconds)
Published: Mon Jul 20 2015
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.