 All right, can everybody hear me okay? And the back, yeah, good. I'm going to assume that everyone read the updated session details, which is why this room is packed, that this is a BYOB session. So if you have it, as you can see, the organizers gave me a nice Bud Light to drink. So this is the Missifying AJAX Callback Commands in Drupal 8. I applaud you guys for coming to this session. Last session of a great conference, and it's a technical session, so your brains aren't completely mush yet. They will be at the end of this because there is code examples, but you should learn a lot hopefully. So let's get the nice of these out of the way. My name is Mike Miles. I'm from Boston, Massachusetts. I've been working with Drupal since 2008, doing everything you can think of with Drupal. Theming, site building, module development, large scale architecture is what I do most of the day now. I have a couple modules out there. I help run the Boston Drupal Meetup. I am AQUIA certified in MVP and all that jazz, so good for me. I work for a company called Genuine. I'm the associate director of PHP there. Genuine, we're not a Drupal shop. We're a full service digital first agency, so we do a lot more than just development and a lot more than just Drupal. We do video production, both digital and some traditional, brand engagement, brand strategy, design, UX, SEO, interactive applications for touchscreens and kiosks, and then development. We have three development teams, a .NET team who does SiteCorn and Braco. We have a front-end team who uses a lot of JavaScript frameworks and HTML and CSS and SAS and all that cool stuff, and then our PHP team, who 99% of the time we do Drupal. We have offices in Boston, Chicago, San Francisco, New York, fun company work for a lot of great projects. We're always hiring for multiple positions, so check us out, we are genuine, if you're interested. And if you wanna know any more about me after this session, you can find me anywhere online at MikeMiles86, so d.o, Twitter, IRC. It's not a clever username, but it is a consistent one. I dare someone to guess what year I was born. It's not 1886, I will tell you that. Or I look really good for my age. Okay, I have three goals for this session that I hope to accomplish. The first is to explain what exactly AJAX callback commands are. What they're composed of, code-wise, how they're used in Drupal, and how you can use them. I want to outline how to use the callback commands, how to write your own callback commands to really take control of AJAX functionality. And in doing that, I hope to demonstrate successfully how easy it is to use callback commands and create them for yourself. Now, in coming up with this session, I wanted to figure out a way to define AJAX callback commands in a single sentence. And I got really inspired by the city, so I came up with a local analogy. In Drupal, if an AJAX request were a bignet, then callback commands would be the powdered sugar. How many people here have been lucky enough to have bignets? All right, yeah, that's like 100% of the room. If you haven't, you have time to do it, and you have to. So let me explain this analogy a little bit. Bignets are fried delicious balls of dough that are covered in like three pounds of powdered sugar. You cannot have a bignet without powdered sugar. You cannot eat a bignet without getting powdered sugar all over yourself. And in Drupal, you cannot do AJAX functionality without using callback commands. Whether you know it or not, anytime you do AJAX functionality, anytime an AJAX event occurs in Drupal, it is using callback commands. So a more straightforward description is callback commands are the instructions that are built by the server and executed by the client in every AJAX event in Drupal. So when an AJAX request is made, the server is building a collection of commands to return back to the client, which are translated into JavaScript functions to be executed to manipulate the data on the page. All this functionality is provided by the AJAX framework, which is part of Drupal Core. Drupal 7 had the AJAX API, same thing, different name, some object-oriented stuff has happened, but the AJAX framework is responsible for all AJAX functionality. It provides some server-side interfaces and functions and code, as well as the front-end library in JavaScript to execute AJAX functions, AJAX requests. With the AJAX framework comes callback commands, and every callback command is made up of two parts. The first part is a JavaScript function that is attached to a global JavaScript object provided by the AJAX framework, which I will explain in a moment, and then a PHP class that implements an interface provided by the AJAX framework. In Drupal 7, callback commands were composed of a JavaScript function and a PHP function. Since we have symphony, we have object-oriented programming, so it's a PHP class. Callback commands are provided by Drupal Core in the AJAX framework, of which in Drupal 8, there are 25 core commands, and by modules. So an example of modules that provide JavaScript, AJAX callback commands, views, technically that's part of core, but the views module inside core still defines its own callback commands. The Ctools module is another good example that has custom callback commands. Wim Lears has a new module out called Refreshless, which uses AJAX callback commands, and then any modules you might write to use AJAX functionality will probably, after today, contain callback commands. So if we look a little deeper into what callback commands are on the JavaScript side, as I said, they are functions attached to a global object provided by AJAX, the AJAX framework in AJAX.js. This object is called the Drupal.AJAX commands dot prototype object defined in miscellaneous slash AJAX in Drupal Core. All this object has attached to it are functions that are the JavaScript versions of callback commands, and each one of these functions accepts three arguments. The first argument you usually refer to as AJAX itself is a JavaScript object that contains information about the AJAX event that occurred. So what element triggered it, what endpoint was requested, what element is supposed to be manipulated, and what methods are supposed to be used. The second argument is known as response. This contains all data relating to this callback command that has come back from the server. So what markup to place on the page, what elements to target with a selector, what settings to implement, whatever data the server wants to send to this command is contained in the response object. And then the final one is status, just the status code of the AJAX request, whether it was a 500, a four or four, hopefully not four or four, or 200. These functions, all they are just wrappers for additional JavaScript. I said in Drupal eight core there are 25 commands. Most of them are just wrappers for jQuery methods. The reason for this is Drupal, after an AJAX event occurs, may want to do some cleanup before it removes an item or adds items to the page for things like behaviors and other aspects. Now if we take a look at the structure of a JavaScript part of a callback command, it's set up a bit like this. This is how it would be structured if a module is defining it. If you look on line 10 of this code here, you'll see that we have the Drupal.AJAX commands dot prototype object, and a function is being attached to it. The function name usually follows lower camel case. So if it's multiple words, it's the first word has lower case letter and the rest of the words have not per case at the beginning. And it's a function that accepts those three arguments, AJAX response and status. Within that, it just wraps whatever JavaScript it wants to execute. And that's all it takes for this function. Now typically you'll find that the pattern that's followed with modules is that this function or multiple of these functions are placed in a JavaScript file that's located in a JS directory. It doesn't have to go there. And I'll explain why in the next section. It could go anywhere within the module, but this is the typical pattern. So the other half of a callback command is a PHP class. Now the AJAX framework provides an interface that callback command classes have to implement. And this is the command interface. In interface, it's just a contracting code that states any class that uses that interface must define certain methods and is expected to have certain methods. For a command interface, that method is the render method. And this is the method that will be called when an AJAX response is being built by the server to send back to the client. It's going to call the render method on a class to know what command to send back. This render method, all it is responsible for doing is returning an associative array. That's all it has to do. And all this associative array has to contain is an element with the key of command. And the value of this element is the name of the JavaScript function that's attached to that global object. Now this associative array can contain other data, other keyed elements, and those are passed as part of that response argument in the JavaScript function. They're the response data that is sent from the server to the JavaScript function. If we take a look at the structure of a PHP class for a callback command, as I said, it is a class on line five that is attached to the command interface. The typical pattern that is followed is the name of the class is command name in upper camel case, followed by the word command. It has to define a render method as this is doing on line eight that must return an associative array on line nine that has an element with the key of command and the value being the name of the JavaScript function on line 10 here. Now where the JavaScript function is placed in a JavaScript file can be placed anywhere in the module. The PHP classes, because Drupal 8 uses PSR4 auto-loading are expected to be placed in a certain location within the root of a module. This is the SRC folder. Inside that the Ajax folder with a capital A and then in a file that has the same exact name as the class name. So command name in upper camel case, followed by the word command. The way Drupal knows to do this is on line one you'll see we namespace the class with Drupal, the module name in Ajax. So any other module that wants to use this command in a Ajax response can use that name space in a use statement. Yeah, I think it's something like that, we'll get to it. And so Drupal knows where to find this file. So this is the basic structure of a callback command. Let's take a look at a core example so you can guys can see how it's actually used. As I said, most of the callback commands in Drupal core are wrappers for jQuery methods. One of those is the remove method. So if we look in the Ajax.js file provided by the Ajax framework in Drupal core. It's actually the file that defines that global object. So on line one, it's the definition for drupal.ajaxcommand.prototype. And in that object, Drupal core defines all the core callback commands. So we have highlighted here the remove command on line 12. Takes those three arguments, Ajax response and status. And it just wraps additional JavaScript. So in this example, Drupal on line 14 it's getting what CSS selector should be targeted to be removed from the response from the server. It's detaching behaviors which is Drupal attaches behaviors to elements. And then it's calling jQuery remove on line 17. If we look on the PHP side of the remove command from Drupal core, again it's a class that implements command interface. It's called remove command, upper camel case. Since it implements that interface it defines the render method it is expected to. And it returns in a social array with that element of key of command the value being the name of the JavaScript function remove. And then any other data it wants to send to the JavaScript function in the response argument. So we pass a selector element with a CSS selector string. If we look at these two code snippets together in the PHP side in the render method on line four, again element of key of command in the name of the JavaScript function remove. Remove is the exact same as the JavaScript example on line two it's remove. It's exact same strings, exact same casing. Back to the PHP on line five we're passing a selector for a CSS selector and that is being used by the JavaScript function highlighted on line four response.selector it's being sent as response data. So this is a bit how these two are related to each other. The render method that is going to be used by the Ajax response gets all the information about what command to execute and the data for it. And then the JavaScript function is attached to that global object so it can be executed and have the data pass to it. That's all it takes to, that's all that's involved with callback commands. So they are the instructions that are used in all Ajax requests. They are the powdered sugar to the Ajax bignet. They're composed of two parts, a JavaScript function and a PHP class. And they are provided by Drupal core or by modules. Great, so we know the structure of callback commands. Let's take a look at creating them and how we could write our own because since Drupal core only has 25 core commands maybe we want to do something else that's not just a jQuery method or maybe we want to do a different jQuery method. For example, jQuery has the slide down animation method. Drupal core unsurprisingly, oh yeah, why would they have it? It's not as far as Drupal core, why would you need that core? But maybe we want that as a custom command. And just as a refresher the slide down method does something like this when it gets triggered it expands a hidden element on the page in a nice little expanding animation. So as I said to create a custom command you need to have a module. There's no way you can write a callback command without using a custom module to the best of my knowledge. I'm not going to get into all the aspects of writing a module in Drupal 8 but you do need an info.yaml file. How many people are familiar with creating modules in Drupal 7 or Drupal 8? Wow, the whole room, that's excellent, that's great. Makes my job a lot easier. I don't have to explain every single thing. So we define info.yaml file, we create a module called slide down command and give it a description. Hey, it provides the slide down, JavaScript or jQuery. Callback commands, what happened to my mouse? Callback commands are composed of two parts again. The first one being a JavaScript function. So we have to attach a JavaScript function to that global object. That's what we do in our slide down dash command.js file of our module. We attach slide down to the Ajax command Drupal Ajax commands prototype object on line six. We call it slide down in lower camel case. Again, it's a function that takes those three arguments. I'm going to say that a lot, Ajax response and status. And we just wrap some additional JavaScript. So in this example, we are going to assume that the server passed us a duration, how long the animation should take. So on line eight, we're checking, does the response contain a duration attribute? If so, we'll use that. If not, we'll default to slow. And then on line 10, like the remove example, we are going to assume the server is going to tell us what elements to target on the page to expand. So we check for response dot selector and then we call slide down on that. Now in creating your own custom commands, you want to use them. Obviously, that's why you're writing them or maybe you just want to have a collection. To include custom JavaScript on a page in Drupal 8, you need to make it part of an asset library. And these are defined in libraries.yaml, as far as your module. Asset libraries are just a way to tell Drupal about a collection of CSS and JavaScript files. Each one has an asset name. Here we call it slide down on line one. And on line three, we're telling Drupal that this library has a JavaScript file or in on line four, we're telling Drupal where that JavaScript file is located. It's in the JS directory and it's in the file called slide down command.js. This is why you can put this JavaScript anywhere you want in your module because you tell Drupal in the library's file where it's going to be located. What I like about libraries is they can have dependencies. Just like Drupal modules can have dependencies on other modules, libraries can have dependencies on other libraries. So if you're writing a custom callback command, you want to use it with Ajax functionality. You want to make sure the Ajax library is included on the page because unlike Drupal 7, Drupal 8 will not include all JavaScript on all pages. You'll only include the JavaScript you tell it to. So if you're creating a custom callback command in your asset library, you want to have a dependency on the core Drupal Ajax library. And that will include that Ajax.js file defined by the Ajax framework so that objects available and Ajax functionality can occur. In our example going on, we have to create a PHP class, the PHP side of a callback command. So here we define a class called slide down command on line four, implementing the command interface. Which again means we must define a render method that we do on line 13. All we have to do is return an associative array. Line 15, we pass an element with the key of command. The name being the slide down value, the name of our JavaScript function. And then additional data that we want to send to that function. So we mentioned we want to pass a selector. So on line 17, we pass a selector element. We want to pass a duration. So on line 18, we pass a duration element. Which values will be set when we create an instance of this class in the next section. Since we're using PSR for auto loading, we give this class a namespace on line one of Drupal slide down, the name of our module Ajax. And we place it in a file within the source directory, the Ajax directory with the capital A and in a file called slide down command in upper camel case. This is all the code that was written to do this. We have a module, we have a JS directory with a JavaScript file that contains that command. We have an info.yaml file. We have a library's file to tell Drupal about our JavaScript. And then we have a command class in source Ajax. What I like to look at this is there is no Drupal in this code here. I mean, maybe the info.yaml file is Drupal, but there is no .module file even. There are no hooks. This is all it takes. Now, in a real scenario, you probably are not going to write a module just for a callback command. Maybe you'll write one that has a lot of them in it. That'd be cool. But more likely, you're going to write one as part of a module you're already creating or functionality you're already doing. Perfectly capable of doing that. Again, the views module does that, the C tools module does that. But these are the elements that you have to have as part of your module to add custom callback commands. So to create a callback command, you need to create a module. You have to create a module. You need to attach a JavaScript function to the drupal.ajaxcommands.prototype object, making sure it accepts those three arguments. Again, I'll say it, Ajax response and status. Make sure that that JavaScript function is in a JavaScript file that is defined in an asset library that depends on the core Drupal Ajax library. And then create a PHP class that implements command interface, which means it defines a render method that returns an associative array that has an element with the key of command and the value being the name of the JavaScript function. Keep repeating these things a lot because they're important. Like, as soon as you know them, that's all you need to know. That's all there is to it. Let's take a look at using callback commands, the meat and potatoes of this presentation and probably what you guys really came for. Unless you just wanted to hear me speak if you've heard me speak before. That's fine. We'll use another example scenario. This one will be more in a Drupal context so we can all wrap our minds around it. So most of, almost everyone here raised their hands saying they are developers and site builders. So I'm sure you're familiar with this page. This is the recent log messages page provided by the DB log module, or it's the watchdog page. It provides a nice table of logged events that have happened on your site so when something goes wrong, you come to this page and see what occurred. Gives you what module logged this event when it was logged, message, title, other information. Those message titles are links. When you click one, you are taken to another page that provides more details about that logged event. Really helpful information when debugging a problem that's occurred. What's annoying is when you're debugging a problem that's occurred and you don't know what logged event made it happen or what's involved with it. You click on a link, view the details, you click back, click on a link, view the details, you click back. Very annoying. I find it annoying. Yeah, that's what syslog is for, yeah. But let's say we want to keep using this and we don't want that annoyingness. Why don't we use Ajax and callback commands to load those message details onto the DB log page so we can view them when we click the message title and they'll just be part of the table and they'll expand and we'll get to read them. Now, to use Ajax callback commands and to use Ajax, you have to have the Ajax library attached to the page you want to make Ajax requests on. The library's not included, there's gonna be no Ajax functionality. I'm not gonna get into the black magic of how I took over this page because that's a whole another topic. Let's just say I have a controller that is taking over that overview page and how it's generated. Since, by default, Drupal's not gonna include the Ajax library because it doesn't need to on that page, I want to make sure I have the Ajax library included. One of the methods to include libraries is to attach them to render arrays. If anyone went to Gus Child's talk yesterday on render arrays, you'll know that they're really awesome. I like them, they're also burdensome, but they're awesome. So to attach it to a render array, a library, on line nine, you add it to the attached attribute to that, the library subarray and you pass it the name of the library. The libraries are named space by the module name or by core. So for this example, we're creating a module called Ajax DB log and we're gonna have a class called Ajax dash DB log and so we pass that library name on line nine. Now in our last set library, this is what we define here. Give it a name, we pass a CSS file and the JavaScript file just for some cleanup and make it look good. But you'll see I do not define the core Drupal Ajax library as a dependency. But what is defined as a dependency is our previous library, the slide down library from that other module. And if you look back at that library's definition, it has a dependency on Drupal Ajax. So what happens now with this code is when that overview page is going to be rendered, Drupal sees that okay, the Ajax DB log library is being attached, let me get the information about that. Okay, it has a dependency on the slide down library, let me get the information on that. Okay, the slide down library has a dependency on the Drupal Ajax library, let me get the information for that, include all the JavaScript that all those libraries define. This means we included the Ajax library onto the page using library inception. We could go deeper, but we won't. Which is a really cool thing about libraries within dependencies that that can happen. I think that's really cool. Okay, so we have the Ajax library included onto the page by attaching it as a render array in our library inception. Next we need elements that trigger an Ajax request. This is all building up to using commands, don't worry. There's tons of documentation out there on how to add Ajax to elements. Unfortunately, 90% of it is how to do it with forms. I don't know why that's all that's out there. I like adding Ajax to links and that's what we're going to do in this scenario. To make a link to Ajaxify a link, I don't know if Ajaxify is a word, but to Ajaxify a link, the Ajax library requires that links have a certain class on them. And on line 18 here, we are going to add to those message title links the class use-ajax. So when the page gets loaded and the Ajax library is included on the page, the Ajax library is going to find any links that have the class use Ajax. I'm going to know that when a user clicks on that link, an Ajax request should be made to whatever path that link is describing and not just a regular link action. We also, in this scenario, we are going to have the links point to a custom route that we define so that we can build an Ajax response to send back. So I'm not going to get into how I'm creating a link object. On line 21, I'm defining the route name to use and then I'm passing the options to build the link and above that on line 13, some of the parameters to pass with that link. So right now, this is where we're at. This is what the page looks like. The exact same. But on the underlying part of it, we have the Ajax library included. We have our custom slide down command included and all these links are now being targeted to use Ajax. So as I said, these links, I have them pointing to a custom route. So when you're creating Ajax requests in Drupal 8, more likely than not, you want to point to a custom endpoint where you can build your Ajax response. So you need to find a route for your endpoint. So here we're defining one called Ajax DB log event. That's what all those messages titles are going to point to. It has a path that it links to that has some parameters in it. It has a method parameter and event ID. And then it tells Drupal what function to call and what class to build the response. So this is in Drupal 7, this would be equivalent to using hook menu to build a link item or a menu path. Now one thing I want to note about having an argument called method in this path, you'll see on line seven, I am telling Drupal that that argument accepts two strings, either no JS and OJS or the word Ajax. And the purpose of this is to cover what is known as graceful degradation. That is providing users with a working experience no matter what. If I jump back for a second into building those links on line 13, I'm passing as a parameter to that route. The element method and the value for that is no JS. So when these links here get rendered, the path that they link to is something like this. Admin reports DB log, no JS event and then the event ID. But when the Ajax library makes an Ajax request, it is going to call admin reports DB log Ajax event, whatever the event ID is. So the difference is no JS versus Ajax. The reason why the Ajax library replaces no JS with Ajax again is for graceful degradation. So if you're passing it as an attribute with your path in your endpoint, you can check to see did a user reach me via Ajax if not provide them with a different experience. You don't want to return an Ajax response because they'll get a JSON array that in a blank page. That's not very user friendly. Maybe someone has JavaScript turned off. So when they click that link, you want to provide them maybe a redirect to the actual detail page. So if we look at the endpoint in our controller, I have a method called Ajax event details. That's where all those Ajax requests are coming to. And on line 10, we're checking if the method is Ajax to know if we should build an Ajax response. If not, we'll do something else. Now when you have an endpoint for an Ajax request, you have to return an Ajax response object. Ajax response is a class provided by the Ajax framework. And on line 11, sorry, on line 14, we're defining a new instance of Ajax response. And this is what's going to be responsible for calling those render methods on all those commands and building a JSON or string that it can send to the client for them the JavaScript to parse and execute JavaScript functions. The way you add commands to Ajax response is by using the add command method. What's great is you can add multiple commands in one response. So on line 16, on line 18, on line 20 of this code example, we are adding multiple commands. So on line 16, what we're doing is we're calling add command and we're passing a new instance of a command class. So we're gonna use that core remove command that we looked at and pass it an element to remove from the page. We're doing this because we're assuming this is not the first time that this request is being made so we can remove the old message details before we add new ones. Then we're attaching on line 18 message details. And then on line 20, we're gonna use our fancy new slide down command that we created in the previous section, giving it the target to expand. So what happens now when a user clicks on this link, and I know you can't see this, I'll expand it in a moment. When they click this link, Ajax request is made to our endpoint. Passing the word Ajax as the method in the event ID. Our endpoint knows that a user reached it via Ajax, builds an Ajax response that adds those three commands in that order. Drupal then takes that response and renders it into a JSON array or JSON string and it sends it back to the client, which will parse it. So this response that was turned, here's what it looks like. This is the actual response from that request. You'll see it's just a JSON array that has a bunch of objects in it. And these objects you look familiar from, well at least the top one and the bottom one from the examples that we looked at when we looked at the core command and the one we built. These are the arrays from the render methods. So this JSON array gets sent back to the client. The Ajax library JavaScript goes through each element and says, all right, give me the value for command. I'm gonna call an object that's attached to my, I'm gonna call function that's attached to my global object and I'm gonna pass this data as the response data to that function so that it can execute. So remove gets executed, insert gets executed and then slide down gets executed. And now what we end up with is an experience like this. The message title is clicked, Ajax request is made and the events slide down on the page. Yeah, maybe I should make a patch for Drupal core. Okay. And you'll see when you click on a different one, when the GIF restarts, that the old details are removed because we had the remove command. So let's let it go one more time. So you click, it expands. I have a close function that I did just because click, it expands, click on the next one, the old one gets removed before the next one expands. Very cool. So to use Ajax callback commands, you have to include the Ajax library in any custom command functions onto the page by adding that library and using library inception. Have an endpoint that returns an Ajax response that also checks to see if a user actually reached you with Ajax, if not return a different response, maybe a redirect response or just an HTTP response. But when you're building your Ajax response objects, attach the command classes to it using the add command method in passing new instances of those command classes. And then your page should work and you should have these really feature rich Ajax experiences. So you can manipulate multiple pieces of data on your page in multiple different ways, do some crazy stuff. If you look at the C tools commands, they do some crazy things inside them in their JavaScript functions. All right, so let's review. Ajax callback commands, they are functions that are used in all Drupal Ajax requests. They are in the instructions that are sent from the server to the client to execute JavaScript. Callback commands composed of two parts, a JavaScript function and a PHP class. And callback commands are defined by the Ajax framework, Drupal 8, there are 25, or by custom modules or contrib modules. To create Ajax callback commands, you need to have a custom module. You need to add a JavaScript function to that global object, the Drupal.ajax commands that prototype object, which you then add to a library so that it can be included. And you need a PHP class that implements command interface, which means it defines a render method that returns an associative array that has an element with the key of command, the value being the name of the JavaScript function. To use callback commands, include the Ajax framework and any custom commands onto the page, again, using library inception. Return an Ajax response object in the request, which you've attached callback commands to using the add command method. So that's all I have. I hope I didn't disappoint you guys with how pretty simple it actually is and how commands are being used. Every Ajax request in Drupal, I want to just drive it home, uses callback commands. Whether you're just adding an Ajax attribute to a form, or you are just making an Ajax callback, every Ajax request returns that JSON object with commands. Check it out. Look at any Ajax functionality that happens in Drupal, inspect it, and you'll see that it returns a command object. It's pretty cool. I have some resources for some homework for you guys. The first, and I'll come back to this so you don't have to scribble them all down right now. The first one is linked to the official Drupal.ajax framework API information. It includes a list of all the core commands and how to use them. I have a link to this presentation, annotated version. You don't get to hear me talk, but you get to hear what I wrote or read what I wrote. Nice and interactive. I have a link to these slides. If you want the more boring, non-interactive version. Again, annotated. All the example code that we went through, so the slide down module and the Ajax DB log module. I have links to that. Fully commented up to Drupal coding standards, I hope, so you can check it out. I have a blog post I wrote last year on creating callback commands in Drupal 8 that you can read, and then I just have a blog if you want to hear what I have to say. You can check that out. Before we get to questions, before I put that slide back up, I want to say, if you have any feedback for this presentation, please let me know. Sessions are always, it's an iterative process. They're always a work in progress. This one's gone here because of some great feedback I've gotten from people such as Larry Garfield, who, the first time I had this, he had some good feedback for it for some bad examples I had. And I want to thank you for coming to my session, the last session of the last day. You could have been here in Dreespeak right now, but instead you came to hear me speak. I don't know how that happened. So I really thank you. I appreciate it that I got a chance to speak. And we have time for questions, and I will put the resources slide back up, and then if you have a question, please come up to the mic or shout really loud, and then I'll have to repeat your question. I know, right? Yeah, that's the one thing. I need that. It looked too easy because it is too easy. It's crazy. I think someone has a question. I apologize if you covered this, I didn't quite understand. So if you're doing multiple commands like you were showing there, where you're doing a slide down and insert and remove, is there like a mechanism that'll prevent like a race condition from happening, where one will finish before the other one does? So yeah, if you are adding, hopefully everyone copied down those links, I go back to it. Yeah, here we go. So you're asking if there's a race condition, so like before the remove command finishes, the after command doesn't have it, yeah. From this, from the PHP side, there is not. That can be sort of problematic. And so on the JavaScript side, I don't know if the Ajax framework will wait till one finishes or not. It may, but if you wanted to wait for like the slide down animation to complete, that wouldn't happen, default. So you may run into those race conditions. That's why if you wanna write really complex time things, you write your own commands that do all that in the JavaScript function. Okay, so that you can just like specify like a promise in your JavaScript so that it doesn't happen. Yeah, now some of the core commands do take a callback argument so that you can tell it to execute another piece of JavaScript after it runs. So that's a way to do that with some of the core commands. But I don't think all of them just by default handle like the timing like that. But it's pretty good, cause it'll execute them in order and most of them are pretty quick unless they're really time intensive, so. Cool, thank you. From here to, what's the difficulty of going from here to a modal? What I did with here? The difficulty of like getting this from non Ajax to Ajax. No Ajax but in a modal. In a modal, probably would not be that difficult. That would come down probably more to styling I would think for modals. Cause you'd probably have like a div on the page that you populate and then you trigger to expand. There are some, views has a modal callback command to handle, I don't know how well you could use that outside the context of views. But again with modals it's just triggering Ajax to occur to display the modal so that would be as simple as triggering that element. Yeah, it's not, it's really not. Oh, does it? Let's get to know that the jQuery UI module has a dependency on it. No, the library, the jQuery UI library. Yep, and then it would have modal. Very cool. If you're trying to alter a form that has a field set you have an add more button and you just want to keep adding more and more. Do you still need to have an Ajax wrapper div around the whole thing to replace it when it gets rebuilt every time? So if you were going to have an add more on a form, if you are using the form API then that's gonna handle a lot of that for you. You just add the Ajax attribute and you tell it the function that will define the form with that additional elements. And the form API will actually take care of building those commands to deal with all of that so you don't necessarily have to wrap everything in Ajax, you just have to specify the Ajax attribute on the element and then the form API will handle that for you. Which is really great, that Ajax framework is part of Drupal core because all these core systems utilize it in some way, especially the form system. So that makes it easier for you so you don't have to find your own callback commands to do any of that. That's probably why most of the documentation online is for forms for using Ajax. You guys are still sitting here so I imagine there are more questions. There's one in the back. Sure, so the question was how did the Ajax framework change from Drupal 7 to Drupal 8? I actually have a version of this presentation on Drupal 7. In Drupal 7, well the only thing that's changed is really the PHP side in the name of the JavaScript object on the client side. I forget off the top of my head what it's called in Drupal 7, but again it's just provided by Ajax.js, same file, same location. It's a global object that you attach a function to with those three arguments. And then on the PHP side in Drupal 7, you create a PHP function that you then include in whatever function's going to build your Ajax response. You return basically a render array to be built on the server. So the difference in Drupal 8 is that the JavaScript object is called something different and then the PHP instead of writing a PHP function, you're writing a PHP class that implements an interface. Those are the two main differences other than that. Oh and also it used to be called the Ajax API and now it's called the Ajax framework. But other than that they're very similar so a lot of the reading you can do is pretty agnostic to 7 or 8. Please do not ask me about Drupal 6. Good question though. You had one over here, yeah? What do I mind? Like putting it out there? Yeah. You think they've accepted, so I've been, yeah you'd use it? All right, after this I'm going to go get the namespace right now before someone else does it because I have all the example code available on GitHub. But yeah, I'd be happy to. It's a really cool example. I'm glad people actually want to use it. For it soon, the Ajax DB log module. Yeah, I'm actually, I'm literally going to go sit down right now and get the namespace for the module. Do you get to go home now or are you going to go home tomorrow? I'm going to go tomorrow.