Tuesday, August 21, 2012

CSS: Absolute Positioning

I was using the JCarousel package to create a 'Related Items' carousel to style the WordPress plugin for 'Related Items'. CSS is a tricky area for me especially things like positioning.

On this particular piece of functionality that I was building, when the user hovered a 'Related Item', an overlay needed to pop-up exactly over it with some additional information.

Basically, a
<ul> tag is created with several <li>, each </li> <li> contains two <div> tags. One is the 'active' div and the other is the 'inactive' div. When the 'inactive' div is hovered you want the 'active' div to show.

For the most part it worked fine, however, I noticed that the first 4 related items worked fine, however, the last would hover up and over to the left rather than right over the image being hovered. So confusing. Anyway, it goes back to understanding absolute positioning.

I had the 'active' class defined like this:

.active {
width:160px;
height:160px;
display: none;
position:absolute;
top:0;
left:-1;
z-index:2;
}

This should pop this div up from its original placement to cover the 'inactive' div.

My problem was solved by explicitly making the parent of this (which in my case was  a <li> classed as 'jcarousel-item') marked as position:relative like so:

.jcarousel-skin-tango .jcarousel-item {
    width: 165px;
    height: 165px;  
    position:relative;  
}

Apparently child items that are absolutely position need the parent to be relative. By default it is static, that is why I was getting the odd last item positioned funny.

This post helped me to better understand things.




Monday, August 20, 2012

HttpWebRequest Time Out HTTPS Call

I recently had some HttpWebRequest calls begin to timeout without any error code returned. Just a timeout. I had not changed my code so I suspected that the site I was calling had changed something.

I found that I could call other HTTPS sites just fine, but this one in particular just timed out. I also tried to bypass all the certificate errors using the code:

ServicePointManager.ServerCertificateValidationCallback = (s, cert, chain, ssl) => true;

That did not work. I had the break-through moment when I found that if I change the call from HTTPS to HTTP, it worked. Although that was not going to be a fix!

After much searching, I found this post, I submitted the fix to the company and it resolved the problem.

The company had migrated the webserver which was an Apache Server. This small configuration item made some mismatch with the SSL certificate which blocked the HttpWebRequest calls I was making to the HTTPS urls.

Basically, Apache httpd.conf needed to be modified. Here is info from the post:

It had the server name like this: ServerName www.secure.mydomain.com

The certificate was registered to secure.mydomain.com, and the URL I was calling was also https://secure.mydomain.com/xxxx.html.

So simply changing the conf file to the following and restarting Apache did the trick:

ServerName secure.mydomain.com

The following would have also worked, most likely:
ServerName www.secure.mydomain.com
ServerAlias secure.mydomain.com

Hope this saves someone a major headache!

Thursday, August 16, 2012

PHP Location Redirect Error IE

This will be short. You try using the PHP location command to redirect or refresh your page. It works in Firefox but you notice that IE cuts you off with "Page cannot be displayed" error.

Look at your code very carefully:

I had this:
header("location:".$_SERVER["PHP_SELF"]);
exit();

Notice the lowercase "l" and the lack of a space after the colon, this was the problem, this fixed it:

header("Location: ".$_SERVER["PHP_SELF"]);
exit();

Apparently, IE can be picky about this...

Also, make sure you include the exit, it is important...

Tuesday, August 7, 2012

Picup App load image locally rather than using Imgur

A few months back I blogged about using the Picup app to grap iPhone/iPod/iPad pictures from their "i"-device to your website.

The part that has been bugging me was doing a remote upload to Imgur rather than a local upload to my server. I assume Imgur owns any image you upload to them which was a concern of mine.

So I spent some time yesterday trying to figure out my missing piece. I was relieved when I figured out that it was not my lack of brain power :) but rather the technology that I was using. I don't generally use classic ASP. I prefer ASP.NET/C# or PHP any day! With Classic ASP, you cannot easily upload files to your server by accessing the response.form. Instead, you have to download one of several 3rd party components to get the files, which then you have to register the dll blah blah blah.

However, on my server I happened to also have access to PHP. Out of frustration, I thought I will just try all my code on PHP to see if the upload will work. And it did...easily.

So to re-iterate the steps:

STEP 1. Create initial page with an input button, here is a short sample:
<html>
<header></header>
<body class="iphone" onLoad="loadMobile();" >
<form method="post" name="form1">

<input type="file" name="attach1" id="attach1"/>

</body></form></html>
STEP 2. Add script calls to that page.
<script type="text/javascript" src="js/picup.js"></script>
<script type="text/javascript" src="js/prototype.js"></script>
STEP 3. Add javascript function that sets up picup app settings. This function is loaded on the body "onLoad" see step 1. You could probably use jQuery to load this after document ready...
<SCRIPT TYPE="text/javascript">
function loadMobile(){

Picup.checkHash();
var url = escape('http://yourwebsite.com/uploadPhoto.asp');
var posturl = escape('http://yourwebsite.com/get-posted.php');

currentParams = {
'callbackURL': url, //the page called after upload.
'referrername'   : escape('mywebsitename'),
'referrerfavicon'  : escape('http://yourwebsite.com/images/favicon.ico'),
'purpose'               : escape('Select...message to user..'),
'debug'   : 'false',
'returnThumbnailDataURL': 'false',
'thumbnailSize'         : '80',
'postURL': posturl,    //the page that will upload the photo
'returnServerResponse':'true' //returns output of posturl
};

Picup.convertFileInput($('attach1'), currentParams);
}
</script>
STEP 4. Setup the "postURL" page, for me it is a simple PHP file. It outputs the name of the file as the response body so that my callback page can get the file name and update records accordingly.
<?php
if (isset($_FILES)){
 foreach ($_FILES as $key => $file){
  move_uploaded_file($file['tmp_name'], 'photos/'.$file['name']);
  echo $file['name'];
 }
}
?>
STEP 5. Setup the javascript on the callback page to grab the file name...and anything else that it needs.
<SCRIPT TYPE="text/javascript">
var fileName = unescape(getHashUrlVars()['serverResponse']);
var success = getHashUrlVars()['status'];

//parse hashed values from url
function getHashUrlVars(){
 var vars = [], hash;
 var hashes = window.location.href.slice(window.location.href.indexOf('#') + 1).split('&');
 for(var i = 0; i < hashes.length; i++)
 {
 hash = hashes[i].split('=');
 vars.push(hash[0]);
 vars[hash[0]] = hash[1];
 }
 return vars;
}

....process as needed

I hope this helps.

Thursday, August 2, 2012

CSS: Using Fieldset in place of Tables to lay out form information

Typically, I've used tables or nested div tags to lay out a page that has label/input items for forms such as "Contact Us". Although tables and div tags can work fine, I found that using a fieldset tag with label and input tags can be very easy to use with a little CSS to help things along.

First here is a sample fieldset layout:
<fieldset>
<label for="name">Name</label>
<input type="text" name="name" id="name" />
<label for="phone">Phone Number</label>
<input type="text" name="phone" id="phone" />
</fieldset>

Which looks as follows:
This will layout the data from top to bottom, vertically. Now the problem is the default spacing and border stuff. To control this, attach a stylesheet or style tag with class definitions as follows:
/*get rid of gray border*/
.styleFieldset {border: 0 none;}

/*style the input fields*/
.styleFieldset input{
border: solid;
border-color:#9FB6CD;
border-width: thin;
background: #FFF;
width: 250px;
height: 25px;
font-size:100%;
float: left;
clear: left;
border-radius: 3px;
color: #4F4F4F;
}

/*style the label fields*/
.styleFieldset label {
float: left;
clear: left;
text-align:left; 
width:250x; 
color:#006296;
font-weight:bold;
padding-bottom:5px;
padding-top:12px}
Which then you would apply the class as follows:

<fieldset class='styleFieldset'>
<label for="name">Name</label>
<input type="text" name="name" id="name" />
<label for="phone">Phone Number</label>
<input type="text" name="phone" id="phone" />
</fieldset>

And finally should look as follows: