Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials - Front-End Web Development

341 Articles
article-image-one-page-application-development
Packt
12 Sep 2013
10 min read
Save for later

One-page Application Development

Packt
12 Sep 2013
10 min read
(For more resources related to this topic, see here.) Model-View-Controller or MVC Model-View-Controller ( MVC ) is a heavily used design pattern in programming. A design pattern is essentially a reusable solution that solves common problems in programming. For example, the Namespace and Immediately-Invoked Function Expressions are patterns that are used throughout this article. MVC is another pattern to help solve the issue of separating the presentation and data layers. It helps us keep our markup and styling outside of the JavaScript; keeping our code organized, clean, and manageable—all essential requirements for creating one-page-applications. So let's briefly discuss the several parts of MVC, starting with models. Models A model is a description of an object, containing the attributes and methods that relate to it. Think of what makes up a song, for example the track's title, artist, album, year, duration, and more. In its essence, a model is a blueprint of your data. Views The view is a physical representation of the model. It essentially displays the appropriate attributes of the model to the user, the markup and styles used on the page. Accordingly, we use templates to populate our views with the data provided. Controllers Controllers are the mediators between the model and the view. The controller accepts actions and communicates information between the model and the view if necessary. For example, a user can edit properties on a model; when this is done the controller tells the View to update according to the user's updated information. Relationships The relationship established in an MVC application is critical to sticking with the design pattern. In MVC, theoretically, the model and view never speak with each other. Instead the controller does all the work; it describes an action, and when that action is called either the model, view, or both update accordingly. This type of relationship is established in the following diagram: This diagram explains a traditional MVC structure, especially that the communication between the controller and model is two-way; the controller can send data to/from the model and vice versa for the view. However, the view and model never communicate, and there's a good reason for that. We want to make sure our logic is contained appropriately; therefore, if we wanted to delegate events properly for user actions, then that code would go into the view. However, if we wanted to have utility methods, such as a getName method that combines a user's first name and last name appropriately, that code would be contained within a user model. Lastly, any sort of action that pertains to retrieving and displaying data would be contained in the controller. Theoretically, this pattern helps us keep our code organized, clean, and efficient. In many cases this pattern can be directly applied, especially in many backend languages like Ruby, PHP, and Java. However, when we start applying this strictly to the frontend, we are confronted with many structural challenges. At the same time, we need this structure to create solid one-page-applications. The following sections will introduce you to the libraries we will use to solve these issues and more. Introduction to Underscore.js One of the libraries we will be utilizing in our sample application will be Underscore.js. Underscore has become extremely popular in the last couple of years due to the many utility methods it provides developers without extending built-in JavaScript objects, such as String, Array, or Object. While it provides many useful methods, the suite has also been optimized and tested across many of the most popular web browsers, including Internet Explorer. For these reasons, the community has widely adopted this library and continually supported it. Implementation Underscore is extremely easy to implement in our applications. In order to get Underscore going, all we need to do is include it on our page like so: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <title></title> <meta name="description" content=""> <meta name="viewport" content="width=device-width"> </head> <body> <script src = "//ajax.googleapis.com/ajax/libs/jquery/ 1.9.0/jquery.min.js"></script> <script src = "//cdnjs.cloudflare.com/ajax/libs/underscore.js/ 1.4.3/underscore-min.js"></script> </body> </html> Once we include Underscore on our page, we have access to the library at the global scope using the _ object. We can then access any of the utility methods provided by the library by doing _.methodName. You can review all of the methods provided by Underscore online (http://underscorejs.org/), where all methods are documented and contain samples of their implementation. For now, let's briefly review some of the methods we'll be using in our application. _.extend The extend method in Underscore is very similar to the extend method we have been using from Zepto (http://zeptojs.com/#$.extend). If we look at the documentation provided on Underscore's website (http://underscorejs.org/#extend), we can see that it takes multiple objects with the first parameter being the destination object that gets returned once all objects are combined. Copy all of the properties in the source objects over to the destination object, and return the destination object. It's in-order, so the last source will override properties of the same name in previous arguments. As an example, we can take a Song object and create an instance of it while also overriding its default attributes. This can be seen in the following example: <script> function Song() { this.track = "Track Title"; this.duration = 215; this.album = "Track Album"; }; var Sample = _.extend(new Song(), { 'track': 'Sample Title', 'duration': 0, 'album': 'Sample Album' }); </script> If we log out the Sample object, we'll notice that it has inherited from the Song constructor and overridden the default attributes track, duration, and album. Although we can improve the performance of inheritance using traditional JavaScript, using an extend method helps us focus on delivery. We'll look at how we can utilize this method to create a base architecture within our sample application later on in the article. _.each The each method is extremely helpful when we want to iterate over an Array or Object. In fact this is another method that we can find in Zepto and other popular libraries like jQuery. Although each library's implementation and performance is a little different, we'll be using Underscore's _.each method, so that we can stick within our application's architecture without introducing new dependencies. As per Underscore's documentation (http://underscorejs.org/#each), the use of _.each is similar to other implementations: Iterates over a list of elements, yielding each in turn to an iterator function. The iterator is bound to the context object, if one is passed. Each invocation of iterator is called with three arguments: (element, index, list). If list is a JavaScript object, iterator's arguments will be (value, key, list). Delegates to the native forEach function if it exists. Let's take a look at an example of using _.each with the code we created in the previous section. We'll loop through the instance of Sample and log out the object's properties, including track, duration, and album. Because Underscore's implementation allows us to loop through an Object, just as easily as an Array, we can use this method to iterate over our Sample object's properties: <script> function Song() { this.track = "Track Title"; this.duration = 215; this.album = "Track Album"; }; var Sample = _.extend(new Song(), { 'track': 'Sample Title', 'duration': 0, 'album': 'Sample Album' }); _.each(Sample, function(value, key, list){ console.log(key + ": " + value); }); </script> The output from our log should look something like this: track: Sample Title duration: 0 album: Sample Album As you can see, it's extremely easy to use Underscore's each method with arrays and objects. In our sample application, we'll use this method to loop through an array of objects to populate our page, but for now let's review one last important method we'll be using from Underscore's library. _.template Underscore has made it extremely easy for us to integrate templating into our applications. Out of the box, Underscore comes with a simple templating engine that can be customized for our purposes. In fact, it can also precompile your templates for easy debugging. Because Underscore's templating can interpolate variables, we can utilize it to dynamically change the page as we wish. The documentation provided by Underscore (http://underscorejs.org/#template) helps explain the different options we have when using templates: Compiles JavaScript templates into functions that can be evaluated for rendering. Useful for rendering complicated bits of HTML from JSON data sources. Template functions can both interpolate variables, using <%= … %>, as well as execute arbitrary JavaScript code, with <% … %>. If you wish to interpolate a value, and have it be HTML-escaped, use <%- … %>. When you evaluate a template function, pass in a data object that has properties corresponding to the template's free variables. If you're writing a one-off, you can pass the data object as the second parameter to template in order to render immediately instead of returning a template function. Templating on the frontend can be difficult to understand at first, after all we were used to querying a backend, using AJAX, and retrieving markup that would then be rendered on the page. Today, best practices dictate we use RESTful APIs that send and retrieve data. So, theoretically, you should be working with data that is properly formed and can be interpolated. But where do our templates live, if not on the backend? Easily, in our markup: <script type="tmpl/sample" id="sample-song"> <section> <header> <h1><%= track %></h1> <strong><%= album %></strong> </header> </section> </script> Because the preceding script has an identified type for the browser, the browser avoids reading the contents inside this script. And because we can still target this using the ID, we can pick up the contents and then interpolate it with data using Underscore's template method: <script> function Song() { this.track = "Track Title"; this.duration = 215; this.album = "Track Album"; }; var Sample = _.extend(new Song(), { 'track': 'Sample Title', 'duration': 0, 'album': 'Sample Album' }); var template = _.template(Zepto('#sample-song').html(), Sample); Zepto(document.body).prepend(template); </script> The result of running the page, would be the following markup: <body> <section> <header> <h1>Sample Title</h1> <strong>Sample Album</strong> </header> </section> <!-- scripts and template go here --> </body> As you can see, the content from within the template would be prepended to the body and the data interpolated, displaying the properties we wish to display; in this case the title and album name of the song. If this is a bit difficult to understand, don't worry about it too much, I myself had a lot of trouble trying to pick up the concept when the industry started moving into one-page applications that ran off raw data (JSON). For now, these are the methods we'll be using consistently within the sample application to be built in this article. It is encouraged that you experiment with the Underscore.js library to discover some of the more advanced features that make your life easier, such as _.map, _.reduce, _.indexOf, _.debounce, and _.clone. However, let's move on to Backbone.js and how this library will be used to create our application.
Read more
  • 0
  • 0
  • 1861

article-image-setting-single-width-column-system-simple
Packt
05 Sep 2013
3 min read
Save for later

Setting up a single-width column system (Simple)

Packt
05 Sep 2013
3 min read
(For more resources related to this topic, see here.) Getting ready To perform the steps listed in this article, we will need a text editor, a browser, and a copy of the Masonry plugin. Any text editor will do, but my browser of choice is Google Chrome, as the V8 JavaScript engine that ships with it generally performs better and supports CSS3 transitions, and as a result we see smoother animations when resizing the browser window. We need to make sure we have a copy of the most recent version of Masonry, which was Version 2.1.08 at the time of writing this article. This version is compatible with the most recent version of jQuery, which is Version 1.9.1. A production copy of Masonry can be found on the GitHub repository at the following address: https://github.com/desandro/masonry/blob/master/jquery.masonry.min.js For jQuery, we will be using a content delivery network (CDN) for ease of development. Open the basic single-column HTML file to follow along. You can download this file from the following location: http://www.packtpub.com/sites/default/files/downloads/1-single-column.zip How to do it... Set up the styling for the masonry-item class with the proper width, padding, and margins. We want our items to have a total width of 200 pixels, including the padding and margins. <style> .masonry-item { background: #FFA500; float: left; margin: 5px; padding: 5px; width: 180px; }</style> Set up the HTML structure on which you are going to use Masonry. At a minimum, we need a tagged Masonry container with the elements inside tagged as Masonry items. <div id='masonry-container'> <div class='masonry-item '> Maecenas faucibus mollis interdum. </div> <div class='masonry-item '> Maecenas faucibus mollis interdum. Donec sed odio dui. Nullamquis risus eget urna mollis ornare vel eu leo. Vestibulum idligula porta felis euismod semper. </div> <div class='masonry-item '> Nullam quis risus eget urna mollis ornare vel eu leo. Crasjusto odio, dapibus ac facilisis in, egestas eget quam. Aeneaneu leo quam. Pellentesque ornare sem lacinia quam venenatisvestibulum. </div></div> All Masonry options need not be included, but it is recommended (by David DeSandro, the creator of Masonry) to set itemSelector for single-column usage. We will be setting this every time we use Masonry. <script> $(function() { $('#masonry-container').masonry({ // options itemSelector : '.masonry-item', }); });</script> How it works... Using jQuery, we select our Masonry container and use the itemSelector option to select the elements that will be affected by Masonry. The size of the columns will be determined by the CSS code. Using the box model, we set our Masonry items to a width of 90 px (80-px wide, with a 5-px padding all around the item). The margin is our gutter between elements, which is also 5-px wide. With this setup, we can con firm that we have built the basic single-column grid system, with each column being 100-px wide. The end result should look like the following screenshot: Summary This article showed you how to set up the very basic Masonry single-width column system around which Masonry revolves. Resources for Article : Further resources on this subject: Designing Site Layouts in Inkscape [Article] New features in Domino Designer 8.5 [Article] Using jQuery and jQueryUI Widget Factory plugins with RequireJS [Article]
Read more
  • 0
  • 0
  • 1852

article-image-portal-and-drag-and-drop-features-ext-gwt
Packt
29 Nov 2010
5 min read
Save for later

Portal and Drag-and-Drop Features of Ext GWT

Packt
29 Nov 2010
5 min read
  Ext GWT 2.0: Beginner's Guide Portlet class The Portlet class extends ContentPanel to provide a special type of panel that can be repositioned in the Viewport by the user with a Portal container. It may appear similar to a window in a desktop application. Creating a Portlet is similar to creating other containers. This code: Portlet portlet = new Portlet(); portlet.setHeight(150); portlet.setHeading("Example Portlet"); creates a Portlet like this: A Portlet can be excluded from being repositioned by pinning it using: portal.setPinned(true); Apart from that, a Portlet inherits all the features of a standard ContentPanel. The Portal class A Portal is a special container for Portlet components. In fact, it is a Container containing a collection of LayoutContainer components arranged using ColumnLayout. Each of those LayoutContainer components in turn is able to contain Portlet components, arranged using a RowLayout. Portal also supports dragging and dropping of Portlet components, both in terms of changing the row it is in within a column and the column within the Portal. When creating a Portal, we need to set the number of columns the Portal should create in the constructor. We also need to set the widths of each column before using the setColumnWidth method of the Portal. So to create a Portal with two columns, (one using 30 percent of the width and the second 70 percent) we would define it as follows: Portal portal = new Portal(2); portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); We can then add a Portlet to each column like this: Portlet portlet1 = new Portlet(); portlet1.setHeight(150); portlet1.setHeading("Example Portlet 1"); portal.add(portlet1, 0); Portlet portlet2 = new Portlet(); portlet2.setHeight(150); portlet2.setHeading("Example Portlet 2"); portal.add(portlet2, 1); This will produce the following output: Both Portlet components can be dragged and dropped into different positions. The Portlet turns into a blue box while being dragged as shown in the following screenshot: A Portlet will automatically resize and ft into the column in which it is dropped, as seen in the next screenshot: ToolButton Like ContentPanel that Portlet extends, we can add ToolButton components to the header. These can be very useful for making a Portlet look and behave even more like windows in a desktop application. portlet.getHeader().addTool(new ToolButton("x-tool-minimize")); portlet.getHeader().addTool(new ToolButton("x-tool-maximize")); portlet.getHeader().addTool(new ToolButton("x-tool-close")); The output can be seen as shown in the following screenshot: At the moment, we are using ContentPanel components in our example application and laying them out using a BorderLayout. We shall now see that it does not take much to change the ContentPanel components into Portlet components and manage them using a Portal. Portlet components are ideally suited to being independent, self-contained user interface elements that respond to the data passed to them. Rather than tying them into a Portal directly, we can use the MVC components to cause the Portal to respond to the creation of a new Portlet to preserve that independence. Time for action – creating a Portal Controller and a Portlet View The first thing we need to do is add a new EventType to the existing AppEvents class named NewPortletCreated. We will fire this when we create a new Portlet. public static final EventType NewPortletCreated = new EventType(); Create a new class named PortalController that extends Controller. public class PortalController extends Controller { Create a new class named PortalView that extends View. public class PortalView extends View { Create a constructor that sets the Controller of the PortalView. public PortalView(PortalController portalController) { super(portalController); } Returning to PortalController, create a variable to hold the PortalView and override the initialize method to set the view. private PortalView portalView; @Override public void initialize() { super.initialize(); portalView = new PortalView(this); } Create a constructor that registers each EventType the PortalController should observe, specifically NewPortletCreated creation and Error. public PortalController() { registerEventTypes(AppEvents.NewPortletCreated ); registerEventTypes(AppEvents.Error); } Override the handleEvent method to forward any events to the View apart from errors which for the time being we will just log to the GWT log. @Override public void handleEvent(AppEvent event) { EventType eventType = event.getType(); if (eventType.equals(AppEvents.error)) { GWT.log("Error", (Throwable) event.getData()); } else { forwardToView(portalView, event); } } Returning to PortalView, create a new portal field consisting of a Portal component with two columns. private final Portal portal = new Portal(2); Override the initialize method to set the width of the two columns, the first to 30 percent of the width of the Portal and the second to 70 percent. @Override protected void initialize() { portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); } Now create a Viewport, set the layout to FitLayout, add the Portal, and then add the Viewport to GWT's RootPanel. @Override protected void initialize() { portal.setColumnWidth(0, 0.3); portal.setColumnWidth(1, 0.7); final Viewport viewport = new Viewport(); viewport.setLayout(new FitLayout()); viewport.add(portal); RootPanel.get().add(viewport); } We also need to implement the handleEvent method of the View. For now, we will catch the NewPortletCreated event, but we will not do anything with it yet. @Override protected void handleEvent(AppEvent event) { EventType eventType = event.getType(); if (eventType.equals(AppEvents.NewPortletCreated )) { } } Finally, go to the onModuleLoad method of the EntryPoint RSSReader class and instead of creating an AppController, create a PortalController, and remove the line that forwards an Init AppEvent, as we will not be using it. The onModuleLoad method will now look like this: public void onModuleLoad() { final FeedServiceAsync feedService = GWT.create(FeedService.class); Registry.register(RSSReaderConstants.FEED_SERVICE, feedService); Dispatcher dispatcher = Dispatcher.get(); dispatcher.addController(new PortalController()); } What just happened? We created the basic framework for a Portal layout of our application. However, if we started it now, we would just get a blank screen. What we need to do is add Portlet components. The actual Portlet components are not too complicated. They will just act as wrappers.
Read more
  • 0
  • 0
  • 1841

article-image-scaffolding-command-line-tool
Packt
25 Jul 2013
4 min read
Save for later

Scaffolding with the command-line tool

Packt
25 Jul 2013
4 min read
(For more resources related to this topic, see here.) CakePHP comes packaged with the Cake command-line tool, which provides a number of code generation tools for creating models, controllers, views, data fixtures, and more, all on the fly. Please note that this is great for prototyping, but is non-ideal for a production environment. On your command line, from the cake-starter folder, type the following: cd appConsolecake bake You will see something similar to the following: > Console/cake bakeWelcome to CakePHP v2.2.3 Console---------------------------------------------------------------App : appPath: /path/to/app/---------------------------------------------------------------Interactive Bake Shell---------------------------------------------------------------[D]atabase Configuration[M]odel[V]iew[C]ontroller[P]roject[F]ixture[T]est case[Q]uitWhat would you like to Bake? (D/M/V/C/P/F/T/Q)> As you can see, there's a lot to be done with this tool. Note that there are other commands beside bake, such as schema, which we be our main focus in this article. Creating the schema definition Inside the app/Config/Schema folder, create a file called glossary.php. Insert the following code into this file: <?php/** * This schema provides the definitions for the core tables in the glossary app. * * @var $glossary_terms - The main terms/definition table for the app * @var $categories - The categories table * @var $terms_categories - The lookup table, no model will be created. * * @author mhenderson * */class GlossarySchema extends CakeSchema { public $glossaryterms = array( 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), 'title' => array('type' => 'string', 'null' => false, 'length' => 100), 'definition' => array('type' => 'string', 'null' => false, 'length' => 512) ); public $categories = array( 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), 'name' => array('type' => 'string', 'null' => false, 'length' => 100), 'definition' => array('type' => 'string', 'null' => false, 'length' => 512) ); public $glossaryterms_categories = array( 'id' => array('type' => 'integer', 'null' => false, 'key' => 'primary'), 'glossaryterm_id' => array('type' => 'integer', 'null' => false), 'category_id' => array('type' => 'string', 'null' => false) );} This class definition represents three tables: glossaryterms , categories, and a lookup table to facilitate the relationship between the two tables. Each variable in the class represents a table, and the array keys inside of the variable represent the fields in the table. As you can see, the first two tables match up with our earlier architecture description. Creating the database schema On the command line, assuming you haven't moved to any other folders, type the following command: Console/cake schema create glossary You should then see the following responses. When prompted, type y once to drop the tables, and again to create them. Welcome to CakePHP v2.2.3 Console---------------------------------------------------------------App : appPath: /path/to/app---------------------------------------------------------------Cake Schema Shell---------------------------------------------------------------The following table(s) will be dropped.glossarytermscategoriesglossaryterms_categoriesAre you sure you want to drop the table(s)? (y/n)[n] > yDropping table(s).glossaryterms updated.categories updated.glossaryterms_categories updated.The following table(s) will be created.glossarytermscategoriesglossaryterms_categoriesAre you sure you want to create the table(s)? (y/n)[y] > yCreating table(s).glossaryterms updated.categories updated.glossaryterms_categories updated.End create. If you look at your database now, you will notice that the three tables have been created. We can also make modifications to the glossary.php file and run the cake schema command again to update it. If you want to try something a little more daring, you can use the migrations plugin found at https://github.com/CakeDC/migrations. This plugin allows you to save "snapshots" of your schema to be recalled later, and also allows you to write custom scripts to migrate "up" to a certain snapshot version, or migrate "down" in the event of an emergency or a mistake. Summary In this article we saw the use of the schema tool and also its database. Resources for Article: Further resources on this subject: Create a Quick Application in CakePHP: Part 1 [Article] Working with Simple Associations using CakePHP [Article] Creating and Consuming Web Services in CakePHP 1.3 [Article]
Read more
  • 0
  • 0
  • 1840

article-image-getting-started-your-first-jquery-plugin
Packt
29 Aug 2013
9 min read
Save for later

Getting started with your first jQuery plugin

Packt
29 Aug 2013
9 min read
(For more resources related to this topic, see here.) Getting ready Before we dive into our development, we need to have a good idea of how our plugin is going to work. For this, we will write some simple HTML to declare a shape and a button. Each shape will be declared in the CSS, and then we will use the JavaScript to toggle which shape is shown by toggling the CSS class appended to it. The aim of this recipe is to help you familiarize yourself both with jQuery plugin development and the jQuery Boilerplate template. How to do it Our first step is to set up our HTML. For this we need to open up our index.html file. We will need to add two elements in HTML: shape and wrapper to contain our shape. The button for changing the shape element will be added dynamically by our JavaScript. We will then add an event listener to it so that we can change the shape. The HTML code for this is as follows: <div class="shape_wrapper"> <div class="shape"> </div> </div> This should be placed in the div tag with class="container" in our index.html file. We then need to define each of the shapes we intend to use using CSS. In this example, we will draw a square, a circle, a triangle, and an oval, all of which can be defined using CSS. The shape we will be manipulating will be 100px * 100px. The following CSS should be placed in your main.css file: .shape{ width: 100px; height: 100px; background: #ff0000; margin: 10px 0px; } .shape.circle{ border-radius: 50px; } .shape.triangle{ width: 0; height: 0; background: transparent; border-left: 50px solid transparent; border-right: 50px solid transparent; border-bottom: 100px solid #ff0000; } .shape.oval{ width: 100px; height: 50px; margin: 35px 0; border-radius: 50px / 25px; } Now it's time to get onto the JavaScript. The first step in creating the plugin is to name it; in this case we will call it shapeShift. In the jQuery Boilerplate code, we will need to set the value of the pluginName variable to equal shapeShift. This is done as: var pluginName = "shapeShift" Once we have named the plugin, we can edit our main.js file to call the plugin. We will call the plugin by selecting the element using jQuery and creating an instance of our plugin by running .shapeShift(); as follows: (function(){$('.shape_wrapper').shapeShift();}()); For now this will do nothing, but it will enable us to test our plugin once we have written the code. To ensure the flexibility of our plugin, we will store our shapes as part of the defaults object literal, meaning that, in the future, the shapes used by the plugin can be changed without the plugin code being changed. We will also set the class name of the shape in the defaults object literal so that this can be chosen by the plugin user as well. After doing this, your defaults object should look like the following: defaults = {shapes: ["square", "circle", "triangle", "oval"],shapeClass: ".shape"}; When the .shapeShift() function is triggered, it will create an instance of our plugin and then fire the init function. For this instance of our plugin, we will store the current shape location in the array; this is done by adding it to this by using this.shapeRef = 0. The reason we are storing the shape reference on this is that it attaches it to this instance of the plugin, and it will not be available to other instances of the same plugin on the same page. Once we have stored the shape reference, we need to apply the first shape class to the div element according to our shape. The simplest way to do this is to use jQuery to get the shape and then use addClass to add the shape class as follows: $(this.element).find(this.options.shapeClass).addClass(this.options.shapes[this.shapeRef]); The final step that we need to do in our init function is to add our button to enable the user to change the shape. To do this, we simply append a button element to the shape container as follows: $(this.element).append('<button>Change Shape</button>'); Once we have our button element, we then need to add the shape reference, which changes the shape of the elements. To do this we will create a separate function called changeShape. While we are still in our init function, we can add an event handler to call the changeShape function onto the button. For reasons that will become apparent shortly, we will use the event delegation format of the jQuery. on() function to do this: $(this.element).on('click','button',this.changeShape); We now need to create our changeShape function; the first thing we will do is change this function name to changeShape. We will then change the function declaration to accept a parameter, in this case e. The first thing to note is that this function is called from an event listener on a DOM element and therefore this is actually the element that has been clicked on. This function was called using event delegation; the reason for this becomes apparent here as it allows us to find out which instance of the plugin belongs to the button that has been clicked on. We do this by using the e parameter that was passed to the function. The e parameter passed to the function is the jQuery event object related to the click event that has been fired. Inside it, we will find a reference to the original element that the click event was set to, which in this case is the element that the instance of the plugin is tied to. To retrieve the instance of the plugin, we can simply use the jQuery.data() function. The instance of the plugin is stored on the element as data using the data key plugin_pluginName, so we are able to retrieve it the same way as follows: var plugin = $(e.delegateTarget).data("plugin_" + pluginName); Now that we have the plugin instance, we are able to access everything it contains; the first thing we need to do is to remove the current shape class from the shape element in the DOM. To do this, we will simply find the shape element then look up in the shapes array to get the currently displayed shape, and then use the jQuery.removeClass function to remove the individual class. The code for doing this starts with a simple jQuery selector that allows us to work with the plugin element; we do this using $(plugin.element). We then look inside the plugin element to find the actual shape. As the name of the shape class is configurable, we can read this from our plugin option; so when we are finding the shape we use .find(plugin.options.shapeClass). Finally we add the class; so that we know which shape is next, we look up the shape class from the shapes array stored in the plugin options, selecting the item indicated by the plugin.shapeRef. The full command then looks as follows: $(plugin.element).find(plugin.options.shapeClass).removeClass(plugin.options.shapes[plugin.shapeRef]); We then need to work out which is the next shape we should show; we know that the current shape reference can be found in plugin.shapeRef, so we just need to work out if we have any more shapes left in the shape array or if we should start from the beginning. To do this, we look at the value of plugin.shapeRef and compare it to the length of the shapes array minus 1 (we substract 1 because arrays start at 0); if the shape reference is equal to the length of the shapes array minus 1, we know that we have reached the last shape, so we reset the plugin.shapeRef parameter to 0. Otherwise, we simply increment the shapeRef parameter by 1 as shown in the snippet: if((plugin.shapeRef) === (plugin.options.shapes.length -1)){plugin.shapeRef = 0;}else{plugin.shapeRef = plugin.shapeRef+1;} Our final step is to add the new shape class to the shape element; this can be achieved by finding the shape element and using the jQuery.addClass function to add the shape from the shapes array. This is very similar to our removeClass command that we used earlier with addClass replacing removeClass. $(plugin.element).find(plugin.options.shapeClass).addClass(plugin.options.shapes[plugin.shapeRef]); At this point we should now have a working plugin; so if we fire up the browser and navigate to the index.html file, we should get a square with a button beneath it. Clicking on the button should show the next shape. If your code is working correctly, the shapes should be shown in the order: square, circle, triangle, oval, and then loop back to square. As a final test to show that each plugin instance is tied to one element, we will add a second element to the page. This is as simple as duplicating the original shape_wrapper and creating a second one as shown: <div class="shape_wrapper"><div class="shape"></div></div> If everything is working correctly when loading the index.html page, we will have 2 squares each with a button underneath them, and on clicking the button only the shape above will change. Summary This article explained how to create your first jQuery plugin that manipulates the shape of a div element. We achieved this by writing some HTML to declare a shape and a button, declaring each shape in the CSS, and then using the JavaScript to toggle which shape is shown by toggling the CSS class appended to it. Resources for Article: Further resources on this subject: Using jQuery and jQueryUI Widget Factory plugins with RequireJS [Article] jQuery Animation: Tips and Tricks [Article] New Effects Added by jQuery UI [Article]
Read more
  • 0
  • 0
  • 1787

article-image-packaged-elegance
Packt
03 Mar 2015
24 min read
Save for later

Packaged Elegance

Packt
03 Mar 2015
24 min read
In this article by John Farrar, author of the book KnockoutJS Web development, we will see how templates drove us to a more dynamic, creative platform. The next advancement in web development was custom HTML components. KnockoutJS allows us to jump right in with some game-changing elegance for designers and developers. In this article, we will focus on: An introduction to components Bring Your Own Tags (BYOT) Enhancing attribute handling Making your own libraries Asynchronous module definition (AMD)—on demand resource loading This entire article is about packaging your code for reuse. Using these techniques, you can make your code more approachable and elegant. (For more resources related to this topic, see here.) Introduction to components The best explanation of a component is a packaged template with an isolated ViewModel. Here is the syntax we would use to declare a like component on the page: <div data-bind="component: "like"''"></div> If you are passing no parameters through to the component, this is the correct syntax. If you wish to pass parameters through, you would use a JSON style structure as follows: <div data-bind="component:{name: 'like-widget',params:{ approve: like} }"></div> This would allow us to pass named parameters through to our custom component. In this case, we are passing a parameter named approve. This would mean we had a bound viewModel variable by the name of like. Look at how this would be coded. Create a page called components.html using the _base.html file to speed things up as we have done in all our other articles. In your script section, create the following ViewModel: <script>ViewModel = function(){self = this;self.like = ko.observable(true);};// insert custom component herevm = new ViewModel();ko.applyBindings(vm);</script> Now, we will create our custom component. Here is the basic component we will use for this first component. Place the code where the comment is, as we want to make sure it is added before our applyBindings method is executed: ko.components.register('like-widget', { viewModel: function(params) {    this.approve = params.approve;    // Behaviors:    this.toggle = function(){      this.approve(!this.approve());    }.bind(this); }, template:    '<div class="approve">      <button data-bind="click: toggle">        <span data-bind="visible: approve" class="glyphicon   glyphicon-thumbs-up"></span>        <span data-bind="visible:! approve()" class="glyphicon   glyphicon-thumbs-down"></span>      </button>    </div>' }); There are two sections to our components: the viewModel and template sections. In this article, we will be using Knockout template details inside the component. The standard Knockout component passes variables to the component using the params structure. We can either use this structure or you could optionally use the self = this approach if desired. In addition to setting the variable structure, it is also possible to create behaviors for our components. If we look in the template code, we can see we have data-bound the click event to toggle the approve setting in our component. Then, inside the button, by binding to the visible trait of the span element, either the thumbs up or thumbs down image will be shown to the user. Yes, we are using a Bootstrap icon element rather than a graphic here. Here is a screenshot of the initial state: When we click on the thumb image, it will toggle between the thumbs up and the thumbs down version. Since we also passed in the external variable that is bound to the page ViewModel, we see that the value in the matched span text will also toggle. Here is the markup we would add to the page to produce these results in the View section of our code: <div data-bind="component:   {name: 'like-widget', params:{ approve: like} }"></div> <span data-bind="text: like"></span> You could build this type of functionality with a jQuery plugin as well, but it is likely to take a bit more code to do two-way binding and match the tight functionality we have achieved here. This doesn't mean jQuery plugins are bad, as this is also a jQuery-related technology. What it does mean is we have ways to do things even better. It is this author's opinion that features like this would still make great additions to the core jQuery library. Yet, I am not holding my breath waiting for them to adopt a Knockout-type project to the wonderful collection of projects they have at this point, and do not feel we should hold that against them. Keeping focused on what they do best is one of the reasons libraries like Knockout can provide a wider array of options. It seems the decisions are working on our behalf even if they are taking a different approach than I expected. Dynamic component selection You should have noticed when we selected the component that we did so using a quoted declaration. While at first it may seem to be more constricting, remember that it is actually a power feature. By using a variable instead of a hardcoded value, you can dynamically select the component you would like to be inserted. Here is the markup code: <div data-bind="component:  { name: widgetName, params: widgetParams }"></div> <span data-bind="text:widgetParams.approve"></span> Notice that we are passing in both widgetName as well as widgetParams. Because we are binding the structure differently, we also need to show the bound value differently in our span. Here is the script part of our code that needs to be added to our viewModel code: self.widgetName = ko.observable("like-widget"); self.widgetParams = {    approve: ko.observable(true) }; We will get the same visible results but notice that each of the like buttons is acting independent of the other. What would happen if we put more than one of the same elements on the page? If we do that, Knockout components will act independent of other components. Well, most of the time they act independent. If we bound them to the same variable they would not be independent. In your viewModel declaration code, add another variable called like2 as follows: self.like2 = ko.observable(false); Now, we will add another like button to the page by copying our first like View code. This time, change the value from like to like2 as follows: <like-widget params="approve: like2"></like-widget> <span data-bind="text: like2"></span> This time when the page loads, the other likes display with a thumbs up, but this like will display with a thumbs down. The text will also show false stored in the bound value. Any of the like buttons will act independently because each of them is bound to unique values. Here is a screenshot of the third button: Bring Your Own Tags (BYOT) What is an element? Basically, an element is a component that you reach using the tag syntax. This is the way it is expressed in the official documentation at this point and it is likely to stay that way. It is still a component under the hood. Depending on the crowd you are in, this distinction will be more or less important. Mostly, just be aware of the distinction in case someone feels it is important, as that will let you be on the same page in discussions. Custom tags are a part of the forthcoming HTML feature called Web Components. Knockout allows you to start using them today. Here is the View code: <like-widget params="approve: like3"></like-widget> <span data-bind="text: like3"></span> You may want to code some tags with a single tag rather than a double tag, as in an opening and closing tag syntax. Well, at this time, there are challenges getting each browser to see the custom element tags when declared as a single tag. This means custom tags, or elements, will need to be declared as opening and closing tags for now. We will also need to create our like3 bound variable for viewModel with the following code: self.like3 = ko.observable(true); Running the code gives us the same wonderful functionality as our data-bind approach, but now we are creating our own HTML tags. Has there ever been a time you wanted a special HTML tag that just didn't exist? There is a chance you could create that now using Knockout component element-style coding. Enhancing attribute handling Now, while custom tags are awesome, there is just something different about passing everything in with a single param attribute. The reason for this is that this process matches how our tags work when we are using the data-bind approach to coding. In the following example, we will look at passing things in via individual attributes. This is not meant to work as a data-bind approach, but it is focused completely on the custom tag element component. The first thing you want to do is make sure this enhancement doesn't cause any issues with the normal elements. We did this by checking the custom elements for a standard prefix. You do not need to work through this code as it is a bit more advanced. The easiest thing to do is to include our Knockout components tag with the following script tag: <script src="/share/js/knockout.komponents.js"></script> In this tag, we have this code segment to convert the tags that start with kom- to tags that use individual attributes rather than a JSON translation of the attributes. Feel free to borrow the code to create libraries of your own. We are going to be creating a standard set of libraries on GitHub for these component tags. Since the HTML tags are Knockout components, we are calling these libraries "KOmponents". The" resource can be found at https://github.com/sosensible/komponents. Now, with that library included, we will use our View code to connect to the new tag. Here is the code to use in the View: <kom-like approve="tagLike"></kom-like> <span data-bind="text: tagLike"></span> Notice that in our HTML markup, the tag starts with the library prefix. This will also require viewModel to have a binding to pass into this tag as follows: self.tagLike = ko.observable(true); The following is the code for the actual "attribute-aware version" of Knockout components. Do not place this in the code as it is already included in the library in the shared directory: // <kom-like /> tag ko.components.register('kom-like', { viewModel: function(params) {    // Data: value must but true to approve    this.approve = params.approve;    // Behaviors:    this.toggle = function(){      this.approve(!this.approve());    }.bind(this); }, template:    '<div class="approve">      <button data-bind="click: toggle">        <span data-bind="visible: approve" class="glyphicon   glyphicon-thumbs-up"></span>        <span data-bind="visible:! approve()" class="glyphicon   glyphicon-thumbs-down"></span>      </button>    </div>' }); The tag in the View changed as we passed the information in via named attributes and not as a JSON structure inside a param attribute. We also made sure to manage these tags by using a prefix. The reason for this is that we did not want our fancy tags to break the standard method of passing params commonly practiced with regular Knockout components. As we see, again we have another functional component with the added advantage of being able to pass the values in a style more familiar to those used to coding with HTML tags. Building your own libraries Again, we are calling our custom components KOmponents. We will be creating a number of library solutions over time and welcome others to join in. Tags will not do everything for us, as there are some limitations yet to be conquered. That doesn't mean we wait for all the features before doing the ones we can for now. In this article, we will also be showing some tags from our Bootstrap KOmponents library. First we will need to include the Bootstrap KOmponents library: <script src="/share/js/knockout.komponents.bs.js"></script> Above viewModel in our script, we need to add a function to make this section of code simpler. At times, when passing items into observables, we can pass in richer bound data using a function like this. Again, create this function above the viewModel declaration of the script, shown as follows: var listItem = function(display, students){ this.display = ko.observable(display); this.students = ko.observable(students); this.type = ko.computed(function(){    switch(Math.ceil(this.students()/5)){      case 1:      case 2:        return 'danger';        break;      case 3:        return 'warning';        break;      case 4:        return 'info';        break;      default:        return 'success';    } },this); }; Now, inside viewModel, we will declare a set of data to pass to a Bootstrap style listGroup as follows: self.listData = ko.observableArray([ new listItem("HTML5",12), new listItem("CSS",8), new listItem("JavaScript",19), new listItem("jQuery",48), new listItem("Knockout",33) ]); Each item in our array will have display, students, and type variables. We are using a number of features in Bootstrap here but packaging them all up inside our Bootstrap smart tag. This tag starts to go beyond the bare basics. It is still very implementable, but we don't want to throw too much at you to absorb at one time, so we will not go into the detailed code for this tag. What we do want to show is how much power can be wrapped into custom Knockout tags. Here is the markup we will use to call this tag and bind the correct part of viewModel for display: <kom-listgroup data="listData" badgeField="'students'"   typeField="'type'"></kom-listgroup> That is it. You should take note of a couple of special details. The data is passed in as a bound Knockout ViewModel. The badge field is passed in as a string name to declare the field on the data collection where the badge count will be pulled. The same string approach has been used for the type field. The type will set the colors as per standard Bootstrap types. The theme here is that if there are not enough students to hold a class, then it shows the danger color in the list group custom tag. Here is what it looks like in the browser when we run the code: While this is neat, let's jump into our browser tools console and change the value of one of the items. Let's say there was a class on some cool web technology called jQuery. What if people had not heard of it and didn't know what it was and you really wanted to take the class? Well, it would be nice to encourage a few others to check it out. How would you know whether the class was at a danger level or not? Well, we could simply use the badge and the numbers, but how awesome is it to also use the color coding hint? Type the following code into the console and see what changes: vm.listData()[3].display() Because JavaScript starts counting with zero for the first item, we will get the following result: Now we know we have the right item, so let's set the student count to nine using the following code in the browser console: vm.listData()[3].students(9) Notice the change in the jQuery class. Both the badge and the type value have updated. This screenshot of the update shows how much power we can wield with very little manual coding: We should also take a moment to see how the type was managed. Using the functional assignment, we were able to use the Knockout computed binding for that value. Here is the code for that part again: this.type = ko.computed(function(){ switch(Math.ceil(this.students()/5)){    case 1:    case 2:      return 'danger';      break;    case 3:      return 'warning';      break;    case 4:      return 'info';      break;    default:      return 'success'; } },this); While the code is outside the viewModel declaration, it is still able to bind properly to make our code run even inside a custom tag created with Knockout's component binding. Bootstrap component example Here is another example of binding with Bootstrap. The general best practice for using modal display boxes is to place them higher in the code, perhaps under the body tag, to make sure there are no conflicts with the rest of the code. Place this tag right below the body tag as shown in the following code: <kom-modal id="'komModal'" title="komModal.title()"   body="komModal.body()"></kom-modal> Again, we will need to make some declarations inside viewModel for this to work right. Enter this code into the declarations of viewModel: self.komModal = { title: ko.observable('Modal KOMponent'), body: ko.observable('This is the body of the <strong>modal   KOMponent</strong>.') }; We will also create a button on the page to call our viewModel. The button will use the binding that is part of Bootstrap. The data-toggle and data-target attributes are not Knockout binding features. Knockout works side-by-side wonderfully though. Another point of interest is the standard ID attribute, which tells how Bootstrap items, like this button, interact with the modal box. This is another reason it may be beneficial to use KOmponents or a library like it. Here is the markup code: <button type="button" data-toggle="modal" data-   target="#komModal">Open Modal KOmponent</button> When we click on the button, this is the requestor we see: Now, to understand the power of Knockout working with our requestor, head back over to your browser tools console. Enter the following command into the prompt: vm.komModal.body("Wow, live data binding!") The following screenshot shows the change: Who knows what type of creative modular boxes we can build using this type of technology. This brings us closer towards creating what we can imagine. Perhaps it may bring us closer to building some of the wild things our customers imagine. While that may not be your main motivation for using Knockout, it would be nice to have a few less roadblocks when we want to be creative. It would also be nice to have this wonderful ability to package and reuse these solutions across a site without using copy and paste and searching back through the code when the client makes a change to make updates. Again, feel free to look at the file to see how we made these components work. They are not extremely complicated once you get the basics of using Knockout and its components. If you are looking to build components of your own, they will help you get some insight on how to do things inside as you move your skills to the next level. Understanding the AMD approach We are going to look into the concept of what makes an AMD-style website. The point of this approach to sites is to pull content on demand. The content, or modules as they are defined here, does not need to be loaded in a particular order. If there are pieces that depend on other pieces, that is, of course, managed. We will be using the RequireJS library to manage this part of our code. We will create four files in this example, as follows: amd.html amd.config.js pick.js pick.html In our AMD page, we are going to create a configuration file for our RequireJS functionality. That will be the amd.config.js file mentioned in the aforementioned list. We will start by creating this file with the following code: // require.js settings var require = {    baseUrl: ".",    paths: {        "bootstrap":       "/share/js/bootstrap.min",        "jquery":           "/share/js/jquery.min",        "knockout":         "/share/js/knockout",        "text":             "/share/js/text"    },    shim: {        "bootstrap": { deps: ["jquery"] },        "knockout": { deps: ["jquery"] },    } }; We see here that we are creating some alias names and setting the paths these names point to for this page. The file could, of course, be working for more than one page, but in this case, it has specifically been created for a single page. The configuration in RequireJS does not need the .js extension on the file names, as you would have noted. Now, we will look at our amd.html page where we pull things together. We are again using the standard page we have used for this article, which you will notice if you preview the done file example of the code. There are a couple of differences though, because the JavaScript files do not all need to be called at the start. RequireJS handles this well for us. We are not saying this is a standard practice of AMD, but it is an introduction of the concepts. We will need to include the following three script files in this example: <script src="/share/js/knockout.js"></script> <script src="amd.config.js"></script> <script src="/share/js/require.js"></script> Notice that the configuration settings need to be set before calling the require.js library. With that set, we can create the code to wire Knockout binding on the page. This goes in our amd.html script at the bottom of the page: <script> ko.components.register('pick', { viewModel: { require: 'pick' }, template: { require: 'text!pick.html' } }); viewModel = function(){ this.choice = ko.observable(); } vm = new viewModel(); ko.applyBindings(vm); </script> Most of this code should look very familiar. The difference is that the external files are being used to set the content for viewModel and template in the pick component. The require setting smartly knows to include the pick.js file for the pick setting. It does need to be passed as a string, of course. When we include the template, you will see that we use text! in front of the file we are including. We also declare the extension on the file name in this case. The text method actually needs to know where the text is coming from, and you will see in our amd.config.js file that we created an alias for the inclusion of the text function. Now, we will create the pick.js file and place it in the same directory as the amd.html file. It could have been in another directory, and you would have to just set that in the component declaration along with the filename. Here is the code for this part of our AMD component: define(['knockout'], function(ko) {    function LikeWidgetViewModel(params) {        this.chosenValue = params.value;        this.land = Math.round(Math.random()) ? 'heads' : 'tails';    }    LikeWidgetViewModel.prototype.heads = function() {        this.chosenValue('heads');    };    LikeWidgetViewModel.prototype.tails = function() {        this.chosenValue('tails');    };    return LikeWidgetViewModel; }); Notice that our code starts with the define method. This is our AMD functionality in place. It is saying that before we try to execute this section of code we need to make sure the Knockout library is loaded. This allows us to do on-demand loading of code as needed. The code inside the viewModel section is the same as the other examples we have looked at with one exception. We return viewModel as you see at the end of the preceding code. We used the shorthand code to set the value for heads and tails in this example. Now, we will look at our template file, pick.html. This is the code we will have in this file: <div class="like-or-dislike" data-bind="visible: !chosenValue()"> <button data-bind="click: heads">Heads</button> <button data-bind="click: tails">Tails</button> </div> <div class="result" data-bind="visible: chosenValue">    You picked <strong data-bind="text: chosenValue"></strong>    The correct value was <strong data-bind="text:   land"></strong> </div> There is nothing special other than the code needed to make this example work. The goal is to allow a custom tag to offer up heads or tails options on the page. We also pass in a bound variable from viewModel. We will be passing it into three identical tags. The tags are actually going to load the content instantly in this example. The goal is to get familiar with how the code works. We will take it to full practice at the end of the article. Right now, we will put this code in the View segment of our amd.html page: <h2>One Choice</h2> <pick params="value: choice"></pick><br> <pick params="value: choice"></pick><br> <pick params="value: choice"></pick> Notice that we have included the pick tag three times. While we are passing in the bound choice item from viewModel, each tag will randomly choose heads or tails. When we run the code, this is what we will see: Since we passed the same bound item into each of the three tags, when we click on any heads or tails set, it will immediately pass that value out to viewModel, which will in turn immediately pass the value back into the other two tag sets. They are all wired together through viewModel binding being the same variable. This is the result we get if we click on Tails: Well, it is the results we got that time. Actually, the results change pretty much every time we refresh the page. Now, we are ready to do something extra special by combining our AMD approach with Knockout modules. Summary This article has shown the awesome power of templates working together with ViewModels within Knockout components. You should now have an awesome foundation to do more with less than ever before. You should know how to mingle your jQuery code with the Knockout code side by side. To review, in this article, we learned what Knockout components are. We learned how to use the components to create custom HTML elements that are interactive and powerful. We learned how to enhance custom elements to allow variables to be managed using the more common attributes approach. We learned how to use an AMD-style approach to coding with Knockout. We also learned how to AJAX everything and integrate jQuery to enhance Knockout-based solutions. What's next? That is up to you. One thing is for sure, the possibilities are broader using Knockout than they were before. Happy coding and congratulations on completing your study of KnockoutJS! Resources for Article: Further resources on this subject: Top features of KnockoutJS [article] Components [article] Web Application Testing [article]
Read more
  • 0
  • 0
  • 1776
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-search-engine-optimization-using-sitemaps-drupal-6
Packt
10 Nov 2009
8 min read
Save for later

Search Engine Optimization using Sitemaps in Drupal 6

Packt
10 Nov 2009
8 min read
Let's get started. As smart as the Google spider is, it's possible for them to miss pages on your site. Maybe you've got an orphaned page that isn't in your navigation anymore. Or, perhaps you have moved a link to a piece of content so that it's not easily accessible. It's also possible that your site is so big that Google just can't crawl it all without completely pulling all your server's resources—not pretty! The solution is a sitemap. In the early 2000s, Google started supporting XML sitemaps. Soon after Yahoo came out with their own standard and other search engines started to follow suit. Fortunately, in 2006, Google, Yahoo, Microsoft, and a handful of smaller players all got together and decided to support the same sitemap specification. That made it much easier for site owners to make sure every page of their web site is crawled and added to the search engine index. They published their specification at http://sitemaps.org. Shortly thereafter, the Drupal community stepped up and created a module called (surprise!) the XML sitemap module. This module automatically generates an XML sitemap containing every node and taxonomy on your Drupal site. Actually, it was written by Matthew Loar as part of the Google Summer of Code. The Drupal 6 version of the module was developed by Kiam LaLuno. Finally, in mid-2009, Dave Reid began working on a version 2.0 of the module to address performance, scalability, and reliability issues. Thanks, guys! According to www.sitemaps.org: Sitemaps are an easy way for Webmasters to inform search engines about pages on their sites that are available for crawling. In its simplest form, a Sitemap is an XML file that lists URLs for a site along with additional metadata about each URL (when it was last updated, how often it usually changes, and how important it is, relative to other URLs in the site) so that search engines can more intelligently crawl the site. Web crawlers usually discover pages from links within the site and from other sites. Sitemaps supplement this data to allow crawlers that support Sitemaps to pick up all URLs in the Sitemap and learn about those URLs using the associated metadata. Using a sitemap does not guarantee that every page will be included in the search engines. Rather, it helps the search engine crawlers find more of your pages. In my experience, submitting an XML Sitemap to Google will greatly increase the number of pages when you do a site: search. The keyword site: searches show you how many pages of your site are included in the search engine index, as shown in the following screenshot: Setting up the XML Sitemap module The XML Sitemap module creates a sitemap that conforms to the sitemap.org specification. Which XML Sitemap module should you use? There are two versions of the XML Sitemap module for Drupal 6. The 1.x version is, as of this writing, considered the stable release and should be used for production sites. However, if you have a site with more than about 2000 nodes, you should probably consider using the 2.x version. From www.drupal.org: 'The 6.x-2.x branch is a complete refactoring with considerations for performance, scalability, and reliability. Once the 6.x-2.x branch is tested and upgradeable, the 6.x-1.x branch will no longer be supported'. What this means is that in the next few months (quite possibly by the time you're reading this) everyone should be using the 2.x version of this module. That's the beauty of open source software—there are always improvements coming that make your Drupal site better Search Engine Optimized. Carry out the following steps to set up the XML Sitemap module: Download the XML Sitemap module and install it just like a normal Drupal module.  When you go to turn on the module, you'll be presented with a list that looks similar to the following screenshot: Now that you have the XML sitemap module properly installed and configured, you can start defining the priority of the content on your site—by default, the priority is .5. However, there are times when you may want Google to visit some content more often and other times when you may not want your content in the sitemap at all (like the comment or contact us submission forms). Each node now has an XML sitemap section that looks like the following screenshot: Before you turn on any included modules, consider what pieces of content on your site you want to show up in the search engines and only turn on the modules you need. The XML sitemap module is required. Turn it on. XML sitemap custom allows you to add your own customized links to the sitemap. Turn it on. XML sitemap engines will automatically submit your sitemap to the search engines each time it changes. This is not necessary and there are better ways to submit your sitemap. However, it does a nice job of helping you verify your site with each search engine. Turn it on. XML sitemap menu adds your menu items to the sitemap. This is probably a good idea. Turn it on. XML sitemap node adds all your nodes. That's usually the bulk of your content so this is a must-have. Turn it on. XML sitemap taxonomy adds all your taxonomy term pages to the sitemap. Generally a good idea but some might not want this listed. Term pages are good category pages so I recommend it. Turn it on. Don't forget to click Save configuration. Go to http://www.yourDrupalsite.com/admin/settings/xmlsitemap or go to your admin screen and click on Administer | Site Configuration | XML sitemap link. You'll be able to see the XML sitemap, as shown in the following screenshot: Click on Settings and you'll see a few options, as shown in the following screenshot: Minimum sitemap lifetime: It determines that minimum amount of time that the module will wait before renewing the sitemap. Use this feature if you have an enormous sitemap that is taking too many server resources. Most sites should leave this set on No minimum. Include a stylesheet in the: The sitemaps will generate a simple css file to include with the sitemap that is generated. It's not necessary for the search engines but very helpful for troubleshooting or if any humans are going to view the sitemap. Leave it checked. Generate sitemaps for the following languages: In the future, this option will allow you to actually specify sitemaps for different languages. This is very important for international sites who want to show up in localized search engines. For now, English is the only option and should remain checked. Click the Advanced settings drop-down and you'll see several additional options. Number of links in each sitemap page allows you to specify how many links to pages on your web site will be in each sitemap. Leave it on Automatic unless you are having trouble with the search engines accepting the sitemap. Maximum number of sitemap links to process at once sets the number of additional links that the module will add to your sitemap each time the cron runs. This highlights one of the biggest differences between the new XML sitemap and the old one. The new sitemap only processes new nodes and updates the existing sitemap instead of reprocessing every time the sitemap is accessed. Leave this setting alone unless you notice that cron is timing out. Sitemap cache directory allows you to set where the sitemap data will be stored. This is data that is not shown to the search engines or users; it's only used by the module. Base URL is the base URL of your site and generally should be left as it is. Click on the Front page drop-down and set these options: Front page priority: 1.0 is the highest setting you can give a page in the XML sitemap. On most web sites, the front page is the single most important part of your site so, this setting should probably be left at 1.0. Front page change frequency: Tells the search engines how often they should revisit your front page. Adjust this setting to reflect how often the front page of your site changes. What is priority and how does it work? Priority is an often-misunderstood part of a sitemap. For instance, the priority is only used to compare pages of your own site and you cannot increase your ranking in the Search Engine Results Page (SERPS) by increasing the priority of your pages. However, it does help let the search engines know which pages of your site you feel are more important. They could use this information to select between two different pages on your site when deciding which page to show to a search engine user.
Read more
  • 0
  • 0
  • 1775

article-image-delicious-tagometer-widget
Packt
20 Oct 2009
10 min read
Save for later

Delicious Tagometer Widget

Packt
20 Oct 2009
10 min read
Background Concept Delicious was founded by Joshua Schachter in 2003 and acquired by Yahoo in 2005. This website was formerly used to run in the domain http://del.icio.us hence known as del.icio.us. Now, this domain redirects to the domain http://delicious.com. This website got redesigned in July 2008 and the Delicious 2.0 went live with new domain, design and name. Delicious is probably one of the largest social bookmarking website in the WWW world for discovering, sharing and storing the interesting and useful URL on the Internet. When saving the URL, user can enter tags for the URL which is quite useful when you’ve to search the particular URL from many bookmarks. The number of saves of a particular URL in Delicious is one of the measurements for checking popularity of that URL. Delicious Tagometer As the name specifies, Delicious Tagometer is a badge which displays the tags as well count of the users who have saved the particular URL. Tagometer gets displayed in the web page which contains the code given below: <script src="http://static.delicious.com/js/blogbadge.js"></script> This is the new URL of the Tagometer badge from the Delicious. The URL for the Tagometer used to be different in the del.icio.us domain in past. For more information on future updates, you can check http://delicious.com/help. The delicious Tagometer looks as shown: As you can easily guess, the above Tagometer is placed on a web page whose URL has not yet been saved in Delicious. Now let’s take a look at the Tagometer which is placed on a web page whose URL is saved by many users of Delicious. In the above widget, the text “bookmark this on Delicious" is the hyperlink for saving the URL in delicious. To save an URL in Delicious, you have to provide the URL and give a Title on the http://delicious.com/save page. After clicking on the “bookmark this on Delicious” hyperlink on the Delicious Tagometer widget you can see the image of the web page on delicious. The Delicious Tagometer widget also shows the list of tags which are used by the users of Delicious to save the URL. Each of these tags link to a tag specific page of Delicious. For example, an URL saved with tag JavaScript can be found on the page http://delicious.com/tag/javascript. And, the number is linked to the URL specific page on Delicious. For example, if you wish to view the users and their notes on the saves of the URL- http://digg.com, then the URL of delicious will be http://delicious.com/url/926a9b7a561a3f650ff41eef0c8ed45d The last part “926a9b7a561a3f650ff41eef0c8ed45d” is the md5 hash of the URL http://digg.com. The md5 is a one way hashing algorithm which converts a given string to a 32 character long string known as md5 digest. This hashed string can’t be reversed back into original string.  The md5 function protects and ensures data integrity of Delicious Data Feeds. Delicious data feeds are read-only web feeds containing bookmark information and other information which can be used third party websites. These feeds are available into two different format: RSS and JSON. Among the various data feeds on the Delicious, let’s look at the details of the data feed which contains summary information of a URL. According to Delicious feed information page, these data feed for URL information can be retrieved via following call, http://feeds.delicious.com/v2/json/urlinfo/{url md5} It clearly specifies summary of URL can be retrieved in the json format only from Delicious. To get the summary about a URL, You can provide the actual URL in the url parameter of the above URL. Alternatively, you can provide md5() hash of the url in the hash parameter in the above URL. Now, let’s look at feed URLs which can be used to access the summary of the http://digg.com from Delicious: http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url=http://digg.com OR http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&hash=926a9b7a561a3f650ff41eef0c8ed45d From the above URLs, it is clear that md5 hash of the string "http://digg.com" is 926a9b7a561a3f650ff41eef0c8ed45d When JSON is used as the format of data returned form Delicious feed then you must specify the JavaScript callback function to handle the JSON data. Now, let look at the JSON data which is returned from any of the above URL of Delicious feed. displayTotalSaves([{"hash":"926a9b7a561a3f650ff41eef0c8ed45d","title":"digg", "url":"http://digg.com/","total_posts":51436,"top_tags":{"news":23581, "digg":10771,"technology":10713,"blog":8628,"web2.0":7800, "tech":6459,"social":5436,"daily":5173,"community":4477,"links":2512}}]) As you can see clearly, the above JSON data contains hash of URL, the URL itself, total no of saves in Delicious in total_posts variable. Along with them, different tags including number of times that tag is used by different users of Delicious for saving the URL  http://digg.com. If the URL is not saved in Delicious then data returned from Delicious feed will be like this : displayTotalSaves([]) Now, having understod the information returned above, let’s see how to create Delicious widget step by step. Creating Delicious Tagometer Widget Our Delicious Tagometer widget looks very similar to actual Delicious Tagometer widget but has different format and texts. In the Tagometer badge provided by delicious, there is no option for specifying a particular URL whose summary is to be displayed. It automatically displays the details of the URL of the web page containing the code. While in our custom widget, you can also specify the URL explicitly in the badge which is an optional parameter. For creating this widget, we will use JavaScript, CSS, XHTML and Delicious’s data feed in JSON format. The above image is of the Delicious widget which we’re going to make and you can see clearly that the provided URL is not yet saved on Delicious. Now, let’s look at the Custom Delicious Tagometer which we can see for a URL saved on the delicious. The above badge of delicious is displayed for the URL: http://yahoo.com. Writing Code for Delicious First of all, let’s start looking at the JavaScript code for handling the parameters-url and title of the web page, when it is not provided. If these parameters are not defined explicitly then url and title of the web page using the widget is provided for saving the bookmark. if(typeof delicious_widget_url!='undefined') delicious_widget_url=encodeURIComponent(delicious_widget_url);else delicious_widget_url=encodeURIComponent(document.location);if(typeof delicious_widget_title!='undefined') delicious_widget_title=encodeURIComponent(delicious_widget_title);else delicious_widget_title=encodeURIComponent(document.title); As can be seen from the above code, if the variable delicious_widget_url is not defined already then the URL of the current document encoded with encodeURIComponent() function is assigned to this variable. If delicious_widget_url variable is already defined then it is encoded with encodeURIComponent() function and assigned to the same variable. The typeof JavaScript operator can be used for checking the type of variable and also serves a very useful purpose of checking whether the variable or function is already defined or not. For example, the statement: typeof xyz==’function’ returns true if the function xyz is already defined. Similarly, if the variable delicious_widget_title is not defined then document.title, which contains title of current web page, is encoded with encodeURIComponent() function and assigned to the delicious_widget_title variable . Next, a variable del_rand_number is defined for handling multiple instances of the widget. var del_rand_number=Math.floor(Math.random()*1000); The Math.random() function returns random values between 0 to 1 and when multiplied by 1000 results in a random number between 1 to 1000. Since this random number is a  floating point number hence floor() function of JavaScript Math Object is used for converting it to the greatest whole number which is less than or equal to generated random number. The Math object of JavaScript has three different functions which can be used to convert a floating point number to whole number:Math.floor(float_val) – converts to greatest integer less than or equal to float_val.Math.ceil(float_val) – converts to smallest integer grater than or equal to float_val.Math.round(float_val) – converts to nearest integer. If the decimal portion of float_val is greater than or equal to .5 then the resulting integer is the next whole number otherwise resulting number is rounded to the nearest integer less than float_val. After that, now using above random number let’s define a variable which holds the “id” of the element in widget for displaying total no. of saves and tags. var del_saved_id="delicious-saved-"+del_rand_number; Now, let’s look at the initWidget() function for initializing the widget. function initWidget(){ //write the elements needed for widget writeWidgetTexts(); //now attach the stylesheet to the document var delCss=document.createElement("link"); delCss.setAttribute("rel", "stylesheet"); delCss.setAttribute("type", "text/css"); delCss.setAttribute("href", "http://yourserver.com/delicious/delicious.css"); document.getElementsByTagName("head")[0].appendChild(delCss); //now call the script of delicious var delScript = document.createElement("script"); delScript.setAttribute("type", "text/javascript"); delScript.setAttribute("src", "http://feeds.delicious.com/v2/json/urlinfo?callback=displayTotalSaves&url="+delicious_widget_url); //alert(delicious_widget_url); document.getElementsByTagName("head").item(0).appendChild(delScript); } At the start of the above code, the function writeWidgetTexts(); is called for writing the content of widget. The functions createElement() and setAttribute() are DOM manipulation function for creating a element and adding attribute to the element respectively. So, the next four statements of the above function create link element and sets various attributes for attaching CSS document to the page using widget. Once link element is created and various attribute is assigned to it the next step is to append it to the document using widget, which is done with appendChild() function in the next line of above function. getElementsByTagName() is a DOM function for accessing the document by the name of tag. Unlike getElementById() which access single element in the document, getElementsByTagName() can access multiple elements of DOM with the help of index. For example, document.getElementsByTagName("div")[0] or document.getElementsByTagName("div").item(0) refers to the first division element of the document Similarly, script element is created for getting JSON feed from Delicious. The call back JavaScript function displayTotalSaves() is used for handling JSON data returned from Delicious.
Read more
  • 0
  • 0
  • 1757

article-image-creating-our-first-jquery-plugin
Packt
14 Oct 2010
7 min read
Save for later

Creating Our First jQuery Plugin

Packt
14 Oct 2010
7 min read
  jQuery Plugin Development Beginner's Guide A practical straightforward guide for creating your first jQuery plugin Utilize jQuery's plugin framework to create a wide range of useful jQuery plugins from scratch Understand development patterns and best practices and move up the ladder to master plugin development Discover the ins and outs of some of the most popular jQuery plugins in action A Beginner's Guide packed with examples and step-by-step instructions to quickly get your hands dirty in developing high quality jQuery plugins         Read more about this book       (For more resources on jQuery, see here.) Defining our own default plugin structure To make things easier to remember and apply, we are going to start off with the definition of what we will be referring to when speaking of the basic template that all the plugins we are going to develop should conform to. Actually, we have already had a quick look at it earlier in the previous chapter, but there's something more definitely worth saying. From now on, we will call the following code the default structure for our plugins. This is what we will promptly copy and paste into each file we're going to write a plugin into. jQuery.fn.PLUGINNAME = function() { return this.each(function() { // code });} Needless to say, the this.each loop iterates all of the matching elements. We return the jQuery object (this) to allow chaining. We extend the jQuery.fn object; all of the code will be put inside the function. Also: The file name of every plugin we're going to develop will bejquery.PLUGINNAME.js. For the moment, remember to always avoid referring to the jQuery object with the dollar sign ($), to prevent possible conflicts with other libraries. We'll get to using aliases very soon. All of the functions that we write to make our plugin work should be private and not accessible from outside, in an attempt to avoid cluttering and possible backwards incompatibility. If not from the very start, at least at the end, a user will be able to specify options to control the plugin behavior. Default options for the plugin will be publicly accessible to allow for easier customization with minimal code. The directory that the plugin resides in will also contain two other files, by default: index.html: This is our test page. jquery.js: This is the jQuery library that we need to make things work. Setting the basics for our first plugin As our first plugin, we might want to create something uncomplicated but somewhat impressive: what about something that, when the cursor is hovering over an element, substitutes the text contained with some words of our choice? Time for action – our first plugin, Part I Getting started in creating jQuery plugins in not difficult at all. For example, creating this simple plugin should help us in understanding how things actually work. Given that our plugin name is txtHover, create all the directories and files we need by default, and copy over the jquery.js file. Copy the default structure for our plugins to the plugin file and make sure the function is named accordingly. It should look like this: jQuery.fn.txtHover = function() { return this.each(function() { // code });}; Nothing's easier to do than change the text contained in some element. Inside the plugin function, write the following to let the trick happen: jQuery(this).text("Text changed"); To test this in action, we can modify the HTML document to look like this: <!DOCTYPE html><html><head> <script src="jquery.js"></script> <script src="jquery.txthover.js"></script> <script> $(document).ready(function() { $("p#one").txtHover(); }); </script></head><body> <p id="one">Some text.</p></body></html> Unfortunately, the result is neither fancy nor satisfactory—something we've experienced earlier too. But we're just getting started; we won't stop here this time! What just happened? The plugin is working correctly so far. When the page loads, the text is changed to what we had defined into the plugin code. However, there are a couple of things to pay attention to: The function text() from the jQuery API expects either one or no arguments to be passed: if there is no argument the function returns the current content of the selected element. The text string passed as an argument substitutes the element text otherwise. There are, however, some similarities with the html() function, which treats the text it operates on as if it were HTML code. That is, passing any tag to the html() function results in having the element possibly containing other elements after the operation (also, the same applies for getting HTML code from within the element), whereas the this function will just treat the HTML code as plain text and not affect any element hierarchy. The fact that the text cannot be changed, unless we directly modify the code of the plugin. Getting a step farther Despite the good realization, our plugin still misses the point. Our goal was to activate the text substitution whenever the mouse pointer hovered over the text to be replaced, whereas our current implementation does it right after the page is loaded. We put it inside the "document ready" statement, after all! Time for action – our first plugin, Part II: Hovering By adding little pieces of code one at a time, we can easily understand what we are going to do and which is the best layout for our plugin. Activating the plugin whenever the mouse pointer hovers over the selected elements is surely another little step that adds up to reach our final goal. Back to our plugin file, we have to change the code so that the whole mechanism activates when the hover event is triggered. jQuery provides a function called hover(), which we can use to achieve our objective: jQuery.fn.txtHover = function() { return this.each(function() { jQuery(this).hover(function() { jQuery(this).text("Mouse hovered"); }); });}; Now, on to testing. Once the mouse pointer hovers over the text, it is effectively replaced by our string. But even if the mouse is moved, the text doesn't revert to the original. In fact, looking at the hover documentation, we see the function can also take a second argument, that is, the pointer to a function to be executed when the mouse goes off the element. Our modified code will now look like the following: jQuery.fn.txtHover = function() { return this.each(function() { var oldTxt = jQuery(this).text(); jQuery(this).hover(function() { jQuery(this).text("Mouse hover"); }, function() { jQuery(this).text(oldTxt); }); });}; The result is somewhat better now: the text is changed when we leave the pointer on the paragraph, and is changed again to its original form once the pointer is moved away. What just happened? We might be a little more satisfied with this evolution of our plugin, even though it's far from complete. Its functioning is fairly straightforward: we have made use of a variable (oldTxt) to store the old content, and we then have proceeded to using two anonymous functions (function(){ }), passed as arguments to the hover() function, to handle the mouse hover event (write our string) and the mouse out event (text back to original). There's still something to do though: We have used far too many instances of $(this) in our code and, on a larger scale application, a lot of memory would be wasted this way. It will be incredibly better for performance to make up a variable and use it every time we refer to the element with $(this). The text cannot be changed, unless we directly modify the code of the plugin. Have a go hero – html () versus text () Read the documentation for the html() function. Create a plugin that, once the mouse pointer hovers over an element, displays the HTML code of its content. The content should then change back to normal once the mouse pointer is moved away from that space. What happens if the html() and text() functions are used one inside the other, that is, $(sel).text($(sel).html()) or $(sel).html($(sel).text())? Just play around a little bit.
Read more
  • 0
  • 0
  • 1751

article-image-working-entities-google-web-toolkit-2
Packt
19 Jan 2011
9 min read
Save for later

Working with Entities in Google Web Toolkit 2

Packt
19 Jan 2011
9 min read
  Google Web Toolkit 2 Application Development Cookbook Over 70 simple but incredibly effective practical recipes to develop web applications using GWT with JPA , MySQL and i Report Create impressive, complex browser-based web applications with GWT 2 Learn the most effective ways to create reports with parameters, variables, and subreports using iReport Create Swing-like web-based GUIs using the Ext GWT class library Develop applications using browser quirks, Javascript,HTML scriplets from scratch Part of Packt's Cookbook series: Each recipe is a carefully organized sequence of instructions to complete the task as efficiently as possible         Read more about this book       (For more resources on GWT, see here.) Finding an entity In this recipe, we are going to write the code to find an entity. From the client side, the ID of the entity will be passed to the server; the server will find the entity in the database using the JPA controller class, and then return the entity to the client in order to display it. How to do it... Declare the following method in the GWTService interface: public BranchDTO findBranch(int branchId); Declare the asynchronous version of the above method in GWTServiceAsync interface public void findBranch(int branchId, AsyncCallback<BranchDTO> asyncCallback); Implement this method in GWTServiceImpl class @Override public BranchDTO findBranch(int branchId) { Branch branch=branchJpaController.findBranch(branchId); BranchDTO branchDTO=null; if(branch!=null) { branchDTO=new BranchDTO(); branchDTO.setBranchId(branch.getBranchId()); branchDTO.setName(branch.getName()); branchDTO.setLocation(branch.getLocation()); } return branchDTO; } Create a callback instance in client side (BranchForm in this case) to call this method as shown in the following code: final AsyncCallback<BranchDTO> callbackFind = new AsyncCallback<BranchDTO>() { @Override public void onFailure(Throwable caught) { MessageBox messageBox = new MessageBox(); messageBox.setMessage("An error occured! Cannot complete the operation"); messageBox.show(); clear(); } @Override public void onSuccess(BranchDTO result) { branchDTO=result; if(result!=null) { branchIdField.setValue(""+branchDTO.getBranchId()); nameField.setValue(branchDTO.getName()); locationField.setValue(branchDTO.getLocation()); } else { MessageBox messageBox = new MessageBox(); messageBox.setMessage("No such Branch found"); messageBox.show(); clear(); } } }; Write the event-handling code for the find button as follows: findButton.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { MessageBox inputBox = MessageBox.prompt("Input", "Enter the Branch ID"); inputBox.addCallback(new Listener<MessageBoxEvent>() { public void handleEvent(MessageBoxEvent be) { int branchId = Integer.parseInt(be.getValue()); ((GWTServiceAsync)GWT.create(GWTService.class)). findBranch(branchId,callbackFind); } }); } }); How it works... Here, the steps for calling the RPC method are the same as we had done for the add/save operation. The only difference is the type of the result we have received from the server. We have passed the int branch ID and have received the complete BrachDTO object, from which the values are shown in the branch form. Updating an entity In this recipe, we are going to write the code to update an entity. The client will transfer the DTO of updated object, and the server will update the entity in the database using the JPA controller class. How to do it... Declare the following method in the GWTService interface: public boolean updateBranch(BranchDTO branchDTO); Declare the asynchronous version of this method in the GWTServiceAsync interface: public void updateBranch(BranchDTO branchDTO, AsyncCallback<java.lang.Boolean> asyncCallback); Implement the method in the GWTServiceImpl class: @Override public boolean updateBranch(BranchDTO branchDTO) { boolean updated=false; try { branchJpaController.edit(new Branch(branchDTO)); updated=true; } catch (IllegalOrphanException ex) { Logger.getLogger(GWTServiceImpl.class.getName()). log(Level.SEVERE, null, ex); } catch (NonexistentEntityException ex) { Logger.getLogger(GWTServiceImpl.class.getName()). log(Level.SEVERE, null, ex); } catch (Exception ex) { Logger.getLogger(GWTServiceImpl.class.getName()). log(Level.SEVERE, null, ex); } return updated; } Create a callback instance for this method in the client side (BranchForm in this case, if it is not created yet): final AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() { MessageBox messageBox = new MessageBox(); @Override public void onFailure(Throwable caught) { messageBox.setMessage("An error occured! Cannot complete the operation"); messageBox.show(); } @Override public void onSuccess(Boolean result) { if (result) { messageBox.setMessage("Operation completed successfully"); } else { messageBox.setMessage("An error occured! Cannot complete the operation"); } messageBox.show(); } }; Write the event handle code for the update button: updateButton.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { branchDTO.setName(nameField.getValue()); branchDTO.setLocation(locationField.getValue()); ((GWTServiceAsync)GWT.create(GWTService.class)). updateBranch(branchDTO,callback); clear(); } }); How it works... This operation is also almost the same as the add operation shown previously. The difference here is the method of controller class. The method edit of the controller class is used to update an entity. Deleting an entity In this recipe, we are going to write the code to delete an entity. The client will transfer the ID of the object, and the server will delete the entity from the database using the JPA controller class. How to do it... Declare the following method in the GWTService interface public boolean deleteBranch(int branchId); Declare the asynchronous version of this method in GWTServiceAsync interface public void deleteBranch(int branchId, AsyncCallback<java.lang.Boolean> asyncCallback); Implement the method in GWTServiceImpl class @Override public boolean deleteBranch(int branchId) { boolean deleted=false; try { branchJpaController.destroy(branchId); deleted=true; } catch (IllegalOrphanException ex) { Logger.getLogger(GWTServiceImpl.class.getName()). log(Level.SEVERE, null, ex); } catch (NonexistentEntityException ex) { Logger.getLogger(GWTServiceImpl.class.getName()). log(Level.SEVERE, null, ex); } return deleted; } Create a callback instance for this method in the client side (BranchForm in this case, if it is not created yet): final AsyncCallback<Boolean> callback = new AsyncCallback<Boolean>() { MessageBox messageBox = new MessageBox(); @Override public void onFailure(Throwable caught) { messageBox.setMessage("An error occured! Cannot complete the operation"); messageBox.show(); } @Override public void onSuccess(Boolean result) { if (result) { messageBox.setMessage("Operation completed successfully"); } else { messageBox.setMessage("An error occured! Cannot complete the operation"); } messageBox.show(); } }; Write the event handling code for the delete button: deleteButton.addSelectionListener(new SelectionListener<ButtonEvent>() { @Override public void componentSelected(ButtonEvent ce) { ((GWTServiceAsync)GWT.create(GWTService.class)). deleteBranch(branchDTO.getBranchId(),callback); clear(); } }); Managing a list for RPC Sometimes, we need to transfer a list of objects as java.util.List (or a collection) back and forth between the server and the client. We already know from the preceding recipes that the JPA entity class objects are not transferable directly using RPC. Because of the same reason, any list of the JPA entity class is not transferable directly. To transfer java.util.List using RPC, the list must contain objects from DTO classes only. In this recipe, we will see how we can manage a list for RPC. In our scenario, we can consider two classes—Customer and Sales. The association between these two classes is that one customer makes zero or more sales and one sale is made by one customer. Because of such an association, the customer class contains a list of sales, and the sales class contains a single instance of customer class. For example, we want to transfer the full customer object with the list of sales made by this customer. Let's see how we can make that possible. How to do it... Create DTO classes for Customer and Sales (CustomerDTO and SalesDTO, respectively). In the following table, the required changes in data types are shown for the entity and DTO class attributes. The list in the DTO class contains objects of only the DTO class; on the other hand, the list of the entity class contains objects of entity class. Define the following constructor in the Customer entity class: public Customer(CustomerDTO customerDTO) { setCustomerNo(customerDTO.getCustomerNo()); setName(customerDTO.getName()); setAddress(customerDTO.getAddress()); setContactNo(customerDTO.getContactNo()); List<SalesDTO> salesDTOList=customerDTO.getSalesList(); salesList = new ArrayList<Sales>(); for(int i=0;i<salesDTOList.size();i++) { SalesDTO salesDTO=salesDTOList.get(i); Sales sales=new Sales(salesDTO); salesList.add(sales); } } Define the following constructor in the Sales entity class: public Sales(SalesDTO salesDTO) { setSalesNo(salesDTO.getSalesNo()); setSalesDate(salesDTO.getSalesDate()); setCustomer(new Customer(salesDTO.getCustomer())); // there's more but not relevant for this recipe } How it works... Now in the server side, the entity classes, Customer and Sales, will be used, and in the client side, CustomerDTO and SalesDTO, will be used. Constructors with DTO class type argument are defined for the mapping between entity class and DTO class. But here, the addition is the loop used for creating the list. From the CustomerDTO class, we get a list of SalesDTO. The loop gets one SalesDTO from the list, converts it to Sales, and adds it in the Sales list—that's all. Authenticating a user through username and password In this recipe, we are going to create the necessary methods to authenticate a user through a login process. Getting ready Create the DTO class for the entity class Users. How to do it... Declare the following method in the GWTService interface: public UsersDTO login(String username,String password); Declare the following method in the GWTServiceAsync interface: public void login(String username, String password, AsyncCallback<UsersDTO> asyncCallback); Implement the method in the GWTServiceImpl class: @Override public UsersDTO login(String username, String password) { UsersDTO userDTO = null; UsersJpaController usersJpaController = new UsersJpaController(); Users user = (Users) usersJpaController.findUsers(username); if (user != null) { if (user.getPassword().equals(password)) { userDTO=new UsersDTO(); userDTO.setUserName(user.getUserName()); userDTO.setPassword(user.getPassword()); EmployeeDTO employeeDTO= new EmployeeDTO(user.getEmployee().getEmployeeId()); employeeDTO.setName(user.getEmployee().getName()); userDTO.setEmployeeDTO(employeeDTO); } } return userDTO; } How it works... A username and password are passed to the method. An object of the UsersJpaController class is created to find the Users object based on the given username. If the find method returns null, it means that no such user exists. Otherwise, the password of the Users object is compared with the given password. If both the passwords match, a UsersDTO object is constructed and returned. The client will call this method during the login process. If the client gets null, the client should handle it accordingly, as the username/password is not correct. If it is not null, the user is authenticated. Summary In this article we how we can manage entities in GWT RPC. Specifically, we covered the following: Finding an entity Updating an entity Deleting an entity Managing a list for RPC Authenticating a user through username and password Further resources on this subject: Google Web Toolkit 2: Creating Page Layout [Article] Communicating with Server using Google Web Toolkit RPC [Article] Password Strength Checker in Google Web Toolkit and AJAX [Article] Google Web Toolkit GWT Java AJAX Programming [Book] Google Web Toolkit 2 Application Development Cookbook [Book]
Read more
  • 0
  • 0
  • 1731
article-image-baritem-class-and-radoutlookbar-control
Packt
18 Feb 2014
6 min read
Save for later

The BarItem class and the RadOutlookBar control

Packt
18 Feb 2014
6 min read
(For more resources related to this topic, see here.) The next aspect of the system we want to review is the BarItem class. The design of this class is set up to be used by the RadOutlookBarItem and RadMenuItem classes. The reason for this setup was to match the properties of the Telerik item classes. The following is a screenshot of the class design: The main properties include Header, Position, and ReferId. The Header property is set up to match the Header property from the RadOutlookBarItem and RadmenuItem classes. The Position property orders the items on the system for proper display, and the ReferId property creates the structure of the view. The ReferId values are set up so that if the ReferId property is zero, this item becomes the header, otherwise the rest of the items become the items under that main item. Now that we've covered the new concepts within this article, let's start to work with the navigation containers for Telerik. The next sections of this article will cover the RadOutlookBar and RadMenu controls using the concepts from this section to load these controls based on the level of user access. RadOutlookBar The first control I will review in this article will be the RadOutlookBar control. This control is unique to the Telerik toolset. The standard Visual Studio control library does not contain a control like the RadOutlookBar control. The first example I will review will be to set the binding of the control's tabs using both a list of class objects from the object layer, and the database to populate the list of objects and authenticate the user. The first step will be to create a new window in the current WPF project; name this new window Chap5OutlookWindow.xaml. Once you have created the new window, you will need to add the RadOutlookBar control: RadOutlookBar: Name the outlook bar RadTestOutlook The final appearance of the window should be the following screenshot: Notice that the RadOutlookBar control is already loaded with the options. This is the fully functioning example, but gives you an idea for how the window should look once we've finished this section. RadOutlook with GenericList, DataBinding, and database security This is the first example of populating the RadOutlookBar with the menu links from the database. The concept we are demonstrating is that the menu links inside the RadOutlookBar control will be populated based on the user that is authenticated into the system. In this example, we will be using database security. This means that the database will store the username and password, and security link information for the RadOutlookBar control. Since we don't have a login form to gather the username and password, we will create the user information within the App.xaml.cs file instead. This will allow us to simulate the login process and authenticate the user in the system. This should not be done for a production application—this setup is for demonstration purposes only. Hard-coding a username and password is always a bad practice in a real-world application. The following screenshot shows how the code should look inside the App.xaml.cs file: Let's review the preceding code. The first step is to create an instance of the UserEntity class. The next step is to determine the type of security the system will be using to authenticate the user. The app.config file has a setting for the type of security as shown in the following line of code: <add key="SecurityType" value="DB"/> This key value is passed to the system, and used by the system to determine which type of security is used in the App.xaml.cs class. The value is read by the system; it sets an enum property from the UserEntity class called SecurityType. This enumeration is then evaluated to determine the security setup for the system. The next step is to set the UserName and UserChkPwd properties. Once these properties are set we can then call the Authenticate method to verify the user information against the database. The next step will be to set the CurrentUser property in the application request class. This object is passed to each window to persist base application information to each window. The final step will be to create an instance of the OutlookBarWindow class to open the window. Notice the code for the instance; we are passing the AppRequest object to the window using the instance method of the window. The following screenshot is the instance code: Now that the window code is set up, let's review the LoadRadOutlook method from the BaseWindow class. This method requires two values: the OutlookBar object to be loaded, and a generic list of BarItem objects. The BarItem class takes the information from the database and loads the RadOutlookBar control using BarItems to create the RadOutlookBarItem objects to load the RadOutlookBar control. The LoadRadOutlook method also creates a RadTreeView control of the options within each RadOutlookBarItem object. The database version then handles the gathering of the BarItem class and loading the RadOutlookBar control using a method called FetchMenuOptions. This method takes BarItems from the database query, and created a RadOutlookBar object with all the menu options for the current user. This method gathers the menu information based on the current username and generates a generic list of the BarItem classes. This list is used by the BaseWindow class to load the RadOutlookBar control. RadOutlookBar using generic list binding with XML security The next method for populating the RadOutlookBar control on the window will be to use a serialized XML to populate the generic list of objects to load the RadOutlookBar control. The XML file has the group information and pulls the BarItem objects based on the user's group information. The example we will be using has the group information hard-coded into the group list, but this is just an example. You should not hard-code the groups in a real-world application. Here is the method for gathering the menu items from the XML file: Notice that we first load the XDocument object, then deserialize the XDocument object to gather the list of BarItem objects. Once the full list is loaded, we use a Linq query to gather the items based on the user group for the current user. Now that we have that new list, we can populate the UserMenuItems property for use in the application. The application then calls the LoadOutlookBar method to generate the RadOutlookBar control again. Summary Thus in this article we learned what a RadOutlookBar control is and how it can be used with GenericList, DataBinding, database security and generic list binding with XML security. We also had a glance over the BarItem class and how the design of this class is set up to be used by the RadOutlookBarItem and RadMenuItem classes. Resources for Article: Further resources on this subject: WPF 4.5 Application and Windows [Article] Windows Presentation Foundation Project - Basics of Working [Article] Introduction to Web Experience Factory [Article]
Read more
  • 0
  • 0
  • 1712

article-image-structure-applications
Packt
21 Apr 2015
21 min read
Save for later

Structure of Applications

Packt
21 Apr 2015
21 min read
In this article by Colin Ramsay, author of the book Ext JS Application Development Blueprints, we will learn that one of the great things about imposing structure is that it automatically gives predictability (a kind of filing system in which we immediately know where a particular piece of code should live). The same applies to the files that make up your application. Certainly, we could put all of our files in the root of the website, mixing CSS, JavaScript, configuration and HTML files in a long alphabetical list, but we'd be losing out on a number of opportunities to keep our application organized. In this article, we'll look at: Ideas to structure your code The layout of a typical Ext JS application Use of singletons, mixins, and inheritance Why global state is a bad thing Structuring your application is like keeping your house in order. You'll know where to find your car keys, and you'll be prepared for unexpected guests. (For more resources related to this topic, see here.) Ideas for structure One of the ways in which code is structured in large applications involves namespacing (the practice of dividing code up by naming identifiers). One namespace could contain everything relating to Ajax, whereas another could contain classes related to mathematics. Programming languages (such as C# and Java) even incorporate namespaces as a first-class language construct to help with code organization. Separating code from directories based on namespace becomes a sensible extension of this: From left: Java's Platform API, Ext JS 5, and .NET Framework A namespace identifier is made up of one or more name tokens, such as "Java" or "Ext", "Ajax" or "Math", separated by a symbol, in most cases a full stop/period. The top level name will be an overarching identifier for the whole package (such as "Ext") and will become less specific as names are added and you drill down into the code base. The Ext JS source code makes heavy use of this practice to partition UI components, utility classes, and all the other parts of the framework, so let's look at a real example. The GridPanel component is perhaps one of the most complicated in the framework; a large collection of classes contribute to features (such as columns, cell editing, selection, and grouping). These work together to create a highly powerful UI widget. Take a look at the following files that make up GridPanel: The Ext JS grid component's directory structure The grid directory reflects the Ext.grid namespace. Likewise, the subdirectories are child namespaces with the deepest namespace being Ext.grid.filters.filter. The main Panel and View classes: Ext.grid.Grid and Ext.grid.View respectively are there in the main director. Then, additional pieces of functionality, for example, the Column class and the various column subclasses are further grouped together in their own subdirectories. We can also see a plugins directory, which contains a number of grid-specific plugins. Ext JS actually already has an Ext.plugins namespace. It contains classes to support the plugin infrastructure as well as plugins that are generic enough to apply across the entire framework. In the event of uncertainty regarding the best place in the code base for a plugin, we might mistakenly have put it in Ext.plugins. Instead, Ext JS follows best practice and creates a new, more specific namespace underneath Ext.grid. Going back to the root of the Ext JS framework, we can see that there are only a few files at the top level. In general, these will be classes that are either responsible for orchestrating other parts of the framework (such as EventManager or StoreManager) or classes that are widely reused across the framework (such as Action or Component). Any more specific functionality should be namespaced in a suitably specific way. As a rule of thumb, you can take your inspiration from the organization of the Ext JS framework, though as a framework rather than a full-blown application. It's lacking some of the structural aspects we'll talk about shortly. Getting to know your application When generating an Ext JS application using Sencha Cmd, we end up with a code base that adheres to the concept of namespacing in class names and in the directory structure, as shown here: The structure created with Sencha Cmd's "generate app" feature We should be familiar with all of this, as it was already covered when we discussed MVVM in Ext JS. Having said that, there are some parts of this that are worth examining further to see whether they're being used to the full. /overrides This is a handy one to help us fall into a positive and predictable pattern. There are some cases where you need to override Ext JS functionality on a global level. Maybe, you want to change the implementation of a low-level class (such as Ext.data.proxy.Proxy) to provide custom batching behavior for your application. Sometimes, you might even find a bug in Ext JS itself and use an override to hotfix until the next point release. The overrides directory provides a logical place to put these changes (just mirror the directory structure and namespacing of the code you're overriding). This also provides us with a helpful rule, that is, subclasses go in /app and overrides go in /overrides. /.sencha This contains configuration information and build files used by Sencha Cmd. In general, I'd say try and avoid fiddling around in here too much until you know Sencha Cmd inside out because there's a chance you'll end up with nasty conflicts if you try and upgrade to a newer version of Sencha Cmd. bootstrap.js, bootstrap.json, and bootstrap.css The Ext JS class system has powerful dependency management through the requires feature, which gives us the means to create a build that contains only the code that's in use. The bootstrap files contain information about the minimum CSS and JavaScript needed to run your application as provided by the dependency system. /packages In a similar way to something like Ruby has RubyGems and Node.js has npm, Sencha Cmd has the concept of packages (a bundle which can be pulled into your application from a local or remote source). This allows you to reuse and publish bundles of functionality (including CSS, images, and other resources) to reduce copy and paste of code and share your work with the Sencha community. This directory is empty until you configure packages to be used in your app. /resources and SASS SASS is a technology that aids in the creation of complex CSS by promoting reuse and bringing powerful features (such as mixins and functions) to your style sheets. Ext JS uses SASS for its theme files and encourages you to use it as well. index.html We know that index.html is the root HTML page of our application. It can be customized as you see fit (although, it's rare you'll need to). There's one caveat and it's written in a comment in the file already: <!-- The line below must be kept intact for Sencha Cmd to build your application --><script id="microloader" type="text/javascript" src="bootstrap.js"></script> We know what bootstrap.js refers to (loading up our application and starting to fulfill its dependencies according to the current build). So, heed the comment and leave this script tag, well, alone! /build and build.xml The /build directory contains build artifacts (the files created when the build process is run). If you run a production build, then you'll get a directory inside /build called production and you should use only these files when deploying. The build.xml file allows you to avoid tweaking some of the files in /.sencha when you want to add some extra functionality to a build process. If you want to do something before, during, or after the build, this is the place to do it. app.js This is the main JavaScript entry point to your application. The comments in this file advise avoiding editing it in order to allow Sencha Cmd to upgrade it in the future. The Application.js file at /app/Application.js can be edited without fear of conflicts and will enable you to do the majority of things you might need to do. app.json This contains configuration options related to Sencha Cmd and to boot your application. When we refer to the subject of this article as a JavaScript application, we need to remember that it's just a website composed of HTML, CSS, and JavaScript as well. However, when dealing with a large application that needs to target different environments, it's incredibly useful to augment this simplicity with tools that assist in the development process. At first, it may seem that the default application template contains a lot of cruft, but they are the key to supporting the tools that will help you craft a solid product. Cultivating your code As you build your application, there will come a point at which you create a new class and yet it doesn't logically fit into the directory structure Sencha Cmd created for you. Let's look at a few examples. I'm a lumberjack – let's go log in Many applications have a centralized SessionManager to take care of the currently logged in user, perform authentication operations, and set up persistent storage for session credentials. There's only one SessionManager in an application. A truncated version might look like this: /** * @class CultivateCode.SessionManager * @extends extendsClass * Description */ Ext.define('CultivateCode.SessionManager', {    singleton: true,    isLoggedIn: false,      login: function(username, password) {        // login impl    },        logout: function() {        // logout impl    },        isLoggedIn() {        return isLoggedIn;    } }); We create a singleton class. This class doesn't have to be instantiated using the new keyword. As per its class name, CultivateCode.SessionManager, it's a top-level class and so it goes in the top-level directory. In a more complicated application, there could be a dedicated Session class too and some other ancillary code, so maybe, we'd create the following structure: The directory structure for our session namespace What about user interface elements? There's an informal practice in the Ext JS community that helps here. We want to create an extension that shows the coordinates of the currently selected cell (similar to cell references in Excel). In this case, we'd create an ux directory—user experience or user extensions—and then go with the naming conventions of the Ext JS framework: Ext.define('CultivateCode.ux.grid.plugins.CoordViewer', {    extend: 'Ext.plugin.Abstract',    alias: 'plugin.coordviewer',      mixins: {        observable: 'Ext.util.Observable'    },      init: function(grid) {        this.mon(grid.view, 'cellclick', this.onCellClick, this);    },      onCellClick: function(view, cell, colIdx, record, row, rowIdx, e) {        var coords = Ext.String.format('Cell is at {0}, {1}', colIdx, rowIdx)          Ext.Msg.alert('Coordinates', coords);    } }); It looks a little like this, triggering when you click on a grid cell: Also, the corresponding directory structure follows directly from the namespace: You can probably see a pattern emerging already. We've mentioned before that organizing an application is often about setting things up to fall into a position of success. A positive pattern like this is a good sign that you're doing things right. We've got a predictable system that should enable us to create new classes without having to think too hard about where they're going to sit in our application. Let's take a look at one more example of a mathematics helper class (one that is a little less obvious). Again, we can look at the Ext JS framework itself for inspiration. There's an Ext.util namespace containing over 20 general classes that just don't fit anywhere else. So, in this case, let's create CultivateCode.util.Mathematics that contains our specialized methods for numerical work: Ext.define('CultivateCode.util.Mathematics', {    singleton: true,      square: function(num) {        return Math.pow(num, 2);    },      circumference: function(radius) {        return 2 * Math.PI * radius;    } }); There is one caveat here and it's an important one. There's a real danger that rather than thinking about the namespace for your code and its place in your application, a lot of stuff ends up under the utils namespace, thereby defeating the whole purpose. Take time to carefully check whether there's a more suitable location for your code before putting it in the utils bucket. This is particularly applicable if you're considering adding lots of code to a single class in the utils namespace. Looking again at Ext JS, there are lots of specialized namespaces (such as Ext.state or Ext.draw. If you were working with an application with lots of mathematics, perhaps you'd be better off with the following namespace and directory structure: Ext.define('CultivateCode.math.Combinatorics', {    // implementation here! }); Ext.define('CultivateCode.math.Geometry', {    // implementation here! }); The directory structure for the math namespace is shown in the following screenshot: This is another situation where there is no definitive right answer. It will come to you with experience and will depend entirely on the application you're building. Over time, putting together these high-level applications, building blocks will become second nature. Money can't buy class Now that we're learning where our classes belong, we need to make sure that we're actually using the right type of class. Here's the standard way of instantiating an Ext JS class: var geometry = Ext.create('MyApp.math.Geometry'); However, think about your code. Think how rare it's in Ext JS to actually manually invoke Ext.create. So, how else are the class instances created? Singletons A singleton is simply a class that only has one instance across the lifetime of your application. There are quite a number of singleton classes in the Ext JS framework. While the use of singletons in general is a contentious point in software architecture, they tend to be used fairly well in Ext JS. It could be that you prefer to implement the mathematical functions (we discussed earlier) as a singleton. For example, the following command could work: var area = CultivateCode.math.areaOfCircle(radius); However, most developers would implement a circle class: var circle = Ext.create('CultivateCode.math.Circle', { radius: radius }); var area = circle.getArea(); This keeps the circle-related functionality partitioned off into the circle class. It also enables us to pass the circle variable round to other functions and classes for additional processing. On the other hand, look at Ext.Msg. Each of the methods here are fired and forget, there's never going to be anything to do further actions on. The same is true of Ext.Ajax. So, once more we find ourselves with a question that does not have a definitive answer. It depends entirely on the context. This is going to happen a lot, but it's a good thing! This article isn't going to teach you a list of facts and figures; it's going to teach you to think for yourself. Read other people's code and learn from experience. This isn't coding by numbers! The other place you might find yourself reaching for the power of the singleton is when you're creating an overarching manager class (such as the inbuilt StoreManager or our previous SessionManager example). One of the objections about singletons is that they tend to be abused to store lots of global state and break down the separation of concerns we've set up in our code as follows: Ext.define('CultivateCode.ux.grid.GridManager', {       singleton: true,    currentGrid: null,    grids: [],      add: function(grid) {        this.grids.push(grid);    },      setCurrentGrid: function(grid) {        this.focusedGrid = grid;    } }); No one wants to see this sort of thing in a code base. It brings behavior and state to a high level in the application. In theory, any part of the code base could call this manager with unexpected results. Instead, we'd do something like this: Ext.define('CultivateCode.view.main.Main', {    extend: 'CultivateCode.ux.GridContainer',      currentGrid: null,    grids: [],      add: function(grid) {        this.grids.push(grid);    },      setCurrentGrid: function(grid) {        this.currentGrid = grid;    } }); We still have the same behavior (a way of collecting together grids), but now, it's limited to a more contextually appropriate part of the grid. Also, we're working with the MVVM system. We avoid global state and organize our code in a more correct manner. A win all round. As a general rule, if you can avoid using a singleton, do so. Otherwise, think very carefully to make sure that it's the right choice for your application and that a standard class wouldn't better fit your requirements. In the previous example, we could have taken the easy way out and used a manager singleton, but it would have been a poor choice that would compromise the structure of our code. Mixins We're used to the concept of inheriting from a subclass in Ext JS—a grid extends a panel to take on all of its functionality. Mixins provide a similar opportunity to reuse functionality to augment an existing class with a thin slice of behavior. An Ext.Panel "is an" Ext.Component, but it also "has a" pinnable feature that provides a pin tool via the Ext.panel.Pinnable mixin. In your code, you should be looking at mixins to provide a feature, particularly in cases where this feature can be reused. In the next example, we'll create a UI mixin called shakeable, which provides a UI component with a shake method that draws the user's attention by rocking it from side to side: Ext.define('CultivateCode.util.Shakeable', {    mixinId: 'shakeable',      shake: function() {        var el = this.el,            box = el.getBox(),            left = box.x - (box.width / 3),            right = box.x + (box.width / 3),            end = box.x;          el.animate({            duration: 400,            keyframes: {                33: {                      x: left                },                66: {                    x: right                },                 100: {                    x: end                }            }        });    } }); We use the animate method (which itself is actually mixed in Ext.Element) to set up some animation keyframes to move the component's element first left, then right, then back to its original position. Here's a class that implements it: Ext.define('CultivateCode.ux.button.ShakingButton', {    extend: 'Ext.Button',    mixins: ['CultivateCode.util.Shakeable'],    xtype: 'shakingbutton' }); Also it's used like this: var btn = Ext.create('CultivateCode.ux.button.ShakingButton', {    text: 'Shake It!' }); btn.on('click', function(btn) {    btn.shake(); }); The button has taken on the new shake method provided by the mixin. Now, if we'd like a class to have the shakeable feature, we can reuse this mixin where necessary. In addition, mixins can simply be used to pull out the functionality of a class into logical chunks, rather than having a single file of many thousands of lines. Ext.Component is an example of this. In fact, most of its core functionality is found in classes that are mixed in Ext.Component. This is also helpful when navigating a code base. Methods that work together to build a feature can be grouped and set aside in a tidy little package. Let's take a look at a practical example of how an existing class could be refactored using a mixin. Here's the skeleton of the original: Ext.define('CultivateCode.ux.form.MetaPanel', {    extend: 'Ext.form.Panel',      initialize: function() {        this.callParent(arguments);        this.addPersistenceEvents();    },      loadRecord: function(model) {        this.buildItemsFromRecord(model);        this.callParent(arguments);    },      buildItemsFromRecord: function(model) {        // Implementation    },      buildFieldsetsFromRecord: function(model){        // Implementation    },      buildItemForField: function(field){        // Implementation    },      isStateAvailable: function(){        // Implementation    },      addPersistenceEvents: function(){      // Implementation    },      persistFieldOnChange: function(){        // Implementation    },      restorePersistedForm: function(){        // Implementation    },      clearPersistence: function(){        // Implementation    } }); This MetaPanel does two things that the normal FormPanel does not: It reads the Ext.data.Fields from an Ext.data.Model and automatically generates a form layout based on these fields. It can also generate field sets if the fields have the same group configuration value. When the values of the form change, it persists them to localStorage so that the user can navigate away and resume completing the form later. This is useful for long forms. In reality, implementing these features would probably require additional methods to the ones shown in the previous code skeleton. As the two extra features are clearly defined, it's easy enough to refactor this code to better describe our intent: Ext.define('CultivateCode.ux.form.MetaPanel', {    extend: 'Ext.form.Panel',      mixins: [        // Contains methods:        // - buildItemsFromRecord        // - buildFieldsetsFromRecord        // - buildItemForField        'CultivateCode.ux.form.Builder',          // - isStateAvailable        // - addPersistenceEvents        // - persistFieldOnChange        // - restorePersistedForm        // - clearPersistence        'CultivateCode.ux.form.Persistence'    ],      initialize: function() {        this.callParent(arguments);        this.addPersistenceEvents();    },      loadRecord: function(model) {        this.buildItemsFromRecord(model);        this.callParent(arguments);    } }); We have a much shorter file and the behavior we're including in this class is described a lot more concisely. Rather than seven or more method bodies that may span a couple of hundred lines of code, we have two mixin lines and the relevant methods extracted to a well-named mixin class. Summary This article showed how the various parts of an Ext JS application can be organized into a form that eases the development process. Resources for Article: Further resources on this subject: CreateJS – Performing Animation and Transforming Function [article] Good time management in CasperJS tests [article] The Login Page using Ext JS [article]
Read more
  • 0
  • 0
  • 1685

article-image-photo-pad
Packt
11 Sep 2013
7 min read
Save for later

Photo Pad

Packt
11 Sep 2013
7 min read
(For more resources related to this topic, see here.) Time for action – creating Photo Pad In the HTML file, we will add a toolbar with buttons for Load, Save, and Effects. <body> <div id="app"> <header>Photo Pad </header> <div id="main"> <div id="toolbar"> <div class="dropdown-menu"> <button data-action="menu">Load</button> <ul id="load-menu" data-option="file-picker" class="file-picker menu"> <li data-value="file-picker"> <input type="file" /> </li> </ul> </div> <button data-action="save">Save</button> <div class="dropdown-menu"> <button data-action="menu">Effects</button> <ul data-option="applyEffect" class="menu"> <li data-value="invert">Invert</li> </ul> </div> </div> <canvas width="0" height="0"> Sorry, your browser doesn't support canvas. </canvas> </div> <footer>Click load to choose a file</footer> </div> </body> The Load toolbar item has a drop-down menu, but instead of menu items it has a file input control in it where the user can select a file to load. The Effects item has a drop-down menu of effects. For now we just have one in there, Invert, but we will add more later. For our CSS we will copy everything we had in canvasPad.css to photoPad.css, so that we get all of the same styling for the toolbar and menus. We will also use the Toolbar object in toolbar.js. In our JavaScript file we will change the application object name to PhotoPadApp. We also need a couple of variables in PhotoPadApp. We will set the canvas variable to the <canvas> element, the context variable to the canvas's context, and define an $img variable to hold the image we will be showing. Here we initialize it to a new <img> element using jQuery: function PhotoPadApp() { var version = "5.2", canvas = $("#main>canvas")[0], context = canvas.getContext("2d"), $img = $("<img>"); The first toolbar action we will implement is the Save button, since we already have that code from Canvas Pad. We check the action in toolbarButtonClicked() to see if it's "save", and if so we get the data URL and open it in a new browser window: function toolbarButtonClicked(action) { switch (action) { case "save": var url = canvas.toDataURL(); window.open(url, "PhotoPadImage"); break; } } What just happened? We created the scaffolding for the Photo Pad application with toolbar items for Load, Save, and Effects. We implemented the save function the same as we did for Canvas Pad. The next thing we'll implement is the Load drop-down menu since we need an image to manipulate. When the Load toolbar button is clicked, it will show the drop-down menu with a file input control in it that we defined previously. All of that we get for free because it's just another drop-down menu in our toolbar. But before we can do that we need to learn about the HTML5 File API. The File API We may not be able to save files directly to the user's filesystem, but we can access files using HTML5's File API. The File API allows you to get information about, and load the contents of, files that the user selects. The user can select files using an input element with a type of file. The process for loading a file works in the following way: The user selects one or more files using a <input type="file"> element. We get the list of files from the input element's files property. The list is a FileList object containing File objects. You can enumerate over the file list and access the files just like you would an array. The File object contains three fields. name: This is the filename. It doesn't include path information. size: This is the size of the file in bytes. type: This is the MIME type, if it can be determined. Use a FileReader object to read the file's data. The file is loaded asynchronously. After the file has been read, it will call the onload event handler. FileReader has a number of methods for reading files that take a File object and return the file contents. readAsArrayBuffer(): This method reads the file contents into an ArrayBuffer object. readAsBinaryString(): This method reads the file contents into a string as binary data. readAsText(): This method reads the file contents into a string as text. readAsDataURL(): This method reads the file contents into a data URL string. You can use this as the URL for loading an image. Time for action – loading an image file Let's add some code to the start() method of our application to check if the File API is available. You can determine if a browser supports the File API by checking if the File and FileReader objects exist: this.start = function() { // code not shown... if (window.File && window.FileReader) { $("#load-menu input[type=file]").change(function(e) { onLoadFile($(this)); }); } else { loadImage("images/default.jpg"); } } First we check if the File and FileReader objects are available in the window object. If so, we hook up a change event handler for the file input control to call the onLoadFile() method passing in the <input> element wrapped in a jQuery object. If the File API is not available we will just load a default image by calling loadImage(), which we will write later. Let's implement the onLoadFile() event handler method: function onLoadFile($input) { var file = $input[0].files[0]; if (file.type.match("image.*")) { var reader = new FileReader(); reader.onload = function() { loadImage(reader.result); }; reader.readAsDataURL(file); } else { alert("Not a valid image type: " + file.type); setStatus("Error loading image!"); } } Here we get the file that was selected by looking at the file input's files array and taking the first one. Next we check the file type, which is a MIME type, to make sure it is an image. We are using the String object's regular expression match() method to check that it starts with "image". If it is an image, we create a new instance of the FileReader object. Then we set the onload event handler to call the loadImage() method, passing in the FileReader object's result field, which contains the file's contents. Lastly, we call the FileReader object's readAsDataURL() method, passing in the File object to start loading the file asynchronously. If it isn't an image file, we show an alert dialog box with an error message and show an error message in the footer by calling setStatus(). Once the file has been read, the loadImage() method will be called. Here we will use the data URL we got from the FileReader object's result field to draw the image into the canvas: function loadImage(url) { setStatus("Loading image"); $img.attr("src", url); $img[0].onload = function() { // Here "this" is the image canvas.width = this.width; canvas.height = this.height; context.drawImage(this, 0, 0); setStatus("Choose an effect"); } $img[0].onerror = function() { setStatus("Error loading image!"); } } First we set the src attribute for the image element to the data URL we got after the file was loaded. This will cause the image element to load that new image. Next we define the onload event handler for the image, so that we are notified when the image is loaded. Note that when we are inside the onload event handler, this points to the <image> element. First we change the canvas' width and height to the image's width and height. Then we draw the image on the canvas using the context's drawImage() method. It takes the image to draw and the x and y coordinates of where to draw it. In this case we draw it at the top-left corner of the canvas (0, 0). Lastly, we set an onerror event handler for the image. If an error occurs loading the image, we show an error message in the footer. What just happened? We learned how to use the File API to load an image file from the user's filesystem. After the image was loaded we resized the canvas to the size of the image and drew the image onto the canvas.
Read more
  • 0
  • 0
  • 1681
article-image-services
Packt
19 Mar 2014
12 min read
Save for later

Services

Packt
19 Mar 2014
12 min read
(For more resources related to this topic, see here.) Services A service is just a specific instance of a given class. For example, whenever you access doctrine such as $this->get('doctrine'); in a controller, it implies that you are accessing a service. This service is an instance of the Doctrine EntityManager class, but you never have to create this instance yourself. The code needed to create this entity manager is actually not that simple since it requires a connection to the database, some other configurations, and so on. Without this service already being defined, you would have to create this instance in your own code. Maybe you will have to repeat this initialization in each controller, thus making your application messier and harder to maintain. Some of the default services present in Symfony2 are as follows: The annotation reader Assetic—the asset management library The event dispatcher The form widgets and form factory The Symfony2 Kernel and HttpKernel Monolog—the logging library The router Twig—the templating engine It is very easy to create new services because of the Symfony2 framework. If we have a controller that has started to become quite messy with long code, a good way to refactor it and make it simpler will be to move some of the code to services. We have described all these services starting with "the" and a singular noun. This is because most of the time, services will be singleton objects where a single instance is needed. A geolocation service In this example, we imagine an application for listing events, which we will call "meetups". The controller makes it so that we can first retrieve the current user's IP address, use it as basic information to retrieve the user's location, and only display meetups within 50 kms of distance to the user's current location. Currently, the code is all set up in the controller. As it is, the controller is not actually that long yet, it has a single method and the whole class is around 50 lines of code. However, when you start to add more code, to only list the type of meetups that are the user's favorites or the ones they attended the most. When you want to mix that information and have complex calculations as to which meetups might be the most relevant to this specific user, the code could easily grow out of control! There are many ways to refactor this simple example. The geocoding logic can just be put in a separate method for now, and this will be a good step, but let's plan for the future and move some of the logic to the services where it belongs. Our current code is as follows: use GeocoderHttpAdapterCurlHttpAdapter; use GeocoderGeocoder; use GeocoderProviderFreeGeoIpProvider; public function indexAction()   { Initialize our geocoding tools (based on the excellent geocoding library at http://geocoder-php.org/) using the following code: $adapter = new CurlHttpAdapter(); $geocoder = new Geocoder(); $geocoder->registerProviders(array( new FreeGeoIpProvider($adapter), )); Retrieve our user's IP address using the following code: $ip = $this->get('request')->getClientIp(); // Or use a default one     if ($ip == '127.0.0.1') {   $ip = '114.247.144.250'; } Get the coordinates and adapt them using the following code so that they are roughly a square of 50 kms on each side: $result = $geocoder->geocode($ip); $lat = $result->getLatitude(); $long = $result->getLongitude(); $lat_max = $lat + 0.25; // (Roughly 25km) $lat_min = $lat - 0.25; $long_max = $long + 0.3; // (Roughly 25km) $long_min = $long - 0.3; Create a query based on all this information using the following code: $em = $this->getDoctrine()->getManager(); $qb = $em->createQueryBuilder(); $qb->select('e')     ->from('KhepinBookBundle:Meetup, 'e')     ->where('e.latitude < :lat_max')     ->andWhere('e.latitude > :lat_min')     ->andWhere('e.longitude < :long_max')     ->andWhere('e.longitude > :long_min')     ->setParameters([       'lat_max' => $lat_max,       'lat_min' => $lat_min,       'long_max' => $long_max,       'long_min' => $long_min     ]); Retrieve the results and pass them to the template using the following code: $meetups = $qb->getQuery()->execute(); return ['ip' => $ip, 'result' => $result, 'meetups' => $meetups]; } The first thing we want to do is get rid of the geocoding initialization. It would be great to have all of this taken care of automatically and we would just access the geocoder with: $this->get('geocoder');. You can define your services directly in the config.yml file of Symfony under the services key, as follows: services:   geocoder:     class: GeocoderGeocoder That is it! We defined a service that can now be accessed in any of our controllers. Our code now looks as follows: // Create the geocoding class $adapter = new GeocoderHttpAdapterCurlHttpAdapter(); $geocoder = $this->get('geocoder'); $geocoder->registerProviders(array(     new GeocoderProviderFreeGeoIpProvider($adapter), )); Well, I can see you rolling your eyes, thinking that it is not really helping so far. That's because initializing the geocoder is a bit more complex than just using the new GeocoderGeocoder() code. It needs another class to be instantiated and then passed as a parameter to a method. The good news is that we can do all of this in our service definition by modifying it as follows: services:     # Defines the adapter class     geocoder_adapter:         class: GeocoderHttpAdapterCurlHttpAdapter         public: false     # Defines the provider class     geocoder_provider:         class: GeocoderProviderFreeGeoIpProvider         public: false         # The provider class is passed the adapter as an argument         arguments: [@geocoder_adapter]     geocoder:         class: GeocoderGeocoder         # We call a method on the geocoder after initialization to set up the         # right parameters         calls:             - [registerProviders, [[@geocoder_provider]]] It's a bit longer than this, but it is the code that we never have to write anywhere else ever again. A few things to notice are as follows: We actually defined three services, as our geocoder requires two other classes to be instantiated. We used @+service_name to pass a reference to a service as an argument to another service. We can do more than just defining new Class($argument); we can also call a method on the class after it is instantiated. It is even possible to set properties directly when they are declared as public. We marked the first two services as private. This means that they won't be accessible in our controllers. They can, however, be used by the Dependency Injection Container (DIC) to be injected into other services. Our code now looks as follows: // Retrieve current user's IP address $ip = $this->get('request')->getClientIp(); // Or use a default one if ($ip == '127.0.0.1') {     $ip = '114.247.144.250'; } // Find the user's coordinates $result = $this->get('geocoder')->geocode($ip); $lat = $result->getLatitude(); // ... Remaining code is unchanged Here, our controllers are extending the BaseController class, which has access to DIC since it implements the ContainerAware interface. All calls to $this->get('service_name') are proxied to the container that constructs (if needed) and returns the service. Let's go one step further and define our own class that will directly get the user's IP address and return an array of maximum and minimum longitude and latitudes. We will create the following class: namespace KhepinBookBundleGeo; use GeocoderGeocoder; use SymfonyComponentHttpFoundationRequest; class UserLocator {     protected $geocoder;     protected $user_ip;     public function__construct(Geocoder $geocoder, Request $request) {         $this->geocoder = $geocoder;         $this->user_ip = $request->getClientIp();         if ($this->user_ip == '127.0.0.1') {             $this->user_ip = '114.247.144.250';         }     }     public function getUserGeoBoundaries($precision = 0.3) {         // Find the user's coordinates         $result = $this->geocoder->geocode($this->user_ip);         $lat = $result->getLatitude();         $long = $result->getLongitude();         $lat_max = $lat + 0.25; // (Roughly 25km)         $lat_min = $lat - 0.25;         $long_max = $long + 0.3; // (Roughly 25km)         $long_min = $long - 0.3;         return ['lat_max' => $lat_max, 'lat_min' => $lat_min,            'long_max' => $long_max, 'long_min' => $long_min];     } } It takes our geocoder and request variables as arguments, and then does all the heavy work we were doing in the controller at the beginning of the article. Just as we did before, we will define this class as a service, as follows, so that it becomes very easy to access from within the controllers: # config.yml services:     #...     user_locator:        class: KhepinBookBundleGeoUserLocator        scope: request        arguments: [@geocoder, @request] Notice that we have defined the scope here. The DIC has two scopes by default: container and prototype, to which the framework also adds a third one named request. The following table shows their differences: Scope Differences Container All calls to $this->get('service_name') return the sameinstance of the service. Prototype Each call to $this->get('service_name') returns a new instance of the service. Request Each call to $this->get('service_name') returns the same instance of the service within a request. Symfony can have subrequests (such as including a controller in Twig). Now, the advantage is that the service knows everything it needs by itself, but it also becomes unusable in contexts where there are no requests. If we wanted to create a command that gets all users' last-connected IP address and sends them a newsletter of the meetups around them on the weekend, this design would prevent us from using the KhepinBookBundleGeoUserLocator class to do so. As we see, by default, the services are in the container scope, which means they will only be instantiated once and then reused, therefore implementing the singleton pattern. It is also important to note that the DIC does not create all the services immediately, but only on demand. If your code in a different controller never tries to access the user_locator service, then that service and all the other ones it depends on (geocoder, geocoder_provider, and geocoder_adapter) will never be created. Also, remember that the configuration from the config.yml is cached when on a production environment, so there is also little to no overhead in defining these services. Our controller looks a lot simpler now and is as follows: $boundaries = $this->get('user_locator')->getUserGeoBoundaries(); // Create our database query $em = $this->getDoctrine()->getManager(); $qb = $em->createQueryBuilder(); $qb->select('e')     ->from('KhepinBookBundle:Meetup', 'e')     ->where('e.latitude < :lat_max')     ->andWhere('e.latitude > :lat_min')     ->andWhere('e.longitude < :long_max')     ->andWhere('e.longitude > :long_min')     ->setParameters($boundaries); // Retrieve interesting meetups $meetups = $qb->getQuery()->execute(); return ['meetups' => $meetups]; The longest part here is the doctrine query, which we could easily put on the repository class to further simplify our controller. As we just saw, defining and creating services in Symfony2 is fairly easy and inexpensive. We created our own UserLocator class, made it a service, and saw that it can depend on our other services such as @geocoder service. We are not finished with services or the DIC as they are the underlying part of almost everything related to extending Symfony2. Summary In this article, we saw the importance of services and also had a look at the geolocation service. We created a class, made it a service, and saw how it can depend on our other services. Resources for Article: Further resources on this subject: Developing an Application in Symfony 1.3 (Part 1) [Article] Developing an Application in Symfony 1.3 (Part 2) [Article] User Interaction and Email Automation in Symfony 1.3: Part1 [Article]
Read more
  • 0
  • 0
  • 1672

article-image-extending-search-engine-optimization-using-sitemaps-drupal-6
Packt
09 Nov 2009
5 min read
Save for later

Extending Search Engine Optimization using Sitemaps in Drupal 6

Packt
09 Nov 2009
5 min read
We have discussed some of the techniques earlier in Search Engine Optimization using Sitemaps in Drupal 6 article which mainly covered XML sitemaps. The Google spider is quite smart, but then the possibility of them missing pages on your site is also quite high. You may have pages that are not in navigation anymore or you have moved a link to a piece of content so that it's not easily accessible. A possibility is also that your site is very big for Google to just crawl it all without completely pulling all your server's resources. The solution to this is sitemaps. Google News XML Sitemap Google has created one of the most popular news sources on the Internet just by collecting and organizing news articles from other sites. It's called Google News and if you are running a news web site then you know how powerful it can be for picking up your comment. One front page article can generate 50,000 or more visitors in an hour or two. To be listed in Google News takes more than luck. You need to write great content and proactively seek to create timely and news-worthy content. If you've done that and you're still not showing up in Google news then it's time to create a Google News XML Sitemap. The Google News sitemap generator module was originally created by Adam Boyse at Webopius and is being maintained by Dave Reid. Thanks to both of you! Setting up the Google News sitemap generator module Carry out the following steps to set up the Google News sitemap generator module: Download the Google News sitemap module from http://drupal.org/project/googlenews and install it just like a normal Drupal module. Go to http://www.yourDrupalsite.com/admin/settings/googlenews or go to your admin screen, and click the Administer | Site Configuration | Google News sitemap feed link. You'll see a screen similar to the following screenshot: Select the content types that you wish to show up in the news feed. If all your story content types are newsworthy, pick Story. Your blog or page content types are probably not a good fit and selecting them may hurt the chances of your content being approved by Google. Click on Save configuration. Point your browser to http://www.yourDrupalsite.com/googlenews.xml and double check that you can see the sitemap, as shown in the following screenshot: Submitting your Google News sitemap to Google News Once you've assembled your new articles for a single publication label, submit them to Google News sitemaps by carrying out the following steps: Check Google News to see if your site is already included. If not, you can request inclusion by visiting the following link, http://www.google.com/support/news_pub/bin/request.py?ctx=answer. The inclusion process may take up to a few weeks, and you'll only be able to submit a News sitemap once this process is complete. If your site is already showing up in Google News then proceed. If not, you should wait a couple of weeks and try again. Log in to Google Webmaster Tools by pointing your browser to http://www.google.com/webmasters/tools/. On the Webmaster Tools Dashboard, click on Add next to the site you want to submit. From the Choose type drop-down menu, select News sitemap, and then type the sitemap URL, in this case http://www.yourDrupalsite.com/googlenews.xml. In the list, select the publication label for the articles. You can select only one label for each sitemap. Click on OK. URL list The XML Sitemap is the ideal choice because it allows you to specify a lot of information about the content of your site. But, say for some reason that you can't install an XML Sitemap. Maybe there's a conflict with another module that you just have to have. Perhaps your server doesn't have the power to handle the large overhead that an XML sitemap needs for large sites. Or, possibly you want to submit a sitemap to a search engine that doesn't support XML yet. Well, there is an alternative. It's not as robust but it is a functional, albeit rudimentary, solution. Just make a list of every URL in your site and put the list in one big text document with one URL on each line. Too much work, you say? Good thing there is a Drupal module that does all the work for you. It's called the URL list module. It's maintained by David K. Norman. Thank you, David! Setting up a URL list sitemap Download the Sitemap module from http://drupal.org/project/urllist and install it just like a normal Drupal module. Go to http://www.yourDrupalsite.com/admin/settings/urllist or go to your admin screen and click the Administer | Site Configuration | URL list link. You'll see the URL list screen, as shown in the following screenshot: You can adjust the settings to keep track of who accessed the URL list to submit your site to Yahoo! and to help you authenticate with Yahoo! However, you can leave all these settings untouched for now. Point your browser to http://www.yourDrupalsite.com/urllist.txt (http://www.yourDrupalsite.com/?q=urllist.txt if you don't have clean URLs installed) and you'll see your URL list sitemap, as shown in the following screenshot: You can submit this sitemap to Google, Yahoo!, and many other search engines in lieu of an XML sitemap. Just follow the same steps as defined in the Submit your XML Sitemap to Google section above but use # http://www.yourDrupalsite.com/urllist.txt as the URL. Remember to use http://www.yourDrupalsite.com/?q=urllist.txt if Google has problems with your URL.
Read more
  • 0
  • 0
  • 1661
Modal Close icon
Modal Close icon