Tutorial: jQuery wrap doesn’t work in IE

This is something happen to me a while ago when i am testing my WordPress plugin over different browser (testing cross browser issue). Every browser work well (Firefox, Opera, Chrome, Safari) but IE went wrong. Not surprising IE is the king for being different and causing most problem to developers (well known fellow). Oddly, IE is pointing its finger on one of the line related to jQuery wrap manipulation operation. Weird.

Problem

After debugging a while, i manage to find the problem that is happening with IE and not with other browsers. I used wrap operation to insert a form into a div container (to perform a asynchronous upload over different browser and try not to knock on WordPress style sheet etc.). So the form should wrap over the div container as stated in jQuery documentation. However, in IE it couldn't seems to find this particular new form that was inserted through the wrap operation (scratch head). Since this is a JavaScript DHTML operation, obviously it won't show during view source (at least not for IE). Through the error line instructed by IE browser it indicated that the particular form ID could not be found (form doesn't exist). jQuery warp doesn't support IE 7? Nah..

Solution

So what is going on? Many jQuery users will like to write a wrap operation in this way (including me)


$('#example').wrap('<form id="form2" name="form" action="#" method="POST" enctype="multipart/form-data" >');

This is perfectly alright to wrap a form over some div block. Nothing seems to be wrong as it can be declare this way. Well, most of us will do that since it doesn't add additional word to lengthen the instruction which always make it a bit difficult to read (due to jQuery chaining). However, if you declare it this way using the wrap operation, IE will not work! The wrap operation basically fail without showing any error indicating that the new form which was instructed to create was not there. Good news is that it is not really jQuery fault that it doesn't work when declaring a wrap operation this way. In order for jQuery v1.3 to work in IE using the wrap operation, the declaration must be in this form


$('#example').wrap('<form id="form2" name="form" action="#" method="POST" enctype="multipart/form-data" ></form>');

seems no differences between the two code. But the key is the closing tag which is that ONLY requirement for IE to work flawlessly. Without the closing tag it will not work.

Demo

let me show you a demo to illustrate the differences between the two declaration using the following JavaScript.


$(function(){
	$('#wrong').wrap('<form id="form1" name="form" action="#" method="POST" enctype="multipart/form-data" >');
	$('#correct').wrap('<form id="form2" name="form" action="#" method="POST" enctype="multipart/form-data" ></form>');
});

function withoutCloseTag()
{
	if(document.getElementById('form1') != null && document.getElementById('form1') != "undefined")
	{
		alert("We found wrap for button 'IE with problem'");
	}
}

function withCloseTag()
{
	if(document.getElementById('form2') != null && document.getElementById('form2') != "undefined")
	{
		alert("We found wrap for button 'IE without problem'");
	}
}

The script will alert if the usage of wrap is successful and when fail it will not show any alert message. Try this in IE with other browser. You will find that the second declaration work flawlessly over all browser while the first declaration will only work on all browser except IE (IE no pop out).

Conclusion

Unlike some jQuery tutorial online that teaches the basic of jQuery that indicates the first method of declaration work (without closing tag). It is necessary for jQuery developers to know the differencces between declaring a DHTML operation using jQuery that a closing tag will make a differences when your application is serving different browser.

$(function(){
$('#wrong').wrap('
');
$('#correct').wrap('
');
});
function withoutCloseTag()
{
if(document.getElementById('form1') != null && document.getElementById('form1') != "undefined")
{
alert("We found wrap for button 'IE with problem'");
}
}
function withCloseTag()
{
if(document.getElementById('form2') != null && document.getElementById('form2') != "undefined")
{
alert("We found wrap for button 'IE without problem'");
}
}

Tutorial: How to get post id when using publish_post action hook in WordPress

This topic may seems stupid to some plugin developers but it may really surprise you. Most of you will just say, "Hey, just use the WordPress global variable, $post. Issue solved!". Yes, it is stated as global variable across WordPress developers and it should be globally available. Surprisingly, IT IS NOT~. I spend hours researching for an answer which are not document anywhere and finally decided to write a post to inform some plugin developer who are still unaware of such condition.

Problem

I wanted to attached a function to an event, publish_post whenever the user click on publish or update button when they have done with their post in WordPress. Usually, global variable $post will solve this problem easily. But for the case of publish_post action hook, this is not the case. The global variable $post which is accessible in any area of WordPress is not accessible when a user clicked on the publish button. The global variable $post will return 'null' instead of the post object which contain all the post data. Let the nightmare began.

Solution

Usually, we will see this on top of the post,

url-wordpress

The URL of the post page contains the post ID! So the smart alex me try to be funny and use a $_GET['post'] to try retrieve the post id after i have failed miserably on the global variable, $post upon user clicked on publish button. With hope, it fail again. So i was thinking, maybe there exist some post data instead of a get data. So i try to use $_POST['post'] to retrieve the post id. Fail (expected). Since i am using a function to tried all these methods (post,get, global variable) as shown below,

function example()
{
global $wpdb;
global $post;
echo var_dump($post)."<br />";
echo $_POST['post']."<br />";
echo $_GET['post']."<br />";
}
add_action('publish_post', 'example');

There might be a problem retrieving global variable in my function so i try doing it outside the method as shown below,

global $post;
echo var_dump($post)."<br />";
echo $_POST['post']."<br />";
echo $_GET['post']."<br />";

function example()
{
global $wpdb;
global $post;
echo var_dump($post)."<br />";
echo $_POST['post']."<br />";
echo $_GET['post']."<br />";
}
add_action('publish_post', 'example');

It still fail! Nightmare. If you look at WordPress Plugin API, on the publish_post description it state this,

Runs when a post is published, or if it is edited and its status is "published". Action function arguments: post ID.

Action function arguments: post ID? Looks like using this action hook required a function argument post ID. So i tried this instead.

function example($post_ID)
{
global $post;
echo $post_ID."<br />";
echo var_dump($post)."<br />";
echo $_POST['post']."<br />";
echo $_GET['post']."<br />";
}
add_action('publish_post', 'example');

Surprisingly, i got it! The ID is retrieved this way! No global variable available if you are using publish_post action hook!

Conclusion

I believe the reason why the global variable,$post  is not available during publish_post action hook was because the details of the post has been updated by the user and the information in the global variable are not updated. Thus, only the ID is available in the global variable if there is one. So to avoid unnecessary usage of memory, the global variable, $post was not created instead. The WordPress version for this was 2.8. Hope this help out a bit.

Tutorial: How to add action to excerpt in WordPress

In case some of you don't know what the title of this post means, it has to do with building plugin for WordPress. Let me explain  a little on what does an action means in WordPress. Basically, we can add a function to an action or event (whatever you called it) in WordPress to perform some task before or after the action or event has occured.

Problem

The reason why i bought this post up was because i nearly get frustrated working on my WordPress plugin because there wasn't any action listed in WordPress plugin API that stated an action that can be attached to an event before or after an excerpt is being bought out! Search all over the place, fail. So i decided to do a trial and guess with these action thing for my plugin to attached an event when an excerpt is being bought out.

Solution

In case you might not aware how a excerpt is being printed out on the template, they used


the_excerpt();

This will print out the excerpt in your WordPress. So i tried using the_excerpt to be placed into my WordPress add_action statement as shown below,


add_action('the_excerpt', 'hpt_attach_excerpt');

'hpt_attach_excerpt' is the function call when excerpt is being triggered. To my surprise, it work! But it will only display whatever the function, 'hpt_attach_excerpt' contains as shown below. no_exerpt_attached

So where is my regular excerpt? It seems like if i attached a defined action used in WordPress that are not listed in the WordPress Plugin API, it will be overwritten by my own method 'hpt_attach_excerpt'. I digged again to find the method in WordPress site that will provide me with the missing excerpt i was looking for. Fail. So i digged into the source code of WordPress and managed to find the key method that return the excerpt of a post, get_the_excerpt(). get_the_excerpt() is the based method that retrieve the data from the database to the_excerpt for it to filter.  Now i write the code as follow,


function hpt_attach_excerpt()
{
echo "This is the function 'hpt_attach_excerpt' produce";
echo get_the_excerpt();
}
add_action('the_excerpt', 'hpt_attach_excerpt');

Looking back to the display to check whether the attachment has completed.

found-excerpt-attached

There it is! Both my function message and my excerpt message!

P.S: You can use add_filter if you do not wish to overwrite the default function of 'the_excerpt' function.

Conclusion

If you have read through the post, you might aware that this is not only restricted to adding action for excerpt. This shows that we can add any WordPress function that are not defined in WordPress Plugin API (Offical action available) as action and rewrite or append any type of instruction to the default action given by WordPress. Can't find your action needed to perform your WordPress plugin? You just found the answer! Hope this can help many developers who are working on their plugin! ( Thanks for all the wonderful plugin developed! )

Tutorial: How to find width and height of a uploaded image with JavaScript

This is more like a clever trick to find out the height and width of a uploaded image that i would like to share with you. This method most likely will be useful to you when you are dealing with asynchronous uploading which you required the width and height of the image so that you could display the size of the preview box or window. Another usage will be user will have the ability to pre-set the width and height of each images outside the upload function which will resize the uploaded image and you will either required to query the database or look up using server scripting ( both provide redundency). This method will eliminate the need of redundency of query the database or passing the data from server scripting to JavaScript. Instead, we will just required a few sentence of JavaScript to determine the width and height of the uploaded image.

Concept

Let's take an example to demonstrate the concept. Imagine you are trying to perform a asynchronous uploading function that allow users to view their uploaded images on the screen dynamically. So we can use the simple asynchronous uploading function to perform the upload function and use asynchronous complete detection function to inform the user that it has been completed. So once we know that the upload has completed, we want to preview this image to the user right? Assuming that the upload function resize this image randomly. So what is the resize width and height of this image? There are few method that can work this out,

  1. Since we are doing asynchronous upload, we can provide the width and height of the image from the server to the client script
  2. store the width and height of the new image to the database and query it using ajax function
  3. Any other method that required additional work!

This is not efficient at all. What we really need is just JavaScript alone.

  1. Upload the image
  2. Upload completed
  3. display it on the screen
  4. set the width and height to be empty ( reset the width and height to null)
  5. create a new image object and store the new image into it
  6. retrieve the new image object width and height
  7. change the width and height of the display screen to the new image object width and height
  8. Ta-Da~

Simple and clean!

JavaScript

var imgObj = document.getElementById('uploadedImage');
var newImg = new Image();
newImg.src = imgObj.attr('src');

var height = newImg.height;
var width = newImg.width;

imgObj.style.width = width;
imgObj.style.height = height;

I shall skip the codes for PHP and HTML part on how it upload the file to the server and how the server return the images (just have to echo '' after it has been uploaded to the server) to the client as it has been demonstrated on the above link provided. What the JavaScript is trying to do is to retrieve the DOM object of the preview image send in back the server side after uploaded.  It creates a image object and insert that particular preview image into this object. Thus, we have all the information we need stored into this object and placed them into the preview box.

Demo

There are no demo for this method (since i can't store the uploaded images all on the server, it will blow after sometimes) but you can use the demo previously created on asynchronous complete detection function and add a few function into it to make it randomly resize the image you placed into, provide the width and height of each uploaded images via a pop up and resize the iframe according to the new width and height.

Tutorial: How to determine an asynchronous upload completion with JavaScript and PHP

Originally, i wanted to create a progress bar with JavaScript using Ajax as assistance to prompt the server for raw post data. But it seems like PHP doesn't provides raw post data manipulation for its users. Many uses Perl, Flash, Python and etc. which you can see where i am going (Other languages instead of PHP). PHP 5.2 onwards there is an extension to help PHP user manipulate this data but it required the end users or plugin users to adjust their PHP settings to enable certain extension and variables in the PHP setting which is not what i wanted. Therefore, this tutorial is created instead which doesn't required the end users to adjust anything and will be more welcome by programmers. (messing up the setting of PHP can result to security flaws and etc.) But the fall back of this method is that they won't be able to know the progress of upload. (in term of percentage %)

Aim

The aim of this tutorial is to demonstrate a simple method to help programmers who is dealing with iFrame or Ajax (which ever you prefer to call it) upload function to keep track of the upload completion of the file. Simple and Easy is the key objective for this tutorial.

Requirement

There are a few requirement you will need other than reading this post.

  1. Asynchronous upload function - Easy asynchronous upload function using iFrame
  2. JavaScript file - this is the main function to check whether iFrame has complete uploaded the file
  3. Read!

Concept

I like to  have a concept sub section to make my reader understand how it work before showing out all the boring codes. In order to be informed that the upload process has completed, the iFrame will have to show certain message (error and complete message) so that our JavaScript can be informed with the process of the upload function. We will accomplish this with the following steps

  1. Start uploading From iFrame
  2. loading.gif start running
  3. a 'check_complete()' function is being initialize to check the iFrame for message
  4. iFrame shows a message, determine this message (error or success) and output the result accordingly

Asynchronous upload function

Unlike the previous tutorial on asynchronous upload function, i have updated some codes into the previous codes in order demonstrate this tutorial. (Please visit the simplify version of the Asynchronous upload function on the link if you find this complicated)

HTML


<form id="my_form" name="form" action="upload.php" method="POST" enctype="multipart/form-data" >

<div id="main">
<p>
MAX SIZE: 100kb<br/>
ALLOWED FILES EXTENSION: .png, .gif, .jpg, .jpeg<br/>
Other than the above mention rules, all other type of file upload will result in error alert.<br/></p>
<input type="hidden" name="MAX_FILE_SIZE" value="100000" />
<input name="my_files" id="my_file" size="27" type="file" />
<input type="button" name="action" value="Upload" onclick="redirect()"/>
<iframe id='my_iframe' name='my_iframe' src="">
</iframe>
</div>
<div id="loading"></div>
</form>

The only differences in this part is the instruction added for the demo to work and a div block box for the loading.gif to appear.

JavaScript


function redirect()
{
document.getElementById('my_form').target = 'my_iframe'; //'my_iframe' is the name of the iframe
document.getElementById('my_form').submit();

var iFrame = document.getElementById("my_iframe");
var loading = document.getElementById("loading");
iFrame.style.display = "none";
iFrame.contentDocument.getElementsByTagName("body")[0].innerHTML = "";
loading.style.display = "block";
checkComplete();
}

In the redirect method which is also the key to use to perform this asynchronous upload function has a few more sentences as shown above which is different from the previous method that only required the first 2 sentence. The above new codes indicate that every time the upload button is pressed, the iFrame should be reminded to be disappeared and the internal of the iFrame should be empty(no message), this sentence is there so that we can perform multiple upload without any problem. Others will required loading.gif to appear to inform the users that it is in progress and the checkComplete() method (the method is located below) is invoked to start monitor the upload completion.

PHP


<?php

$uploaddir = '/images/';
$uploadfile = $uploaddir . basename($_FILES['my_files']['name']);
$file = $_FILES['my_files'];
$allowedExtensions = array("jpg", "png", "gif", "jpeg");
if($file['error'] == UPLOAD_ERR_OK) {
if(isAllowedExtension($file['name'])) {
# Do uploading here

$uploaddir = '/images/';
$uploadfile = getcwd ().$uploaddir . basename($_FILES['my_files']['name']);

//if (move_uploaded_file($_FILES['my_files']['tmp_name'], $uploadfile)) {
echo "success";
//} else {
//  echo "error";
//}
} else {
echo "Invalid file type";
}
} else die("Cannot upload");

function isAllowedExtension($fileName) {
global $allowedExtensions;

return in_array(end(explode(".", $fileName)), $allowedExtensions);
}
?>

What i have added here which is different from the previous version is that i have added a simple validation to validate extension of the files before uploading them into the server in order to demonstrate the different message of this tutorial (error and success).

CSS

Please refer to the demo files if you are interested in the CSS of this demo.

JavaScript

Here is the main method to check for the upload completion from the iFrame.


var checkComplete = function()
{
var iFrame = document.getElementById("my_iframe").contentDocument.getElementsByTagName("body")[0];
var loading = document.getElementById("loading");

if(iFrame.innerHTML == "")
{
setTimeout ( checkComplete, 2000 );
}
else
{
if(iFrame.innerHTML == "success")
{
loading.style.display = "none";
document.getElementById("my_iframe").style.display = "block";
//successful do something here!
}
else
{
loading.style.display = "none";
alert("Error: "+ iFrame.innerHTML);
}
}
}

The first few sentences take  their DOM object for loading.gif and iframe into a variable. Then we check whether the iframe 'body' block contains any message. If there isn't any message we do a recursive loop by calling itself again after 2 second else we hide the loading.gif and show the iframe message if and only if the message in the iframe is 'success' all other message will result in alert to the screen.

Demo

Determine an asynchronous upload completion demo consist of the aim of this post. However, no files will be stored in the server as i am merely providing a demo site to demonstrate this concept. The condition for a success message to appear are stated in the demo site. If you are interested to look up the overall code in this demo, you can download the file at JavaScript-upload-completion-alert. (Please be reminded you will need to setup a webserver in order to test it in your own pc)

function redirect()
{
document.getElementById('my_form').target = 'my_iframe'; //'my_iframe' is the name of the iframe
document.getElementById('my_form').submit();

var iFrame = document.getElementById("my_iframe");
var loading = document.getElementById("loading");
iFrame.style.display = "none";
iFrame.contentDocument.getElementsByTagName("body")[0].innerHTML = "";
loading.style.display = "block";
checkComplete();
}