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

How-To Tutorials - Front-End Web Development

341 Articles
article-image-creating-image-gallery
Packt
30 Oct 2013
5 min read
Save for later

Creating an image gallery

Packt
30 Oct 2013
5 min read
(For more resources related to this topic, see here.) Getting ready Before we get started, we need to find a handful of images that we can use for the gallery. Find four to five images to use for the gallery and put them in the images folder. How to do it... Add the following links to the images to the index.html file: <a class="fancybox"href="images/waterfall.png">Waterfall</a><a class="fancybox" href="images/frozenlake.png">Frozen Lake</a><a class="fancybox" href="images/road-inforest.png">Road in Forest</a><a class="fancybox" href="images/boston.png">Boston</a> The anchor tags no longer have an ID, but a class. It is important that they all have the same class so that Fancybox knows about them. Change our call to the Fancybox plugin in the scripts.js file to use the class that all of the links have instead of show-fancybox ID. $(function() { // Using fancybox class instead of the show-fancybox ID $('.fancybox').fancybox(); }); Fancybox will now work on all of the images but they will not be part of the same gallery. To make images part of a gallery, we use the rel attribute of the anchor tags. Add rel="gallery" to all of the anchor tags, shown as follows: <a class="fancybox" rel="gallery" href="images/waterfall.png">Waterfall</a> <a class="fancybox" rel="gallery" href="images/frozenlake.png">Frozen Lake</a> <a class="fancybox" rel="gallery" href="images/roadin-forest.png">Road in Forest</a> <a class="fancybox" rel="gallery" href="images/boston.png">Boston</a> Now that we have added rel="gallery" to each of our anchor tags, you should see left and right arrows when you hover over the left-hand side or right-hand side of Fancybox. These arrows allow you to navigate between images as shown in the following screenshot: How it works... Fancybox determines that an image is part of a gallery using the rel attribute of the anchor tags. The order of the images is based on the order of the anchor tags on the page. This is important so that the slideshow order is exactly the same as a gallery of thumbnails without any additional work on our end. We changed the ID of our single image to a class for the gallery because we wanted to call Fancybox on all of the links instead of just one. If we wanted to add more image links to the page, it would just be a matter of adding more anchor tags with the proper href values and the same class. There's more... So, what else can we do with the gallery functionality of Fancybox? Let's take a look at some of the other things that we could do with the gallery that we have currently. Captions and thumbnails All of the functionalities that we discussed for single images apply to galleries as well. So, if we wanted to add a thumbnail, it would just be a matter of adding an img tag inside the anchor tag instead of the text. If we wanted to add a caption, we can do so by adding the title attribute to our anchor tags. Showing slideshow from one link Let's say that we wanted to have just one link to open our gallery slideshow. This can be easily achieved by hiding the other links via CSS with the help of the following step: We start by adding this style tag to the <head> tag just under the <script> tag for our scripts.js file, shown as follows: <style type="text/css"> .hidden { display: none; } </style> Now, we update the HTML file so that all but one of our anchor tags have the hidden class. Next, when we reload the page, we will see only one link. When you click on the link, you should still be able to navigate through the gallery just like all of the links were on the page. <a class="fancybox" rel="gallery" href="images/waterfall.png">Image Gallery</a> <div class="hidden"> <a class="fancybox" rel="gallery" href="images/frozen-lake.png">Frozen Lake</a> <a class="fancybox" rel="gallery" href="images/roadin-forest.png">Road in Forest</a> <a class="fancybox" rel="gallery" href="images/boston.png">Boston</a> </div> Summary In this article we saw that Fancybox provides very strong image handling functionalities. We also saw how an image gallery is created by Fancybox. We can also display images as thumbnails and display the images as a slideshow using just one link. Resources for Article: Further resources on this subject: Getting started with your first jQuery plugin [Article] OpenCart Themes: Styling Effects of jQuery Plugins [Article] The Basics of WordPress and jQuery Plugin [Article]
Read more
  • 0
  • 0
  • 2143

article-image-working-events-mootools-part-1
Packt
07 Jan 2010
9 min read
Save for later

Working with Events in MooTools: Part 1

Packt
07 Jan 2010
9 min read
We have a lot of things to cover in this article, so hold on to your seats and enjoy the ride! What are Events, Exactly? Events are simply things that happen in our web pages. MooTools supports all HTML 4.01 event attributes like onclick and onmouseout, but the framework refers to them without the "on"  prefix (click instead of onclick, mouseout instead of onmouseout). What's neat about MooTools is that it not only extends HTML 4.01 event attributes with a few of its own, but also ensures that methods and functions that deal with web page events work across all web browsers by providing us with a solid, built-in object called Events. Event is part of the Native component of MooTools, and is also referred to as the Event hash. You can read the official W3C specifications on events, in the HTML 4.01 Specification, section 18.2.3, under Intrinsic Events:http://www.w3.org/TR/html401/interact/scripts.html#h-18.2.3 We'll go over all of the available event attributes in MooTools so you can learn what stuff we can listen to. There are several events that we can detect or "listen to". We can, for the sake of discussion, divide them into five groups: window events, form events, keyboard events, mouse events, and MooTools custom events. Window Events Window events refer to activities that occur in the background. There are only two window events. HTML Event attribute / MooTools event name What is it? onload / load This event occurs when the window and images on the page has fully loaded and/or when all of the iFrames in the page have loaded. It can be used for monitoring when the web page has fully loaded (such as when you want to know if all images have been downloaded). onunload / unload This even happens when a window or an iFrame is removed from the web page. It has limited use. Form events There are events that occur within Form elements (such as <input> elements), and we'll refer to these as form events. For example, the onfocus  event is triggered when the user clicks on an input field (you'll see this in action in this article), effectively focusing on that particular input field. Some of these events apply event to non-form elements. HTML Event attribute / MooTools event name What is it? onblur / blur This event occurs when an element loses focus, either because the user has clicked out of it, or because the user used the Tab key to move away from it. This is helpful for monitoring the instant the user loses focus on a particular element. onchange / change This event happens when the element loses focus or when its original value has changed. This is helpful for knowing when the user starts typing in a input text field or textarea, or when a user selects a different option in a select drop-down element. onfocus / focus This event is the opposite, of the blur event: it is triggered when the user focuses on an element. This is useful for watching when the user highlights a form field or when they have navigated to it using the Tab key. onreset / reset This event only applies to form elements. This event is triggered when the form has been reset to its default values. onselect / select This event happens when the user highlights (selects) text in a text field. onsubmit / submit This event is only for form elements. This event occurs when the user submits a web form. Keyboard events There are events that happen when a user presses on a keyboard input device; let's call these keyboard events. For example, the onkeypress event is triggered when you press any key on your keyboard. HTML Event attribute / MooTools event name What is it? onkeydown / keydown This event occurs when the user holds down a keyboard key. onkeypress / keypress This event is triggered whenever the user presses a keyboard key. onkeyup /keyup This event happens when the user releases a key. Mouse events There are several HTML event properties that allow you to deal with activities related to the mouse. Clicking, moving, double-clicking, and hovering are all mouse events. HTML Event attribute / MooTools event name What is it? onclick / click This event occurs whenever the user uses the mouse button to click on an element. ondblclick / dblclick This even occurs whenever the user double-clicks on an element. onmousedown / mousedown This event occurs when the mouse button is held down. onmouseup / mouseup This even occurs when the mouse button is released. onmousemove / mousemove This event occurs when the mouse is moved. onmouseout / mouseout This event occurs when the mouse pointer is removed from the target element. onmouseover / mouseover This event occurs when the mouse pointer enters the target element. MooTools Custom Mouse Events MooTools supplies us with three custom events that extend the standard mouse events. MooTools event name What is it? mouseenter This event is triggered when the user's mouse pointer enters an element, but does not fire again when the mouse goes over a children element (unlike mouseover). This is useful for detecting the mouseover event once in nested element structures, such as <li><a>item</a></li>. If we were to use the mouseover event, it would be triggered twice, once for <li> and once again for <a>. mouseleave This event works similarly to mouseenter in that it is triggered only once when the mouse pointer exits the target element. Unlike the mouseout event, which will be triggered more than once for nested element structures. mousewheel This even is triggered when the scroller on a mouse is used (available in most modern mice input devices, usually situated in between the left and right mouse buttons). Adding Event Listeners We can attach event listeners to elements on a web page using the addEvent and addEvents method. By doing so, we're able to find out whenever that event happens, as well as execute a function to react to them. Adding event listeners is the basis for interactivity and is where JavaScript (and subsequently) MooTools has gained its popularity. Imagine being able to perform an operation whenever a user hovers over an image, or clicks on a link, or whenever the user submits a form -- the possibilities are endless. Adding a single event listener The addEvent method allows you to add one event listener to an element method and follows the format: $(yourelement).addEvent(event, function(){}) For example, in the following code block, we attach a click event listener for all <a> elements. When the user clicks on any hyperlink on our web page, it runs a function that opens up an alert dialog box that says You clicked on a hyperlink. $$('a').addEvent('click', function(){ alert('You clicked on a hyperlink');}); In a moment, we'll create a simple web form the highlights the input field that the user is focused on. Time for action – Highlighting focused fields of web forms Let's start with our web form's HTML. We'll use <input> and <textarea> tags that will hold our user's information as well as provide them a means to submit the web form (input type="button").We use the <label>  tag to indicate to the user what information to put inside each form field. <form action="" method="get"> <p><label for="Name">Name: </label> <input name="Name" type="text"></p> <p><label for="Email">Email: </label> <input name="Email" type="text"></p> <p><label for="Comment">Comment: </label> <textarea name="Comment" cols="" rows=""></textarea></p> <p><input name="Submit" type="button" value="Submit"></p></form> With the above markup, this is how our form looks like: Our web form is a bit dull, so how about we spruce it up a bit with some CSS? Read the comments to gain insight on some of the more important CSS properties to take a note off. /* Center the fields using text-align:center */form { width:300px; border:1px solid #b1b8c2; background-color:#e3e9f2; text-align:center; padding:25px 0;}label { display:block; font:12px normal Verdana, Geneva, sans-serif;}/* Give the input and textarea fields a 1px border */input, textarea { width:250px; border:1px solid #5c616a;}textarea { height:100px;}p { text-align:left; display:block; width:250px; overflow:auto; padding:0; margin:5px 0;}/* We will give fields that are currently focused on the .focus class which will give them a distinct thicker border and background color compared to the other input fields */.focused { border:3px solid #b1b8c2; background-color: #e8e3e3;} With just a few styles, our simple web form has transformed to a more attractive form field. Let us move onto the JavaScript. We use the addEvent method to add an event listener for the form event, onfocus. When the user focuses on a particular field, we run a function that adds the .focus CSS class on that field we declared as a style rule in step 2. We'll also remove .focus class on other fields on the web page. window.addEvent('domready', function(){ var els = $$('input, textarea') els.addEvent('focus', function(){ els.removeClass('focused'); this.addClass('focused'); })}); Now, when you focus on a form field, it will be highlighted with a thick blue border and with a lighter blue background. Users who use the Tab key to navigate in between form fields will appreciate this feature since they'll clearly see which field is active. What just happened? In the previous example, we created a simple and interactive web form that highlights the current field the user has active. We did this by using the addEvent method, adding an event listener for the focus form event. When the user focuses on a particular input field, we ran a function that adds the .focusCSS class which highlights the focused field <input> or <textarea>with a thick blue border with a light blue background. By highlighting active fields in a web form, we have just improved our form's usability by providing visual feedback about which field the user is currently on.
Read more
  • 0
  • 0
  • 2136

article-image-deep-customization-bootstrap
Packt
19 Dec 2014
8 min read
Save for later

Deep Customization of Bootstrap

Packt
19 Dec 2014
8 min read
This article is written by Aravind Shenoy and Ulrich Sossou, the authors of the book, Learning Bootstrap. It will introduce you to the concept of deep customization of Bootstrap. (For more resources related to this topic, see here.) Adding your own style sheet works when you are trying to do something quick or when the modifications are minimal. Customizing Bootstrap beyond small changes involves using the uncompiled Bootstrap source code. The Bootstrap CSS source code is written in LESS with variables and mixins to allow easy customization. LESS is an open source CSS preprocessor with cool features used to speed up your development time. LESS allows you to engage an efficient and modular style of working making it easier to maintain your CSS styling in your projects. The advantages of using variables in LESS are profound. You can reuse the same code many times thereby following the write once, use anywhere paradigm. Variables can be globally declared, which allows you to specify certain values in a single place. This needs to be updated only once if changes are required. LESS variables allow you to specify widely-used values such as colors, font family, and sizes in a single file. By modifying a single variable, the changes will be reflected in all the Bootstrap components that use it; for example, to change the background color of the body element to green (#00FF00 is the hexadecimal code for green), all you need to do is change the value of the variable called @body-bg in Bootstrap as shown in the following code: @body-bg: #00FF00; Mixins are similar to variables but for whole classes. Mixins enable you to embed the properties of a class into another. It allows you to group multiple code lines together so that it can be used numerous times across the style sheet. Mixins can also be used alongside variables and functions resulting in multiple inheritances; for example, to add clearfix to an article, you can use the .clearfix mixin as shown in the left column of the following table. It will result in all clearfix declarations included in the compiled CSS code shown in the right column: Mixin CSS code article { .clearfix; }   { article:before, article:after { content: " "; // 1 display: table; // 2 } article:after { clear: both; } }   A clearfix mixin is a way for an element to automatically clear after itself, so that you don't need to add additional markup. It's generally used in float layouts, where elements are floated to be stacked horizontally. Let's look at a pragmatic example to understand how this kind of customization is used in a real-time scenario: Download and unzip the Bootstrap files into a folder. Create an HTML file called bootstrap_example and save it in the same folder where you saved the Bootstrap files. Add the following code to it: <!DOCTYPE html> <html> <head> <title>BootStrap with Packt</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial- scale=1.0"> <!-- Downloaded Bootstrap CSS --> <link href="css/bootstrap.css" rel="stylesheet"> <!-- JavaScript plugins (requires jQuery) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/ jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> </head> <body> <h1>Welcome to Packt</h1> <button type="button" class="btn btn-default btn-lg" id="packt">PACKT LESSONS</button> </body> </html> The output of this code upon execution will be as follows: The Bootstrap folder includes the following folders and file:     css     fonts     js     bootstrap_example.html This Bootstrap folder is shown in the following screenshot: Since we are going to use the Bootstrap source code now, let's download the ZIP file and keep it at any location. Unzip it, and we can see the contents of the folder as shown in the following screenshot: Let's now create a new folder called bootstrap in the css folder. The contents of our css folder will appear as displayed in the following screenshot: Copy the contents of the less folder from the source code and paste it into the newly created bootstrap folder inside the css folder. Thus, the contents of the same bootstrap folder within the css folder will appear as displayed in the following screenshot: In the bootstrap folder, look for the variable.less file and open it using Notepad or Notepad++. In this example, we are using a simple Notepad, and on opening the variable.less file with Notepad, we can see the contents of the file as shown in the following screenshot: Currently, we can see @body-bg is assigned the default value #fff as the color code. Change the background color of the body element to green by assigning the value #00ff00 to it. Save the file and later on, look for the bootstrap.less file in the bootstrap folder. In the next step, we are going to use WinLess. Open WinLess and add the contents of the bootstrap folder to it. In the folder pane, you will see all the less files loaded as shown in the following screenshot:   Now, we need to uncheck all the files and only select the bootstrap.less file as shown in following screenshot:  Click on Compile. This will compile your bootstrap.less file to bootstrap.css. Copy the newly compiled bootstrap.css file from the bootstrap folder and paste it into the css folder thereby replacing the original bootstrap.css file. Now that we have the updated bootstrap.css file, go back to bootstrap_example.html and execute it. Upon execution, the output of the code would be as follows:  Thus, we can see that the background color of the <body> element turns to green as we have altered it globally in the variables.less file that was linked to the bootstrap.less file, which was later compiled to bootstrap.css by WinLess. We can also use LESS variables and mixins to customize Bootstrap. We can import the Bootstrap files and add our customizations. Let's now create our own less file called styles.less in the css folder. We will now include the Bootstrap files by adding the following line of code in the styles.less file: @import "./bootstrap/bootstrap.less"; We have given the path,./bootstrap/bootstrap.less as per the location of the bootstrap.less file. Remember to give the appropriate path if you have placed it at any other location. Now, let's try a few customizations and add the following code to styles.less: @body-bg: #FFA500; @padding-large-horizontal: 40px; @font-size-base: 7px; @line-height-base: 9px; @border-radius-large: 75px; The next step is to compile the styles.less file to styles.css. We will again use WinLess for this purpose. You have to uncheck all the options and select only styles.less to be compiled:  On compilation, the styles.css file will contain all the CSS declarations from Bootstrap. The next step would be to add the styles.css stylesheet to the bootstrap_example.html file.So your HTML code will look like this: <!DOCTYPE html> <html> <head> <title>BootStrap with Packt</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial- scale=1.0"> <!-- Downloaded Bootstrap CSS --> <link href="css/bootstrap.css" rel="stylesheet"> <!-- JavaScript plugins (requires jQuery) --> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/ jquery.min.js"></script> <!-- Include all compiled plugins (below), or include individual files as needed --> <script src="js/bootstrap.min.js"></script> <link href="css/styles.css" rel="stylesheet"> </head> <body> <h1>Welcome to Packt</h1> <button type="button" class="btn btn-default btn-lg" id="packt">PACKT LESSONS</button> </body> </html> The output of the code is as follows: Since we changed the background color to orange (#ffa500), created a border radius, and defined the font-size-base and line-height-base, the output on execution was as displayed in the preceding screenshot. The LESS variables should be added to the styles.less file after the Bootstrap import so that they override the variables defined in the Bootstrap files. In short, all the custom code you write should be added after the Bootstrap import. Summary Therefore, we had a look at the procedure to implement Deep Customization in Bootstrap. However, we are still at the start of the journey. The learning curve is always steep as there is so much more to learn. Learning is always an ongoing process and it would never cease to exist. Thus, there is still a long way to go and in a pragmatic sense, the journey is the destination. Resources for Article: Further resources on this subject: Creating attention-grabbing pricing tables [article] Getting Started with Bootstrap [article] Bootstrap 3.0 is Mobile First [article]
Read more
  • 0
  • 0
  • 2133

article-image-slider-dynamic-applications-using-scriptaculous-part-2
Packt
08 Oct 2009
4 min read
Save for later

Slider for Dynamic Applications using script.aculo.us (part 2)

Packt
08 Oct 2009
4 min read
Code usage for sliders with options We are now done with the most important part of the slider: the implementation of the slider in our applications. But wait, we need the slider to suit our applications, right? So let's customize our slider with options. We have mentioned earlier that track is the range of values. So let's first define the range for our slider. window.onload = function() { new Control.Slider('handle1' , 'track1', { axis:'vertical', range:$R(1,100)} The range option uses the Prototypes' objectRange instance. Hence, we declare it using $R (minimum, Maximum). Everything looks neat until here. Let's add some more options to our constructor, onSlide(). Using the onSlide() callback every time, we drag the slider and the callback is invoked. The default parameter passed to onSlide() is the current slider value. window.onload = function() { new Control.Slider('handle1' , 'track1', { axis:'vertical', range:$R(1,100), onSlide: function(v) { $('value1').innerHTML = "New Slide Value="+v;} }} We have added a div called value1 in our HTML code. On dragging the slider, we will update the value1 with the current slider value. OK, so let's see what happened to our slider to this point. Check out the following screenshot: Impressed? And, we are not done yet. Let's add more options to the slider now. You may ask me, what if the slider in the application needs to be at a particular value by default? And I will say use the sliderValue option. Let's make our slider value 10 by default. Here is the snippet for the same: window.onload = function() {      new Control.Slider('handle1' , 'track1',     {   axis:'vertical',   range:$R(1,100),   sliderValue: 10,   onSlide: function(v) { $('value1').innerHTML = "New Slide                                                 Value="+v;}} And, you should see the slider value at 10 when you run the code. Now your dear friend will ask, what if we don't want to give the range, but we need to pass the fixed set of values? And you proudly say, use the values option. Check out the usage of the values options in the constructor. window.onload = function() { new Control.Slider('handle1' , 'track1', { range:$R(1,25), values:[1, 5,10,15,20,25], onSlide:function(v){ $('value1').innerHTML = "New Slide Value="+v;} } );} We have added a set of values in the array form and passed it to our constructor. Let's see what it looks like. Tips and tricks with the slider After covering all the aspects of the slider feature, here is a list of simple tips and tricks which we can make use of in our applications with ease. Reading the current value of the slider script.aculo.us "genie" provides us with two callbacks for the slider to read the current value of the slider. They are: onSlide onChange Both these callbacks are used as a part of options in the slider. onSlide contains the current sliding value while the drag is on. The callback syntax is shown as follows: onSlide: function(value) {// do something with the value while sliding. Write or Edit thevalue //of current slider value while sliding} onChange callback will contain the value of the slider while the sliding or the drag event ends. After the drag is completed and if the value of the slider has changed then the onChange function will be called. For example, if the slider's current value is set to 10 and after sliding we change it to 15, then the onChange callback will be fired. The callback syntax is shown as follows: onChange: function(value){// do anything with the "changed" and current value} Multiple handles in the slider Now, a thought comes to our mind at this point: Is it possible for us to have two handles in one track? And, the mighty script.aculo.us library says yes! Check out the following code snippet and screenshot for a quick glance of having two handles in one track: HTML code<div id="track1"><div id="handle1"></div><div id="handle2"></div></div> JavaScript code for the same: window.onload = function() { new Control.Slider(['handle1','handle2'] , 'track1');} Now, check out the resulting screenshot having two handles and one track: The same can also be applied for the vertical slider too.
Read more
  • 0
  • 0
  • 2130

article-image-developing-seam-applications
Packt
08 Oct 2009
10 min read
Save for later

Developing Seam Applications

Packt
08 Oct 2009
10 min read
Seam application architecture As most enterprise Java developers are probably familiar with JSF and JSP, we will be using this as the view technology for our sample applications. Facelets is the recommended view technology for Seam-based applications once we have a solid understanding of Seam. In a standard Java EE application, Enterprise Application Resource (EAR) files contain one or more Web Application Resource (WAR) files and one or more sets of Java Archive (JAR) files containing Enterprise JavaBeans (EJB) functionality. Seam applications are generally deployed in exactly the same manner as depicted in the following diagram. It is possible to deploy Seam onto a servlet-only container (for example, Tomcat) and use POJOs as the server-side Seam components. However, in this situation, we don't get any of the benefits that EJBs provide, such as security, transaction handling, management, or pooling. Seam components Within Seam, components are simple POJOs. There is no need to implement any interfaces or derive classes from a Seam-specific base class to make Seam components classes. For example, a Seam component could be: A simple POJO a stateless Session Bean a stateful Session Bean a JPA entity and so on Seam components are defined by adding the @Name annotation to a class definition. The @Name annotation takes a single parameter to define the name of the Seam component. The following example shows how a stateless Session Bean is defined as a Seam component called calcAction. package com.davidsalter.seamcalculator; @Stateless @Name("calcAction") public class CalcAction implements Calc { ... } When a Seam application is deployed to JBoss, the log output at startup lists what Seam components are deployed, and what type they are. This can be useful for diagnostic purposes, to ensure that your components are deployed correctly. Output similar to the following will be shown in the JBoss console log when the CalcAction class is deployed: 21:24:24,097 INFO [Initialization] Installing components...21:24:24,121 INFO [Component] Component: calcAction, scope: STATELESS, type: STATELESS_SESSION_BEAN, class: com.davidsalter.seamcalculator.CalcAction, JNDI: SeamCalculator/CalcAction/local Object Injection and Outjection One of the benefits of using Seam is that it acts as the "glue" between the web technology and the server-side technology. By this we mean that the Seam Framework allows us to use enterprise beans (for example, Session Beans) directly within the Web tier without having to use Data Transfer Object (DTO) patterns and without worrying about exposing server-side functionality on the client. Additionally, if we are using Session Beans for our server-side functionality, we don't really have to develop an additional layer of JSF backing beans, which are essentially acting as another layer between our web page and our application logic. In order to fully understand the benefits of Seam, we need to first describe what we mean by Injection and Outjection. Injection is the process of the framework setting component values before an object is created. With injection, the framework is responsible for setting components (or injecting them) within other components. Typically, Injection can be used to allow component values to be passed from the web page into Seam components. Outjection works in the opposite direction to Injection. With Outjection, components are responsible for setting component values back into the framework. Typically, Outjection is used for setting component values back into the Seam Framework, and these values can then be referenced via JSF Expression Language (EL) within JSF pages. This means that Outjection is typically used to allow data values to be passed from Seam components into web pages. Seam allows components to be injected into different Seam components by using the @In annotation and allows us to outject them by using the @Out annotation. For example, if we have some JSF code that allows us to enter details on a web form, we may use an <h:inputText …/> tag such as this: <h:inputText value="#{calculator.value1}" required="true"/> The Seam component calculator could then be injected into a Seam component using the @In annotation as follows: @In private Calculator calculator; With Seam, all of the default values on annotations are the most likely ones to be used. In the preceding example therefore, Seam will look up a component called calculator and inject that into the calculator variable. If we wanted Seam to inject a variable with a different name to the variable that it is being injected into, we can adorn the @In annotation with the value parameter. @In (value="myCalculator") private Calculator calculator; In this example, Seam will look up a component called myCalculator and inject it into the variable calculator. Similarly, if we want to outject a variable from a Seam component into a JSF page, we would use the @Out annotation. @Out private Calculator calculator; The outjected calculator object could then be used in a JSF page in the following manner: <h:outputText value="#{calculator.answer}"/> Example application To see these concepts in action, and to gain an understanding of how Seam components are used instead of JSF backing beans, let us look at a simple calculator web application. This simple application allows us to enter two numbers on a web page. Clicking the Add button on the web page will cause the sum of the numbers to be displayed. This basic application will give us an understanding of the layout of a Seam application and how we can inject and outject components between the business layer and the view. The application functionality is shown in the following screenshot. The sample code for this application can be downloaded from the Packt web site, at http://www.packtpub.com/support. For this sample application, we have a single JSF page that is responsible for: Reading two numeric values from the user Invoking business logic to add the numbers together Displaying the results of adding the numbers together <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <html> <head> <title>Seam Calculator</title> </head> <body> <f:view> <h:form> <h:panelGrid columns="2"> Value 1: <h:inputText value="#{calculator. value1}" /> Value 2: <h:inputText value="#{calculator. value2}" /> Add them together gives: <h:outputText value=" #{calculator.answer} "/> </h:panelGrid> <h:commandButton value="Add" action= "#{calcAction.calculate}"/> </h:form> </f:view> </body> </html> We can see that there is nothing Seam-specific in this JSF page. However, we are binding two inputText areas, one outputText area, and a button action to Seam components by using standard JSF Expression Language. JSF EL Seam Binding calculator.value1 This is bound to the member variable value1 on the Seam component called calculator. This value will be injected into the Seam component. calculator.value2 This is bound to the member variable value2 on the Seam component called calculator. This value will be injected into the Seam component. calculator.answer This is bound to the member variable answer on the Seam component called calculator. This value will be outjected from the Seam component. calcAction.calculate This will invoke the method calculate() on the Seam component called calcAction. Our business logic for this sample application is performed in a simple POJO class called Calculator.java. package com.davidsalter.seamcalculator; import java.io.Serializable; import org.jboss.seam.annotations.Name;@Name("calculator") public class Calculator { private double value1; private double value2; private double answer; public double getValue1() { return value1; } public void setValue1(double value1) { this.value1 = value1; } public double getValue2() { return value2; } public void setValue2(double value2) { this.value2 = value2; } public double getAnswer() { return answer; } public void add() { this.answer = value1 + value2; } } This class is decorated with the @Name("calculator") annotation, which causes it to be registered to Seam with the name, "calculator". The @Name annotation causes this object to be registered as a Seam component that can subsequently be used within other Seam components via Injection or Outjection by using the @In and @Out annotations. Finally, we need to have a class that is acting as a backing bean for the JSF page that allows us to invoke our business logic. In this example, we are using a Stateless Session Bean. The Session Bean and its local interface are as follows. In the Java EE 5 specification, a Stateless Session Bean is used to represent a single application client's communication with an application server. A Stateless Session Bean, as its name suggests, contains no state information; so they are typically used as transaction façades. A Façade is a popular design pattern, which defines how simplified access to a system can be provided. For more information about the Façade pattern, check out the following link: http://java.sun.com/blueprints/corej2eepatterns/Patterns/SessionFacade.html Defining a Stateless Session Bean using Java EE 5 technologies requires an interface and an implementation class to be defined. The interface defines all of the methods that are available to clients of the Session Bean, whereas the implementation class contains a concrete implementation of the interface. In Java EE 5, a Session Bean interface is annotated with either the @Local or @Remote or both annotations. An @Local interface is used when a Session Bean is to be accessed locally within the same JVM as its client (for example, a web page running within an application server). An @Remote interface is used when a Session Bean's clients are remote to the application server that is running within a different JVM as the application server. There are many books that cover Stateless Session Beans and EJB 3 in depth, such as EJB 3 Developer's Guide by Michael Sikora, published by Packt Publishing. For more information on this book, check out the following link: http://www.packtpub.com/developer-guide-for-ejb3 In the following code, we are registering our CalcAction class with Seam under the name calcAction. We are also Injecting and Outjecting the calculator variable so that we can use it both to retrieve values from our JSF form and pass them back to the form. package com.davidsalter.seamcalculator; import javax.ejb.Stateless; import org.jboss.seam.annotations.In; import org.jboss.seam.annotations.Out; import org.jboss.seam.annotations.Name; @Stateless @Name("calcAction") public class CalcAction implements Calc { @In @Out private Calculator calculator; public String calculate() { calculator.add(); return ""; } } package com.davidsalter.seamcalculator; import javax.ejb.Local; @Local public interface Calc { public String calculate(); } That's all the code we need to write for our sample application. If we review this code, we can see several key points where Seam has made our application development easier: All of the code that we have developed has been written as POJOs, which will make unit testing a lot easier. We haven't extended or implemented any special Seam interfaces. We've not had to define any JSF backing beans explicitly in XML. We're using Java EE Session Beans to manage all of the business logic and web-tier/business-tier integration. We've not used any DTO objects to transfer data between the web and the business tiers. We're using a Seam component that contains both state and behavior. If you are familiar with JSF, you can probably see that adding Seam into a fairly standard JSF application has already made our development simpler. Finally, to enable Seam to correctly find our Seam components and deploy them correctly to the application server, we need to create an empty file called seam.properties and place it within the root of the classpath of the EJB JAR file. Because this file is empty, we will not discuss it further here. To deploy the application as a WAR file embedded inside an EAR file, we need to write some deployment descriptors.
Read more
  • 0
  • 0
  • 2126

article-image-setting-rig
Packt
21 Aug 2014
16 min read
Save for later

Setting Up The Rig

Packt
21 Aug 2014
16 min read
In this article by Vinci Rufus, the author of the book AngularJS Web Application Development Blueprints, we will see the process of setting up various tools required to start building AngularJS apps. I'm sure you would have heard the saying, "A tool man is known by the tools he keeps." OK fine, I just made that up, but that's actually true, especially when it comes to programming. Sure you can build complete and fully functional AngularJS apps just using a simple text editor and a browser, but if you want to work like a ninja, then make sure that you start using some of these tools as a part of your development workflow. Do note that these tools are not mandatory to build AngularJS apps. Their use is recommended mainly to help improve the productivity. In this article, we will see how to set up and use the following productivity tools: Node.js Grunt Yeoman Karma Protractor Since most of us are running a Mac, Windows, Ubuntu, or another flavor of the Linux operating system, we'll be covering the deployment steps common for all of them. (For more resources related to this topic, see here.) Setting up Node.js Depending on your technology stack, I strongly recommend you have either Ruby or Node.js installed. In case of AngularJS, most of the productivity tools or plugins are available as Node Package Manager (npm), and, hence, we will be setting up Node.js along with npm. Node.js is an open source JavaScript-based platform that uses an event-based Input/output model, making it lightweight and fast. Let us head over to www.nodejs.org and install Node.js. Choose the right version as per your operating system. The current version of Node.js at the time of writing this article is v0.10.x which comes with npm built in, making it a breeze to set up Node.js and npm. Node.js doesn't come with a Graphical User Interface (GUI), so to use Node.js, you will need to open up your terminal and start firing some commands. Now would also be a good time to brush up on your DOS and Unix/Linux commands. After installing Node.js, the first thing you'd want to check is to see if Node.js has been installed correctly. So, let us open up the terminal and write the following command: node –-version This should output the version number of Node.js that's installed on your system. The next would be to see what version of npm we have installed. The command for that would be as follows: npm –-version This will tell you the version number for your npm. Creating a simple Node.js web server with ExpressJS For basic, simple AngularJS apps, you don't really need a web server. You can simply open the HTML files from your filesystem and they would work just fine. However, as you start building complex applications where you are passing data in JSON, web services, or using a Content Delivery Network (CDN), you would find the need to use a web server. The good thing about AngularJS apps is that they could work within any web server, so if you already have IIS, Apache, Nginx, or any other web server running on your development environment, you can simply run your AngularJS project from within the web root folder. In case you don't have a web server and are looking for a lightweight web server, then let us set one up using Node.js and ExpressJS. One could write the entire web server in pure Node.js; however, ExpressJS provides a nice layer of abstraction on top of Node.js so that you can just work with the ExpressJS APIs and don't have to worry about the low-level calls. So, let's first install the ExpressJS module for Node.js. Open up your terminal and fire the following command: npm install -g express-generator This will globally install ExpressJS. Omit the –g to install ExpressJS locally in the current folder. When installing ExpressJS globally on Linux or Mac, you will need to run it via sudo as follows: sudo npm install –g express-generator This will let npm have the necessary permissions to write to the protected local folder under the user. The next step is to create an ExpressJS app; let us call it my-server. Type the following command in the terminal and hit enter: express my-server You'll see something like this: create : my-server create : my-server/package.json create : my-server/app.js create : my-server/public create : my-server/public/javascripts create : my-server/public/images create : my-server/public/stylesheets create : my-server/public/stylesheets/style.css create : my-server/routes create : my-server/routes/index.js create : my-server/routes/user.js create : my-server/views create : my-server/views/layout.jade create : my-server/views/index.jade install dependencies: $ cd my-server && npm install run the app: $ DEBUG=my-server ./bin/www This will create a folder called my-server and put in a bunch of files inside the folder. The package.json file is created, which contains the skeleton of your app. Open it and ensure the name says my-server; also, note the dependencies listed. Now, to install ExpressJS along with the dependencies, first change into the my-server directory and run the following command in the terminal: cd my-server npm install Now, in the terminal, type in the following command: npm start Open your browser and type http://localhost:3000 in the address bar. You'll get a nice ExpressJS welcome message. Now to test our Address Book App, we will copy our index.html, scripts.js, and styles.css into the public folder located within my-server. I'm not copying the angular.js file because we'll use the CDN version of the AngularJS library. Open up the index.html file and replace the following code: <script src= "angular.min.js" type="text/javascript"> </script> With the CDN version of AngularJS as follows: <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.min.js"></script> A question might arise, as to what if the CDN is unreachable. In such cases, we can add a fall back to use a local version of the AngularJS library. We do this by adding the following script after the CDN link is called: <script>window.angular || document.write('<script src="lib/angular/angular.min.js"></script>');</script> Save the file in the browser and enter localhost:3000/index.html. Your Address Book app is now running from a server and taking advantage of Google's CDN to serve the AngularJS file. Referencing the files using only // is also called the protocol independent absolute path. This means that the files are requested using the same protocol that is being used to call the parent page. For example, if the page you are loading is via https://, then the CDN link will also be called via HTTPS. This also means that when using // instead of http:// during development, you will need to run your app from within a server instead of a filesystem. Setting up Grunt Grunt is a JavaScript-based task runner. It is primarily used for automating tasks such as running unit tests, concatenating, merging, and minifying JS and CSS files. You can also run shell commands. This makes it super easy to perform server cleanups and deploy code. Essentially, Grunt is to JavaScript what Rake would be to Ruby or Ant/Maven would be to Java. Installing Grunt-cli Installing Grunt-cli is slightly different from installing other Node.js modules. We first need to install the Grunt's Command Line Interface (CLI) by firing the following command in the terminal: npm install -g grunt-cli Mac or Linux users can also directly run the following command: sudo npm install –g grunt-cli Make sure you have administrative privileges. Use sudo if you are on a Mac or Linux system. If you are on Windows, right-click and open the command prompt with administrative rights. An important thing to note is that installing Grunt-cli doesn't automatically install Grunt and its dependencies. Grunt-cli merely invokes the version of Grunt installed along with the Grunt file. While this may seem a little complicated at start, the reason it works this way is so that we can run different versions of Grunt from the same machine. This comes in handy when your project has dependencies on a specific version of Grunt. Creating the package.json file To install Grunt first, let's create a folder called my-project and create a file called package.json with the following content: { "name": "My-Project", "version": "0.1.0", "devDependencies": { "grunt": "~0.4.5", "grunt-contrib-jshint": "~0.10.0", "grunt-contrib-concat": "~0.4.0", "grunt-contrib-uglify": "~0.5.0", "grunt-shell": "~0.7.0" } } Save the file. The package.json is where you define the various parameters of your app; for example, the name of your app, the version number, and the list of dependencies needed for the app. Here we are calling our app My-Project with Version 0.1.0, and listing out the following dependencies that need to be installed as a part of this app: grunt (v0.4.5): This is the main Grunt application grunt-contrib-jshint (v0.10.0): This is used for code analysis grunt-contrib-concat (v0.4.0): This is used to merge two or more files into one grunt-contrib-uglify (v0.5.0): This is used to minify the JS file grunt-shell (v0.7.0): This is the Grunt shell used for running shell commands Visit http://gruntjs.com/plugins to get a list of all the plugins available for Grunt and also their exact names and version numbers. You may also choose to create a default package.json file by running the following command and answering the questions: npm init Open the package.json file and add the dependencies as mentioned earlier. Now that we have the package.json file, load the terminal and navigate into the my-project folder. To install Grunt and the modules specified in the file, type in the following command: npm install --save-dev You'll see a series of lines getting printed in the console, let that continue for a while and wait until it returns to the command prompt. Ensure that the last line printed by the previous command ends with OK code 0. Once Grunt is installed, a quick version check command will ensure that Grunt is installed. The command is as follows: grunt –-version There is a possibility that you got a bunch of errors and it ended with a not ok code 0 message. There could be multiple reasons why that would have happened, ranging from errors in your code to a network connection issue or something changing at Grunt's end due to a new version update. If grunt --version throws up an error, it means Grunt wasn't installed properly. To reinstall Grunt, enter the following commands in the terminal: rm –rf node_modules npm cache clean npm install Windows users may manually delete the node_modules folder from Windows Explorer, before running the cache clean command in the command prompt. Refer to http://www.gruntjs.com to troubleshoot the problem. Creating your Grunt tasks To run our Grunt tasks, we'll need a JavaScript file. So, let's copy our scritps.js file and place it into the my-projects folder. The next step is to create a Grunt file that will list out the tasks that we need Grunt to perform. For now, we will ask it to do four simple tasks, first check if our JS code is clean using JSHint, then we will merge three JS files into one and then minify the JS file, and finally we will run some shell commands to clean up. Until Version 0.3, the init command was a part of the Grunt tool and one could create a blank project using grunt-init. With Version 0.4, init is now available as a separate tool called grunt-init and needs to be installed using the npm install –g grunt-init command line. Also note that the structure of the grunt.js file from Version 0.4 onwards is fairly different from the earlier versions you've used. For now, we will resort to creating the Grunt file manually. Refer to the following screenshot: In the same location as where you have your package.json, create a file called gruntfile.js as shown earlier and type in the following code: module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jshint:{ all:['scripts.js'] } }); grunt.loadNpmTasks('grunt-contrib-jshint'); // Default task. grunt.registerTask('default', ['jshint']); }; To start, we will add only one task which is jshint and specify scripts.js in the list of files that need to be linted. In the next line, we specify grunt-contrib-jshint as the npm task that needs to be loaded. In the last line, we define the jshint as the task to be run when Grunt is running in default mode. Save the file and in the terminal run the following command: grunt You would probably get to see the following message in the terminal: So JSHint is saying that we are missing a semicolon on lines 18 and 24. Oh! Did I mention that JSHint is like your very strict math teacher from high school. Let's open up scripts.js and put in those semicolons and rerun Grunt. Now you should get a message in green saying 1 file lint free. Done without errors. Let's add some more tasks to Grunt. We'll now ask it to concatenate and minify a couple of JS files. Since we currently have just one file, let's go and create two dummy JS files called scripts1.js and scripts2.js. In scripts1.js we'll simply write an empty function as follows: // This is from script 1 function Script1Function(){ //------// } Similarly, in scripts2.js we'll write the following: // This is from script 2 function Script2Function(){ //------// } Save these files in the same folder where you have scripts.js. Grunt tasks to merge and concatenate files Now, let's open our Grunt file and add the code for both the tasks—to merge the JS file, and minify them as follows: module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jshint:{ all:['scripts.js'] }, concat: { dist: { src: ['scripts.js', 'scripts1.js','scripts2.js'], dest: 'merged.js' } }, uglify: { dist: { src: 'merged.js', dest: 'build/merged.min.js' } } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); // Default task. grunt.registerTask('default', ['jshint','concat','uglify']); }; As you can see from the preceding code, after the jshint task, we added the concat task. Under the src attribute, we define the files separated by a comma that need to be concatenated. And in the dest attribute, we specify the name of the merged JS file. It is very important that the files are entered in the same sequence as they need to be merged. If the sequence of the files entered is incorrect, the merged JS file will cause errors in your app. The uglify task is used to minify the JS file and the structure is very similar to the concat task. We add the merged.js file to the src attribute and in the dest attribute, we will place the merged.min.js file into a folder called build. Grunt will auto create the build folder. After defining the tasks, we will load the necessary plugins, namely the grunt-contrib-concat and the grunt-contrib-uglify, and finally we will register the concat and uglify tasks to the default task. Save the file and run Grunt. And if all goes well, you should see Grunt running these tasks and informing the status of each of the tasks. If you get the final message saying, Done, without any errors, it means things went well, and this was your lucky day! If you now open your my-project folder in the file manager, you should see a new file called merged.js. Open it in the text editor and you'll notice that all the three files have been merged into this. Also, go into the build/merged.min.js file and verify whether the file is minified. Running shell commands via Grunt Another really helpful plugin in Grunt is grunt-shell. This allows us to effectively run clean-up activities such as deleting .tmp files and moving files from one folder to another. Let's see how to add the shell tasks to our Grunt file. Add the following highlighted piece of code to your Grunt file: module.exports = function(grunt) { // Project configuration. grunt.initConfig({ jshint:{ all:['scripts.js'] }, concat: { dist: { src: ['scripts.js', 'scripts1.js','scripts2.js'], dest: 'merged.js' } }, uglify: { dist: { src: 'merged.js', dest: 'build/merged.min.js' } } , shell: { multiple: { command: [ 'rm -rf merged.js', 'mkdir deploy', 'mv build/merged.min.js deploy/merged.min.js' ].join('&&') } } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-shell'); // Default task. grunt.registerTask('default', ['jshint','concat','uglify', 'shell' ]); }; As you can see from the code we added, we are first deleting the merged.js file, then creating a new folder called deploy and moving our merged.min.js file into it. Windows users would need to use the appropriate DOS commands for deleting and copying the files. Note that .join('&&') is used when you want Grunt to run multiple shell commands. The next steps are to load the npm tasks and add shell to the default task list. To see Grunt perform all these tasks, run the Grunt command in the terminal. Once it's done, open up the filesystem and verify whether Grunt has done what you had asked it to do. Just like we used the preceding four plugins, there are numerous other plugins that you can use with Grunt to automate your tasks. A point to note is while the default Grunt command will run all the tasks mentioned in the grunt.registerTask statement, if you would need to run a specific task instead of all of them, then you can simply type the following in the command line: grunt jshint Alternatively, you can type the following command: grunt concat Alternatively, you can type the following command: grunt ugligy At times if you'd like to run just two of the three tasks, then you can register them separately as another bundled task in the Grunt file. Open up the gruntfile.js file, and just after the line where you have registered the default task, add the following code: grunt.registerTask('concat-min', ['concat','uglify']); This will register a new task called concat-min and will run only the concat and uglify tasks. In the terminal run the following command: grunt concat-min Verify whether Grunt only concatenated and minified the file and didn't run JSHint or your shell commands. You can run grunt --help to see a list of all the tasks available in your Grunt file.
Read more
  • 0
  • 0
  • 2115
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
article-image-angularjs-web-application-development-cookbook
Packt
08 May 2015
2 min read
Save for later

AngularJS Web Application Development Cookbook

Packt
08 May 2015
2 min read
Architect performant applications and implement best practices in AngularJS. Packed with easy-to-follow recipes, this practical guide will show you how to unleash the full might of the AngularJS framework. Skip straight to practical solutions and quick, functional answers to your problems without hand-holding or slogging through the basics. (For more resources related to this topic, see here.) Some highlights include: Architecting recursive directives Extensively customizing your search filter Custom routing attributes Animating ngRepeat Animating ngInclude, ngView, and ngIf Animating ngSwitch Animating ngClass, and class attributes Animating ngShow, and ngHide The goal of this text is to have you walk away from reading about an AngularJS concept armed with a solid understanding of how it works, insight into the best ways to wield it in real-world applications, and annotated code examples to get you started. Why you should buy this book A collection of recipes demonstrating optimal organization, scaleable architecture, and best practices for use in small and large-scale production applications. Each recipe contains complete, functioning examples and detailed explanations on how and why they are organized and built that way, as well as alternative design choices for different situations. The author of this book is a full stack developer at DoorDash (YC S13), where he joined as the first engineer. He led their adoption of AngularJS, and he also focuses on the infrastructural, predictive, and data projects within the company. Matt has a degree in Computer Engineering from the University of Illinois at Urbana-Champaign. He is the author of the video series Learning AngularJS, available through O'Reilly Media. Previously, he worked as an engineer at several educational technology start-ups. Almost every example in this book has been added to JSFiddle, with the links provided in the book. This allows you to merely visit a URL in order to test and modify the code with no setup of any kind, on any major browser and on any major operating system. Resources for Article:  Further resources on this subject: Working with Live Data and AngularJS [article] Angular Zen [article] AngularJS Project [article]
Read more
  • 0
  • 0
  • 2093

article-image-augmentedti-application-architecture
Packt
31 Dec 2012
5 min read
Save for later

augmentedTi: The application architecture

Packt
31 Dec 2012
5 min read
(For more resources related to this topic, see here.) An overview The augmentedTi application has been developed to demonstrate Augmented Reality in action; it has been coded using the Appcelerator Titanium Framework. This framework enables a "code once, adapt everywhere" approach to mobile application development. It uses the commonJS architecture at its core and has a set of best practices, which can be read at https://wiki.appcelerator.org/display/guides/Best+Practices. The application follows these guidelines and also implements an MVC style architecture, using a controller, and event driven flow control methodology incorporating localization. At the current time trying to implement a CSS applied look and feel using the frameworks JSS method is not viable. The application gets around the issue of hard coding fonts, colors, and images into the application by using two files—ui/layout.js and ui/images.js. These files contain the look, feel, and images applied throughout the application, and are standalone modules, enabling them to be included in any other modules. The application As you start to explore the application you will see that the main bootstrap file app.js only contains the require of the controller file and the call to the initial function startApp(): var ctl = require('/control/controller'); ctl.startApp(); To implement methodology for separating the code into distinct commonJS modules, the following file structure is applied: i18n/en/strings.xml resources/app.js resources/control/controller.js resources/images resources/services/googleFeed.js location.js resources/tools/augmentedReality.js common.js iosBackgroundService.js persHandler.js ui/images.js layout.js common/activity.js titleBar.js screens/ARScreen.js homeScreen.js The main file which controls the application is controller.js. When an activity is completed, the control is returned here and the next activity is processed. This has an implication with enabling the program flow—application-level event listeners have to be added, using up resources. The application gets around this by creating a single custom event listener, which then calls a function to handle the flow. The fire event is handled within the tools/common.js file by providing a single function to be called, passing the required type and any other parameters: Ti.App.addEventListener('GLOBALLISTENER', function(inParam){ var gblParams = {}; for(var paramKeyIn in inParam) { if(inParam[paramKeyIn]) { gblParams[paramKeyIn] = inParam[paramKeyIn]; }} processGlobalListener(gblParams);}); function launchEvent(inParam){ var evtParams = {}; for(var paramKeyIn in inParam) { if(inParam[paramKeyIn]) { evtParams[paramKeyIn] = inParam[paramKeyIn]; }} Ti.App.fireEvent('GLOBALLISTENER', evtParams);} common.launchEvent({ TYPE : 'ERROR', MESS : 'E0004'}); Throughout the application's commonJS modules, a standard approach is taken, defining all functions and variables as local and exporting only those required at the end of the file: exports.startApp = startApp; In keeping with the commonJS model, the modules are only required when and where they are needed. No application-level global variables are used and each part of the application is split into its own module or set of modules. Within the application where data has to be stored, persistent data is used. It could have been passed around, but the amount of data is small and required across the whole application. The persistent data is controlled through the tools/persHandler.js module, which contains two functions—one for setting and one for getting the data. These functions accept the parameter of the record to update or return. var persNames = { lon : 'longitude', lat : 'latitude', width : 'screenWidth', height : 'screenHeight', bearing : 'bearing' }; function putPersData(inParam){ Ti.App.Properties.setString(persNames[inParam.type], inParam.data); return;} persHandler.putPersData({ type : 'width', data : Ti.Platform.displayCaps.platformWidth }); The application does not use the in-built tab navigation; instead it defines a custom title bar and onscreen buttons. This enables it to work across all platforms with the same look and feel. It also uses a custom activity indicator. Augmented Reality This section explains what Augmented Reality is and the solution provided within the augmentedTi application. With all technology something and somebody has to be first. Mobile computing and especially smart phones are still in their infancy. Resulting in new technologies, applications, and solutions being devised and applied almost daily. Augmented Reality is only now becoming viable, as the devices, technology, and coding solutions are more advanced. In this section a coding solution is given, which shows how to implement location-based Augmented Reality. It should work on most smart phones, and can be coded in most frameworks and native code. The code examples given use the Appcelerator Titanium Framework only. No additional modules or plugins are required. Summary This article dived into the open source code base of the augmentedTi example application, explaining how it has been implemented. Resources for Article : Further resources on this subject: iPhone: Customizing our Icon, Navigation Bar, and Tab Bar [Article] Animating Properties and Tweening Pages in Android 3-0 [Article] Flash Development for Android: Visual Input via Camera [Article]
Read more
  • 0
  • 0
  • 2086

article-image-preparing-your-website-use-gridster
Packt
22 May 2013
4 min read
Save for later

Preparing your website to use Gridster

Packt
22 May 2013
4 min read
(For more resources related to this topic, see here.) Getting ready There are only two things needed to get Gridster installed on your source code. You first need to download jQuery if you don't already have it, and then download the latest version of Gridster. After that, you will use plain HTML code to include both libraries in your webpage. For most casual users, adding the latest version of jQuery will suffice. There are also nightly builds available, but these won't be discussed here as they are not necessary, and the latest version should be able to do everything we need. How to do it... Start by visiting jQuery's website, http://jquery.com/download/, and download the library to a location you will remember. We won't be debugging our jQuery code in the examples given in this book, so downloading the production version will be fine. We should now head over to Gridster's website, http://gridster.net/#download/, and download the minified versions of both the gridster.js and gridster.css files. These are the files we will use throughout this entire book, so make sure they are kept safe and accessible. A suggestion would be to create a directory structure to make it easier to refer to the files. I will be using the following structure for the examples given here: Under the directory recipe1, create a new text file called index.html. This file should initially contain the following code: <!DOCTYPE html><html><head><script src = "../scripts/jquery-1.8.3.min.js"></script><script src = "../scripts/jquery.gridster.min.js"></script><link href = "../styles/jquery.gridster.min.css" rel="stylesheet" /><title>Recipe 1</title></head><body>Hello Gridster!</body></html> You can download the example code files for all Packt books that you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub. com/support and register to have the files e-mailed directly to you. By double-clicking on this file, you should be presented with a screen that looks like the following screenshot: You can check that everything has loaded up correctly by pressing the F12 key on your browser (Chrome or Firefox), and checking that all files have been correctly loaded without errors, as shown in the following screenshot: There's more... Instead of downloading the files into your project, you can simply load them up via CDN-hosted copies of the files, as follows: <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> In that case, the files wouldn't be coming from your website, but from jQuery's website itself. This is a good practice when trying to improve performance, as big web servers tend to host files on multiple locations and use very aggressive caching techniques to make sure the files are served quickly. Gridster also offers files in the same way from their website as you will find in their download section. So, for example, you could link directly to their minified file as follows: <scriptsrc ="https://raw.github.com/ducksboard/gridster.js/master/dist/jquery.gridster.min.js"></script> Summary In this recipe we described all the necessary steps to get Gridster up and running on your website, and also demonstrated how to include any of the dependencies needed by the library. Resources for Article : Further resources on this subject: Getting Started with jQuery [Article] jQuery Animation: Tips and Tricks [Article] Tips and Tricks for Working with jQuery and WordPress [Article]
Read more
  • 0
  • 0
  • 2067

article-image-form-handling
Packt
20 Feb 2014
22 min read
Save for later

Form Handling

Packt
20 Feb 2014
22 min read
(For more resources related to this topic, see here.) Collecting user data is a basic function of many websites and web applications, from simple data collection techniques such as registration or login information, to more complex scenarios such as payment or billing information. It is important that only relevant and complete information is collected from the user. To ensure this, the web developer must enforce validation on all data input. It is also important to provide a good user experience while enforcing this data integrity. This can be done by providing useful feedback to the user regarding any validation errors their data may have caused. This article will show you how to create an attractive web form that enforces data integrity while keeping a high-quality user experience. A very important point to note is that any JavaScript or jQuery validation is open to manipulation by the user. JavaScript and jQuery resides within the web browser, so a user with little knowledge can easily modify the code to bypass any client-side validation techniques. This means that client-side validation cannot be totally relied on to prevent the user from submitting invalid data. Any validation done within the client side must be replicated on the server, which is not open for manipulation by the user. We use client-side validation to improve the user experience. Because of this, the user does not need to wait for a server response. Implementing basic form validation At the most basic level of form validation, you will need to be able to prevent the user from submitting empty values. This recipe will provide the HTML and CSS code for a web form that will be used for recipes 1 through 8 of this article. Getting ready Using your favorite text editor or IDE, create a blank HTML page in an easily accessible location and save this file as recipe-1.html. Ensure that you have the latest version of jQuery downloaded to the same location as this HTML file. This HTML page will form the basis of most of this article, so remember to keep it after you have completed this recipe. How to do it… Learn how to implement basic form validation with jQuery by performing the following steps: Add the following HTML code to index.html. Be sure to change the source location of the JavaScript included for the jQuery library, pointing it to where the latest version of jQuery is downloaded on your computer. <!DOCTYPE html> <html > <head>    <title>Chapter 5 :: Recipe 1</title>    <link type="text/css" media="screen" rel="stylesheet" href="styles.css" />    <script src = "jquery.min.js"></script>    <script src = "validation.js"></script> </head> <body>    <form id="webForm" method="POST">       <div class="header">          <h1>Register</h1>       </div>       <div class="input-frame">          <label for="firstName">First Name:</label>          <input name="firstName" id="firstName" type="text"             class="required" />       </div>       <div class="input-frame">          <label for="lastName">Last Name:</label>          <input name="lastName" id="lastName" type="text"             class="required" />       </div>       <div class="input-frame">          <label for="email">Email:</label>          <input name="email" id="email" type="text"             class="required email" />       </div>       <div class="input-frame">          <label for="number">Telephone:</label>          <input name="number" id="number" type="text"             class="number" />       </div>       <div class="input-frame">          <label for="dob">Date of Birth:</label>          <input name="dob" id="dob" type="text"             class="required date"             placeholder="DD/MM/YYYY"/>       </div>       <div class="input-frame">          <label for="creditCard">Credit Card #:</label>          <input name="creditCard" id="creditCard"             type="text" class="required credit-card" />       </div>       <div class="input-frame">          <label for="password">Password:</label>          <input name="password" id="password"             type="password" class="required" />       </div>       <div class="input-frame">          <label for="confirmPassword">Confirm             Password:</label>             <input name="confirmPassword"                id="confirmPassword" type="password"                class="required" />       </div>       <div class="actions">          <button class="submit-btn">Submit</button>       </div>    </form> </body> </html> Create a CSS file named styles.css in the same directory and add the following CSS code to add style to our HTML page and form: @import url(http: //fonts.googleapis.com/css?family=Ubuntu); body {    background-color: #FFF;    font-family: 'Ubuntu', sans-serif; } form {    width: 500px;    padding: 20px;    background-color: #333;    border-radius: 5px;    margin: 10px auto auto auto;    color: #747474;    border: solid 2px #000; } form label {    font-size: 14px;    line-height: 30px;    width: 27%;    display: inline-block;    text-align: right; } .input-frame {    clear: both;    margin-bottom: 25px;    position: relative; } form input {    height: 30px;    width: 330px;    margin-left: 10px;    background-color: #191919;    border: solid 1px #404040;    padding-left: 10px;    color: #DB7400; } form input:hover {    background-color: #262626; } form input:focus {    border-color: #DB7400; } form .header {    margin: -20px -20px 25px -20px;    padding: 10px 10px 10px 20px;    position: relative;    background-color: #DB7400;    border-top-left-radius: 4px;    border-top-right-radius: 4px; } form .header h1 {    line-height: 50px;    margin: 0px;    padding: 0px;    color: #FFF;    font-weight: normal; } .actions {    text-align: right; } .submit-btn {    background-color: #DB7400;    border: solid 1px #000;    border-radius: 5px;    color: #FFF;    padding: 10px 20px 10px 20px;    text-decoration: none;    cursor: pointer; } .error input {    border-color: red; } .error-data {    color: red;    font-size: 11px;    position: absolute;    bottom: -15px;    left: 30%; } In addition to the jQuery library, the previous HTML page also uses another JavaScript file. Create a blank JavaScript file in the directory where the index.html file is saved. Save this file as validation.js and add the following JavaScript code: $(function(){    $('.submit-btn').click(function(event){       //Prevent form submission       event.preventDefault();       var inputs = $('input');       var isError = false;       //Remove old errors       $('.input-frame').removeClass('error');       $('.error-data').remove();       for (var i = 0; i < inputs.length; i++) {          var input = inputs[i];          if ($(input).hasClass('required') &&             !validateRequired($(input).val())) {             addErrorData($(input), "This is a required             field");             isError = true;          }         }       if (isError === false) {          //No errors, submit the form          $('#webForm').submit();       }    }); });   function validateRequired(value) {    if (value == "") return false;    return true; }   function addErrorData(element, error) {    element.parent().addClass("error");    element.after("<div class='error-data'>" + error + "</div>"); } Open index.html in a web browser and you should see a form similar to the following screenshot: If you click on the Submit button to submit an empty form, you will be presented with error messages under the required fields. How it works… Now, let us understand the steps performed previously in detail. HTML The HTML creates a web form with various fields that will take a range of data inputs, including text, date of birth, and credit card number. This page forms the basis for most of this article. Each of the input elements has been given different classes depending on what type of validation they require. For this recipe, our JavaScript will only look at the required class, which indicates a required field and therefore cannot be blank. Other classes have been added to the input fields, such as date and number, which will be used in the later recipes in this article. CSS Basic CSS has been added to create an attractive web form. The CSS code styles the input fields so they blend in with the form itself and adds a hover effect. The Google Web Font Ubuntu has also been used to improve the look of the form. jQuery The first part of the jQuery code is wrapped within $(function(){});, which will ensure the code is executed on page load. Inside this wrapper, we attach a click event handler to the form submit button, shown as follows: $(function(){     $('.submit-btn').click(function(event){         //Prevent form submission         event.preventDefault();             }); }); As we want to handle the form submission based on whether valid data has been provided, we use event.preventDefault(); to initially stop the form from submitting, allowing us to perform the validation first, shown as follows: var inputs = $('input'); var isError = false; After the preventDefault code, an inputs variable is declared to hold all the input elements within the page, using $('input') to select them. Additionally, we create an isError variable, setting it to false. This will be a flag to determine if our validation code has discovered an error within the form. These variable declarations are shown previously. Using the length of the inputs variable, we are able to loop through all of the inputs on the page. We create an input variable for each input that is iterated over, which can be used to perform actions on the current input element using jQuery. This is done with the following code: for (var i = 0; i < inputs.length; i++) { var input = inputs[i]; } After the input variable has been declared and assigned the current input, any previous error classes or data is removed from the element using the following code: $(input).parent().removeClass('error'); $(input).next('.error-data').remove(); The first line removes the error class from the input's parent (.input-frame), which adds the red border to the input element. The second line removes the error information that is displayed under the input if the validation check has determined that this input has invalid data. Next, jQuery's hasClass() function is used to determine if the current input element has the required class. If the current element does have this class, we need to perform the required validation to make sure this field contains data. We call the validateRequired() function within the if statement and pass through the value of the current input, shown as follows: if ($(input).hasClass('required') && !validateRequired($(input).val())) { addErrorData($(input), "This is a required field");    isError = true; } We call the validateRequired() function prepended with an exclamation mark to check to determine if this function's results are equal to false; therefore, if the current input has the required class and validateRequired() returns false, the value of the current input is invalid. If this is the case, we call the addErrorData() function inside the if statement with the current input and the error message, which will be displayed under the input. We also set the isError variable to true, so that later on in the code, we will know a validation error occurred. The JavaScript's for loop will repeat these steps for each of the selected input elements on the page. After the for loop has completed, we check if the isError flag is still set to false. If so, we use jQuery to manually submit the form, shown as follows: if (isError === false) {    //No errors, submit the form    $('#webForm').submit(); } Note that the operator === is used to compare the variable type of isError (that is, Boolean) as well as its value. At the bottom of the JavaScript file, we declare our two functions that have been called earlier in the script. The first function, validateRequired(), simply takes the input value and checks to see if it is blank or not. If the value is blank, the function returns false, meaning validation failed; otherwise, the function returns true. This can be coded as follows: function validateRequired(value) {     if (value == "") return false;     return true; } The second function used is the addErrorData() function, which takes the current input and an error message. It uses jQuery's addClass() function to add the error class to the input's parent, which will display the red border on the input element using CSS. It then uses jQuery's after() function to insert a division element into the DOM, which will display the specified error message under the current input field, shown as follows: function validateRequired(value) {    if (value == "") return false;    return true; } function addErrorData(element, error) {    element.parent().addClass("error");    element.after("<div class='error-data'>" + error + "</div>"); } There's more... This structure allows us to easily add additional validation to our web form. Because the JavaScript is iterating over all of the input fields in the form, we can easily check for additional classes, such as date, number, and credit-card, and call extra functions to provide the alternative validation. The other recipes in this article will look in detail at the additional validation types and add these functions to the current validation.js file. See also Implementing input character restrictions Adding number validation When collecting data from a user, there are many situations when you will want to only allow numbers in a form field. Examples of this could be telephone numbers, PIN codes, or ZIP codes, to name a few. This recipe will show you how to validate the telephone number field within the form we created in the previous recipe. Getting ready Ensure that you have completed the previous recipe and have the same files available. Open validation.js in your text editor or IDE of choice. How to do it… Add number validation to the form you created in the previous recipe by performing the following steps: Update validation.js to be as follows, adding the valdiateNumber() function with an additional hasClass('number') check inside the for loop: $(function(){    $('.submit-btn').click(function(event){       //Prevent form submission       event.preventDefault();       var inputs = $('input');       var isError = false;       //Remove old errors       $('.input-frame').removeClass('error');       $('.error-data').remove();       for (var i = 0; i < inputs.length; i++) {          var input = inputs[i];            if ($(input).hasClass('required') &&             !validateRequired($(input).val())) {                addErrorData($(input), "This is a required                   field");                isError = true;             } /* Code for this recipe */          if ($(input).hasClass('number') &&             !validateNumber($(input).val())) {                addErrorData($(input), "This field can only                   contain numbers");                isError = true;             } /* --- */         }       if (isError === false) {          //No errors, submit the form          $('#webForm').submit();       }    }); });   function validateRequired(value) {    if (value == "") return false;    return true; }   /* Code for this recipe */ function validateNumber(value) {    if (value != "") {       return !isNaN(parseInt(value, 10)) && isFinite(value);       //isFinite, in case letter is on the end    }    return true; } /* --- */ function addErrorData(element, error) {    element.parent().addClass("error");    element.after("<div class='error-data'>" + error + "</div>"); } Open index.html in a web browser, input something other than a valid integer into the telephone number field, and click on the Submit button. You will be presented with a form similar to the following screenshot: How it works… First, we add an additional if statement to the main for loop of validation.js to check to see if the current input field has the class number, as follows: if ($(input).hasClass('number') &&    !validateNumber($(input).val())) {    addErrorData($(input), "This field can only contain numbers");    isError = true; } If it does, this input value needs to be validated for a number. To do this, we call the validateNumber function inline within the if statement: function validateNumber(value) {    if (value != "") {       return !isNaN(parseInt(value, 10)) && isFinite(value);       //isFinite, in case letter is on the end    }    return true; } This function takes the value of the current input field as an argument. It first checks to see if the value is blank. If it is, we do not need to perform any validation here because this is handled by the validateRequired() function from the first recipe of this article. If there is a value to validate, a range of actions are performed on the return statement. First, the value is parsed as an integer and passed to the isNaN() function. The JavaScript isNaN() function simply checks to see if the provided value is NaN (Not a Number). In JavaScript, if you try to parse a value as an integer and that value is not actually an integer, you will get the NaN value. The first part of the return statement is to ensure that the provided value is a valid integer. However, this does not prevent the user from inputting invalid characters. If the user was to input 12345ABCD, the parseInt function would ignore ABCD and just parse 12345, and therefore the validation would pass. To prevent this situation, we also use the isFinite function, which returns false if provided with 12345ABCD. Adding credit card number validation Number validation could be enough validation for a credit card number; however, using regular expressions, it is possible to check for number combinations to match credit card numbers from Visa, MasterCard, American Express, and more. Getting ready Make sure that you have validation.js from the previous two recipes in this article open and ready for modification. How to do it… Use jQuery to provide form input validation for credit card numbers by performing the following step-by-step instructions: Update validation.js to add the credit card validation function and the additional class check on the input fields: $(function(){    $('.submit-btn').click(function(event){       //Prevent form submission       event.preventDefault();       var inputs = $('input');       var isError = false;       for (var i = 0; i < inputs.length; i++) {   // -- JavaScript from previous two recipes hidden                       if ($(input).hasClass('credit-card') &&             !validateCreditCard($(input).val())) {             addErrorData($(input), "Invalid credit card                number");             isError = true;          }         } // -- JavaScript from previous two recipes hidden    }); });   // -- JavaScript from previous two recipes hidden   function validateCreditCard(value) {    if (value != "") {       return /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9]) [0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}| (?:2131|1800|35d{3})d{11})$/.test(value);    }    return true; } // -- JavaScript from previous two recipes hidden } Open index.html and input an invalid credit card number. You will be presented with the following error information in the form: How it works… To add credit card validation, as with the previous two recipes, we added an additional check in the main for loop to look for the credit-card class on the input elements, as follows: if ($(input).hasClass('credit-card') &&    !validateCreditCard($(input).val())) {    addErrorData($(input), "Invalid credit card number");    isError = true; } The validateCreditCard function is also added, which uses a regular expression to validate the input value, as follows: function validateCreditCard(value) {    if (value != "") {       return /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-          9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-          9]{13}|3(?:0[0-5]|[68][0-9])[0-          9]{11}|(?:2131|1800|35d{3})d{11})$/.test(value);    }    return true; } The first part of this function determines if the provided value is blank. If it isn't, the function will perform further validation; otherwise, it will return true. Most credit card numbers start with a prefix, which allows us to add additional validation to the inputted value on top of numeric validation. The regular expression used in this function will allow for Visa, MasterCard, American Express, Diners Club, Discover, and JCB cards. See also Adding number validation
Read more
  • 0
  • 0
  • 2025
article-image-adding-interactivity-and-completing-your-site
Packt
06 Dec 2012
7 min read
Save for later

Adding Interactivity and Completing Your Site

Packt
06 Dec 2012
7 min read
(For more resources related to this topic, see here.) Using jQuery HTML5 Boilerplate provides a handy and safe way to load jQuery. With jQuery, it is vastly simple to work on writing scripts to access elements. If you are writing custom jQuery script either to kick off a plugin you are using or to do some small interaction, put it in the main.js file in the js folder. Using other libraries If you are more comfortable using other libraries, you can also load and use them in a similar way to jQuery. The following is how we load jQuery: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min. js"></script> <script>window.jQuery || document.write('<script src="js/vendor/ jquery-1.8.2.min.js"></script>') </script> Let us say, you want to use another library (like MooTools ), then look up the Google Libraries API to see if that library is available at developers.google.com/speed/libraries/. If it is available, just replace the reference with the appropriate reference from the site. For example, if we want to replace our jQuery link with a link to MooTools, we would simply replace the following code: <script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min. js"> </script> With the following line of code: <script src="ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootoolsyui- compressed.js"> </script> We will also download Mootools' minified file to the js/vendor folder locally and replace the following code: <script>window.jQuery||document.write('<script src="js/vendor/jquery- 1.7.2.min.js"></script>') </script> With the following line of code: <script>window.jQuery||document.write('<script src="js/vendor/ mootools-core-1.4.5-full-compat-yc.js"></script>') </script> Adding smooth-scroll plugin and interaction If you have not noticed it already, the website we are building is a single page site! All content that is required is found on the same page. The way our site is currently designed, it would mean clicking on one of the site navigation links would scroll roughly to the section that the navigation link refers to. We would like this interaction to be smooth. Let us use jQuery's smooth-scroll plugin to provide this. Let us download the plugin file from the Github repository, hosted on github.com/kswedberg/jquery-smooth-scroll. In it, we find a minimized version of the plugin (jquery.smooth-scroll.min.js) that we shall open in our text editor. Then copy all the code and paste it within the plugins.js file. Let us add a class name js-scrollitem to let us distinguish that this element has a script that will be used on those elements. This way, there will be a lesser chance of accidentally deleting class names that are required for interactions prompted via JavaScript. Now, we shall write the code to invoke this plugin in the main.js file. Open the main.js file in your text editor and type: $('.js-scrollitem').smoothScroll(); This will make all the clickable links that link to sections on the same page within the parent container with class js-scrollitem scroll smoothly with the help of the plugin. If we have used our HTML5 Boilerplate defaults correctly, adding this will be more than sufficient to get started with smooth scrolling. Next, we would like the navigation links in the line up section to open the right-hand side line up depending on which day was clicked on. Right now, in the following screenshot, it simply shows the line up for the first day, and does not do anything else: Let us continue editing the main.js file and add in the code that would enable this. First, let's add the class names that we will use to control the styling, and the hiding/showing behavior within our code. The code for this functionality is as follows: <nav class="t-tab__nav"> <a class="t-tab__navitem--active t-tab__navitemjs-tabitem" href="#day- 1">Day 1</a> <a class="t-tab__navitemjs-tabitem" href="#day-2">Day 2</a> </nav> Now, we shall write the code that will show the element we clicked on. This code is as follows: var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; $navlinks.click(function() { // our code for showing or hiding the current day's line up $(this.hash).removeClass(hiddenClass); }); By checking how we have done so far, we notice it keeps each day's line up always visible and does not hide them once done! Let us add that too, as shown in the following code snippet: var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; var $lastactivetab = null; $navlinks.click(function() { var $this = $(this); //take note of what was the immediately previous tab and tab nav that was active $lastactivetab = $lastactivetab || $tabs.not('.' + hiddenClass); // our code for showing or hiding the current day's line up $lastactivetab.addClass(hiddenClass); $(this.hash).removeClass(hiddenClass); $lastactivetab = $(this.hash); return false; } You would notice that the active tab navigation item still seems to suggest it is Day 1! Let us fix that by changing our code to do something similar with the tabbed navigation anchors, as shown in the following code snippet: var $navlinks = $('#lineup .js-tabitem'); var $tabs = $('.t-tab__body'); var hiddenClass = 'hidden'; var activeClass = 't-tab__navitem--active'; var $lastactivetab = null; var $lastactivenav = null; $navlinks.click(function() { var $this = $(this); //take note of what was the immediately previous tab and tab nav that was active $lastactivetab = $lastactivetab || $tabs.not('.' + hiddenClass); $lastactivenav = $lastactivenav || $navlinks.filter('.' + activeClass); // our code for showing or hiding the current day's line up $lastactivetab.addClass(hiddenClass); $(this.hash).removeClass(hiddenClass); $lastactivetab = $(this.hash); // change active navigation item $lastactivenav.removeClass(activeClass); $this.addClass(activeClass); $lastactivenav = $this; return false; }); Bingo! We have our day-by-day line up ready. We now need to ensure our Google Maps iframe renders when users click on the Locate on a map link. We also want to use the same link to hide the map if the users want to do so. First, we add some identifiable features to the anchor element used to trigger the showing/hiding of map and the iframe for the maps, as shown in the following code snippet: <p>The festival will be held on the beautiful beaches of NgorTerrouBi in Dakar.<ahref="#" class="js-map-link">Locate it on a map</a></p><iframe id="venue-map" class="hidden" width="425"height="350" frameborder="0" scrolling="no" marginheight="0"marginwidth="0" src="http://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=ngor+terrou+bi,+dakar,+senegal&;aq=&sll=37.0625,-95.677068&sspn=90.404249,95.976562&ie=UTF8&hq=ngor&hnear=Terrou-Bi,+Bd+Martin+Luther+King,+Gueule+Tapee,+Dakar+Region,+Guediawaye,+Dakar+221,+Senegal&t=m&amp;fll=14.751996,-17.513559&fspn=0.014276,0.011716&st=109146043351405611748&rq=1&ev=p&split=1&ll=14.711109,-17.483921&spn=0.014276,0.011716&output=embed"></iframe> Then we use the following JavaScript to trigger the link: $maplink = $('.js-map-link'); $maplinkText = $maplink.text(); $maplink.toggle(function() { $('#venue-map').removeClass(hiddenClass); $maplink.text('Hide Map'); }, function() { $('#venue-map').addClass(hiddenClass); $maplink.text($maplinkText); });
Read more
  • 0
  • 0
  • 2018

article-image-creating-your-own-theme
Packt
13 Jun 2013
5 min read
Save for later

Creating Your Own Theme

Packt
13 Jun 2013
5 min read
(For more resources related to this topic, see here.) Starting with a new layout Before we start creating a concrete5 theme we need a layout. In this article, we're going to use a simple layout without any pictures to keep the code as short as possible—it's about concrete5, not about HTML and CSS. If you don't have the time for an exercise, you can use your own layout. With good knowledge about the basic technologies of concrete5, you should be able to amend the instructions in this article to match your own layout. If you don't feel very comfortable working with PHP you should probably use the printed HTML code in this article. Here's a screenshot of what our site is going to look like once we've finished our theme: While this layout isn't very pretty, it has an easy structure; navigation on top and a big content area where we can insert any kind of block we want. In case you're using your own layout, try to use one with a simple structure; navigation on top or on the left with one big place for the content, and try to avoid Flash. The HTML code Let's have a look at the HTML code: <!DOCTYPE html><html lang="en"><head><title>concrete5 Theme</title><meta http-equiv="Content-Type" content="text/html;charset=utf-8" /><style type="text/css" media="screen">@import "main.css";</style></head><body><div id="wrapper"><div id="page"><div id="header_line_top"></div><div id="header"><ul class="nav-dropdown"><li><a href="#">Home</a></li><li><a href="#">Test</a></li><li><a href="#">About</a></li></ul></div><div id="header_line_bottom"></div><div id="content"><p>Paragraph 1</p><p>Paragraph 2</p><p>Paragraph 3</p></div><div id="footer_line_top"></div><div id="footer"></div><div id="footer_line_bottom"></div></div></div></body></html> There are three highlighted lines in the preceding code: The CSS import: This is to keep the layout instructions separated from the HTML elements; we've got all the CSS rules in a different file named main.css. This is also how almost all concrete5 themes are built. The header block contains the navigation. As we're going to apply some styles to it, make sure it has its own ID. Using an ID also improves the performance when using CSS and JavaScript to access an element, as an ID is unique. The same applies to the content block. Make sure it has a unique ID. Most web technologies we use nowadays are standardized in one way or another. Currently, the most important organization is W3C. They also offer tools to validate your code. Checking your code is never a bad idea. Navigate to http://validator.w3.org/ and enter the address of the website you want to check or in this case, as your website isn't accessible by the public, click on Validate by Direct Input and paste the HTML code to see if there are any mistakes. While it should be fairly easy to produce valid HTML code, things are a bit tricky with CSS. Due to some old browser bugs, you're often forced to use invalid CSS rules. There's often a way to rebuild the layout to avoid some invalid rules but often this isn't the case—you won't be doomed if something isn't 100 percent valid but you're on the safer side if it is. CSS rules As mentioned earlier, all CSS rules are placed in a file named main.css. Let's have a look at all CSS rules you have to put in our CSS file: /* global HTML tag rules */html, body, div, pre, form, fieldset, input, h1, h2, h3, h4, h5, h6,p, textarea, ul, ol, li, dl, dt, dd, blockquote, th, td {margin: 0;padding: 0;}p {margin: 5px 0px 15px 0px;}html {height: 100%;}body {background-color: #989898;height: 100%;}/* layout rules */#wrapper {margin: 0 auto;width: 980px;text-align: left;padding-top: 35px;}#page {background: #FFFFFF;float: left;width: 960px;padding: 5px;-moz-box-shadow: 0 0 15px black;-webkit-box-shadow: 0 0 15px black;box-shadow: 0 0 15pxblack;border-radius: 10px;}/* header */#header {background: #262626;border-radius: 10px 10px 0px 0px;height: 75px;}#header_line_top {background: #262626;height: 0px;}#header_line_bottom {background: #e64116;height: 3px;}/* content */#content {min-height: 300px;padding: 30px;color: #1E1E1E;font-family: verdana, helvetica, arial;font-size: 13px;line-height: 22px;}/* footer */#footer {background: #262626;height: 75px;border-radius: 0px 0px 10px 10px;}#footer_line_top {background: #e64116;height: 3px;}#footer_line_bottom {background: #262626;height: 0px;}/* header navigation */#header ul{margin: 0px;padding: 20px;}#header ul li {float: left;list-style-type: none;}#header ul li a {margin-right: 20px;display: block;padding: 6px 15px 6px 15px;color: #ccc;text-decoration: none;font-family: verdana, helvetica, arial;}#header ul li a:hover {color: white;}
Read more
  • 0
  • 0
  • 2015

article-image-foundation
Packt
19 Aug 2014
22 min read
Save for later

Foundation

Packt
19 Aug 2014
22 min read
In this article by Kevin Horek author of Learning Zurb Foundation, we will be covering the following points: How to move away from showing clients wireframes and how to create responsive prototypes Why these prototypes are better and quicker than doing traditional wireframes The different versions of Foundation What does Foundation include? How to use the documentation How to migrate from an older version Getting support when you can't figure something out What browsers does Foundation support? How to extend Foundation Our demo site (For more resources related to this topic, see here.) Over the last couple of years, showing wireframes to most clients has not really worked well for me. They never seem to quite get it, and if they do, they never seem to fully understand all the functionality through a wireframe. For some people, it is really hard to picture things in their head, they need to see exactly what it will look and function like to truly understand what they are looking at. You should still do a rough wireframe either on paper, on a whiteboard, or on the computer. Then once you and/or your team are happy with these rough wireframes, then jump right into the prototype. Rough wireframing and prototypying You might think prototyping this early on when the client has only seen a sitemap is crazy, but the thing is, once you master Foundation, you can build prototypes in about the same time you would spend doing traditional high quality wireframes in Illustrator or whatever program you currently use. With these prototypes, you can make things clickable, interactive, and super fast to make edits to after you get feedback from the client. With the default Foundation components, you can work out how things will work on a phone, tablet, and desktop/laptop. This way you can work with your team to fully understand how things will function and start seeing where the project's potential issues will be. You can then assign people to start dealing with these potential problems early on in the process. When you are ready to show the client, you can walk them through their project on multiple devices and platforms. You can easily show them what content they are going to need and how that content will flow and reflow based on the medium the user is viewing their project on. You should try to get content as early as possible; a lot of companies are hiring content strategists. These content strategists handle working with the client to get, write, and rework content to fit in the responsive web medium. This allows you to design around a client's content, or at least some of the content. We all know that what a client says they will get you for content is not always what you get, so you may need to tweak the design to fit the actual content you get. Making these theming changes to accommodate these content changes can be a pain, but with Foundation, you can just reflow part of the page and try some ideas out in the prototype before you put them back into the working development site. Once you have built up a bunch of prototypes, you can easily combine and use parts of them to create new designs really fast for current or new projects. When prototyping, you should keep everything grayscale, without custom fonts, or a theme beyond the base Foundation one. These prototypes do not have to look pretty. The less it looks like a full design, the better off you will be. You will have to inform your client that an actual design for their project will be coming and that it will be done after they sign off this prototype. When you show the client, you should bring a phone, a tablet, and a laptop to show them how the project will flow on each of these devices. This takes out all the confusion about what happens to the layouts on different screen sizes and on touch and non-touch devices. It also allows your client and your team to fully understand what they are building and how everything works and functions. Trying to take a PDF of wireframes, a Photoshop file, and trying to piece them together to build a responsive web project can be really challenging. With this approach, so many details can get lost in translation, you have to keep going back to talk to the client or your team about how certain things should work or function. Even worse, you have to make huge changes to a section close to the end of the project because something was designed without being really thought through and now your developers have to scramble to make something work within the budget. Prototyping can sort out all the issues or at least the major issues that could arise in the project. With these Foundation prototypes, you keep building on the code for each step of the web building process. Your designer can work with your frontend/backend team to come up with a prototype that everyone is happy with and commit to being able to build it before the client sees anything. If you are familiar with version control, you can use it to keep track of your prototypes and collaborate with another person or a team of people. The two most popular version control software applications are Git (http://git-scm.com/) and Subversion (http://subversion.apache.org/). Git is the more popular of the two right now; however, if you are working on a project that has been around for a number of years, chances are that it will be in Subversion. You can migrate from one to the other, but it might take a bit of work. These prototypes keep your team on the same page right from the beginning of the project and allow the client to sign off on functionality and how the project will work on different mediums. Yes, you are spending more time at the beginning getting everyone on the same page and figuring out functionality early on, but this process should sort out all the confusion later in a project and save you time and money at the end of the project. When the client has changes that are out of scope, it is easy to reference back to the prototype and show them how that change will impact what they signed off on. If the change is major enough then you will need to get them a cost on making that change happen. You should test your prototypes on an iPhone, an Android phone, an iPad, and your desktop or laptop. I would also figure out what browser your client uses and make sure you test on that as well. If they are using an older version of IE, 8 or earlier, you will need to have the conversation with them about how Foundation 4+ does not support IE8. If that support is needed, you will have to come up with a solution to handle this outdated version of IE. Looking at a client's analytics to see what versions of IE their clients are coming to the project with will help you decide how to handle older versions of IE. Analytics might tell you that you can drop the version all together. Another great component that is included with Foundation is Modernizr (http://modernizr.com/); this allows you to write conditional JS and/or CSS for a specific situation or browser version. This really can be a lifesaver. Prototyping smaller projects While you are learning Foundation, you might think that using Foundation on a smaller project will eat up your entire budget. However, these are the best projects to learn Foundation. Basically, you take the prototype to a place where you can show a client the rough look and feel using Foundation. Then, you create a theme board in Photoshop with colors, fonts, photos and anything else to show the client. This first version will be a grayscale prototype that will function across multiple screen sizes. Then you can pull up your theme board to show the direction you are thinking of for the look and feel. If you still feel more comfortable doing your designs in Photoshop, there are some really good Photoshop grid templates at http://www.yeedeen.com/downloads/category/30-psd. If you want to create a custom grid that you can take a screenshot of, then paste into Photoshop, and then drag your guidelines over the grid to make your own template, you can refer to http://www.gridlover.net/foundation/. Prototyping wrap-up These methods are not perfect and may not always work for you, but you're going to see my workflow and how Foundation can be used on all of your web projects. You will figure out what will work with your clients, your projects, and your workflow. Also, you might have slightly different workflows based on the type of project, and/or project budget. If the client does not see value in having a responsive site, you should choose if you want to work with these types of clients. The Web is not one standard resolution anymore and it never will be again, so if a client does not understand that, you might want to consider not working with them. These types of clients are usually super hard to work with and your time is better spent on clients that get or are willing to allow you to teach them and trust you that you are building their project for the modern Web. Personally, clients that have fought with me to not be responsive usually come back a few months later wondering why their site does not work great on their new smartphone or tablet and wanting you to fix it. So try and address this up front and it will save you grief later on and make your clients happier and their experience better. Like anything, there are exceptions to this but just make sure you have a contract in place to outline that you are not building this as responsive, and that it could cause the client a lot of grief and costs later to go back and make it responsive. No matter what you do for a client, you should have a contract in place, this will just make sure you both understand what is each party responsible for. Personally, I like to use a modified version of, (https://gist.github.com/malarkey/4031110). This contract does not have any legal mumbo jumbo that people do not understand. It is written in plain English and has a little bit of a less serious tone. Now that we have covered why prototyping with Foundation is faster than doing wireframes or prototypes in Photoshop, let's talk about what comes in the base Foundation framework. Then we will cover which version to install, and then go through each file and folder. Introducing the framework Before we get started, please refer to the http://foundation.zurb.com/develop/download.html webpage. You will see that there are four versions of Foundation: complete, essentials, custom, and SCSS. But let's talk about the other versions. The essentials is just a smaller version of Foundation that does not include all the components of the framework; this version is a barebones version. Once you are familiar with Foundation, you will likely only include the components that you need for a specific project. By only including the components you need, you can speed up the load time of your project and you do not make the user download files that are not being used by your project. The custom version allows you to pick the components and basic sizes, colors, radius, and text direction. You will likely use this or the SCSS version of Foundation once you are more comfortable with the framework. The SCSS or Sass version of Foundation is the most powerful version. If you do not know what Sass is, it basically gives you additional features of CSS that can speed up how you theme your projects. There is actually another version of Foundation that is not listed on this page, which can be found by hitting the blue Getting Started option in the top right-corner and then clicking on App Guide under Building and App. You can also visit this version at http://foundation.zurb.com/docs/applications.html. This version is the Ruby Gem version of Foundation, and unless you are building a Ruby on Rails project, you will never use this version of Foundation. Zurb keeps the gem pretty up to date, you will likely get the new version of the gem about a week or two after the other versions come out. Alright, let's get into Foundation. If you have not already, hit the blue Download Everything button below the complete heading on the webpage. We will be building a one page demo site from the base Foundation theme that you just downloaded. This way, you can see how to take what you are given by default and customize this base theme to look anyway you want it to. We will give this base theme a custom look and feel, and make it look like you are not using a responsive framework at all. The only way to tell is if you view the source of the website. The Zurb components have very little theming applied to them. This allows you to not have to worry about really overriding the CSS code and you can just start adding additional CSS to customize these components. We will cover how to use all the major components of the framework, you will have an advanced understanding of the framework and how you can use it on all your projects going forward. Foundation has been used on small-to-large websites, web apps, at startups, with content management systems, and with enterprise-level applications. Going over the base theme The base theme that you download is made up of an HTML index file, a folder of CSS files, JavaScript files, and an empty img folder for images, which are explained in the following points: The index.html file has a few Foundation components to get you started. You have three, 12- column grids at three screen sizes; small, medium, and large. You can also control how many columns are in the grid, and the spacing (also called the gutter) between the columns, and how to use the other grid options. You will soon notice that you have full control over pretty much anything and you can control how things are rendered on any screen size or device, and whether that device is in portrait or landscape. You also have the ability to render different code on different devices and for different screen sizes. In the CSS folder, there is the un-minified version of Foundation with the filename foundation.css. There is also a minified version of Foundation with the filename foundation.min.css. If you are not familiar with minification, it has the same code as the foundation.css file, just all the spacing, comments, and code formatting have been taken out. This makes the file really hard to read and edit, but the file size is smaller and will speed up your project's load time. Most of the time, minified files have all the code on one really long line. You should use the foundation.css file as reference but actually include the minified one in your project. The minified version makes debugging and error fixing almost impossible, so we use the un-minified version for development and then the minified version for production. The last file in that folder is normalize.css; this file can be called a reset file, but it is more of an alternative to a reset file. This file is used to try to set defaults on a bunch of CSS elements and tries to get all the browsers to be set to the same defaults. The thinking behind this is that every browser will look and render things the same, and, therefore, there should not be a lot of specific theming fixes for different browsers. These types of files do a pretty good job but are not perfect and you will have to do little fixes for different browsers, even the modern ones. We will also cover how to use some extra CSS to take resetting certain elements a little further than the normalize file does for you. This will mainly include showing you how to render form elements and buttons to be the same across-browser and device. We will also talk about, browser version, platform, OS, and screen resolution detection when we talk about testing. We will also be adding our own CSS file that we will add our customizations to, so if you ever decide to update the framework as a new version comes out, you will not have to worry about overriding your changes. We will never add or modify the core files of the framework; I highly recommend you do not do this either. Once we get into Sass, we will cover how you can really start customizing the framework defaults using the custom variables that are built right into Foundation. These variables are one of the reasons that Foundation is the most advanced responsive framework out there. These variables are super powerful and one of my favorite things about Foundation. Once you understand how to use variables, you can write your own or you can extend your setup of Foundation as much as you like. In the JS folder, you will find a few files and some folders. In the Foundation folder, you will find each of the JavaScript components that you need to make Foundation work properly cross-device, browser, and responsive. These JavaScript components can also be use to extend Foundation's functionality even further. You can only include the components that you need in your project. This allows you to keep the framework lean and can help with load times; this is especially useful on mobile. You can also use CSS to theme each of these components to be rendered differently on each device or at different screen sizes. The foundation.min.js file is a minified version of all the files in the Foundation folder. You can decide based on your needs whether you want to include only the JavaScripts you are using on that project or whether you want to include them all. When you are learning, you should include them all. When you are comfortable with the framework and are ready to make your project live, you should only include the JavaScripts you are actually using. This helps with load times and can make troubleshooting easier. Many of the Foundation components will not work without including the JavaScript for that component. The next file you will notice is jquery.js it might be either in the root of this folder or in the vendor folder if you are using a newer version of Foundation 5. If you are not familiar with jQuery, it is a JavaScript library that makes DOM manipulation, event handling, animation, and Ajax a lot easier. It also makes all of this stuff work cross-browser and cross-device. The next file in the JS folder or in the vendor folder under JS is modernizr.js; this file helps you to write conditional JavaScript and/or CSS to make things work cross-browser and to make progressive enhancements. Also, you put third-party JavaScript libraries that you are using on your project in the vendor folder. These are libraries that you either wrote yourself or found online, are not part of Foundation, and are not required for Foundation to work properly. Referring to the Foundation documentation The Foundation documentation is located at http://foundation.zurb.com/docs/. Foundation is really well documented and provides a lot of code samples and examples to use in your own projects. All the components also contain Sass variables that you can use to customize some of the defaults and even build your own. This saves you writing a bunch of override CSS classes. Each part of the framework is listed on the left-hand side and you can click on what you are looking for. You are taken to a page about that specific part and can read the section's overview, view code samples, working examples, and how to customize that part of the framework. Each section has a pretty good walk through about how to use each piece. Zurb is constantly updating Foundation, so you should check the change log every once in a while at http://foundation.zurb.com/docs/changelog.html. If you need documentation on an older version of Foundation, it is at the bottom of the documentation site in the left-hand column. Zurb keeps all the documentation back to Foundation 2. The only reason you will ever need to use Foundation 2 is if you need to support a really, really old version of IE, such as version 7. Foundation never supported IE6, but you will likely never have to worry about that version of IE. Migrating to a newer version of Foundation If you have an older version of Foundation, each version has a migration guide. The migration guide from Foundation 4 to 5 can be found at http://foundation.zurb.com/docs/upgrading.html. Personally, I have migrated websites and web apps in multiple languages and as long as Zurb does not change the grid, like they did from Foundation 3 to 4, then usually we copy-and-paste over the old version of the Foundation CSS, JavaScript, and images. You will likely have to change some JavaScript calls, do some testing, and do some minor fixes here and there, but it is usually a pretty smooth process as long as you did not modify the core framework or write a bunch of custom overrides. If you did either of these things, you will be in for a lot of work or a full rebuild of your project, so you should never modify the core. For old versions of Foundation, or if your version has been heavily modified, it might be easier to start with a fresh version of Foundation and copy-and-paste in the parts that you want to still use. Personally, I have done both and it really depends on the project. Before you do any migration, make sure you are using some sort of version control, such as GIT. If you do not know what GIT is, you should look into it. Here is a good place to start: (http://git-scm.com/book/en/Getting-Started) GIT has saved me from losing code so many times. If GIT is a little overwhelming right now, at the very least, duplicate your project folder as a backup and then copy in the new version of the framework over your files. If things are really broken, you can at least still use your old version while you work out the kinks in the new version. Framework support At some point, you will likely have questions about something in the framework, or will be trying to get something to work and for some reason, you can't figure it out. Foundation has multiple ways to get support, some of which are listed as follows: E-mail Twitter GitHub StackOverflow Forums To visit or get in-touch with support go to http://foundation.zurb.com/support/support.html. Browser support Foundation 5 supports the majority of browsers and devices, but like anything modern, it drops support for older browser versions. If you need IE8 or cringe, or IE7 support, you will need to use an older version of Foundation. You can see a full browser and device compatibility list at http://foundation.zurb.com/docs/compatibility.html. Extending Foundation Zurb also builds a bunch of other components that usually make their way into Foundation at some point, and work well with Foundation even though they are not officially part of it. These components range from new JavaScript libraries, fonts, icons, templates, and so on. You can visit their playground at http://zurb.com/playground. This playground also has other great resources and tools that you can use on other projects and other mediums. The things at Zurb's playground can make designing with Foundation a lot easier, even if you are not a designer. It can take quite a while to find icons or make them into SVGs or fonts for use in your projects, but Zurb has provided these in their playground. Overview of our one-page demo website The best way to show you how to learn the Zurb Foundation Responsive Framework is to actually get you building a demo site along with me. You can visit the final demo site we will be building at http://www.learningzurbfoundation.com/demo. We will be taking the base starter theme that we downloaded and making a one-page demo site. The demo site is built to teach you how to use the components and how they work together. You can also add outside components, but you can try those on your own. The demo site will show you how to build a responsive website, and it might not look like an ideal site, but I am trying to use as many components as possible to show you how to use the framework. Once you complete this site, you will have a deep understanding of the framework. You can then use this site as a starter theme or at the very least, as a reference for all your Foundation projects going forward. Summary In this article, we covered how to rough wireframe and quickly moved into prototyping. We also covered the following points: We went over what is included in the base Foundation theme Explored the documentation and how to migrate Foundation versions How to get framework support Started to get you thinking about browser support Letting you know that you can extend Foundation beyond its defaults We quickly covered our one-page demo site Resources for Article: Further resources on this subject: Quick start – using Foundation 4 components for your first website [Article] Zurb Foundation – an Overview [Article] Best Practices for Modern Web Applications [Article]
Read more
  • 0
  • 0
  • 2014
article-image-need-directives
Packt
22 Aug 2013
7 min read
Save for later

The Need for Directives

Packt
22 Aug 2013
7 min read
(For more resources related to this topic, see here.) What makes a directive a directive Angular directives have several distinguishing features, but for the sake of simplicity we'll focus on just three in this article. In contrast to most plugins or other forms of drop-in functionality, directives are declarative, data driven, and conversational. Directives are declarative If you've done any JavaScript development before, you've almost certainly used jQuery (or perhaps Prototype), and likely one of the thousands of plugins available for it. Perhaps you've even written your own such plugin. In either case, you probably have a decent understanding of the flow required to integrate it. They all look something like the following code: $(document).ready(function() { $('#myElement').myPlugin({pluginOpts});}); In short, we're finding the DOM element matching #myElement, then applying our jQuery plugin to it. These frameworks are built from the ground up on the principle of DOM manipulation. In contrast, Angular directives are declarative, meaning we write them into the HTML elements themselves. Declarative programming means that instead of telling an object how to behave (imperative programming), we describe what an object is. So, where in jQuery we might grab an element and apply certain properties or behaviors to it, with Angular we label that element as a type of directive, and, elsewhere, maintain code that defines what properties and behaviors make up that type of object: <html> <body> <div id="myElement" my-awesome-directive></div> </body></html> At a first glance, this may seem rather pedantic, merely a difference in styles, but as we begin to make our applications more complex, this approach serves to streamline many of the usual development headaches. In a more fully developed application, our messages would likely be interactive, and in addition to growing or shrinking during the course of the user's visit, we'd want them to be able to reply to some or retweet themselves. If we were to implement this with a DOM manipulation library (such as jQuery or Prototype), that would require rebuilding the HTML with each change (assuming you want it sorted, just using .append() won't be enough), and then rebinding to each of the appropriate elements to allow the various interactions. In contrast, if we use Angular directives, this all becomes much simpler. As before, we use the ng-repeat directive to watch our list and handle the iterated display of tweets, so any changes to our scoped array will automatically be reflected within the DOM. Additionally, we can create a simple tweet directive to handle the messaging interactions, starting with the following basic definition. Don't worry right now about the specific syntax of creating a directive; for now just take a look at the overall flow in the following code: angular.module('myApp', []) .directive('tweet', ['api', function (api) { return function ($scope, $element, $attributes) { $scope.retweet = function () { api.retweet($scope.tweet);// Each scope inherits from it's parent, so we still have access to the full tweet object of { author : '…', text : '…' } }; $scope.reply = function () { api.replyTo($scope.tweet); }; } }]); For now just know that we're getting an instance of our Twitter API connection and passing it into the directive in the variable api, then using that to handle the replies and retweets. Our HTML for each message now looks like the following code: <p ng-repeat="tweet in tweets" tweet> <!-- ng-click allows us to bind a click event to a function on the $scope object --> @{{tweet.author}}: {{tweet.text}} <span ng-click="retweet()">RT</span> | <span ng-click="reply()">Reply</span></p> By adding the tweet attribute to the paragraph tag, we tell Angular that this element should use the tweet directive, which gives us access to the published methods, as well as anything else we later decide to attach to the $scope object. Directives in Angular can be declared in multiple ways, including classes and comments, though attributes are the most common. Scoping within directives is simultaneously one of the most powerful and most complicated features within Angular, but for now it's enough to know that every property and function we attach to the scope is accessible to us within the HTML declarations. Directives are data driven Angular directives are built from the ground up with this philosophy. The scope and attribute objects accessible to each directive form the skeleton around which the rest of a directive is built and can be monitored for changes both within the DOM as well as the rest of your JavaScript code. What this means for developers is that we no longer have to constantly poll for changes, or ensure that every data change that might have an impact elsewhere within our application is properly broadcast. Instead, the scope object handles all data changes for us, and because directives are declarative as well, that data is already connected to the elements of the view that need to update when the data changes. There's a proposal for ECMAScript 6 to support this kind of data watching natively with Object.observe(), but until that is implemented and fully supported, Angular's scope provides the much needed intermediary. Directives are conversational Modular coding emphasizes the use of messages to communicate between separate building blocks within an application. You're likely familiar with DOM events, used by many plugins to broadcast internal changes (for example, save, initialized, and so on) and subscribe to external events (for example, click, focus, and so on). Angular directives have access to all those events as well (the $element variable you saw earlier is actually a jQuery wrapped DOM element), but $scope also provides an additional messaging system that functions only along the scope tree. The $emit and $broadcast methods serve to send messages up and down the scope tree respectively, and like DOM events, allow directives to subscribe to changes or events within other parts of the application, while still remaining modular and uncoupled from the specific logic used to implement those changes. If you don't have jQuery included in your application, Angular wraps the element in jqLite, which is a lightweight wrapper that provides the same basic methods. Additionally, when you add in the use of Angular services, directives gain an even greater vocabulary. Services, among many other things, allow you to share specific pieces of data between the different pieces of your application, such as a collection of user preferences or utility mapping item codes to their names. Between this shared data and the messaging methods, separate directives are able to communicate fully with each other without requiring a retooling of their internal architecture. Directives are everything you've dreamed about Ok, that might be a bit of hyperbole, but you've probably noticed by now that the benefits outlined so far here are exactly in line with the best practices. One of the most common criticisms of Angular is that it's relatively new (especially compared to frameworks such as Backbone and Ember). In contrast, however, I consider that to be one of its greatest assets. Older frameworks all defined themselves largely before there was a consensus on how frontend web applications should be developed. Angular, on the other hand, has had the advantage of being defined after many of the existing best practices had been established, and in my opinion provides the cleanest interface between an application's data and its display. As we've seen already, directives are essentially data driven modules. They allow developers to easily create a packageable feature that declaratively attaches to an element, molds to fit the data at its disposal, and communicates with the other directives around it to ensure coordinated functionality without disruption of existing features. Summary In this article, we learned about what attributes define directives and why they're best suited for frontend development, as well as what makes them different from the JavaScript techniques and packages you've likely used before. I realize that's a bold statement, and likely one that you don't fully believe yet. Resources for Article: Further resources on this subject: Using jQuery and jQueryUI Widget Factory plugins with RequireJS [Article] So, what is EaselJS? [Article] So, what is KineticJS? [Article]
Read more
  • 0
  • 0
  • 2012

article-image-getting-started-with-rapidweaver
Packt
09 Sep 2012
7 min read
Save for later

Getting Started withRapidWeaver

Packt
09 Sep 2012
7 min read
In this article by Joe Workman, the author of RapidWeaver Beginner's Guide, we will learn the basics of RapidWeaver. Mainly, we will cover the following topics: What is RapidWeaver? Installing RapidWeaver Creating our first web page Publishing our website on the Internet So strap your seat belts on and let's have some fun! What is RapidWeaver? RapidWeaver is a web development and design application for Mac that was developed by Realmac Software. It allows you to build stunning, professional websites very easily. RapidWeaver has both the novice and professional web designer covered. If you don't know (or don't want to know) how to code, RapidWeaver supports full code-free creation of your website; from blogs to site maps, photo albums to contact forms, you can build your entire website without a single line of code! Without a doubt, RapidWeaver appeals to the aspiring novice web designer. However, it does not forget about the geeky, code loving, power users! And in case you were wondering…yeah, that includes me! RapidWeaver gives us geeks full access to peek under the hood. You can effortlessly add your own HTML or PHP file to any page. You can customize the look and feel with your own CSS file. For example, maybe you would like to add your own JavaScript for the latest and greatest animations out there; not a problem, RapidWeaver has got you covered. We even have full access to the amazing WebKit Developer Tools from directly inside the application. As RapidWeaver has all of these advanced features, it really serves as a catalyst to help an aspiring, novice web designer become a geeky, code loving, power user. RapidWeaver's theme engine is a godsend for those users who are design challenged. However, it's also for those who don't want to spend time developing a site theme as they can leverage the work that some amazing theme developers have already done. Yeah, this includes me too! RapidWeaver ships with over 45 stunning themes built-in. This means that you can have a website that was designed by some world-class web designers. Each theme can be customized to your liking with just a few clicks. If you ever get tired of how your website looks, you can change your theme as often as you like. And your website content will remain 100 percent intact. Once you have your website fully constructed, RapidWeaver makes it very simple to publish your website online. It will be able to publish to pretty much every web host around through its native support for both FTP and SFTP. You will be able to publish your website for the world to see with a single click. iWeb versus RapidWeaver versus Dreamweaver RapidWeaver is most commonly compared with both iWeb and Dreamweaver. While there are definitely direct feature comparisons, we are trying to compare apples with oranges. RapidWeaver is a great tool that falls somewhere between iWeb at one end of the scale and Dreamweaver at the other end. Apple's iWeb was their first foray into personal web development software. In true Apple fashion, the application was extremely user friendly and developed beautiful websites. However, the application was really geared towards users who wanted to create a small website to share family photos and maybe have a blog. iWeb was not very extensible at all. If you ever wanted to try to steer outside the bounds of the default templates, you had to drive directly into full custom HTML. One of the biggest downsides that I came across was that once you choose the look and feel of your site, there was no going back. If you wanted to change the theme of your website, you had to redo every single page manually! For those of you who love the drag-and-drop abilities of iWeb, look no further than the RapidWeaver Stacks plugin from YourHead Software. Apple has acknowledged iWeb's shortcomings by pretty much removing iWeb from its lineup. You cannot purchase iWeb from Apple's Mac App Store. Furthermore, if you look at Apple's iLife page on their website, all traces of iWeb have been removed—if this is not a clear sign of iWeb's future, I don't know what is. Now, let's jump to the opposite end of the spectrum with Adobe Dreamweaver. Dreamweaver has a much steeper learning curve than RapidWeaver (not to mention a much steeper price tag). Dreamweaver has a lot of capability for site management and can be used collaboratively on projects, and is designed to play well with Adobe's other design software. The Adobe Creative Suite with Dreamweaver is the package of choice for very large organizational websites being developed and managed by a team, or for complex dynamic sites. I am talking about websites such as http://www.apple.com or http://www.nytimes.com. For individual and small to mid-sized business websites, I can't think of a reason why one would prefer Dreamweaver to RapidWeaver. So as I stated at the beginning, RapidWeaver provides a perfect middle ground for novice web designers and geeky code lovers! It's more than an app So far, I have talked about the RapidWeaver application itself. However, RapidWeaver is so much more than just an application. The user community that has been built around the RapidWeaver product is like nothing I have seen with any other application. The RapidWeaver forums hosted by Realmac are by far the most active and useful forums that I have seen. Users and developers spend countless hours helping each other with tips and tricks on design, code, and product support. It's a worldwide community that is truly active 24/7. You can find the forums at http://forums.realmacsoftware.com. A part of the success of the strong RapidWeaver community is the strong third-party developers that exist. RapidWeaver provides a strong and flexible platform for developers to extend the application beyond its default feature set. There are currently three primary ways to extend your RapidWeaver application: Themes, Plugins, and Stacks. As you may guess, third-party theme developers design custom themes that go above and beyond the themes that ship out of the box with RapidWeaver. With the number of amazing theme developers out there, it would be impossible not to develop a site that fits your style and looks amazing. RapidWeaver ships with 11 page styles out of the box. Blog Contact Form File Sharing HTML Code iFrame Movie Album Offsite Page Photo Album QuickTime Sitemap Styled Text However, RapidWeaver plugins can create even more page styles for you. There are a plethora of different page plugins from calendars to file uploads, and shopping carts to image galleries. To illustrate the power of RapidWeaver's platform, YourHead Software developed the Stacks plugin for fluid page layout. The Stacks plugin created an entire new class of third-party RapidWeaver developer: the stack developer! A stack is simply a widget that can be used as a building block to construct your web page. There are stacks for just about anything: animated banners, menu systems, photo galleries, or even full-blown blog integrations. If you can dream it up, there is probably a stack for it! If you have visited my website, then you should know that my origins in the RapidWeaver community are as a Stacks Developer. I think that Stacks is amazing and should probably be the first plugin that you should consider acquiring. Realmac Software has added a section on their website in order to make it easier for users to explore and locate useful third-party add-ons. So make sure that you go check it out and peruse through all the great themes, plugins, and stacks! You can browse the add-ons at http://www.realmacsoftware.com/addons.
Read more
  • 0
  • 0
  • 2005
Modal Close icon
Modal Close icon