We were in the process of building our WebPanel. WWattractionsFromScratch where we saw how to condition and sort and organize the data shown on the Grid. The Grid had a Base table. For that case, we also saw how to load a Grid variable for each line with the Load Event. We use the Refresh and the Start Events, and we programmed an Event at the line level to call the Attraction Transaction in Update mode. Now let’s add another action of the line level. But this action will not call another object with interface, as it happened in the case invoking the Attraction Transaction. We can imagine that, for instance, we will enable the possibility to create, from a line in Attraction a new Trip in the Database, with that Attraction. First we add a new variable to the Grid called NewTrip and 10 character. Let’s change it to ReadOnly. We want it to contain the NewTrip text, so we assign it in the Start Event because there will be no variations by line. And let’s program the click Event for that variable, the Click Event. What do we want to do when the user clicks on NewTrip. For example call a Procedure to which we pass the identifier of the lines Attraction. And then we create the Trip with that Attraction. Note that we implemented it with the New command, to create a record directly in the Trip table and another one in the TripAttraction table, the solution shows how the commands are used. However, a more recommended solution would be to use the Business Component of Trip for inserting. In this course ,we did not see how to load a two-level Business Component, which is very simple to do. We will see that, following the insertion of the header and line of Trip, we calculate the number of trips that include this Attraction. Since the Inline formula is triggered without positioning on any table, It’s loose inside the code, we must indicate the explicit condition that we want to filter the Trips of the Attraction. And that is the value returned, when this Procedure is called. So, from the Click Event of the NewTrip control variable, we invoke this Procedure and pass the AttractionId of the line from where the Click is done. And since the parameter returned is the one we need to show in the Trips column, we assign it directly to the variable. It’s only logical that, upon the users Click on NewTrip, for that line in the trips column, the values shown, should be the one it had prior to the Click plus one. That is, the line should be refreshed. Let’s execute and give it a try. For example, let’s filter by France. And for the Louvre Museum Attraction, which for the time being is not part of any Trip, let’s Click on NewTrip. We can see that the line has been automatically refreshed, now it shows the number of Louvre Trips. However, the Total count was not refreshed, it should be 4, but it keeps the previous value .Why? Upon executing the Click Event associated with the NewTrip variable, only its code was executed. And because inside it a variable of the Grid was assigned a value, the line is refreshed and only that line. No other Event was executed not even the Load Event. Therefore, we have 2 options to keep the total number of Trips loaded on the Grid updated when this Event occurs: One possibility, is to add one to TotalTrips, because the Procedure only added one Trip to that Attraction. But if the Procedure is later changed with the addition of more Trips, then we will have to remember to do the change in a way consistent with this Event. A better solution is to request the WebPanel to execute the Refresh and Load Events once again. To do this, we use the Refresh command. When we do this, the Grid will be loaded in the Database once again, let’s try executing this. We add a Trip for the Matisse Museum. And we can see that now, it has updated at all. It executed the Refresh and Load Events once again. The loadder was executed seven, times once for every line to be loaded. Let’s review what we have seen so far. For the case of a WebPanel with a Grid with attributes, GeneXus will understand that the Grid has an associated Base table. That is to say, a table to be navigated in order to load the Grid lines. It’ll load a line for each record in that Base table. To filter, we have the Conditions property of the Grid, and to sort we have the Order property. A Grid the Base table is analogous to a For each. For the System Events produced in the WebPanels, we can program code to be executed at the time when they are triggered. We saw 3 of such events that are always triggered when a WebPanel is opened that is in the first execution: The Start ,is triggered only once, there we can for example initialize variables. The Fefresh, is triggered prior to the loading of the screen data. Following this Event, the access to the Database will take place in order to bring the data of the Base table and its Extended table. A Load Event is produced for each record on the Base table, that is about to be loaded on the Grid. Therefore, this will be the point where all the actions we want executed before the line, is actually loaded on the Grid, will have to be programmed. The data loaded on the Grid is exclusively the data from the Visible or Invisible columns included in it. After this, the WebPanel will be loaded with the information obtained from the Database, and it’s then disconnected from it. But WebPanels also enabled the definition of other Events, that will be triggered after the first time. This means, that they are triggered after the WebPanel has been loaded, always as a result of the user’s action. For example, the Click Event that we programmed on this Image, or the click on NewTrip. Or even in the WebPanel we defined several classes ago. The User Event, we associated with the button that we gave this name. These events, are known as User Events or Control Events, as the Click event we saw. When the user causes one of these Events, only its code is executed, without screen refreshing. The only exception occur,s when the event takes place at the level of a line in the Grid. As In the case we saw of NewTrip, where a variable from the same Grid, in our case Trips, is assigned inside its code. In this case, the value of the variable is refreshed on screen, for that line, so it’s shown updated. When we need the refresh to be executed again, and that lines loaded again on the Grid from the Database for example to update the total of lines, we may write the Refresh command in the Event. We studied the case of WebPanel with a Grid with attributes. But, what if we have a WebPanel without Grid and with attributes in the form. Let’s suppose that we want to click on the name of the Attraction, and call a WebPanel to show all data on that Attraction. To do that, we’ve already implemented this WebPanel. Where we’ve inserted, in its form, the attributes of an Attraction that we want to show. We also wrote a Parm rule to receive a parameter. We can see that, instead of receiving in a variable, we decided to receive in the AttractionId attribute. What we wan,t is that when this WebPanel is called from the Click Event of AttractionName, in our other WebPanel. To pass the d of the Attraction of the gridline, GeneXus automatically goes to the Attractions table, to find the Attraction with that Id. And show for that Attraction, the information on the attributes located in the form. In some, a WebPanel that has no Grid, but containing attributes on the form, will also have Base table. How does GeneXus determine it if we don’t have Base Transaction to indicate. That’s something we will not see in this course. But it’s something similar to the case of a For each where no Base Transaction is indicated. But in this case, since we don’t have a Grid, only one record from that Base table, and it’s Extended table will have to be loaded. Where do we indicate the filter to enable the return of that record. In our case, it received in the AttractionId attribute. There we specify the automatic filter, to indicate which records from the Base table must be taken. If we need to establish another type of condition, or if we received in variable instead of in attribute, we have the Conditions tab to establish the filter. Let’s execute to see this. So far we’ve seen 2 WebPanels with Base table.The first one with a Grid. Ther,e the Base table of the Grid is the Base table of the WebPanel, that is, the table that the WebPanel automatically decides to navigate to retrieve the information to be loaded on screen. The second one without Grid, but with attributes, there the Base table of the WebPanel is found from those attributes. We will now see the case of Webpanels without Base table, that is, WebPanels that do not have a query to the Database programmed automatically. The case most evident is when no query is made at all to the Database. As In the case of our initial WebPanel, which only requested data from the user and called other objects. But we can also have a WebPanel that does query the Database. With that query and load on screen ,fully in hands of the developer. The WebPanels we implemented with Base table, could also have been implemented in this way. Let’s take a look at the case of the WebPanel that shows the Attractions in the Grid. But this time instead of having attributes in the Ggrid, we will have variables. So in the Events, we have to change the invocations we had. Where we passed the AttractionId attribute in the AttractionId variable. If we now only have variables, how does GeneXus know that it has to navigate the Attraction table, and it’s eExtended table to load a line in the Grid per record. In fact, it doesn’t know that.The load of this Grid will not be automatic as in the case where we used attributes. This means, that the Load Event will not be executed when it has gone to navigate a table for each record, where we’re positioned at a given moment. This is because we are not positioned anywhere. However, the Load Event will indeed be triggered. Except that it’ll be triggered only once after the Refresh, and not being in the Database at all. In that triggering, in that execution, we will have to program the Grid load manually. We will to explicitly request access to the Database. In our case by going to the Attraction table. And indicate that every time that a line is loaded. in. In order to instruct it to insert a new line in the Grid, with the values of the variables corresponding to the columns half at the time. We have the Load command. Not the Event, but the Command. Every time that a Load command is inside the Load Event the only location where this command is loud, a line is inserted in the Grid. What we will have to do then, is to program inside the Load Event the access to the Attraction table with a For each. Where we will specify the Order clauses and, in the Where clauses the conditions that the data must fulfill. And for each record compliant with those filters. We will load the Grid variables with the values of that Attraction. Once all the variables are loaded, we then write the Load command to add a line in the Grid, with those values. Here we have this WebPanel that’s already implemented. We did a save as of the one we had with attributes and change it with variables. And we also change the Events as we just saw. Let’s try what we did to see that in run time. There is not a difference between the WebPanel with Base table, and the WebPanel without a Base table. Let’s now filter by France, for example. Now if we note the Navigation listing of the WebPanel without Base table, we have the following. We can see the For each in the Load indicating the navigation. In sum.. When we head to WebPanel with a Base table,upon opening the WebPanel, the Start Event was executed. Followed immediately by the Refresh. And then we access the Base table automatically. Filtering pursuant to the Grid Conditions, and sorting according to the attributes indicated in the Grids Order property. We consider this, as a sort of implied For each that GeneXus places there internally, without the need for the developer to do anything at all. And for each record to be loaded as a line in the Grid, prior to doing that, the Load Event is executed. This is why the Load Eventis triggered, in this case as many times, as there are lines to be loaded in the Grid. On the other hand, when the WebPanel has no Base table, the Grid only has variables and there is no implied For each. When we open the WebPanel, the Start Event is executed just like before ,and so is the Refresh while the Load is only executed once. When we need to go to the Database to retrieve information, we must do it explicitly inside this Event. In other words… We must write the For each and use the Order and Where clauses there. In order to load each line, we must do it explicitly with the Load command for each one of them. To end this, we should note that the applications designed by GeneXus do an auto-adjustment of the information shownon screen, according to the size of the screen. For instance, if we execute the Work With Attractions created by the Pattern. We are executing on a browser that occupies the full screen of a notebook. But let’s see what happens when we make the browser screen smaller. If we make it smaller from the right. We will see that there comes a time when the Grid shows only the name of the Attraction and the actions. And if we make it even smaller. We no longer receive the left column. This is how it’ll appear on a mobile phone executing the application from its browser. If we now go to our work with developed from scratch. We will see that even when we did nothing, it does have a slight self adjustment. If we take a look at the variables on top, we will note that they have the label on the left and occupy a given, width prior to the start of their own variable control. Where, they then have the label on top, occupying the whole width. To achieve this behavior ,when objects use Rsponsive tables. We will not be covering this topic in this course. But if we go to our WebPanel and stand inside the form in the CountryId control. We will see that here on the top. It shows the table control inside the one that it’s inserting. This is the Main table, and if we click on it, we will see that the Properties of this table include the Response of sizes property relating to the Responsive sizes. And if we click here, this screen can be edited. We will note that it has the controls inserted in the Main table. In turn, some of them, like this table or like the Grid, have controls inside as wel. And we also have a combo and mabeline us to select screen sizes. We now have the Medium size, but if we select Small or Extra Small, we will see that the values change. We should note specifically that for CountryId on an Extra Small screen, we will have the label occupying the whole width. And the Variable control itself will occupy the remaining 100% . And that is why we viewed the label over the variable in runtime. If we now select the Medium size, we will see that the label occupies 25% of the width, and the Variable control per say, occupies the remaining size to 100%. This is in line with what we saw at runtime. We should also note that we have the Visible property to hide certain controls for specific screen sizes. This enables us to manage controls in order to self adjust, where it is shown at runtime. According to the size of the screen on which the form is deployed on different instances. This is called Responsive Web Design. Which we only mentioned by way of introduction for now. So, now let’s upload everything we did, to GeneXus Server. There a lot more to learn about WebPanels. For example, when the WebPanel has no Grids or when it only has one. Where exactly it is GeneXus find attributes to determine whether it associates an implied Based table or not. And when the attributes appear there, what is the criteria that should abide by. Even when we might suspect that they’re the same as in the case of a For each, they must belong to the Extended table. It’s possible to implement WebPanels with multiple Grids ,either parallel or nested. It’s similar to having parallel or nested For each’s. There are 3 types of WebPanels. These videos have shown us only the Webpage type. But there are WebPanels, that may be defined as components, for cases where we need to repeat a part of a page, in multiple WebPanels. When we define it as Component, we can insert it in other objects with Web screen. We also have WebPanels defined as Master Pages. All KBs are created with Master Pages, which constitute the framework in which all pages executed are loaded. Here we can see on top, that the Transaction is part of the Master Page of the application. The Transaction screen opens up in the area meant for that in the Maste Page. And lastly, we should mention that, for developing mobile apps for Smart Devices, we also have panels called Panels for Smart Devices. In an upcoming video ,we will have an introduction to these types of applications.