Which files are changed when you add a new table to your AppGini project?

Many users wonder which files should they upload to their web server after adding a new table to AppGini and generating the app. Of course, you could just upload everything and you’d be on the safe side. But sometimes you might be working over a slow network or a metered data connection and don’t have the luxury of uploading everything. In that case, you could just upload only the changed files.

So, here is a list of all files changed when you add a new table to your AppGini project.

  • admin/incFunctions.php
  • admin/pageRebuildFields.php
  • ajax_combo.php
  • common.js.php
  • incCommon.php
  • parent-children.php
  • updateDB.php
  • resources/table_icons/*.png (normally only one new file exists in this folder, which is the icon of the new table)
  • all files beginning with the new table name in the main application folder and in templates folder.

How to allow numbers only in a field?

Let’s say you have a numeric field, maybe a price, a score or some other field that should contain numbers only. If you set the data type of the field in AppGini (or in your database) to be numeric (INT, DECIMAL, FLOAT … etc) that would allow only numbers to be stored in the database.

But you might still wish to alert the user that only numbers are allowed before she saves the record. Here is how to do it in JavaScript:

First, you should place this code in the hooks/footer-extras.php file:

Next, also in the hooks folder, create a file named tablename-dv.js (where tablename is the name of the concerned table) if it’s not already there, and add this code to it:

Change field1 and field2 in the above code to the actual names of the fields that you want to set to accept only numeric values. Add more lines if you have more fields or remove a line if you have only one numeric field.

The above code would remove any non-numeric characters that the user types, on the fly. And it would still allow negative sign and decimal point.

How to hide the seconds in a time field?

If you have a time field in your AppGini application, it displays a time picker in the detail view like this one:

The timepicker includes seconds. If you wish to hide the seconds part, you could do so by editing the tablename_dv hook. Open the generated hooks/tablename_dv.php file in a text editor (where tablename is the name of the concerned table) and look for the dv function, then add this line inside it:

If you refresh the page, the time field would now look like this, showing no seconds:

Auto save a new record without having to click ‘Save as copy’

An AppGini customer told me recently that he has a table containing only one field, a barcode field, that he uses a barcode scanner to populate. He has thousands of items to enter, and wanted to know if there is someway to expedite his workflow, maybe by avoiding to click ‘Save as copy’ everytime he scans a new barcode.

I suggested the following code to him, to be placed in the hooks/tablename-dv.js (where tablename is the name of the concerned table — create that file if it doesn’t already exist).

Change fieldname in line 2 above to the actual name of the barcode field. The above code checks if the concerned barcode field has been changed. If it has been, the ‘Save as copy’ button (using the #insert selector) is clicked.

Programmatically change the value of an image field in the detail view

In the detail view, if you have some ajax request running in the background that should update your detail view form (or if you do this in the tablename_dv hook), you might already know that you can change the data of a normal text field using this JavaScript code:

But if your field is an image field, the above code won’t work. Try this instead:

Of course, change fieldname in the above code to the actual field name.

Creating an ON/OFF switch using bootstrap and jQuery

In some projects that I work on, I need a quick way of adding some cool-looking user-friendly on/off switch. Checkboxes are ugly! And I don’t want to add a new component/plugin to the already loaded pages. So, I wrote some quick code snippet for a switch based on Bootstrap 3 and jQuery. Here is the HTML code:

And here is the jQuery code (should be placed inside any jQuery DOM loaded block):

Here is what the output looks like when the page loads (the default state is locked):

And when the switch is clicked, here is how it looks like (unlocked):

Here is a demo of the switch in action. Have fun!

Prepare a LAMP web development server on Amazon EC2

Here is a quick checklist for setting up LAMP development server on Amazon EC2. I used a standard Amazon Linux AMI on a T2.micro instance, which costs about $9/month at the time of writing this.

  1. Edit the DNS zone for your domain to add an A record for a sub-domain to point to the public IP of the instance. I recommend setting the TTL to 60 for fastest updates of IP later if necessary.
  2. Use putty or ssh to log in to the instance.
  3. Follow the instructions at https://gist.github.com/aronwoost/1105007
  4. Test the server by visiting it on your browser using either the public IP or the url.
  5. Prepare web directory: A useful guide for permissions. The Apache user is “apache”, member of group “apache”.
  6. Prepare HTTPS: for Amazon Linux, this is already set up … but for more info, see http://wiki.centos.org/HowTos/Https
  7. Install Codiad (an online code editor/IDE — this enables you to write your code anywhere rather than being bound to your workstation and your desk):
  8. Browse to servername/edit to set up Codiad. Once done, it’s now ready to use. from that same location.

Tip: need to set up multiple virtual hosts on the server? Amazon Linux is based on CentOS. Here is a step-by-step guide on setting up virtual hosts on CentOS. A similar guide for SSL virtual hosts.

How to paginate a database query in PHP — the no-frameworks way

OK, I admit! Every time I have to write similar code I get stuck rethinking it — every time … If I wasted 10 minutes thinking of it every time, and I did so for 100 times, then I’ve already wasted more than 2 working days in the last 12 years doing it! I guess it’s time to stop that loss!

So, the issue I’m talking about is when having a web page (or a web service, or a command line utility, or any other interface) that lists a set of records from a database, and then the user wants to retrieve the next set of records, this is called pagination. If I’m not explaining it clearly, feel free to look it up in Wikipedia.

So, how should pagination be handled in the server side? Here is the most recent way I did it … If you have a better suggestion, feel free to post your comment below. I’ll be using this from now, and update it as necessary:

The tricky part that wastes most of the time in the above code is line 12 .. that is, figuring out the formula for calculating the offset, or the number of records to skip from the query .. it’s a simple one, I know, but if you’re like me and get confused by the zero-one worlds … it could drag your mind for some time! So, I hope this would save you 10 minutes in your next coding adventure.

Making sure a PHP script is accessible only through being included

Let’s say we have a PHP script that we don’t want users to access directly by calling it through their browser. We want that script to be included in other scripts but not accessed by typing its URL.

A lot of sites suggest saving such scripts into a directory outside the document root. This would do, but in some cases might not be an optimal solution. For example, you might need to be able to easily distribute your PHP application in an archive that the user can easily extract into some folder on his site. Telling your users to move some files to a folder outside their web root adds a lot of inconvenience and confusion. And you’ll probably add a lot of support overhead due to this approach.

Another method I prefer is to add code at the top of the script that checks if it is included in another file or being accessed directly. A good way of doing this is using the get_included_files PHP function. Here is what I use at the top of any such scripts:

The first item in the array returned by get_included_files is the path of the script called directly by the user. The following items in the array are any other scripts that were included afterwards. So, the above line of code makes sure the current script is not the first item in that array.