Another IE6 issue

The world is beginning to move on from IE6 and hopefully, we won’t need to code with IE6 specifics in mind anymore. However, if you have to test your websites on IE6, then this information might be of some use to you.

Let’s consider the following situation. You want to make a custom form, and besides the usual ‘input’ elements, you have some other components, like divs or images. In this case, it is very likely that you might need to float the elements to have them positioned correctly. To be even more specific, let’s say that you need to have an input box next to a div, so both will be floated to the left.

Ok, that sounds simple enough, let’s have a look at some mark-up:

<div id="ref"></div>
<div class="float-left">
	<input type="text" id="inputBox" />
</div>

Now for the CSS code:

.float-left
{
	float:left;
}

#inputBox
{
	background-color:#006699;
	border:0;
	margin:0;
}

#ref
{
	background-color:#006699;
	float:left;
	height:18px;
	width:75px;

We’ll use the first div as a reference point to fully understand the issue presented in this post.

So, like I said, we have a left-floated div, and another one which contains an input box. You can see the result here. Notice how it looks on IE6, as opposed to Firefox, Chrome and Safari. If you don’t have IE6 (I salute you for it), here is a photo of what this issue looks like (on the left is the reference div and on the right, the input box):

IE6 float/margin issue

IE6 float/margin issue

Why does this happen, you ask? Well, it seems that IE6 adds some margins to input elements, or it adds some padding to containers of input elements, even if you specify that no margin or padding is to be applied, using CSS.

And now, for the moment we’ve all been waiting for. The actual fix. I must admit, I found the solution by accident. In order to fix this issue, you need to float the input box, instead of the container. Some of you might say that it’s logical to be this way, however, I have to disagree. An input box is not considered to be a structural element per say, unlike a div. I know that you shouldn’t overuse divs to define the structure of a page, but it’s useful to contain other elements in divs, since IE and the rest of the browsers have different methods of rendering them.

Remember this simple idea, and hopefully some time from now you will have saved hours of nail-biting, hair-pulling, teeth-grinding, IE6-cursing agony… oh yeah, we have all been there before.

So consider this mark-up, as opposed to the previous one:

<div id="ref">
</div>
<input type="text" id="inputBox" class="float-left" />

Before we end another article, I have to point out one more thing. IE6 is notorious for minding blank spaces in the page code. This means that if you like to write clean, structured, easy-to-read code, you might run into problems similar to this one. The easiest way to fix this problem, is to specify the ‘font-size:0px;‘ property for the whole page, and then redefine the text properties for span, p etc. elements.

Posted in: HTML/CSS

CSS header trick

Hello people. Let me start by saying that I know an article is overdue. However, when work piles up, and then you add a certain amount of WoW to your free time, you have a genuine recipe for no free time whatsoever… But I have been thinking hard about the next topic so today we will discuss another cool-looking, and useful effect.

Let’s say you have a website, in which the header is centered and the background image is asymmetric. What does that mean? Well, it means that the left margin is different than the right in terms of aspect, and furthermore, it means that if you tile an image with a width of 1px (height equal to the header’s) you won’t get a correctly tiled header.

Here is an example: link

So, the first thing that comes to mind is how to get an element with two background images. Searching the internets, I found no quick solution, so here is my way of solving this problem:

Having two tile-images (left and right), both with a 1px width, we can make two divs that overlap and on top of them, the header. Well, that seems simple enough, and it really is. Here is how to do it:

1. You make one div with a width of 100% (width of the page), and the height equal to that of the header, also with the background image created using the first column of pixels from the header background. This is how you would normally go about making an symmetric header.

2. Make a div with a width of 50% (half of the page’s width), same height and a background image created using the last column of pixels from the header image. This div has another property unlike the first one, it has the margin-top property equal to the negative height of the header. Now we’ll have two divs that seem to have a 50% width next to each other.

3. Finally, we add the header div, width the same margin-top property of the second div.

And here we have it! An asymmetrical header that tiles on both sides. This technique can be used also to tile the footer. If you want to tile the content div this way, you need to take into account the fact that its height can vary. This means that you have to modify the height of the left and right divs to match the height of the content. Some simple Javascript code can do the trick.

Posted in: HTML/CSS

A nifty Javascript library

I recently found a Javascript library which adds a nice effect to a website. It’s called jParalax and what it does is create layers from an element and its children to give a nice effect. The layers are absolutely positioned and move in response to the mouse, to give a parallax effect. They have the script available for download, and many nice demos.

Here is the link.

Posted in: Javascript

Fun with Javascript

I must admit I always felt fascinated by the limitless possibilities of creating rich user interfaces using Javascript. You can see all sorts of examples out there, but it’s always a lot of fun to mess around with the code to get your own results, plus, as a web developer, it keeps you in shape.

The latest experiment resembles the igoogle interface, meaning you can drag and drop divs around, and also have certain areas where a div can snap to a predefined position.

So, you can check it out here, and if you want to look at the source code, click here.

I didn’t have any idea what to call this one, so I named it DivOps, short for Div Operations…

I used Firefox for development, so please don’t comment on the way it works on IE and other browsers. I have checked it on IE just for the hell of it, and except the fact that it calculates to margins differently, it works just the same.

Posted in: Javascript

AJAX shopping cart

Hello. This time we’ll discus writing a simple AJAX-driven shopping cart. Again, a challenge that has many solutions, but I prefer to write my own code. Especially for these posts… Like always, we need to discus the languages used and then we can talk about the code. Also, I will provide the full source code this time. You can find it here.

Also, you can see the project here.

Since we’ll use AJAX, we’ll have to write PHP and Javascript code, and of course HTML with a bit of CSS (for the interface). The JS part of the application will send requests to a PHP script, which takes the id of the item that needs to be added, and then display the response text in a container, which is our cart. The JS function sends via XMLHttpRequest two parameters, the first being the id of the item, and the second being a add/subtract ’switch’ (1 - add, 0 - subtract).

Now for the server side part. Since we need to manipulate a series of items, the first thing that comes to mind, is an array. And furthermore, since we need to pass this item from one file to another, we can uses sessions. So, we use a session-stored array to hold out items like this:

Array(
    [item_id1] => quantity1
    [item_id2] => quantity2
    [item_id3] => quantity3
    . . .
);

This is how it looks in PHP:

<?php
session_start();
$_SESSION['items'] = array();
?>

This way we can keep all the information in one array (rather than keeping item_id’s and quantity separately, or using objects).

So, what happens when we send a request? Well, first, the server side script recieves the two parameters, the id and the ’switch’; If the id that was sent is equal to 0, then it means the user wants to empty the shopping, so we do just that, we empty the array and then we exit.

session_start();
$id = $_POST['id'];

if($id == 0)
{
	array_splice($_SESSION['items'], 0);
	exit();
}

If that’s not the case, we need to manipulate an item. We do this by checking if a key equal to the sent id hasn’t been added to the array. In this case, then we simply add an item, else if the switch is equal to 1, we increase the quantity of the item by 1, and if it’s equal to 0, we subtract by 1.

if(!array_key_exists($id, $_SESSION['items']))
	$_SESSION['items'][$id] = 1;
else
	($_POST['add']) ? $_SESSION['items'][$id]++ : $_SESSION['items'][$id]--;

The final step is sending the response text back to the client side, so we just display the result. We parse the array, and display the data in the form we want it. In this case I have used a table:

<table>
<?php
foreach($_SESSION['items'] as $key => $quantity)
{
	if($quantity <= 0)
		unset($_SESSION['items'][$key]);
	else
	{
	?>
	<tr>
		<td width="50"><div class="item<?php echo $key;?>"></div></td>
		<td width="50">x <?php echo $quantity;?></td>
		<td width="150" align="right">
			<a href="#" onclick="sendRequest(<?php echo $key;?>,1);">+</a>
			 /
			<a href="#" onclick="sendRequest(<?php echo $key;?>,0);">-</a>
		</td>
	</tr>
	<?php
	}
}
?>
</table>

Ok. Now that the text is formated nicely, we can add it to the cart, I mean, we let the client side script handle that… So that’s basically it. I won’t go into to much detail about the code, since you can find the source code here.

Feel free to experiment with it and post you version here. If you need any further info, please ask.

Posted in: AJAX

Sponsored links - alternative solution

This time, we’ll do something a little bit different. I want to explain an idea based on a project.

The project was, in fact, a web directory for all the companies in my city. Each company had an image attached, and a link (besides the normal stuff, like name, phone number etc.). This was the basic package, meaning that a company could appear on the site for free. However, there was an option for customers which wanted to pay, in order to get their name faster to the users of the site… Because, really, this was the main idea to begin with.

So, besides the above-mentioned items, a paying company could add 3 photos more (like a small gallery), a wide description, and…oh yes, “sponsored link” treatment. What this means is that, if a user searches for something within the page, the first results would be the ones with a paid account. Pretty nifty, if I may say so myself.

And here is where the main discussion starts. How to go about implementing a sponsored links search system. As I’m sure you all are guessing there are many ways to do this, so I’ll only be talking about one.

For this, I used PHP, MySQL and a small bit of Javascript. We won’t focus so much on the first two, because it should be very easy implement a system that adds/modifies/removes items from a MySQL database using PHP for sending queries.

I will say that each item had a field to determine if it is sponsored or not, a simple, boolean (true/false) field. For the search system I used Sphider. It is a very nice search script, which crawls a site and then indexes the inner pages, based on keywords. Of course the tricky part was to modify the script in order to recognize the pages with a paid account. That means linking a search result with the MySQL database in order to determine its status.

With that out of the way, the only obstacle left was to display the sponsored links first. That was a challenge because the database didn’t make a difference between a paid and a free account (except for that certain field), and a “SELECT” query would return all the items regardless of their status.

And now, on to the final part of the story. For such a vast introduction, I know you would expect for an ending to match. But I have to say right from the start, that it’s a simple idea, but works really well in this situation. Sphider returns search results in the form of an array, which can be parsed in order to display the results. This was of great help, because each result can be manipulated individually. That means they can be styled or whatnot…but in this case they can be displayed as sponsored links, if that’s the case.

So, how do you display the sponsored links at the top of the page, even if they are at the bottom of the database? Easy:

You make a container <div> before the results and append the sponsored links to it. That way, they will be on top regardless of their previous order. Another simple but very effective concept. Unfortunately I can’t post any source code this time because I don’t have it anymore…but I have a small script which shows this concept:

<div id="div1" style="height:100px; width:300px; border:1px solid red;"></div>
<div id="div2" style="height:75px; width:250px; border:1px solid blue;"></div>

<script language="javascript">
var el1 = document.getElementById('div1');
var el2 = document.getElementById('div2');
el1.appendChild(el2)
</script>

That might not be much, but if you ever had to do something similar, I have no doubt this article was at least a little bit helpful. So, I hope you enjoyed reading this, because when I searched for some hints on this topic, I didn’t manage to find any out there.

Posted in: Javascript

PHP-XML selectors

We all know the getElementsByTagName function. However, wouldn’t it be nice to have a standard function for selecting elements based on an attribute value? Of course it would, but first we need to think about whether we need just the first element with the specific attribute, or all of them.

In the first case, things are pretty simple. All we do is use getElementsByTagName, which returns an array of elements with that specific tag name, and then we loop through it. In case we find an element with that certain attribute, we return it. If we don’t find any elements with that attribute value, we return NULL.

Here is the function:


function getElementByAttribute(DOMDocument $dom_xml,
 $tagname, $att_name, $att_value)
{
	$items = $dom_xml->getElementsByTagName($tagname);
	foreach($items as $item)
		if($item->getAttribute($att_name) == $att_value)
			return $item;
	return NULL;
}

Ok, pretty straightforward. We need to pass the xml handler(in case there are more than one), the tag name, the attribute name, then last and most important, the attribute value. This function returns a reference to that specific item in the xml file, so we can use all the functions associated with an xml item, like setAttribute, getAttribute etc.

Now, if we need all the elements which have the same attribute value, we have to write a function which stores them in an array and then returns it. I’ll say right from the start, I’m not really sure this is the best way to go about it, since this way you won’t be able to use the item(<index>) function, but the standard way for accessing items, array_name[<index>], works. So, it shouldn’t be too much of a problem. If you guys have any better ideas, please share them, they are very welcome.

So, on with the code:


function getElementsByAttribute(DOMDocument $dom_xml,
 $tagname, $att_name, $att_value)
{
	$array = array();
	$items = $dom_xml->getElementsByTagName($tagname);
	foreach($items as $item)
		if($item->getAttribute($att_name) == $att_value)
			array_push($array, $item);
	return $array;
}

That should do nicely. Function parameters have the same meaning as above.

Posted in: PHP

Equal height columns

There are many solutions out there regarding this old problem, of course, some better than others, and I had to try a come up with my own way of doing this. My question was how to set the height property of a div 100% of the container, which had the height set to auto. This could be used for the initial problem.

If we use Javascript, this can be very easily achieved.

First, let’s take a look at the mark-up:

<div id="container">
	<div id="column1">
	...
	</div>

	<div id="column2">
	...
	</div>
</div>

A standard container, with two child <div>’s. Now for the CSS:

#container
{
	width:402px;
	height:auto;
	overflow:auto;
	border:1px solid red;
}

#column1
{
	width:200px;
	height:auto;
	float:left;
	background-color:#00CC99;
}

#column2
{
	width:200px;
	height:auto;
	float:left;
	background-color:#0066FF;
}

Finally, we add a small script, just before the </body> tag:

<script language="javascript">
div1 = document.getElementById('column1');
div2 = document.getElementById('column2');

if(div1.offsetHeight > div2.offsetHeight)
	div2.style.height = div1.offsetHeight + 'px';
else
	div1.style.height = div2.offsetHeight + 'px';
</script>

The basic idea is to just set the height property of the smaller <div> equal to the taller one. Ok, that might not be the ultimate solution to this problem but it works if you need a quick way of rendering columns of equal height and you don’t want to use Faux columns.

You can see this little demo here.

Posted in: HTML/CSS

Finally…

We all knew it was inevitable. It was just a matter a time, with no end in sight, however…but it’s finally here:

http://idroppedie6.com

Posted in: Uncategorized

XML array sorting using AJAX

Back again with a new post! This time, we’ll discuss how to make a sortable table using AJAX. This can be very useful when you make a site that displays items in the form of a list(table), and the user needs to sort the table using a specific criteria by clicking on a field.

In order to proceed, I’ll just mention a few things we need to know:

1. The list of items is stored in a XML file, therefore we’ll be loading the file using PHP.

2. In order to display the array without refreshing the page, we need to use XmlHttpObject so we can send a request to the server, in order to sort the array

3. The array isn’t sorted per say, we just need to retrieve a list of indices that defines the order of the items, in this case alpha-ascending order. This saves time because the server doesn’t need to do too many operations in order to sort the table.

You can see the project in action here.

Now that we have mentioned these things, we can proceed to analyze the project in detail.

1.

The XML file holds our list of items in the form of elements. Each element has three attributes which hold the value for that specific field. Since this is just a demo, I have used generic values:

<list>
  <item field1="Value 1" field2="Value 2" field3="Value 3"/>
  <item field1="Value 2" field2="Value 4" field3="Value 1"/>
  <item field1="Value 3" field2="Value 3" field3="Value 4"/>
  <item field1="Value 4" field2="Value 1" field3="Value 2"/>
</list>

Loading a XML file in a variable is simple enough using PHP 5:

$xml = new DomDocument(’1.0′);
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);

And getting the items is also very simple:

$items = $xml->getElementsByTagName(’item’);

2.

Now that we have discussed the XML structure and the PHP-loading part, we can talk about how to use AJAX to sort the array using a request object and displaying the result.

The easiest way to create a request object is to use a function which returns an instance of the created object so you can store it in a variable, like this:


function GetXmlHttpObject()
{
	var xmlHttpObj = null;
	try
	{
		//Firefox, Opera8.0+, Safari
		xmlHttpObj = new XMLHttpRequest();
	}
	catch (e)
	{
		//Internet Explorer
		try
    		{
    			xmlHttpObj = new ActiveXObject("Msxml2.XMLHTTP");
    		}
		catch (e)
		{
			xmlHttpObj = new ActiveXObject("Microsoft.XMLHTTP");
		}
	}
	return xmlHttpObj;
}

The next step is to write the function which sends the request, and handles the response text. First we create a request object, then we form the string we want to send to the server, using the request, and finally, we write a function to determine if the request’s state has changed and therefore, a response is available. If the server has generated a response, another function handles the text. First the function to send the request:

function sendRequest(url, crit) //the url of the PHP script and the sorting criteria
{
	xmlhttpobj = GetXmlHttpObject(); //the above mentioned function

	if (xmlhttpobj == null)
	{
		alert ("Your browser does not support AJAX!");
		return;
	}

	var string = 'crit=' + crit; //string to send using the request

	xmlhttpobj.onreadystatechange = stateChanged;
	xmlhttpobj.open("POST", url, true); //we'll get the criteria using the $_POST variable
	//request headers
	xmlhttpobj.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
	xmlhttpobj.setRequestHeader("Content-length", string.length);
	xmlhttpobj.setRequestHeader("Connection", "close");

	xmlhttpobj.send(string);
}

Ok. This is the main function of our request sending script. Now, the only thing left, is to write the function which handles the server response upon the state change. This is again easy, since we only need to determine if the response has arrived. We do this by asking if the request’s ready state is 4, then we put the response text in a <div> element which has the id ‘container’:

function stateChanged()
{
    if (xmlhttpobj.readyState == 4) //global variable
        document.getElementById("container").innerHTML = xmlhttpobj.responseText;
}

3.

The final part of the application is the server-side script which handles the array sorting. Like I said in the beginning, we don’t actually need to sort the entire array, instead we just form an array of indices (corresponding to each item of the list) that defines the order in which we want to display the items, in this case, alpha-ascending order by one of the three fields. The algorithm loops through the items array and determines the index of the item with the minimal (alpha-ascending) that hasn’t been added to the index array. After one loop we get the index of the item that needs to be added at that particular moment, and after doing this for each item, we get an array that stores the indices of the items in alpha-ascending order.


function sort_xml(DOMDocument $s_xml, $att, &$array)
{
	$items = $s_xml->getElementsByTagName('item');
	$index = 0;
	$con = 0;

	for($i=0; $i<$items->length; $i++)
	{
		$con = 0;
		$min_att = 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzz';
		foreach($items as $item)
		{
			if(strcmp($item->getAttribute($att), $min_att) < 0 && !added($con, $array))
			{
				$min_att = $item->getAttribute($att);
				$index = $con;
			}
			$con++;

		}
		array_push($array, $index);
	}
}

The function which determines if an index has been already added:


function added($index, $array)
{
        for($i=0; $i<sizeof($array); $i++)
                if($array[$i] == $index)
                        return true;
        return false;
}

Now that we have a way to sort the array, the only thing left is to display the results according to the index array. First, we call the sort function:


$xml = new DomDocument('1.0');
$xml->preserveWhiteSpace = false;
$xml->load([ XML file ]);
$crit = $_POST['crit'];
$index_array = array();


sort_xml($xml, $crit, $index_array);

The we simply display the sorted table, since it will be handled as a response text:

<table>
	<tr bgcolor="#006699">
		<td width="100" onclick="sendRequest('scripts/table-script.php','field1')">
			<span class="heading">Field 1</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field2')">
			<span class="heading">Field 2</span>
		</td>
		<td width="100" onclick="sendRequest('scripts/table-script.php','field3')">
			<span class="heading">Field 3</span>
		</td>
	</tr>
	<?php
	$items = $xml->getElementsByTagName('item');
	for($i=0; $i<sizeof($index_array); $i++)
	{
		$item = $items->item($index_array[$i]);
		?>
		<tr bgcolor="#006699">
			<td><?php echo $item->getAttribute('field1');?></td>
			<td><?php echo $item->getAttribute('field2');?></td>
			<td><?php echo $item->getAttribute('field3');?></td>
		</tr>
		<?php
	}
	?>
</table>

We add the onclick attribute for all the field columns, and that’s it. Click here for a demo of this post.

Posted in: AJAX