Create a blog with JQuery Mobile and PHP

Post to Twitter

With the recent “alpha 1” release of JQuery Mobile. I decided to learn about this new framework and create a simple mobile blog. With this new framework we can target several platforms easily:

  • Apple iOS: iPhone, iPod Touch, iPad (all versions)
  • Android: all devices (all versions)
  • Blackberry Torch (version 6)
  • Palm WebOS Pre, Pixi
  • Nokia N900
  • Let’s start…

    Update – Nov. 11, 2010: Code updated to reflect changes in JQuery Mobile Alpha 2.

    Update – April 5, 2011: Code updated to reflect changes in JQuery Mobile Alpha 4. Fixed capitalization in code for “posts” table.

    I built this using PHP, Apache 2, and of course JQuery Mobile. To keep it simple I’m only using two PHP files, the bulk of the code is in a file called index.php. The code to insert new posts is in a file called newpost.php. Please keep in mind this code was put together quickly as a demo more than anything so if you use this as a base for a future projects you need to validate the data, ensure strings lengths are of acceptable ranges, and much more, etc.

    The nice thing about working with JQuery Mobile is that I was able to use Google Chrome to easily debug and view my work as I proceeded. I found IE 7 though to be problematic. I didn’t test any other browsers.

    The MySQL script for the database is very straight forward:

    CREATE DATABASE MobileBlog;
    
    CREATE TABLE IF NOT EXISTS `posts` (
      `post_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `post_title` varchar(100) NOT NULL,
      `post_content` text NOT NULL,
      `post_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
      PRIMARY KEY (`post_id`)
    ) ENGINE=MyISAM
    

    Simply a place to put the blog post’s title, content and the time it was created.

    With the database in place let’s move onto the HTML and JQuery code.

    The header is simple enough with a call to grab the JQuery files we will need:

    <!DOCTYPE html>
    <html>
    	<head>
    	<title>MobileBlog</title>
    	<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />
    	<script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
    	<script src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>
    </head>
    

    The nice thing is you now have all the power of JQuery available to you in the mobile framework.

    Laying out the initial view is very straight forward and you can read more about it as well as grab a starter template here.

    <div data-role="page" id="indexPage">
        <div data-role="header">
            <h1>Welcome!</h1>
        </div>
        <div data-role="content">
            <ul data-role="listview">
                <li>
                    <a href="#createNewPostPage">Create New Post</a>
                </li>
                <li>
                    <a href="#readBlogPage">Read Blog</a>
                </li>
                <li>
                    <a href="#aboutMobileBlogPage">About MobileBlog</a>
                </li>
            </ul>
        </div>
    
        <div data-role="footer">
            <h1>- MobileBlog -</h1>
        </div>
    </div>
    

    Typical structure once the container is in place looks like this:

    <div data-role="header">...</div>
    <div data-role="content">...</div>
    <div data-role="footer">...</div>
    

    The first component I used was a List View and you need to get familiar with these since they are going to be a primary component when working with this mobile framework.

    I then laid out a few more pages. One to create new posts, one to read them, and an about page. In the case of creating a new post I used Ajax to call the newpost.php file which looks like this:

    <?php
    	try
    	{
    		$connection = mysql_connect("localhost","mobileblog","password");
    		mysql_select_db("MobileBlog", $connection);
    		// Note: You need to verify the data coming in isn't harmful, this SQL pretty much puts anything into the database so make sure to change this!
    		$postTitle = mysql_real_escape_string($_POST[postTitle]);
    		$postContent = mysql_real_escape_string($_POST[postContent]);
    
    		mysql_query("INSERT INTO posts (post_title, post_content) VALUES ('$postTitle', '$postContent')");
    		mysql_close($connection);
    		echo "SUCCESS";
    	}
    	catch(Exception $e)
    	{
    		echo $e->getMessage();
    		// Note: Log the error or something
    	}
    ?>
    

    Very simple code and directly to the point. If the insert works a string is passed back as “SUCCESS” otherwise the error is passed back. Obviously in a production environment you would want to hide the true error from the user and dump a more friendly message to them.

    The Ajax code looks like this to make the save:

    $(document).ready(function() {
    	$("#submit").click(function(){
    
    		var formData = $("#newPostForm").serialize();
    
    		$.ajax({
    			type: "POST",
    			url: "/mobile/newpost.php",
    			cache: false,
    			data: formData,
    			success: onSuccess
    		});
    
    		return false;
    	});
    
    	$("#cancel").click(function(){
    		resetTextFields();
    	});
    
    	$("#refresh").click(function(){
    		location.reload();
    	});
    });
    

    On a successful Ajax call this code is called:

    function onSuccess(data, status)
    {
    	resetTextFields();
    	// Notify the user the new post was saved
    	$("#notification").fadeIn(2000);
    	data = $.trim(data);
    	if(data == "SUCCESS")
    	{
    		$("#notification").css("background-color", "#ffff00");
    		$("#notification").text("The post was saved");
    	}
    	else
    	{
    		$("#notification").css("background-color", "#ff0000");
    		$("#notification").text(data);
    	}
    	$("#notification").fadeOut(5000);
    }
    

    To read the blogs posts I simply put the PHP code directly in rather than make an Ajax call and populate it as needed. I also added a refresh button since any new posts added after the site loads won’t show up automatically. Ideally you would want to load the post titles into a List View and then link to the full article and load just that data since loading everything at once could get very slow if you are loading a lot of posts with content. In fact on a mobile device you could easily frustrate the user so keep this in mind. Its really about speed with mobile web apps.

    The code looks like this to read the blog posts:

    <div data-role="page" id="readBlogPage">
        <div data-role="header">
            <h1>Read Blog</h1>
        </div>
        <div data-role="content">
            <button data-theme="b" data-role="button" data-iconpos="left" id="refresh" type="button" data-icon="refresh">Refresh</button>
            <ul data-role="listview" data-theme="d" data-inset="true">
                <!-- Note: You should really display the blog post articles and then link to the full article, since this is a simple demo
                    I'm just loading all the articles, obviously this is not a production quality blog since this could take a long
                    time to load all the articles and on a mobile device speed counts.  Also, this data won't automatically refresh on a new post insert.
                -->
                <?php
                    try
                    {
                        $connection = mysql_connect("localhost","mobileblog","password");
                        mysql_select_db("MobileBlog", $connection);
                        $result = mysql_query("SELECT * FROM posts");
    
                        while($row = mysql_fetch_array($result))
                        {
                            echo "<li><h2>" . $row['post_title'] . "</h2>" . $row['post_content'] . "<p class='ui-li-aside'>" . $row['post_date'] . "<strong></p>";
                        }
    
                        mysql_close($connection);
                    }
                    catch(Exception $e)
                    {
                        echo $e->getMessage();
                    }
                ?>
            </ul>
        </div>
    
        <div data-role="footer">
            <h1>- MobileBlog -</h1>
        </div>
    </div>
    

    The final code looks like this:

    <!DOCTYPE html>
    <html>
    	<head>
    	<title>MobileBlog</title>
    	<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.css" />
    	<script src="http://code.jquery.com/jquery-1.5.2.min.js"></script>
    	<script src="http://code.jquery.com/mobile/1.0a4/jquery.mobile-1.0a4.min.js"></script>
    </head>
    
    <body>
    
    	<script type="text/javascript">
    		function resetTextFields()
    		{
    			$("#postTitle").val("");
    			$("#postContent").val("");
    		}
    
    		function onSuccess(data, status)
    		{
    			resetTextFields();
    			// Notify the user the new post was saved
    			$("#notification").fadeIn(2000);
    			data = $.trim(data);
    			if(data == "SUCCESS")
    			{
    				$("#notification").css("background-color", "#ffff00");
    				$("#notification").text("The post was saved");
    			}
    			else
    			{
    				$("#notification").css("background-color", "#ff0000");
    				$("#notification").text(data);
    			}
    			$("#notification").fadeOut(5000);
    		}
    
    		$(document).ready(function() {
    			$("#submit").click(function(){
    
    				var formData = $("#newPostForm").serialize();
    
    				$.ajax({
    					type: "POST",
    					url: "/mobile/newpost.php",
    					cache: false,
    					data: formData,
    					success: onSuccess
    				});
    
    				return false;
    		  	});
    
    			$("#cancel").click(function(){
    				resetTextFields();
    		  	});
    
    			$("#refresh").click(function(){
    				location.reload();
    		  	});
    		});
    
    	</script>
    
        <!-- indexPage -->
        <div data-role="page" id="indexPage">
            <div data-role="header">
                <h1>Welcome!</h1>
            </div>
            <div data-role="content">
                <ul data-role="listview">
                    <li>
    			<a href="#createNewPostPage">Create New Post</a>
                    </li>
                    <li>
    			<a href="#readBlogPage">Read Blog</a>
                    </li>
                    <li>
    			<a href="#aboutMobileBlogPage">About MobileBlog</a>
                    </li>
                </ul>
            </div>
    
            <div data-role="footer">
            	<h1>- MobileBlog -</h1>
            </div>
        </div>
    
    
        <!-- createNewPostPage -->
        <div data-role="page" id="createNewPostPage">
            <div data-role="header">
                <h1>Create New Post</h1>
            </div>
    
            <div data-role="content">
                <div data-role="content">
                	<form id="newPostForm">
                        <div data-role="fieldcontain">
                            <label for="postTitle"><strong>Post Title:</strong></label>
                            <input type="text" name="postTitle" id="postTitle" value=""  />
    
                            <label for="postContent"><strong>Post Content:</strong></label>
                            <textarea name="postContent" id="postContent"></textarea>
    
                            <fieldset class="ui-grid-a">
                                <div class="ui-block-a"><a href="#indexPage" id="cancel" data-role="button">Cancel</a></div>
                                <div class="ui-block-b"><button data-theme="b" id="submit" type="submit">Submit</button></div>
                            </fieldset>
    						<h3 id="notification"></h3>
                        </div>
                    </form>
            	</div>
        	</div>
    
            <div data-role="footer">
                <h1>- MobileBlog -</h1>
            </div>
        </div>
    
        <!-- readBlogPage -->
        <div data-role="page" id="readBlogPage">
            <div data-role="header">
                <h1>Read Blog</h1>
            </div>
            <div data-role="content">
    			<button data-theme="b" data-role="button" data-iconpos="left" id="refresh" type="button" data-icon="refresh">Refresh</button>
                <ul data-role="listview" data-theme="d" data-inset="true">
    				<!-- Note: You should really display the blog post articles and then link to the full article, since this is a simple demo
    					I'm just loading all the articles, obviously this is not a production quality blog since this could take a long
    					time to load all the articles and on a mobile device speed counts.  Also, this data won't automatically refresh on a new post insert.
    				-->
    				<?php
    					try
    					{
    						$connection = mysql_connect("localhost","mobileblog","password");
    						mysql_select_db("MobileBlog", $connection);
    						$result = mysql_query("SELECT * FROM posts");
    
    						while($row = mysql_fetch_array($result))
    						{
    							echo "<li><h2>" . $row['post_title'] . "</h2>" . $row['post_content'] . "<p class='ui-li-aside'>" . $row['post_date'] . "<strong></p>";
    						}
    
    						mysql_close($connection);
    					}
    					catch(Exception $e)
    					{
    						echo $e->getMessage();
    					}
    				?>
                </ul>
            </div>
    
            <div data-role="footer">
            	<h1>- MobileBlog -</h1>
            </div>
        </div>
    
        <!-- aboutMobileBlogPage -->
        <div data-role="page" id="aboutMobileBlogPage">
            <div data-role="header">
                <h1>About MobileBlog</h1>
            </div>
    
            <div data-role="content">
                <div data-role="content">
                    <div data-role="fieldcontain">
                        <p><a href="http://giantflyingsaucer.com/blog/?p=1856">MobileBlog</a></p>
                        <p>Created by: <a href="http://twitter.com/chadlung">Chad Lung</a></p>
                        <p>Powered by: <a href="http://jquerymobile.com">JQuery Mobile</a></p>
                	</div>
            	</div>
        	</div>
    
            <div data-role="footer">
                <h1>- MobileBlog -</h1>
            </div>
        </div>
    
    </body>
    </html>
    

    I then used the Android Emulator to view MobileBlog running using this address: http://10.0.2.2/mobile – Keep in mind you cannot use “localhost” in the emulator.

    Here are some screenshots of MobileBlog running:

    Post to Twitter

    This entry was posted in JavaScript, Mobile, PHP. Bookmark the permalink.

    21 Responses to Create a blog with JQuery Mobile and PHP

    1. Sam says:

      Thanks a lot for this post. I am alo testing JQuery Mobile, and I plan to use it in the future. But for now, I think Sencha Touch is more advanced, but it’s not the same philosophy (JQuery is DOM centric). And this is just an Alpha release.
      I would like to play with your code. Is your project is hosted on github or somewhere ?

    2. Chad Lung says:

      @Sam,

      The full code is in this article. I haven’t had a chance to setup Git on my new computer yet so I haven’t been able to load it into my GutHub account.

      Chad

    3. iphone says:

      this is too good site to view

    4. ciro says:

      hi, thanks for tutorial. btw, where is index.php code?

    5. David says:

      Thanks nice tutorial i will be experimenting with the code

    6. rob-ot says:

      very clear and very useful !! tnx.

    7. Pingback: Re : Study Material - Jquery Home

    8. Viswanadh says:

      Hi,

      Very gud example , jus started playing around with JQM.

      I saw a flaw in ur code , its working only if i replace the line

      ‘ Submit’

      with

      Submit

      Can u please tell me why the submit is not working ? Please reply ASAP.

    9. Thanks for the great demo. We’re looking at using jQuery mobile for our web app. Thanks!

    10. Pingback: Create a basic layout using JQuery Mobile, ASP.NET MVC 2 and HTML5

    11. Pingback: Create a blog with JQuery Mobile and ASP.NET MVC 3 with C#

    12. hi, thanks for tutorial…

    13. wHiTeHaT says:

      Anyone now a good authentication tutorial to use with php and jqm?

    14. justmyfreak says:

      Very nice tutorial, It working on me but I got no notification after saving my post..
      Still try to figuring this out..
      😀

    15. John says:

      Thanks for great tuttorial – I can read from data inserted manually into the db but I get an error when submitting – code hinting syas ther is an error in your newpost.php code but I can’t spot – is ther any other download link?

    16. Chad Lung says:

      @John,

      Double check your code and turn on any JavaScript tools you have in the browser. I’ve used the code above and it worked.

      Chad

    17. jhon says:

      hi, this can embed to a iphone app native with phonegap?

    18. Chad Lung says:

      @jhon,

      You could embed this into a native app but you would have to keep in mind the AJAX calls would be going out to some server so you would need to check that the device your running on has granted permission for your app to make those calls and that the device has network connectivity each time you make a network call, etc.

      Personally I wouldn’t make this kind of app into a (mobile) native one, I’d keep it purely on the web.

      Chad

    19. Mark says:

      Thanks for the useful article. With the latest JQM libraries (RC1) the ‘Back’ buttons do not appear in the header of the 2 pages (createNewPostPage and readBlogPage). To get the ‘Back’ button to automatically appear, simply add data-add-back-btn=”true” to the 3 pages, so you get:

      <div data-role="page" id="indexPage" data-add-back-btn="true">
      <div data-role="page" id="createNewPostPage" data-add-back-btn="true">
      <div data-role="page" id="readBlogPage" data-add-back-btn="true"
      

      Cheers, Mark
      Sydney, Australia

    20. Chad Lung says:

      @Mark,

      Thanks for the update. A lot has changed in JQM since I wrote this article.

      Chad

    21. Gaetan says:

      Hi,
      Once a record is added, I would like to automatically go back to “#indexPage”.
      I have tried “return true;” instead of “return false;”.
      Unfortunately, it then goes back too quickly to “#indexPage” … There is then not enough time to view the “notification” message.
      Could someone help ?
      Thanks

    Comments are closed.