Tag Archive: jQuery

One WP REST API Usage Tip

WP REST API with WordPress

I have been experimenting with WP-API for the last several months and here is one tip I’ve discovered so far:

I mentioned in the previous post that I needed to setup separate sub-domains for serving WP-API and consuming it.

However, I’ve been consuming WP-API as part of a theme for the same sub-domain without any problem. In fact, there are actually some benefits to use it as a WordPress theme, such as:

  • The ability to use WordPress functions if you want to.
  • Utilize permalink structure without implementing your own router functions or using third-party library.
  • Take advantage of WordPress plugins ecosystem for the front-end.
  • Can be edited using WordPress Customizer.
  • And many other benefits …

Of course there are some disadvantages as well, such as slow performance of using too much plugins and use one server for both generate and process API is very resource intensive.

However, if you can’t get out of the WordPress environment just yet and still want to take advantage of WP REST API, this is the better way to go without using any third-party libraries which are not included in WordPress (it’s worth mentioning that jQuery is one of the third party libraries which is included in WordPress).

As WP REST API improves and moves more closer to the WordPress Core, we will be able to see more and more themes that use WP REST API.

Working with jQuery and CakePHP

Recently I’m working with CakePHP and SQLite to develop a gallery for a client. This is going to be my first CakePHP app.

While I’m working on the admin section, I wanted to allow the client to see the image once the image filename field is out of focused so that he could see if it’s the correct image.

The only JS library included with CakePHP is Prototype. Fortunately, the latest version of CakePHP (1.3.11 as of right now) allows us to include with other JS library. I included jQuery with the help of Js helper:

var $helpers = array("Js"=>array("Jquery"));

The above code is included with the whatever controller(s) you want to use this helper. In my case is galleries_controller.php and images_controller.php.

Then I just need to add the following code into the corresponding views, in my case is some of the admin views (admin_edit.ctp, and admin_add.ctp):

echo $this->Js->set("imageLoc", $this->Html->image("0"));

echo $this->Js->get("#GalleryCover")->event("blur", "$('#cover').html(window.beta.imageLoc.substring(0, window.beta.imageLoc.length-12) + 'images/' + $('#GalleryPath').val() + '/thumb/' + $(this).val() + '" />');");

Note that I used image object in the Html helper to generate a dummy img tag so that I could precisely get the image folder location in the webroot folder. Then I used set object in the Js helper to transfer this generated PHP value to Javascript variable “imageLoc”. The second line is self-explanatory if you know jQuery. Here is the documentation in the CakePHP Cookbook for you to review.

In the jQuery code section of the second line, I used the substring function to remove the last 12 characters in the img tag (0″ alt=”” />). And used the html function to include the generated code into the “cover” div. Every time the “GalleryCover” field is blurred out of focus, the image inside the “cover” div would change to the corresponding images.

If you need more information on how to use CakePHP generated Javascript variables, please refer to the second article in the reference section.

Do you have any other tips on how to incorporate jQuery into CakePHP? Please share them in the comment below.

Reference

Remove AIO SEO related Columns with Greasemonkey and jQuery in WordPress (Updated)

Update (7/23/2015): Since I wrote this post four years ago, the following tip no longer needed as All in One SEO already has this feature build-in. For more information, here is the direct copy of the comment written by Tony Zeoli, Director of Digital Marketing for All In One SEO (you can see the original comment in the comment section of this post):

Hey Robby,

Hope all is well.

I just stumbled across this post from 2011, which is now outdated. AIOSEO Pack columns can now be hidden via the Screen Options menu at the top of the All Posts list view page in the WordPress Dashboard admin.

I’ve posted the screenshot to this comment.

Your post, while a great resource at the time, might now confuse developers and users who don’t realize that show/hide is now implemented in the admin by default.

Can you please either remove this post as it’s outdated, or at least update the post to reflect that your workaround is no longer necessary. We would sincerely appreciate it.

Tony Zeoli
Director, Digital Marketing
All In One SEO Pack

Thumbnail

 

Although you can still use the tip in this post, the official way discussed above is preferred. If you want to know how the above way works, you can always read the source code of this plugin.


 

Since I installed All in One SEO plugin, I have a hard time to look for the specified posts on the Posts page within the WordPress admin area because of the three added SEO-related columns.

All in One SEO plugin is enabled

All in One SEO plugin is enabled

I don’t like the look of this page, and besides, I don’t use these columns very much. I mainly use this plugin to automatically generate SEO required meta information.

The plugin doesn’t have the option to remove these columns, and editing its source files is useless since they will be restored once the plugin is updated. Using Greasemonkey to modify the layout of the posts page is the only option to permanently to remove these columns.

However, I used to use jQuery to write JavaScript. Writing the raw JavaScript code is a little challenging to me. Fortunately, 0.8 to the latest version of Greasemonkey has the @require metadata block. I can use it to include the jQuery library.

So I wrote the following small segment of code to automatically remove the SEO-related columns once the posts page is loaded:

// ==UserScript==
// @name  AIO SEO posts columns remover
// @namespace  AIOseo
// @require  http://code.jquery.com/jquery-latest.js
// @include  http://blog.robbychen.com/wp-admin/edit.php
// ==/UserScript==

$(document).ready(function() {
 $("*[class*='seo']").remove();
});

After the above script is executed, the posts page is now returned to the original layout.

Greasemonkey script loaded

Greasemonkey script loaded

In the above code, I select all the elements and remove the elements which the class name which contains “seo”:

$("*[class*='seo']").remove();

According to the jQuery document, it is called Attribute Contains Selector.

I like to use this layout most of time. If I want to see these three columns for SEO purpose in the future, I would just disable Greasemonkey to show them.

Do you have any suggestion what to do with these column? Post them below.

A Small Fancybox Tip – Show scrollbar when viewing Large Images

Intro

I use Fancybox jQuery plugin to view large/original size of images. However, its default settings don’t setup to view the large size images. It auto resizes based on the browser window size instead. According to the documentation, the options “autoScale” and “scrolling” disables the automatic scaling and enables the scrollbar to be visible respectively. However, I couldn’t figure out the scrolling option since the horizontal scrollbar is missing when viewing a large image that is bigger than the browser width. After looked into the code generated by Fancybox, I noticed that the scrolling option is applied to other than the body element, which is what I want the scrollbars to be at (edges of the browser window). So I used onStart option to write a callback function that set the overflow property for the body element to be visible.

The Code

$("element").fancybox({
 transitionIn: "elastic",
 transitionOut: "elastic",
 autoScale: false,
 onStart: function() {
  $("body").css({overflow:"visible"});
 }
});

Below is the difference between use the scrolling option and use the onStart callback function:

Scrolling

Scrolling Option

onStart callback function

onStart Callback Function

 

Questions

All of the above options are explained in the Fancybox document page. If you still have questions, feel free to ask them below.

Selectively Include jQuery Plugins

Introduction

I’m often using jQuery and a little PHP because of the recent interest in the jQuery animation. Therefore I need lots of jQuery plugins to load in every web page. I need some plugins on each page such as Color plugin for the navigation and IE font-face ClearType fix for adding font-face support to IE, but I don’t need other plugins to load unless there is a page element specifically used with those plugins.

The Code

 // Function to create script element dynamically
function createScript(src) {
 var script = document.createElement("script");
 script.src = "scripts/" + src + ".js";
 script.type= "text/javascript";
 $("body").append(script);
}
$(window).load(function() {
  // Load the custom fonts in IE
 $("body").ieffembedfix();
  // Top Navigation Menu Animation
 $("#horiNav a").hover(function() {
  if ($(this).attr("id") != "currentPage") {
   $("#currentPage").stop().animate({backgroundColor:"#FFF", color:"#87CEEB"});
   $(this).stop().animate({backgroundColor:"#A7D4F2", color:"#FFF"});
  }
 }, function() {
  if ($(this).attr("id") != "currentPage") {
   $(this).stop().animate({backgroundColor:"#FFF", color:"#87CEEB"});
   $("#currentPage").stop().animate({backgroundColor:"#A7D4F2", color: "#FFF"});
  }
 });
 if ($("#slideshow").length != 0) {
   // Load the Cycle plugin dynamically
  createScript("jquery.cycle.all.latest");
   // Cycle through the slideshow on the home page
  $("#slideshow").cycle({
   fx: "fade",
   timeout:"3000",
   pager:"#SSnav"
  })
   // Stop the slideshow once it is clicked
  .bind("click", function() {
   $(this).cycle("toggle");
  });
 }
});

Explanation

Here I defined a function that creates a script element before the end of body. The function basically used raw Javascript code to create script element and a line of jQuery code to append the new element to the body.

I used $(window).load instead of $(document).ready method to execute the jQuery code after the page is loaded. I then demonstrated the code for the font-face support for IE and the navigation color animation.

In order to selectively include jQuery plugins, check the existence of the element that requires to use those plugins first. I used if statement to check the length of the element. Include the jQuery plugins if the number of the specified element is at least one. Then execute rest of the code within the if statement. The screenshot below shows Firebug that the page has successfully loaded the required plugin.

Loaded required jQuery plugin successfully

Loaded required jQuery plugin successfully

Head over to wcf.robbychen.com to see it in action. Make sure to open Firebug when visiting the site to see which jQuery plugins are loaded. Right now only the homepage and Who We Are page use additional jQuery plugins.

Questions

If you have any question about the above code, feel free to post them in the comments below.

Final Revision for Scrolling Animation Code, Maybe

Introduction

After I revised the scrolling animation jQuery code yesterday, I was going to rewrite it using Mootools. However, I noticed that this code was doing two unnecessary actions. The first one is the removing of the first set of images, and another one is the appending of new sets of images. Several minutes after my eyes watched the scrollbar animate back and forth, I revised the code to the following.

The Code

if ($("#whoWeAreImages").length != 0) {
  // Scroll Animation for the images in the Who We Are page
 var $whoWeAreImages = $("#whoWeAreImages"),
 $wwaLink = $whoWeAreImages.find("a"),
 $wwaImg = $whoWeAreImages.find("img"),
 scrollWidth = $whoWeAreImages.attr("scrollWidth");
  // Do the following once the page is loaded
 $whoWeAreImages.css({overflow:"hidden"}) // Hide the images scrollbar
 .scrollLeft(0) // Make sure the scrollbar is at the beginning when the page is reloaded
 .append($(this).html()) // Add one more set of images
  // Begin the animation
 .autoscroll({
  direction: 0,
  step: 50,
  onEvaluate: function() {
    // Click action for the images in the Who We Are page
   $wwaLink.fancybox({
    transitionIn: "elastic",
    transitionOut: "elastic"
   })
    // Scroll to the beginning once it scrolls to the beginning of the second set of images
   if ($(this).scrollLeft() >= scrollWidth) {
    $(this).autoscroll("pause");
    $(this).attr("scrollLeft", "0");
    $(this).autoscroll("resume");
   }
  }
 })
 .autoscroll("addpausesource", $wwaImg);
}

Explanation

In the above code, I removed the remove() action and added the append action at the beginning of the loop. It means that it will only has two sets of images available instead of an infinite loop that remove and append continuously to limit two loops which has slower performance.

After this revision, the animation lag still exists. This is probably the final revision of the code before I rewrite it using Mootools because I might discover some techniques during the rewriting of this code.

Revision for the Auto Scrolling Animation code

Autoscroll Animation

Introduction

Since I wrote the auto scrolling animation code with jQuery two days ago, I struggled with the browser performance while running this animation. It seems that the animation needs lots of CPU power and it sometimes appears to be lagging. In order to solve the CPU issue, I included a jQuery plugin named Autoscroll. As the name applies, it automatically scrolls the specified element. This has the same feature as the code I wrote, but it’s a plugin and it will immediately stop the animation when in hover state whereas my code stops animation few seconds after the cursor was hovered over the element.

The Source Code

The following is the revised code:

if ($("#whoWeAreImages").length != 0) {
  // Scroll Animation for the images in the Who We Are page
 var $whoWeAreImages = $("#whoWeAreImages"),
     $wwa = $(".WWA:first"),
     $wwaLink = $whoWeAreImages.find("a"),
     $wwaImg = $whoWeAreImages.find("img"),
     scrollWidth = $whoWeAreImages.attr("scrollWidth"),
     wwaHTML = $whoWeAreImages.html();
  // Do the following once the page is loaded
 $whoWeAreImages.css({overflow:"hidden"}) // Hide the images scrollbar
 .scrollLeft(0) // Make sure the scrollbar is at the beginning when the page is reloaded
  // Begin the animation
 .autoscroll({
  direction: 0,
  step: 50,
  onEvaluate: function() {
    // Click action for the images in the Who We Are page
   $wwaLink.fancybox({
    transitionIn: "elastic",
    transitionOut: "elastic"
   })
    // Remove the first set of images in order to limit loop
   if ($(this).scrollLeft() >= scrollWidth) {
    $wwa.remove();
    $(this).autoscroll("pause");
    $(this).attr("scrollLeft", "0");
    $(this).autoscroll("resume");
   }
  },
  onEdge: function(a) {
   if ($(this).attr("scrollLeft") != 0) {
     // Append the same images to the end of the last image if it finished scrolling to loop through the animation
    $(this).append(wwaHTML);
   }
  }
 })
 .autoscroll("addpausesource", $wwaImg);
}

Explanation

As you can see in the code, I optimized the code to use the chaining method for jQuery.

I also changed the way images were looped. When scrollLeft greater than or equals to scrollWidth, the first set of images will be removed/deleted, pause the animation, set scrollLeft to zero, and restart the animation.

This means that when the position of the scrollbar reaches the beginning of the second set of images (or second loop), delete the first set of images using :first pseudo selector and reset the scrollbar position to the beginning. Since the scrollbar position will be at the end of the first loop and the beginning of the second loop, remove the first loop and reset the scrollbar position have no effect on the animation. The animation would continue to loop through the images without interruption but it’s limited to two loops.

Although the code was optimized, the animation still has some lag. It will sometimes stop and continue without interaction, much like the under-powered graphics card. I have not yet find any solution to this issue yet. However, I found out that Mootools animation is sometimes more smooth than jQuery. I will try to use Mootools to animate the auto scroll later.

Do you believe that Mootools animation is more smooth than jQuery? Please share your opinion in the discussion.

Auto Scroll Images jQuery Animation

Update (12/14/2010): I wrote the revised code for better performance.

Introduction

Based on the last past, I wrote a jQuery snippets to automatically scroll through the images horizontally. I used scrollLeft and scrollWidth attributes to achieve this animation. And if the scrollbar scrolled to the end of the element, it will append the original content in the element to the end of the element in order to loop through the images. Take a look at the source code below to see what I mean. Note that the HTML code is the same as last post.

The Source Code

 // Scroll Animation for the images
var div = $("#div");
 // Do the following once the page is loaded
div.css({overflow:"hidden"}); // Hide the images scrollbar
div.attr("scrollLeft",0); // Make sure the scrollbar is at the beginning
 // Begin the animation
var scrollAnime = function() {
 div.animate({"scrollLeft":"+=20"}, 1000, "linear");
  // Append the same images to the end of the last image if it finished scrolling to loop through the animation
 if (div.attr("scrollLeft") >= div.attr("scrollWidth") - div.width() - 10) {
  div.append(div.html());
 }
  // Click action for the images
 $("#div a").fancybox({
  transitionIn: "elastic",
  transitionOut: "elastic"
  });
 }
 var beginAnime = setInterval(scrollAnime, 1000);

  // Stop the animation in hover state
 div.hover(function() {
  clearInterval(beginAnime);
 }, function() {
  beginAnime = setInterval(scrollAnime, 1000);
 });

CSS recommendation: (Optional if you don’t want the animation to show where to end/start the new loop of the images)

#div .lastImage {
 border-right:1px solid #000;
 padding-right:1em;
 margin-right: 1em;
}

Explanation

Firstly, as you can see in the source code, I use Fancybox jQuery plugin to view enlarged images. I put this piece of code inside the setInterval function together with the rest of the code so that it can recognize the new images which are generated inside the function. I also set the scrollLeft to 0 when the document is loaded to ensure that the scrollbar resets to the left when the page is refreshed. The default value for the third parameter of the animate function is swing. In order to make the ScrollLeft animation more smooth, I changed it to linear since there are only these two values available when used with jQuery, according to the API documentation. Other section in the source code above is explained in the comments after each line. One thing to note is that I found the usage for  the third parameter for the animate function  in the source code of image board jQuery plugin which is similar to my code above, except it will not loop through the images continuously, instead it goes back to the first image once it passed the last image.

You can see a demo of the above code at wcf.robbychen.com.

Since I don’t know how to write a jQuery plugin yet, I’m sure that there are similar plugins out there. If you find one, please share it in the comments section below.

Switch Between Stylesheets Dynamically with jQuery

jQuery Tips

Introduction

I recently learned that almost all of the modern browsers supports CSS3’s media queries. Since I want my webpage cross-browser compatible and display the same layout in different screen sizes, I wrote the following jQuery code inspired by the original Javascript code.

The Code

<link href="styles/main.css" id="styles" type="text/css" rel="stylesheet" />
$(document).ready(function() {
if (screen.width <= 1024) {
$("#styles").attr("href", "styles/netbook.css");
}
});

Explanation

As you can see, I only used the netbook screen size as an example since my netbook has maximum screen width of 1024. You can also easily switch to mobile stylesheet to display on the mobile device by changing the screen.width value in the if statement from 1024 to some smaller value.

Note that unlike the CSS3 media queries, screen.width is your actual screen width instead of browser width. Therefore, using this method will not change the stylesheet on the resized browser window.

If you find any better method to determine the screen size other than CSS3 media queries, please feel free to discuss in the comments below.