Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Free Learning
Arrow right icon

How-To Tutorials - Web Design

132 Articles
article-image-fundamental-razor-syntaxes
Packt
18 Jun 2013
2 min read
Save for later

Fundamental Razor syntaxes

Packt
18 Jun 2013
2 min read
(For more resources related to this topic, see here.) Getting ready In this view page you can try all the Razor syntaxes given in this section. How to do it... Here, let's start learning the fundamene written using three different approaches: inline, code block, and mixed. Inline code expressions Inline code expressions are always written in a single line, as follows: I always enjoy @DateTime.Now.DayOfWeek with my family. At runtime, the inline code expression, which is @DateTime.Now.DayOfWeek, will be converted into a day, such as Sunday. This can be seen in the following screenshot: Let's look at one more example, which will pass the controller's ViewBag and ViewData messages on the view. The rendered output will be as follows: Code block expression Code block expression is actually a set of multiple code lines that start and end with @{}. The use of opening (@{) and closing (}) characters is mandatory, even for single line of C# or VB code; as shown in the following screenshot: This will render the following output: Mixed code expression Mixed code expression is a set of multiple inline code expressions in a code block where we switch between C# and HTML. The magical key here is @:, which allows writing HTML in a code block, as follows: This will render the following output: So, this is all about how we write the code on Razor view page. Summary This article thus you learned about inline code expressions, code block expressions, and mixed code expressions. Resources for Article : Further resources on this subject: Deploying HTML5 Applications with GNOME [Article] Making the World Wide Web an Easier Place to Talk About [Article] The Best Way to Create Round Cornered Boxes with CSS [Article]
Read more
  • 0
  • 0
  • 1066

article-image-building-multipage-forms-intermediate
Packt
11 Jun 2013
5 min read
Save for later

Building multipage forms (Intermediate)

Packt
11 Jun 2013
5 min read
(For more resources related to this topic, see here.) Getting ready We'll separate our existing user registration form already created to multipage forms. The sections will be for personal information, address details, and contact information. How to do it... All code related to the form is written in a file named _form under protected/views/user. We are dividing the input fields into three sections, so create three separate files in the same folder with the names _page1, _page2, and _page3. Separate the code's respective files. Some sample lines are as follows: <?php $form=$this->beginWidget('CActiveForm', array( 'id'=>'user-form', 'enableAjaxValidation'=>false, 'stateful'=>true, )); ?> <div class="row"> <?php echo $form->labelEx($model,'first_name'); ?> <?php echo $form->textField($model,'first_name', array( 'size'=>50, 'maxlength'=>50 )); ?> <?php echo $form->error($model,'first_name'); ?> </div> ..... ..... <div class="row buttons"> <?php echo CHtml::submitButton('Next', array( 'name'=>'page2' )); ?> </div> <?php $this->endWidget(); ?> .... <div class="row buttons"> <?php echo CHtml::submitButton('back', array( 'name'=>'page1' )); ?> <?php echo CHtml::submitButton('Next', array( 'name'=>'page3' )); ?> </div> <div class="row buttons"> <?php echo CHtml::submitButton('Back', array( 'name'=>'page2' )); ?> <?php echo CHtml::submitButton('submit', array( 'name'=>'submit' )); ?> </div> Now, in the User controller, change the code for actionCreate as follows: public function actionCreate() { if(isset($_POST['page1'])) { $model = new User('page1'); $this->checkPageState($model, $_POST['User']); $view = '_page1'; } elseif(isset($_POST['page2'])) { $model = new User('page1'); $this->checkPageState($model, $_POST['User']); if($model->validate()) { $view = '_page2'; $model->scenario = 'page2'; } else { $view = '_page1'; } } .... $this->render($view, array('model'=>$model)); } And add a function, checkPageState(), as follows: private function checkPageState(&$model, $data) { $model->attributes = $this->getPageState('page', array()); $model->attributes = $data; $this->setPageState('page', $model->attributes); } Lastly, create scenarios in the model User to validate each page of the form separately. Add three arrays specifying all the required fields per page, as follows: return array( array('first_name, last_name, gender, dob', 'required', 'on'=>'page1' ), array('address_1, city, state, country', 'required', 'on'=>'page2' ), array('phone_number_1, email_1', 'required', 'on'=>'page3' ), How it works... We have separated all our input fields into three forms. Each page contains an entire standalone form that accepts the input from the user, validates it from the server, and stores the data till we finally submit this form. The parameter stateful passed to the CactiveForm widget specifies the form needed to maintain the state across the pages. To do this, Yii creates a hidden field in each form with the name YII_PAGE_STATE, as shown in the following screenshot: All the data submitted on the first page is stored in this hidden field and passed to the server with the second page. To read the data from this field we have used the method getPageState(), and to write we have used setPageState(). We have added a private method checkPageState() to the User controller, which reads the page state, if any, and assigns it to $model->attributes, then assigns data from the current form using $model->attributes = $_POST['User'], and finally overwrites the page state with freshly combined data. When we click on Next on _page1, we set the POST variable page2, which in turn executes the second block in the if-else ladder in actionCreate. In this article, we create an instance of the model User with scenario set to _page1 (as we need to validate the data received from _page1). With a call to checkPageState(), we check the current page state and add any new data from _page1 to the page state. Then we check if the data filled is valid using $model->validate() . If the model passes the validation we set, apply view to _page2 and set $model->scenario to _page2, to mark the required fields on _page2. If the validation fails, we set the view to _page1 with the validation errors set in the model. At the end of the action, we render the selected view with the current state of the model. If any validation errors are set, they are listed on the same page; else, the next page will be rendered. The same steps are repeated for _page2 as well. When the submit button is clicked on on _page3, we retrieve the previous data from the page state using getPageState(). Here we are not using checkPageState() as now we do not need to store any data to the page state. We simply assign the data from _page3 to the model, and if the model validates we save all the data to the database with $model->save(). After saving, we are redirected to actionView(), where data from all three forms is listed as shown in the following screenshot: Summary In this article, we saw the importance of dividing big single forms into mulitpage forms. The article provided an insight into the making of multipage forms. Resources for Article : Further resources on this subject: Play! Framework 2 – Dealing with Content [Article] Play Framework: Introduction to Writing Modules [Article] Generating Content in WordPress Top Plugins—A Sequel [Article]
Read more
  • 0
  • 0
  • 1838

article-image-article-nesting-extend-placeholders-and-mixins
Packt
05 Jun 2013
9 min read
Save for later

Nesting, Extend, Placeholders, and Mixins

Packt
05 Jun 2013
9 min read
(For more resources related to this topic, see here.) Styling a site with Sass and Compass Personally, while abstract examples are fine, I find it difficult to fully understand concepts until I put them into practice. With that in mind, at this point I'm going to amend the markup in our project's index.html file, so we have some markup to flex our growing Sass and Compass muscles on. We're going to build up a basic home page for this book. Hopefully, the basic layout and structure will be common enough to be of help. If you want to see how things turn out, you can point your browser at http://sassandcompass.com, as that's what we'll be building. The markup for the home page is fairly simple. It consists of a header with links, navigation made up of list items, images, and content and a footer area. Pasting the home page markup here will span a few pages (and be extremely dull to read. Don't get too hung up on the specifics of the markup. Let me be clear. The actual code, selectors used, and the finished webpage that we'll create are not important. The Sass and Compass techniques and tools we use to create them are. You can download the code from the book's page at http://packtpub.com and also from http://sassandcompass.com You can download the code from the book's page at http:// packtpub.com and also from http://sassandcompass.com At this point, here's how the page looks in the browser: Image Wow, what a looker! Thankfully, with Sass and Compass we're going to knock this into shape in no time at all. Notice that in the source code there are semantically named classes in the markup. Some people dislike this practice, but I have found that it makes it easier to create more modular and maintainable code. A full discussion on the reasoning behind using classes against styling elements themselves is a little beyond the scope of this book. However, a good book on this topic is SMACSS by Jonathan Snook (http:// smacss.com). It's not essential to adhere slavishly to the conventions he describes, but it's a great start in thinking about how to structure and write style sheets in general. First, let's open the _normalize.scss partial file and amend the default styles for links (changing the default text-underline to a dotted bottom border) and remove the padding and margin for the ul tags. Now I think about this, before we get knee-deep in code, a little more organization is called for. Separating the layout from visuals Before getting into nesting, @extend, placeholders, and mixins, it makes sense to create some partial files for organizing the styles. Rather than create a partial Sass file for each structural area (the header, footer, and navigation), and lump all the visual styles relevant inside, we can structure the code in a slightly more abstract manner. There is no right or wrong way to split up Sass files. However, it's worth looking at mature and respected projects such as Twitter Bootstrap (https://github.com/twitter/ bootstrap) and Foundation from Zurb (https://github.com/zurb/foundation) to see how they organize their code. We'll create a partial file called _base.scss that will contain some base styles: code Then a partial file called _layout.scss. That will only contain rules pertaining to visual layout and positioning of the main page areas (the previously mentioned header, footer, aside, section, and navigation). Here are the initial styles being added into the _layout.scss partial file: code There is nothing particular to Sass there, it's all standard CSS. Debug help in the browser Thanks to the popularity of Sass there are now experimental features in browsers to make debugging Sass even easier. When inspecting an element with developer tools, the source file and line number is provided, making it easier to find the offending selector. For Chrome, here's a step-by-step explanation: http://benfra.in/1z1 Alternatively, if using Firefox, check out the FireSass extension: https://addons.mozilla.org/en-us/firefox/addon/ firesass-for-firebug/ Let's create another partial file called _modules.scss. This will contain all the modular pieces of code. This means, should we need to move the .testimonial section (which should be a modular section) in the source code, it's not necessary to move it from one partial file to another (which would be the case if the partial files were named according to their existing layout). The _module.scss file will probably end up being the largest file in the Sass project, as it will contain all the aesthetics for the items on the page. However, the hope is that these modular pieces of code will be flexible enough to look good, regardless of the structural constraints defined in the _layout.scss partial file. If working on a very large project, it may be worth splitting the modules into sub-folders. Just create a sub-folder and import the file. For example, if there was a partial called _callouts.scss in a sub-folder called modules, it could be imported using the following code: code Here is the contents of the amended styles.scss file: code A quick look at the HTML in the browser shows the basic layout styles applied: Image With that done, let's look at how Sass's ability to nest styles can help us make modules of code. What nesting is and how it facilitates modules of code Nesting provides the ability to nest styles within one another. This provides a handy way to write mini blocks of modular code. Nesting syntax With a normal CSS style declaration, there is a selector, then an opening curly brace, and then any number of property and value pairs, followed by a closing curly brace. For example: code Where Sass differs is that before the closing curly brace, you can nest another rule within. What do I mean by that? Consider this example: code In the previous code, a color has been set for the link tag using a variable. Then the hover and focus state have been nested within the main anchor style with a different color set. Furthermore, styles for the visited and active state have been nested with an alternate color defined. To reference a variable, simply write the dollar sign ( $) and then the name of the variable, for example, $variable. When compiled, this produces the following CSS: code Notice that Sass is also smart enough to know that the hex value #7FFF00 is actually the color called chartreuse, and when it has generated the CSS it has converted it to the CSS color name. How can this be used practically? Let's look at the markup for the list of navigation links on the home page. Each currently looks like this: code I've omitted the additional list items and closing tags in the previous code for the sake of brevity. From a structure point of view, each list item contains an anchor link with a <b> tag and a <span> tag within. Here's the initial Sass nested styles that have been added into the _modules.scss partial to control that section: code Notice that the rules are being nested inside the class .chapter-summary. That's because it then limits the scope of the nested styles to only apply to elements within a list item with a class of .chapter-summary. However, remember that if the styles can be re-used elsewhere, it isn't necessarily the best practice to nest them, as they may become too specific. The nesting of the selectors in this manner partially mirrors the structure of the HTML, so it's easy to see that the styles nested within only apply to those that are similarly structured in the markup. We're starting with the outermost element that needs to be styled (the <li class=”chapter-summary”>) and then nesting the first element within that. In this instance, it's the anchor tag. Then further styles have been nested for the hover and visited states along with the <b> and <span> tags. I tend to add focus and active states at the end of a project, but that's a personal thing. If you're likely to forget them, by all means add them at the same time you add hover. Here's the generated CSS from that block: code The nested styles are generated with a degree of specificity that limits their scope; they will only apply to elements within a <li class=”chapter-summary”>. It's possible to nest all manner of styles within one another. Classes, IDs, pseudo classes; Sass doesn't much care. For example, let's suppose the <li> elements need to have a dotted border, except for the last one. Let's take advantage of the last-child CSS pseudo class in combination with nesting and add this section: code The parent selector Notice that any pseudo selector that needs to be nested in Sass is prefixed with the ampersand symbol (&), then a colon (:). The ampersand symbol has a special meaning when nesting. It always references the parent selector. It's perfect for defining pseudo classes as it effectively says 'the parent plus this pseudo element'. However, there are other ways it can work too, for example, nesting a few related selectors and expressing different relationships between them: code This actually results in the following CSS: code We have effectively reversed the selectors while nesting by using the & parent selector. Chaining selectors It's also possible to create chained selectors using the parent selector. Consider this: code That will compile to this: code That will only select an element that has both HTML classes, namely selector-one and selector-two. The parent selector is perfect for pseudo selectors and at odd times its necessary to chain selectors, but beyond that I couldn't find much practical use for it, until I saw this set of slides by Sass guru Brandon Mathis http://speakerdeck.com/u/imathis/p/sass-compass-the-future-of-stylesheets-now. In this, he illustrates how to use the parent selector for nesting a Modernizr relevant rule.
Read more
  • 0
  • 0
  • 1531
Banner background image

article-image-getting-started-zombiejs
Packt
22 May 2013
9 min read
Save for later

Getting Started with Zombie.js

Packt
22 May 2013
9 min read
(For more resources related to this topic, see here.) A brief history of software and user interface testing Software testing is a necessary activity for gathering information about the quality of a certain product or a service. In the traditional software development cycle, this activity had been delegated to a team whose sole job was to find problems in the software. This type of testing would be required if a generic product was being sold to a domestic end user or if a company was buying a licensed operating system. In most custom-built pieces of software, the testing team has the responsibility of manually testing the software, but often the client has to do the acceptance testing in which he or she has to make sure that the software behaves as expected. Every time someone in these teams finds a new problem in the software, the development team has to fix the software and put it back in the testing loop one more time. This implies that the cost and time required to deliver a final version of the software increases every time a bug is found. Furthermore, the later in the development process the problem is found, the more it will impact the final cost of the product. Also, the way software is delivered has changed in the last few years; the Web has enabled us to make the delivery of software and its upgrade easy, shortening the time between when new functionality is developed and when it is put in use. But once you have delivered the first version of a product and have a few customers using it, you can face a dilemma; fewer updates can mean the product quickly becomes obsolete. On the other hand, introducing many changes in the software increases the chance of something going wrong and your software becoming faulty, which may drive customers away. There are many versions and iterations over how a development process can mitigate the risk of shipping a faulty product and increase the chances of new functionalities to be delivered on time, and for the overall product to meet a certain quality standard, but all people involved in building software must agree that the sooner you catch a bug, the better. This means that you should catch the problems early on, preferably in the development cycle. Unfortunately, completely testing the software by hand every time the software changes, would be costly. The solution here is to automate the tests in order to maximize the test coverage (the percentage of the application code that is tested and the possible input variations) and minimize the time it takes to run each test. If your tests take just a few seconds to run, you can afford to run them every time you make a single change in the code base. Enter the automation era Test automation has been around for some years, even before the Web was around. As soon as graphical user interfaces (GUIs) started to become mainstream, the tools that allowed you to record, build, and run automated tests against a GUI started appearing. Since there were many languages and GUI libraries for building applications, many tools that covered some of these started showing up. Generally they allowed you to record a testing session that you could later recreate automatically. In this session, you could automate the pointer to click on things (buttons, checkboxes, places on a window, and so on), select values (from a select box, for instance), and input keyboard actions and test the results. All of these tools were fairly complex to operate and, worst of all, most of them were technology-specific. But, if you're building a web-based application that uses HTML and JavaScript, you have better alternatives. The most well known of these is likely to be Selenium, which allows you to record, change, and run testing scripts against all the major browsers. You can run tests using Selenium, but you need at least one browser for Selenium to attach itself to, in order to load and run the tests. If you run the tests with as many browsers as you possibly can, you will be able to guarantee that your application behaves correctly across all of them. But since Selenium plugs into a browser and commands it, running all the tests for a considerably complex application in as many browsers as possible can take some time, and the last thing you want is to not run the tests as often as possible. Unit tests versus integration tests Generally you can divide automated tests into two categories, namely unit tests and integration tests. Unit tests: These tests are where you select a small subset of your application—such as a class or a specific object—and test the interface the class or object provides to the rest of the application. In this way, you can isolate a specific component and make sure it behaves as expected so that other components in the application can use it safely. Integration tests: These tests are where individual components are combined together and tested as a working group. During these tests, you interact and manipulate the user interface that in turn interacts with the underlying blocks of your application. The kind of testing you do with Zombie.js falls in this category. What Zombie.js is Zombie.js allows you to run these tests without a real web browser. Instead, it uses a simulated browser where it stores the HTML code and runs the JavaScript you may have in your HTML page. This means that an HTML page doesn't need to be displayed, saving precious time that would otherwise be occupied rendering it. You can then use Zombie.js to conduct this simulated browser into loading pages and, once a page is loaded, doing certain actions and observing the results. And you can do all this using JavaScript, never having to switch languages between your client code and your test scripts. Understanding the server-side DOM Zombie.js runs on top of Node.js (http://nodejs.org), a platform where you can easily build networking servers using JavaScript. It runs on top of Google's fast V8 JavaScript engine that also powers their Chrome browsers. At the time of writing, V8 implements the JavaScript ECMA 3 standard and part of the ECMA 5 standard. Not all browsers implement all the features of all the versions of the JavaScript standards equally. This means that even if your tests pass in Zombie.js, it doesn't mean they will pass for all the target browsers. On top of Node.js, there is a third-party module named JSDOM (https://npmjs.org/package/jsdom) that allows you to parse an HTML document and use an API on top of a representation of that document; this allows you to query and manipulate it. The API provided is the standard Document Object Model (DOM). All browsers implement a subset of the DOM standard, which has been dictated as a set of recommendations by a working group inside the World Wide Web Consortium (W3C). They have three levels of recommendations. JSDOM implements all three. Web applications, directly or indirectly (by using tools such as jQuery), use this browser-provided DOM API to query and manipulate the document, enabling you to create browser applications that have complex behavior. This means that by using JSDOM you automatically support any JavaScript libraries that most modern browsers support. Zombie.js is your headless browser On top of Node.js and JSDOM lies Zombie.js. Zombie.js provides browser-like functionality and an API you can use for testing. For instance, a typical use of Zombie.js would be to open a browser, ask for a certain URL to be loaded, fill some values on a form, and submit it, and then query the resulting document to see if a success message is present. To make it more concrete, here is a simple example of what the code for a simple Zombie.js test may look like: browser.visit('http://localhost:8080/form', function() {browser.fill('Name', 'Pedro Teixeira').select('Born', '1975').check('Agree with terms and conditions').pressButton('Submit', function() {assert.equal(browser.location.pathname, '/success');assert.equal(browser.text('#message'),'Thank you for submitting this form!');});}); Here you are making typical use of Zombie.js: to load an HTML page containing a form; filling that form and submitting it; and then verifying that the result is successful. Zombie.js may not only be used for testing your web app but also by applications that need to behave like browsers, such as HTML scrapers, crawlers, and all sorts of HTML bots. If you are going to use Zombie.js to do any of these activities, please be a good Web citizen and use it ethically. Summary Creating automated tests is a vital part of the development process of any software application. When creating web applications using HTML, JavaScript, and CSS, you can use Zombie.js to create a set of tests; these tests load, query, manipulate, and provide inputs to any given web page. Given that Zombie.js simulates a browser and does not depend on the actual rendering of the HTML page, the tests run much faster than they would if you instrumented a real browser. Thus it is possible for you to run these tests whenever you make any small changes to your application. Zombie.js runs on top of Node.js, uses JSDOM to provide a DOM API on top of any HTML document, and simulates browser-like functionalities with a simple API that you can use to create your tests using JavaScript Resources for Article : Further resources on this subject: Understanding and Developing Node Modules [Article] An Overview of the Node Package Manager [Article] Build iPhone, Android and iPad Applications using jQTouch [Article]
Read more
  • 0
  • 0
  • 9427

article-image-tips-and-tricks
Packt
09 May 2013
7 min read
Save for later

Tips and Tricks

Packt
09 May 2013
7 min read
(For more resources related to this topic, see here.) Adding more template files to your theme Let's say our site needed to display posts from a specific category differently from the rest of the site, or we needed the home page to work differently, or maybe we wanted to have more control over how search results or 404 pages were displayed. With template files, we can do all that. A search.php file for search results WordPress handles search results pretty well already. Let's see what's displayed in our theme if we try to search for example post (Note that we've now added a Search widgetto the right-hand side footer widget area to make this possible): As you can see, it' s using our index.php template file, so the heading reads This Month:.We'd rather make it more obvious that these are search results. Now let's see what happens if we search for something that can't be found: Again, the heading isn't great. Our theme gives the user a message telling them what's happened (which is coded into index.php as we'll see), but we could beef that up a bit,for example by adding a list of the most recent posts. Time for action – creating a search.php template file Let's create our search.php file and add some code to get it working in the way we'dlike it to: In your theme folder, make a copy of index.php and call it search.php. Find the following code near the top of the file: <h2 class="thisMonth embossed" style="color:#fff;">This Month:</h2> Edit the contents of the h2 element so the line of code now reads: <h2 class="thisMonth embossed" style="color:#fff;">Searchresults:</h2> Find the loop. This will begin with: <?php if (have_posts()) :?><?php while (have_posts()) : the_post();?> The first section of the loop displays any posts found by the search, leave this as itis. The second section of the loop specifies what happens if no search results are found. It's in the following lines of code: <?php else : ?><h2 class="center">Not Found</h2><p class="center">Sorry, but you are looking for somethingthat isn't here.</p><?php get_search_form(); ?><?php endif; ?> Underneath the line that reads <?php get_search_form(); ?> and before <?php endif; ?>, add the following lines of code: <?php endif; ?>, add the following lines of code:<h3>Latest articles:</h3><?php $query = new WP_Query( array ( 'post_type' => 'post', 'post_count' => '5' ) );while ( $query->have_posts() ) : $query->the_post(); ?><ul><li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li></ul><?php endwhile; ?> Save your search.php file and try searching for something which isn't included in the site. What just happened? We created a new template file called search.php, which will be used to display theresults of a site search. We then edited the heading to make it clearer, and added somecode to display the latest posts if the search had no results. We actually did something pretty advanced, we added a second loop inside our original loop. Let's have a look at the code we added after the search form: The function $query = new WP_Query() runs a new query on the database, based on the WordPress WP_Query function, which is the function you should use when running a loop inside the main loop. We gave WP_Query the following parameters: 'post_type' => 'post' – this ensures that the query will only look for posts, not for any other kind of content. 'post_count' => '5' – this tells WordPress how many posts to show. Five, in this case. We then output the title of each post with the php the_title() tag whichwe've already used higher up in the loop to display post titles. We wrapped this in a link inside a list item. The link uses the_permalink() to link to the blog post whose title is displayed. This is very similar to the main loop. Finally, we added endwhile() to stop this loop. This doesn't replace theendwhile() at the end of our main loop, which is higher up in the file. For more on WP_Query and how to use it to create multiple loops, see http://codex.wordpress.org/Class_Reference/ WP_Query. Let's have a look at what our users will see when they do a search now. First,a successful search: Next, an unsuccessful search: So that's how we set up a template file for search results. Our search page is only displayingtwo posts because that's all we have on our site. If there were more than five, it would justdisplay the five most recent. Now let's set one up to display some pages differently. Creating a custom page template In many themes, all pages will need the same basic layout and content, with the same sidebarsand footer and the same styling. But sometimes you may need some pages to look different. For example, you might want to use different sidebars in different pages, or you might wanta different layout. Here we'll look at the second of those two options. Time for action – creating a custom page template Imagine that you have some pages containing a lot of content which you want to displayacross the full width of the page, without the sidebar getting in the way. The way to handlethis is to create a page template which doesn't include the sidebar, and then select thatpage template when you're creating or editing those pages. Let's try it out. In the same folder as your other theme files, make a copy of your page.php file and call it page-no-sidebar.php. At the very top of the file, above the line reading <?php get_header(); ?>,insert the following code: <?php/*Template Name: Full width page without sidebar*/?> Find the following line of code: <div class="content left two-thirds"> Edit it so it reads: <div class="content left full"> Now find the line that reads <?php get_sidebar(); ?> and delete it. Save your file. What just happened? We created a new template file called page-no-sidebar.php, and edited it to displaycontent differently from our default page template: We edited the classes for our .content div, using the object-oriented approach to styling used by the layout-core.css file. This will apply styling for the .fullclass to this div, so that it displays a full width instead of two-thirds of its containing element. We removed the line calling the get_sidebar include, so that it won't be displayed on any pages using this template. The lines we added at the top are essential for WordPress to pick up on our page templateand make it available in the WordPress admin. Page editors will see a drop-down list of pagetemplates available, and the name we defined in the template is what they'll see in that list,as shown in the following screenshot: As you can see, in the Page Attributes box to the right-hand side, a new select box has appeared called Template. Our new page template is listed in that select box, along withDefault Template, which is page.php. Now we can try it out by assigning this template to a page and seeing how it looks.
Read more
  • 0
  • 0
  • 1455

article-image-converting-tables-graphs-advanced
Packt
06 May 2013
7 min read
Save for later

Converting tables into graphs (Advanced)

Packt
06 May 2013
7 min read
(For more resources related to this topic, see here.) Getting ready We maintained the same structure for our table, however this time we do not use this example and load it via AJAX. So the markup looks as follows: <table id="dynamicTable" class="table"> <thead> <tr> <th>Reviews</th> <th>Top</th> <th>Rolling Stones</th> <th>Rock Hard</th> <th>Kerrang</th> </tr> </thead> <tbody> <tr> <th>Ac/Dc</th> <td>10</td> <td>9</td> <td>8</td> <td>9</td> </tr> <tr> <th>Queen</th> <td>9</td> <td>6</td> <td>8</td> <td>5</td> </tr> <tr> <th>Whitesnake</th> <td>8</td> <td>9</td> <td>8</td> <td>6</td> </tr> <tr> <th>Deep Purple</th> <td>10</td> <td>6</td> <td>9</td> <td>8</td> </tr> <tr> <th>Black Sabbath</th> <td>10</td> <td>5</td> <td>7</td> <td>8</td> </tr> </tbody> </table> How to do it... Let's see what we need to do: Add a div right on the top of our table with an ID called graph: <div id="graph"></div> We will use a jQuery Plugin called Highcharts, which can be downloaded for free from http://www.highcharts.com/products/highcharts. Add the following script to the bottom of our document: <script src = "highcharts.js"></script> Add a simple script to initialize the graph as follows: var chart; Highcharts.visualize = function(table, options) { // the data series options.series = []; var l= options.series.length; options.series[l] = { name: $('thead th:eq('+(l+1)+')', table).text(), data: [] }; $('tbody tr', table).each( function(i) { var tr = this; var th = $('th', tr).text(); var td = parseFloat($('td', tr).text()); options.series[0].data.push({name:th,y:td}); }); chart = new Highcharts.Chart(options); } // On document ready, call visualize on the datatable. $(document).ready(function() { var table = document.getElementById('dynamicTable'), options = { chart: { renderTo: 'graph', defaultSeriesType: 'pie' }, title: { text: 'Review Notes from Metal Mags' }, plotOptions: { pie: { allowPointSelect: true, cursor: 'pointer', dataLabels: { enabled: false }, showInLegend: true } }, tooltip: { pointFormat: 'Total: <b>{point.percentage}%</ b>', percentageDecimals: 1 } }; Highcharts.visualize(table, options); }); Many people choose to hide the div with the table in smaller devices and show only the graph. Once they've optimized our table and depending on the amount of data, there is no problem. It also shows that the choice is yours. Now when we look at the browser, we can view both the table and the graph as shown in the following screenshot: Browser screenshot at 320px. Highcharts plugins have an excellent quality in all browsers and works with SVG, they are compatible with iPad, iPhone, and IE 6. How it works... The plugin can generate the table using only a single data array, but by our intuition and step-by-step description of its uses, we have created the following code to generate the graph starting from a table previously created. We create the graph using the id#= dynamicTable function, where we read its contents through the following function: $('tbody tr', table).each( function(i) { var tr = this; var th = $('th', tr).text(); var td = parseFloat($('td', tr).text()); options.series[0].data.push({name:th,y:td}); }); In the plugin settings, we set the div graph to receive the graph after it is rendered by the script. We also add a pie type and a title for our graph. options = { chart: { renderTo: 'graph', defaultSeriesType: 'pie' }, title: { text: 'Review Notes from Metal Mags' }, There's more... We can hide the table using media query so that only the graph appears. Remember that it just hides the fact and does not prevent it from being loaded by the browser; however we still need it to build the graph. For this, just apply display none to the table inside the breakpoint: @media only screen and (max-width: 768px) { .table { display: none; } } Browser screenshot at 320px, without the table Merging data – numbers and text (Advanced) We introduce an alternative based on CSS3 for dealing with tables containing text and numbers. Getting ready Tables are used for different purposes, we will see an example where our data is not a data table. (Code Example: Chapter07_Codes_1 ) Browser screenshot at 1024px Although our table did not have many columns, showing it on a small screen is not easy. Hence we will progressively show the change in the table by subtracting the width of the screen. How to do it... Note that we have removed the .table class so this time apply the style directly in the table tags, see the following steps: Let's use a simple table structure as we saw before. Add some CSS3 to make some magic with our selectors. Set our breakpoints to two sizes. <table> <thead> <tr> <th>CONTACT</th> <th scope="col">Manager</th> <th scope="col">Label</th> <th scope="col">Phone</th> </tr> </thead> <tbody> <tr> <th scope="row">Black Sabbath</th> <td>Richard Both</td> <td>Atlantic</td> <td>+1 (408) 257-1500 </td> </tr> <tr> <th scope="row">Ac/DC</th> <td>Paolla Matazo</td> <td>Sony</td> <td>+1 (302) 236-0800</td> </tr> <tr> <th scope="row">Queen</th> <td>Suzane Yeld</td> <td>Warner</td> <td>+1 (103) 222-6754</td> </tr> <tr> <th scope="row">Whitesnake</th> <td>Paul S. Senne</td> <td>Vertigo</td> <td>+1 (456) 233-1243</td> </tr> <tr> <th scope="row">Deep Purple</th> <td>Ian Friedman</td> <td>CosaNostra</td> <td>+1 (200) 255-0066</td> </tr> </tbody> </table> Applying the style as follows: table { width: 100%; background-color: transparent; border-collapse: collapse; border-spacing: 0; background-color: #fff } th { text-align: left; } td:last-child, th:last-child { text-align:right; } td, th { padding: 6px 12px; } tr:nth-child(odd), tr:nth-child(odd) { background: #f3f3f3; } tr:nth-child(even) { background: #ebebeb; } thead tr:first-child, thead tr:first-child { background: #000; color:white; } table td:empty { background:white; } We use CSS3 pseudo-selectors here again to help in the transformation of the table. And the most important part, the Media Queries breakpoints: @media (max-width: 768px) { tr :nth-child(3) {display: none;} } @media (max-width: 480px) { thead tr:first-child {display: none;} th {display: block} td {display: inline!important;} } When the resolution is set to 768px, we note that the penultimate column is removed. This way we keep the most relevant information on the screen. We have hidden the information less relevant to the subject. And when we decrease further, we have the data distributed as a block. Summary In this article, we saw an alternative solution combining the previous recipes with another plugin for rendering graphics. Resources for Article : Further resources on this subject: MySQL 5.1 Plugin: HTML Storage Engine—Reads and Writes [Article] Creating Accessible Tables in Joomla! [Article] HTML5: Generic Containers [Article]
Read more
  • 0
  • 0
  • 3027
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-introduction-rwd-frameworks
Packt
29 Mar 2013
8 min read
Save for later

Introduction to RWD frameworks

Packt
29 Mar 2013
8 min read
(For more resources related to this topic, see here.) Certainly, whether you are a beginner designer or an expert, creating a responsive website from the ground up can be convoluted. This is probably because of some indispensable technical issues in RWD, such as determining the proper number of columns in the grid and calculating the percentage of the width for each column, determining the correct breakpoint, and other technicalities that usually appear in the development stage. Many threads regarding the issues of creating responsive websites are open on StackOverflow: CSS Responsive grid 1px gap issue (http://stackoverflow.com/questions/12797183/cssresponsive-grid-1px-gap-issue) @media queries - one rule overrides another? (http://stackoverflow.com/questions/12822984/media-queriesone-rule-overrides-another) Why use frameworks? Following are a few reasons why using a framework is considered a good option: Time saver: If done right, using a framework could obviously save a lot of time. A framework generally comes with predefined styles and rules, such as the width of the gird, the button styles, font sizes, form styles, CSS reset, and other aspects to build a website. So, we don't have to repeat the same process from the beginning but simply follow the instructions to apply the styles and structure the markup. Bootstrap, for example, has been equipped with grid styles (http://twitter.github.com/bootstrap/scaffolding.html), basic styles (http://twitter.github.com/bootstrap/base-css.html), and user interface styles (http://twitter.github.com/bootstrap/components.html). Community and extension: A popular framework will most likely have an active community that extends the framework functionality. jQuery UI Bootstrap is perhaps a good example in this case; it is a theme for jQuery UI that matches the look and feel of the Bootstrap original theme. Also, Skeleton, has been extended to the WordPress theme (http://themes.simplethemes.com/skeleton/) and to Drupal (http://demo.drupalizing.com/?theme=skeleton). Cross browser compatibility : This task of assuring how the web page is displayed on different browsers is a really painful one. With a framework, we can minimize this hurdle, since the developers, most likely, have done this job before the framework is released publicly. Foundation is a good example in this case. It has been tested in the iOS, Android, and Windows Phone 7 browsers (http://foundation.zurb.com/docs/support.html). Documentation: A good framework also comes with documentation. The documentation will be very helpful when we are working with a team, to get members on the same page and make them follow the standard code-writing convention. Bootstrap ( http://twitter.github.com/bootstrap/getting-started.html) and Foundation ( http://foundation.zurb.com/docs/index.php), for example, have provided detailed documentation on how to use the framework. There are actually many responsive frameworks to choose from, such as Skeleton, Bootstrap, and Foundation. Let's take a look. Skeleton Skeleton (http://www.getskeleton.com/) is a minimal responsive framework; if you have been working with the 960.gs framework (http://960.gs/), Skeleton should immediately look familiar. Skeleton is 960 pixels wide with 16 columns in its basic grid; the only difference is that the grid is now responsive by integrating the CSS3 media queries. In case this is the first time you have heard about 960.gs or Grid System, you can follow the screencast tutorial by Jeffrey Way available at http://learncss.tutsplus.com/lesson/css-frameworks/. In this screencast, he shows how Grid System works and also guides you to create a website with 960.gs. It is a good place to start with Grid System. Bootstrap Bootstrap (http://twitter.github.com/bootstrap/) was originally built by Mark Otto (http://markdotto.com) and only intended for internal use in Twitter. Short story: Bootstrap was then launched as a free software for public. In it's early development, the responsive feature was not yet included; it was then added in Version 2 in response to the increasing demand for RWD. Bootstrap has a lot more added features as compared to Skeleton. It is packed with styled user interface components of commonly-used interfaces on a website, such as buttons, navigation, pagination, and forms. Beyond that, Bootstrap is also powered with some custom jQuery plugins, such as a tab, carousel, popover, and modal box. To get started with Bootstrap, you can follow the tutorial series (http://www.youtube.com/playlist?list=PLA615C8C2E86B555E) by David Cochran (https://twitter.com/davidcochran). He has thoroughly explained from the basics to utilizing the plugins in this series. Bootstrap has been associated with Twitter so far, but since the author has departed from Twitter and Bootstrap itself has grown beyond expectation, Bootstrap is likely to get separated from the Twitter brand as well (http://blog.getbootstrap.com/2012/09/29/onward/). Foundation Foundation (http://foundation.zurb.com) was built by a team at ZURB (http://www.zurb.com/about/), a product design agency based in California. Similar to Bootstrap, Foundation is beyond just a responsive CSS framework; it is equipped with predefined styles for a common web user interface, such as buttons (http://foundation.zurb.com/docs/components/buttons.html), navigation (http://foundation.zurb.com/docs/components/top-bar.html), and forms. In addition to this, it has also been powered up with some jQuery plugins. A few high-profile brands, such as Pixar (http://projection.pixar.com/) and National Geographic Channel (http://globalcloset.education.nationalgeographic.com/), have built their website on top of this framework. Who is using these frameworks? Now, apart from the two high-profile names we have mentioned in the preceding section, it will be nice to see what other brands and websites have been doing with these frameworks to get inspired. Let's take a look. Hivemind Hivemind is a design firm based in Wisconsin. Their website (www.ourhivemind.com) has been built using Skeleton. As befits the Skeleton framework, their website is very neat, simple, and well structured. The following screenshot shows how it responds in different viewport sizes: Living.is Living.is (http://living.is) is a social sharing website for living room stuff, ideas, and inspiration, such as sofas, chairs, and shelves. Their website has been built using Bootstrap. If you have been examining the Bootstrap UI components yourself, you will immediately recognize this from the button styles. The following screenshot shows how the Living.is page is displayed in the large viewport size: When viewed in a smaller viewport, the menu navigation is concatenated, turning into a navigation button with three stripes, as shown in the following screenshot. This approach now seems to be a popular practice, and this type of button is generally agreed to be a navigation button; the new Google Chrome website has also applied this button approach in their new release. When we click or tap on this button, it will expand the navigation downward, as shown in the following screenshot: To get more inspiration from websites that are built with Bootstrap, you can visit http://builtwithbootstrap.com/. However, the websites listed are not all responsive. Swizzle Swizzle (www.getswizzle.com) is an online service and design studio based in Canada. Their website is built on Foundation. The following screenshot shows how it is displayed in the large viewport size: Swizzle used a different way to deliver their navigation in a smaller viewport. Rather than expanding the menu as Bootstrap does, Swizzle replaces the menu navigation with a MENU link that refers to the navigation at the footer. The cons Using a framework also comes with its own problems. The most common problems found when adopting a framework are as follows: Excessive codes: Since a framework is likely to be used widely, it needs to cover every design scenario, and so it also comes with extra styles that you might not need for your website. Surely, you can sort out the styles and remove them, but this process, depending on the framework, could take a lot of time and could also be a painful task. Learning curve: The first time, it is likely that you will need to spend some time to learn how the framework works, including examining the CSS classes, the ID, and the names, and structuring HTML properly. But, this probably will only happen in your first try and won't be an issue once you are familiar with the framework. Less flexibility: A framework comes with almost everything set up, including the grid width, button styles, and border radius, and follows the standard of its developers. If things don't work the way we want them to, changing it could take a lot of time, and if it is not done properly, it could ruin all other code structure. TOther designers may also have particular issues regarding using a framework; you can further follow the discussion on this matter at http://stackoverflow.com/questions/203069/ what-is-the-best-css-framework-and-are-they-worth-the-effort. The CSS Trick forum has also opened a similar thread on this topic at http://css-tricks.com/forums/discussion/11904/css-frameworks-the-pros-and-cons/p1. Summary In this article we discussed some basic things about Responsive Web Design framework. Resources for Article : Further resources on this subject: Creating mobile friendly themes [Article] Tips and Tricks for Getting Started with OpenGL and GLSL 4.0 [Article] Debugging REST Web Services [Article]
Read more
  • 0
  • 0
  • 2825

article-image-implementation-sass
Packt
21 Mar 2013
8 min read
Save for later

Implementation of SASS

Packt
21 Mar 2013
8 min read
(For more resources related to this topic, see here.) Downloading and installing SASS We're going to kick off the recipes by downloading and setting up SASS ready for use — this will get your system ready to compile SASS files as you create them. Getting ready For this recipe you will need a few things — you will need your choice of normal text editor; I normally use TextPad, which is available on a commercial license at http://www.textpad.com, although please feel free to use whichever editor you prefer. You will also need a copy of RubyInstaller for Windows, which you can download from http://www.rubyinstaller.org/downloads ; at the time of writing, the latest version is 1.9.3. If you are a Mac OS X user, you will already have Ruby installed as part of the operating system; Linux users can download and install it through their distribution's package manager. How to do it... Let's begin by running rubyinstaller-1.9.3-p286.exe , and clicking on Run when prompted. At the Select Setup Language window prompt, select your preferred language — the default is English. At the License Agreement window, select I accept the license then click on Next. At the Installation Destination and Optional Tasks window, select Add Ruby executables to your PATH, and Associate .rb and .rbw files with this Ruby installation: Click on Install. Ruby will now install, you will see a progress window displayed on the screen while the software is being installed. A dialog window will appear when this is completed. Click on Finish to close the window. The next stage is to install SASS. For this, you need to bring up a command prompt, then type gem install sass and press Enter. Ruby will now go ahead and install SASS – you will see an update similar to the following screenshot: You may find this takes a short while, with little apparent change on screen; there is no need to worry, as it will still be downloading and installing SASS. Now that SASS is installed, we can go ahead and start creating SASS files. Open up your text editor, add the following lines, and save it as example1.scss in a folder called c:sass: $blue: #3bbfce; $margin: 16px; .content-navigation { border-color: $blue; color: darken($blue, 9%); } .border { padding: $margin / 2; margin: $margin / 2; border-color: $blue; } We now need to activate the compiler. If you don't already have a session open, bring up a command prompt, and enter the following: sass --watch c:sassexample1.scss:c:sassexample1.css If you get a "permission denied" error when running sass --watch, then make sure you are running the command prompt as an administrator. This activates the SASS compiler which will then automatically generate a CSS file when any change is made to the SCSS file: As soon as you save the file, the SASS compiler will pick up the change, and update the appropriate CSS file accordingly: If you look in the c:sass folderexample1.css file that has been generated, you will see the resulting CSS, which you can then attach to your project: .content-navigation { border-color: #3bbfce; color: #2ca2af; } .border { padding: 8px; margin: 8px; border-color: #3bbfce; } How it works... In this recipe, we've installed Ruby and SASS, and looked at how to run the SASS --watch command to set the SASS compiler to automatically compile CSS files when you create SCSS files. In this instance, we created a basic SCSS file, which SASS has parsed; it works out where variable "placeholders" have been used, and replaces them with the appropriate value that has been specified at the start of the file. Any variables included in the SASS file that are not subsequently used, are automatically dropped by SASS. When using Ruby 1.9, SASS is able to automatically determine which character encoding it should use, and will handle this in the same way as CSS (which is UTF-8 by default or a more local encoding for some users). You can change this if needed; simply add @charset "ENCODING-NAME"; at the beginning of the stylesheet, where ENCODING-NAME is the name of a format that can be converted to Unicode. While the creation of CSS files using this method is simple, it is a manual process that has to be run outside of your text editor. In the next recipe, we'll take a look at how you can add support so you can compile code from within your text editor, using Sublime Text 2 as your example editor. Viewing SASS in a browser When you have compiled your SASS files into valid CSS, an important step is to then test to see that it works. If you start seeing unexpected results, you will want to troubleshoot the CSS code. The trouble is, most browsers don't include support to trace back a SASS-compiled style to its original SASS code; we can fix that (at least for Firefox), by using FireSASS. Getting ready For this exercise, you will need a copy of Firefox, with Firebug installed. You can get the latter from http://www.getfirebug.com. How to do it... Let's get FireSASS installed. To do this, you need to browse to https://addons.mozilla.org/en-US/firefox/addon/firesass-for-firebug/, then click on the Add to Firefox button: Firefox will prompt you to allow it to install. Click on Allow, then on Install Now on the window that appears. You will need to restart Firefox for FireSASS to complete its installation. To test it, we need to create a SASS file with some example code, and use it within a HTML test page. Go ahead and add the following to a copy of the template, and save it as example2.html, within the c:sass folder we created earlier: <body> <form action=""> Name: <input type="text" class="input" /> Password: <input type="password" class="input" /> <input type="submit" value="This is a button" id="submitfrm" /> </form> </body> Add the following to a new SCSS file within Sublime Text 2. Save this as example2.scss; you will also need to link this into the <head> section of your code: $color-button: #d24444; #submitfrm { color: #fff; background: $color-button; border: 1px solid $color-button - #222; padding: 5px 12px; } Activate the SASS compiler from the command prompt, using the following command: sass --watch c:sassexample2.scss:c:sassexample2.css --debug-info If all is well, you should see the following screenshot when you view the file in your browser: How it works... FireSASS works by replacing the line number of the CSS style in use, with that of the line number from the original SCSS file: It relies on the --watch function being activated with --debug-info enabled. Using the previous example, we can see from the screenshot that the border color calculation of border: 1px solid $color-button - #222 returned a color of #B02222, which is a slightly darker shade of red than the main button itself. The beauty of this is that no matter whatever color you decide to use, the calculation will automatically return the right shade of color for the border. Not convinced? Change the $color-button variable to something completely different. I've chosen #3bbfce. Now recompile the SASS file in Sublime Text 2 and the result is a nice shade of blue: Okay, so we've only changed the color for one button in this example – it doesn't matter if you make a change for one button or many; using this code means you only need to change one variable to update any button that uses the same variable in your code. There's more... If you look into the folder where you are storing your SASS files, you may notice the presence of a .sass-cache folder, inside which there will be one or more .scssc files as shown in the following screenshot: These are cache files, which live in the same folder as your source files by default. They are created by SASS when initially compiling SCSS files. This dramatically speeds up the compilation process, particularly when you have a large number of files to compile. It works even better if styles for a project have been separated into one of these files, which SASS can then compile into one large master file. Summary Thus in this article, we saw that the Role Tailored approach provides a single point of access into the system for each user through their assigned Role Center. The user's Role Center acts as their home page. We saw how Role Center focuses on the tasks needed to support its users' jobs throughout the day. Resources for Article : Further resources on this subject: Inheritance in Python [Article] Managing the IT Portfolio using Troux Enterprise Architecture [Article] Data Migration Scenarios in SAP Business ONE Application- part 1 [Article]
Read more
  • 0
  • 0
  • 1559

article-image-remotely-preview-and-test-mobile-web-pages-actual-devices-adobe-edge-inspect
Packt
19 Mar 2013
8 min read
Save for later

Remotely Preview and test mobile web pages on actual devices with Adobe Edge Inspect

Packt
19 Mar 2013
8 min read
(For more resources related to this topic, see here.) Creating a sample mobile web application page for our testing purpose Let's first check out a very simple demo application that we will set up for our test. Our demo application will be a very simple structured HTML page targeted for mobile browsers. The main purpose behind building it is to showcase the various inspection and debugging capabilities of Adobe Edge Inspect. Now, let's get started by creating a directory named adobe_inspect_test inside your local web server's webroot directory. Since I have WAMP server installed on my Windows computer, I have created the directory inside the www folder (which is the webroot for WAMP server). Create a new empty HTML file named index.html inside the adobe_inspect_test directory. Fill it with the following code snippet: <html> <head> <title>Simple demo</title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"/> <style type='text/css' > html, body, p, div, br, input{ margin:0; padding:0; } html,body{ font-family:Helvetica; font-size:14px; font-weight:bold; color:#222; width:100%; height:100%; } #wrapper{ width:100%; height:100%; overflow:hidden; } .divStack{ padding:10px; margin:20px; text-align:center; } #div1{ background:#ABA73C; } #div2{ background:#606873; } input[type=button] { padding:5px; } <script type="text/javascript"> window.addEventListener('load',init,false); function init() { document.getElementById('btn1').addEventListener ('click',button1Clicked,false); document.getElementById('btn2').addEventListener ('click',button2Clicked,false); } function button1Clicked() { console.log('Button 1 Clicked'); } function button2Clicked() { console.log('Button 2 Clicked'); } </script> </style> </head> <body> <div id="wrapper"> <div id="div1" class="divStack"><p>First Div</p></div> <div id="div2" class="divStack"><p>Second Div</p></div> <div class="divStack"> <input id="btn1" type="button" value="Button1" /> <input id="btn2" type="button" value="Button2" /> </div> </div> </body> </html> As you can make out we have two div elements (#div1 and #div2) and two buttons (#btn1 and #btn2). We will play around with the two div elements, make changes to their HTML markup and CSS styles when we start remote debugging. And then with our two buttons we will see how we can check JavaScript console log messages remotely. Adobe Edge Inspect is compatible with Google Chrome only, so throughout our testing we will be running our demo application in Chrome. Let’s run the index.html page from our web server. This is how it looks as of now: Now, let’s check if the two buttons are generating the console log messages. For that, right-click inside Chrome and select Inspect element. This will open up the Chrome web developer tools window. Click on the Console tab. Now click on the two buttons and you will see console messages based on the button clicked. The following screenshot shows it: Everything seems to work fine and with that our demo application is ready to be tested in a mobile device with Adobe Edge Inspect. With the demo application running in Chrome and your mobile devices paired to your computer , you will instantly see the same page opening in the Edge Inspect client app in all your mobile devices. The following image shows how the page looks in an iPhone paired to my computer. Open the Edge Inspect web inspector window Now that you can see our demo application in all your paired mobile devices we are ready to remotely inspect and debug on a targeted mobile device. Click on the Edge Inspect extension icon in Chrome and select a device for inspection. I am selecting the iPhone from the list of paired devices. Now click on the Remote Inspection button to the right of the selected device name. The following image should help you: This will open up the Edge Inspect web inspector window also known as the weinre (WEb INspector REmote) web inspector. This looks very similar to the Chrome web inspector window, doesn't it? So if you have experience with the Chrome web debugging tools then this should look familiar to you. The following screenshot shows it: As you can see, by default the Remote tab opens up. The title bar says target not connected. So, although your mobile device is paired it is not yet ready for remote inspection. Under Devicess you can see your paired mobile device name with the URL of the page opened in it. Now, click on the device name to connect it. As soon as you do that, you will notice that it turns green. Congratulations! You are now ready for remote inspection as your mobile device is connected. The following screenshot shows it: Changing HTML markup and viewing the results Your target mobile device (the iPhone in my case) and the debug client (the Edge Inspect web inspector) are connected to the weinre debug server now and we are ready to make some changes to the HTML. Click on the Elements tab in the Edge Inspect web inspector on your computer and you will see the HTML markup of our demo application in it. It may take a few seconds to load since the communication is via Ajax over HTTP. Now, hover your mouse over any element and you would instantly see it being highlighted in your mobile device. Now let's make some changes to the HTML and see if it is reflected in the target mobile device. Let's change the text inside #div2 from Second Div to Second Div edited. The following screenshot shows the change made in #div2 in the Edge Inspect web inspector in my computer: And magic! It is changed on the iPhone too. Cool, isn't it? The following screenshot shows the new text inside #div2. This is what remote debugging is all about. We are utilizing the power of Adobe Edge Inspect to overcome the limitations of pure debugging tools in mobile browsers. Instead make changes on your computer and see them directly in your handset. Similarly you can make other markup changes such as removing an HTML element, changing element properties, and so on. Changing CSS style rules Now, let's make some CSS changes. Select an element in the Elements tab and the corresponding CSS styles are listed on the right. Now make changes to the style and the results will reflect on the mobile device as well. I have selected the First Div (#div1) element. Let's remove its padding. Uncheck the checkbox against padding and the 10 px padding is removed. The following screenshot shows the CSS change made in the Edge Inspect web inspector on my computer: And the following image shows the result being reflected on the iPhone instantly: Similarly, you can change other style rules such as width, height, padding, and margin and see the changes directly on your device. Viewing console log messages Click on the Console tab in the Edge Inspect web inspector to open it. Now click/tap on the buttons one by one on your mobile device. You will see that log messages are being printed on the console for the corresponding button clicked/tapped on the mobile device. This way you can debug JavaScript code remotely. Although Edge Inspect lacks JavaScript debugging using breakpoints (which would have been really handy had we been able to watch local and global variables, function arguments by pausing the execution and observing the state) but nevertheless, by using the console messages you can at least know that your JavaScript code is executing correctly to the point where the log is generated. So basic script debugging can be done. The following screenshot shows the console messages printed remotely from the paired iPhone: Similarly you can target another device for remote inspection and see the changes directly in the device. With that we have covered how to remotely debug and test web applications running on a mobile device browser. Summary In this article, we have seen the most important feature of Adobe Edge Inspect, that is, how we can remotely preview, inspect, and debug a mobile web page. We first created a sample mobile web page, edited it using Adobe Edge Inspect, changed the HTML markup and CSS styles by remote testing, and saw the results as to how this special feature of Adobe Edge Inspect is utilized. Resources for Article : Further resources on this subject: Adapting to User Devices Using Mobile Web Technology [Article] Getting Started on UDK with iOS [Article] Getting Started with Internet Explorer Mobile [Article]
Read more
  • 0
  • 0
  • 1072

article-image-creating-mobile-friendly-themes
Packt
15 Mar 2013
3 min read
Save for later

Creating mobile friendly themes

Packt
15 Mar 2013
3 min read
(For more resources related to this topic, see here.) Getting ready Before we start working on the code, we'll need to copy the basic gallery example code from the previous example and rename the folder and files to be pre fixed with mobile. After this is done, our folder and file structure should look like the following screenshot: How to do it... We'll start off with our galleria.mobile.js theme JavaScript file: (function($) { Galleria.addTheme({ name: 'mobile', author: 'Galleria How-to', css: 'galleria.mobile.css', defaults: { transition: 'fade', swipe: true, responsive: true }, init: function(options) { } }); }(jQuery)); The only difference here from our basic theme example is that we've enabled the swipe parameter for navigating images and the responsive parameter so we can use different styles for different device sizes. Then, we'll provide the additional CSS file using media queries to match only smartphones. Add the following rules in the already present code in the galleria. mobile.css file: /* for smartphones */ @media only screen and (max-width : 480px){ .galleria-stage, .galleria-thumbnails-container, .galleria-thumbnails-container, .galleria-image-nav, .galleria-info { width: 320px; } #galleria{ height: 300px; } .galleria-stage { max-height: 410px; } } Here, we're targeting any device size with a width less than 480 pixels. This should match smartphones in landscape and portrait mode. These styles will override the default styles when the width of the browser is less than 480 pixels. Then, we wire it up just like the previous theme example. Modify the galleria. mobile-example.html file to include the following code snippet for bootstrapping the gallery: <script> $(document).ready(function(){ Galleria.loadTheme('galleria.mobile.js'); Galleria.run('#galleria'); }); </script> We should now have a gallery that scales well for smaller device sizes, as shown in the following screenshot: How to do it... The responsive option tells Galleria to actively detect screen size changes and to redraw the gallery when they are detected. Then, our responsive CSS rules style the gallery differently for different device sizes. You can also provide additional rules so the gallery is styled differently when in portrait versus landscape mode. Galleria will detect when the device screen orientation has changed and apply the new styles accordingly. Media queries A very good list of media queries that can be used to target different devices for responsive web design is available at http://css-tricks.com/snippets/css/media-queriesfor-standard-devices/. Testing for mobile The easiest way to test the mobile theme is to simply resize the browser window to the size of the mobile device. This simulates the mobile device screen size and allows the use of standard web development tools that modern browsers provide. Integrating with existing sites In order for this to work effectively with existing websites, the existing styles will also have to play nicely with mobile devices. This means that an existing site, if trying to integrate a mobile gallery, will also need to have its own styles scale correctly to mobile devices. If this is not the case and the mobile devices switch to zoom-like navigation mode for the site, the mobile gallery styles won't ever kick in. Summary In this article we have seen how to create mobile friendly themes using responsive web design. Resources for Article : Further resources on this subject: jQuery Mobile: Organizing Information with List Views [Article] An Introduction to Rhomobile [Article] Creating and configuring a basic mobile application [Article]
Read more
  • 0
  • 0
  • 1120
article-image-common-design-patterns-and-how-prototype-them
Packt
15 Mar 2013
7 min read
Save for later

Common design patterns and how to prototype them

Packt
15 Mar 2013
7 min read
(For more resources related to this topic, see here.) When you tackle a design challenge and decide to re-use a solution that was used in the past, you probably have a design pattern. Design patterns are commonly used concepts that plead to be re-used. They save time, they are well recognized by a majority of users, they provide their intended functionality, and they always work (well, assuming you selected the right design pattern and used it in the right place). In this article , we will prototype one of the commonly used design pattern,: Module tabs pattern Once you created a design pattern prototype, you can copy and paste it into an Axure project. A better alternative is to create a custom widgets library and load it into your Axure environment, making it handy for every new prototype you make. Module tabs Module tabs pattern allows the user to browse through a series of tabs without refreshing the page. Why use it? Module tabs design pattern is commonly used in the following situations: When we have a group of closely related content, and we do not want to expose it to the user all at once. (In order to decrease cognitive load, because we have limited space, or maybe in order to avoid a second navigation bar.) When we do not care for (or maybe even prefer) a use case where a visitor interacts only with one pane at a time, thereby limiting his capability to easily compare information or process data simultaneously. Hipmunk.com is using it A module tabs design is used in www.hipmunk.com for a quick toggle between Flights and Hotels. By default, the user is exposed to Hipmunk's prime use case, which is the flight search. Prototyping it This is a classic use of the Axure dynamic panels. We will use a mixture of button-shaped widgets along with a dynamic panel. A module tabs design is comprised of a set of clickable tabs, located horizontally on top of a dynamic content area. Tabs can also be located vertically on the left side of the content area. We will start with creating a content area having three states: Drag a Rectangle-Dropshadow widget from the Better Defaults library into the wireframe and resize it to fit a large enough content area. This will be our background image for all content states. Now drag a Dynamic Panel widget, locate it on top of the rectangle, and resize it to fit the blank area. Label the dynamic panel with a descriptive name (the Label field is in the Widget Properties pane). In this example we will use the label: content-area dPanel. Examine your dynamic panel on the Dynamic Panel Manager pane, and add two more states under it. Since we are in the travel business, you can name them as flight, hotel, and car (these states are going to include each tab's associated content). Put some text in each of the three dynamic panel states to easily designate them upon state change (later on you can replace this text with some real content). In the screenshot that follows, you can see the content-area dPanel with its three states. Next, we will add three tab buttons to control these three states: We are going to experiment a little bit with styles and aesthetics, so let's hide the dynamic panel object from view by clicking on the small, blue box next to its name on the Dynamic Panel Manager pane. Hiding a dynamic panel has no functional implication; it will still be generated in the prototype. Drag one basic Rectangle widget, and place it above our large dropshadow rectangle. Resize the widget so that it will have the right proportions. In the following screenshot, you can see the new rectangle widget location. Also you can see what happens when we hide the dynamic panel from view: When a tab is selected (becomes active), it is important to make it look like it is part of the active area. We can achieve this by giving it the same color of the active state background as well as eliminating any border line separating them. But let's start with reshaping the rectangle widget, making it look like a tab: Right-click on the Rectangle widget and edit its shape (click on Edit button shape and select a shape). Choose the rounded top shape. This shape has no bottom border line and that's why we like it. Notice the small yellow triangle on top of the rounded top. Try to drag it to the left. You will see that we can easily control its rounded corners' angle, making it look much more like a tab button (See the screenshot that follows). Now that we have a nice looking tab button we can move forward. By default, the tab should have a gray color, which designates an unselected state. So, select the widget and click on Fill color button on the Axure toolbar to set its default color to gray. Once the tab is selected, it needs to be painted white, so that it easily blends with the content area background color under it. To do that, right-click on the tab and edit its selected style (Edit button shape Edit selected style|); the fill color should be set to white (select the preview checkbox to verify that). We are almost done. Duplicate the tab and place three identical widgets above the content area. Move them one pixel down so that they overlap and hide the rectangle border line underneath them. In the screenshot that follows, you can see how the three tabs are placed on top of the white rectangle in such a way that they hide the rectangle's border line. Examine the split square in the upper-left corner of each tab widget you created. You can preview the rollover style and selected state style of the widget by hovering over and clicking on it. Try it! The last thing to do is to add interactions. We would like to set a tab to the selected state upon mouse click, and to change the state of content-area dPanel accordingly. Put a name on each tab (Flight, Hotel, and Car), and give each tab a descriptive label. Set the OnClick event for each tab to perform two actions: Set Widget(s) to selected state: Setting the widget after it was clicked to be in a selected style. Set Panel state(s) to state(s): Setting the dynamic panel state to the relevant content (Flight, Hotel, or Car). Since we would like to have only one selected widget at a time, we should put the three of them in a selection group. Do that by selecting all the three widgets, right-clicking, and choosing the menu option Assign Selection Group. Each time this page is loaded, the Flight tab needs to be selected. To do that, we will configure the OnPageLoad event to set the Flight tab to be selected (find it at the pane located under the wireframe). By the way, there is no need to set the dynamic panel state to flight as well since it is already located on top of the three states in the Dynamic Panel Manager pane, making it the default state. In the screenshot that follows, you can see the Page Interactions pane located under the wireframe area. You can also see that the flight state is the one on top of the list, which makes it the dynamic panel's default view. The menu navigation widget cannot be used as an alternative for the tab buttons design explained here. The reason is that the navigation menu does not support the Selection Group option. Summary In this article, we learned about one of the three commonly used UI design patterns, Module Tabs and learned how to prototype them using the key features of Axure. We can now work more efficiently with Axure and will be able to deliver detailed designs much faster. Resources for Article : Further resources on this subject: Using Prototype Property in JavaScript [Article] Creating Your First Module in Drupal 7 Module Development [Article] Axure RP 6 Prototyping Essentials: Advanced Interactions [Article]
Read more
  • 0
  • 0
  • 1758

article-image-modules
Packt
08 Mar 2013
6 min read
Save for later

Modules

Packt
08 Mar 2013
6 min read
(For more resources related to this topic, see here.) We are going to try mastering modules which will help us break up our application into sensible components. Our configuration file for modules is given as follows: var guidebookConfig = function($routeProvider) { $routeProvider .when('/', { controller: 'ChaptersController', templateUrl: 'view/chapters.html' }) .when('/chapter/:chapterId', { controller: 'ChaptersController', templateUrl: 'view/chapters.html' }) .when('/addNote/:chapterId', { controller: 'AddNoteController', templateUrl: 'view/addNote.html' }) .when('/deleteNote/:chapterId/:noteId', { controller: 'DeleteNoteController', templateUrl: 'view/addNote.html' }) ; }; var Guidebook = angular.module('Guidebook', []). config(guidebookConfig); The last line is where we define our Guidebook module. This creates a namespace for our application. Look at how we defined the add and delete note controllers: Guidebook.controller('AddNoteController', function ($scope, $location, $routeParams, NoteModel) { var chapterId = $routeParams.chapterId; $scope.cancel = function() { $location.path('/chapter/' + chapterId); } $scope.createNote = function() { NoteModel.addNote(chapterId, $scope.note.content); $location.path('/chapter/' + chapterId); } } ); Guidebook.controller('DeleteNoteController', function ($scope, $location, $routeParams, NoteModel) { var chapterId = $routeParams.chapterId; NoteModel.deleteNote(chapterId, $routeParams.noteId); $location.path('/chapter/' + chapterId); } ); Since Guidebook is a module, we're really making a call to module.controller() to define our controller. We also called Guidebook.service(), which is really just module.service(), to define our models. One advantage of defining controllers, models, and other components as part of a module is that it groups them together under a common name. This way, if we have multiple applications on the same page, or content from another framework, it's easy to remember which components belong to which application. The second advantage of defining components as part of a module is that AngularJS will do some heavy lifting for us. Take our NoteModel, for instance. We defined it as a service by calling module.service(). AngularJS provides some extra functionality to services within a module. One example of that extra functionality is dependency injection. This is why in our DeleteNoteController, we can include our note model simply by asking for it in the controller's function: Guidebook.controller('DeleteNoteController', function ($scope, $location, $routeParams, NoteModel) { var chapterId = $routeParams.chapterId; NoteModel.deleteNote(chapterId, $routeParams.noteId); $location.path('/chapter/' + chapterId); } ); This only works because we registered both DeleteNoteController and NoteModel as parts of the same module. Let's talk a little more about NoteModel. When we define controllers on our module, we call module.controller(). For our models, we called module.service(). Why isn't there a module.model()? Well, it turns out models are a good bit more complicated than controllers. In our Guidebook application, our models were relatively simple, but what if we were mapping our models to some external API, or a full- fledged relational database? Because there are so many different types of models with vastly different levels of complexity, AngularJS provides three ways to define a model: as a service, as a factory, and as a provider. We'll now see how we define a service in our NoteModel: Guidebook.service('NoteModel', function() { this.getNotesForChapter = function(chapterId) { ... }; this.addNote = function(chapterId, noteContent) { ... }; this.deleteNote = function(chapterId, noteId) { ... }; }); It turns out this is the simplest type of model. We're simply defining an object with a number of functions that our controllers can call. This is all we needed in our case, but what if we were doing something a little more complicated? Let's pretend that instead of using HTML5 local storage to store and retrieve our note data, we're getting it from a web server somewhere. We'll need to add some logic to set up and manage the connection with that server. The service definition can help us a little here with the setup logic; we're returning a function, so we could easily add some initialization logic. When we get into managing the connection, though, things get a little messy. We'll probably want a way to refresh the connection, in case it drops. Where would that go? With our service definition, our only option is to add it as a function like we have for getNotesForChapter(). This is really hacky; we're now exposing how the model is implemented to the controller, and worse, we would be allowing the controller to refresh the connection. In this case, we would be better off using a factory. Here's what our NoteModel would look like if we had defined it as a factory: Guidebook.factory('NoteModel', function() { return { getNotesForChapter: function(chapterId) { ... }, addNote: function(chapterId, noteContent) { ... }, deleteNote: function(chapterId, noteId) { ... } }; }); Now we can add more complex initialization logic to our model. We could define a few functions for managing the connection privately in our factory initialization, and give our data methods references to them. The following is what that might look like: Guidebook.factory('NoteModel', function() { var refreshConnection = function() { ... }; return { getNotesForChapter: function(chapterId) { ... refreshConnection(); ... }, addNote: function(chapterId, noteContent) { ... refreshConnection(); ... }, deleteNote: function(chapterId, noteId) { ... refreshConnection(); ... } }; }); Isn't that so much cleaner? We've once again kept our model's internal workings completely separate from our controller. Let's get even crazier. What if we backed our models with a complex database server with multiple endpoints? How could we configure which endpoint to use? With a service or a factory, we could initialize this in the model. But what if we have a whole bunch of models? Do we really want to hardcode that logic into each one individually? At this point, the model shouldn't be making this decision. We want to choose our endpoints in a configuration file somewhere. Reading from a configuration file in either a service or a factory will be awkward. Models should focus solely on storing and retrieving data, not messing around with configuration updates. Provider to the rescue! If we define our NoteModel as a provider, we can do all kinds of configuration from some neatly abstracted configuration file. Here's how our NoteModel looks if we convert it into a provider: Guidebook.provider('NoteModel', function() { this.endpoint = 'defaultEndpoint'; this.setEndpoint = function(newEndpoint) { this.endpoint = newEndpoint; }; this.$get = function() { var endpoint = this.endpoint; var refreshConnection = function() { // reconnect to endpoint }; return { getNotesForChapter: function(chapterId) { ... refreshConnection(); ... }, addNote: function(chapterId, noteContent) { ... refreshConnection(); ... }, deleteNote: function(chapterId, noteId) { ... refreshConnection(); ... } }; }; }); Now if we add a configuration file to our application, we can configure the endpoint from outside the model: Guidebook.config(function(NoteModelProvider) { NoteModelProvider.setEndpoint('anEndpoint'); }); Providers give us a very powerful architecture. If we have several models, and we have several endpoints, we can configure all of them in one single configuration file. This is ideal, as our models remain single-purpose and our controllers still have no knowledge of the internals of the models they depend on. Summary Thus we saw in this article modules provide an easy, flexible way to create components in AngularJS. We've seen three different ways to define a model, and we've discussed the benefits of using a module to create an application namespace. Resources for Article : Further resources on this subject: Framework Comparison: Backbase AJAX framework Vs Other Similar Framework (Part 1) [Article] Getting Started With Spring MVC - Developing the MVC components [Article] ASP.NET MVC Framework [Article]
Read more
  • 0
  • 0
  • 1411

article-image-blocking-versus-non-blocking-scripts
Packt
08 Feb 2013
7 min read
Save for later

Blocking versus Non blocking scripts

Packt
08 Feb 2013
7 min read
(For more resources related to this topic, see here.) Blocking versus non blocking The reason we've put this library into the head of the HTML page and not the footer is because we actually want Modernizr to be a blocking script; this way it will test for, and if applicable create or shim, any elements before the DOM is rendered. We also want to be able to tell what features are available to us before the page is rendered. The script will load, Modernizr will test the availability of the new semantic elements, and if necessary, shim in the ones that fail the tests, and the rest of the page load will be on its merry way. Now when I say that we want the script to be "blocking", what I mean by that is the browser will wait to render or download any more of the page content until the script has finished loading. In essence, everything will move in a serial process and future processes will be "blocked" from occurring until after this takes place. This is also referred to as single threaded. More commonly as you may already be aware of, JavaScripts are called upon in the footer of the page, typically before the last body tag or by way of self-construction through use of an anonymous or immediate function, which only builds itself once the DOM is already parsed. The async attribute Even more recently, included page scripts can have the async attribute added to their tag elements, which will tell the browser to download other scripts in parallel. I like to think of serial versus parallel script downloading in terms of a phone conversation, each script being a single phone call. For each call made, a conversation is held, and once complete, the next phone call is made until there aren't any numbers left to be dialled. Parallel or asynchronous would be like having all of the callers on a conference call at one time. The browser, as the person making all these calls at once, has the superpower to hold all these conversations at the same time. I like to think of blocking scripts as phone calls, which contain pieces of information in their conversations that the person or browser would need to know before communicating or dialling up with the other scripts on this metaphoric conference call. Blocking to allow shimming For our needs, however, we want Modernizr to block that, so that all feature tests and shimming can be done before DOM render. The piece of information the browser needs before calling out the other scripts and parts of the page is what features exist, and whether or not semantic HTML5 elements need to be simulated. Doing otherwise could mean tragedy for something being targeted that doesn't exist because our shim wasn't there to serve its purpose by doing so. It would be similar to a roofer trying to attach shingles to a roof without any nails. Think of shimming as the nails for the CSS to attach certain selectors to their respective DOM nodes. Browsers such as IE typically ignore elements they don't recognize by default so the shims make the styles hold to the replicated semantic elements, and blocking the page ensures that happens in a timely manner. Shimming, which is also referred to as a "shiv", is when JavaScript recreates an HTML5 element that doesn't exist natively in the browser. The elements are thus "shimmed" in for use in styling. The browser will often ignore elements that don't exist natively otherwise. Say for example, the browser that was used to render the page did not support the new HTML5 section element tag. If the page wasn't shimmed to accommodate this before the render tree was constructed, you would run the risk of the CSS not working on those section elements. Looking at the reference chart on http://caniuse.com , this is somewhat likely for anyone using IE 8 or earlier: Now that we've adequately covered how to load Modernizr in the page header, we can move back on to the HTML. Adding the navigation Now that we have verified all of the JavaScript that is connected, we can start adding in more visual HTML elements. I'm going to add in five sections to the page and a fixed navigation header to scroll to each of them. Once that is all in place and working, we'll disable the default HTML actions in the navigation and control everything with JavaScript. By doing this, there will be a nice graceful fallback for the two people on the planet that have JavaScript disabled. Just kidding, maybe it's only one person. All joking aside, a no JavaScript fallback will be in place in the event that it is disabled on the page. If everything checks out as it should, you'll see the following printed in the JavaScript console in developer tools: While we're at it let's remove the h1 tag as well. Since we now know for a fact that Modernizr is great, we don't need to "hello world" it. Once the h1 tag is removed, it's time for a bit of navigation. The HTML used is as follows: <!-- Placing everything in the <header> html5 tag. --> <header> <div id="navbar"> <div id="nav"> <!-- Wrap the navigation in the new html5 nav element --> <nav> <href="#frame-1">Section One</a> <href="#frame-2">Section Two</a> <href="#frame-3">Section Three</a> <href="#frame-4">Section Four</a> <href="#frame-5">Section Four</a> </nav> </div> </div> </header> This is a fairly straightforward navigation at the moment. The entire fragment is placed inside the HTML5 header element of the page. A div tag with the id field of navbar will be used for targeting. I prefer to use HTML5 purely for semantic markup of the page as much as possible and to use div tags to target with styles. You could just as easily add CSS selectors to the new elements and they would be picked up as if they were any other inline or block element. The section frames After the nav element we'll add the page section frames. Each frame will be a div element, and each div element will have an id field matching the href attribute of the element from the navigation. For example, the first frame will have the id field of frame-1 which matches the href attribute of the first anchor tag in the navigation. Everything will also be wrapped in a div tag with the id field of main. Each panel or section will have the class name of frame, which allows us to apply common styles across sections as shown in the following code snippet: <div id="main"> <div id="frame-1" ></div> <div id="frame-2" ></div> <div id="frame-3" ></div> <div id="frame-4" ></div> <div id="frame-5" ></div> </div> Summary In this article we saw the basics of blocking versus non blocking scripts. We saw how the async attribute allows the browser to download other scripts in parallel. We blocked scripts using shimming, and also added navigation to the scripts. Lastly, we saw the use of section frames in scripts. Resources for Article : Further resources on this subject: HTML5: Generic Containers [Article] HTML5 Games Development: Using Local Storage to Store Game Data [Article] Building HTML5 Pages from Scratch [Article]
Read more
  • 0
  • 0
  • 3625
article-image-article-getting-started-with-html5-modernizer-url
Packt
31 Jan 2013
4 min read
Save for later

Getting Started with Modernizr

Packt
31 Jan 2013
4 min read
(For more resources on this subject, see here.) Detect and design with features, not User agents (browsers) What if you could build your website based on features instead of for the individual browser idiosyncrasies by manufacturer and version, making your website not just backward compatible but also forward compatible? You could quite potentially build a fully backward and forward compatible experience using a single code base across the entire UA spectrum. What I mean by this is instead of baking in an MSIE 7.0 version, an MSIE 8.0 version , a Firefox version, and so on of your website, and then using JavaScript to listen for, or sniff out, the browser version in play, it would be much simpler to instead build a single version of your website that supports all of the older generation, latest generation, and in many cases even future generation technologies, such as a video API,box-shadow,and first-of-type. Think of your website as a full-fledged cable television network broadcasting over 130 channels, and your users as customers that sign up for only the most basic package available, of only 15 channels. Any time that they upgrade their cable (browser) package to one offering additional channels (features), they can begin enjoying them immediately because you have already been broadcasting to each one of those channels the entire time. What happens now is that a proverbial line is drawn in the sand, and the site is built on the assumption that a particular set of features will exist and are thus supported. If not, fallbacks are in place to allow a smooth degradation of the experience as usual, but more importantly the site is built to adopt features that the browser will eventually have. Modernizr can detect CSS features, such as @font-face , box-shadow , and CSS gradients. It can also detect HTML5 elements, such as canvas , localstorage, and application cache. In all it can detect over 40 features for you, the developer. Another term commonly used to describe this technique is "progressive enhancement ". When the time fi nally comes that the user decides to upgrade their browser, the new features that the more recent browser version brings with it, for example text-shadow , will automatically be detected and picked up by your website, to be leveraged by your site with no extra work or code from you when they do. Without any additional work on your part, any text that is assigned text-shadow attributes will turn on at the fl ick of a switch so that user's experience will smoothly, and progressively be enhanced. What is Modernizr? More importantly, why should you use it? At its foundation, Modernizr is a feature-detection library powered by none other than JavaScript. Here is an example of conditionally adding CSS classes based on the browser, also known as the User Agent . When the browser parses this HTML document and fi nds a match, that class will be conditionally added to the page. Now that the browser version has been found, the developer can use CSS to alter the page based on the version of the browser that is used to parse the page. In the following example, IE 7, IE 8, and IE 9 all use a different method for a drop shadow attribute on an anchor element: /* IE7 Conditional class using UA sniffing */ .lt-ie7 a{ display: block; float: left; background: url( drop-shadow. gif ); } .lt-ie8 a{ display: inline-block; background: url( drop-shadow.png ); } .lt-ie9 a{ display: inline-block; box-shadow: 10px 5px 5px rgba(0,0,0,0.5); } The problem with the conditional method of applying styles is that not only does it require more code, but it also leaves a burden on the developer to know what browser version is capable of a given feature, in this case box-shadow . Here is the same example using Modernizr . Note how Modernizr has done the heavy lifting for you, irrespective of whether or not the box-shadow feature is supported by the browser: /* Box shadow using Modernizr CSS feature detected classes */ .box-shadow a{ box-shadow: 10px 5px 5px rgba(0,0,0,0.5); } .no-box-shadow a{ background: url( drop-shadow.gif ); }   The Modernizr namespace The Modernizr JavaScript library in your web page's header is a lightweight feature library that will test your browser for the features that it may or may not support, and store those results in a JavaScript namespace aptly named Modernizr. You can then use those test results as you build your website. From this point on everything you need to know about what features your user's browser can and cannot support can be checked for in two separate places. Going back to the cable television analogy, you now know what channels (features) your user does and does not have, and can act accordingly.
Read more
  • 0
  • 0
  • 935

article-image-null-16
Packt
30 Jan 2013
4 min read
Save for later

Getting Started with HTML5 Modernizr

Packt
30 Jan 2013
4 min read
Detect and design with features, not User Agents (browsers) What if you could build your website based on features instead of for the individual browser idiosyncrasies by manufacturer and version, making your website not just backward compatible but also forward compatible? You could quite potentially build a fully backward and forward compatible experience using a single code base across the entire UA spectrum. What I mean by this is instead of baking in an MSIE 7.0 version, an MSIE 8.0 version , a Firefox version, and so on of your website, and then using JavaScript to listen for, or sniff out, the browser version in play, it would be much simpler to instead build a single version of your website that supports all of the older generation, latest generation, and in many cases even future generation technologies, such as a video API , box-shadow, first-of-type , and more. Think of your website as a full-fledged cable television network broadcasting over 130 channels, and your users as customers that sign up for only the most basic package available, of only 15 channels. Any time that they upgrade their cable (browser) package to one offering additional channels (features), they can begin enjoying them immediately because you have already been broadcasting to each one of those channels the entire time. What happens now is that a proverbial line is drawn in the sand, and the site is built on the assumption that a particular set of features will exist and are thus supported. If not, fallbacks are in place to allow a smooth degradation of the experience as usual, but more importantly the site is built to adopt features that the browser will eventually have. Modernizr can detect CSS features, such as @font-face , box-shadow , and CSS gradients. It can also detect HTML5 elements, such as canvas, localstorage, and application cache. In all it can detect over 40 features for you, the developer. Another term commonly used to describe this technique is progressive enhancement. When the time finally comes that the user decides to upgrade their browser, the new features that the more recent browser version brings with it, for example text-shadow, will automatically be detected and picked up by your website, to be leveraged by your site with no extra work or code from you when they do. Without any additional work on your part, any text that is assigned text-shadow attributes will turn on at the flick of a switch so that user's experience will smoothly, and progressively be enhanced. What is Modernizr? More importantly, why should you use it? At its foundation, Modernizr is a feature-detection library powered by none other than JavaScript. Here is an example of conditionally adding CSS classes based on the browser, also known as the User Agent. When the browser parses this HTML document and finds a match, that class will be conditionally added to the page. code 1 Now that the browser version has been found, the developer can use CSS to alter the page based on the version of the browser that is used to parse the page. In the following example, IE 7, IE 8, and IE 9 all use a different method for a drop shadow attribute on an anchor element: code 2 The problem with the conditional method of applying styles is that not only does it require more code, but it also leaves a burden on the developer to know what browser version is capable of a given feature, in this case box-shadow . Here is the same example using Modernizr. Note how Modernizr has done the heavy lifting for you, irrespective of whether or not the box-shadow feature is supported by the browser: code 3
Read more
  • 0
  • 0
  • 896