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
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-article-building-objects-inkscape
Packt
22 May 2012
9 min read
Save for later

Building Objects in Inkscape

Packt
22 May 2012
9 min read
(For more resources on Inkscape, see here.) Working with objects Objects in Inkscape are any shapes that make up your overall drawing. This means that any text, path, or shape that you create is essentially an object. Let's start by making a simple object and then changing some of its attributes. Time for action – creating a simple object Inkscape can create predefined shapes that are part of the SVG standard. These include rectangles/squares, circles/ellipses/arcs, stars, polygons, and spirals. To create any of these shapes, you can select items from the toolbar: However, you can also create more freehand-based objects as well. Let's look at how we can create a simple freehand triangle: Select the Bezier tool: Click once where you want the first corner and then move the mouse/pointer to the next corner. A node appears with the click and then a freehand line: When you have the length of the first side of the triangle estimated, click for the second corner: Move the mouse to form the second side and click for the third corner: Move the mouse back to the first corner node and click it to form the triangle, shown as follows: Now save the file. From the main menu, select File and then Save. We will use this triangle to build a graphic later in this book, so choose a location to save so that you will know where to find the file. Now that the basic triangle is saved, let's also experiment with how we can manipulate the shape itself and/or the shape's position on the canvas. Let's start with manipulating the triangle. Select the triangle and drag a handle to a new location. You have essentially skewed the triangle, as shown in the following diagram: To change the overall shape of the triangle, select the triangle, then click the Edit path by Nodes tool (or press F2 ): Now the nodes of the triangle are displayed as follows: Nodes are points on a path that define the path's shape. Click a node and you can drag it to another location to manipulate the triangle's overall shape as follows: Double-click between two nodes to add another node and change the shape: If you decide that you don't want the extra node, click it (the node turns red), press Delete on your keyboard and it disappears. You can also use the control bar to add, delete, or manipulate the path/shape and nodes: If you want to change the position of the shape on the canvas by choosing the Select tool in the toolbox, click and drag the shape and move it where you need it to be. Change the size of the shape by also choosing the Select tool from the toolbox, clicking and holding the edge of the shape at the handle (small square or circles at edges), and dragging it outward to grow larger or inward to shrink until the shape is of the desired size. You can also rotate an object. Choose the Select tool from the toolbox and single-click the shape until the nodes turn to arrows with curves (this might require you to click the object a couple of times). When you see the curved arrow nodes, click-and-drag on a corner node to rotate the object until it is rotated and positioned correctly. No need to save this file again after we have manipulated it—unless you want to reference this new version of the triangle for future projects. What just happened? We created a free-form triangle and saved it for a future project. We also manipulated the shape in a number of ways—used the nodes to change the skew of the overall shape, added nodes to change the shape completely, and also how to move the shape around on the canvas. Fill and Stroke As you've already noticed, when creating objects in Inkscape they have color associated with them. You can fill an object with a color as well as give the object an outline or stroke. This section will explain how to change these characteristics of an object in Inkscape. Fill and Stroke dialog You can use the Fill and Stroke dialog from the main menu to change the fill colors of an object. Time for action – using the Fill and Stroke dialog Let's open the dialog and get started: Open your triangle Inkscape file again and select the triangle. From the main menu, choose Object | Fill and Stroke (or use the Shift + Ctrl + F keyboard shortcut). The Fill and Stroke dialog appears on the right-hand side of your screen. Notice it has three tabs: Fill, Stroke paint, and Stroke style , as shown in the following screenshot: Select the Fill tab (if not already selected). Here are the options for fill: Type of fill: The buttons below the Fill tab allow you to select the type of fill you would like to use. No fill (the button with the X), flat color, linear or radial gradients. In the previous example screenshot, the flat fill button is selected. Color picker : Another set of tabs below the type of the fill area are presented; RGB , CMYK, HSL, and Wheel. You can use any of these to choose a color. The most intuitive option is Wheel as it allows you to visually see all the colors and rotate a triangle to the color of your choice, as shown in the following screenshot: Once a color is chosen, then the exact color can be seen in various values on the other color picker tabs. Blur : Below the color area, you also have an option to blur the object's fill. This means that if you move the sliding lever to the right, the blur of the fill will move outward. See the following diagram for examples of an object without and with blur: Opacity: Lastly, there is the opacity slider. By moving this slider to the right you will give the object an alpha of opacity setting making it a bit more transparent. The following diagram demonstrates opacity: In the Fill and Stroke dialog , if you select the Stroke paint tab , you will notice it looks very much like the Fill tab. You can remove the stroke (outline) of the object, set the color, and determine if it is a flat color or gradient: In the last tab, Stroke style is where you can most notably set the width of the stroke: You can also use this tab to determine what types of corners or joins an object has (round or square corners) and how the end caps of the border look like. The Dashes field gives options for the stroke line type, as shown in the following screenshot: Start, Mid, and End Markers allow you to add end points to your strokes, as follows: For our triangle object, use the Fill tab and choose a green color, no stroke, and 100 percent opacity: What just happened? You learned where to open the Fill and Stroke dialog, adjust the fill of an object, use blur and opacity, and how to change the stroke color and weights of the stroke line. Next, let's learn other ways to change the fill and stroke options. Color palette bar You can also use the color palette bar to change fill color: Time for action – using the color palette Let's learn all the tips and tricks for using the color palette bar: From the palette bar, click a color and drag it from the palette onto the object to change its fill, as shown in the following diagram: You can also change an object and the stroke color in a number of other ways: Select an object on the canvas and then click a color box in the palette to immediately set the fill of an object. Select an object on the canvas and then right-click a color box in the palette. A popup menu appears with options to set the fill (and stroke). If you hold the Shift key and drag a color box onto an object, it changes the stroke color. Shift + left-click a color box to immediately set the stroke color. Note, you can use the scroll bar just below the viewable color swatches on the color palette to scroll right to see even more color choices. What just happened? You learned how to change the fill and stroke color of an object by using the color swatches on the color palette bar on the main screen of Inkscape. Dropper Yet another way to change the fill or stroke of an object is to use the dropper: Let's learn how to use it. Time for action – using the dropper tool Open an Inkscape file with objects on the canvas or create a quick object to try this out: Select an object on the canvas. Select the dropper tool from the toolbar or use the shortcut key F7 . Then click anywhere in the drawing with that tool that has the color you want to choose. The chosen color will be assigned to the selected object's fill. Alternatively, use Shift + click to set the stroke color. Be aware of the tool control bar and the dropper tool controls, shown as follows: The two buttons affect the opacity of the object, especially if it is different than the 100% setting. If Pick is disabled, then the color as chosen by the dropper looks exactly like it is on screen If Pick is enabled and Assign is disabled, then the color picked by the dropper is one that the object would have if its opacity was 100% If Pick is enabled and Assign is enabled, then the color and opacity are both copied from the picked object What just happened? By using the dropper tool, you learned how to change a color of another object on the screen.
Read more
  • 0
  • 0
  • 17486

article-image-designs-and-themes
Packt
19 May 2012
15 min read
Save for later

Designs ans Themes

Packt
19 May 2012
15 min read
(For more resources on e-Commerce, see here.) The Magento theme structure Magento allows you to customize many store aspects at some or all of the GWS levels. The same holds true for themes. You can specify the look and feel of your stores at the Global, Website, or Store levels (themes can be applied for individual store views relating to a store) by assigning a specific theme. In Magento, group of related themes is referred to as a design package. Design packages contains files that control various functional elements that are common among the themes within the package. By default, Magento Community installs two design packages: Base package: A special package that contains all the default elements for a Magento installation (we will discuss this in more detail in a moment) Default package: This contains the layout elements of the default store (look and feel) Themes within a design package contain the various elements that determine the look and feel of the site: layout files, templates, CSS, images, and JavaScript. Each design package must have at least one default theme, but can contain other theme variants. You can include any number of theme variants within a design package and use them, for example, for seasonal purposes (that is, holidays, back-to-school, and so on). The following image shows the relationship between design packages and themes: A design package and theme can be specified at the Global, Website or Store levels. Most Magento users will use the same design package for a website and all descendant stores. Usually, related stores within a website business share very similar functional elements, as well as similar style features. This is not mandatory; you are free to specify a completely different design package and theme for each store view within your website hierarchy. The Theme structure Magento divides themes into two group of files: templating and skin. Templating files contain the HTML, PHTML, and PHP code that determines the functional aspects of the pages in your Magento website. Skin files are made of CSS, image, and JavaScript files that give your site its outward design. Ingeniously, Magento further separates these areas by putting them into different directories of your installation: Templating files are stored in the app/design directory, where the extra security of this section protects the functional parts of your site design Skin files are stored within the skin directory (at the root level of the installation), and can be granted a higher permission level, as these are the files that are delivered to a visitor's browser for rendering the page Templating hierarchy Frontend theme template files (the files used to produce your store's pages) are stored within three subdirectories: layout: It contains the XML files that contain the various core information that defines various areas of a page. These files also contain meta and encoding information. template: This stores the PHTML files (HTML files that contain PHP code and processed by the PHP server engine) used for constructing the visual structure of the page. locale: This directory has files that provide additional language translations for site elements, such as labels and messages. Magento has a distinct path for storing templating files used for your website: app/design/frontend/[Design Package]/[Theme]/. Skin hierarchy The skin files for a given design package and theme are subdivided into: css: This stores the CSS stylesheets, and, in some cases, related image files that are called by CSS files (this is not an acceptable convention, but I have seen some designers do this) images: It contains the JPG, PNG, and GIF files used in the display of your site js: It contains the JavaScript files that are specific to a theme (JavaScript files used for core functionality are kept in the js directory at the root level) The path for the frontend skin files is: skin/frontend/[Design Package]/[Theme]/. The concept of theme fallback A very important and brilliant aspect of Magento is what is called the Magento theme fallback model. Basically, this concept means that when building a page, Magento first looks to the assigned theme for a store. If the theme is missing any necessary templating or skin files, Magento then looks to the required default theme within the assigned design package. If the file is not found there, Magento finally looks into the default theme of the Base design package. For this reason, the Base design package is never to be altered or removed; it is the failsafe for your site. The following flowchart outlines the process by which Magento finds the necessary files for fulfilling a page rendering request. This model also gives the designers some tremendous assistance. When a new theme is created, it only has to contain those elements that are different from what is provided by the Base package. For example, if all parts of a desired site design are similar to the Base theme, except for the graphic appearance of the site, a new theme can be created simply by adding new CSS and image files to the new theme (stored within the skin directory). Any new CSS files will need to be included in the local.xml file for your theme. If the design requires different layout structures, only the changed layout and template files need to be created; everything that remains the same need not be duplicated. While previous versions of Magento were built with fallback mechanisms, only in the current versions has this become a true and complete fallback. In the earlier versions, the fallback was to the default theme within a package, not to the Base design package. Therefore, each default theme within a package had to contain all the files of the Base package. If Magento base files were updated in subsequent software versions, these changes had to be redistributed manually to each additional design package within a Magento installation. With Magento CE 1.4 and above, upgrades to the Base package automatically enhance all design packages. If you are careful not to alter the Base design package, then future upgrades to the core functionality of Magento will not break your installation. You will have access to the new improvements based on your custom design package or theme, making your installation virtually upgrade proof. For the same reason, never install a custom theme inside the Base design package. Default installation design packages and themes In a new, clean Magento Community installation, you are provided with the following design packages and themes: Depending on your needs, you could add additional custom design packages, or custom themes within the default design package: If you're going to install a group of related themes, you should probably create a new design package, containing a default theme as your fallback theme On the other hand, if you're using only one or two themes based on the feature of the default design package, you can install the themes within the default design package hierarchy I like to make sure that whatever I customize can be undone, if necessary. It's difficult for me to make changes to the core, installed files; I prefer to work on duplicate copies, preserving the originals in case I need to revert back. After re-installing Magento for the up-teenth time because I had altered too many core files, I learned the hard way! As Magento Community installs a basic variety of good theme variants from which to start, the first thing you should do before adding or altering theme components is to duplicate the default design package files, renaming the duplicate to an appropriate name, such as a description of your installation (for example, Acme or Sports). Any changes you make within this new design package will not alter the originally installed components, thereby allowing you to revert any or all of your themes to the originals. Your new theme hierarchy might now look like this: When creating new packages, you also need to create new folders in the /skin directory to match your directory hierarchy in the /app/design directory. Likewise, if you decide to use one of the installed default themes as the basis for designing a new custom theme, duplicate and rename the theme to preserve the original as your fallback. The new Blank theme A fairly recent default installed theme is the one called Blank. If your customization to your Magento stores is primarily one of colors and graphics, this is not a bad theme to use as a starting point. As the name implies, it has a pretty stark layout, as shown in the following screenshot. However, it does give you all the basic structures and components. Using images and CSS styles, you can go a long way to creating a good-looking, functional website, as shown in the next screenshot for www.aviationlogs.com: When duplicating any design package or theme, don't forget that each of them is defined by directories under /app/design/frontend/ and /skin/frontend/ Installing third-party themes In most cases, Magento users, who are beginners, will explore hundreds of the available Magento themes created by third-party designers. There are many free ones available, but most are sold by dedicated designers. Shopping for themes One of the great good/bad aspects of Magento is the third-party themes. The architecture of the Magento theme model gives knowledgeable theme designers tremendous abilities to construct themes that are virtually upgrade proof, while possessing powerful enhancements. Unfortunately, not all designers have either upgraded older themes properly or created new themes fully honoring the fallback model. If the older fallback model is still used for current Magento versions, upgrades to the Base package could adversely affect your theme. Therefore, as you review third-party themes, take time to investigate how the designer constructs their themes. Most provide some type of site demo. As you learn more about using themes, you'll find it easier to analyze third-party themes. Apart from a few free themes offered through the Magento website, most of them require that you install the necessary files manually, by FTP or SFTP to your server. Every third-party theme I have ever used has included some instructions on how to install the files to your server. However, allow me to offer the following helpful guidelines: When using FTP/SFTP to upload theme files, use the merge function so that only additional files are added to each directory, instead of replacing entire directories. If you're not sure whether your FTP client provides merge capabilities, or not sure how to configure for merge, you will need to open each directory in the theme and upload the individual files to the corresponding directories on your server. If you have set your CSS and JavaScript files to merge, under System | Configuration | Developer, you should turn merging off while installing and modifying your theme. After uploading themes or any component files (for example, templates, CSS, or images), clear the Magento caches under System | Cache Management in your backend. Disable your Magento cache while you install and configure themes. While not critical, it will allow you to see changes immediately instead of having to constantly clear the Magento cache. You can disable the cache under System | Cache Management in the backend. If you wish to make any changes to a theme's individual file, make a duplicate of the original file before making your changes. That way, if something goes awry, you can always re-install the duplicated original. If you have followed the earlier advice to duplicate the Default design package before customizing, instructions to install files within /app/design/frontend/default/ and /skin/frontend/default/ should be interpreted as /app/design/frontend/[your design package name]/ and /skin/frontend/[your design package name]/, respectively. As most of the new Magento users don't duplicate the Default design package, it's common for theme designers to instruct users to install new themes and files within the Default design package. (We know better, now, don't we?) Creating variants Let's assume that we have created a new design package called outdoor_package. Within this design package, we duplicate the Blank theme and call it outdoor_theme. Our new design package file hierarchy, in both /app/design/ and /skin/frontend/ might resemble the following hierarchy:   app/     design/       frontend/         default/           blank/           modern/           iphone/         outdoor_packkage/           outdoor_theme/   skin/     frontend/       default/         blank/           blue/         french/         german/         modern/         iphone/       outdoor_packkage/         outdoor_theme/ However, let's also take one more customization step here. Since Magento separates the template structure from the skin structure—the layout from the design, so to speak—we could create variations of a theme that are simply controlled by CSS and images, by creating more than one skin. For Acme, we might want to have our English language store in a blue color scheme, but our French language store in a green color scheme. We could take the acme/skin directory and duplicate it, renaming both for the new colors:   app/     design/       frontend/         default/           blank/           modern/           iphone/         outdoor_packkage/           outdoor_theme/   skin/     frontend/       default/         blank/           blue/         french/         german/         modern/         iphone/       outdoor_packkage/         outdoor_blue/         outdoor_green/ Before we continue, let's go over something which is especially relevant to what we just created. For our outdoor theme, we created two skin variants: blue and green. However, what if the difference between the two is only one or two files? If we make changes to other files that would affect both color schemes, but which are otherwise the same for both, this would create more work to keep both color variations in sync, right? Remember, with the Magento fallback method, if your site calls on a file, it first looks into the assigned theme, then the default theme within the same design package, and, finally, within the Base design package. Therefore, in this example, you could use the default skin, under /skin/frontend/outdoor_package/default/ to contain all files common to both blue and green. Only include those files that will forever remain different to each of them within their respective skin directories. Assigning themes As mentioned earlier, you can assign design packages and themes at any level of the GWS hierarchy. As with any configuration, the choice depends on the level you wish to assign control. Global configurations affect the entire Magento installation. Website level choices set the default for all subordinant store views, which can also have their own theme specifics, if desired. Let's walk through the process of assigning custom design package and themes. For the sake of this exercise, let's continue with our Outdoor theme, as described earlier. We're going to now assign our Outdoor theme to a Outdoor website and store views. Our first task is to assign the design package and theme to the website as the default for all subordinant store views: Go to System | Configuration | General | Design in your Magento backend. In the Current Configuration Scope drop-down menu, choose Outdoor Products. As shown in the following screenshot, enter the name of your design package, template, layout, and skin. You will have to uncheck the boxes labeled Use Default beside each field you wish to use. Click on the Save Config button. The reason you enter default in the fields, as shown in the previous screenshot, is to provide the fallback protection I described earlier. Magento needs to know where to look for any files that may be missing from your theme files.
Read more
  • 0
  • 0
  • 1394

article-image-magento-designs-and-themes
Packt
19 May 2012
13 min read
Save for later

Magento: Designs and Themes

Packt
19 May 2012
13 min read
(For more resources on e-Commerce, see here.) The Magento theme structure The same holds true for themes. You can specify the look and feel of your stores at the Global, Website, or Store levels (themes can be applied for individual store views relating to a store) by assigning a specific theme. In Magento,a group of related themes is referred to as a design package. Design packages contain files that control various functional elements that are common among the themes within the package. By default, Magento Community installs two design packages: Base package: A special package that contains all the default elements for a Magento installation (we will discuss this in more detail in a moment) Default package: This contains the layout elements of the default store (look and feel) Themes within a design package contain the various elements that determine the look and feel of the site: layout files, templates, CSS, images, and JavaScript. Each design package must have at least one default theme, but can contain other theme variants. You can include any number of theme variants within a design package and use them, for example, for seasonal purposes (that is, holidays, back-to-school, and so on). The following image shows the relationship between design packages and themes: A design package and theme can be specified at the Global, Website or Store levels. Most Magento users will use the same design package for a website and all descendant stores. Usually, related stores within a website business share very similar functional elements, as well as similar style features. This is not mandatory; you are free to specify a completely different design package and theme for each store view within your website hierarchy. The Theme structure Magento divides themes into two group of files: templating and skin. Templating files contain the HTML, PHTML, and PHP code that determines the functional aspects of the pages in your Magento website. Skin files are made of CSS, image, and JavaScript files that give your site its outward design. Ingeniously, Magento further separates these areas by putting them into different directories of your installation: Templating files are stored in the app/design directory, where the extra security of this section protects the functional parts of your site design Skin files are stored within the skin directory (at the root level of the installation), and can be granted a higher permission level, as these are the files that are delivered to a visitor's browser for rendering the page Templating hierarchy Frontend theme template files (the files used to produce your store's pages) are stored within three subdirectories: layout: It contains the XML files that contain the various core information that defines various areas of a page. These files also contain meta and encoding information. template: This stores the PHTML files (HTML files that contain PHP code and processed by the PHP server engine) used for constructing the visual structure of the page. locale: This add files within this directory to provide additional language translations for site elements, such as labels and messages. Magento has a distinct path for storing templating files used for your website: app/design/frontend/[Design Package]/[Theme]/. Skin hierarchy The skin files for a given design package and theme are subdivided into the following: css: This stores the CSS stylesheets, and, in some cases, related image files that are called by CSS files (this is not an acceptable convention, but I have seen some designers do this) images:This contains the JPG, PNG, and GIF files used in the display of your site js: This contains the JavaScript files that are specific to a theme (JavaScript files used for core functionality are kept in the js directory at the root level) The path for the frontend skin files is: skin/frontend/[Design Package]/[Theme]/. The concept of theme fallback A very important and brilliant aspect of Magento is what is called the Magento theme fallback model. Basically, this concept means that when building a page, Magento first looks to the assigned theme for a store. If the theme is missing any necessary templating or skin files, Magento then looks to the required default theme within the assigned design package. If the file is not found there, Magento finally looks into the default theme of the Base design package. For this reason, the Base design package is never to be altered or removed; it is the failsafe for your site. The following flowchart outlines the process by which Magento finds the necessary files for fulfilling a page rendering request. This model also gives the designers some tremendous assistance. When a new theme is created, it only has to contain those elements that are different from what is provided by the Base package. For example, if all parts of a desired site design are similar to the Base theme, except for the graphic appearance of the site, a new theme can be created simply by adding new CSS and image files to the new theme (stored within the skin directory). Any new CSS files will need to be included in the local.xml file for your theme (we will discuss the local.xml file later in this article). If the design requires different layout structures, only the changed layout and template files need to be created; everything that remains the same need not be duplicated. While previous versions of Magento were built with fallback mechanisms, only in the current versions has this become a true and complete fallback. In the earlier versions, the fallback was to the default theme within a package, not to the Base design package. Therefore, each default theme within a package had to contain all the files of the Base package. If Magento base files were updated in subsequent software versions, these changes had to be redistributed manually to each additional design package within a Magento installation. With Magento CE 1.4 and above, upgrades to the Base package automatically enhance all design packages. If you are careful not to alter the Base design package, then future upgrades to the core functionality of Magento will not break your installation. You will have access to the new improvements based on your custom design package or theme, making your installation virtually upgrade proof. For the same reason, never install a custom theme inside the Base design package. Default installation design packages and themes In a new, clean Magento Community installation, you are provided with the following design packages and themes: Depending on your needs, you could add additional a custom design packages, or custom themes within the default design package: If you're going to install a group of related themes, you should probably create a new design package, containing a default theme as your fallback theme On the other hand, if you're using only one or two themes based on the features of the default design package, you can install the themes within the default design package hierarchy I like to make sure that whatever I customize can be undone, if necessary. It's difficult for me to make changes to the core, installed files; I prefer to work on duplicate copies, preserving the originals in case I need to revert back. After re-installing Magento for the umpteenth time because I had altered too many core files, I learned the hard way! As Magento Community installs a basic variety of good theme variants from which to start, the first thing you should do before adding or altering theme components is to duplicate the default design package files, renaming the duplicate to an appropriate name, such as a description of your installation (for example, Acme or Sports). Any changes you make within this new design package will not alter the originally installed components, thereby allowing you to revert any or all of your themes to the originals. Your new theme hierarchy might now look like this: When creating new packages, you also need to create new folders in the /skin directory to match your directory hierarchy in the /app/design directory. Likewise, if you decide to use one of the installed default themes as the basis for designing a new custom theme, duplicate and rename the theme to preserve the original as your fallback. The new Blank theme A fairly recent default installed theme is Blank. If your customization to your Magento stores is primarily one of colors and graphics, this is not a bad theme to use as a starting point. As the name implies, it has a pretty stark layout, as shown in the following screenshot. However, it does give you all the basic structures and components. Using images and CSS styles, you can go a long way to creating a good-looking, functional website, as shown in the next screenshot for www.aviationlogs.com: When duplicating any design package or theme, don't forget that each of them is defined by directories under /app/design/frontend/ and /skin/frontend/ Installing third-party themes In most cases, Magento users who are beginners will explore hundreds of the available Magento themes created by third-party designers. There are many free ones available, but most are sold by dedicated designers. Shopping for themes One of the great good/bad aspects of Magento is the third-party themes. The architecture of the Magento theme model gives knowledgeable theme designers tremendous abilities to construct themes that are virtually upgrade proof, while possessing powerful enhancements. Unfortunately, not all designers have either upgraded older themes properly or created new themes fully honoring the fallback model. If the older fallback model is still used for current Magento versions, upgrades to the Base package could adversely affect your theme. Therefore, as you review third-party themes, take time to investigate how the designer constructs their themes. Most provide some type of site demo. As you learn more about using themes, you'll find it easier to analyze third-party themes. Apart from a few free themes offered through the Magento website, most of them require that you install the necessary files manually, by FTP or SFTP to your server. Every third-party theme I have ever used has included some instructions on how to install the files to your server. However, allow me to offer the following helpful guidelines: When using FTP/SFTP to upload theme files, use the merge function so that only additional files are added to each directory, instead of replacing entire directories. If you're not sure whether your FTP client provides merge capabilities, or not sure how to configure for merge, you will need to open each directory in the theme and upload the individual files to the corresponding directories on your server. If you have set your CSS and JavaScript files to merge, under System | Configuration | Developer, you should turn merging off while installing and modifying your theme. After uploading themes or any component files (for example, templates, CSS, or images), clear the Magento caches under System | Cache Management in your backend. Disable your Magento cache while you install and configure themes. While not critical, it will allow you to see changes immediately instead of having to constantly clear the Magento cache. You can disable the cache under System | Cache Management in the backend. If you wish to make any changes to a theme's individual file, make a duplicate of the original file before making your changes. That way, if something goes awry, you can always re-install the duplicated original. If you have followed the earlier advice to duplicate the Default design package before customizing, instructions to install files within /app/design/frontend/default/ and /skin/frontend/default/ should be interpreted as /app/design/frontend/[your design package name]/ and /skin/frontend/[your design package name]/, respectively. As most of the new Magento users don't duplicate the Default design package, it's common for theme designers to instruct users to install new themes and files within the Default design package. (We know better, now, don't we?) Creating variants Let's assume that we have created a new design package called outdoor_package. Within this design package, we duplicate the Blank theme and call it outdoor_theme. Our new design package file hierarchy, in both /app/design/ and /skin/frontend/ might resemble the following hierarchy: app/ design/ frontend/ default/ blank/ modern/ iphone/ outdoor_package/ outdoor_theme/ skin/ frontend/ default/ blank/ blue/ french/ german/ modern/ iphone/ outdoor_package/ outdoor_theme/ However, let's also take one more customization step here. Since Magento separates the template structure from the skin structure—the layout from the design, so to speak—we could create variations of a theme that are simply controlled by CSS and images, by creating more than one skin. For Acme, we might want to have our English language store in a blue color scheme, but our French language store in a green color scheme. We could take the acme/skin directory and duplicate it, renaming both for the new colors: app/ design/ frontend/ default/ blank/ modern/ iphone/ outdoor_package/ outdoor_theme/ skin/ frontend/ default/ blank/ blue/ french/ german/ modern/ iphone/ outdoor_package/ outdoor_blue/ outdoor_green/ Before we continue, let's go over something which is especially relevant to what we just created. For our outdoor theme, we created two skin variants: blue and green. However, what if the difference between the two is only one or two files? If we make changes to other files that would affect both color schemes, but which are otherwise the same for both, this would create more work to keep both color variations in sync, right? Remember, with the Magento fallback method, if your site calls on a file, it first looks into the assigned theme, then the default theme within the same design package, and, finally, within the Base design package. Therefore, in this example, you could use the default skin, under /skin/frontend/outdoor_package/default/ to contain all files common to both blue and green. Only include those files that will forever remain different to each of them within their respective skin directories. Assigning themes As mentioned earlier, you can assign design packages and themes at any level of the GWS hierarchy. As with any configuration, the choice depends on the level you wish to assign control. Global configurations affect the entire Magento installation. Website level choices set the default for all subordinant store views, which can also have their own theme specifics, if desired. Let's walk through the process of assigning custom design package and themes. For the sake of this exercise, let's continue with our Outdoor theme, as described earlier.Refer to the following screenshot: We're going to now assign our Outdoor theme to a Outdoor website and store views. Our first task is to assign the design package and theme to the website as the default for all subordinant store views: Go to System | Configuration | General | Design in your Magento backend. In the Current Configuration Scope drop-down menu, choose Outdoor Products. As shown in the following screenshot, enter the name of your design package, template, layout, and skin. You will have to uncheck the boxes labeled Use Default beside each field you wish to use. Click on the Save Config button. The reason you enter default in the fields, as shown in the previous screenshot, is to provide the fallback protection I described earlier. Magento needs to know where to look for any files that may be missing from your theme files.
Read more
  • 0
  • 0
  • 2713

article-image-plsql-using-collections
Packt
17 May 2012
18 min read
Save for later

PL/SQL: Using Collections

Packt
17 May 2012
18 min read
Collections—an overview A collection is a homogeneous single dimensional structure, which constitutes an ordered set of elements of a similar type. Being a homogeneous structure, all elements are of the same data type. The structure of the element contains cells with a subscript. The elements reside in these cells to make the index as their location information. The subscript or cell index becomes identification of an element and is used for its access. Structure of a collection type, SPORT, is shown in the following diagram. Note the subscript and elements into it. A new element, GOLF, enters at the last empty location and is represented as SPORT [6]: A collection element can be of any valid SQL data type or a user-defined type. An element of the SQL primitive data type is a scalar value while an element of the user-defined type is an object type instance. A collection can be used within a PL/SQL program by declaring a PL/SQL variable of collection type. The local PL/SQL variable can hold the instances of its collection type. Besides, a database column in a table can also be of the schema collection type. The collections in Oracle are strictly one dimensional. They cannot be realized on two-dimensional coordinates. However, multidimensional arrays can be realized when the collection has an object type or collection type attribute. A collection can be bounded or unbounded. Bounded collections can accommodate a limited number of elements while unbounded collections have no upper limit for subscripts. Collections provide an efficient way to organize the data in an array or set format while making the use of object-oriented features. An instance of a nested table or varray collection type is accessed as an object while the data is still stored in database columns. Collections can be used to avail data caching in programs and boost up the performance of SQL operations. On dedicated server connections, a session always uses User Global Area (UGA), a component of PGA, for collection operations. On the other hand, for shared server mode, the collection operations are still carried out in UGA; but UGA is now a part of System Global Area (SGA), thus indirectly in SGA. This is because in shared server connections, multiple server processes can affect a session, thus UGA must be allocated out of the SGA. Categorization Collections are of two types—persistent and non-persistent. A collection is persistent if it stores the collection structure and elements physically in the database. Contrarily, a non-persistent collection is active for a program only that is, maximum up to a session. Apart from the preceding categories, a collection can be realized in three formats namely, associative array, nested table or varray. This categorization is purely based on their objective and behavioral properties in a PL/SQL program. The following diagram combines the abstract and physical classification of collections: We will take a quick tour of these collection types now and discuss them in detail in the coming sections: Associative array (index-by table): This is the simplest form of non- persistent unbounded collections. As a non-persistent collection, it cannot be stored in the database, but they are available within a PL/SQL block only. The collection structure and data of associative array cannot be retained once the program is completed. Initially, during the days of Oracle 7, it was known as PL/SQL tables. Later, Oracle 8 version released it as index-by tables as they used an index to identify an element. Nested table: This is a persistent form of unbounded collections which can be created in the database as well as in PL/SQL block. Varray (variable-size array): This is a persistent but bounded form of collection which can be created in the database as well as in PL/SQL. Similar to a nested table, a varray is also a unidimensional homogeneous collection. The collection size and storage scheme are the factors which differentiate varrays from nested tables. Unlike a nested table, a varray can accommodate only a defined (fixed) number of elements. Selecting an appropriate collection type Here are a few guidelines to decide upon the appropriate usage of collection types in programs: Use of associative arrays is required when: You have to temporarily cache the program data in an array format for lookup purpose. You need string subscripts for the collection elements. Note that it supports negative subscripts, too. Map hash tables from the client to the database. Use of nested tables is preferred when: You have to stores data as sets in the database. Database columns of nested table type can be declared to hold the data persistently. Perform major array operations such as insertion and deletion, on a large volume of data. Use of varrays is preferred when: You have to store calculated or predefined volume of data in the database. Varray offers limited and defined storage of rows in a collection. Order of the elements has to be preserved. Associative arrays Associative arrays are analogous to conventional arrays or lists which can be defined within a PL/SQL program only. Neither the array structure nor the data can be stored in the database. It can hold the elements of a similar type in a key-value structure without any upper bound to the array. Each cell of the array is distinguished by its subscript, index, or cell number. The index can be a number or a string. Associative arrays were first introduced in Oracle 7 release as PL/SQL tables to signify its usage within the scope of a PL/SQL block. Oracle 8 release identified the PL/SQL table as Index by table due to its structure as an index-value pair. Oracle 10g release recognized the behavior of index by tables as arrays so as to rename it as associative arrays due to association of an index with an array. The following diagram explains the physical lookup structure of an associative array: Associative arrays follow the following syntax for declaration in a PL/SQL declare block: TYPE [COLL NAME] IS TABLE OF [ELEMENT DATA TYPE] NOT NULL INDEX BY [INDEX DATA TYPE] In the preceding syntax, the index type signifies the data type of the array subscript. RAW, NUMBER, LONG-RAW, ROWID, and CHAR are the unsupported index data types. The suited index types are BINARY_INTEGER, PLS_INTEGER, POSITIVE, NATURAL, SIGNTYPE, or VARCHAR2. The element's data type can be one of the following: PL/SQL scalar data type: NUMBER (along with its subtypes), VARCHAR2 (and its subtypes), DATE, BLOB, CLOB, or BOOLEAN Inferred data: The data type inherited from a table column, cursor expression or predefined package variable User-defined type: A user defined object type or collection type For illustration, the following are the valid conditions of the associative array in a PL/SQL block: /*Array of CLOB data*/ TYPE clob_t IS TABLE OF CLOB INDEX BY PLS_INTEGER; /*Array of employee ids indexed by the employee names*/ TYPE empno_t IS TABLE OF employees.empno%TYPE NOT NULL INDEX BY employees.ename%type; The following PL/SQL program declares an associative array type in a PL/ SQL block. Note that the subscript of the array is of a string type and it stores the number of days in a quarter. This code demonstrates the declaration of an array and assignment of the element in each cell and printing them. Note that the program uses the FIRST and NEXT collection methods to display the array elements. The collection methods would be covered in detail in the PL/SQL collection methods section: /*Enable the SERVEROUTPUT on to display the output*/ SET SERVEROUTPUT ON /*Start the PL/SQL block*/ DECLARE /*Declare a collection type associative array and its variable*/ TYPE string_asc_arr_t IS TABLE OF NUMBER INDEX BY VARCHAR2(10); l_str string_asc_arr_t; l_idx VARCHAR2(50); BEGIN /*Assign the total count of days in each quarter against each cell*/ l_str ('JAN-MAR') := 90; l_str ('APR-JUN') := 91; l_str ('JUL-SEP') := 92; l_str ('OCT-DEC') := 93; l_idx := l_str.FIRST; WHILE (l_idx IS NOT NULL) LOOP DBMS_OUTPUT.PUT_LINE('Value at index '||l_idx||' is '||l_str(l_ idx)); l_idx := l_str.NEXT(l_idx); END LOOP; END; / Value at index APR-JUN is 91 Value at index JAN-MAR is 90 Value at index JUL-SEP is 92 Value at index OCT-DEC is 93 PL/SQL procedure successfully completed. In the preceding block, note the string indexed array. A string indexed array considerably improves the performance by using indexed organization of array values. In the last block, we noticed the explicit assignment of data. In the following program, we will try to populate the array automatically in the program. The following PL/SQL block declares an associative array to hold the ASCII values of number 1 to 100: /*Enable the SERVEROUTPUT on to display the output*/ SET SERVEROUTPUT ON /*Start the PL/SQL Block*/ DECLARE /*Declare an array of string indexed by numeric subscripts*/ TYPE ASCII_VALUE_T IS TABLE OF VARCHAR2(12) INDEX BY PLS_INTEGER; L_GET_ASCII ASCII_VALUE_T; BEGIN /*Insert the values through a FOR loop*/ FOR I IN 1..100 LOOP L_GET_ASCII(I) := ASCII(I); END LOOP; /*Display the values randomly*/ DBMS_OUTPUT.PUT_LINE(L_GET_ASCII(5)); DBMS_OUTPUT.PUT_LINE(L_GET_ASCII(15)); DBMS_OUTPUT.PUT_LINE(L_GET_ASCII(75)); END; / 53 49 55 PL/SQL procedure successfully completed. The salient features of associative arrays are as follows: An associative array can exist as a sparse or empty collection Being a non-persistent collection, it cannot participate in DML transactions It can be passed as arguments to other local subprograms within the same block Sorting of an associative array depends on the NLS_SORT parameter An associative array declared in package specification behaves as a session-persistent array Nested tables Nested tables are a persistent form of collections which can be created in the database as well as PL/SQL. It is an unbounded collection where the index or subscript is implicitly maintained by the Oracle server during data retrieval. Oracle automatically marks the minimum subscript as 1 and relatively handles others. As there is no upper limit defined for a nested table, its size can grow dynamically. Though not an index-value pair structure, a nested table can be accessed like an array in a PL/SQL block. A nested table is initially a dense collection but it might become sparse due to delete operations on the collection cells. Dense collection is the one which is tightly populated. That means, there exists no empty cells between the lower and upper indexes of the collection. Sparse collections can have empty cells between the first and the last cell of the collection. A dense collection may get sparse by performing the "delete" operations. When a nested table is declared in a PL/SQL program, they behave as a one-dimensional array without any index type or upper limit specification. A nested table defined in a database exists as a valid schema object type. It can be either used in a PL/SQL block to declare a PL/SQL variable for temporarily holding program data or a database column of particular nested table type can be included in a table, which can persistently store the data in the database. A nested table type column in a table resembles a table within a table, but Oracle draws an out- of-line storage table to hold the nested table data. This scenario is illustrated in the following diagram: Whenever a database column of nested table type is created in a table (referred to as parent table), Oracle creates a storage table with the same storage options as that of the parent table. The storage table created by Oracle in the same segment carries the name as specified in the NESTED TABLE STORE AS clause during creation of the parent table. Whenever a row is created in the parent table, the following actions are performed by the Oracle server: A unique identifier is generated to distinguish the nested table instances of different parent rows, for the parent row The instance of the nested table is created in the storage table alongside the unique identifier of the parent row The Oracle server takes care of these nested table operations. For the programmer or user, the whole process is hidden and appears as a normal "insert" operation. A nested table definition in PL/SQL follows the following syntax: DECLARE TYPE type_name IS TABLE OF element_type [NOT NULL]; In the preceding syntax, element_type is a primitive data type or a user-defined type, but not as a REF CURSOR type. In a database, a nested table can be defined using the following syntax: CREATE [OR REPLACE] TYPE type_name IS TABLE OF [element_type] [NOT NULL]; / In the preceding syntax, [element_type] can be a SQL supported scalar data type, a database object type, or a REF object type. Unsupported element types are BOOLEAN, LONG, LONG-RAW, NATURAL, NATURALN, POSITIVE, POSITIVEN, REF CURSOR, SIGNTYPE, STRING, PLS_INTEGER, SIMPLE_INTEGER, BINARY_INTEGER and all other non-SQL supported data types. If the size of the element type of a database collection type has to be increased, follow this syntax: ALTER TYPE [type name] MODIFY ELEMENT TYPE [modified element type] [CASCADE | INVALIDATE]; The keywords, CASCADE or INVALIDATE, decide whether the collection modification has to invalidate the dependents or the changes that have to be cascaded across the dependents. The nested table from the database can be dropped using the DROP command, as shown in the following syntax (note that the FORCE keyword drops the type irrespective of its dependents): DROP TYPE [collection name] [FORCE] Nested table collection type as the database object We will go through the following illustration to understand the behavior of a nested table, when created as a database collection type: /*Create the nested table in the database*/ SQL> CREATE TYPE NUM_NEST_T AS TABLE OF NUMBER; / Type created. The nested table type, NUM_NEST_T, is now created in the database. Its metadata information can be queried from the USER_TYPES and USER_COLL_TYPES dictionary views: SELECT type_name, typecode, type_oid FROM USER_TYPES WHERE type_name = 'NUM_NEST_T'; TYPE_NAME TYPECODE TYPE_OID --------------- --------------- -------------------------------- NUM_NEST_T COLLECTION 96DE421E47114638A9F5617CE735731A Note that the TYPECODE value shows the type of the object in the database and differentiates collection types from user-defined object types: SELECT type_name, coll_type, elem_type_name FROM user_coll_types WHERE type_name = 'NUM_NEST_T'; TYPE_NAME COLL_TYPE ELEM_TYPE_NAME --------------- ---------- -------------------- NUM_NEST_T TABLE NUMBER Once the collection type has been successfully created in the database, it can be used to specify the type for a database column in a table. The CREATE TABLE statement in the following code snippet declares a column of the NUM_NEST_T nested table type in the parent table, TAB_USE_NT_COL. The NESTED TABLE [Column] STORE AS [Storage table] clause specifies the storage table for the nested table type column. A separate table for the nested table column, NUM, ensures its out-of-line storage. SQL> CREATE TABLE TAB_USE_NT_COL (ID NUMBER, NUM NUM_NEST_T) NESTED TABLE NUM STORE AS NESTED_NUM_ID; Table created. A nested table collection type in PL/SQL n PL/SQL, a nested table can be declared and defined in the declaration section of the block as a local collection type. As a nested table follows object orientation, the PL/SQL variable of the nested table type has to be necessarily initialized. The Oracle server raises the exception ORA-06531: Reference to uninitialized collection if an uninitialized nested table type variable is encountered during block execution. As the nested table collection type has been declared within the PL/SQL block, its scope, visibility, and life is the execution of the PL/SQL block only. The following PL/SQL block declares a nested table. Observe the scope and visibility of the collection variable. Note that the COUNT method has been used to display the array elements. /*Enable the SERVEROUTPUT to display the results*/ SET SERVEROUTPUT ON /*Start the PL/SQL block*/ DECLARE /*Declare a local nested table collection type*/ TYPE LOC_NUM_NEST_T IS TABLE OF NUMBER; L_LOCAL_NT LOC_NUM_NEST_T := LOC_NUM_NEST_T (10,20,30); BEGIN /*Use FOR loop to parse the array and print the elements*/ FOR I IN 1..L_LOCAL_NT.COUNT LOOP DBMS_OUTPUT.PUT_LINE('Printing '||i||' element: '||L_LOCAL_ NT(I)); END LOOP; END; / Printing 1 element: 10 Printing 2 element: 20 Printing 3 element: 30 PL/SQL procedure successfully completed. Additional features of a nested table In the earlier sections, we saw the operational methodology of a nested table. We will now focus on the nested table's metadata. Furthermore, we will demonstrate a peculiar behavior of the nested table for the "delete" operations. Oracle's USER_NESTED_TABLES and USER_NESTED_TABLE_COLS data dictionary views maintain the relationship information of the parent and the nested tables. These dictionary views are populated only when a database of a nested table collection type is included in a table. The USER_NESTED_TABLES static view maintains the information about the mapping of a nested table collection type with its parent table. The structure of the dictionary view is as follows: SQL> desc USER_NESTED_TABLES Name Null? Type ----------------------- -------- --------------- TABLE_NAME VARCHAR2(30) TABLE_TYPE_OWNER VARCHAR2(30) TABLE_TYPE_NAME VARCHAR2(30) PARENT_TABLE_NAME VARCHAR2(30) PARENT_TABLE_COLUMN VARCHAR2(4000) STORAGE_SPEC VARCHAR2(30) RETURN_TYPE VARCHAR2(20) ELEMENT_SUBSTITUTABLE VARCHAR2(25) Let us query the nested table relationship properties for the TAB_USE_NT_COL table from the preceding view: SELECT parent_table_column, table_name, return_type, storage_spec FROM user_nested_tables WHERE parent_table_name='TAB_USE_NT_COL' / PARENT_TAB TABLE_NAME RETURN_TYPE STORAGE_SPEC ---------------------------------------------------------------------- NUM NESTED_NUM_ID VALUE DEFAULT In the preceding view query, RETURN_TYPE specifies the return type of the collection. It can be VALUE (in this case) or LOCATOR. Another column, STORAGE_SPEC, signifies the storage scheme used for the storage of a nested table which can be either USER_SPECIFIED or DEFAULT (in this case). The USER_NESTED_TABLE_COLS view maintains the information about the collection attributes contained in the nested tables: SQL> desc USER_NESTED_TABLE_COLS Name Null? Type ----------------------- -------- --------------- TABLE_NAME NOT NULL VARCHAR2(30) COLUMN_NAME NOT NULL VARCHAR2(30) DATA_TYPE VARCHAR2(106) DATA_TYPE_MOD VARCHAR2(3) DATA_TYPE_OWNER VARCHAR2(30) DATA_LENGTH NOT NULL NUMBER DATA_PRECISION NUMBER DATA_SCALE NUMBER NULLABLE VARCHAR2(1) COLUMN_ID NUMBER DEFAULT_LENGTH NUMBER DATA_DEFAULT LONG NUM_DISTINCT NUMBER LOW_VALUE RAW(32) HIGH_VALUE RAW(32) DENSITY NUMBER NUM_NULLS NUMBER NUM_BUCKETS NUMBER LAST_ANALYZED DATE SAMPLE_SIZE NUMBER CHARACTER_SET_NAME VARCHAR2(44) CHAR_COL_DECL_LENGTH NUMBER GLOBAL_STATS VARCHAR2(3) USER_STATS VARCHAR2(3) AVG_COL_LEN NUMBER CHAR_LENGTH NUMBER CHAR_USED VARCHAR2(1) V80_FMT_IMAGE VARCHAR2(3) DATA_UPGRADED VARCHAR2(3) HIDDEN_COLUMN VARCHAR2(3) VIRTUAL_COLUMN VARCHAR2(3) SEGMENT_COLUMN_ID NUMBER INTERNAL_COLUMN_ID NOT NULL NUMBER HISTOGRAM VARCHAR2(15) QUALIFIED_COL_NAME VARCHAR2(4000) We will now query the nested storage table in the preceding dictionary view to list all its attributes: SELECT COLUMN_NAME, DATA_TYPE, DATA_LENGTH, HIDDEN_COLUMN FROM user_nested_table_cols where table_name='NESTED_NUM_ID' / COLUMN_NAME DATA_TYP DATA_LENGTH HID ------------------------------ ---------- ----------- ----- NESTED_TABLE_ID RAW 16 YES COLUMN_VALUE NUMBER 22 NO We observe that though the nested table had only number elements, there is two- columned information in the view. The COLUMN_VALUE attribute is the default pseudo column of the nested table as there are no "named" attributes in the collection structure. The other attribute, NESTED_TABLE_ID, is a hidden unique 16-byte system generated raw hash code which latently stores the parent row identifier alongside the nested table instance to distinguish the parent row association. If an element is deleted from the nested table, it is rendered as parse. This implies that once an index is deleted from the collection structure, the collection doesn't restructure itself by shifting the cells in a forward direction. Let us check out the sparse behavior in the following example. The following PL/SQL block declares a local nested table and initializes it with a constructor. We will delete the first element and print it again. The system raises the NO_DATA_FOUND exception when we query the element at the index 1 in the collection:   /*Enable the SERVEROUTPUT to display the block messages*/ SQL> SET SERVEROUTPUT ON /*Start the PL/SQL block*/ SQL> DECLARE /*Declare the local nested table collection*/ TYPE coll_method_demo_t IS TABLE OF NUMBER; /*Declare a collection variable and initialize it*/ L_ARRAY coll_method_demo_t := coll_method_demo_t (10,20,30,40,50); BEGIN /*Display element at index 1*/ DBMS_OUTPUT.PUT_LINE('Element at index 1 before deletion:'||l_ array(1)); /*Delete the 1st element from the collection*/ L_ARRAY.DELETE(1); /*Display element at index 1*/ DBMS_OUTPUT.PUT_LINE('Element at index 1 after deletion:'||l_ array(1)); END; / Element at index 1 before deletion:10 DECLARE * ERROR at line 1: ORA-01403: no data found ORA-06512: at line 15
Read more
  • 0
  • 0
  • 8214

article-image-creating-modal-dialogs-grids-and-collapsible-blocks
Packt
16 May 2012
8 min read
Save for later

Creating Modal-Dialogs Grids and Collapsible Blocks

Packt
16 May 2012
8 min read
Creating Dialogs Dialogs: at least under the jQuery Mobile framework: are small windows that cover an existing page. They typically provide a short message or question for the user. They will also typically include a button that allows the user to dismiss the dialog and return back to the site. Creating a dialog in jQuery Mobile is done by simply adding a simple attribute to a link: data-rel="dialog". The following listing demonstrates an example: Listing 7-1: test1.html <!DOCTYPE html> <html> <head> <title>Dialog Test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/ latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/latest/ jquery.mobile.min.js"></script> </head> <body> <div data-role="page" id="first"> <div data-role="header"> <h1>Dialog Test</h1> </div> <div data-role="content"> <p> <a href="#page2">Another Page (normal)</a> </p> <p> <a href="#page3" data-rel="dialog">A Dialog (dialog)</a> </p> </div> </div> <div data-role="page" id="page2"> <div data-role="header"> <h1>The Second</h1> </div> <div data-role="content"> <p> This is the Second </p> </div> </div> <div data-role="page" id="page3"> <div data-role="header"> <h1>The Third</h1> </div> <div data-role="content"> <p> This is the Third </p> </div> </div> </body> </html> This is a simple, multi-page jQuery Mobile site. Notice how we link to the second and third page. The first link is typical. The second link, though, includes the data-rel attribute mentioned earlier. Notice that both the second and third page are defined in the usual manner. So the only change we have here is in the link. When that second link is clicked, the page is rendered completely differently: Remember, that page wasn't defined differently. The change you see in the previous screenshot is driven by the change to the link itself. That's it! Clicking the little X button will hide the dialog and return the user back to the original page. Any link within the page will handle closing the dialog as well. If you wish to add a cancel type button, or link, you can do so using data-rel="back" in the link. The target of the link should be to the page that launched the dialog. Listing 7-2 shows a modified version of the earlier template. In this one, we've simply added two buttons to the dialog. The first button will launch the second page, while the second one will act as a Cancel action. Listing 7-2: test2.html <!DOCTYPE html> <html> <head> <title>Dialog Test (2)</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/ latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/ latest/jquery.mobile.min.js"></script> </head> <body> <div data-role="page" id="first"> <div data-role="header"> <h1>Dialog Test</h1> </div> <div data-role="content"> <p> <a href="#page2">Another Page (normal)</a> </p> <p> <a href="#page3" data-rel="dialog">A Dialog (dialog)</a> </p> </div> </div> <div data-role="page" id="page2"> <div data-role="header"> <h1>The Second</h1> </div> <div data-role="content"> <p> This is the Second </p> </div> </div> <div data-role="page" id="page3"> <div data-role="header"> <h1>The Third</h1> </div> <div data-role="content"> <p> This is the Third </p> <a href="#page2" data-role="button">Page 2</a> <a href="#first" data-role="button" data-rel="back">Cancel</a> </div> </div> </body> </html> The major change in this template is the addition of the buttons in the dialog, contained within page3 div. Notice the first link is turned into a button, but outside of that is a simple link. The second button includes the addition of the data-rel="back" attribute. This will handle simply dismissing the dialog. The following screenshot shows how the dialog looks with the buttons added: Laying out content with grids Grids are one of the few features of jQuery Mobile that do not make use of particular data attributes. Instead, you work with grids simply by specifying CSS classes for your content. Grids come in four flavors: Two column, Three column, Four column, and Five column. (You will probably not want to use the five column on a phone device. Save that for a tablet instead.) You begin a grid with a divblockthat makes use of the class ui-grid-X, where X will be either a, b, c, or d. ui-grid-arepresents a two column grid. ui-grid-bis a three column grid. You can probably guess what cand dcreate. So to begin a two column grid, you would wrap your content with the following: <div class="ui-grid-a"> Content </div> Within the divtag, you then use a divfor each "cell" of the content. The class for grid calls begins with ui-block-X, where Xgoes from a to d. ui-block-a would be used for the first cell, ui-block-b for the next, and so on. This works much like HTML tables. Putting it together, the following code snippet demonstrates a simple two column grid with two cells of content: <div class="ui-grid-a"> <div class="ui-block-a">Left</div> <div class="ui-block-b">Right</div> </div> Text within a cell will automatically wrap. Listing 7-3 demonstrates a simple grid with a large amount of text in one of the columns: Listing 7-3: test3.html <!DOCTYPE html> <html> <head> <title>Grid Test</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="http://code.jquery.com/mobile/ latest/jquery.mobile.min.css" /> <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> <script src="http://code.jquery.com/mobile/ latest/jquery.mobile.min.js"></script> </head> <body> <div data-role="page" id="first"> <div data-role="header"> <h1>Grid Test</h1> </div> <div data-role="content"> <div class="ui-grid-a"> <div class="ui-block-a"> <p> This is my left hand content. There won't be a lot of it. </p> </div> <div class="ui-block-b"> <p> This is my right hand content. I'm going to fill it with some dummy text. </p> <p> Bacon ipsum dolor sit amet andouille capicola spare ribs, short loin venison sausage prosciutto turducken turkey flank frankfurter pork belly short ribs. Venison frankfurter filet mignon, jowl meatball hamburger pastrami pork chop drumstick. Fatback pancetta boudin, ribeye shoulder capicola cow leberkäse bresaola spare ribs prosciutto venison ball tip jowl andouille. Beef ribs t-bone swine, tail capicola turkey pork belly leberkäse frankfurter jowl. Shankle ball tip sirloin frankfurter bacon beef ribs. Tenderloin beef ribs pork chop, pancetta turkey bacon short ribs ham flank chuck pork belly. Tongue strip steak short ribs tail swine. </p> </div> </div> </div> </div> </body> </html> In the mobile browser, you can clearly see the two columns: Working with other types of grids then is simply a matter of switching to the other classes. For example, a four column grid would be set up similar to the following code snippet: <div class="ui-grid-c"> <div class="ui-block-a">1st cell</div> <div class="ui-block-b">2nd cell</div> <div class="ui-block-c">3rd cell</div> </div>
Read more
  • 0
  • 0
  • 1426

article-image-article-working-with-microsoft-dynamics-ax-forms
Packt
16 May 2012
9 min read
Save for later

Working with Microsoft Dynamics AX Forms

Packt
16 May 2012
9 min read
Building a dynamic form A standard approach for creating forms in Dynamics AX is to create and store form objects in the AOT. Using this approach, it is possible to achieve a high level of complexity. However, in a number of cases, it is required to have forms created dynamically. In the standard Dynamics AX application we can see that application objects, such as the Table browser form, various lookups, or dialogs, are built dynamically. In this recipe, we will create a dynamic form. In order to show how flexible it can be, we will replicate the layout of the existing Customer groups form located in the Accounts receivable module. It can be opened from Accounts receivable | Setup | Customers. How to do it... Carry out the following steps in order to complete this recipe: In the AOT, create a new class called CustGroupDynamic with the following code: code 7 In order to test the form, run the class. Notice that the form is similar to the one in Accounts receivable | Setup | Customers | Customer groups: How it works... We start the code by declaring some variables. Note that most of them begin with FormBuild, which is part of a set of the application classes used for building dynamic forms. Each of these types correspond to the control types manually used when building forms in the AOT. Right after the variable declaration, we create a dictTable object based on the CustGroup table. We will use this object several times later in the code. Then we create a new form object and set its AOT name by calling the following code: code 8 The name is not important as this is a dynamic form, unless we are planning to save it in the AOT. The form should have a data source, so we add one by calling the addDataSource() method on the form object and providing the previously created dictTable object. code 9 Every form has a design, so we add a new design, define its style as a simple list, and set its title data source: code Once the design is ready, we can start adding controls from the code as if we were doing this from the AOT. The first thing to do is to add a strip action pane with its buttons: code 10 Right after the action pane, we add an automatically expanding Grid control pointing to the previously mentioned data source. Just to follow best practice, we place the grid inside of a Group control: code 11 Next, we add a number of grid controls pointing to the relevant data source fields by calling addDataField() on the grid object. The last thing is to initialize and run the form. Here we use a recommended approach to create and run forms using the globally available classFactory object. Adding a form splitter In Dynamics AX, more complex forms consist of one or more sections. Each section may contain grids, groups or any other element. In order to maintain section sizes while resizing the form, the sections are normally separated by so-called splitters. Splitters are not special Dynamics AX controls; they are group controls with the properties modified so they look like splitters. Most of the multisection forms in Dynamics AX already contain splitters. In this recipe, to demonstrate the usage of splitters, we will modify one of the existing forms that does not have a splitter. We will modify the Account reconciliation form in the Cash and bank management module, which can be opened from Cash and bank management | Bank accounts list page, by clicking on the Reconcile | Account reconciliation button in the action pane, and then selecting any of the existing records and hitting the Transactions button. In the following screenshot, you can see that it is not possible to control the sizes of each grid individually, and they are resized automatically using a fixed ratio when resizing the form: In this recipe, we will demonstrate the usage of splitters by resolving this situation. We will add a form splitter in the middle of the two grids in the mentioned form. It will allow users to define the size of both grids to make sure the data is optimally displayed. How to do it... Carry out the following steps in order to complete this recipe: Open the BankReconciliation form in the AOT, and in the form's design add a new Group control right after the ActionPane control with the following properties: table 1 Move the AllReconciled, Balances, and Tab controls into the newly created group. Add a new Group control right below the Top group with the following properties: table 2 Add the following line of code to the bottom of the form's class declaration: code 12 Add the following line of code to the bottom of the form's init() method: code 13 Override three methods in the Splitter group with the following code: code 14 Change the following properties of the existing BankTransTypeGroup group: table 3 Change the following property of the exiting TypeSums grid located inside the BankTransTypeGroup group: table 4 In the AOT, the modified BankReconciliation form should look similar to the following screenshot: Now, to test the results, open Cash and bank management | Bank accounts, select any bank account, click Reconcile | Account reconciliation, choose an existing one or create a new bank statement, and click on the Transactions button. Notice that the form now has a nice splitter in the middle, which makes the form look better and allows resizing of both grids: Open the SalesCreateOrder form in the AOT, and set its Design property: table 5 In order to test, open Sales and marketing | Sales orders | All sales orders, and start creating a new order. Notice that now the sales order creation form always stays on top: < How it works... Normally, a splitter has to be placed between two form groups. In this recipe, to follow that rule, we need to adjust the BankReconciliation form's design. The AllReconciled, Balances and Tab controls are moved to a new group called Top. We do not want this new group to be visible to the user, so we FrameType to None. Setting AutoDeclaration to Yes allows us to access this object from the code. Finally, we make this group automatically expanding in the horizontal direction by setting its Width to Column width. At this stage, visual form layout does not change, but now we have the upper group ready. The BankTransTypeGroup group could be used as a bottom group with slight changes. We change its Top behavior to Auto and make it fully expandable in the horizontal and vertical directions. The Height of the grid inside this group also has to be changed to Column height in order to fill all the vertical space. In the middle of those two groups, we add a splitter. The splitter is nothing but another group, which looks like a splitter. In order to achieve that, we set the Height to 5, FrameType to Raised 3D, and BackgroundColor to Windows background. This group does not hold any other controls inside, therefore, in order to make it visible we have to set the HideIfEmpty property to No. The Column width value of the property Width forces the splitter to automatically fill the form's width. Mouse events are handled by the SysFormSplitter_Y application class. After it has been declared in the form's class declaration, we instantiate it in the object in the form's init() method. We pass the name of the splitter control, the name of the top group, and the form itself as arguments when creating it. A fully working splitter requires three mouse event handlers. It is implemented by overriding the mouseMove(), mouseDown(), and mouseUp()event methods in the splitter group control. All arguments are passed to the respective member methods of the SysFormSplitter_Y class, which does all the work. In this way, horizontal splitters can easily be added to any form. The Dynamics AX application also contains nice examples about splitters, which can be found in the AOT in the Tutorial_ Form_Split form. Vertical splitters can also be added to forms using a very similar approach. For this, we need to use another application class called SysFormSplitter_X.     Creating a modal form Quite often people who are not familiar with computers and software tend to get lost among open application windows. The same could be applied to Dynamics AX. Often a user opens one form, clicks a button to open another one, and then goes back to the first one without closing the second one. Sometimes this happens intentionally, sometimes not, but the result is that the second form is hidden behind the first one and the user starts wondering why it is not possible to close or edit the first form. Such issues can be easily solved by making the child form a modal window. In other words, the second form always stays on top of the first one until closed. In this recipe, we will do exactly that. As an example, we will make the Create sales order form a modal window. How to do it... Carry out the following steps in order to complete this recipe: How it works... The design of the form has a WindowType property, which is set Standard by default. In order to make a form behave as a modal window, we have to change it to Popup. Such forms will always stay on top of the parent form. There's more We already know that some of the Dynamics AX forms are created dynamically using the Dialog class. If we look deeper into the code, we could find that the Dialog class actually creates a runtime form. This means that we can apply the same principle—change the relevant form's design property. The following code could be added to the Dialog object and would do the job. The format is given as follows: code 15 Here we get a reference to the form's design, by first using the dialogForm() method of the dialog object to get a reference to the DialogForm object, and then we call buildDesign() on the latter object. Finally, we set the design property by calling its windowType() with an argument FormWindowType::Popup. Summary In this article, we looked at various aspects of building forms in Dynamics AX. We looked at dialogs and their events. We learned how to create a dialog and how to handle it. We also learned how to build a dyamic form, as well as learned how to create a modal form. We also looked at splitter, which is an important feature of Microsoft Dynamics AX 2012.   Installing Microsoft Dynamics NAV [Article] Integrating BizTalk Server and Microsoft Dynamics CRM [Article] Installing the Dynamics AX Base Server Components for Microsoft [Article] Fine-tuning the SQL Server database for fcDynamics NAV [Article]
Read more
  • 0
  • 0
  • 5130
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 €18.99/month. Cancel anytime
article-image-oracle-workflow-builder
Packt
11 May 2012
9 min read
Save for later

Oracle Workflow Builder

Packt
11 May 2012
9 min read
(For more resources on Oracle, see here.) Introduction In this article, we are going to take a look at workflow . There is a fair bit to go through but by the end of this article you will have a good grasp of the concepts of developing workflows and how to monitor them. We will also delve into business events and advanced queues as they are fairly closely related, especially in Release 12. Workfl ow Builder can be downloaded from Oracle (follow note ID 261028.1 from Oracle Support). In this article we are going to create a workflow that is triggered by a business event. We are going to create our own advanced queue and service component that will monitor the inbound XML messages for the recipes in this article. We are going to build a solution for a scenario where a signed absence form is sent in to the office from an employee's manager. The document is scanned and an XML message is extracted from metadata in the absence form. The XML message is then en-queued onto the advanced queue. The message on the queue launches a workflow, triggered by a business event, that will perform a number of actions and will end up creating an absence. When we create the workflow we will progress the workflow throughout the article until we have a solution to the business scenario. We will be starting the process at the point where we put an XML message onto the inbound queue. There will be a number of features of workflow that will be demonstrated, which will include: Creating attributes Creating messages Creating lookups Branching Notifications Timeouts Events Processes and subprocesses Introducing Workflow Builder Workflow builder is a development tool we will use to develop our workflow processes. It has a navigator similar to Oracle forms which is used to define attributes, processes, notifications, functions, events, messages, and lookup types. We can create and use these objects to build our processes. It is assumed that you have it installed on your PC. How to do it... There is a feature called access protection in Workflow Builder and this allows objects within a workflow to be locked. This prevents seeded workflows from being modified. Nearly all objects within Oracle Workflow have an Access tab on the Properties window except lookup codes, function attributes, and message attributes which inherit access protection settings from their parent object. The level of access can be set in Workflow Builder and developers need to set access levels as defined in the following list: 0-9 is reserved for Oracle Workflow 10-19 is reserved for Oracle Application Object Library 20-99 is reserved for Oracle E-Business Suite 100-999 is reserved for customer specific extensions 1000 is reserved for public An object will be locked to users that have a higher protection level than the object. You can see this as there is a padlock against objects that you do not have the access level to modify. The access level defaults to 100 and as an e-Business Suite developer, we always operate with an access level of 100. The access level can be modified by navigating to Help | About Oracle Workflow Builder as shown in the following screenshot: Oracle does not support customizations to standard workflows that have a protection level less than 100. We should not alter an object's protection level if it is less than 100 and we should never change the access level with the intention of modifying an object. How it works... We have discussed access control and how it determines the objects that should not be modified. However, always refer to the product-specific user guide and documents available through Oracle Support for details relating to specific seeded workflows. The product specific documentation will detail what should not be modified. Oracle Support Services will not support extensions to any workflow processes that they specifically state should not be modified. There's more… In addition to what we have discussed relating to access, it is also important to understand what the workflow engine is and how we can create supplemental engines to process costly activities such as Deferred workflows through the Workflow Background Process concurrent program. The Workflow Engine is a collection of server side PL/SQL tables, views, packages, and procedures embedded in the Oracle Applications database. It processes activities as they are executed at runtime and will process these through to completion provided each preceding activity completes successfully. When an activity gets stuck, deferred, or timed out, it will be left in that state to be processed by the Workflow Background Engine as these activity statuses are too costly to be maintained at runtime. When the background engine runs any stuck, deferred, or timed out activity statuses will be re-evaluated and the workflow will resume if logical conditions permit it. The workflow engine will process all function activities and send out notifications automatically. It can support numerous logical conditions such as launching subprocesses, running parallel processes, looping, and branching. The Workflow Background Process concurrent program is available in the System Administrator responsibility request group and can also be run from the Oracle Applications Manager screen. Generally, we will schedule a background engine concurrent program for specific item types to run periodically but there should be at least one background engine for each of the following: Timed out activities Deferred activities Stuck processes There are a number of parameters for the concurrent program that allow us to restrict the process to handle activities for specific item types, and within specific cost ranges. We can select parameters to process any combination of deferred, timed out, or stuck activities. A separate background engine to check for stuck processes can be scheduled at less frequent intervals than those scheduled for deferred activities. See also For more information on Oracle Workflow refer to the Oracle Workflow User Guide, Oracle Workflow Developers Guide, and Oracle Workflow API Reference Guide . Installing the database objects Create the database objects for this article before you start by using a script provided. The code comes with the readme file, readme_5_1.txt. We are going to create a number of objects that we will use throughout the article. For all the database objects, there is a script provided called 4842_05_01.sh. The following recipe provides details of how to run the script. How to do it... To create an advanced queue , perform the following steps: Create a local directory C:packtscriptsch5 where the scripts are downloaded to. Open Putty and connect to the application tier user.cd $XXHR_TOP/install    mkdir ch5  Create a new directory on the application tier under $XXHR_TOP/install with the following commands: cd $XXHR_TOP/install    mkdir ch5  Navigate to the new directory with the following command: cd ch5  Open WinSCP and ftp the files from C:packtscriptsch5 to $XXHR_TOP/ install/ch5 as shown in the following screenshot:   In Putty, change the permissions of the script with the following command:  chmod 775 4842_05_01.sh  Run the following script to create all of the objects by issuing the following command: ./4842_05_01.sh apps/apps  The script checks whether all of the files are present in your $XXHR_TOP/install/ ch5 directory and will prompt you to continue if they are all there, so type Y and press Return. After the script has completed check the XXHR_4842_05_01.log file for errors. (It will be created in the same directory, $XXHR_TOP/install/ch5). How it works... We have now created all of the database objects for this article. Creating an advanced queue We will now create an advanced queue and the messages we put into the queue will trigger our workflow process later in the article. The creation of advanced queues is performed by calls to the dbms_aqadm package. Advanced queues are very different from normal database tables. For example, we cannot insert records directly into the advanced queue tables. We must enqueue and dequeue messages to the advanced queue. When we create an advanced queue we will perform the following tasks: Create queue table Create queue Start queue Grant ENQUEUE and DEQUEUE privileges to the apps user Getting started To perform these actions there is a script in the download bundle called XXHR_CREATE_ABS_ AQ.sql. We are going to use this script to create the queue in the APPLSYS schema. How to do it... To create the advanced queue, perform the following steps: Ftp the SQL script XXHR_CREATE_ABS_AQ.sql to $XXHR_TOP/install/ch5. Open a Putty session and change the directory to $XXHR_TOP/install/ch5 with the following command: cd $XXHR_TOP/install/ch5  Start an SQL*Plus session and log on as the APPLSYS user by typing the following command: sqlplusapplsys/<apps password>  (Remember the APPLSYS password will be the same as the apps password.) Run the SQL script with the following command: SQL> @XXHR_CREATE_ABS_AQ.sql  When the script has completed type exit to come out of SQL*Plus. Now you can close the Putty session. Run the following query to check that all of the objects have been created successfully: SELECT OWNER, OBJECT_NAME, OBJECT_TYPE, STATUS   FROM ALL_OBJECTS  WHERE (OBJECT_NAME LIKE 'XXHR%ABS%'    OR OBJECT_NAME LIKE 'XXHR%XML%')ORDER BY 1, 2  How it works... The advanced queue will be used to enqueue XML messages in this article. We will use a script to put XML messages onto the queue. The queue will be monitored by an agent listener so that any message will trigger a business event. We will subscribe to the business event to launch a workflow.
Read more
  • 0
  • 0
  • 5633

article-image-troubleshooting-intuit-quickbooks
Packt
08 May 2012
12 min read
Save for later

Troubleshooting with Intuit Quickbooks

Packt
08 May 2012
12 min read
The following table is the Recipe Reference Card for the keyboard shortcuts included in this article: Find Ctrl+F Delete the line Ctrl+Del Save and close Alt+A Advance to the next field Tab Regress to the previous field Shift+Tab Customize the report Alt+M   Clearing stale undeposited funds When the Undeposited Funds window includes customer payments, which you know have already been deposited, recorded, and reconciled, the Income or Unearned Income and Undeposited Funds accounts are overstated. You can use this recipe to efficiently combine the cleared deposit with the undeposited funds. Getting ready Verify that the appropriate bank account is reconciled for the period containing the stale undeposited funds. If not, this can be resolved simply by deleting the recorded deposit and recording the deposit of the undeposited funds. How to do it... With the Find tool (Edit | Find or Ctrl+F), use the Amount filter, along with the Date filter, if necessary, to bring up both the deposit and the customer payment already recorded. Open up the deposit, and click on the Payments button. Check off the appropriate transaction, and click on OK to add this to the deposit. Click on the line item for the deposit originally on the screen, that is, the duplicate of the payment that you just added to this screen. Click on Edit | Delete Line (Ctrl+Del), and then Save and Close (Alt+A). How it works… The only way to directly delete an item added to Undeposited Funds is to delete the underlying customer payment or sales receipt. However, this is not advisable, because these transactions are typically accurate representations of a real-world activity. Additionally, when the deposit was recorded, the related account duplicated the income or customer deposit from the original invoice or sales receipt. Therefore, the deposit itself needs to be modified to simultaneously remove the duplicate offset account, and resolve the outstanding Undeposited Funds item. There's more… For a printable and memorizable list of all outstanding items in the Undeposited Funds account, open the Undeposited Funds ledger. Click on Customize Report | Filters | Choose Filter | Cleared | No. On the Header/Footer tab, in the Report Title field, enter Undeposited Funds, and click on OK. Adjusting cash basis receivables or payables balances Does your cash basis balance sheet show balance in your receivable or payables accounts? This recipe will take you through the two-step process of resolving these items: Locate them Adjust them Getting ready To find out which customers and vendors are responsible for your cash basis accounts receivable or accounts payable balances, respectively, run the following report: Go to Reports | Custom Reports | Summary. Set Dates to All. If you desire a cut-off date, leave the From field blank, and enter your cut-off date in the To field. Set Report Basis to Cash. Set Display rows by to Customer or Vendor. Go to Advanced, and set Display Rows to Non-zero. Go to the Filters tab, and set Account to Accounts Receivable (or Accounts Payable). Go to the Header/Footer tab, and set Report Title to Cash Basis A/R by Customer or Cash Basis A/P by Vendor. The report total matches your balance sheet account total for the same cut-off date. How to do it... Double-click one of the account balances to reveal the detail, and remove the columns irrelevant to this effort. Scan the activity for patterns, unusual items, or clues about the cash basis balance. Gain an understanding of the transaction, and resolve the items by changing the accounts, changing a date, making a journal entry, noting that no adjustment is needed, or other action. Refresh the report, and confirm either a zero balance or an appropriate cash basis balance. How it works… Some of the most likely patterns to scan for include the following: A Balance column, which keeps returning to 0.00, and then stops returning to 0.00: An unusual transaction Type: A recurring figure in the Balance column. This lets you know that at least one culprit occurred before the recurrence began: A zero balance right before a transaction, which is also the aggregate balance sheet account balance: There's more… The most common reasons for a cash basis receivables or payable balance are: Payment date precedes bill or invoice date, and the report cut-off is between both the dates Offset account is a balance sheet account, and the bill or the invoice is unpaid Writing off stale receivables Making a journal entry to write off stale A/R in bulk is easy, but this makes it difficult to trace through the accounting records. The possible uses for more precise information include producing a trail for taxing authorities, internal or independent auditors, or banks. A separate spreadsheet may suffice, but it may be difficult to coordinate. This recipe focuses on straightforward ways to write off these balances in a detailed, but effi cient fashion. Getting ready Have your criteria ready for which invoices are to be written off. The A/R Aging Summary report may help (Reports | Customers & Receivables | A/R Aging Summary). To further analyze your oldest receivables: Go to Customize Report | Age through how many days?, and type 360. Go to Filters | Choose Filter | Aging | >=, and type 90. Go to Header/Footer, add the text: Older Than 90 days to the Report Title, and click on OK. How to do it... To write off a stale receivable: Go to the Customers page or Home Page | Receive Payments. From the Received From drop-down box, select the appropriate customer. If applicable, select the particular job instead. In the Date field, enter the effective date of the writeoff. Click on the Discount & Credits button. In the Discount and Credits pop-up window, fill in the amount to be written off, the writeoff account (generally Bad Debt), and the same class from the original invoice, if class tracking is used in the file: The completed screen should have 0.00 in the Amount and Payment fields. Include the amount written off in the Discount field: If an allowance for doubtful accounts is used against bad debt for writeoffs, then set up the Allowance account as an Accounts Receivable account type , and select the Allowance account from the drop-down box at the top of the Customer Payments screen. A set of journal entries can be used later, to remove the amounts from both Accounts Receivable and the Allowance account. There's more… This is the same procedure that can be used to record discounts, but the key is that an income or expense account must always be selected. This procedure is not appropriate for a balance sheet account to be selected, such as debiting a liability account while crediting A/R, or debiting the Allowance account while crediting A/R. This will cause a cash basis balance sheet report to be out of balance. If that combination of debits and credits is essential, then use a journal entry instead. Then, apply the journal entry to the original invoice, by opening the invoice, and clicking the Apply Credits button. When this recipe is used to write off receivables, Act. Revenue is reduced in the Job Profitability Summary report , and there is no effect on the Item Profitability Summary report. The same reporting results are attained if a journal entry is used to debit Bad Debt Expense and credit Accounts Receivable. If a Credit Memo is used instead, Act. Revenue is reduced in the Job Profitability Summary report as well as the Item Profitability Summary report. In order to increase the Act. Cost column in the Job Profitability Summary report instead, use the Write Checks screen in an unusual fashion: on the Items tab, use an Other Charge item called Bad Debt or Writeoffs. When you create this item, link it to the Bad Debt Expense account. On the Write Checks screen, be sure to enter the Customer:Job name as well as the writeoff amount. On the Expenses tab, select Accounts Receivable, and enter the writeoff amount as a negative number, so that the total amount of the check equals 0. Be sure that the check bears no check number, and clear it in the next bank reconciliation. This technique causes both the Job Profitability and Item Profitability reports to show the transaction as an expense, rather than as a reduction of revenue. It works because QuickBooks includes the Write Check transactions in the Act. Cost column of these reports. Writing off stale payables Making a journal entry to write off stale A/P in bulk is easy, but makes it difficult to trace through the accounting records. Possible uses for more precise information include producing a trail for taxing authorities, internal or independent auditors, or banks. A separate spreadsheet may suffice, but may be difficult to coordinate. This recipe focuses on straightforward ways to write off these balances in a detailed but efficient fashion. Getting ready Have your criteria ready for which bills are to be written off. The A/P Aging Summary report may help (Reports | Vendors & Payables | A/P Aging Summary). To further analyze your oldest payables: Go to Customize Report | Age through how many days?, and type 360. Go to Filters | Choose Filter | Aging | >=, and type 90. Go to Header/Footer, add the text: Older Than 90 days to the Report Title, and click on OK. How to do it... Go to Vendors or Home Page | Pay Bills. Consider using the Filter by drop-down list to only show bills from a particular vendor, and consider using the Sort by drop-down list to organize the payables list by Due Date. For one single vendor, check off the fi rst bill to be written off. Click on the Set Discount button . In the Discount and Credits pop-up window, fi ll in the amount to be written off, the writeoff account (generally the same expense account as the original bill), and the same class from the original bill, if class tracking is used in the file: Click on Done, and proceed to the next bill for the same vendor. Make sure the Payment Date field is the effective date of the write off. The completed screen should have 0.00 in the Amt. to Pay field. Include the amount written off in the Disc. Used field: When the writeoffs for that vendor are complete, click on Pay Selected Bills, followed by Pay More Bills for additional writeoffs. There's more… The advantage of this recipe is that the transaction is created and applied to the bill in a single step. However, the drawback is that it does not appear in the Job Profitability Summary or the Item Profitability Summary reports. For that to occur, create a vendor credit instead, by using the Enter Bills screen, and clicking on the Credit button. Then, use the Items tab to record the credit, using the same item that was used in the original bill. Additionally, use the Customer:Job field to apply the credit to a particular job. For a partial writeoff, after the Discount and Credits window is closed, be sure to manually input 0.00 into the Amt. to Pay field. The default is to include the remaining balance in that field, and this recipe assumes that the current action is only to record writeoffs, not payments to vendors. Balancing the balance sheet How can a balance sheet get out of balance in a software program? If you're reading this recipe, you may have already seen for yourself that the impossible can happen. The following is a procedure to root out the transaction which is causing this phenomenon. Getting ready A balance sheet prepared on the cash basis can be out of balance if certain transactions were saved, for example if the Discount feature was used with a balance sheet account. How to do it... Open a Balance Sheet Summary report. Click on the Customize Report button and in the Dates drop-down box, select All. If the report is on the accrual basis, change the Report Basis to Cash. In the Display columns by drop-down box, change the selection to Year, and click on OK. Look at the balance sheet, and identify the earliest year in which the balance sheet is out of balance. Click on the Customize Report button . In the From and To fields, enter the beginning and ending dates of the year identified in the previous step. In the Display columns by drop-down box, change the selection to Month, and click on OK. Look at the balance sheet, and identify the earliest month in which the balance sheet is out of balance. Click on the Customize Report button . In the From and To fields, enter the beginning and ending dates of the month identified in the previous step. In the Display columns by drop-down box , change the selection to Week, and click on OK. Look at the balance sheet, and identify the earliest week in which the balance sheet is out of balance. Click on the Customize Report button . In the From and To fields, enter the beginning and ending dates of the week identified in the previous step. In the Display columns by drop-down box, change the selection to Day, and click on OK. Look at the balance sheet, and identify the earliest day in which the balance sheet is out of balance: Run a transaction journal (Reports | Accountant & Taxes | Journal), limit the transactions to that day, and scan the report for the transaction responsible. Delete the transaction which caused the imbalance, which is usually a Customer Payment or other A/R or A/P data entry screen, and make a journal entry instead, to cover the appropriate debit and credit. There's more… If the Discount feature was used to reclassify an Accounts Receivable balance to Retainage Receivable, make a journal entry to achieve the same General Ledger effect instead, and apply the transaction to the original invoice, by opening the invoice and using the Apply Credits button.
Read more
  • 0
  • 0
  • 2142

article-image-creating-and-managing-user-accounts-microsoft-windows-sbs-2011
Packt
25 Apr 2012
6 min read
Save for later

Creating and managing user accounts in Microsoft Windows SBS 2011

Packt
25 Apr 2012
6 min read
  (For more resources on Microsoft, see here.) A user account or object in a Windows Server domain is a security mechanism that allows a person to access the resources of the network by "logging in" to the network. Doing so with the correct credentials automatically provides the user with the configured rights to network resources such as files, folders, printers, and so on. Most importantly, Windows SBS 2011 Standard is just like any Windows Server in that it leverages the power of Active Directory to manage and maintain these user objects. The major difference that Windows SBS 2011 Standard brings with it is that the majority of these tasks can be accomplished via wizards. Using the wizards not only reduces the time taken to administer a Windows SBS 2011 Standard network, but it also always produces a consistent result. For these reasons alone every Windows SBS 2011 Standard administrator should always use the wizards when administrating their network, especially when working with user accounts.   Creating, editing, and deleting user accounts It is important that you always use the Windows SBS 2011 Standard Console and wizards when you create, edit, or delete any users. The main reason is that the wizards do a number of things behind the scenes to ensure everything works correctly on the Windows SBS 2011 Standard system. Creating users manually via native Active Directory tools may result in features not being enabled. The wizards are there to do all the hard work and create the accounts for you in Active Directory; so don't fear they are doing something different, they aren't. They are there to make an administrators' life easier, so use them every time. This cannot be stressed strongly enough. To create a new user: Run the Windows SBS 2011 Standard Console. Select the Users and Groups icon. Select the Users tab: (Move the mouse over the image to enlarge.) You should now see a list of any existing users and you should also see the option Add a new user account link under the Tasks section to the right. Click this option to create a new user. The Add a New User Account wizard now runs. Enter the details for the user. Also select the role for that user from the drop-down list. When complete, click the Next button to continue. At the next screen you will be prompted to enter the user's password. It is important to note that you cannot progress past this screen until you have entered a password that conforms to both length and complexity requirements. These requirements can be modified in the system if required. Once you have entered a suitable password, the Add user account button will be available. Click this to continue. The wizard will now run and create a network account for the user, create a home folder for that user, an e-mail account, set appropriate quotas, and send a Welcome e-mail to the user's inbox. When complete, click the Finish button: You should now see the user you created appear in the list of Users. To edit an existing user account, simply: Run the Windows SBS 2011 Standard Console. Select the Users and Groups icon. Select the Users tab. Select the user you wish to edit from the list of users that is displayed. From the Tasks list on the right, select Edit user account properties. You shouldnow see all the properties of the user displayed in a window, as shown in the next screenshot. Simply select the desired section from the left and make any changes to the properties on the right. Click the OK button to save the changes and return to the Windows SBS 2011 Standard console: To delete an existing user account: Run the Windows SBS 2011 Standard Console. Select the Users and Groups icon. Select the Users tab. Select the user you wish to delete from the list of users that is displayed. On the right-hand side, under the Tasks pane select Remove user account. You'll be prompted to confirm that you wish to delete the selected account. By default doing so will also remove that user's mailbox and shared folder. If you don't desire this, simply uncheck these options before clicking the Yes button to proceed: The selected account will then be removed from the system and you should receive a confirmation that the process completed successfully. When this is displayed simply click the OK button. This will take you to the Windows SBS 2011 Standard Console and you should notice that the selected user no longer appears in the list.   Assigning permissions to users To assign permissions to an existing user account you will need to edit that account. To do this: Run the Windows SBS 2011 Standard Console. Select the Users and Groups icon. Select the Users tab. Select the user you wish to edit from the list of users that is displayed. From the Tasks list on the right, select Edit user account properties. You should now see all the properties of the user displayed in a window, as shown in the following screenshot. Simply select the desired section from the left and make any changes to the properties on the right: For example, if you wish to change the user's rights to the files on the server, this would normally be done via the Groups option. If you select the Groups option, you will be shown a list of groups that the user belongs to. You can select an existing group and remove it or you can add a group. Adding a user to a group will automatically provide them access to whatever the group has access to. Click the OK button to save the changes and return to the Windows SBS 2011 Standard console. You can also change the user's permissions by changing their role on the network. In this way, you can promote or demote a user to the same level as any pre-configured user role. To make this change: Run the Windows SBS 2011 Standard Console. Select the Users and Groups icon. Select the Users tab. Select the user you wish to edit from the list of users that is displayed. From the Tasks list on the right, select Change user role for user accounts. The wizard will then prompt you to select which role you wish that user to assume, as previously shown. You can also elect to Replace user permissions or settings or Add user permissions or settings: You will then be asked to select one or more users from a list of users whose role you wish to change. Once the selection process is complete click the Change user role button. The wizard will now run and when complete you will be provided with a status window as to the success of the process. Click the Finish button to complete the process. The user will now have either the same permissions as the role you selected, or the merged permission of the user role and the existing rights, depending on what option you selected during the process.  
Read more
  • 0
  • 2
  • 10671

article-image-components-tm1
Packt
24 Apr 2012
7 min read
Save for later

The Components of TM1

Packt
24 Apr 2012
7 min read
The components of TM1 First we'll get introduced to the client components of Cognos TM1. Client components Client components allow access to the TM1 Servers. During a default installation, the following Client components will be installed: TM1 Client TM1 Perspectives TM1 Architect TM1 API OLE DB Provider What we mean by OLE DB Provider is simply an external software component that enables TM1 to have specialized access to OLAP data sources such as Microsoft Analysis Services and it is not directly referenced in the current IBM Cognos TM1 Developer (Test COG-310) certification exam, so we will not spend time on it. All of the client components can be installed on a user (client) machine as well as the (server) machine that the TM1 server components are installed. There is an advantage in having at least one client component installed on a server machine for debugging purposes, however some installation polices may inhibit this practice. TM1 Client The TM1 (basic) client is accessed through Microsoft Excel as an Add-In and will allow limited access to available TM1 Servers. As a Cognos TM1 developer, you should know that a Microsoft Excel Add-In is a file that Excel can load when it starts up. The file contains program code that adds additional functionality to Excel, usually in the form of new functions. TM1 Client does not allow administrative access to any TM1 Servers. It does not offer the ability to set up and run a local TM1 Server. During the installation, a local version of TM1 Server is installed and can be accessed by TM1 Client, TM1 Perspectives, or TM1 Arch itect. A local TM1 Server gives you exclusive (administrative) access to data and objects in a set of Windows folders called data directories. During a TM1 Client session, only you can create, browse, and modify data or objects that a local server stores. You can also control where the data directories should be located. Since the TM1 Client is limited in functionality, most users will choose to install and use TM1 Perspectives (TM1 Client is not covered in the exam, but you should at least be aware that it exists and what functionality it offers). During a default installation, TM1 Client and TM1 Perspectives are both installed. Upon loading of the TM1 Add-In in Microsoft Excel, if no valid TM1 Perspectives license file (.lic) is found, you can only start and run TM1 Client even though you have installed TM1 Perspectives. TM1 Perspectives As with TM1 Client, TM1 Perspectives is loaded and runs as an Add-In to Microsoft Excel. With TM1 Perspectives, you can access data within TM1 Servers and you can also create and maintain TM1 objects and data on both local and remote TM1 Servers. It is important to be aware of the fact that with each installation of TM1 Client and TM1 Perspectives, a "personal configuration" file named Tm1p.ini is installed. This file is used to configure the settings for the behavior of the Add-In file within Microsoft Excel. During a TM1 installation, you can choose to automatically load TM1 Perspectives (or TM1 Client) when Excel starts. Don't worry, if you missed this during the installation, you can perform the following easy steps: Open Microsoft Excel on your desktop. Click on Tools | Add-Ins from the Excel menu bar. Select Tm1p.xla. Click on OK. When you click on Add-Ins, Microsoft Excel will most likely show you a location where it thinks the TM1P Add-In file exists.   You will almost never find the TM1P file where Excel says it should be, so you will need to browse to the location on your machine where TM1 installed the file as shown in the following screenshot:   The TM1P Add-In file is usually installed during installation to the directory folder CognosTM1bin. Features of TM1P The default version of Tm1p.ini allows multiple users to use TM1 on a given computer. Tm1p.ini must be present the first time a user starts TM1 on the computer, as the parameters in the system default version govern the behavior of the initial startup of the TM1 Client for each user. After a user starts TM1 on the computer, a user-specific copy of Tm1p.ini is created in %APPDATA%ApplixTM1Tm1p.ini. In most cases, the full path to the Tm1p.ini file is: C:Documents and Settings<user name>Application DataApplixT M1Tm1p.ini. The user-specific copy of Tm1p.ini accepts all parameter settings and changes for the user and governs the behavior of the TM1 Client for all subsequent user sessions of the TM1 Client. It is important to know how to locate and configure the Tm1p.ini file. As you will find references to the file's purpose and settings of the file in the exam and in practice, you will have occasion to access and update it. For your users running TM1 Clients on Windows Vista and Windows 7, application data (and therefore the Tm1p.ini file) is stored differently. To locate the .ini file, open a command line prompt, for example – Start | Run | cmd. Execute the command set APPDATA to discover where the application data (and the Tm1p.ini file) is stored. The directory that is displayed will contain a directory named ApplixTM1 that will contain Tm1p.ini. The Tm1p.ini file is important because that is where you can set parameters that change the user's TM1 Perspectives experience. Some of the most interesting (and important) .ini file parameters are: ConnectLocalAtStartup: This parameter is set to True or False and indicates whether the client automatically attempts to connect to the local server at startup. For most users it is advantageous not to connect to the local server. AdvancedRulesEditor: This parameter is set to True or False and will indicate the type of TM1 Rules Editor that is used. The advanced Rules Editor has an enhanced interface and is somewhat more complicated and may or may not be a good choice to offer to the user, depending on that user's skill level. DisplayApplications, DisplayChores, DisplayControlCubes, DisplayCubes, DisplayDimensions, DisplayProcesses: These parameters (set to True or False) indicate whether TM1 Perspectives will display application folders, chores, cubes, dimensions, or processes to the user. At this point in my career I have never seen these parameters set to values other than their default values. DisplayExplorerPropertiesWindow: This is again a True or False parameter that indicates whether the Properties pane is visible in Server Explorer on startup. The Properties pane can be helpful to some users, but there is a slight performance impact with it "turned on" and visible. You may want to set this default to False. The Properties pane can be made visible later in TM1 Server Explorer by clicking on View and then selecting Properties Window. DisplayReplications: This True/False parameter should be set to False for most users. This parameter indicates whether the Replications group is visible in Server Explorer at startup. TM1 Architect TM1 Architect is a standalone TM1 Client application (meaning that it does not plug in to Microsoft Excel) and is used to create and maintain data and metadata on both local and remote TM1 servers. Usually, you will see a separate menu item on your computer's desktop for accessing TM1 Architect directly as shown in the following screenshot: This is a tool that will be used by a TM1 user who is granted at least minimal "administrator" privileges (that is, a developer or programmer type). It is best to use Architect when focusing on Turbo integrator scripting or possibly checking security assignments because it allows access to these features of TM1 without having to load Microsoft Excel. You can actually have both TM1 Perspectives and TM1 Architect open and running at the same time on your machine, accessing the same or different TM1 Servers. Again, TM1 Architect does not hook into Microsoft Excel and cannot be used directly to create and maintain TM1 enabled Excel worksheets. TM1 API Along with TM1 Architect, an application programming interface (API) is installed during a default installation. This interface may be used by more experienced developers to create C++ and VB applications that interact with TM1. The API is not covered in the exam. During the installation, JAVA and .NET API are also installed.
Read more
  • 0
  • 0
  • 4308
article-image-dynamic-flash-charts-fusioncharts-style
Packt
24 Apr 2012
30 min read
Save for later

Dynamic Flash Charts - FusionCharts style

Packt
24 Apr 2012
30 min read
As web developers, we build applications that feed on data. We parse it, process it and report it. Our reports take the form of tables, grids, and diagrams such as charts, gauges, and maps. Parsing and processing are backend tasks that are unseen by the user. The actual reporting of data, however, is the bulk of the experience a user has with our application. To make our reports interesting and insightful, it is important to provide a highly engaging and functional face to the data in context. While tables, grids, and basic charting are natively supported by most web scripting languages, creating advanced or interactive charts require the use of third-party components. FusionCharts Suite is one such suite of components that help you deliver a delightful experience by aiding the creation of animated and interactive charts, gauges, and maps. Before we jump in and look at what FusionCharts can do for you, let us see where charts, gauges, and maps can be helpful. Google Analytics, a tool that most web developers swear by, is a beautiful example of effective data presentation. In case you do not know, it is a tool that records a ton of information such as visitor demographics, referrers, advertising, browser information, and so on. With so much data recorded, it is of utmost importance to present it in a compact, yet insightful way, as shown in the following screenshot:     Note how the Dashboard has a very clean and non-cluttered look, despite the large data set it represents. Extra information, which is not required in the main layout, is displayed as tool tips and annotations. Interactive features such as a clickable world map lets you explore the data the way you want to. The selection of chart types is also immaculate, with the line chart showing the trend of the most commonly used metric—the number of visitors to the site. Other relevant metrics such as Pageviews and Pages/Visit are communicated in large text along with sparklines providing a historical context. A world map is used to display where the traffic is coming from. FusionCharts Suite helps you build similar dashboards with a lot more chart types and interactivity. Without further ado, let us proceed and set the goals for this article. What is FusionCharts Suite? FusionCharts Suite is a collection of four products, each of which help generate different types of charts, gauges, or maps in web applications. These data-visualization components are ideal for use within reports, dashboards, analytics, surveys, and monitors in web and enterprise applications. The visualizations are rendered using both Adobe Flash and JavaScript (HTML5), thereby making the experience seamless across PCs, Macs and a wide spectrum of devices including iPads and iPhones. The four products in the suite are: FusionCharts XT: This helps create the 45 most used chart types such as pie, column, bar, area, line, stacked, combination, and advanced ones such as Pareto and Marimekko. FusionWidgets XT: This helps create Key Performance Indicators ( KPI) and make real-time data in dashboards, monitors, and reports more insightful. It includes a wide variety of charts and gauges such as dial charts, linear gauges, Gantt charts, funnel charts, sparklines, data-streaming column, line, and area charts. PowerCharts XT : This helps create charts for domain-specific usage such as those in network diagrams, performance analysis, profit-loss analysis, financial planning, stock price plotting, and hierarchical structures. FusionMaps XT: This consists of over 550 geographical maps, including all countries, US states, and regions in Europe for plotting business data. All the products are built on a common framework and offer similar ways to use and configure them. To start with, we will create charts using FusionCharts XT and later explore charts of other products. Without further ado, let us get started and build our first chart. For that, you will first need to download FusionCharts Suite. Getting FusionCharts FusionCharts allows you to download the trial version from its website http://www.fusioncharts.com. This trial does not have any feature restriction or an expiry date. The only caveat is that the charts in the evaluation version have FusionCharts printed on the chart, which can be removed by purchasing a license of FusionCharts and later just replacing the Shockwave ( SWF ) and JavaScript( JS ) files, as we shall see later. Time for action – downloading and extracting FusionCharts Go to http://www.fusioncharts.com/download and fill in your particulars in the download form and click on Download. On the next page, you will find links to either download the entire FusionCharts Suite, or individual products from the suite. In this article, we will work with FusionCharts XT only and hence will explore that. Once the ZIP file has been downloaded, extract it to a folder on your hard drive, which is conveniently located at C:FusionChartsSuiteFusionChartsXT on Windows or Users/{YourName}/FusionChartsSuite/FusionChartsXT on Mac or UNIX based systems. Throughout this book, we will refer to this folder as the FusionCharts Installation Folder. The steps to install and use FusionCharts remain the same, whether you are using the trial or licensed version. What just happened? You have now successfully downloaded FusionCharts XT and extracted it in the FusionCharts Installation Folder. We will soon learn how to use these files to build charts. Before that, let us quickly explore the contents of the FusionCharts package. Within the FusionCharts Installation Folder, you will find multiple folders. Some of the folders are internal folders used to store documentation and gallery files, for example, Contents, Gallery, and so on. The folders that you will mostly use are Charts, Code, SourceCode, ExportHandlers, and the Tools folder for the following purpose: Folder Name What it contains? Charts Contains all the SWF and JS files that form the core of FusionCharts – we will refer to it as Core FusionCharts files. The FusionCharts SWF files have been created using Adobe Flash 8 and need Flash Player 8 (or above) to run. The JavaScript is compatible with IE6 (or above), Firefox, Chrome, Opera, and Safari, including that on iPads and iPhones. Code Consists of code samples in various programming languages that you can explore, to quickly learn or get started with. SourceCode Present only in Enterprise and Enterprise Plus license, this folder contains the source code of FusionCharts in both Flash Source files (.fla) and JavaScript files. Tools Consists of utility applications in three subfolders: FCDataConverter helps you convert the FusionCharts XML data to JSON data and vice versa. We will explore this later in the chapter, after we have created our first chart. FlashPlayerSecuritySetup contains scripts that help you configure security settings on your local machine only when using FusionCharts with JavaScript. We will explore this later in the book when we build advanced examples of FusionCharts integrated with JavaScript. XMLGenerator is a visual interface to generate XML data for FusionCharts. This is primarily intended for non-developers and would not be of much help to us. The FusionCharts Installation Folder also contains three files in the root folder: Filename What it contains? FusionCharts License Agreement.rtf Contains the license agreement that governs the usage of FusionCharts. You may want to read through it before using FusionCharts. Version.txt Contains the detailed version history of FusionCharts XT. Index.html The main page that you use to start exploring FusionCharts package. When you run Index.html, you will see a page similar to the following screenshot: When you click on the Documentation link, it opens the documentation for FusionCharts XT, as shown in the following screenshot: This documentation is an exhaustive resource for FusionCharts including sections for beginners, chart parameter lists, API references, and sections on advanced charting. From Index.html, you can also explore all the chart types present in FusionCharts XT by clicking on Chart Gallery. It presents a list of chart types and multiple examples for each, as shown in the following screenshot. We recommend you spend some time exploring this, as this is a good learning resource to get a real-world feel of the charts and understand what you can create once you are familiar with FusionCharts. The Live Demos section, accessible from Index.html, lets you explore sample dashboards and examples created using FusionCharts—both offline and online. Now that you have had a taste of what FusionCharts can do for you, it is time to create your own chart, your first chart using FusionCharts. Creating your first chart In our examples, we will create charts for a fictional supermarket, Harry's SuperMart, so that Harry, the owner of the supermarket, can make more sense out of his data. Harry's SuperMart, with 11 stores located in four states in the US, offering over 2,000 types of products and a customer base of around 25,000, records an intensive amount of data, which when presented effectively gives a lot of actionable insights. We will learn how to build meaningful charts that can facilitate this. For our first chart, let us build a simple Revenue by Year chart. Once completed, the chart should look similar to the following screenshot: Steps to create a chart using FusionCharts Fundamentally, for each chart you build, you should ask yourself the following questions to ensure that the chart serves a meaningful purpose, as opposed to just being a fancy object on the page: Who will view this chart and why will this data interest him? This person is the end user. What type of chart is best suited to represent this data? Are there any alternate charts that we can use? Is this chart part of a bigger report/dashboard, or standalone? This helps us decide how to split information across multiple charts. For our first chart that we build, Harry is the end user. This chart lets him compare the revenues of this year against the last two years. We would plot this data on a 3D Column chart, as Harry uses this to compare the revenues instead of seeing the overall trend. Had Harry wanted to see the trend of revenues over multiple years, we would have used an area or line chart. Also, to keep things simple, we will build this as a standalone chart. Thereafter, technically, there are three steps to build a chart using FusionCharts: Set up FusionCharts for the entire application, typically done only once per application. Encode the data for the chart, either in XML or format. Write the HTML and JavaScript code to include the chart in a web page. Let us cover them one-by-one. Time for action – set up FusionCharts for our first chart Create a folder on your hard-drive to centrally store all the examples that we will build iteratively. If you are working on a web server, you can create this under the root folder of the web application. Let us name it as LearningFusionCharts. You can give it any other name as well. Create a subfolder called FusionCharts within this folder. This folder will contain all the SWF and JavaScript files of FusionCharts, which are the FusionCharts Core files. If you are working on a web server, create this folder under the root of the web application, so that the entire web application can conveniently access this. Copy all the SWF and JS files from the Charts folder under the FusionCharts Installation Folder (where you had earlier downloaded and extracted the FusionCharts ZIP file) to the newly created FusionCharts folder. This step completes the installation of FusionCharts for your application. Create another folder under LearningFusionCharts and name it as FirstChart. This will be used to store the XML data and the HTML file for our first chart. Upgrading the FusionCharts version, or converting from trial to licensed If you are upgrading to a newer version of FusionCharts, or converting from evaluation to a licensed version, all you need to do is copy the SWF and JS files from the new or licensed version and overwrite the existing files in the FusionCharts folder. What just happened? You just installed FusionCharts. It involved copying of all the SWF and JavaScript files of FusionCharts, which are the FusionCharts Core files. If you intend to plot just a subset of chart types, you can select only those SWF files and paste them here. However, copying all files makes it easier in the future whenever you need to create a new chart type in your application. Each SWF file is used to plot a particular type of chart in Flash and the name of the file represents the chart type. You can find the complete list of charts in FusionCharts Documentation | Introduction | List of Charts. For our first chart, we are going to use Column3D.swf to plot a 3D Column chart. The FusionCharts folder also contains six JavaScript files that aid in embedding and configuring charts, along with rendering them in JavaScript when viewed on devices that do not support Flash. These files are as follows: Filename of the JavaScript Class Purpose FusionCharts.js This is the main JavaScript class for FusionCharts, which helps you embed charts in your web pages in a user-friendly way, and offers functionalities such as updating chart data, retrieving chart data, supporting multiple data formats, and event handling. FusionCharts.HC.js This framework contains code to render FusionCharts in JavaScript. FusionCharts.HC.Charts.js Contains chart specific code to render FusionCharts XT in JavaScript. jquery.min.js Minified jQuery framework used by FusionCharts class for internal functions. FusionCharts.jqueryplugin.js FusionCharts jQuery class that lets you embed FusionCharts using jQuery syntax. FusionChartsExportComponent.js The charts generated by FusionCharts can be exported as images or PDFs in the browser itself, using a module called Client-side Export Component, as we will see later. This JavaScript file provides interfaces to link the Client-side Export Component to the charts. While creating your chart, as you will soon see, you just need to include FusionCharts.js in your page. The other files such as FusionCharts.HC.js, FusionCharts.HC.Charts.js, and jquery.min.js are dynamically loaded by the code in FusionCharts.js. With the basic setup in place, let us focus on the data for our chart. Time for action – creating XML data for our first chart Create an empty XML file within the FirstChart folder named as Data.xml. This can be done using your text editor (Notepad on Windows, or TextEdit on Mac). To do so, while saving an empty text file, rename the extension to .xml. Write the following XML code in the file and save it: <chart caption='Harry&apos;s SuperMart' subcaption='Revenue by Year' xAxisName='Year' yAxisName='Amount' numberPrefix='$'> <set label='2009' value='1487500' /> <set label='2010' value='2100600' /> <set label='2011' value='2445400' /> </chart> Check whether the XML is valid by opening Data.xml in Internet Explorer or Firefox. If the browser shows the XML properly, you are good to go. Otherwise, review the error message and fix the error in XML accordingly. What just happened? Here, we have encoded the data, as shown in the following table, to an XML format supported by FusionCharts: Year Revenue 2009 $1,487,500 2010 $2,100,600 2011 $2,445,400 Each chart in FusionCharts is powered by data. This data could be static and hand-coded as we will build in this example, or dynamically generated by live scripts that are connected to databases or web services. FusionCharts can accept this data in two formats—XML and JSON. Both are commonly used formats for data exchange on the Web, with XML being easy on the human eyes. The XML format that we just created is called single-series XML in FusionCharts parlance, as we are plotting just one series of data. Later in this chapter, we will explore multi-series charts that let you compare more than one series of data, for example, revenue split across Food and Non-Food products for each year across last three years. All FusionCharts XML files start with the <chart> element. The attributes of the <chart> element help you configure the functional and cosmetic properties of the chart. In our example, we have defined the chart caption, subcaption, axis titles, and the currency prefix for numbers on the chart, as in the following line of code: <chart caption='Harry&apos;s SuperMart' subcaption='Revenue by Year' xAxisName='Year' yAxisName='Amount' numberPrefix='$'> For each chart type, there are hundreds of optional attributes that you can define. If these are not defined, the chart assumes the default values for each of them. Special characters in XML need to be encoded XML documents can contain non-ASCII characters or special characters. However, these need to be encoded before they are provided in the XML document. In our example, note how we have encoded the apostrophe in Harry's to Harry's. Had we not done that, the XML document would have been an invalid one and raised errors when opened in a browser. Each row of data to be plotted on the chart is represented by the <set> element. The label attribute defines the text label for each data point, and the value attribute defines its numerical value to be plotted. There are additional attributes that can be defined for the <set> element, for example, user-defined colors, which we will explore in later chapters. An important thing to note is how the $ prefix or comma separators have been stripped off the revenue numbers, before encoding them as a value for the <set> element, that is, $1,487,500 has been converted to 1487500, as shown in the following line of code: <set … value='1487500' /> This is necessary as FusionCharts can interpret only standard numeric values. While the standard attributes for the <chart> and <set> elements are common across chart types, many chart types have special features that are controlled by attributes that are specific for the chart. You can explore a list of all such attributes for each chart in the documentation of FusionCharts, under the section Chart XML API. With both the basic setup and data in place, we are just one step away from seeing our chart live—writing the HTML and JavaScript to embed this chart, which we will do next. Time for action – writing the HTML and JavaScript code to embed the chart Create an empty HTML file within the FirstChart folder named as FirstChart.html. Paste the following code in the file and save it: <html> <head> <title>My First chart using FusionCharts</title> <script type="text/javascript" src="../FusionCharts/FusionCharts.js"> </script> </head> <body> <div id="chartContainer">FusionCharts will load here!</div> <script type="text/javascript"> <!-- var myChart = new FusionCharts("../FusionCharts/ Column3D.swf", "myChartId", "400", "300", "0", "1" ); myChart.setXMLUrl("Data.xml"); myChart.render("chartContainer");//--> </script> </body> </html> Open it in a web browser. You should see your first chart coming to life, as shown in the following screenshot. Refresh the browser to experience the animation again, or hover over the columns to see tooltips. If you have access to an iPad or iPhone, open this example using the device. To do so, upload the entire LearningFusionCharts to a server that can be accessed over the Internet. Now point the browser in the device to http://Your_Website_URL/FirstChart/FirstChart.html. You will be able to see the same chart, but this time, rendered using JavaScript. The following screenshot shows a rendering of the chart within Safari in an iPhone. Tap on the columns to see the tool-tips. What just happened? You just created your first chart, that's what happened! This chart renders using Adobe Flash on devices that support it, and automatically switches to JavaScript rendering on devices such as iPads and iPhones. The beauty of the solution is that no additional code or configuration is required to do this. Let us break down our HTML and JavaScript code into digestible chunks. To create charts using FusionCharts in your page, you first need to include the FusionCharts JavaScript library (FusionCharts.js), as in the following lines of code: <script type="text/javascript" src="../FusionCharts/FusionCharts.js"> </script> Note that you only need to include FusionCharts.js in your code. The other files required for FusionCharts, namely FusionCharts.HC.js, FusionCharts.HC.Charts.js, and jquery.min.js are dynamically loaded by code in FusionCharts.js. Next, we create a DIV as a placeholder where the chart would be rendered. We give the DIV an ID—chartContainer. This is done using the following code: <div id="chartContainer">FusionCharts will load here!</div> The DIV carries a placeholder text FusionCharts will load here! which will be displayed if there is an error in your JavaScript code, or FusionCharts.js or the chart SWF file could not be loaded. If you see this text instead of the chart, you know what to fix. Following this, we initialize a chart by invoking the FusionCharts JavaScript constructor, using the following code: var myChart = new FusionCharts("../FusionCharts/Column3D.swf", "myChartId", "400", "300", "0", "1" ); To this constructor, we pass the following parameters in order: Path and filename of the chart SWF: The first parameter contains the path and filename of the chart SWF file. We have used the relative path to the SWF file, which is recommended. ID of the chart: Each chart on the page needs a unique ID. This ID is different from the ID of the container DIV. As we will learn later, this ID is used to get a reference of the chart for manipulation using advanced JavaScript. Width and height in pixels: Each chart needs to be initialized with width and height, specified either in pixels (specified in numeric format, without appending px) or percentage. In this example, we have used pixels. You can also set it to % values as in the following code: var myChart = new FusionCharts("../FusionCharts/Column3D.swf", "myChartId", "100%", "100%", "0", "1" ); The FusionCharts JavaScript class will automatically convert the % dimensions to pixel dimensions, with respect to the parent container element in HTML, DIV in this case, and pass it to the chart. Whether to start the chart in Debug mode: While developing your charts, if you face any issues, you can initialize them in debug mode by setting this parameter to 1. The Debug mode gives you behind-the-scenes information on where the data is loaded from, errors, and so on. In our example, we are rendering the chart in normal mode, by setting this parameter to 0. In previous versions of FusionCharts, you had to manually set the last parameter to 1, if you wanted FusionCharts to communicate with JavaScript. Now that FusionCharts is very well integrated with JavaScript, this parameter is a mandatory 1. Alternate compact constructor method A chart can also be initialized using the static render() method of the FusionCharts class, as shown below. <script type="text/javascript"> <!--var myChart = FusionCharts.render ("../FusionCharts/Column3D.swf", "myChartId", "400", "300", "chartContainer", "Data.xml"); // --> </script> There are additional possible syntaxes of this constructor and are detailed in FusionCharts Documentation | FusionCharts and JavaScript | Constructor methods. Once the chart is constructed, we tell the chart where to source data from. We use a relative path to Data.xml , as it is stored in the same folder. myChart.setXMLUrl("Data.xml"); If you recall, FusionCharts accepts data in two formats – XML and JSON – either provided as a string or a URL that points to the data file. In our example, we have used XML as the data format, which is stored in Data.xml. So, we use the setXMLURL() function to pass the URL of the XML data file to the chart. What if the XML data file was stored in another location or subdomain? If your data file was stored in a different folder, you would have to specify the relative path to the folder and then the filename, for example, ../ Source/Data/MyData.xml. We do not recommend specifying absolute URLs, because, if you move your web page or data file to another domain, cross-domain security issues would crop up and the chart would stop working. Flash Player's sandbox security model blocks loading of files across different sub-domains. If you need to load your XML data from another subdomain, you will have to create a Cross domain policy XML file, as explained at http://www.adobe.com/devnet/articles/crossdomain_ policy_file_spec.html. Finally, to render the chart in the DIV that you had earlier created, you invoke the render() function and pass to it the ID of the DIV. myChart.render("chartContainer"); Do remember that each chart and DIV needs to have its own unique ID. What to look for if your chart is not rendered? If you do not see any chart, there could be multiple reasons behind it. You should check for the following, based on what you see in your browser: What do you currently see instead of the chart? Corrective measures you should take ”FusionCharts will load here!” text that you had placed in the container DIV Check whether FusionCharts folder is present in LearningFusionCharts folder and contains all JavaScript files required for FusionCharts. Check whether you have provided the correct relative path to FusionCharts.js in the page FirstChart.html Check for errors in your JavaScript code that you have written to embed the chart. Use the browser's developer tools to check this. Ensure that you have given different IDs for container DIV, chart JavaScript variable and the chart object in the constructor. Empty white area instead of the chart Check whether you have copied Column3D.swf to FusionCharts folder. Check whether the relative path provided to Column3D.swf in FusionCharts constructor is correct. "Error in loading data" Check whether Data.xml is present within FirstChart folder Check whether the path specified to Data.xml is correct in setXMLUrl() method "Invalid data" Check for the validity of XML data in Data.xml by opening it in a browser or an XML editor. Or, you can also switch the debug mode of chart to ON by changing the last but one parameter in constructor to 1. That will highlight the error in XML, as shown in the following screenshot: With these measures, you should be able to locate the error and get your chart working. Before we move ahead to explore the other aspects of FusionCharts, let us understand how FusionCharts automatically switches between Flash and JavaScript mode. Converting the chart to a pure JavaScript chart By default, FusionCharts renders its charts using Adobe Flash. However, as you have seen earlier, when you view the chart on iPads or iPhones, FusionCharts automatically switches to JavaScript rendering, as Flash is not supported on those devices. This is internally checked by FusionCharts.js, and the auto-loaded files FusionCharts.HC.js, FusionCharts.HC.Charts.js, and jquery.min.js then aid in rendering the chart using JavaScript, using the same datasource and configuration. FusionCharts also provides an option to entirely skip Flash rendering and use JavaScript as the default rendering, irrespective of the device. This feature can be very nifty for developers who want to develop JavaScript-only applications or even frameworks. Let us quickly see how to attain that. Time for action – creating JavaScript only charts Create a copy of our FirstChart.html in the same location and name it as JavaScriptChart.html. Add the following lines of code before the constructor: <html> <body> <div id="chartContainer">FusionCharts will load here!</div> <script type="text/javascript"> <!--FusionCharts.setCurrentRenderer('javascript'); var myChart = new FusionCharts("../FusionCharts/ Column3D.swf", "myChartId", "400", "300", "0", "1" ); myChart.setXMLUrl("Data.xml"); myChart.render("chartContainer");// --> </script> </body> </html> Open the page in a browser. You should see the same chart as earlier, but this time rendered using JavaScript. It has animations and interactivity similar to the Flash version as shown in the following screenshot: How different is the Flash rendering from JavaScript rendering? The JavaScript version of FusionCharts behaves similar to the Flash version, offering most of the functional and cosmetic configuration. With the exception of a true 3D chart, all charts look and behave almost the same as their Flash counterpart. There are minor visual differences in the JavaScript version such as the width of columns, effect of shadows, handling of long x-axis labels, appearance of scroll bars, and so on. A detailed list of such differences are present in FusionCharts Documentation | Introduction | JavaScript Charting Capabilities | How different is JavaScript charts from Flash charts? What just happened? You just converted the previous chart to a pure JavaScript chart, irrespective of the device it is now viewed on. The following snippet of code instructs FusionCharts to switch the rendering mode to JavaScript: FusionCharts.setCurrentRenderer('javascript'); If your page contains multiple charts, this setting applies to all such charts that are defined after this line of code. Hence, if you declare this at the beginning, all the charts in the page will render using JavaScript. You would not need to declare the same for each chart in the page. JavaScript cannot access data stored on your hard drive in some browsers Some browsers restrict JavaScript from accessing the local filesystem due to security reasons. Hence, the JavaScript charts, when running from your local hard drive, would not be able to access XML or JSON data provided as a URL. However, when run from a server, including localhost, they will run fine. An alternate method to get JavaScript charts working locally is to use the Data String method, which we will explore in the next section. Have a go hero – build a dashboard for Harry In this example, you created a standalone Column 3D chart. How about inching towards building a complete dashboard? To do so, convert the existing chart to a Column 2D chart and add the following three charts to this page. In addition, specify different width and height for each chart to accommodate the amount of data it presents, and also place them in order of importance of the chart to Harry. A Line 2D chart, using Line.swf, comparing monthly revenues for this year. For this, you need to create an XML data with the <set> element for each month of the year. A Pie 2D chart , using Pie2D.swf, showing the composition of expenses of this year split under these categories: Salary, Cost of Goods, Marketing Costs, Overheads, and Administration. A Column 2D chart , using Column2D.swf, showing the top five salespersons for the year. All these charts use the same single-series XML format that you had earlier created. Remember to provide a different ID for each chart and its container DIV . Also, do not forget to encode special characters such as & (ampersand) or ' (apostrophe) in XML. Once you are done, let us explore the other way to provide XML data to FusionCharts—as a string, instead of providing a URL, for example, Data.xml. Using the Data String method to provide data As we had mentioned earlier, there are two ways to provide data to FusionCharts – either as a URL to the datasource (Data URL method), or as a string (Data String method). Till now, we have used the former method by invoking the setXMLUrl() method on the chart instance and providing Data.xml as the URL. In order to pass the XML as a string to the chart, we can use the setXMLData() method, as explained next. Time for action – embedding XML in the web page and using the Data String method Create a copy of our FirstChart.htmlDataStringMethod.html. Change the following lines in code: <html> <body> <div id="chartContainer">FusionCharts will load here!</div> <script type="text/javascript"> <!-- var myChart = new FusionCharts ("../FusionCharts/Column3D.swf", "myChartId", "400", "300", "0", "1" ); myChart.setXMLData("<chart caption='Harry&apos;s SuperMart' subcaption='Revenue by Year' xAxisName='Year' yAxisName='Amount' numberPrefix='$'> <set label='2009' value='1487500' /> <set label='2010' value='2100600' /> <set label='2011' value='2445400' /> </chart>"); myChart.render("chartContainer");// --> </script> </body> </html> Open the page in a browser. You should see the same chart as earlier, but this time using data embedded in the page, and not Data.xml. What just happened? You just used the Data String method of FusionCharts to power up your chart using XML data embedded in the page, instead of reading it from Data.xml. This was done by invoking the setXMLData() method on the chart instance. myChart.setXMLData("<chart caption='Harry&apos;s SuperMart' subcaption='Revenue by Year' xAxisName='Year' yAxisName='Amount' numberPrefix='$'> <set label='2009' value='1487500' /> <set label='2010' value='2100600' /> <set label='2011' value='2445400' /> </chart>"); The entire XML string is passed to this method. Note how we are using the characters in JavaScript to split the XML data string into multiple lines for enhanced readability. Make sure there are no trailing spaces, when using this approach. You can also define a JavaScript string variable, store XML data in it, and then assign the variable reference to the chart instance, as shown in the following code snippet: <html> <body> <div id="chartContainer">FusionCharts will load here!</div> <script type="text/javascript"><!-- var strData = "<chart caption='Harry&apos;s SuperMart' subcaption='Revenue by Year' xAxisName='Year' yAxisName='Amount' numberPrefix='$'>" + "<set label='2009' value='1487500' />" + "<set label='2010' value='2100600' />" + "<set label='2011' value='2445400' />" + "</chart>"; var myChart = new FusionCharts("../FusionCharts/Column3D.swf", "myChartId", "400", "300", "0", "1" ); myChart.setXMLData(strData); myChart.render("chartContainer");// --> </script> </body> </html> In the previous example, we had stored the entire XML string in the variable strData, and then passed its reference to the setXMLData() method, instead of the XML string directly. When using this method to provide data, if your chart is not working or reporting Invalid data, check for the following: Make sure that the quotation marks specified in JavaScript to provide parameters and in XML to provide attributes are different. Otherwise, it will result in a JavaScript syntax error. To keep things easy to remember, use double quotation marks for JavaScript, and single quotation marks for XML attributes. Ensure that special characters such as ', ", &, <, and > present as XML attribute values are encoded to ', ", &, <, and > respectively.
Read more
  • 0
  • 0
  • 4647

article-image-microsoft-silverlight-5-working-services
Packt
23 Apr 2012
11 min read
Save for later

Microsoft Silverlight 5: Working with Services

Packt
23 Apr 2012
11 min read
(For more resources on silverlight, see here.) Introduction Looking at the namespaces and classes in the Silverlight assemblies, it's easy to see that there are no ADO.NET-related classes available in Silverlight. Silverlight does not contain a DataReader, a DataSet, or any option to connect to a database directly. Thus, it's not possible to simply define a connection string for a database and let Silverlight applications connect with that database directly. The solution adds a layer on top of the database in the form of services. The services that talk directly to a database (or, more preferably, to a business and data access layer) can expose the data so that Silverlight can work with it. However, the data that is exposed in this way does not always have to come from a database. It can come from a third-party service, by reading a file, or be the result of an intensive calculation executed on the server. Silverlight has a wide range of options to connect with services. This is important as it's the main way of getting data into our applications. In this article, we'll look at the concepts of connecting with several types of services and external data. We'll start our journey by looking at how Silverlight connects and works with a regular service. We'll see the concepts that we use here recur for other types of service communications as well. One of these concepts is cross-domain service access. In other words, this means accessing a service on a domain that is different from the one where the Silverlight application is hosted. We'll see why Microsoft has implemented cross-domain restrictions in Silverlight and what we need to do to access externally hosted services. Next, we'll talk about working with the Windows Azure Platform. More specifically, we'll talk about how we can get our Silverlight application to get data from a SQL Azure database, how to communicate with a service in the cloud, and even how to host the Silverlight application in the cloud, using a hosted service or serving it from Azure Storage. Finally, we'll finish this chapter by looking at socket communication. This type of communication is rare and chances are that you'll never have to use it. However, if your application needs the fastest possible access to data, sockets may provide the answer. Connecting and reading from a standardized service Applies to Silverlight 3, 4 and 5 If we need data inside a Silverlight application, chances are that this data resides in a database or another data store on the server. Silverlight is a client-side technology, so when we need to connect to data sources, we need to rely on services. Silverlight has a broad spectrum of services to which it can connect. In this recipe, we'll look at the concepts of connecting with services, which are usually very similar for all types of services Silverlight can connect with. We'll start by creating an ASMX webservice—in other words, a regular web service. We'll then connect to this service from the Silverlight application and invoke and read its response after connecting to it. Getting ready In this recipe, we'll build the application from scratch. However, the completed code for this recipe can be found in the Chapter07/SilverlightJackpot_Read_Completed folder in the code bundle that is available on the Packt website. How to do it... We'll start to explore the usage of services with Silverlight using the following scenario. Imagine we are building a small game application in which a unique code belonging to a user needs to be checked to find out whether or not it is a winning code for some online lottery. The collection of winning codes is present on the server, perhaps in a database or an XML file. We'll create and invoke a service that will allow us to validate the user's code with the collection on the server. The following are the steps we need to follow: We'll build this application from scratch. Our first step is creating a new Silverlight application called SilverlightJackpot. As always, let Visual Studio create a hosting website for the Silverlight client by selecting the Host the Silverlight application in a new Web site checkbox in the New Silverlight Application dialog box. This will ensure that we have a website created for us, in which we can create the service as well. We need to start by creating a service. For the sake of simplicity, we'll create a basic ASMX web service. To do so, right-click on the project node in the SilverlightJackpot. Web project and select Add | New Item... in the menu. In the Add New Item dialog, select the Web Service item. We'll call the new service as JackpotService. Visual Studio creates an ASMX file (JackpotService.asmx) and a code-behind file (JackpotService.asmx.cs). To keep things simple, we'll mock the data retrieval by hardcoding the winning numbers. We'll do so by creating a new class called CodesRepository.cs in the web project. This class returns a list of winning codes. In real-world scenarios, this code would go out to a database and get the list of winning codes from there. The code in this class is very easy. The following is the code for this class: public class CodesRepository{ private List<string> winningCodes; public CodesRepository() { FillWinningCodes(); } private void FillWinningCodes() { if (winningCodes == null) { winningCodes = new List<string>(); winningCodes.Add("12345abc"); winningCodes.Add("azertyse"); winningCodes.Add("abcdefgh"); winningCodes.Add("helloall"); winningCodes.Add("ohnice11"); winningCodes.Add("yesigot1"); winningCodes.Add("superwin"); } } public List<string> WinningCodes { get { return winningCodes; } }} At this point, we need only one method in our JackpotService. This method should accept the code sent from the Silverlight application, check it with the list of winning codes, and return whether or not the user is lucky to have a winning code. Only the methods that are marked with the WebMethod attribute are made available over the service. The following is the code for our service: [WebService(Namespace = "http://tempuri.org/")][WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)][System.ComponentModel.ToolboxItem(false)]public class JackpotService : System.Web.Services.WebService{ List<string> winningCodes; public JackpotService() { winningCodes = new CodesRepository().WinningCodes; } [WebMethod] public bool IsWinningCode(string code) { if(winningCodes.Contains(code)) return true; return false; }} Build the solution at this point to ensure that our service will compile and can be connected from the client side. Now that the service is ready and waiting to be invoked, let's focus on the Silverlight application. To make the service known to our application, we need to add a reference to it. This is done by right-clicking on the SilverlightJackpot project node, and selecting the Add Service Reference... item. In the dialog that appears, we have the option to enter the address of the service ourselves. However, we can click on the Discover button as the service lives in the same solution as the Silverlight application. Visual Studio will search the solution for the available services. If there are no errors, our freshly created service should show up in the list. Select it and rename the Namespace: as JackpotService, as shown in the following screenshot. Visual Studio will now create a proxy class: The UI for the application is kept quite simple. An image of the UI can be seen a little further ahead. It contains a TextBox, where the user can enter a code, a Button that will invoke a check, and a TextBlock that will display the result. This can be seen in the following code: <StackPanel> <TextBox x_Name="CodeTextBox" Width="100" Height="20"> </TextBox> <Button x_Name="CheckForWinButton" Content="Check if I'm a winner!" Click="CheckForWinButton_Click"> </Button> <TextBlock x_Name="ResultTextBlock"> </TextBlock></StackPanel> In the Click event handler, we'll create an instance of the proxy class that was created by Visual Studio as shown in the following code: private void CheckForWinButton_Click(object sender, RoutedEventArgs e){ JackpotService.JackpotServiceSoapClient client = new SilverlightJackpot.JackpotService.JackpotServiceSoapClient();} All service communications in Silverlight happen asynchronously. Therefore, we need to provide a callback method that will be invoked when the service returns: client.IsWinningCodeCompleted += new EventHandler <SilverlightJackpot.JackpotService. IsWinningCodeCompletedEventArgs> (client_IsWinningCodeCompleted); To actually invoke the service, we need to call the IsWinningCodeAsync method as shown in the following line of code. This method will make the actual call to the service. We pass in the value that the user entered: client.IsWinningCodeAsync(CodeTextBox.Text); Finally, in the callback method, we can work with the result of the service via the Result property of the IsWinningCodeCompletedEventArgs instance. Based on the value, we display another message as shown in the following code: void client_IsWinningCodeCompleted(object sender, SilverlightJackpot.JackpotService. IsWinningCodeCompletedEventArgs e){ bool result = e.Result; if (result) ResultTextBlock.Text = "You are a winner! Enter your data below and we will contact you!"; else ResultTextBlock.Text = "You lose... Better luck next time!";} We now have a fully working Silverlight application that uses a service for its data needs. The following screenshot shows the result from entering a valid code: How it works... As it stands, the current version of Silverlight does not have support for using a local database. Silverlight thus needs to rely on external services for getting external data. Even if we had local database support, we would still need to use services in many scenarios. The sample used in this recipe is a good example of data that would need to reside in a secure location (meaning on the server). In any case, we should never store the winning codes in a local database that would be downloaded to the client side. Silverlight has the necessary plumbing on board to connect with the most common types of services. Services such as ASMX, WCF, REST, RSS, and so on, don't pose a problem for Silverlight. While the implementation of connecting with different types of services differs, the concepts are similar. In this recipe, we used a plain old web service. Only the methods that are attributed with the WebMethodAttribute are made available over the service. This means that even if we create a public method on the service, it won't be available to clients if it's not marked as a WebMethod. In this case, we only create a single method called IsWinningCode, which retrieves a list of winning codes from a class called CodesRepository. In real-world applications, this data could be read from a database or an XML file. Thus, this service is the entry point to the data. For Silverlight to work with the service, we need to add a reference to it. When doing so, Visual Studio will create a proxy class. Visual Studio can do this for us because the service exposes a Web Service Description Language (WSDL) file. This file contains an overview of the methods supported by the service. A proxy can be considered a copy of the server-side service class, but without the implementations. Instead, each copied method contains a call to the actual service method. The proxy creation process carried out by Visual Studio is the same as adding a service reference in a regular .NET application. However, invoking the service is somewhat different. All communication with services in Silverlight is carried out asynchronously. If this wasn't the case, Silverlight would have had to wait for the service to return its result. In the meantime, the UI thread would be blocked and no interaction with the rest of the application would be possible. To support the asynchronous service call inside the proxy, the IsWinningCodeAsync method as well as the IsWinningCodeCompleted event is generated. The IsWinningCodeAsync method is used to make the actual call to the service. To get access to the results of a service call, we need to define a callback method. This is where the IsWinningCodeCompleted event comes in. Using this event, we define which method should be called when the service returns (in our case, the client_IsWinningCodeCompleted method). Inside this method, we have access to the results through the Result parameter, which is always of the same type as the return type of the service method. See also Apart from reading data, we also have to persist data. In the next recipe, Persisting data using a standardized service, we'll do exactly that.
Read more
  • 0
  • 0
  • 2549

article-image-2d-game-development-monkey
Packt
20 Apr 2012
9 min read
Save for later

2D game development with Monkey

Packt
20 Apr 2012
9 min read
Call the Monk and start praying—the Monkey IDE We are just kidding here; there are no religious activities planned in this article. Even though sometimes you will find yourself praying that a new piece of code you have created works like it should.If you haven't installed Monkey already, then it is time to do that now.The software can be downloaded from the site http://www.monkeycoder.co.nz/. Some prebuilt scripts are available as the support code files for the book Monkey Game Development Beginner's Guide. Why learn about Monk? Monk is the code editor/IDE that ships with Monkey. It is the first place that you will fire up when you start using Monkey. So, it is important to know your first main tool, if you want to develop games with Monkey. Starting up Monk It's time now to start Monk. You will do this by double-clicking on the Monk.app icon on OSX or start Monk.exe in Windows. Monk's user interface Monk's user interface is divided into three sections: The toolbar The code editor area The info box The toolbar All functions of Monk can be called through keyboard shortcuts and through the main menu. Some functions are also reachable through the toolbar. The code editor area The code editor in Monk supports syntax highlighting and automatic casing of the basic commands in the Monkey programming language. Sadly, it doesn't highlight and auto-case the commands from the modules, which is something that could help tremendously. But, the usual suspects are all there—copy, cut, paste, search and replace, Block in and out denting, goto line, and Find in Files will get you a long way before you ask for more The info box The info box is your navigation system, when it comes to Monkey coding. You can open your code files, and also the files included with Monkey, from the Nav tree view: In the bananas section of the Nav tree view, you will find all the sample scripts that ship with Monkey. Shortly, we will go there and start a sample script from there. The next tab header is the Code tree view. It contains all function and method headers of the included classes in the currently visible code file The last Debug tab is a relic from Monk's origins, being the native editor for BlitzMax. There, it has a built-in debugger, something that Monkey lacks at the moment. So, please just ignore that tab. Ok, now let's do something. How about opening one of the sample scripts? Time for action – opening a sample script Opening an existing script can be done through several methods. One is through the toolbar. Follow the given steps: Click on the Open icon in the toolbar: Next, you will see a file dialog where you can select a .Monkey file to be opened. Navigate, within the dialog, into the bananas folder of Monkey's main directory. There, you have subfolders from some authors of sample scripts. Head to the mak folder, and from within that, to the firepaint folder. Inside, you will find the firepaint.Monkey file. Select it and click on the Open button in the File dialog. Voila! Monk just opened the selected script: Of course, there are other ways to open a script. For example, you can double-click on a filename inside the Nav tree view What just happened? You have opened your first Monkey script. Good job! Please note how the GUI has changed. In the top of Monk, you see the file path of your currently visible script. Also, for each script you open or create, Monk creates a new tab inside the code area. In our example, this tab is named firepaint.Monkey. If you have several scripts open at once, you can switch between them by clicking on the tab header or press Ctrl + the left/right key on Windows or cmd + the left/right key on OSX. Where is my navi? Games are not usually coded with just 10-20 lines. We talk here about at least a few hundred lines of code. And to help you navigate through your code more easily, Monk supports the Code tab in the info box on the right. To practice navigation in a script file a little, here is the next task. Time for action - navigating to the main() function Every Monkey game needs a Main() function. To find it, select the Code tab in the info box. There you find two parent nodes. Try to find Main() in one of them. Found it? Good. Click on it. You will see that the code area changed and the cursor jumped to the top line of the definition of the Main() function: What just happened? Navigating through a script is very easy. Search for the item you want to jump to inside the Code tab of the info box and click on it. The content of the code tab always reflects the changes inside the code area! Save... save... save! One of the first and most important rules of software development is save your code, save it a lot. Remember this and live by it. There is nothing worse than a hard drive failure or a power outage after an hour of coding. Time for action - saving a script To save a script, here are some things you have to do Open an empty script by pressing Ctrl + N in Windows or cmd + N on OSX. Monkey will open a fresh and empty code area for you. Next, type anything inside it, just anything. Now, save your script. For this, you should use your mouse and the menu. Click on File | Save as. A dialog opens where you can set the filename and location to save your script to. Do this and click on Save. What just happened? You have saved your first script. Most likely, it isn't even close to a run-worthy script, but you have learned how to save your creation. Did you notice how the caption of the tab for the code area changed? And also the title bar of Monk's window? They now reflect the name you gave your script when you saved it. Projects—bringing in some organization When you look at the Nav tab of the info box, it's nice that you can browse through the folders of Monkey and open scripts from there. Good news is near; you can do this with your own code too. That is why Monk supports projects. They become new entries under the initial tree view inside the Nav tab. Time for action - creating a project Let's assume that we want to turn the FirePaint example into a project. For this, you have to create a new project first. Follow the ensuing steps: Click on File | Project Manager, in the menu. A new dialog will open: There, you will first see the Monkey project. To create a new one, click on Add Project. In the following dialog, you need to give your project a name. For now, My firepaint project should be fine. Also select the folder where the previous sample script was loaded from. After you do this, the top of the dialog should look a little like this: The bottom of the dialog with fields including sub-version controls is not functional and is probably a relic from Monk's origins of being the BlitzMAX IDE. Now, click on OK to create your project. What just happened? In the first dialog, there is now a new line with the project title. If you select this line, you could either change the properties of your project or remove it completely. You can close this dialog for now. Another thing you will notice is that, in the info box on the Nav tab, there is now a new project entry with the name you have given before. Browse through this entry and open the scripts from there by double-clicking on the script name. Convenient, isn't it? Yes, it is. And the cool thing is that this now stays there, even if you close Monk. At the next start of Monk, your new project entry is still there. The Monkey programming language To create games with Monkey, you should know a little bit about its programming language and its features. We won't cover the whole manual here, but will go through some of the most important parts of it. But first, you should write your first script. Without any practice, you say? Right, just like that! Time for action - Monkey's Hello World Here is a version of the famous Hello World script, done in Monkey. You have to start somewhere. You will learn what the starting point of every Monkey app looks like, the Main() function, and how to print some text to the browser. Ok, let's go! Start with a single line comment that describes the app: 'Monkeys Hello World Next is the function header for the Main() function, the piece of code that will be called at the start of the app. Every function starts with the keyword Function, then its name, followed by opening and closing parentheses: Function Main() Now, it's time to print the famous text Hello World. For this, Monkey provides the Print command. And don't forget to indent the code through the menu or just by pressing the Tab key once: Print ("Hello World") Every function needs to be closed. In Monkey, we do this with the End command: End Now, save your script. The name and folder are not important. Build and run the script by clicking on the tilted rocket in the toolbar. What just happened? Drum roll please.... tadaaaa! You have coded your first Monkey script and just ran it inside the browser. If everything is correct, you will have seen a plain (white) background and then the text Hello World printed on it. Running your first script in a browser To start this script, press Ctrl + R for Windows or cmd + R for OSX, to build and run the script. For this, select HTML5 as the target platform. You should see something like this: Cool, isn't it? And you did this all yourself.
Read more
  • 0
  • 0
  • 5302
article-image-social-media-wordpress-vip-memberships
Packt
19 Apr 2012
8 min read
Save for later

Social Media for Wordpress: VIP Memberships

Packt
19 Apr 2012
8 min read
(For more resources on WordPress, see here.) Three important facets of membership sites Although you can dissect a successful membership-based site into pieces, there are three vital elements. What do I get out of registering for this site? Why should I register now? How will this site impact me two weeks from now? These are all simple and fair enough questions. Let's get down to the nitty-gritty. Customer value proposition Creating membership-based sites is tricky, because there is a natural expectation that a visitor or customer will receive something of value by registering for a site. If there is a low incentive for registering for your site, don't expect too many signups. The opposite is true, as well. A site that offers a full album in exchange for site registration will fare better than a site that only offers one song from the same album. Customer Value Proposition (CVP) is not rocket science, but it's a concept that you need to grasp to grow your site. What you perceive as great value might not necessarily be in line with what your prospective members expect. CVP also doesn't dictate that you need to put a price tag on the value that you're proposing; it merely suggests that what you are proposing will be useful and relevant to your site visitors. If you are unsure whether you are proposing something valuable on your site, in exchange for the time and effort it takes to complete a site registration, ask a neighbour, co- worker, or other acquaintance some of these questions: What aspect of this site would make you register for it? If you wouldn't register for it, why not? Would you recommend this site to your friends or family? How can the membership be more compelling? Would you ever consider paying a fee to keep your membership? Regardless of what people say, you have to be open to constructive criticism. Throwing all feedback by the wayside typically means that you are not prepared to embark on what you are doing. Last, be honest with yourself and try not to ask your parents, best friend, or spouse for this type of critical feedback, unless you're certain they won't be shy in trying to poke holes at your ideas. The more uncensored, truthful opinions you can collect, the more your site and membership will be polished. Timing Roman philosopher Lucius Annaeus Seneca is often quoted as saying, Luck is what happens when preparation meets opportunity. While you don't have to be lucky to offer memberships, you do have to be strategic in how you open up site registrations. For example, you wouldn't suddenly offer a VIP membership in the form of a paywall, if there weren't any significant differences in your own freely available content or that of a competitor. You would, however, open limited VIP membership registrations on December 12, 2012 that offered premium content such as videos, downloads, and other goodies. In this example, the advantages are two-fold: First, you would spark a sense of urgency and exclusivity by using the terms limited registrations. Second, the registration date would allow you to market the VIP membership during the holiday season, when people are already on a spending spree. Plus, you would be able to make it easier for prospective VIP members to memorize this registration date by advertising it as a 12.12.12 event. Again, it's not rocket science per se, but you do have to take the opportunity and be prepared with a plan of action. You only get one first impression when you pitch your membership to your visitors, so try to schedule the registration period during a time when there is a significant change on your site—a site launch, re-design, newly added section, partnership, or any other big announcement. This way, it appears more like a bonus feature than a gateway to profile your users. If you plan on keeping membership registrations open indefinitely, be sure to keep the content fresh on the page that outlines the benefits of registering for your site. Some sites update rotating testimonials whereas others may feature recently registered users to prevent the membership opportunity from looking stale. Holidays and other celebratory days are extremely helpful when it comes to timing, as they allow you to spotlight your membership section. If you charge for a premium membership, for example, you can always promote discounted specials through Facebook, Twitter, or any other social media networking site. Pairing Earth Day with news that your sites are running on energy efficient servers, for instance, would allow you to advertise something like Our community is all about green energy. You could even build a whole green campaign around membership signups, utilizing videos (http://www.youtube.com) and photo galleries (http://www.flickr.com) to paint a more telling story. Sustainability We've figured out a way to entice your prospective customers to register with our site, but what now? When it comes to site memberships, sustainability is a blanket term that incorporates long-term growth coupled with loyalty marketing—the practice in which you retain your customers, or site members, by focusing and delivering customer satisfaction, which, in turn, leads to an increased ROI. We come full-circle, now that we're honing in on building site memberships. Sustainability, at this juncture, means repetition. It means that we cannot rely on a one-off piece of content, an interesting blog post, a great album, or an amazing product to engage our members. It means that we cannot procrastinate on our content, if we want people to actively talk about it. The web works at warp speed, so it's imperative that we churn out good content on a regular basis. It can be absolutely time-consuming. But that's also why we've learned how to automate a lot processes to dedicate more resources to content. Good content will always remain at the forefront of sustaining your user retention. Time for action – how to open limited membership registrations and reward users For this activity, we will start off by using WordPress' official Twenty Eleven theme and four plugins—HeadSpace2 SEO, WP Show IDs, S2 Member, and Cube Points: Part 1—setting up member-accessible content In this part, we will configure the S2 Member plugin to block content for site visitors that have not registered with the site yet: In your dashboard, navigate to Add New under Plugins and search for S2 Member. Install and activate the plugin. Next, add a new plugin called WP Show IDs by repeating the directions in Step 1. This plugin simply displays the ID associated with each post, page, and category. Now we'll create the login welcome page, which is the page a member will see upon logging in, by navigating to Add New under Pages. Title it Login Welcome Page. Since this is the first page that members will see each time, take the opportunity to let them connect with you on Facebook, Twitter, LinkedIn, or any of your other social media networking accounts, by mentioning this in your content field. See the following screenshot for an example: Create a new page but, this time, give it a title of Membership Options Page. This will be the page non-members, or the general public, will be redirected to when they attempt to access any content that's restricted to members. It can also double as a payment gateway page, if you choose to sell subscriptions to access content. Again, be sure to highlight your other social media network accounts by mentioning this in your content field like in the previous step. Navigate to Categories under Posts and create a new category called VIP. We'll use this to restrict access to posts filed under this category. Be sure to jot down the ID of this category when you create it, as you'll need it later. The ID is located in the last column to the right of the category list. Configure S2 Member to recognize the VIP category as a restricted category, only accessible to registered members, by navigating to Restriction Options under S2 Member. Click the Category Access Restrictions section and type in 3, the ID you obtained by the previous step, under the Categories That Require Level #0 Or Higher: field. Be sure to press the Save All Changes button at the bottom to save your changes. Since S2 Member isn't set up yet to use the two pages that you've created in Steps 3 and 4, we'll now configure this by navigating to General Options under S2 Member. Under the Login Welcome Page section, select the page that you created in Step 3 from the drop-down selection. Under the Members Options Page, select the page that you had created in Step 4 from the drop-down selection. Be sure to press the Save All Changes button to save your changes. As an optional step, you can test your VIP membership by creating a new post and categorizing it under VIP. View the page to simulate the logged in state. Then, log out and try to access that post again. If you're redirected to your Members Options Page, it's properly configured. Everything still remains customizable, so if you change your page titles, post contents, category labels, or slugs, just be sure to update your settings accordingly under the General Options and Restriction Options sections in S2 Member.
Read more
  • 0
  • 0
  • 1879

article-image-gradebook-introduction
Packt
13 Apr 2012
5 min read
Save for later

Gradebook-An Introduction

Packt
13 Apr 2012
5 min read
  Getting to the gradebook All courses in Moodle have a grades area, also known as the gradebook . A number of activities within Moodle can be graded and these grades will automatically be captured and shown in the gradebook. To get to the gradebook, view the Settings block on the course and then click on Grades. The following screenshot shows an example of the teachers' view of a simple gradebook with a number of different graded activities within it. Let's take a quick tour of what we can see! The top row of the screenshot shows the column headings which are each of the assessed activities within the Moodle course. These automatically appear in the grades area. In this case, the assessed activities are: Initial assessment U1: Task 1 U1: Task 1 U1: Task 2 U2: Test Evidence On the left of the screenshot, you can see the students' names. Essentially, the name is the start of a row of information about the student. If we start with Emilie H, we can see that she received a score of 100.00 for her Initial assessment. Looking at Bayley W, we can see that his work for U1: Task 2 received a Distinction grade. Using the gradebook, we can see all the assessments and grades linked to each student from one screen. Users with teacher, non-editing teacher, or manager roles will be able to see the grades for all students on the course. Students will only be able to see their own grades and feedback. The advantage of storing the grades within Moodle is that information can be easily shared between all teachers on the online course. Traditionally, if a course manager wanted to know how students were progressing they would need to contact the course teacher(s) to gather this information. Now, they can log in to Moodle and view the live data (as long as they have teacher or manager rights to the course). There are also benefits to students as they will see all their progress in one place and can start to manage their own learning by reviewing their progress to date as shown in the following example student view: This is Bayley W's grade report. Bayley can see each assessment on the left-hand side with his grade next to it. By default, the student grades report also shows the range of grades possible for the assessment (for example, the highest and lowest scores possible), but this can be switched off by the teacher in the Grades course settings. It also shows the equivalent percentage as well as the written feedback given by the teacher. Activities that work with the gradebook There are a number of Moodle activities that can be graded and, therefore, work with the gradebook. The main ones are the following: Quiz Assignments: Four different core assignment types can be used to meet a range of needs within courses: Advanced uploading of files Online text Upload a single file Offline activity (The offline assignment is particularly useful for practical qualifications or presentations where the assessment is not submitted and is assessed offline by the teacher. The offline activity allows the detail of the assessment to be provided to students in Moodle, and the grade and feedback to be stored in the gradebook, even though no work has been electronically submitted.) Encouraging the use of the gradebook The offline activity is often a good way to start using the gradebook to record progress, as the assessment can take place in the normal way, but the grades can be recorded centrally to benefit teachers and students. Once confident with using the gradebook, teachers can then review assessment processes to use other assignment types   Forum Lesson SCORM package Workshop Glossary It is also possible to manually set up a "graded item" within the gradebook that is not linked with an activity, but allows a grade to be recorded. Key features of the gradebook The gradebook primarily shows the grade or score for each graded activity within the online course. This grade could be shown in a number of ways: Numeric grade: A numerical grade between 1 and 100. This is already set up and ready to use within all Moodle courses. Scale: A customized grading profile that can be letters, words, statements, or numbers (such as Pass , Merit, and Distinction). Letter grade: A grading profile that can be linked to percentages (such as 100 percent = A) Organizing grades With lots of activities that use grades within a course, the gradebook can be a lot of data on one page. Categories can be created for group activities and the gradebook view can be customized according to the user to see all or some categories on the screen. Think about a course that has 15 units and each unit has three assessments within it. The gradebook will have 45 columns of grades – which is a lot of data! We can organize this information into categories to make it easier to use.
Read more
  • 0
  • 0
  • 2010
Modal Close icon
Modal Close icon