 All right. Thanks, everybody, for coming to my talk today. Today I'm going to be talking about Form Builder, which is a project that's existed for quite a little while here. But what I'm going to do today is kind of give you guys a three-part introduction into Form Builder, an introduction into what Form Builder is, what Form Builder does today, ways that you can develop with it, essentially an introduction into the API, because this is a code talk, and then also a short discussion of possibilities for Drupal 8, and using Form Builder as a replacement for our current field UI. So the last part, mostly theoretical. So if the code stuff kind of goes over your head at some point, don't worry. We're going to tone it back down a little bit towards the end. So first off, who am I? My name is Nathan Haug, or Nate Haug. I'm Quicksketch on Drupal.org. A lot of people know me from a lot of contrib modules that I maintain. I maintain web form, insert, flag, file field, image field. And I wrote a bunch of other ones, like link and five-star. So I'm really active in the Drupal community, as well as in the Drupal core issue queues. My most recent accomplishment was that I put image module into Drupal core, including image cache and image field, and image API, and file field, and the field UI. So that was awesome. But actually kind of as a funny side effect is of trying to put image module into core, we had to shove through the field UI module, which is basically the CCK field UI from Drupal 6 put into Drupal 7. And it actually got worse in that process, which is unfortunate. So Drupal 8 hoping to undo some of those repercussions from speeding that along so quickly with this form builder talk. And I'm also the author or co-author of the book Using Drupal. Also, I'm also very active in making a lot of tutorials and instructional videos on Drupal. And this is a pitch for my company, Lullabot. We have a site, DrupalizeMe, that has a coupon code at the end. And I'd be happy to. I'd love for you guys to try it out and see what you think. So let's talk about form builder. The history of form builder. Form builder is a project on Drupal.org. You can see it's been around since June 22, 2006. And the URL, of course, is just Drupal.org project slash form builder. And it originally was a Google Summer Code project. This idea of being able to edit a form within Drupal through a visual interface has been around for a really long time and a lot of different attempts at it. In 2008 it was rewritten again in its current incarnation. And in 2010 it basically sat there for a long time in Drupal 6, basically as a finished product, and never actually went anywhere. Which basically Drupal 7 development kind of came to a close, and we found that there was no way it was going to get in and wasn't ready yet. So it kind of just sat there for a little while. But in 2010, Arcquia wanted to use form builder in their implementation of web form in Arcquia Gardens. So they ported it to Drupal 7 and finished out the web form implementation, which was fantastic. So now in 2011 it's been expanded and stabilized and fully supported in web form. So you can actually use form builder with web form today largely because of the good start that Arcquia put onto it when they put it into gardens. So the first thing we're going to do is we're actually just going to take a look at what form builder is today. And if you aren't familiar with web form, the module for making surveys in Drupal, I suggest that you head over to archive.org and just do a search for web form. And there's a talk from Drupal Con Chicago that I did that is an introduction to web form. So this isn't really about web form. This is about form builder today. So I'm going to head on over here to my Drupal 7 site. And I'm going to go ahead and create a new piece of content here and create a new web form. So if I add a new web form. And I've already enabled the form builder module and the form builder web form integration module. So the form builder module itself, which is nothing, it doesn't do anything at all by itself other than provide infrastructure for other modules to implement with it. And then you need to turn on an integration module like the form builder web form module that comes with the form builder project. And you can see here essentially I start out with a blank form, and I have a palette of fields over here on the right-hand side that is all of the various things that you can do with web form. And you simply take it and drag fields over from the right-hand side and assemble your form, essentially. And obviously you can see it's ridiculously fast to actually implement a form like this. One of the reasons for that is because all of these fields have essentially like reasonable defaults sort of defined for all of them. If you were to do the same thing in field UI, you're prompted with a C of like eight empty text fields where you're like, what do you want to name your field? What do you want the title of your field to be? What do you want your options of your field to be? What do you want all of these settings to be? And one of the things that is required for form builder to work is for every single element to have a default. So a set of defaults that makes sense so that when you drag those things in, things like the choices here, poor average, good, excellent, we're all there. But of course, you can go in and edit them. So you edit by clicking on a field, which apparently is being weird. One second. So you edit a field by clicking on it. And currently, this is the way it works where the options for editing a field appear down below. Some of the work that Awkward did in Gardens is they wanted the options to show up over here, where the palette is. So the API has the ability to display the options for it someplace else. But the default implementation and the way that is least likely to break the layout of your site is if it just puts it right down below the field that's being edited. And then you can go over here, go to your options, and you can add in. So these are the things across the top. Poor average, excellent, or good, excellent. You may add another one that is awesome, like even better than everything else. And you can see it does an Ajax request every time you do some kind of change of any kind. Like if I want to make this field required, I check the box, it does an Ajax request, and then it updates the display of that element on the Drupal side and then replaces it into the interface. So the whole thing is really, it's quite speedy. And there's very little code that is actually needed in order to make this work. Because it's all still PHP, the actual JavaScript file for this is only, I don't know, 700, 800 lines, which isn't terrible considering the amount of functionality that this does and the way that it works so quickly with the Drupal Forms API to actually edit these things. So that's the basic concept here. I made the mistake of dragging a field set, which doesn't work so hot. So anyway, you save, and then I can go over here to view, and you can see that the form that I constructed with my awesome option is all here and ready, and it's good to go. Incredibly quick and really user-friendly. Like the concept behind it, you click on it, you edit it, you drag it in a new field, all of this stuff. It just goes ridiculously quick. So there are some advantages that Webform has when it comes to implementation. Because when I was running Form Builder, I wrote it basically for Webform, but with the intention of making it work for other things. So lots of abilities that Webform is utilizing, but we'll need to make some enhancements in order to work with Field UI. So let's talk a little bit about the way it works. So that's basically what it does. If you want to, you can go to my site, quicksketch.org. And there's a demo site right up there at the top of the page that is linked there. And you can play around with it as much as you want. Or you can, of course, just download and install the module. So the way it works, most people in here, this being the Codertrack, are probably familiar with the way that Dribble works when it builds forms. All of Dribble's forms are arranged as arrays. So big nested arrays of things like this. So this would render a title field that is a text field that has the label of title, a description, a max length property. It would have the asterisk and validation for it being required, and it would have a weight negative 10, meaning it would be at the top of the form, essentially. So what FormBuilder does is it basically has the ability to look at any one of these arrays. And then through a series of hooks, you can say, my module knows how to edit fields that are of type text fields, so it'll read the type. And if you've enabled your module to edit this particular type property, like a text field, then it says, OK, well, in a text field, what properties do I know how to edit within a text field element? And then you would specify title, description, max length required, weight, all of these things here. You would say, my module knows how to edit all of these things. And in a lot of situations, your module may not be able to actually edit all of the available properties here that are available to the Forms API. It's something like pound process, or pound pre-render, or pound theme, a lot of properties that are out there that you wouldn't want somebody to be able to edit that from the interface. I mean, you could. FormBuilder can change any property, literally any property in the entire system. It can change it if you tell it how. Every single one of these properties, essentially, has a form tied to it saying that if there is a title property, then this is the form that is available for editing the title property, which is just a text field that lets you type in a new title. So the form lets you modify the value. And then FormBuilder basically reads in the properties and lets you edit the ones that it knows of. The craziness of Drupal 7 is that this approach here of using arrays isn't just for Forms anymore. Actually, even in Drupal 6, we had this ability that the node content property was also an array. So something like the title, this would be the display of the node, was actually an array also. And it would look something like this, where it was pound type equals markup, the title or label of it. Maybe it had a title, whether or not you wanted the label to show or not, the actual value of the title and then the weight. And so this means that with FormBuilder being a FormAPI array editor and us expanding the FormAPI concept to everything, everything is now called a renderable instead of a FormAPI array. FormBuilder can actually be used on this stuff too. There's no reason why it wouldn't. It's the same thing. It's just that the properties are different, essentially. So if you teach FormBuilder how to edit these properties in addition to the ones that already knows how to, then you can have FormBuilder work not only on your back end for editing your forms, but also on your front end for editing the display of things, which opens up a whole world of potential here. So now we've established that it is a renderable array editor. How does this module actually work? Actually implementing the FormBuilder interface into your module is actually really pretty simple. There's one function that you call to actually bootstrap the entire FormBuilder interface. You can only have one of them on a page, but I hope most of the time that's not a problem. You call FormBuilder interface. And then just like you have a form ID, you have to specify a FormBuilder ID, which sometimes if you wanted to, you can make that the same as the form ID. And then a type. So a type would be something like if you were editing an entity, the type would be the bundle, which is the node type, or if you were editing a web form, the type is actually the node ID. Since every single web form has a different ID, essentially. So what happens when you call FormBuilder interface is that a module needs to implement Hook FormBuilder load, and it checks the FormBuilder ID and the type. And then it loads that form, or renderable, and then passes it back to FormBuilder. And so the typical thing you'll do inside of Hook FormBuilder load in your module is called DribbleGetForm. And DribbleGetForm will actually load the renderable array, and then you get an array back, and then you just return that array back from this hook. And that basically says here at FormBuilder, here's the form, make it editable. And then the FormBuilder interface will be built out and let you edit that array. Or NodeView, if you were editing the front end, you call NodeView, and that gives you the content array for a node. And then you pass the content array to FormBuilder, and then it can edit the content. It's really crazy. So you let FormBuilder manipulate the properties it knows about. So this is when the user is dragging in new fields, changing properties, reordering them, et cetera. And then you use a separate form to actually save all of the changes by loading FormBuilder from the cache very much like views. Views has the ability to edit a lot of things all at once. So you can change a bunch of things about the sort order or the filter criteria or which fields are in it. And all of those changes are being saved dynamically through Ajax requests as you're making them. But the changes aren't actually made to your view until you click the Save button. And it's the same thing with FormBuilder. FormBuilder uses an identical method, essentially, to store a cache of what's changed as you're making all the changes to your form. And then all of it isn't actually saved until you click the Save button, which will load it from the cache that has been generated by all of Ajax requests. So the hooks that are available in FormBuilder, it's a whole set of them. So there is Hook FormBuilder types. And Hook FormBuilder types is sort of like the granddaddy of FormBuilder and the way it works. FormBuilder types is basically an array of arrays of arrays, kind of standard Drupal practice here. So it's an array of form types, such as webform or entity or node. So that's the key that contains a list of element types that are editable. Such as text field, checkboxes, radio select lists, whatever it is that you want to actually make editable within that type of form. And then it also determines whether or not you have palette grouping and whether or not your fields are unique and which fields are possibly editable. Unique fields are really interesting and something that right now nothing is actually utilizing, but the functionality is there, where if you have something like you're editing the node form, you want to do something like have the path settings. There's only one path settings on the node form. You can't have multiple paths, doesn't make any sense. So if you were to drag in the path settings from the palette, the path settings option in the palette disappears after there's one already there. And if you remove the path settings from the form, then the path settings reappear in the palette. So you can drag it back in again. So unique fields are really cool that are useful when there's only one thing possibly. Everything else, when you drag it in, you can add as many checkboxes as you want on an individual form. Really cool. Hook form builder properties. And this hook basically defines a global list of properties that can be editable. So things like pound title, pound options, pound everything, pound default values. All of the properties that are within a renderable array. There's only one giant global editable list of properties. So it's important that modules basically choose unique property names. So if you have pound options, pound options is used equally between the types of like a radio button or radio buttons and checkboxes and select lists. And fortunately, pound options is edited in the exact same way for all three of those things. Because they're all the same thing, an array of options essentially. And so if you're going to be making new properties, you want to make sure that your property names are always unique. So like in the example that we saw with webform where I pulled out a grid, I didn't want to use pound options there because pound options, I don't want to conflict with the existing settings for pound options. So I named it like pound webform grid options or something like that. You can make up your own properties just willy nilly. And make sure that they're unique so you don't run into a namespace clash, essentially. So define the renderable properties and forms to edit that property. So each individual property, like pound title or pound options, then has a callback form that is for editing that particular property. So if you run into an element that has that property, it just puts in that form that corresponds to that property to edit it. And then there's hook form builder load. And I already mentioned this hook a little bit earlier. And this is the hook that is responsible for essentially finding the form API array to actually edit. So when you call form builder interface and say, let me edit the form by this name, this hook responds to that and says, OK, here's the array that is editable for this particular form ID. So there we go. And then it's complement hook form builder load. A lot of other modules, actually very few people probably actually need hook form builder load. But a lot of people need hook form builder load alter. So the module that is responsible for providing the form, like node module, would implement node form or node underscore form underscore builder underscore load to load the node form. But then every other module, like path module or taxonomy or system module, actually maybe would provide some menu module, would actually implement the load alter to then add in its modifications to say, oh, that path field set, you can change that too. So path module would provide some alterations to make it so you could edit that particular section of the form. If no module claims a particular area of the form, then what form builder will naturally do is it will allow you to move that element up and down. So let's say path module didn't implement path form builder load alter. What would end up happening is you could move the path options up and down in the node form. But you wouldn't be able to remove it. And you wouldn't be able to edit it in any way. And you would just be able to move it up and down in the form. So that's sort of a natural effect of form builders that if it doesn't know how to handle something, then it just lets you move it around up and down and adjust the pound weight property, but nothing else. And you can't nest it either, all these things that are limitations if you're working with limited information, essentially. So let's see. Before I go on, I'm just firehosing hook names that you guys, do you guys have any questions so far? It's like, no, no, this is too way over my head. So sorry about that. So a couple other hooks that are available. There is hook form builder add element alter. And I know that's just a terrible name. But that's exactly what it is. Essentially, when you drag a field in from the palette, this is a hook that fires just before that element is rendered on the form. So this allows you to do things like give it a unique ID, for example. If you're going to be auto-incrementing your IDs of fields that you're pulling in, you can count the number of fields that you currently have and give it a unique ID right before it gets added to the form. And then there's hook form builder preview alter. And this particular hook is essentially like a pre-render function, if you will. It allows you to essentially make some manipulations in the preview that make it so that some things like an invisible element would become visible in the form. So if you dragged in a hidden element or a hidden field into the form, even though that's not going to show up if it were rendered on the front end, it's still really important that the administrator can see that hidden field exists. So you have to alter it to maybe turn it into a text field or maybe just turn it into a string of text that says hidden in parentheses or something like that, something so that the user can actually see that element. So if your element is going to look different between when it's actually displayed and when you're working on it in the form preview, then you have to sort of modify it before it's actually shown in the form preview. Utility functions that FormBuilder provides are actually really cool. There's a whole list of them. And these are basically just like tools for manipulating a form API array of any kind. Like FormBuilder getElement, if you have a big form or a big nested renderable, and it just says layer upon layer upon layer, it's really hard to just find one element in that entire array. And so FormBuilder provides a convenience function for FormBuilder getElement. That is a recursive search function, if you will, just to pull out that element and then return it back to you. This element ID that you actually use to find the element, it's not just the key of that form API element. It's in the special property. In that hookFormBuilder load and hookFormBuilder load alter, each module needs to go through and basically assign everything that it knows about an element ID. So in webform, that's the component ID. And in fieldModularCCK, that's like field underscore fieldName, which isn't actually a form API property anywhere. So you need to basically tell FormBuilder what that field's unique ID is for the entire form, which every individual field will have a unique ID of some kind. But whatever that ID is, you need to place it into this particular property. So that way, FormBuilder can use this get and its complement set element by checking this particular ID. So the complement, if you make any modifications to an element, then you can say set this element and it will find it wherever it is in the form API array and insert it back into the array. Some other crazy thing that you can do with this is you can actually move an element by modifying pound parents and pound key. You can actually move an element in the array by getting the element changing pound key to something else and then setting it back again will actually move its location in the form. So a whole bunch of crazy logic in there to basically manipulate a form API array through code. And then there's this really awesome function. There's a whole suite of functions that start with FormBuilderCache. And that's that static cache that I was talking about that sits in the database. And as it's doing AJAX requests, it's updating that cache with various properties. There's FormBuilderCache difference, where you can essentially say, hey, since this form started being edited, what form elements changed in the entire set of elements that changed? So if you go in and you only change one thing, like you change a title or a label on something, and then you hit Save, only one field has actually changed in that huge array. And it'd be a big pain to go through and figure out what are all the elements that changed here when only one property changed in the entire form API array. And this function essentially does that for you, where it finds all of the elements that have potentially changed. And then you can also tell it to exclude weight. So if you do something like you drag a field from one position down just one slot, that may re-weight everything in the entire form. And if you don't want to have the weight property essentially to make every element in the entire form flagged as being different, then you can just ignore the changes to weight and show me only changes to other properties, essentially. So now that we've done sort of with the grand tour of hooks that FormBuilder provides, I'm going to talk a little bit more about some concrete code here. And that's how to actually save your changes. Before I talk about saving, this is what it would look like if you were actually implementing this in your own module, like if you wanted to build a FormBuilding interface somewhere on your site. This would be a menu callback here. So my module admin page. And this would be returning the contents of a page. So the total contents of a page here are pretty simple here. You say output in Drupal 7, all pages instead of returning a string in menu callbacks, you now return an array. So the entire page itself is also a renderable array. And you only need to put two parts into this page. You need to load the FormBuilder interface itself. So this is why I was saying, FormBuilder interface. And you say, the form ID, this is a little bit off. This should be form ID first here. So you basically say, load the form ID and then initialize the interface. And then in addition to that, that would load the entire interface for editing a particular form API array that matches to form ID. But the user doesn't actually have any way to save their changes. There's no save button that is provided by the FormBuilder interface. So you need to make another form that is nothing but the save button, which is really kind of interesting. So the FormBuilder interface will ultimately call hook FormBuilder load. And then your module would return back the form API array inside of that function. And then you specify the form itself. When you call Drupal get form, the string that you pass in here maps one to one. The form ID maps one to one to a function name. So here's the form callback for actually returning the form. And as you can see in here, there's nothing in here but a submit button, which is kind of crazy. So the submit button, when you actually click Save inside of this button, what this looks like is it would execute the name of your form. So module underscore save underscore form underscore submit, so submit handler function. And this is generally what it would look like. So you would use the FormBuilder cache load, and you would load the particular form that had just been edited. And so this gives you the form API array as it is currently, like the modified one that's been updated. Or an alternative to that, that gives you the entire form. If you wanted to, you could use this function, FormBuilder cache difference, and pass in the form ID once again. And that would return just the elements that have changed. So this line up here isn't actually necessary. It's just an option. But most of the time, I think this differences is actually what's important here. And then you loop through the differences. So you'd say for each of the differences as element ID. So this is the unique element ID again. You get two properties inside of that array, the original one, so what it was before the changes, and then the modified one after the user had made some changes to that particular element. And then you have to go back through, and this is where you do the database changes to insert a record or update a record, save the settings somewhere that record the mappings of what changed in that property. So if you change the label, any sub dates, the field table that stores what the label of the field is, and things like that. So that's the general idea of the way the FormBuilder module actually operates. It's basically a whole set of hooks that allow FormBuilder to find a form. Modules that then say, these are the fields that are actually editable within a form, and these are the properties within those fields that FormBuilder should have the knowledge to actually modify. So there's sort of a three tiered approach there. What forms are possibly editable? What fields within those forms? And what properties within those fields within those forms? So it seems a little bit complicated, but actually implementing it once you get over formBuilder provides basically forms for editing every property in all of core. So anything that is in the Form API documentation, FormBuilder has already provided a form for you to be able to edit that property. If it's provided by core, FormBuilder already supports it. So it makes it so that the amount of reuse of forms is extremely high. So right now, every time you need to edit a title field or title property in any number of form editing systems, you have to write the form all over again. Whereas FormBuilder gets an extremely high amount of reuse of the same forms, sort of assembled from pieces, and then put into a big form to control the overall settings for that particular field. So some nice reuse there. Do we have any questions so far on the architecture, like the way that FormBuilder works and the way that you might be able to use it in your own solutions? Yeah. Yeah, so that was a great question. Is there any reason not to use this for front-end display instead of forms? Maybe even emails or just the display of the content on your site? And no, there's no reason why you wouldn't want to do that. I actually think that that is going to be the future of this project is editing front-end display things. And you mentioned emails, which is really interesting, thinking about emails as a renderable array. That's exactly what Webform does when it sends out emails, is it basically builds up the entire form as if it were going to display the form. But instead of showing the form, it displays a whole bunch of text. And then that text is plain text emails that then gets sent out whenever a user completes a submission. So absolutely. I mean, this will eventually be seen, I think, everywhere. Any other questions? Yeah. Yeah, do I see something like this making it into core? Of course, that's like the big question, right? Why don't we talk about that since that's the next topic. So what is the potential here for using FormBuilder in core? I actually really wanted to show you guys a usable demo because I actually did this. I wrote the CCK integration and node integration and path and menu integration and all of these integrations, but all for Drupal 6. And when Drupal 7 development came to an end, the FormBuilder project kind of stagnated there because I wasn't very motivated to work on something when core was frozen. Now with Drupal 8, unfortunately, we're not actually really in a code thaw right now for Drupal 8. It's still kind of like a slush or a freeze even because of the number of bugs we have. So we're not really moving forward on new features right now. So anyway, so I just have mockups to show you guys. I hope that's not too disappointing. So originally, this was the approach that I was going to use. We're exactly like Webform. There is a field palette over here on the right hand side. And what you would do is you drag in what field module would call the widget. So the widget being like a text field or a select checkboxes or radio buttons or something like that. And then it makes that particular element. And then you would click on it and you would edit the properties and display exactly like what we just saw. But there's a difference here in that CCK or field module, both they also have to do with the structure of your database, right? Like what type of data is actually being saved into this select list. And so my original thought was I was like, oh, well that's a piece of cake. We just add a new tab here for type. And then we let you choose the widget and the data type. So the data type would be text, integer, decimal, whatever type the field module would actually use in the database to store that particular property. And of course, these things don't have form API properties. And the only thing FormBuilder is capable of editing is things that are properties. So easy enough, you just make up two new properties like pound field widget for editing the widget and pound field type for editing the type. And then you define in FormBuilder, this is how you edit the field type property and this is how you edit the field widget property. And then you allow the user to change those things. So that was the initial thought here. And of course, there are some things that you would need to lock down. Just like in field module right now, after you set the data type, text, integer, decimal, var car, whatever you're going to set it to, it becomes locked after you set it. So if you messed up the field type originally or the data type originally, you have to delete the field and add it again. But the nice thing about doing this with FormBuilder, at least, is that we don't need to lock the data type until after the entire form is mid-built and the user clicks save. So we have this nice opportunity, essentially, that when the user clicks save, I showed you the submit button that I had where it's literally just nothing but a button. And then in the save process, it immediately just injects all that stuff in the database. And now it analyzes the changes, saves them. You could very easily build in a multi-step form there instead, though. When the user clicks save, you give them a review screen of all of the action that's about to occur. And in the case of field module, at least in CCK, when it used to do all the crazy data juggling when it was like normalizing or denormalizing your database, I was suggesting that people put their site offline before they make a whole bunch of crazy database changes. So that way you don't get somebody writing to the database at the same time as data's being flown around. So all kinds of great things you can do where after the user has set up all of their fields, then you can do a nice warning screen of these are the things that are about to occur, which would be really cool. So how does this proposition sound? Yeah, it sounds pretty cool. So I thought it made total sense because this is the way I think that if I want a text field, I drag in a text field and then I set the data type on that text field. I think that that makes a lot of sense to assemble the form first. However, after having a lot of conversations about this, there was a suggestion that I don't do the widgets over here. This is essentially a list of widgets. And then you set the field type or the data type inside of here. That's backwards from the way CCK or Field Module works right now. And what would it look like if you put the data type over here instead in the palette and you dragged in text or integer or float or something like that? And it sounds like a terrible idea. At least I think so. So if we look at this, so text field, file, select, text area, checkboxes, radios. This instead, maybe you'd get text, long text, decimal, integer, float, boolean, list. It's like, well, what's going to happen when I pull in a long text? What would happen then? Well, I think it would be a natural thing for a long text would be a text area and a natural thing for text would be a text field. And if you dragged in something like a decimal or an integer, it would probably also be a text field. And it's a little bit puzzling what would happen as you were pulling those things in. But if you bear with me here and we think about this and it seems like it's not as good an idea as the first one. But then I had this crazy revelation of you can edit not only the form at this point because you're just pulling in data types. So if you already know the data type, the data type essentially is bound to a form element. And then on the front end display, it's bound to a formatter. So why not make it so you can edit both at the same time? So you could actually toggle between the form here. So what I've done here is I took the form preview and I turned into a tab and made it so there's a display option at the same time. And you could toggle back and forth between them and assemble the display parts and the form at the same time. And if you drag in a decimal at this point, it would drag in a sample decimal number like 1.23456 or something like that. And if you dragged in a long text, it would be a big blob of text. And then you could go back to your form and you could change the form at the same time. And so essentially this part is like configuring your display formatters. And this part is configuring your fields. So instead of those being two different pages, it would be one big interface. And you could edit both at the same time and save a content type that is completely finished all in one big screen, which sounds kind of crazy. So does that sound like it's a little feasible? I mean, it sounds better. Let's take a vote. Who likes option one? Dragging in form fields first. And who likes option two, dragging in data types and then displays? Wow. Well, I thought that I was completely convinced. I'm like, this is totally awesome. It's way better. But so for people not in the room and listening on the recording, that was like an overwhelming majority preferred option one, probably 70 to 30 or so. What happens if you let the user change? Right. What happens when a user changes the data type after the form has been built and there's already data in the database? And that's actually one of the limitations of field module right now. You can never change the data type after the field has been added. So as soon as you hit the Save button, which I don't have on this screen, as soon as you hit the Save button and those database tables are created, you can never change the type. If you need to change the type, you literally need to delete the field, add another one. And that does exactly what you'd expect of the data. It deletes the data and then starts out with a fresh new table, essentially. Yeah. Oh, OK. What about basically a mixed approach, Gabor suggests, where on the Form tab, let's see if I can get there, on the Form tab, you drag in the widgets, like option number one, but we still include the Display option. And the Display option, you would then drag in the data types. I don't know about that. Yep. So basically the statement was that on the display side, you're actually looking at data. So it makes sense that if you pulled in text, you would see text, and if you pulled in an integer, you would see an integer. And on the Form side, if you pull in an integer, who knows what the hell that's going to look like in the form. But if it were a text field, you would get a text field. And I guess that has its merits in that if you toggle back and forth, because you could do this really quickly, if you toggle back and forth, you'd probably see that all text fields that you drag out all are text, like text text. They're not numbers. And if you wanted to make it into a number or a list, you would be able to make that change really quickly back here in the middle. So the statement was that the data types is not actually, that's a really good point, actually, that what you're doing is you're not actually dragging in data. What you're doing is you're dragging in formatters. So you would say you would drag in a formatter for image, or something like that, or an image cache preset, or something like a plain text, or a trimmed text, or a list of all the formatters. And the formatters are, of course, only associated with particular data types. So you'd be able to drag in which formatter you wanted immediately without having to change it. And I think you're totally right. I think that makes more sense if you're going to be taking the widget approach. The display side should be the formatter. And the formatter then can sort of inherently decide the data type, but only to a certain degree. Because there's a lot of formatters like plain text that apply to multiple types of data, of course. So let's go back here. Gotcha. Yeah, so a combination approach being suggested, where in addition to a list of widgets, so we go back to option one, because option one is winning the battle right now. Option one, where you have text field, select checkboxes, text area. And all of these things can have multiple data types associated with them, so why not have a list, essentially, of text fields for text, text field for integer, text field for decimal. Yes, and then it would allow you to set better default values when you drag things in. It would also be less clicking. At least I think it would be more direct. Form Builder does already have the option of categorizing fields within a palette by default. It just puts them all in a generic group. And the generic group, if there's only nothing but the generic group, then it doesn't display a title here that labels them as generic or standard or something like that. But if you have multiple groups, such as the unique fields and the node form, I've called them special, so things like path and menu settings and things like that. And there's no reason why we couldn't use that grouping ability to do the data type. And then instead of displaying it as just a long list in the right-hand sidebar, you might do tabs, tabs of field. So you want to say a tab that is integers, a tab that is text, a tab that is decimal. And then inside of each one of those, you would have a different collection of widgets to drag in. I don't know, just kind of thinking out loud here, or UI design on the fly. Yeah, or instead of using tabs, use a dropdown that filters or switches between available data types. I'm going to go up here first, and then we'll come back there. So the question was, thinking about future proofing, how would we handle things like HTML5 elements that are things like type equals phone and type equals email? Yeah, those would definitely be, hmm, good question. Whether or not the data is actually because those fields in the database are still like varkar or text or something like that. But they're a special kind of text, like especially formatted text. Date, of course, would be a date field or a date time field. So that definitely would be listed both as a widget and as a data type. But yeah, you can make up your own data types that could be something like you would have an email field. And that would be both email and data storage and email in the widget. And there's a lot of modules that do that kind of specialized things, like link module. Actually, I think there is an email module that provides an email CCK field that is specialized. And even though it saves it as text, it provides additional validation and makes sure that it's an email. And same sort of thing for phones or for link module is a really good example of that, where it's still just text that's a URL, plus whether or not you want it to open a new window or not. But it's just like a combined field. So yes, to all of that, if you are using email or phone or some kind of dedicated HTML5 element, I would say that should probably both be a specialized data and a specialized widget. So it would show up in either one of these options as something you would drag in in the back. So basically, could you choose your own defaults here? So you like your own sample text? Yeah, your own visual. So you could, in a lot of ways, if you wanted to, you could do it per instance. So if you were editing the particular field, there would be no reason why we couldn't have sample text here. So you could type in your own sample text or upload your own sample image to make it so you could get a better visual of what it was you were talking about. And that sounds awesome. I do think that we would need to provide some kind of default for if you dragged in an image field, it would just be the default. And then you could upload your own if you wanted to. But like image module in Drupal 7, it just provides that nice picture of the balloons. That's a theme function that you can override. So if you wanted to change the generic one, change it there. Yeah, that's a great suggestion. And just like over here, we've got default values. Over here, we could have sample display. I think that's a great idea. Yeah. OK. So there was a comment about we may not be able to use the data type here when we drag in a field, because that's not always just a single field that's being configured, like an address field where you have city, state, or province, I suppose, here. Country, all of these various fields that are all sort of together, I need to be able to configure those. Well, FormBuilder doesn't need to be able to edit just one field. As long as there's a parent that wraps around all of those, then you can edit the group as a whole, which is really cool. In Drupal 7, I suppose, when you drag in the menu settings for a node, the menu settings are actually a group of fields, right? It's a dropdown select list, and it's a text field. And it's all inside of a field set. And you have to configure all of that. You have to configure if the field set is collapsed or not by default, whether or not it's in a vertical tab. Which menu you want to be selected as the default. All of those things, and you basically can figure it as a group. So if you had a big address field that had a whole bunch of options, the list of options would probably be pretty formidable for something like that if you're configuring five fields at once. But you configure them all as a group. So I think that problem can be solved. There's one over here, I think. And no, let's go on the back then. Yeah, that's an excellent question, something that almost always comes up when I'm thinking about this, which is if you're looking at the display side, if you give a user this much, like if you get them this close, they're going to want to be able to do everything. They're going to want to be able to do layout, right? They're going to want to be able to do columns. They'll want to be able to do everything. And unfortunately, what you're doing here is you're just configuring an array. An array is, by definition, it's linear, top to bottom. And so the interface that you have here is also linear, because it's essentially an array editor. But that doesn't mean that you couldn't do something to sort of fake some layout in here. And I'm not sure that's a good idea. But you could do something like add in as many wrappers as you wanted. The forms already have the ability to do field sets. You could drag in a div that is maybe called left column and a div that is right column and then put stuff into it. And form builder would work fine with that. So you basically could drag in structural elements and then nest things inside of there. And how that would actually work, I don't know. You have some additional things to say? Yeah, so could you provide a set of templates or something like that that provide layouts? Not at this moment. I mean, I think it's technically possible, but how you do that, I'm not sure. So we've only got a couple minutes left here. So I've got one or two more slides I'd like to run through, and then we'll do the last questions that we can. So let's talk about what sort of requirements we have for actually getting this into core, like actually making this into a reality rather than something that's in contrib. Well, there's a couple of really obvious ones, like data object cache storage from C tools, like the way that views has the ability to edit a whole bunch of stuff all at once and then save. And form builder does the exact same thing. Right now, form builder is just imitating the approach used by views when it could be using C tools that provides the exact same functionality. And that should go into core. There's no reason why we wouldn't want that. It would also be nice, because with multiple modules doing this right now, well, now C tools, this is the central place. But it would be nice if that was in core. There's also a module called options element that I didn't really mention as I was using it. But when I was editing that grid and I added another option there, there's a special module that provides nothing but the ability to provide select list options or radio buttons that provides field, field, field, field, field with little pluses and minuses and drag and drop handles, which is way better than asking users to type a list of options into a text area with a pipe in between them. That's just like it's a little bit, a little bit cludgy. So options element solves that problem specifically. We need to convert all settings as much as possible on the field level, the widget level, and the formatter level into properties, like pound properties, so that when you render something out of the formatter, you're not just checking directly against the field settings, which is what a lot of modules do right now. They just look inside what's the pound field type and what's the pound field name. And then they load the field from the database. And then check the settings. What we should be doing is we should be doing that loading earlier on and setting properties on there. So form builder is aware of those properties, and I can actually edit them. Every field must have a discrete function for generating a preview. So if you do something like you drag in the menu options, there needs to be a function that provides exactly the menu options. And right now, things like the menu options are basically hard-coded into a hook form altar. And it's impossible to get them out specifically without a discrete function. And lastly, each field must be able to provide a set of defaults, including the label, default value, a list of options, et cetera. So this is a good idea anyway, providing good defaults, speeds up the processes in a lot of areas. But this is an absolute necessity. If you're going to be dragging in fields, you need to have enough information to actually render that thing immediately, which means setting a good set of defaults. So we actually don't have any time at all for more questions. But I feel like we got a lot of them covered. And actually, this small discussion that we had here today actually was worth about three months of issue queue back and forth bantering. So I feel like this is a really productive session for us. But if you can locate this session on the London 2011 website, click the evaluate the session link. There's also the slides are already up on the site. And as promised, if you would like to receive $20 off a first month of Drupalize Me video, Drupal Tutorials, there's a coupon code specifically for attendees here. Thanks very much for coming, guys.