Bubble.io Tutorial: How to Build an App on Bubble (Full Masterclass)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you're building a no code app on bubble this is the video that's going to help you go from start to finish in it we're covering things like what you can and cannot do on bubble how to build a custom scalable app actual development walkthroughs that you can apply to your own app responsiveness in making your app work on any screen size and more i'm gabby roman co-founder of coaching no code apps where we've been helping entrepreneurs launch no code apps that have helped them grow seven figure businesses start new streams of revenue or simply develop a new set of valuable skills and everything in between this video is your master class on launching no code apps on bubble stick around the whole way through because we're going to be breaking down best practices around using the platform and showcase how creative you can actually get in your own development make sure to bookmark this video because you can apply these principles to your own app and refer to the video as you do so let's start by understanding what the bubble platform is on bubble you can build custom web applications all without code you do not need to have a technical background to build a full scalable app and you have complete control over every aspect of that app how it looks to your front end users the designs of your pages how your database is structured so all of the information that is being stored to the application and how it's used how it's searched you also have control over all of the logic in between so it's up to you to create all the functionality bring it to life so that it is a highly interactive experience for your users that is custom to your needs now all of this is going to happen through visual programming which means that you do not need to have a technical background to build an app you are not going to be writing lines of code instead you're going to be dragging and dropping all of the components to bring your app to life this is the front end designs the way that it looks to your users and also all of the logic behind the scenes to really make it more interactive okay and before you ask yes you can absolutely create robust applications enterprise level productions with drag and drop visual programming it's really up to you to put together the right combination of things with the best practices and strategies to ensure that it's going to be scalable for the long term this platform is not just for mockups or first versions or prototypes you can actually build full-fledged businesses on this platform it's just all in how you structure the data it's how you put together your logic following a lot of best practices and we'll talk about those throughout this video now over here i have a few different types of common applications uh broken down into different categories of what works best on this platform what's just okay in other words you can build them on bubble but there are some things to consider and then what types of applications you'll want to use a different system for this is to give you a sense of what what is possible on this platform and you know how you can mix and match different types of features to create a custom experience so let's start with the types of applications that are really great for this platform anything that's really data driven and has users interacting with each other where they need to create an account and log in and maybe provide some data update statuses be able to search through data in some way that's a very very common type of functionality for bubble apps so marketplaces are huge so connecting users with each other being able to put up listings book services with each other purchase things from each other you can absolutely do that you can also integrate with the payment gateway so that users can pay each other you can take a fee out of that lots of ways to construct a marketplace social network's also very popular so chat functionality between users being able to have activity feeds notifications comment threads sharing pictures with each other normal social network type of stuff dashboards are very popular with business related applications so that they can gather insights about their data they can aggregate on things they can visualize it in charts and be able to search and keep track of it just have an overview picture of their business crms and erps other very common types of needs functionality that businesses need in order to run properly so being able to manage all of their customers or have some kind of an internal custom flow that takes in all of the aspects of their business in a really streamlined and automated way scheduling very popular type of functionality that can be done a number of ways um there's also a lot of plugins that can help uh with certain aspects of calendars and managing dates but you can do all sorts of things uh when it comes to creating a scheduling functionality for appointments for booking reservations um you know blocking out dates creating availability custom time slots all that sort of thing uh to to do scheduling type of features tracking is a common type of functionality that you'll find in a lot of different types of apps so project management or internal operations to keep track of different statuses or even with personal use cases if somebody wants to track their fitness activity or the meals that they eat every day e-commerce big topic lots you can do there so you can absolutely do shopping carts and checkout flows integrating with payment gateways happens through apis and sometimes there are plugins available for it as well so that you can take payments and that can be any kind of payment it can be one-time payments subscription payments um split payments it can go to multiple people just depends on the type of payment gateway that you're integrating with so paypal stripe there's a lot of other ones out there um yeah lots you can do with e-commerce dynamic forms kind of the heart of most applications is being able to collect information from your users and the way that the forms are presented is completely up to you how you're designing it the the logic behind it if it can be a questionnaire a survey or it can just be a more simple form it can be multi-step lots of different ways to approach forms and of course calculators we've actually seen a lot of financial based applications come through and build out custom calculators where they would have otherwise been using spreadsheets but gets very cumbersome in a spreadsheet so a custom application can really make things uh work more efficiently or just be more convenient for anyone that needs to work with those functions now a few different examples of applications that can absolutely be built on bubble but there are some considerations here include the following so media rich portfolios marketing pages blogs static websites the common thread with all of these is that they're not really interactive they don't really need users to log in necessarily to consume this content so while you can absolutely build that type of website really on bubble there are plenty of other services that do a great job for those types of apps specifically um and the bubble platform is really meant to be more of a data driven user interactive type of system so you might find that you're going to be reinventing the wheel quite a bit with some of those static type of applications with bubble apps we're looking at building custom experiences things that are unique to your market your industry your actual needs there's so many other platforms out there that make it easier for you to build static websites really quickly like i said you can do it on bubble um but it might not be so necessary to do it on this particular platform then there are certainly types of applications that don't really work very well on bubbles so anything with heavy graphics and animation so if we're talking about games those are things that you'll need to build coded or in a different platform that's more meant for that multimedia editing like video editing podcast audio editing uh photoshop type of applications um are not best for this type of platform if you're going to try to build something like that you're likely going to be integrating with a lot of custom code anyway so probably better to use different systems um hipaa compliance is on here more as a way for you to check with your industry if you have any specific regulatory um compliance that that you need to meet bubble is not hipaa compliant for example so you wouldn't want to be building applications that have to store sensitive patient information um so that's something that you definitely want to be aware of now as you can see there are a lot of bells and whistles that bubble offers you in terms of managing your application and extending its functionality further for the long term and this is really just the tip of the iceberg we are not going to go through every single bell and whistle that it offers you there's just too many of them instead we're going to stay focused on the core fundamentals the core concepts that you need to build an application that anyone needs to build any type of application on bubble these are things that if you have a good understanding of them you will be able to evolve your application in a smarter way and you'll have full control over how it works and that's what we want to stay focused on today before we dive into those core concepts i want to run through some frequently asked questions that we see come up all the time in case you're still on the fence about whether this platform is right for you and your app the first one is can i design a professional looking app yes a big yes you have complete control over the user interface the ui and how it is presented to your users you're actually given a blank canvas so it's up to you to leverage all of the tools and the design settings to have it look the way that you want in terms of the layouts and the aesthetic the colors the styles everything is under your control and if you don't believe me we're going to go through some demos during this video and you'll see how customizable every aspect of the front end appearance is available to you next question is are there templates yes there are bubble does have a template marketplace where you can build off of a template and modify a template especially if there's something that is close to what you're looking for but we do recommend building your custom applications from scratch it's so much better for your learning um to configure everything completely around your own needs templates are great to learn from to see how things can get set up and if you're not building something super complicated or super custom then a template can help speed up your development and you can get something out the door rather quickly but it is likely if you're building something highly customized for your own needs you're going to end up changing a lot about the template anyway so rather than giving yourself more work than is necessary built from a blank page i promise you'll learn a lot more from it are there plugins yes there is a very big plug-in marketplace um some plugins are published by bubble themselves but the majority of the plugins are actually created by the community there's going to be free plugins and paid plugins um and so you can explore a lot of them have example pages demos to show you how to use them and it's really going to be a case by case in terms of what makes sense or when it makes sense to use a plugin can i put my app in the apple app and google play stores yes you can you can do that through a process known as wrapping so this is not converting your app to native code it's just converting the the web app into a format that is compatible for those app stores there are third-party services that you would go through to make this happen and just keep in mind that at best your app is going to be a hybrid at that point while you will be able to download your application from the app stores you still need to have an internet connection you're not going to get full native mobile app capabilities and you'll want to check with the wrapping service that you use to understand what the limitations might be there can i import my designs so mock-ups of designs not functions from other tools like figma adobe xd envision bubble only has an import tool for figma right now there are several limitations around how everything gets imported and what gets converted properly to bubble it's not 100 perfect if you have simple figma designs it could work really great for you and save you a lot of time but in most cases you're just going to want to do your designs from scratch directly in bubble that's what we have seen works the best can i export or host my app's code no you cannot bubble apps only work on bubbles so you cannot import code from external services and expect them to work on bubble you cannot export your code from bubble and expect them to work on different uh app platforms so it's all contained and this is a great thing and this is part of why bubble is able to make it so easy for non-technical entrepreneurs and app builders uh to create their apps on bubble because everything's handled for you they take care of the servers they take care of the data security they take care of um the connections to your domains um all of that stuff you do not need to worry about it and for that to happen it needs to be in a closed environment so you're not able to export or host your own apps code with that said you can export your data so this is our next question here can i export my data yes absolutely it is your data bubble does not own your data so you can expect export it a few ways via api or csv bubble has some very helpful easy to use tools for exporting to a spreadsheet so that is always available to you is my data secure yes it is bubble is built on aws this is amazon web servers and uh it encrypts your data at rest which is just a fancy way of saying that um there is encryption happening so that if you're not authorized to access the data you will not be able to get to it and amazon's um web servers power a lot of the biggest websites in the world um and bubbles security detail page on their website actually goes into this in much more depth i do encourage you to take a look at that if you're looking for very specific security requirements for your application can i collaborate with other designers or builders yes you can you can invite other bubble users with their own bubble accounts to access your editor so that they can either view things and not edit anything or they can edit you can give them more access to work with you bubble also has capability to have multiple versions so you can be working in one version of your app your collaborator can be working in another there are systems to sync all of those changes lots of different things you can do for that depending on what plan you're on that's also going to dictate how many collaborators you have can i really scale yeah well this is the big question right yes you absolutely can in fact we specifically work with entrepreneurs for building apps for business so they are looking to scale and stay on this platform for the long term um you are literally given a blank canvas it is up to you to put together all of the components in the right way in an efficient way in an optimized way so that it is reliable it's consistent and it can evolve long term once you have more users on board you have higher volume of activity um and like i said there's a lot of strategy around doing that right all right so here's what's coming up next we are going to talk about the pillars of every single uh bubble application the database right that is very much going to power your app and how it functions um most of these applications that are built on bubble they are data driven whether it's data that you are providing as the platform owner or your users are generating themselves responsive design these apps got to look good right so and they have to look good on all different kinds of device sizes so we'll touch on what capabilities you have around not just designing an application and putting something together that looks good but also making sure that it's consistent right that uh that it's intuitive that your users are always oriented when they're in your application workflows this is where the magic happens this is where things come to life and bubble really works in a if this then that type of logic if you click a button then we send an email that is such a basic example but that's essentially what it is that's the kind of logic that you're going to be putting together if someone takes some action then what do we do do we update the database do we show the user something do we have something appear on the screen and visual programming we're going to just talk about how bubble thinks and how you need to approach putting together a bubble app uh the mindset that you want to take like i said you know you're programming you are a developer here there aren't any lines of code that you need to write um but there's very much a logic based approach that you need to take in order to put everything together you have to tell bubble every single thing you want it to do it has no idea what you're trying to build you are given a blank canvas so if you instruct bubble with every step and every action then you will be able to produce that outcome for your users as well so there's a lot to know about how to do that properly and a lot to know about where to find the tools you need to execute on those things then at the very end of this video we're going to go through some overviews of just other features to be aware of tools and resources available to you for testing and deploying we're also going to go over a list of advanced capabilities so that you're aware what is possible when you're ready to grow beyond your first version of your application and expand its capability all right building an application is very visual so as i go through and teach you all the core concepts and fundamentals you need to know i'm going to be putting this all into context through several feature walkthroughs of common functionality so that you can see where all of these things live in the bubble platform and how it can all come to life in fact let's go ahead and take a quick sneak peek at the demos that we're going to be building so that you can get a sense for the level of design and functionality that's coming up that will that we'll be going through so the first one is a very common piece of functionality which is a sign up now in some cases your signup might be very simple one single form like this in other cases it might be more of a multi-step onboarding sequence all of that is very possible but we'll build this from scratch so that you can see how to put this together this layout is very common for modern web applications we're also going to look at an expense and budget tracker trackers we've got more calculations involved here we're working with a lot of dynamic data and so here we have you know the user can add in all of their expenses they can fill out this little form this form collapses down we can switch over to the budget manager so the user can type in what their budget is and the app will tell them you know hey you're under budget you're over budget you're getting close to your budget right it's very interactive so if i change my budget of my supplies to a higher budget right so now i'm i'm not as close to it and this changes for me in real time this is all custom logic that is built for this particular feature these are not templates right there's not a built-in budget calculator that bubble has we're leveraging different components and putting them together with specific logic to make it function in this way so that's what we're going to be looking at as well then we're going to look at chat functionality this is very popular with any type of app that has users communicating with each other so think of a project management type of tool where you have team members uh messaging each other or a social network this has actually been designed from the perspective of a support agent um communicating with customers so they have statuses that they can track and really when we go to this feature we're going to be looking more at the layout and the design how these uh you know chat bubbles have been made more dynamic to expand and contract in their width how we can switch over to different conversations between you know the different customers we have file attachments for each of these individual messages these are different features that again you can customize for your needs you don't have to have all of these different things and you can of course make this even fancier the last feature that we'll go through is a shopping cart and checkout flow so i'll step through this real quick here so that you can see what the experience is like i'm going to start a new order i can see different items i can choose this is a menu of pizzas so i'll add one there maybe i'll add a second one i want a quantity of two and it's adding up my order summary here i'll add another pizza right so i can remove those items it's going to recalculate my total every single time i add new items and once i'm ready to check out it's going to take me to a payment collection form that is connected to stripe which would be the payment gateway that i would use here now before we move on to our next section i want to orient you real quick here inside of our demo application so you know where all the sections are as we go through uh the next topic so every single bubble editor is broken up into seven sections and you can navigate between those sections by clicking on any one of these tabs here right now we're on the design tab this is our canvas this is how we design all of our front end pages so you can see i'm given a blank page to start i have a number of different elements that i can choose from so let's say i click on a button add it to the page and now i'm off to the races now i can configure this button however i want i can have it look different it doesn't have to be this color or this size or this font i can also change the positioning depending on other elements on this page but this property editor here lets me configure that element further i'm going to jump over to another page so you can see what it would look like with something already designed let's actually go to our sign up demo here so a few more elements that we'll see here's my group i have a number of different text elements they're spaced in a certain way this page is responsive in fact this design area lets me toggle between two different views i can look at the ui builder where which is where you'll spend most of your time but also the responsive mode of this screen and bubble gives me different preset break points so that i can make sure that it's still responsive to different sizes your workflow tab is where you make things happen i'm going to switch over to a page that has some actions let's go to that messaging demonstration here alright so this is where we had the conversation threads on the left and the messages would show up on the right so this is where you can visually program your logic and tell bubble to do certain things for example if the user is going to create a new message they'll hit a send button and we're telling bubble in what order to execute certain actions notice that there is no code happening here i have simply chosen specific actions from bubbles big list of available actions right there's it's all categorized we can do a lot of different things here and and to execute these in a certain sequence our data tab is where we configure the architecture of the database so every single bubble app is going to come in with a built-in user data type which equates to a user table right so if i go over to this sub tab for app data and click on all users i can see that i have six users in my database under the user data type you can think of it as a table so every bubble app comes with that so that users can sign up with a secure password and all that but it's up to you to create additional data types that make sense for your application so you can see that i've added a few different data types for the demo features that we'll be going through and if we go over to the app data sub tab i can click through and see some of the entries that have been added for these sample tables okay there's a couple of other sub tabs here to help you manage other things around data like your privacy rules files that are uploaded option sets we'll talk about those in a sec styles is our next tab and this is where you can configure consistent appearance properties across your entire application i highly recommend you take advantage of these because not only do they keep you consistent but they also help you design faster so that you don't have to go through every single button and set it up over and over and over again in the same way changing the color changing the font size changing the font style or the spacing or the roundness there's a lot of different appearance properties for all these different types of elements it's not just buttons we're talking about everything your text your containers your links your maps absolutely everything has at least a handful of appearance properties and so when you set up styles you're basically creating presets the next tab we have here is plugins so bubble has a very big plug-in marketplace some plugins are published by bubble themselves you can see these first ones here but most of them are actually published by the entire bubble community some of them are paid some of them are free uh we can search do an example here for email related plugins so lots of different options to extend functionality in your apps so very helpful area if you're looking to do something that you can't exactly build yourself uh directly in bubble then we have a general settings um area with a lot of sub tabs for all sorts of settings within your application i do encourage you to kind of step through each one of these so you can see what is customizable there but a lot of this is just kind of back end connecting to your domain your app plan and billing all of that the log section is where you can monitor the performance of your application there are some other areas here that have to do with some back-end workflows that's more of an advanced capability but you have some things to help you monitor that activity and this is generally how you can see what kind of capacity your app needs in order to um uh support all of the activity that your app has from your users or from maybe heavy workflows that are happening in your app so you know if you need to upgrade or not there's also different metrics around the usage of your application as well now throughout the rest of this video we're actually going to be more focused on these first three tabs i'm actually going to switch back over here to talk through those a little bit more now those first three tabs make up the three primary pillars of every single bubble app database front-end design and your workflows so as you can see database is where you store your information this is data that either you can pre-populate as the app owner and or data that your users are generating so if they're uploading files they're filling out forms um all of that can be manipulated once it's in the database in a structure that you have defined and you've organized yourself the front end design so that's where the canvas was where you add your visual elements to the page and you can position things how you want you get it to look however you'd like and not only that but it's responsive so it can actually adapt to different screen sizes all the way from a desktop computer down to a smartphone and then the workflows are like the brains of your application this is where you instruct bubble to do certain things in your app whenever a user interacts um with the front end design so they click on a button and then that triggers some sequence of actions to occur so these three things combined create a full stack platform that addresses every aspect of a functioning application and you do not need to go to an external service to manage data to do the front-end designs to do the logic it's all housed in one place for you is really great because they all communicate to each other and it's it's all under your control which is the the best thing here okay so now we're going to take a closer look at the database and the different components that you are responsible for putting together for your own app there's three different sections here data types fields and option sets data types are essentially your tables every single bubble application comes with one built-in data type called the user type bubble essentially assumes that most applications are going to require users to sign up with an email and a password and they can engage with the application as that person uh you know with whatever rules you create around what they have access to do to see beyond that it is up to you to create whatever other data types you need for your application so bubble doesn't know what you're building right you can't just say hey bubble i'm building a marketplace and then boom you have data types to support a marketplace it just doesn't work that way you have to create every individual type that you want for your application this is a good thing because you have complete control over how your data is organized the next piece here are the fields fields are created per type and you can have one or more fields within each type and this is just a way for you to save certain information with a specific format to the to the record in the database so for example a user data type a user might have a first name a last name a profile picture a date of birth right these are different fields you would create within that data type then you go to the next data type and you create the fields that are specific to that type and not only that but you also tell bubble the format of the fields is this a text is this a number is it a date is it a file is a is it a geographic location there's actually a lot more you can do with fields and their definition but essentially that is how you tell bubble what to expect when content is being saved to a particular record and then option sets this third point here this is how you can manage lists of predetermined choices so an example would be a marital status let's say that you wanted to collect that information from your users you want to know what their marital status is so you would create one option set let's let's say it's called marital status and then the list of choices within that set married single widow divorce how you display that set back to your users completely up to you lots of ways you can do that in the front end design they can check boxes they can choose from a drop down or a radio button they can search through the choices if you happen to have a bigger list another example of a common option set is statuses so if you have users creating posts or listings of some sort where they need to go through multiple status steps uh your option set could be called you know let's say listing status and the choices would be things like draft archived published pending review right things like that you are in complete control over what the sets are called what the choices are it's just whatever you need in your application as far as predetermined list of choices the next thing i want to do here is put this into perspective with a different visual representation that you might actually feel more comfortable with more familiar with which is a traditional spreadsheet we've actually heard from a lot of people who are just getting started with bubble that the database is often the hardest part it can feel really abstract especially if you don't have any database background or web application experience um and and not understanding kind of what it means to set up a data type or create relationships between things so what i want to do is show you the equivalent of what you're doing in your editor within a traditional spreadsheet format at the end of the day all you're really doing is setting up tables but it is up to you to configure every part of that table the labels for them how many columns essentially you're creating and also telling bubble what kind of values are being stored the format of the values so in my example here let's imagine for a second that i'm building an e-commerce application where customers will select products that they want to add to their shopping cart and then indicate a quantity for each of those products we calculate a total and we can make a payment on that final amount all of this information to support a full checkout flow is going to be supported by multiple tables because we want to see this data and organize it in different ways depending on whether we're at the customer level at the parent order level or at the individual line item level right the product the quantity and the subtotal of that item so if we look at my spreadsheet workbook here i have things broken down into four tabs these represent four different tables or four different data types okay so the first one here is my user table or my user data type this is equivalent to this data type here right so i'm in my data tab under my data type definition these would be all of my tables in my application now once i go into one data type i can set up what would essentially be the columns for that table so a user has a date of birth a name a photo okay so i have this over here i don't have the exact same fields but the field that you create in your editor i have as column headers in my spreadsheet so user would have a first name a last name a type an email address right users have a creation date and a last modified date if i go into my next table so my products here a product would have a name and a price okay if i go back into my editor go over to my product data type i have name and price is a better example because they are actually the same between the two and notice that when i set up the product data type a product's name is a text product's price is a number so i set that up every time i create a new field right i had done price like this and i selected the field type saying hey this needs to be a number we are going to want to do math with this number at some point so bubble needs to know that this value is something we can calculate on now we get a little bit fancier when it comes time to relating records to one another or relating a record to an option set let's start with the option set so here under my data kind of management area i have a sub tab called option sets and here's where i can manage all of those different lists of choices so for example i have an option set here called user type so i just created that by typing the name here hitting create and i've got my new user type set i can change the name here if i want and then i defined the list of options within this set so users can be admin a customer or a guest i can add another choice and it would add it right there to it so if we go back to my example user uh table here we can see text field text field and then i have this in orange here to indicate that this is an option set so this isn't something that the user is typing in it's something that they're choosing they're selecting from some design that i have on a form uh you know on a front-end page for them maybe it's a drop-down maybe it's a radio button the field that i have here in this dark gray or this black color these are actually built-in fields so bubble has a number of built-in fields for every single data type creation date this is a date and time stamp of when the record was first generated this is not something you can change and then the last modified date so if we updated the customer's last name for example this would update to whatever that timestamp was unique ids every single bubble record is going to get a unique id um you cannot change those this is very helpful for having completely unique across all tables some identifier now it's not sequential like this i did i did this you know in this format just for simplicity but unique ids are actually more random and they're a longer string i'm going to open up a record here so you can see this is really what the unique ids look like so this is essentially what you're doing when you set up your data types you're creating tables and when you set up the fields you're essentially creating the column headers and then you do have to define what type of format those fields are going to be so bubble understands how to work with them going forward now when it comes time to relating records to one another i'm actually going to walk you through that when we go through our shopping cart example because it'll involve workflows it'll be easier to see all that coming together now let's jump into responsive design and in general your front end ui this is how your user is going to experience the visuals of your application you are in complete control over the layouts of your pages how things are positioned uh the spacing between things the alignment of all of your visual elements how things look stylistically right you can add your own branding your own colors your fonts there's a lot that goes into designing the front end pages of your application now it's important to understand that bubble actually has two modes that you can design your pages in first is a completely fixed setting the second is a responsive setting responsive means that the pages can adapt to different screen sizes so if you're building for a desktop and somebody views it on a tablet the page can resize itself and elements can be shifted around so that it still looks good on those other device sizes whatever direction you're going in from a larger screen all the way down to a mobile device you have complete control over that behavior and that is i cannot stress enough going to work best for you if you design with the responsive engine enabled from the start okay so i mentioned that there is a fixed mode that you can create your application in but there are actually fewer cases where you would want to do that these days most web applications are responsive people expect for them to be responsive even if you're only designing your application for one target device so if it's just going to be a mobile app or just for a larger computer you still want to design with the responsive engine enabled why because bubble is going to be in charge of keeping everything neatly aligned spaced really neatly you have a lot of really cool tools to keep things consistent you're essentially designing on a grid take advantage of the responsive engine enable it from the beginning learn the settings we're going to go through a bunch of them here today so you can see what to look out for all right so what i want to do here is go through an introduction of the layout settings available to you when you start adding elements to your page and how you can manipulate all of the layouts so i'm on a blank page right now i'm on my index page and if i double click anywhere here i pull up the property editor okay this is a way for me to manage various appearance settings layout settings conditions and this is a context sensitive window which means that the settings available to me will change based on whatever element i'm working with i have double clicked on the index page and so i can only manage the index page from here if i add a button to the page then you'll see that the property editor changes its perspective to be able to work with the button so for example i can change the label that's on the button let's say submit i can change the style of the button we have some preset styles here or if i wanted to remove the style i can do that and i have more controls to independently style this button as opposed to having a preset applied to it so maybe i give it uh you know a green color here oh that's so bright let's make it a darker green there we go um and a number of different settings based on what's available for that element notice how when i move this button around that it is staying exactly where i want it bubble is not shifting it anywhere for me it's not repositioning it that is because the page itself the index page here is set to a fixed container layout style i can change this to one of my three responsive styles to have bubbles responsive engine kick in and position things for me on a grid so if i change this to a row you see that the button snapped to the upper left corner if i try to now move this button just kind of over here and i let go of my mouse it's going to snap it right back i can no longer freely position things on the page but this is a good thing because this is going to keep you consistent and if you are consistently designing on a grid you're going to create beautiful applications that are intuitive for your users nothing's going to get lost it's going to force you to be a lot cleaner in your designs not to mention it's going to be able to adapt to different screen sizes in a better way so i'm going to add a couple more buttons so that we can see what it you know how we can see rows and columns come together uh so i'm going to copy this button and paste i'm just using my keyboard shortcuts here i'm going to paste a few more other ones uh i'm just using ctrl c ctrl v i'm on a pc if you're on a mac you can do apple c apple v there's a lot of different shortcuts actually if you right click anywhere on the page you have some settings there you also have an edit menu depending on what you're working with you'll have different options available to you so before i change some of these layout settings let me change the appearance of these buttons a little bit so we can keep them apart i'll change this one to a primary um maybe i'll do like a darker purple color here for this button and maybe a different yellow for this one right that way we can see different buttons there so notice how when i copied and pasted those buttons they all fall in a row they're just stacked from left to right one after another again that is because the container they are inside of which is the page and we can have other containers but the container they're inside of is set to a row style now i have settings to manage this row right right now they're aligned to the left so they start from the left and stack going in to the right i can go in the other direction if i go to the center alignment then we have they're all going to just naturally start from the center and then work their way out depending on the number of elements you've added then we have some distribution settings so i can space them out where there is a space between them and you can see there's even distribution so the outer buttons the outer buttons of my row are going to go to the very edges of their container again in this case the container is the page if i choose this other option here it's going to have some space outside of those edges right we have a little space on the left a little space on the right but still even distribution between them on top of that and i'm going to show you here with the center alignment i can add my own gap spacing between the elements so notice that they're touching right the edges are right next to each other there's no space there i can select this and create some column gap spacing let's say 10 pixels of spacing gives me right a little bit of a gap there if i increase it to 20 a little bit more so i have complete control over um how much space happens between each of these visual elements so now if i go to let me just remove this here undo the setting changing the layout style of the page to a column you see how bubble redirects them and now stacks them vertically on top of each other creating a column out of these elements so i also have container alignment settings here right now they're stocked at the top stocked they're stacked at the top top aligned if i go to the center that's at the middle of the page we can see about the height of the page right there let me actually take down the height of my page to 600 pixels just to keep it a little bit shorter that way we can see it better um bottom aligned i can space them out vertically with space around right we have a little space at the end there and then at the beginning versus space between so it moves those outer buttons to the very edges right so i have control over those positionings in a column and row grid format now align to parent this is a different one that you're going to have specific use cases for this typically if you have a lot of elements within a container you're going to go with row or column but if you have a single element with the container that's a great use case for a line to parent that's certainly not the only use case there are others it just depends on what you're designing but i'm going to show you what the behavior is here let me remove all of these buttons except for one and change the page to align to parent now if i go to the element inside of that align to parent container i can place this element in one of these non-ends this is broken up into nine sections so we have one of nine non-ends that we can select right now it's in the upper left corner if i go to the middle left lower left right i can just go all the way around like this i can even put it in the center all right so now we're on the third pillar of every bubble application which are the workflows and i described this earlier as the brains of your app right this is where you instruct bubble to carry out actions for you bubble again has no idea what you're doing so you're going to have to create the logic for every single interaction that you want to happen in the application whether it's something that's an automatic thing or if the user has to click on a button or load a page or provide some information by selecting or typing something in that is up to you to define so that bubble knows what to do with it you want to think of workflows really as the connecting piece between your database uh and the user's front-end experience okay so with workflows bubble follows and if this then that kind of logic if something happens then something else will happen so if a user clicks a button then one or more actions will run if the user loads the page then one or more actions will run if a change has occurred in the database then something can run kind of automatically you don't always need to have user interaction to make things happen that's where you can get really fancy really comprehensive and custom you know automation systems not only that but you can create a lot of really sophisticated conditional logic on your actions so if somebody logs in and you know they fill out the form email password click on the button that says login the next step for their for for them naturally would be to take them inside of the application right maybe redirect them to their dashboard but what if you have an email confirmation process so if they've logged in and they have not confirmed their email you want to take them a different way you want to show an alert message or take them to a different page or show a pop-up of some sort saying hey we need you to confirm your email you know go check your inbox first or maybe click on this button to resend that email versus if they log in and they are confirmed then they can go into their dashboard so that conditional split is logic that you can build into your workflows as well so different things can happen based on who the person is or what data they're interacting with what time of day it is i mean honestly there's so many different variables that you have available to you to create the exact experience that you need for your users to accomplish what they came to your app for um bubble has a ginormous list of built-in actions that are all categorized for you so that you know exactly where to go now you can extend functionality um workflows and actions with plugins that you install into your application like i mentioned a little earlier the marketplace is really big and most of the plugins are published by the community a lot there are of course plugins published by bubble themselves but you're gonna find all sorts of plugins some that will allow you to trigger different kinds of actions um or add different types of visual elements to your list of elements right in the front end design that you can drag and drop onto the canvas um but you'll have to just see what is going to actually make sense for your app all right so now we're going to dive into our first demonstration which is a very common piece of functionality the sign up form most applications are going to have some method of signing up their users so we're going to go through a lot of the common steps that you would take and we're going to look at the three pillars coming together in a start to finish experience we'll look at the data structure necessary for the user account the front-end design that the the new user would be experiencing when they're filling in their details and they're clicking on a button and the workflow logic to connect the two together and actually create that new user record in the database okay so this is the sign up form that i'm going to be rebuilding from scratch from a blank page uh so that you can see how it all comes together this is a design i had done ahead of time so you can understand what the goal what the end result is going to be um but basically what we've got here is a sign up form with a couple inputs a button for the user to click and actually trigger a workflow sign up the user and an image over here on the right and i've actually got some conditional logic to hide this image once the user is on a smaller device size so that it's not really in the way one thing i want you to be mindful of just take a look here at the layout of this page so that we can start to make decisions about how we're going to set up our container styles at the page level i'm really looking at one giant row right if we look at the entire left side this whole white section that is one block in our row of two blocks the white and the blue the light blue okay now inside of this white block i have another container you can actually see the border right which is much smaller it kind of centers the group a little bit centers the form and this container is actually set up in a column structure you see how all the elements inside of that container stack vertically we have the welcome sign up email input password all of it's vertical we have two other row configurations inside of our overall column right within this line here okay if these were within the parent column the forgot password text would fall below this check box but they're actually next to each other on the same line so there's another container in there to kind of isolate those two elements and put them in their own row so that they can be side by side on the same line same thing is happening here for the already have an account text and the login so just be mindful of that layout these are the kinds of things that you want to think about when you are putting together your initial layouts is kind of get a rough picture of um the the rows and columns that you're you're forming through your visual elements because you're really going to start from the container level and then work your way in and that's going to keep your development more efficient okay so let's head over to the editor let's create a new page and i'm going to call this uh sign up demo 2. my first one is currently being taken up by the existing demonstration so we're going to start from a blank page here going to hit create and i have my new page so i first want to do a couple of settings at the page level so if i open up the property editor for this page head over to the layout tab i'm going to move away from that default fix setting and i'm going to set the page to a row layout style so now anything i add remember anything i add to my page is going to fall in a row they're going to stack horizontally so my first elements within my row are going to be two big containers that white group and on the left and then the light blue group on the right so i'm just going to draw an initial setting here we're going to change the widths and all of that in a moment and let's do another group and it's going to copy and paste so you can see these are side by side like that group a and b okay open up my elements tree now i'm going to give them some names so they're easier for us to identify we're going to say group left like that and over here group right and i'll change the colors the background colors of these groups so that you know we have some of that styling happening so i'll remove the default style which is just a transparent group there's no background color to it and i'll give it a flat color of white and then this one i'm going to remove the style as well give it a flat color of that light blue maybe i'll start here maybe take this down just a little bit it's not going to be a perfect match but we'll get kind of close there we go okay so there's my left group and then there's my right group now let's talk about the widths of these containers if i go into the layout setting of this group i don't really have a lot of control over dynamic widths i can set up a fixed width or a fixed height and the reason i can only do fix is because the group itself is set to a fixed container layout i want to change this layout to one of my responsive settings now this container is going to be an alignment to parent because the element inside of this container is going to be my form with that border around it okay let's go ahead and add that so we can start to see that coming together then i'll go back to the widths right so i'm just going to drag this form like this here and we're going to call this group form okay and group form is going to sit in the center of group left group form is in the center of group left let's go to the elements tree so you can see here group form is inside of group left and it's in the center with group form i'm going to give it some borders okay so let's do removing the style and all of this so you can see where the the settings really happen with the appearance properties so let's do a solid border give it some roundness on the corners of 10 pixels and it's a thickness of one pixel on the border i can of course increase it i don't want it to be that obvious just a subtle border and i'll take down the color of the border a bit so it's more light lighter it's lighter in color that was a weird way to say that let me remove real quick here under gridden borders the um bubble has a way for you to kind of always see the boundaries of all of your elements when you have this turned on which is helpful i tend to have this on but i'm going to turn this off for a moment so that you can see what the actual visual properties are when the user is looking at it okay so here we have our left group in white right group in the light blue and then a center group which i've called group form with the border around it you know what i want to do is i think i want to change the size of my page i'm going to go over to the layout and change the preset page width to full width get a little bit more width there and this full width is great for desktop size applications again understanding that we are building this with the responsive engine enabled so um even if i'm on a smaller screen things are going to compress down but this feels a little bit more comfortable for me since i am working on a larger screen anyway so notice that there's now some space over here on the right we're not feeling the whole frame whereas in our example everything is fully filling the frame so we're going to get to that in a moment here okay so back to my group left okay which contains my group form this group left currently has a fixed width setting now i have some controls now i have more controls over changing the widths and the heights because i changed it to a responses setting remember before when it was fixed i only had fixed settings now that it is an align to parent i can change this a little bit more i'm going to remove the fixed width setting i don't want it fixed to 479 i want it to adapt to different screen sizes so i'll uncheck this and it's going to maintain that that what was previously the fixed width now it's going to move it over to the minimum width which means that bubble's going to make it at least that wide and if i'm on a smaller screen it's still going to be at least that wide so things could get cut off so i'm going to remove the minimum width okay so now it is fully dynamic as long as there is space for this white group to exist it's going to expand as much as possible and even if i take down the page size super super narrow it's going to continue to compress down okay but i don't necessarily want it to be just fully extendable like this because i also have this blue group on the right now let's update this one here real quick as well i'm going to change this to align to parent so that the image inside we don't have that quite yet but the image will sit inside in the center i'm also going to remove the fixed width setting and remove the minimum width okay so now that they're both dynamic they're kind they're taking up equal parts within the page right they're both elements in the row at the page level i want to give the form a little bit more room i want to prioritize the form and make the size of this space here for the image be less i don't need as much space for this here so this group on the left i'm going to have it max out okay percentage-wise you can do things either by pixel or by percentage max out at 60 of its most immediate parent in this case it's the page and this group here is going to max out at 40 percent of its parent so you see now this is taking up 60 percent of the space this one's taking up 40 percent you don't have to go off of percentages you can go off of pixels you also don't even have to be specific in this way but i wanted this type of look where the form is always going to be more dominant in the space it takes up on the page and so i'm only allowing this blue group to go 40 of the parent which is the page okay um and if i go into my responsive viewer here and just kind of preview you see how that the the ratio of the 60 to 40 percentages it stays put right as i expand or contract the page they're always going to be 60 to 40 percent relative to whatever the pages overall width is okay all right so now let's look at this group here this is our form we're going to need more space than this this form is still set to a fixed setting so the elements inside of the form right now are fixed i want to change this to a column so we've actually matched mix and matched three different layout styles the page is a row this left group is an align to parent and the form group is a column now the column is what's going to have all the content inside with my text and my inputs okay so let's give this um with a little bit more room let's remove the fix width setting and maybe i just want to max this out at let's say 400 pixels something like that we might end up adjusting this and let me turn on my element borders here but this is going to be a good place for us to start notice how i have not touched inputs or buttons i am starting with the containers it might feel boring i might feel a little tedious but i promise you it's going to save you so much time if you are if you take care of the the foundation of your designs right you're you're basically putting together building blocks so that once it comes time to adding the buttons in the inputs they are exactly where you want them to be on the page right layout wise position wise so okay so let's start adding some elements now that we have a form that is giving us enough space here i've maxed it to 400 pixels and i'm going to start with a text like this and we're going to say welcome okay and this is going to be i'm going to change the styling a little bit i'm going to up the font size um let's make this a heavier font weight maybe the medium maybe one more than that semi-bold okay now you might be tempted to do things like center the text here inside of this you know these boundaries of the text element um or maybe increase the size so that it fills the element boundaries what i want you to prioritize is under the layouts here the width and height settings the responsive width and height settings so i'm going to take away the fixed width setting i'm going to take away the minimum width okay you see how when i took away the the fix now because there's no max it expands the full width of its parent because there's no max we're telling bubble hey have it grow as far as you can within its parent and that's what's happening there if i said i want the max to be 300 pixels then it stops at 300 pixels right what i'm going to do instead though is remove the minimum like this and have it fit to the content so welcome is a certain number of characters and it only needs that much width if my content was bigger right so if i said welcome to the app like this the boundaries of that text element are going to grow with it grow with the content so you're going to have more control over your elements position and spacing relative to other elements if you generally have thing for as far as text goes especially generally have things fitting to content now not everything needs to fit to content sometimes you're going to want to fix things or have certain minimums or maximums but with text i see a lot of people kind of using the font adjustments when really they should be working with the boundaries of the element and changing those widths and heights so the same thing for the height i'm going to remove the minimum height and now you can see the boundaries of that is perfectly around the text so i'm not having any extra space happening here that i would have to account for if i'm going to introduce other elements that need to be spaced around it as well so i'm going to center this now like this and i'm going to duplicate the text i'm just using my keyboard shortcut and going to say sign up below to oops sign up below to get started and i'll take this one to a lower weight maybe regular whoops regular and then maybe a smaller font size let's go to 14. okay so we have more of a heading and then kind of a subheading there next thing i'm going to do i'm going to create my my inputs with the labels so i'm going to copy this text here and give this a label of email address and add an input okay about that that wide um i'm not going to have a placeholder here because i like to have my input labels outside so the user always sees the label placeholders are a way for you to create basically instructions or help or text sample values that are going to be faded in the input and then as soon as they type in it just goes over that but once they type over it they kind of lose their label so i like to have labels outside okay so this is going to be my email input i'm going to make sure to label this email address so that i can identify it when i'm working in the workflows and this is going to be format email address with regular inputs like this there's a number of different formats that bubble can accept and in some cases may even show different formatting to the user so if you have the currency for example bubble's going to show your currency symbol um or decimals it will actually show the decimals with a password it will conceal the password with the dots so just depending on what kind of content you anticipate to be entered in here just pay attention you might have a special type of formatting that you'll want to select emails specifically need to be set up as email so bubble understands that it is an email address there's a lot of special things you can do with email addresses okay now right now everything is just kind of vertically down the center i want to group together my email input and this sorry my email address label and this input so what i'm going to do is multi-select this text and this input by holding down my shift key i'm going to click this one first hold down shift then click this one and they're both selected as you can see and i can either click on this kind of action button here i can group them in a fixed container or i can help myself by right-clicking saving myself one step and grouping in a column container you can group in different containers here i'm going to do that group in a column container so it's going to think about it so now i have another container inside of my group form right here's the text there's the sign up text and then here's my new group i'm going to call this group email okay very important to label as you go it'll keep you very organized now this group can be set up a little bit differently if i want so for example uh the email address text i might want this left aligned so that it's to the left of right if we look at our demo here real quick right you see how these are centered technically in the form group but the label is left aligned um on top of on top of that input now that i have this label and input pair organized how i want it generally within this group i'm going to copy that whole group right i'm going to just use my shortcut ctrl c and then ctrl v now i have a duplicate and i can more quickly create the next input which is going to be the password password is the label and then this input i will change this to password like that okay let's create the next um section here which is the remember me and forgot password text so i'm going to help myself a little bit just by getting started with a new group just because of the sizing so that i have the same widths and i'll remove this input let's say this is the forgot password text and we'll change the color of this to really highlight it for the user i'm going to change the weight of the text and this needs to be a part of a row right if i add my checkbox let's search for checkbox over here and add this to this group they're going to stack in a column i want them to be in a row so that they're in one single line let me move the check box ahead of the you know before the forgot password so i'll just shift it over remember i can use these texts here like that okay now i'm going to change this container to a row container so now they stack horizontally next to each other let me remember to rename my groups here this is group password and this one's going to be group uh check box and forgot like that okay so this row which contains these two elements i'm going to set up the alignment so that there is space between them that way this text is all the way to the right and this checkbox is all the way to the left let's give our checkbox a label this was the remember me checkbox and i don't necessarily want the width of that checkbox to extend past it i don't really need that so i'm going to update the width settings of this checkbox turn that off remove the minimum and have it fit to content same thing for the height i'm just going to remove the minimum height so it fits perfectly around that checkbox and you can see that this group is also much taller than i really need it to be so at the group level i'm also going to remove this minimum height that was just kind of created by default there we go so we have our elements here now you'll notice that i'm waiting until the end to create my spacing between everything um a lot of times i want to just focus more on the configuration of the layouts of all my specific elements and then clean up with all of the spacing because oftentimes those things get changed as you go anyway so just trying to keep my development more efficient here the next thing is going to be the sign up button okay so let's create a button here this is going to say sign up like this and the layout i want to center it horizontally you can see that the width of this button is a little bit wider than my inputs we're going to address that in a moment right now i just want the sign up button in there okay the next thing i want to add is the um other row let's actually go over to our preview here yes they already have an account and then the login text and it's going to be kind of similar to this remember me and forgot password so i'm going to take that group and paste it as well you see how it pasted it right after the thing that i copied from so i can shift it down past the sign up button i could have also picked it up and reorganized it you see that bar there that horizontal bar bubble showing me where this would be positioned if i just dropped it anywhere there in the group so i'm going to put it there and i'm going to have this say what was it it was login and then already have an account so let's actually get rid of the checkbox because these are two going to be two texts so this is already have an account like this and this is going to be log in like this i believe this one was more in the style of our labels and this text here one thing i can do is copy this formatting so copy formatting and then paste the formatting on this text like this so now i don't have to go through and do all the same settings it's a quick little shortcut for me now in my previous design you could see that these are more centered with a little bit of space in between them versus being spread out to the edges of their container so i can accomplish that by going back to the group and let's again rename our group here already have a count and the layout i'm going to change this to a center alignment and add a little bit of gap spacing let's say maybe 10 pixels between them maybe a little bit more 20 pixels between them uh so that they stay centered but you know can then move outward from there okay so now we can adjust our settings our space settings and um distribution and kind of get more consistent in our widths with our form here first thing i'm going to do is have the group itself the group form fit its height to the content so i want to remove the minimum height but now i want to create some padding on the inner uh like sides of this group so that everything inside can essentially stretch out but then be pushed in so we have some border that's created let me show you what i mean a little bit better here i'm going to actually remove from each of these groups the fit width to content setting okay remove that you see how it extends all the way to the width of the container i'm also going to get rid of the minimum same thing here for password remove fixed width same thing for the individual inputs remove all of these fixed width settings so that it all stretches out it's fully fully dynamic same thing for this group and i'll tell you why that i'm doing this and not just creating independent um like margin settings here we're basically going to help ourselves make it easier to create consistency so remove all of this okay all i'm doing is removing the fit with the content and removing any minimum width so everything is fully stretched out now this group i can come in and create some padding let's say we do 20 pixels of padding all the way around okay now i have like a border essentially that has been created there and and because everything was stretched out now we have much more consistent widths of everything at the group level i'm also going to finally add in my gap spacing maybe we do 20 pixels of gap spacing as well okay now it's starting to look a little bit better i'm also going to add a little bit of space between the input label and the input itself so at that container level okay we're going to add a gap spacing here maybe we do 10 pixels okay same thing here for the group password add 10 pixels okay so now we're getting much more spacing in uh in in this form overall one thing that i'm noticing is that both of these groups they're top aligned on the page you see that i have this extra space down here at the page now page heights are going to be dynamic because different devices are going to be different heights if you're on a mobile device it's going to be smaller if you're on a much larger monitor it could be a lot taller you have more space what i want to do is just ensure that this group is always centered on the page for the user when they load their page so this group left what i'm going to do is change the vertical alignment away from the top aligned and have it stretch which means it's going to expand to the full height of the page whatever that height is and again because this group left is an aligned to parent style which means that the form here is at the center is just gonna re-center itself this is fully stretched to the page and this is just going to stay centered we're going to do the same thing with the blue group on the right vertical stretch okay so i'm going to close that so you can see what this looks like now we are starting to have our our sign up form nice and organized um i promise the more you work with this the faster you'll go through building out these things i've obviously been talking through every every single step of the way but this is a kind of form that you can actually build quite quickly once you get the hang of all of the settings and all the adjustments that need to be made and also the shortcuts that you'll pick up for yourself for copying and pasting so you don't have to redo more than you really need all right so looks like we're looking pretty good here in terms of our um let me turn off the borders again in terms of our form that's this one here right nice and clean very evenly distributed even widths um the only thing that i'm missing here is my image so let me go ahead and add a new image element we're going to do this in the center non-end of my group let me go back to layout center right there and under the appearance setting i'm just going to paste in that url so you can do that with images that are hosted elsewhere or you can upload a new image or your images can even come from your database lots of different options for you okay so this image looks like it's pretty good um in terms of you know the aspect ratio and being displayed there i'm going to make a couple of adjustments though i'm going to have this aspect ratio fixed so that it's a perfect square and because of that now i can change the dimensions of that square if i make it bigger let's say 400 pixels right now the image is a lot bigger it's 400 by 400 if i go to 200 it's a lot smaller let's go back to maybe 300 yeah that feels okay all right so here we have it there's our design for the form on the left the image on the right using all the responsive settings so that everything is very neatly organized and consistent on the page let's go ahead and set up the workflow to complete the whole process and see our new user get created in the database so as a reminder going back to the data types under the user data type your email address field is built in you do not need to create another email field also you might notice that there's no password field that is intentional it's hidden from you you will not be able to see the passwords of your users bubble secures that so we actually don't need to add anything extra to our data structure but if i wanted to collect for example a name let's just go ahead and add that in here to our form so we're veering away from our original design but that's okay so let's do um up here at the top let's collect a name and this input is going to be just a regular text so that they can type in their name and i'm going to make sure to change the input name here so we can identify it so this is name input email and password okay so that way we have something to save to the built-in email field the hidden built-in password and also this custom field called name okay so let's start our workflow when this button is clicked okay i'm going to open up the property editor for this button and begin a workflow by clicking on this here start edit workflow when this button is clicked we're going to add some action right so in our workflow section we have our triggers our events in other words and our actions if this then that and the action can be one action it can be a series of actions and you have a number of different events that you can work with number of different triggers what we're working with is an element trigger when a specific element is clicked and i could have built this from scratch here by going to that event and then selecting my button you'll notice that all of my visual elements that i've designed on my page are now available to me that's kind of a long way around a lot of your visual elements will have this option here to begin a workflow when it is clicked okay so when my button is clicked i want to sign up my user so this is an account action lots of different account actions available to you you can change credentials you can reset passwords you can actually create accounts for other people so like an admin person can create a user account for somebody else you can sign up with social networks uh those will involve plugins if you're going to do that um yeah and logging your user in logging them out if we take a look through some of these other categories i mean the they're broken down into the most common pieces of functionality so navigation moving a user from one page to another or working with your database creating records updating records deleting them you can export your data sending emails right payments here the only reason we have actions here is because i have a stripe plug-in in installed into this application by default you're not going to see anything here but with the stripe plug-in we can trigger all sorts of stripe actions creating subscriptions making a payment all of that element actions are more of those visual things on the page so they don't really involve the database it's more like i want to show a pop-up or show an alert message um or reset my input so that they go back to being blank right a lot of things you can do there if you are installing plug-ins that extend functionality they may introduce more actions here it just depends on what you have installed in your app and then we have a couple of custom things that are a little bit more advanced so all we want to do with this sign up is sign the user up and you can see that bubble is asking me for some required information this stuff in red notice that i'm not doing any code i'm just filling out the action settings as as they're you know requiring me to the email is going to be whatever the user typed into that email input so this is uh your dynamic expression composer whenever you can insert dynamic data this is where you find information from your page whether they're coming from inputs or like a file uploader or something or from your database we'll touch on this a lot more throughout the next demonstrations but essentially what we're seeing here are the list of possible input sources data sources to insert here so that bubble knows to sign the user up with this email pretty straightforward in our case we just want to insert the value of the email input now here's an issue two of our inputs are called the exact same thing this is why we have to label our inputs properly so let's just double check i know i renamed this one input name this one is input email address this one is our password has not not been renamed so let's rename it to input password that way we can keep them apart we don't run into any issues in the workflow okay so here's our input email addresses value there's a couple of other properties here but we want to go to the value of that input whatever the user typed in same thing for the password okay if i had introduced another password field so they could retype their password just for confirmation make sure they're within a typo i could have bubble require that and i would provide that second password inputs value here um i can choose to send an email to the user in order for them to confirm bubble will automatically send an email the language of that email is actually managed in your settings and bubba will include a one-time use link for you so that when the user clicks on it bubble's going to mark them internally as confirmed that's kind of a built-in piece of functionality that you can take advantage of and then the remember the email is just so that when the user comes back to this page the input will uh fill in with their email address it's just kind of storing that information based off of cookies so this is just looking for a yes or no value we have provided a checkbox in the form and a checkbox uh essentially outputs a yes or no value right it's either checked or unchecked it's boolean it's true or false um so the way that we'll capture whatever the user chose is we'll reference that checkbox um that checkbox element you can see that we don't have the equivalent here of these inputs we don't have checkboxes value instead we have two different ways of looking at whether the check box is checked or not check box is checked we could do it that way or check box isn't checked what's really happening here is bubble is making a true or false statement this is either going to be true or false right so if we say okay the checkbox is checked that is either um uh true right if the user has checked the box then this is a true statement bubble will set this value to yes i want to remember the email if the user left the check box unchecked this is a false statement and so the expression will evaluate to a no value remember the email no right because they left it unchecked it's a little weird with check boxes to get their values in there but that's how you want to do it now we do want to update another field on the user record at the same time so i clicked on this here so that i can map the name input to the name field in the user record this is one of my custom fields that i created in my data structure the name is going to equal the value of the input names uh that that element there that element's value okay so from one button click bubble is going to create a user account for the record for the oh i said that very backwards bubble is going to create a record for the user and save their email password and their name and this checkbox setting all in one go so now that we've signed the user up that's going to happen behind the scenes the user record will be there but on the front end the user who's actually doing this nothing's going to change for them visually it's going to seem like it's broken actually remember you have to tell bubble absolutely everything you want to happen so let's do a couple things let's uh first reset the group so that it clears out all of the inputs there's actually two ways to do this we could reset the group the the form which will take all of the inputs back to their default state so they were all empty by default or i can say reset inputs which will only clear inputs that were involved in the workflow and we happen to have them all involved here so this will also clear them out so that's one kind of very subtle visual indicator to the user they click on the button and the in inputs will clear out back to empty another more helpful indicator is to actually show an alert message or a pop-up that says hey uh you know check your email we sent you a confirmation link or you are signed up welcome or maybe even navigating them away from this page and going directly to another page to a dashboard to a user settings page however you want that flow to go we're going to keep this simple i'm going to add an alert message um to the page we're just going to do it at the page level and i'll put the alert at the top so that it's just centered there and we can say you are now signed up like this the way that alerts work are that they are hidden by default and you have to show them in a workflow so this is not going to be present when we first load the page but in our workflow what we're going to do is go to this element action show alert message and bubble's going to automatically select that element because it's the only alert we have designed on the page if i had more than i would be able to choose and i can control the timing of this alert again it's hidden by default and when we show it in the workflow it will fade in hold and then fade out so i can control the timing here it's in milliseconds so right now by default it's set to fade in for half a second hold for two fade out half a second all right let's try it out i'm going to preview my page here and we're going to sign up a new user and check our database and make sure that it was created properly okay notice that when i clicked on preview um the debugger was added automatically essentially this is a way for you to troubleshoot um your your designs to troubleshoot your conditions this is a way for you to inspect your elements essentially so i can this toolbar down here is the debugger i can hit inspect select any one of my you know elements and it's going to give me all the properties for this element i can see what things are in real time very very helpful for troubleshooting what i'm going to do for now though is remove the debugger from the url which will turn off that little toolbar at the bottom the debugger also adds a little bit of extra white space and i just want to be able to preview this page without it so here's our design i think our image is a little bit smaller than our original actually let me toggle back and forth there's our original here's the new one it looks like i had the form a bit more narrow compared to the original but hopefully you were able to follow along with where those settings would have happened for increasing the width a little bit um or increasing the size of this image okay so let's say we sign up jane doe jane at sample.com and we're going to use a password and i'll say remember me and we'll click on sign up okay so it's triggering the workflow you see there's my alert message up at the top uh my form completely cleared out so it's a good visual indicator at two visual indicators to the user that it was successful in reality uh you know i wouldn't want the user to just kind of be stuck here if there's no confirmation if i was gonna require confirmation i would say go check your inbox so that they can go do that because the link will take them to a page of your definition once they have confirmed and then they can move on from there or i would automatically redirect them at the end of the workflow just run a go to page action and take them away so they're not stuck here you can ignore this this is just a chrome extension that i have installed that has nothing to do with what i designed here so a good practice whenever you're creating data for the first time after setting up a new workflow or modifying data is to check your database and confirm that everything got created as expected now again we're not going to be able to see the password um under app data here are my users so this was the newest user that i created there's the email there's the name and we know we have our user in the system which is fantastic okay so that same process you'll be able to go through with any other data type this is a simple workflow creating one record doing just a couple things after but you can absolutely build more comprehensive things um you know when it comes to user interaction in the application you can have a big sequence of actions you can trigger other workflows you can work with multiple records at a time in a single workflow modifying many things at once or having things dependent on previous actions and we'll get into some of that here with our next demonstrations last thing i just wanted to go through was some of the responsive settings remember i had placed um in my original a condition to have this entire right side hide once we're on a smaller screen so let's take a look at what how things are set up right now with the current settings in our responsive viewer so if i just drag this in to see what will happen things will start to squish like this is not something that i want to happen i want this blue group to go away um earlier than this i think right otherwise we end up with this kind of collapsing behavior or this overlapping behavior so let's add a condition to this group here okay i'm going to go to the conditional tab and i'm going to say when the current page width creating my conditional expression i can find the current pages width this is a built-in value that bubble makes available to us when this width is let's say less than uh maybe 700 pixels that would be a pretty large smartphone so if we're you know approaching a normal size smartphone we want this to go away so less than 700 pixels i'm gonna change the visibility property of the entire right group and make it not visible i'm going to leave this unchecked if we go to the layout tab you'll notice that by default every element you add to your design is going to be visible on page load so you can change that if you want that behavior to be the opposite maybe by default you want it to be hidden so you would uncheck this i am also going to collapse this group down when it is hidden so if we are less than 700 pixels i want to make this hidden which will mean that the height of the height of this group is going to fully collapse down this is a good practice because if i had other elements designed on the page i don't want to end up with a big gap just kind of hanging out there where this group would be collapsing things down basically means it fully disappears and things can shift around and take up that space again depends on your design you might not want that in certain situations but just be mindful of that setting as well so now if i go back to my responsive view and we you can see here that we're at uh let's see 899 pixels i'm just going to slowly move down until we approach 700 i might even need to do this before then but there we go now let's do it maybe before no i think that's fine but what we do want to do is center okay so if we're at this piece here which is kind of like a uh kind of close to a horizontal mobile or like a larger a larger vertical portrait mode what i want this uh group to do is center itself so if i can open up the settings from here as well um so let's see why this one is not centering let's go to the row all right okay so at the page level remember we set this in a row container alignment style and our container layout style and everything our row is uh left aligned so we have the white group and then right next to it is the the blue group but what i can do instead is have it center so when they're both there we don't really see a difference but when the blue group is gone this one is the only element in the row and it's going to remain centered on the page right if i change this to right aligned you can see the difference here so this setting helps me keep things nice and and centered on that page even with the blue group there when the blue group comes back it's back to normal like this okay so this 320 preset okay so we can see how things are getting really squished here and that's because this form has no minimum width we're allowing it to squish down very very tiny let's maybe give it a minimum of 300 pixels let's try that that looks a little bit better by the way 320 is on the smaller end for smartphones most smartphones these days are a bit bigger than this but if we know that things look good we can see everything nothing's getting cut off nothing's getting squished or overlapped then we're in a safe zone for viewing the these designs so if i start at 320 and kind of work my way back out you can see that it starts to expand because we haven't met the the max width settings right and i can really play around with that there's a lot of different variables that have to all work together as you can see to get really good looking responsive design hopefully as you see me work through these you can at least see where all of the components are i could probably fine-tune this even further to be even more specific with different break points okay now let's talk about bubble logic we saw a little bit of this happening with our sign up form but we're going to take a deeper dive into it particularly with dynamic expressions dynamic expressions and all of the possible uh data sources that are available to you are really what sets the bubble platform apart from other website builders this is how you can create really customized interactive applications okay your data is custom organized within your database your front-end designs are custom configured and it is up to you to manipulate the data that you're collecting from your users to put together the logic that you need for a custom experience and present everything to the user in an easy to consume way in a way that's actually useful for them because they've come to your app for a reason right you might be solving a big problem you might be making their lives easier in some way uh and so this is kind of the heart of everything is the logic that you create through these dynamic expressions of course within the context of everything else within the designs right the layouts within the database architecture and just the workflows dynamic expressions are really the building blocks of those workflows of your conditions to make things actually happen and to make things appear in the way that you want um on the front end so let's take a quick look at what i mean when i say dynamic expression and what i mean when i say data sources okay so let's have a very simple example here i'm going to add a text to my page and immediately we see this little blue flag insert dynamic data now i could just type in a static text i could say hello world right it's me and it will display exactly that there is nothing dynamic about this it is a fixed static piece of text or i could have dynamic data which is information that can come from some source now that source could be the database it could be an input that's on the page it could be a plug-in it could be another integration that you have with an api a few different sources available to you when you open up this expression composer right so that blue flag came up i clicked on it bubble gave me this window it's going to present me with my possible options now it doesn't mean that every single choice can get me something that i want it just means that i could potentially use that as a jumping point because sometimes your expressions are going to be kind of a chain of things coming together to get the right result for example if i wanted to sum up an order total i might look at the orders related line items subtotals and then add them all up right so i'm going through like two different tables and performing a math calculation on a list of numbers from there we'll we will see that uh in one of our demos around the shopping cart but this is the starting point here is the list of data sources available to you so an easy example is stuff that bubble provides just automatically for you so for example the current date and time this is a dynamic expression the date and time is always changing right so if i were to preview this page in this moment when i load the page bubble's going to show me the current date and time and if i reloaded the page after two minutes that time is going to change right right now it's 3 4 in the afternoon if i refresh the page after 2 minutes it's going to say 346. this is dynamic right i do not have to anticipate a date and time further uh from your dynamic expressions you may have the ability to manipulate them so with a date specifically right i can click on this and you see there's a little text there that says more i'll click on that now i can manipulate my date i can extract different date components right i can just pull out the date of the month or just pull out the minute that i'm currently in or i can add time to this date and time maybe i want to set up a workflow where i'm defining an expiration on something so when i want to save some some records expert let's say it's a listing right in an auction type of website like ebay and i and the user publishes their listing and the application wants to save an expiration date of 30 days from now so we'll take the current date and time and add 30 days right i'll just type in 30. so now this is a changed value i'm going to refresh the page again so today is august 9th so it's going to add 30 days and bubble is is doing calendar aware math here right we're not going to get a funky date um it knows that august has a certain number of days in the month before it needs to move into september so 30 days from now is september 8th so at the top we have the most popular things current user is simply a shortcut to the user record of the person who is logged in um there's another way to get to that record but this is you know you're often referring to the current user if the user is logged in if they're logged out if their uh type if their user type is defined as an admin versus a customer or something you can create a lot of conditions around who the current user is um and so the value of this is a user um now bubble is flagging this it's in red this is not a good expression because i'm in a text element and this expression does not evaluate to a text i have simply pointed to a user record not a text the record holds text values such as the user's name right like this now this is a good expression because it's compatible with my text element you're going to find that's a very important thing to be aware of when you're creating your expressions is compatibility of the value that you're trying to get to and the the the vehicle that you're you're putting it in so if it's a text element like this or if it's in a condition or if it's in a workflow action you need to make sure that things match that the format of the value matches the thing that you're putting it in also the if it's a single value versus a list of values that will also create some type compatibility issues if you don't have those right um we'll see other examples of those as well so here i can display the current user's name i believe i'm currently logged in as the user we signed up as because bubble will automatically log you in so i should see yep there's my name jane doe i signed up as that person in our previous example um and so that's who we're seeing there another popular common data source and one that you're actually going to use quite a lot is this one right here do a search for this is how you search your database you first have to define the data type the table that you want to search and then you can get specific from there you can create constraints to find the exact thing that you want from there so let's say i want to search through all of my users and again this is not a compatible expression because the result of this search is a list of users i don't have anything that's actually text that can be printed as a text i could go to the users you see all these different manipulations here i could go to the user's names each item's name so what i'm going to get here is every single user's names just comma separated okay so we refresh the page here actually don't know if my users have no i think they do i think they do in the database there we go yeah those are my users names in my database this was the last one that was added okay um i could also just count up how many users i have and i can mix and match my expressions in most places not everywhere but in most places i can mix a match dynamic with static so i can say give me the count of all of the users in my database and just say you know 10 users or six users i'm not really sure how many i have in there let's refresh the page and we'll see this come together right so i'm creating a a more helpful display of this information sorry it's in the upper left corner i should probably put some spacing around there but we see seven users right this is a mix of dynamic information with some static information okay so i just wanted to introduce you to the concept of data sources so data comes from a shortcut to the current user comes from a general search of your database comes from um you know information that bubble just kind of has standing by at all times um and being able to manipulate those things i'm gonna show you one more another one that's also common that we'll look at a bit more as well if i have an input here okay and i can say maybe this inputs placeholder says type in your name okay and this text is going to say another mix hello comma and then we'll do the inputs value whatever i typed in there hello comma and then the inputs value okay so right now it doesn't say anything i'm gonna do uh hello gabby okay so there's my name it's just pulling directly for this is not coming from the database it's just kind of a real time um reference to something that's happening on the page in that moment let's take a look at our next demo the expense and budget tracking uh feature this is not one that i'm gonna build from scratch because there's a little bit more that's involved there would take a bit longer to to get through everything but i am going to walk you through the whole configuration so that you can pick up on those patterns in terms of layouts and responsive settings but i am going to focus a bit more on the dynamic expressions being used here so that we can create a more interactive experience with the user okay so here's the feature we're on a new demo page here and i am viewing this from a desktop perspective but it has been designed for mobile this is a uh a page that has actually two pieces of functionality first the user can keep track of their budget across different categories so let's say my food budget is 300 um and it's going to calculate how much i've already spent on food this month and the progress bar is going to dynamically show me where i'm at with my budget it's also going to calculate how much under or over i'm at with with that particular budget so i know that i've spent 37.88 let's say my budget was 50 then i'm a lot closer to it i'm a lot closer to meeting that limit or if i go down to 40. right now i've created a condition to change the color of the progress bar to really alert the user hey you are dangerously close to your budget so we can do this per category if i change this to 300 right i've given myself a bigger budget so i'm not so close to the limit there supplies let's change this to 500 even more so this is all interactive keep in mind when i change these numbers um i am actually affecting the database it happens very fast it's just kind of in the background every time i change the input it's modifying a record a budget record that is tied to the user and tied to this category i'll show you the structure in a moment here so if you keep if you keep in mind these numbers 40 300 500 i'm going to refresh the page and what should happen is it should remember those numbers because i have it set up to automatically populate them when i first load the page 40 300 500 there we go okay so that's one piece of functionality that's on this page now i've got a little handy menu here to switch over to a different piece of functionality note that we're on the same page how i've how i did that was actually toggled between two different groups that both live on the page but only one is visible at a time so here are my expenses so here i have a list of all of the expenses i've created now this is leveraging an element that we haven't talked about yet called the repeating group super helpful very powerful for working with dynamic lists right i did not sit here and go through and design how many do we have here five different rows of items so that they all look the same and populate with item one item two item three etc i used a repeating group bubble only asked me to design one cell and it could replicate that design for me and i structured it so that it's in a vertical kind of like a table format you can use repeating groups to show more of a grid you can have multiple columns they can be scrolling but the important thing is that the repeating group is connected to a data source some list of items so that each cell's information can be dynamic they're each different now these records are coming from the database right i told the repeating group to go look at all of my expenses tied to the user who's logged in right i don't want to look at other people's expenses and populate with this information the other thing the user can do here is well you can see this aggregation we're summing all of the expenses i can filter it by category so filter by food it filters it down only shows me the food items travel supplies i can you know undo it so that i see everything again and i can have the user add a new expense in the same place so i clicked on that button take a look at this the whole list went away that was intentional i want their attention to be here also for mobile design it would have gotten kind of clunky to have both things there at the same time but a lot of scrolling up and down um so i just have the form if i change my mind i don't want to add an expense i can hit discard it takes me back here or let's go ahead and fill one out just as an example let's say august 31st 50 let's say travel um gas whoops gas and snacks like this and i also have a file uploader to upload you know a picture of my receipt for example i'll skip that for now ad expense and you can see there it is travel gas and snacks my description for that particular date and for that amount and so it added to my total if i go over to my budget you know my you saw right there the progress bar moved just a little bit because i added to my travel total and so now i'm a little bit closer 50 closer to my travel budget okay so let's dig into how this was put together i really want to take you through all of the dynamic expressions especially but we'll also take a look at the structure here so on this page this is my editor um you'll notice that first thing the width of the page is set to a mobile preset because i designed this to prioritize usage on mobile devices um remember on the sign up demo i had it sent set to a full width so i had a bit more width there but here i'm going to keep things more narrow now if we look at the elements tree i can see the hierarchy of all of my elements um so first we have my header group okay you'll notice that this is an align to parent style so that this text is in the center and my little menu icon here is over to the right by the way this menu icon is actually coming from a really handy plugin that bubble has called slide bar menu for very basic menus you can of course create more comprehensive menus with like sub menu items and different colorings and things like that but this gave me what i needed to toggle between my two sections so this was my header right there and you can see inside those are my two elements okay notice how i'm labeling everything as i went there's my image just as a kind of a you know main image to always have at the top there so that the user knows where they are and i have two separate groups group budget and expenses now you'll notice that group budget is visible by default here in my editor because that's how i've designed it whoops let me click on here in the settings by default when the page is loaded it is going to be visible but it is going to collapse when hidden versus group expenses okay is going to be hidden by default also collapsed when hidden okay so we only see the budget group first now notice they're both in the same page and the page is set to a column structure so they technically stack on top of each other but when this group is hidden the the expenses group again i have it set to collapse when hidden so when it is hidden the height goes away and everything below it shifts up and that's how we're able to see everything basically in the same position on the page right when i go over to budget this stuff isn't pushed down i don't have a bunch of extra white space here that expense group is completely collapsed down so this section can shift up into that space this repeating group is how we can see all of our expenses in a list actually what i'll do is i'm going to back up one step let me walk you through the workflow for creating a new expense record because that will help explain our list of expenses in this repeating group so when this button is clicked let's go over here you can see i'm actually this button is serving a dual purpose if the form is not visible it's first going to show the form if it is visible then it's going to go through and create a new expense record in my database and then it will reset the inputs and it will hide the form so this is similar to how we did the sign up we just capture the information from all of those inputs map them to the right fields in our expense data type so it was our responsibility to create the expense data type properly for those pieces of information these fields here with the number the date the text a relationship to an option set right i have an option set of expense types food supplies travel so that every individual expense has a value for these things here and i can check my data in a more raw format by going to app data expenses and i can see those records there as well but presenting it to the user i might want to do it in a more designed way right so that's exactly what we have here with the repeating group okay so let me close this again go to our repeating group okay so a repeating group again is specifically for a dynamic list we first need to tell bubble that this is a list of expenses we need to define the type and then tell bubble which expenses we want to see we may not want to see every single expense in the data source or in the database so here i've done a search for remember it was the do a search for and i chose the expense data type so i'm searching through that table specifically and i have a filter i have a constraint on this search i only want to see expenses that match the type that was selected by this drop down so that's how i was able to in real time choose a different type in the drop down and it affected the data source in real time without this constraint the search is going to return all expenses with this constraint it will have a filter so that it searches it returns expenses based on that type there now i do have an additional setting here for bubble to ignore the constraint if i've left the drop down empty so that i can see everything by default if i don't want to specify a type one thing that i would add here in a real world scenario is another constraint on the owner of the expense for example the creator so i might want to show expenses created by the current user and only by the current user this way i'm not seeing other people's expenses you know if you have multiple people signing up to the application they're creating their own expenses we don't want to see other people's stuff so creating this type of condition ensures that it filters it only to the user's own expenses you can also protect this kind of data even more with privacy rules so you can create a rule that says hey if the expense creator is not the current user they should never have access to that data but it's a good practice good habit to create constraints like this even within your visual elements okay i'm going to remove it right now because i am not logged in as the creator and i just want to be able to see to see the data here now the repeating group is again a way for you to generate a list automatically from one cell's design so you can see that there's a repetition it's faded from this design here i only needed to set up this one cell so if i open up my repeating group we can see how it was put together we have a group inside of it and then inside of that group more groups here this is where i was custom mixing and matching my layout styles so you'll notice that there is a row right there's uh the let's see this is the date the description and then the amount all in a horizontal row but within those individual components we have a column to display the uh let's see this is the date month and i've got it converted to uppercase you can see this manipulation here that i'm doing on a date and then below i'm displaying the date uh the actual date again uppercase okay so those are in a column within a container that's a part of a larger row so that's why all of these different groups are here you're going to see this you know a number of times throughout these demonstrations how much i'm leveraging groups how much i'm taking advantage of containers because containers can have different layout styles you can add global margins or padding to create more uniform spacing of things yes in theory you could also add a lot of margins and padding you know around individual elements too but you're likely creating more work for yourself start on the outside work your way in okay also this particular group date you can see there's a faint blue border because i was able to custom style the borders look how specific we're getting with these designs i can define every border independently top right left and bottom and i said i only want a right border i want it to be one pixel and i want it to be this color and it's a solid line not a dotted or dashed line just that i could create some separation there okay and i made this bold right so this is ultimately what we end up getting we refresh the page again to remind you of the design okay right so that's how that all turns out now the group the group that's inside of the cell you can see that its data source is the current cell's expense this concept of passing data from one source to another is also very important in bubble all of these elements inside need to carry that cell's data so that one expense so if we return 10 items we're going to have 10 rows that are generated for us first row is the first expense second row is the second expense it represents those results and i want to carry that information into these inner groups because ultimately i need to display something like this in a text the parent group expense so it's referring to the record expense type that's the option set field that the record is tied to and then the display this is the option set choice okay the name of the choice technically option sets can have additional attributes we have not done that that's more advanced you don't always need those um but we do need to tell bubble hey this is an option set choice and we just want to go to the the name of that choice i must do a slightly easier one here the parent groups expense this is the record and then we go to the amount that's a numerical field and here we're formatting that number as a currency because we know that this is an actual price that has been paid it's not uh just a straight decimal or you know a whole number we we want to show it as money that has been paid okay so in order for this text to display properly the sells expense information it needs to have access to the data source from the repeating group and we have so many nested layers in here we don't want to cut off that access to the cell's data source so the first group is also going to hold basically a shortcut to the expense okay so the group is also type expense the data source is coming from the cell the groups inside of that are also going to be the same thing type expense their data source is their parent group so the parent group of this is this one here the parent group of this is the cell right the parent group of the repeating group is group expenses right you just work up the chain okay and if that data is flowing through all the way then we will be able to display all of our information properly i'm going to show you one thing what if i cut off our data source at this group level here let's just collapse this down this group level which contains everything else inside if i remove that data source first of all bubble's not even going to yell at me about it there's no issue that's been generated this is something that you need to just learn and understand that if you're going to pass if you're going to display things inside of a group you need to check your data sources because not all groups have to have a data source some groups can literally just be containers to keep things together but if i cut off the data source i removed it does not matter if the groups inside have this set up it does not matter because their parent group which is this one here does not have a data source it's missing so if i refresh this page we're going to end up with an empty list the cells will be generated but none of the content will actually display so let's switch back over to expenses here look they're gone we've lost the data source this would be a great use case for the debugger to help troubleshoot what's going on here i would have been able to identify that one of my groups was missing a data source because i would have been i would have seen that it was empty i could have gone to each of the individual texts and seen hey there's no value there but i know that this is set up to show the expenses amount i know that the group of the amount has a data source what about the parent of that group i go here okay there's my missing piece this stuff you have to learn it's just gonna you know the more time you put into it the more second nature it will be to just be mindful of all these things so data source is the current sales expense okay let's talk about some calculations uh this total that we have here so this is a real time calculation i'm actually going to build this from scratch here so you can see i just want to add up all of the expense amounts that we're seeing in the list here so i'm going to refer to the repeating group again technically i could do a search i could do a straight search of the database directly based on the filter the type on the user who created the expenses but i don't need to do that bubble's already done the search for me bubble has already sent the data to the browser so for performance reasons i want to consolidate my references a little bit this repeating group has already done the search so i'm actually going to piggyback off of the repeating group repeating group expenses okay it has a list of expenses there's my data source and i'm going to go to each of those expenses amounts okay now i have a list of numbers and bubble will even keep track of where i'm at if i hover over this tells me this is evaluating to a list of numbers and then i'm going to sum that list of numbers what can i do with a list of numbers well these are my options right the list of choices you have here just changes based on what what your last value was um in your expression so i'm going to sum this so now i'm going to have my sum but i want to make sure i present it as a currency so i'm going to click more one more time and format this as a currency let's do two decimal places and a thousands separator with the dollar symbol okay and we end up i just recreated what was already there but we end up with this here okay now let's switch over to the budget group so we can see how we did those fancy little progress bars okay so here we do have another repeating group let's open this up over here this repeating group budget now this is searching through a different table let's go over to the database and just take a look at that table so here are my expenses right the budget data type is a different table with these three um records for a specific user so one user might have a three hundred dollar travel budget another user might have a fifty dollar travel budget which is why we created this in a separate table right because these amounts per expense type are unique to a user so when i'm looking at the budgets for a user i want to show all of the budgets and here i would add a constraint where the creator of that budget created by equals equals the current user i did create these manually in the back end so this isn't going to actually show anything if i were to preview it here but this is how i would structure this so that i'm not seeing other people's budgets okay so i only have three records in the database right now so this will return what i want this search will return those budgets and inside of my repeating group design again i'm only designing one cell bubble will replicate that for me there's lots of settings around the repeating group to set up the size of the cell how many rows how many columns because it's a list you can create actual tables grids scrolling functionality within them i have a group here again to customize my formatting and design i can give it a background color and create some roundness around there i can create more spacing you see have some margins there 10 pixels in the top and the bottom and this is also passing through the budget's source into the rest of the group right it's pulling from the cell now the group is carrying through that data source and we have this group at the top which is set to a row layout you can see the alignment space between so i have this item inside to the very left edge this input over to the right to the very right edge and then the group down below which is also made up of another group right i'm mixing and matching layout styles to get things positioned exactly where i want it by leveraging multiple containers okay so this input the user can type in their own budget by default it's going to display what is currently their budget from the database and so we did that with an initial content the parent groups budgets amount parent groups budgets amount that's the records amount value that number field parent group of this input is this group parent group of that group is this group right and this group is pulling from the cell so we can display by default aka the initial content what they currently have as soon as you load the page that's what we'll show there but it's an input it's something they can interact with and so they can change the number and what we have attached to this input is a workflow to update the record and change the amount field to whatever they've typed into the input so if i go to my workflows and go into this event here right when the inputs value is changed it's going to make a change to the budget record so that came from this action here make a change to a thing i'm not creating a new thing not deleting i'm not signing up a user i'm making a change to something and so bubble's going to ask me what thing do you want to change what record do you want to change it has to say thing because it doesn't know what i'm what what my data types are um and i want to change my budget and so here are my options from my data source you see that now i have a more limited list here because there's also there's only so many sources that will allow me to get to a record to change but it's going to show the most relevant things at the top so this input excuse me if you heard a sound there i just knocked my microphone uh this this input is sitting inside of a group that has a data source and so it's going to give me that as an option i want to change that record and the thing about this that i'm going to change is the amount field and i'm going to change it to this inputs value it says this input right this input because i've triggered this entire workflow from that input so it gives me that little shortcut which is nice notice that i don't have to define other fields here the only thing i care to change is the amount everything else will stay put as is the category will be the same the creator will be the same nothing else changes okay um i don't even need another kind of indicator here i really want this more to be like a in real time bubble changes or the user types in a change and it automatically it's like an auto save type of functionality there is technically an official auto save it's called auto binding that bubble has we're not going to touch on that one today but what we've created here is essentially that type of experience and so because so there's a ripple effect that happens here the moment i change my my budget amount it updates the database this progress bar is dependent on the value in the database so if it updates the database it updates the progress bar it's also going to update my other calculation that i have over here in this text to tell me this is actually happening in conditions whether i'm over or under so you see we're getting a lot fancier now right a lot of the stuff that we've been talking about is now coming together in a lot of different ways here throughout these conditions so let's look at the progress bar um this is another plug-in that bubble has very easy to use you just provide a percentage number so you could do something that's fixed you could type in a number or you can have a calculation that happens in real time so what i've done here is i searched for expenses for the expense type that is this cell remember this is a list of budgets so every budget is per type so i'm trying to calculate where i'm at in my progress for this type so i'm going to search for all of my expenses first i need to see where i'm at for my expenses for this type only so the expense type has to equal the budget's expense type i'm going to take the sum of those expense amounts so let's say for supplies i have spent 100 so there's my sum now i'm going to divide it by my budget i'm just doing math now right for this particular feature um if i have a number i can do different math operations okay i can do all my standard operations i can find um i can do rounding i can find the minimum of a list i can find the maximum average all of that um so i'm going to take my amount that i've spent divided by the actual budget for this cell and because this uh progress bar needs the percentage in a whole number i'm just going to multiply it by 100 otherwise i would get a decimal this text below is calculating just the sum of the expenses it was actually just part of what i did in the progress bar search for expenses based on the type summing the amount and then formatting it in a in a format that makes sense for the user to see it as a currency and then i just combined it with some text here this text is conditional so by default it will say at budget but if we calculate that we are below budget or over budget then it's going to um change the color and uh also change the text so here we're doing the same math as the progress bar but now comparing it to another number so if my percentage is less than 100 right less than 100 but like if i'm if i'm less than my budget then i'm under it so i do the calculation again and just say under if i am over 100 100 then i've exceeded my budget we're going to change the font color here of the text and also display a different text the progress bar itself also has a condition to say once we reach 80 percent or greater we're going to change the color so it's kind of like a visual warning for the user once this calculation is at 80 or above we let the user know hey you're getting dangerously close to that budget this is something that you know we see a lot in financial based applications but also dashboards analytic type of uh features aggregating on data that is being generated by your users whether it's for an admin or for the users themselves just taking the data that's already there right it's the raw data that is already here for budget and for expenses notice that we have not saved totals to the database we technically don't need to we could in some cases you might want to have pre-calculated values especially if you have more complex expressions um but you know we're trying to leverage a good balance between what do we actually need to have in the database and what can bubble just do in real time on the page for us what can the user provide us that we don't know um that we can leave up to them and they can see you know represented in a certain way right the progress bar that is that's a design choice we could have shown this with a chart we could have shown this with just the text and the color coding but part of the way that you you know put your features together has to be to serve the user's experience and actually make things useful for them and so the way that you design some of your data structures some of your layouts you know they need to help each other so that you can get the right experience like this this is super obvious to me oops i'm like very close i don't even need to see the numbers i'm very close to my food budget i should cut back all right the next demonstration we're going to jump into is user to user messaging this is a super popular type of functionality that can happen many ways in all sorts of applications social networks project management internal you know team updates and things like that our example is going to be from the perspective of a chat support agent communicating with customers so this is a one-to-one communication but just know that you can absolutely create group chats um forums right where multiple people are creating a post and other people can comment on them create sort of a thread situation or you can evolve this into more of like an inbox situation so lots of different ways to do messaging in general again it all comes down to how you structure your database and of course how you present the ui to your users i am currently logged in as an admin user who is going to be communicating with all of these customers that we have on the left by the way if you go to your user table here under app data bubble has a really helpful function for running as that user this is an admin function only system admin right you as the uh owner of the application also any collaborators that you might add to your editor uh may have this functionality as well to run as a user in the system what that does bubble logs you in as that person you experience the app as them i'm really helpful for troubleshooting and testing things out so i'm currently running as this user here and i cur i have five conversations going we can see that each of them have a different status um the one that's waiting is going to just keep track of how long they've been waiting uh these individuals the date there the time stamp is just the last message that was sent i can also filter my conversations if things get crazy um to keep myself on top of everybody right maybe i want to filter by all the people that are waiting all the people that are active so i can filter out anybody that's been closed or i can just see everyone all together here so we have a very clear left side and right side for this design i can select a specific conversation you see how the the list of messages actually scroll down to the end for me which is really convenient um if i go to a let's see let's go to actually back to the waiting one you'll notice that they haven't we haven't started the conversation yet and so i have kind of an empty state design um so i don't have anything blank in there it doesn't look broken but this is basically telling me we don't have any messages to show it's a nice little design to keep it with the theme of the rest of the page here if i go into an active message just to show you what you know different options i have here or how this has been put together so every side just like a standard kind of popular chat is going to represent a different user so on the right side we always have the chat agent on the left side the customer and we have it the the message itself um and a timestamp of when that message was created um i want you to pay attention to some of the styling choices here the width of these chat bubbles fit to the content and they only go so far right they don't go all the way to the end right this is going into two lines it technically could have extended all the way to the end where this picture is but it's getting cut off so that it can maintain be more visually clear to the user that there's a left side and a right side and not too much overlap to create any confusion okay so that there's one thing that we have some max widths being set here the other thing is that the roundness of this chat bubble is round on three corners only this fourth corner is a hard corner for the left side whereas the upper right corner is a hard corner for the right side and that's just to create a very subtle detail to make it look more like a chat bubble right where it kind of comes into a point into the direction of the person speaking and that was just done with manipulating individual borders and individual roundness from there notice that the timestamp is on the left side for the chat agent whereas the timestamp is on the right side for the customer and we also have them i mean as you can see for the customer it goes from left to right everything reads in that direction the bubble expands in that direction whereas the bubble expands from right to left on the other direction the support agent can also change the status of the conversation so let's say they change this one to closed okay so we'll see this status changes there that's just updating a field in the conversation thread record which we'll look at in a moment i'll change this back to active um and if i go over to this conversation we also have a really popular type of feature which is including attachments with the message so there's a conditional group here to display a link to open up a file if that message has a file with it otherwise that that group that would contain that link is collapsed in all other instances of our messages here um i'm gonna type in a message as the chat agent uh let's say uh thank you for sending that over um i'm just testing another message okay and send right there's my next message there's the latest timestamp it's just the following message for this chat person um if i wanted to attach something i have this little paper clip here it's gonna show me a nice little pop-up with uh either an option to discard which will just close the pop-up or i can choose to attach a file let's see if i can pull one up okay so i've selected a file and it's going to attach here this is just a csv with some sample data and you'll notice that it's actually displaying it down there now if i hit discard it will clear this and just again close the pop-up and return me to empty but i'm going to go ahead and attach it which means it's just going to close the pop-up and keep this here this is displaying again conditionally based on that file uploader in the pop-up having a value if we know we've uploaded something there it's going to display it here and then i can say here is another file for you too now i can't actually remember if we designed this piece here on the right side so it's possible it might not show up let's do a quick send oh no there it is that's good um and so here i can click on this and because this is a csv it's just going to download it to my computer this one is an image and so the browser should be able to handle that and actually display that image there that's our logo right there okay so let's jump into the editor so we can see all the different components to make this happen both in the workflows but also in the layout decisions here so again we want to start from the outside and work our way in at the page level we're going to go to the layout this is a column and we have some 20 pixel row gap between the column elements which are our header and a kind of a master group called group conversations okay so it's really between this group up here and a group down here which is made up of the left and right side so the list of threads on the left and then the messages on the right so the group conversations is set up as a row so again going back to our first demonstration with the signup form we did the same thing right we have the threads on the left messages on the right they are centered with some 10 pixel spacing in between them that little sliver of vertical space between the two here that's that gap spacing right there if i change this to 40 pixels just to exaggerate it you see it opens that up a bit more i'll undo that for now so on the group thread side we have this set up as a column and notice that this one has 15 pixels of padding on the top and the bottom 10 pixels of padding on the left and the right so we have a bit of a border um you know around all of these inner elements we don't necessarily want all these things touching the the um full edges otherwise it would feel too tight like not a lot of breathing room there this group threads as you can see is made up of some other containers we have the group at the top with the count the total number of our conversations so it's just going off of the repeating group of threads and counting them and then just displaying the word conversations over here we have a drop down so that the user can filter the threads by the status so the drop down is an is an input type of element that can pull its choices dynamically from your database or from your option sets so here it's pulling from our support status option set that is the type of choice the source we just want all support statuses so if we go into the option set tab here and go to support status i want to show all of these in theory you could have the drop down only show some of these if you wanted you could filter out certain choices but it's a dynamic drop down it's pulling from our option set and that way the user can choose um let's take a quick look at the data structure before we go into the rest of the elements for the data types that are involved here so we're looking at these two with the icons by the way and i don't think i've mentioned this yet the icons in front of each of these data type names i added manually just so that i could organize my data types feature by feature bubble will automatically sort these alphabetically but i sometimes like to put icons in front of data types that are actually related to each other for functionality it might not make sense for all applications but it does make it easy for me to find you know these two were unique to the budget and expense tracker these two data types are relevant to the messaging example we're looking at now and then we've got four data types actually that all work together for our next demonstration uh working with a shopping cart so the thread is the parent record to organize a list of messages together right so a thread is going to be with a specific customer this is a relationship to a user the support status is going to be from the option set okay and then a separate table of records is going to be for each individual message each message is tied to a parent thread we have the content of the message itself and the message may or may not have an attachment so not all messages will have a value in this field that's okay but they are going to have some content so if we go over to the app data to see kind of the raw format of our messages here they all are there's all the content you can see two of them have attachments this is the one that i just created and they have all a parent thread now let's take a moment here to talk about this relationship field notice that the value that we see here is a unique id okay if we go over to the threads table i can see this was with who was this with nine okay so that's this record here this is the thread that is active that um i am currently working with that the last message that i had had sent if i open up this record i can see the unique id of this thread it ends in let's see 202 900. okay if i go back to the messages so this was the message that i added to this thread you can see here two zero two nine hundred this field is simply relating to that entire thread record not the thread status not the thread creation date not the thread customer it's the whole object the entire record and from this particular view it is represented by the unique id let's go back to looking at the structure of these elements here so this is a repeating group of threads we're searching for threads we have a potential filter here if i have something selected then it's going to filter by the support status and right now the threads are sorted by their modified date so you can add some sorting functionality here inside of this repeating group we have some more containers so that we can set up our layouts properly right so this one is the main group that contains everything that way we can create some roundness some spacing um that is set up as a row inside of the row we have the left side of the row to show the picture the name the uh time stamp there on the right side of the row i think that is going to be this one it is the text is the only thing on the right side of the row to display the status the status text okay over here parent groups threads support statuses display this is going to have a bunch of conditions to change the color of the font okay so it's not three separate texts you could do that it would kind of be the long way around it's not three separate texts that show conditionally and others hide we're just changing the appearance based on the the data tied to the thread so if the status is active you can see here i can choose for my option set choices this is another example of why option sets are great to leverage if you can bubble kind of bakes in those values into your editor you you will never see something like this coming from your database records you won't ever see like email addresses filled in here from your users this is only an option set thing uh so anyway if the status is active or the status is waiting right we change those colors there on the right side we have more conditional things let's close this down open this one up uh let's open up the repeating group of messages now here's how we achieve this left and right side functionality we have two groups one of them is designed for the left side one of them for the right now they are conditionally visible based on who sent the message so this is a repeating group the outer element is a list of all messages tied to the thread okay so i'll go over the passing of data in a moment basically you click on a thread here it's going to pass that data over to the right side so the right side's data source is very dynamic it changes every time you select one it updates the data source of the group and so therefore we see different messages automatically populating here so we have a repeating group of the messages for this thread and two groups inside of that repeating group now we don't want to show both groups at the same time we only want to show one so these groups are hidden by default both of them are actually this one's hidden by default collapse when hidden and i've named it message from the customer this one here message from the agent also hidden collapsed when hidden and the condition will dictate when it becomes visible if the messages creators user type right the creator is a user if the creator's user type is admin this is another option set if they're an admin then we show this group versus in our other group if they're a customer then we show this group if i go back to my user table here we should be able to see there's only one admin and i'm running as that person right now and everybody else is a customer so any messages that these people create will always show on the left side so again this page has been designed from the perspective of the support agent it's like their portal seeing all the messages from their customers the cust the customer facing could probably be designed differently because they're not looking at multiple threads they're just looking at their one chat with their with the agent but those conditions will dictate which group is visible now these groups are designed very similarly but with opposing alignment settings so the row up at the top here for the customer message is going to be left aligned whereas the group down here is going to be right aligned everything is right aligned the group itself here i'm going to go to the appearance property here's where we independently defined all of the borders the roundness is 10 round on only three of the borders we left it with no roundness it's a sharp corner on one on the top left there and then the opposite on this group down here right so this one is the sharp corner everything else has roundness change the colors of the background um these groups themselves they are also row styles so that there could be a little bit of spacing you see a 10 pixel column gap between the message itself and then the picture inside of the little chat bubble that's set up as a column right so we have the content in a slightly larger font and then the creation date in a smaller font you see that the creation date here is left aligned where the creation date over here is right aligned that way they show kind of in the corner of the message okay so we're just passing that content through the data through to these messages so that we can see all of that information um let's go through the workflow for that particular thing so this this group here is gonna trigger a workflow to pass data from this cell over to this group on the right which we called group messages okay so i can get to this workflow very quickly by going to this little inspector tool here this shows me a few other pieces of information shows me basically what involves the group and i can see that there's an event attached to this group whenever this group is clicked okay so if i click on that bubble is going to take me straight to the workflow which is very handy especially if you have a lot of workflows on your page so when this is clicked i'm going to run a display data action this is passing data from the cell to the right side group that right side groups data source is going to change this that's what this action does is it changes data sources so we're going to change the data source of group messages that's the right side group to whatever the current cell's thread is whatever thread i clicked on to see i want to add a little pause this was just a design choice but i added a quarter second pause before it does a scroll to the last message in the repeating group because by default bubble's actually going to show me the top of the list top of the repeating group and so i want it to scroll automatically to the last item and so we'll go all the way to the end and i have it animating the scroll these are all actions that came from you know the preset list of actions display data is a is a an element action because we are changing the data source of a group that's right there the pause is a navigation action right there adding a pause uh and then the scroll to entry i believe that's an element action which should be right here under the repeating group you know functionality here scroll to specific entry so when that data source is changed let's jump over to that group here's a little shortcut you can right click on these things and do a few different actions i'm going to reveal the element and bubble will take me right to that group it's going to highlight it so that i can see it and here i can see by default the data source of this group is just going to be the first thread in our list of threads on the left that way when i first load the page i always see at least something to start out but this data source gets overridden in the workflow whenever i click on a new thread it'll change okay and then everything inside from there is just going to pull from that group's data source right this group is is looking at the parent groups thread let's take a look at the functionality around the input here so this is another group it looks like one big input but it's actually a group with a background color there's an input inside of it that has no border so it kind of like fits into the group seamlessly so here's our input enough space to type in a good message just set up as a text we have a link icon a little pay-per-click icon and a send button okay so the paperclip icon is just going to show the pop-up that we've designed here i think this is probably the first pop-up that we've had so far pop-ups just live kind of on top of everything else in your design um and they're always hidden by default you have to show them in the workflow so when the paper clip is clicked it's going to show this pop-up and it's also going to pass the thread to the pop-up as well you see the pop-up is another container um and it can also hold a data source so by default there's no data source because we know it's going to be changed in the workflow and the only way the pop-up is going to show is if we're coming from a message or from a thread i should say so clicking on this paper clip here shows the pop-up and displays the data to that pop-up so so that when we are ready to attach we know which thread we're going to attach it to i say that and now i'm remembering that i don't think there is i don't think that workflow is working that way anymore i think it used to but now it's no longer let's just take a quick look attach um yeah i don't think we even need a data source we don't we don't need a data source in the pop-up so that because the pop-up's actually not referencing the thread in any way it's really just holding the file uploader okay so the file uploader is a type of input element that you can grab from your input forms here you can see all the different input forms there's file uploader and this will just trigger the user's own file manager from their computer from their device to open up they can choose something and all we're doing right now is hiding the pop-up but allowing that file uploader to maintain its value maintain the file that was selected if you hide it it's still going to be there just kind of behind the scenes it's not going to clear for you which is a concept that can be very useful for kind of behind the scenes or background calculations within inputs that you don't need the user to see can be helpful in certain cases or just hidden variables bubble does have a custom state system for hidden variables so it really just kind of depends on what's going to work best for your needs i'm getting sidetracked now so when we click attached we hide the pop-up if we click discard it's going to hide the pop-up as well but also reset the pop-up so that the file uploader clears so we're discarding completely wiping that out the next time we show the pop-up it you know it's clean um if there is a value in that file uploader we're going to see a piece of information under this input let's go into we actually right click here and i'm going to do a little shortcut here you'll notice that i'm moving more into more shortcuts uh reveal the elements tree to pull it open uh here automatically just kind of unravels everything for me and here this hidden text would display this this content here file attached and then we'll display the file uploader's value and then the file name and this is hidden by default okay and it collapses down the condition is going to make this text show if there is a value in the file uploader so again we close the pop-up but if we didn't reset it then it will hold its value and then this text will display and let the user know okay you've got a file attached when we're ready to click send and create our new message let's take a look at that workflow it's in green here this is kind of the heart of the whole thing we're going to create a new message record so again just to point out where that action is that's under data here create a new thing create a new message save all of our inputs so the actual content from our input the attachment is coming from the file uploader again not every message is going to have an attachment if there isn't then this is just empty and that's okay and we want to make sure that we relate the message to the thread again this goes back to that relationship field it's not a plain text or anything it's a reference to the entire thread record so as long as the structure of this field was set up where the the type of field right here just getting to it is thread then the value in this workflow can be a thread right not be very clear about this not the threads customer not the threads unique id not the threat's creation date just the thread this value is compatible with the format of the field if i had gone to the threads let's say unique id bubble doesn't like that it's going to say it's in red here and it's going to reveal it in this issue checker i'm saying hey your create a new message value should be a thread but right now it's a text right the unique id is a plain text it needs to be a thread so i'm going to remove the unique id piece a lot of people get confused because they'll see oh there are more options i should keep going with my expression no not necessary those additional options are there because you could potentially have a different expression that you want to create or you might be going through a record to get to another record right you're building off of your expression kind of chaining things together so bubbles kind of giving you every possible rep excuse me every possible route uh but it doesn't mean that you have to just keep going keep going until it ends because it might never end you might always find yourself with more possibilities all we want is a thread value here now that's creating a one-to-one relationship from the message to the thread okay so once we send the message we attach all of those values we reset the input so that it clears out the file uploader is clear and we again scroll to the new message just in case we were scrolled up hit send go back to that new message that was created okay so there we have it there is the messaging functionality a lot of uh things built into a very clean design a very comfortable and familiar design to make it easy for a user to just jump in start typing away there's nothing new to learn about this kind of configurations very common type of setup here but you'll see that there's a lot that you know goes into customizing a a an aesthetic like this down to the roundness of your corners down to the alignment the positioning of your text left center right what information you want to display what do you want to display conditionally okay so there's a lot of logic around all of this for that to happen properly all right so now we're going to go into our shopping cart and checkout flow demonstration this is going to be a collection of all of the things that we've looked at to this point the functionality in here is also going to include an integration with stripes so that you can see a quick way to get payment set up in your application you know this is still really the tip of the iceberg in terms of what's capable what's capable what's possible on this platform um but it is the more sophisticated of all of our demonstrations because there's more data types involved more related fields more related records that need to communicate with each other we have calculations happening like i said we have the connection to stripe so i'm going to take you through walk you through the designs through the workflows um and also a front end preview so you can see what the user will experience this is from the perspective of the customer and they first load the page they are going to be met with an empty state design nothing has really started but it doesn't look broken because we've got this nice little image here and an easy call to action button hey click this to begin so when they click on this button what's happening in the background is a new order record is getting created and that new order record is going to be remembered in a custom state we haven't looked at custom states throughout this entire video it is a more advanced type of feature that you can manipulate in many different ways it's essentially a way for you to create a temporary value so it's not something that's being saved to your database although you could take the custom states value and save it to a record in your database just like you can with input values file uploaders things like that um but the purpose of the custom state here is just to keep track of our parent order as the user goes through and adds items to their order it's going to modify that record and we can ensure that it's always going to modify the right record if i were to refresh the page i start all over the custom state is cleared i need to create a new order okay so as soon as i have an order uh the custom state has a value we're going to see this first group now i haven't added any selections here so this is all that i see the list of products have been set up in my database under the product table so this would be something that me as the app owner if this app is just for my own restaurant i could manage you know in an admin page somewhere my users wouldn't have control over managing products and i can create these these items and their price or if i was building more of a sas application where my customers are multiple restaurants right multiple businesses they create their own menus of products so the database would have to link products to specific businesses that way when a customer of a specific business comes onto an order page they're only seeing the menu of that restaurant that they had selected so think um any kind of online ordering um you know door dash type of thing or uber eats where you have to select your items or you can select the restaurant um and they're all gonna come from one database i mean that's one way to do it of course you can use bubble's sub-app system to have every restaurant on separate databases but the idea is that you've structured your database to relate the products with the right business for now what we have is just one list of products assuming that the app is built from the perspective of one restaurant only so the customer can add quantity to certain items so let's say i want one barbecue chicken the moment i add that first line item you can see here my order summary is going to appear and show me the the total that that i'm accumulating if i wanted to add another barbecue chicken right now when i modify the quantity it is modifying the line item directly the line item is unique to my order with you know this restaurant it's this line item is unique to my order and more specifically with this product the line item is going to have the quantity for that one product so that we can do a subtotal if i add another product to my order i'm creating a new line item with a quantity of one and so because the base price of that item is five dollars times one it's still five dollars if i add another one here it's gonna up the quantity up the subtotal so i am not modifying the products directly i am modifying unique records for my own order i'm gonna add one more here okay so we have three items there's my total it's just adding up all of the subtotals and i can delete you know an entire light item if i want i don't want the barbecue chicken anymore i just want the pepperoni and the margarita all right uh and again i can still modify my quantities from here notice that there's a condition on the minus icon if i have zero because i can't go into negative quantity so i don't want to give the user the opportunity to make that mistake i can always go up but i can't go past zero from here if i'm ready to check out it's going to now trigger a stripe plugin action to generate a checkout page so this is a checkout page that's actually hosted on stripe which is perfect because you want stripe to handle all of the sensitive financial you know transaction information i'm currently logged in as this person and i've actually run through this page before so it remembers the test card that i used but i could change it and type in a different credit card number and make a payment i'll show you right here let's actually just keep using this credit card and i'm going to hit pay but just keep an eye out you see this title pizza app checkout there's my total and it has listed out my items that i selected if i click back it's just going to cancel the transaction just take me back where i came from if i click pay it will process the transaction and if this was in a real live mode not in a live mode it would actually process a real credit card and make the payment from there so you can see when i came back bubble gave me a little alert message your credit card was successfully charged i do have control over that messaging i also have control over not showing that and just showing my own design if i want it okay so i'll hit ok and it just takes me back to where i started so from here of course i could design other steps in the flow for the user to see a receipt an order summary we could send them an email lots of different things we can do from here so let me take you back into the editor so we can see how this all came together there's four data types involved first was the product table so we could have a list of products with a name and a price so if we go into the products list there they are the names and the base prices that would be managed again by the business themselves um when the user first clicks on start a new order a new order record is created um by default the status will be in pending i think that's going to be in the workflows but we could also set up the default here so that every new order is set up as pending and the order is going to update its running total every time we add a new line item we'll update this value we'll see that in the workflows as well but every order is tied to a list of line items so remember before every message was tied to a related thread the order is tied to a list of line items once the user selects a quantity of at least one they're going to create a line item this is the unique combination between an order and a product okay i have i am selecting a specific product for this order and from here i can identify how many of this product i want so that i can do some math in the workflows to multiply my quantity by the product's price okay i don't even need to have the products price here the products price already exists in this record so as long as my line item has a relationship to the product i will know the price of that product and i can multiply it by the quantity to get my subtotal and from there i can add up all the subtotals of my line items to get a final total for my order the last data type we have here is a transaction data type um this is this would be created after the user comes back from stripe um so that we have the amount that was paid the order that it was for and stripe actually creates ids for absolutely everything so when a transaction happens you have an id for that payment and so saving that to the database would be a smart thing to do for troubleshooting just documentation purposes so let's just take a look at the actual data that was generated from that shopping cart that i just created here so let's start with the order this was right here this is my order there was my total 13.75 these are the two related line items remember they're represented by their unique id because line items are identified by the unique id but i could have them identified by products and make sure that the product is also identified by the name otherwise i would just end up with the unique ids of the products which would not be helpful so here i should see there we go there's my order with these two items um under the line item those are the two right here two records with the quantity and the subtotal you can see the unique id of the parent order these are the same because they both belong to the same order and then finally the transaction that was created after i came back from stripe the amount paid the associated order and then there's the stripe charge id ch is the prefix for that one so going over to the design we have a primary group here which is set up as a row uh layout style right again they're both centered the items inside separated by 20 pixel gap spacing in between the two and we have our two groups right on the left we have choose items um which is oh sorry i think that gap spacing was for the choose item no no it was the same i'm getting confused all right so this left group here um is set up as a column so things are stacked vertically i can see some padding right 20 padding on the top and bottom 10 on the left and right and inside we have a reusable sorry a uh repeating group of our products let me open that up here so we can see it there it is repeating group of our products just searching for products no constraints but again if this was more of a sas structure i would constrain on the business on the you know on the restaurant um so that we only see that restaurant's products and then inside we can display information about the product the name the price formatted as a currency we've got a little custom design here to do this quantity this is not an element that exists this is actually made up of two buttons okay a button with a minus and a plus label and then an input uh so that the user can oh sorry this is a text my my apologies my mistake this is a text that is just pulling from the database because the buttons are going to update the line item record in the database and this text will simply display what has been saved to the database so that way the user is actually not typing in their quantity but they're pushing the buttons you could absolutely use an input though to give them both options they could click on the button or they can just type in a number that they want so if they want to jump from zero to ten ten pizzas big pizza party uh they certainly can do that okay um let's see and if the line item is empty then it is going to be zero it's not going to show anything so if we check out the workflows here i mean you can see there's a bunch of conditions to um you know make it more faded out it's not clickable if we don't have a line item right we don't want to go into the negative numbers let's take a look at the workflows for these particular buttons here so let's do this one here first if i click on the plus button and we do not have a line item for this product now notice that it's referencing the parent groups line item why might that be happening well we need to search for an existing line item and we're going to be doing these searches multiple times on the minus button on the plus button on the quantity so we need to streamline them these three elements right here live inside of a group let's go into the tree here these three are inside of this group now this group is doing us a favor it's searching for the line item for our order for this particular product right this sells product right here and if there is a record that exists then the group is going to have a data source it will contain a line item if it does not find that line item that means we have not created anything yet and it's going to be empty the group the group source will be empty so here's the condition again if i click on plus and the parent groups line item is empty then i know i'm safe to create a new line item and i can save all the details here by default it's a quantity of one it's my first click of that plus icon the associated product is going to be tied to the group's product my subtotal at this point is simply the product's price because i'm only at a quantity of one the order is the custom states value i'm going to jump over there in a second so you can see how we set that custom state but i'm referencing the custom states value because that's where my order lives then i'm going to update the order and i'm going to add this new line item to the orders list of related line items remember that's the list field that we created you have list operations here to modify lists and from here i'm then going to want to update my orders total and because i have many different areas that could trigger an update to the total i've consolidated these actions into a single workflow event so that i have to repeat actions multiple times it's less room for error by can streamlining things down consolidating things down so this is going to trigger a custom event here this is another type of trigger you can create and i've just labeled it update total and the only thing that happens here is it recalculates the sum of the order searching for line items for this order taking each item's subtotal and then adding them up if i do a plus when the line item is not empty meaning i'm doing a quantity of two or more then i'm going to update that line item and add to the existing quantity whatever the quantity is now plus one and i'm going to update the subtotal so i'm basically taking the new quantity right whatever the quantity is now plus one times the line item's product price i'm just recalculating everything when i click on these buttons under certain conditions and then i trigger my custom event again to recalculate the total right so both of these trigger one event to recalculate the total this reduces error because if there's a mistake here then i only need to make the change here the correction and i don't need to go check all of my different places where i could potentially be updating totals and they might be inconsistent the minus icon is going to do a delete if we are at the last quantity so if my quantity is currently one then we can go ahead and delete the line item fully we don't need to keep it so this is a delete action if it is anything greater than or equal to two so you can see our conditions here it's going to subtract the quantity and then recalculate the total or the subtotal and then trigger the update total event so they can recalculate the master total the grand total okay let's quickly look at the workflow for when a new order is created when that button is clear that was the first thing i did when i loaded the page i created a new order by default the status is pending and i'm going to save this order in a custom state so we use an action here called set state so this is under element actions set state right there so remember a state is a temporary value it's up to you to create your states and what kind of value you want to save to them states you can think of them as fields they're just not in the database they're on the page so where you have fields on data types states are on elements okay our custom state right now that we're working with is on the page the page is also considered an element so if i open up this little inspector i can get to any states i've created on this page i can create multiple so i've created a state called current order and the value is uh going to be an order record it's a reference to the entire object you can see that i could also set states to be lists you know i can have multiple states i can delete the states from here this is a more advanced piece of functionality but it gives you a lot of flexibility for manipulating values in real time passing data around um kind of behind the scenes so when the order is created we're going to update the value of that state we know the state lives on the page it's possible to create states on other elements too it just depends on how you want it to be organized um and the custom state that i want to modify is this one current order here i could have other states if i wanted and the value is simply the result of step one this is one of these dependent actions where i need to have the order created first and then i can set the state and refer to the result of the previous step which is my new record that happens behind the scenes the user doesn't really see any of this happening they just see groups become visible because there's now a value in that custom state so remember this was the first group that appeared and the condition here is when the the page is the name of my page here you can see cart demo when the pages custom state the name of the state is current order is not empty then we show this group and then this group over here is based off of the line items if our list of line items which is a repeating group in here has at least one item then this becomes visible so you notice that i'm leveraging whether things exist or not to know whether to show something or not and i can reference other elements on the page i could do searches in my database i can reference inputs custom states okay so this repeating group over here on the right is going to be a list of let me go into the parent which is the repeating group this is a list of our line items for the specific order we of course don't want to see line items for other orders so that constraint is very important there and then we show all the details inside the line items products name okay so i'm going through the line item to get to the related product that's a relationship field and then to the product's name over here we display the line item's quantity which is just a number and here we'll display the line items subtotal formatted as a currency this icon is simply going to delete the line item so that triggers a simple delete action and it should recalculate the total i think that's this one right here yeah delete line item and calculate the total notice how like most of these workflows have to update the total so that was very important to create this custom event to make that really efficient for us and safer and this total text here is going to display the value from the record it's the orders total formatted as a sum uh as a currency most of these values i think actually all of them they're pulling from the database directly now you could also have these calculated in real time just like we did with the expense and budget tracker i wanted to do it this way so you can see a different approach okay now the checkout button this is talking to stripe we have an integration here so the plugin that we're using is this one right here stripe this is a bubble publish plugin there's a lot of documentation around getting this set up but basically when you have a stripe account you'll get keys api keys that you can add to the plugin settings here i mean you have a lot of different popular actions available to you charging the user collecting a credit card for paying later um creating subscriptions all of that so what we're going to be triggering here when we click on checkout is the charge the user action and that's found under the payment list here right here all of the actions available so we want to charge the user and we'll basically just fill out the form just like we have with all of our other actions to see what we need we're going to supply the email of the person paying the total amount that they need to pay the currency we're going to have a name for the checkout remember remember in the description i saw the list of pizzas that i had selected and so that was defined here i'm providing that dynamically through this expression i'm taking my line items products names now i had to say unique elements because it's possible that i have multiple let's see actually if the line item is going to be tied to one product we actually didn't need to do unique elements that doesn't really hurt anything um but line items each yeah we didn't need to do that i'm going to change this like this if there's a possibility of a a list expression showing duplicates unique elements removes your duplicates that's the only reason that was there but i'm realizing now that every line item is tied to one product so there would be no danger of having duplicates a couple of other settings around charges when this action runs that's when the user is directed to that checkout page when they come back it's going to pick up with the workflow and we have a internal transaction record this is another data type to be created just for documentation and we'll save all of the details so we can take the result of step one which is the stripe action and stripe returns a number of details that we could capture and save to our database um so i'm just capturing the charge id um i'm also relating it to the order and the amount that was paid so i'm pulling this off of stripe you know they also provided the amount back to us i could have also gotten it from the order um stripe actually returns amounts in the lowest uh unit of the currency so if it was usd it would return it in cents uh and so i needed to multiple or sorry divide by 100 just to have a whole dollar uh conversion for that update the order change its status to paid and clear out my custom state you see i leave this value empty now which means that the groups are going to go away it's going to start me over from the beginning and i can begin a new order if i'd like all right that's a full checkout flow from start to finish with an interactive design so that the user can indicate what they're selecting go into a checkout and make a payment when it comes to building a full application you are putting something live on the internet so there are things to be mindful of that go outside of the front end designs that you're putting together the logic that you're building into your workflows and your database structure you have to manage two different environments a test environment and a live environment you're going to be troubleshooting things bugs will come up they need to be fixed you need to know how to resolve those issues you need to know how to maintain your application for the long term keep an eye on the performance the app capacity that the app is using so bubble has a number of tools and resources available to you to monitor all of these things and to manage these different areas that your users might not necessarily be aware of but you absolutely should and i just want to run through them real quick so you understand what is available to you the debugger is that tool that we saw in some of our demos that shows up on the front end preview it helps you inspect your elements to understand uh behaviors of all of your settings sometimes you might not see what you thought you had designed and the debugger can help you uncover why that might be the responsive viewer we also saw that as well so that you can make sure that everything you're designing looks good on all the different break points all those screen sizes so that's the other kind of toggle view that you get to within the design tab of your editor your issue checker was that little box in the upper right corner with a number count of however many issues you have we opened it up a couple times to see if bubble was flagging something and basically that's when bubble's going to tell you if something's not configured properly in your editor not necessarily anything to do with your custom flows or your you know your your users market or anything like that but more about technical functions that have not been set up properly maybe you might be missing a required value server logs we didn't really touch on but there is a section in your logs tab uh to monitor all activity that happens in your app so anytime somebody makes a database change or clicks on a button everything is getting recorded in those logs and it's a really good resource for some deep troubleshooting depending on the plan that you're on is going to dictate how far back in the logs you can go version control is is very necessary whenever you are deploying your app and you have multiple versions of your application so this way if you ever need to revert your application back to a previous state for example maybe you introduced a new feature too early it was buggy and you need to kind of go back so that your live users aren't interrupted you can always revert back to a previous point in time and bubble has different resources for you to keep track of your different versions with time stamps and all of that again depending on the plan that you're on with your bubble app that's going to dictate how far back you can go and do that kind of revert data copying because you have two separate environments you will have two separate databases you can copy data between the two databases there's a lot of strategy around doing that in some cases you might never need to do that in other cases it might be a frequent occurrence and you can go in either direction so just be careful when you copy data but this can be found in the app data section of your editor deployment and save points i touched on this a little bit but whenever you are ready to go live or push a new version of your development over to the live version uh bubble has tools for you to do that and you can also create save points which are basically bookmarks a way for you to bookmark uh dates and times uh whenever uh you know a big feature a big change happen in your um editing of the application save points do not deploy your application they're just a way for you to keep track of time connecting to a domain so of course if you're going live with the custom application you're likely going to want to be on your own domain rather than bubbles hosted domain that you get initially when you create your app so regardless of who your domain host is by the way you do need to buy a domain separately bubble does not sell domains uh you'll enter in your domain into the settings and bubble will give you instructions on how to connect your domain to your domain host because of the custom domain functionality you'll also be able to send emails uh using bubble's built-in email functionality from your own domain there's also a couple steps there to get that set up properly bubble has a built-in connection with sendgrid uh to do that if you want sendgrid to manage your email sending functionality you can also connect with other services if you prefer to use a different platform for that now of course like i mentioned this is really just the tip of the iceberg everything that we went through here uh covered more of the core fundamentals the core concepts you have to understand in order to get started with a bubble app remember the three pillars are the major ones your database your design and your workflows those three things together will address all of the different components of a functioning interactive data driven application there are many other advanced capabilities available to you so depending on the type of app that you're building or the users that you're working with you might be taking advantage of some of these things so i wanted to just touch on a few popular ones in terms of advanced features api connections this is actually one of the most powerful pieces of functionality that the bubble platform offers is the ability to connect to the outside world via api so the stripe integration was a very simple one because it went through a plug-in but you can also do a manual connection to stripe using bubbles api connector any service that offers an api connection you will most likely be able to connect to it with the api connector it covers um basically standard setups for api's um standard authorization methods as well bubble also has a plug-in that lets you connect to sql databases so if you have an external sql database with all of your content and you'd prefer to grab data from there rather than pull data into the bubble database or maybe do a combination of both there is a connection tool for that as well back in workflows is not something that we touched on during this video but it's another very powerful section to create a background workflows so the user doesn't necessarily need to be present in your application for something to run server-side back-end workflows are a great way for you to create a recursive workflow so things that run on a loop for example sending an email every monday with a summary of you know the latest to do's or the things that are coming up um or creating a lot of data on a loop in a recursive fashion um in general just being able to manage big bulk changes to your database is generally going to be done in a back-end workflow especially for performance um you can also have external services trigger your back-end workflow so it's kind of the reverse in terms of the api connection um this is often known as web hooks so if something happens on an external site they can notify your application like a real time app to app notification system with that information and from there you can do whatever you want send somebody an email update your own database very powerful section for both connecting to the outside world but also um running more advanced uh operations in your own internal application uh custom state so we touched on that just a little bit in our last demo but that was honestly kind of a really really basic use case of a custom state they're really popular for manipulating visual interactions with your users again because they're temporary they they're not saved forever in your database they're really handy for doing calculations for just passing data around there's a lot of specific niche kind of interaction functionality that can leverage custom states to make them work really well in addition to all these kind of built-in features you can add your own custom actual code to your bubble apps as well currently you can add your own css you can upload your own fonts you can add html code there's actually an html element in the design tab and javascript as well so if you have any requirements to have some custom code for that depending on the language of course and if it fits within one of these categories you should be able to do that also keep in mind that you can build custom plugins for yourself that are more javascript based as well where it's private to your application it does not need to be listed publicly in the marketplace you can of course import and export your data your data is yours bubble does not own it um so there are some actions both in the workflows to export data to csv or just directly as an app admin through the editor in the back end you can upload via csv map all of your fields there or modify with a new csv file and there's also plugins and other strategies you can take to ha you know allow your users to upload their data to your application especially if you're working within a sas environment we've seen that very common functionality uh where the platform wants to allow companies to maybe bring in their own customer lists or product lists that all happens through custom workflows that you have to build out step by step but capability is absolutely there sub-app systems for sas products we touched on this earlier at the beginning of this video but this this is a platform that can support that type of structure where if your clients your customers need to be on their own dedicated databases their own instances of your app sub-app system is the way to do that you do need to be on a higher plan in order to enable that capability and there are some things to think about there it's more of an involved process to get that up and running we always recommend starting with one app first to get things off the ground get the feedback you need but that's certainly a system that you can grow into there's a lot more that you can leverage here um i would say that you know honestly the most powerful capability is you um you are the one that is putting together all of the logic you have the tools and resources available to you to combine everything in the way that you need your next step from here is to take what we've covered today and combine it with the right development methodology because being able to think like a programmer as you use bubble is critical to actually launching your app head over to coachingnocodapps.com workshop right now don't wait and join our additional free workshop that'll pair these bubble tactics with a methodology and strategy you'll need to successfully launch your app [Music]
Info
Channel: Coaching No Code Apps
Views: 369,424
Rating: undefined out of 5
Keywords: apps without code, bubble.io, bubble.io tutorials, no code mvp, no code apps, bubble tutorial, bubble help, bubble.io tutorial, bubble app tutorial, buildcamp, bubble.io lesson, Bubble app builder, bubble, no code app development, how to use bubble, how to learn bubble, bubble app examples, bubble walkthrough, bubble coaching, bubble development, bubble no code, build an app without coding, bubble for beginners, bubble crash course, getting started with bubble, matt neary
Id: DYHtR7IONl8
Channel Id: undefined
Length: 192min 30sec (11550 seconds)
Published: Wed Aug 17 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.