Building a Business with Ignition and Perspective – Part 1: First Steps

Welcome to part one of my series on building a project tracking tool in Ignition 8.0 using the new Perspective Module!

The goal for this post is to implement database connectivity, along with our editable text field template so we can begin the process of building out a CRUD (Create, Read, Update, Delete) framework for managing projects, customers, invoices, work orders, etc. in our new application.

Starting With What We Know

I’m starting with a template we built in 7.9 for editable components for text fields, dropdowns, checkboxes, etc. I’m starting with the text field, then will branch out from there. This method will probably be a lot simpler when we figure out how to use some of the built-in Forms scripting. As of the time of this writing, there is zero documentation on that, so we will update our approach once we have something to go on there. We’re on the frontiers with the method below, no need to go into another world entirely.

This text field will be used in most of the CRUD screens for entering names of things. For fields like customers, once we have a list of customers in the database, we will create dropdowns along with checkboxes to show/hide active/inactive customers when creating projects. This is all basic application design 101. I am going to lean pretty heavily on my Ruby on Rails, and ASP.NET MVC experience combined with everything I have done in Ignition here.

Forewarning, this is going to be technical. It will probably include things I will cringe when I look back after I better know what I am doing. I subscribe to the adage if you aren’t embarrassed by your code you waited too long to show it to the world. For reference, even the code I write once I feel like I know what I am doing is almost always laughable once I learn more, as is the process of Mastery.

Let’s Get Setup

I set up a gateway on my computer, added a database connection, and created a new project. This process was very similar to my posts on Perspective and Ignition 8.0, so review those for more information on that process.

I created a folder structure to hold each of the entry field templates I am going to use, starting with a text field. Views in Perspective can be embedded into other views, so this is going to be my version of the template approach we would typically take in the Vision module.

For this view, I am using the “Coordinate” layout view type, as I want to define the layout explicitly. We can then embed this in Breakpoint or Flex layout views to have a responsive site for use on mobile devices. I am going first to get it working, then adjust the layout as needed for use on mobile.

As you can see, I added a couple of labels and a text field to this view. The lbl_title will be the description for the field, the lbl_value will be visible when not in edit mode. The idea is that we can use the same template for both details and edit views. The txt_value will be visible when in edit mode and will allow you to change the value of the field before saving it to the database.

Here we can see what the template looks like in basic form in detail mode:

and in Edit Mode:

To accomplish the visibility, as well as to make it possible to pass in dynamic values for the description and the text value, I added parameters to the view:

The label will hold the description, editable will control text field visibility, and text will handle the value we are displaying.

Then I bound the description text to the label parameter, adding in a colon with an expression binding:

And bound the text field and label value to the text parameter to change the text dynamically:

For reference, here are the property panels for each of the objects on this view:

This handles the field template for initial development purposes. There isn’t any error checking, formatting, styles, etc. yet. We will get to that once we have everything working with known data. I like to avoid premature optimization where possible. Let’s get something we can use as quickly as possible, and let the actual use of the application dictate what we need to do from there.

Where the Rubber Meets the Road

Next, I added a view to handle the primary form for managing customers. Some of this will be hardcoded for now and will be updated once it is working to make it generic for any table in the database. There is a whole different series we could get into about database design and how we have built out systems in Ignition to make things as simple as possible on that front.

Here I am also using a coordinate container; we’ll update this in the future once we get things functioning at the basic level. You can see I added this container, then the template we created above as a child on this container.

Second, on the view itself we will need to know which ID value we are looking for in the database. We also want to know if we can edit this record, or only view it. I added these as parameters on the view (we can then use these in the URL in the future). Also notice the arrow on the right, where we set these to be readable and writeable from the template. (We’ll get more into parameter controls in a future post):

Now to pull data from the database…

First I want to load the data when the page loads. To accomplish this I am calling the code on the onStartup Event on the root container. For ease of future troubleshooting, I set up a custom method on the root container we call in the onStartup event. This makes it easier to find any scripting related to the root container by keeping it all under the scripts section:

Here is the onLoad() method itself:

Let’s go through the code quickly:

The first few lines set up a standard PrepQuery call to the database. The only Perspective specific thing here is the self.view.params.dbID value that grabs the value on the view itself. This would be a self.dbID in Vision if we defined a property on the root container:
query = “SELECT * FROM Customers WHERE id = ?”
args = [self.view.params.dbID] data = system.db.runPrepQuery(query, args)

Next, we are going to map a variable to the text field itself; again this is Perspective specific nomenclature:

field = self.getChild(“cntnr_fields”).getChild(“txt_field_1”)

Finally, we set the properties on the text field template accordingly, using the Perspective specific calls to the properties themselves:

field.props.params.label = “Customer Name”
field.props.params.text = data.getValueAt(0,”customerName”)

 

Now when we open a Perspective session and load the page, we see the first record in the database loaded on the screen:

Now Let’s Make It Do Something

This is a solid start. Let’s bring it home with a checkbox to enable editing, a save button, and a cancel button.

First the checkbox, with a Bidirectional binding to the view’s editable property:

Second, the cancel button. For now, we will cancel editing, and reload from the database using our onLoad() script on the root container:

Finally, the save button. Here we will grab our dbID property, so we know what record to update, get the updated text, and write this to the database:

Now when we open up our Perspective session, change the text and hit save, we will write the data to the database, and we are good to go!

Next time, we are will refactor this code simplify how all of this is managed in the Designer. We will also get into some styles so we can start adding in error handling.

Thanks for reading. Please let me know if there is anything you want to see in our deep dive into Perspective!