Simple Guest Book With Sencha Touch and PHP

January 7th, 2011 by aditia rahman / 45 Comments  

     

A Guest Book application is one of the oldest tutorial in programming, I remember when I first learning PHP, guestbook simple guestbook application give me a good example to show how the the PHP script communicating with the html interface including the javascript. Now I want port it in Sencha Touch interface, this example will be very simple there no validation, only insert data and show existing data.

Download Source

Here is the table that I prepared for this example

CREATE TABLE IF NOT EXISTS `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `email` varchar(50) NOT NULL,
  `url` varchar(100) NOT NULL,
  `message` varchar(255) NOT NULL,
  `date_entry` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Main html code for the layout, this html is inside the body, sure you must include the sencha touch files by yourself

</p>
<div id="guests" class="x-hidden-display">
    <tpl for="."></p>
<div class="detail">
<div class="clear"">
                <label class="label2 topleft">Sender</label>
                <span class="span2 topright">{name}</span>
            </div>
<div class="clear"">
                <label class="label2">Url</label>
                <span class="span2">{url}</span>
            </div>
<div class="clear"">
                <label class="label2 bottomleft">Message</label>
                <span class="span2 bottomright">{message}</span>
            </div>
<div class="clear"></div>
</div>
<p>    </tpl>
</div>
<p>

The main sencha touch component used in this example is TabPanel, there two tab, first is the form and second for displaying data, you can see above there is a <tpl> tag, this is where the existing data will be displayed,, so the component will use XTemplate, now here is the sencha touch code, that I always create separately

Ext.setup({
    glossOnIcon: false,
    onReady: function() {</p>
<p>        var tpl = Ext.XTemplate.from('guests');</p>
<p>		Ext.regModel('User', {
            fields: [
                { name: 'id',       type: 'string' },
                { name: 'name',     type: 'string' },
                { name: 'email',    type: 'string' },
                { name: 'url',      type: 'string' },
                { name: 'message',  type: 'string' }
            ]
        });</p>
<p>		var formBase =  new Ext.form.FormPanel({
            scroll: 'vertical',
            url   : 'server.php',
            standardSubmit : false,
            title: 'Guestbook',
            items: [{
                xtype: 'fieldset',
                title: '',
                instructions: 'Please complete the information.',
                defaults: {
                    labelAlign: 'left',
                    labelWidth: '40%'
                },
                items: [
                    {
                    xtype: 'textfield',
                    name : 'name',
                    label: 'Name',
                    useClearIcon: true,
                    autoCapitalize : false
                }, {
                    xtype: 'emailfield',
                    name : 'email',
                    label: 'Email',
                    placeHolder: 'me@yurl.com',
                    useClearIcon: true
                }, {
                    xtype: 'urlfield',
                    name : 'url',
                    label: 'Url',
                    placeHolder: 'http://yurl.com',
                    useClearIcon: true
                }, {
                    xtype: 'textareafield',
                    name : 'message',
                    label: 'Message',
                    maxLength: 50,
                    maxRows: 5,
                    height: 120
                }]
            }],</p>
<p>            dockedItems: [{
                xtype: 'toolbar',
                dock: 'bottom',
                items: [{
                    xtype: 'spacer'
                }, {
                    text: 'Reset',
                    handler: function() {
                        formBase.reset();
                    }
                }, {
                    text: 'Save',
                    ui: 'confirm',
                    handler: function() {
                        formBase.submit({
                            waitMsg: {
                                message:'Submitting',
                                cls : 'demos-loading'
                            },
                            success: function(e) {
                                showCenteredOverlay();
                                formBase.reset();
                            }
                        });
                    }
                }]
            }]
        });</p>
<p>        var overlayTb = new Ext.Toolbar({
            dock: 'top'
        });</p>
<p>        var overlay = new Ext.Panel({
            floating: true,
            modal: true,
            centered: true,
            width: Ext.is.Phone ? 260 : 400,
            height: 60,
            dockedItems: overlayTb
        });</p>
<p>        var showCenteredOverlay = function() {
            overlayTb.setTitle('Data Inserted');
            overlay.show();
        };</p>
<p>        function showRecent() {
            Ext.Ajax.request({
                url: 'server.php?action=get',
                success: function(e) {
                    var obj = Ext.util.JSON.decode(e.responseText);
                    var guests = obj.guests;
                    if (guests) {
                        var html = tpl.applyTemplate(guests);
                        Ext.getCmp('recentTab').update(html);
                    }
                }
            });
        }</p>
<p>        new Ext.TabPanel({
            fullscreen: true,
            type: 'dark',
            sortable: true,
            items: [formBase, {
                id: 'recentTab',
                title: 'Recent Guests',
                html: '2',
                scroll: 'vertical',
                cls: 'recent',
                listeners: {
                    'beforeshow': showRecent
                }
            }]
        });
    }
});

Well that really simple, after user submitted the form, all the form field back to it’s default value, and the panel I used in here as overlay as the message box, working with form submit, the ajax request, server callback in sencha touch is very similar from extjs. And the beforeshow event binded to the second tab, it will load the data from the server, and to viewing data I only use Xtemplate which mean the data displaying in plain html format.

The PHP code, using the PDO

<?php $dsn = 'mysql:dbname=senchatouch_guestbook;host=127.0.0.1'; $user = 'root'; $password = ''; try {     $dbh = new PDO($dsn, $user, $password);     if (isset($_GET['action']) && $_GET['action'] == "get") {         $sql = "SELECT * FROM messages";         $guests = array();         foreach ($dbh->query($sql) as $row)
        {
            $guests[] = array(
                'id' => $row['id'],
                'name' => $row['name'],
                'email' => $row['email'],
                'url' => $row['url'],
                'message' => $row['message'],
                'date' => $row['date_entry']
            );
        }
        echo json_encode(array('success' => true, 'guests' => $guests));
    } else {
        $dbh->exec("INSERT INTO messages VALUES ('', '".$_POST['name']."',
            '".$_POST['email']."', '".$_POST['url']."', '".$_POST['message']."',
            '".date("Y-m-d H:i:s")."')");</p>
<p>        echo '{"success":true, "msg":'.json_encode('Data Inserted').'}';
    }
} catch (PDOException $e) {
    echo 'Connection failed: ' . $e->getMessage();
}</p>
<p>?>

See there is no validation or something in PHP code, I just want to make it fast, and lastly the CSS code

.recent {
    color: #333;
}
.detail {
    background: #d3d3d3;
    border-bottom: 1px solid #c3c3c3;
    padding: 5px;
    font-size: 14px;
    font-weight: bold;
}
.label2 {
    background: #f3f3f3;
    display: block;
    padding: 10px;
    width: 100px;
    float: left;
    border-bottom: 2px solid #f3f3f3;
}
.span2 {
    display: block;
    padding: 10px;
    background: #666;
    color: #fff;
    float: left;
    width: 210px;
    border-bottom: 2px solid #f3f3f3;
}
.bottomleft {
    -webkit-border-bottom-left-radius: .5em;
}
.bottomright {
    -webkit-border-bottom-right-radius: .5em;
}
.topright {
    -webkit-border-top-right-radius: .5em;
}
.topleft {
    -webkit-border-top-left-radius: .5em;
}
.clear {
    clear: both;
}

And here the download link and what the screen capture look like, I tested on Android SDK version 2.1

Download Source

Sencha Touch Guest Book Data Submitted Capture

Sencha Touch Guest Book View Data Capture

        submit to reddit Delicious

45 Comments Leave a Comment Subscribe RSS

Leave a Comment