Friday, October 5, 2012

Creating a Datepicker

I had a project recently where I needed to create a custom datepicker for a HTML form. I will walk through the basics of how I was able to accomplish this.

The CSS

My specific form required the ability for the user to add multiple dates for a specific event up to a maximum of 20. So I knew I needed to hide the unneeded date fields from view. So I created the class hidden to allow for this. The datepicker needed an absolute positioning because I wanted to move it around the page as needed.

 .hidden{
  display:none; 
 }
 #datepicker{
  background: #ccc;
  position: absolute; 
  z-index: 50;
  border: 1px solid #000;
  padding: 5px;
 }
 #closeButton{
  float:right; 
 }

The Datepicker

I used select lists to allow the user to select the date and start time. The key here was using php to pull in the current year so that I could dynamically create it. I also used php to create some for loops so that I didn't have to manually go through and type all of the options I wanted in my select lists.

<div id="datepicker" class="hidden">
 <table border="0">
  <tr>
   <td colspan="3"><strong>Date:</strong></td>
  </tr>
  <tr>
   <td>
    <select class="changeDate" id="month" name="month">
     <option id="month1" value="1">January</option>
     <option id="month2" value="2">February</option>
     <!-- etc... -->
    </select>
   </td>
   <td>   
    <select class="changeDate" id="day" name="day">
     <?php
      for($i=1; $i<32; $i++){
         echo '<option id="day'.$i.'" value="'.$i.'">'.$i.'</option>'; 
      }
     ?>
    </select>
   </td>
   <td> 
    <select class="changeDate" id="year" name="year">
     <option selected="selected" value="<?php echo date(Y); ?>"><?php echo date(Y); ?></option>
     <option value="<?php echo date(Y) + 1; ?>"><?php echo date(Y) + 1; ?></option>
     <option value="<?php echo date(Y) + 2; ?>"><?php echo date(Y) + 2; ?></option>
     <option value="<?php echo date(Y) + 3; ?>"><?php echo date(Y) + 3; ?></option>
     <option value="<?php echo date(Y) + 4; ?>"><?php echo date(Y) + 4; ?></option>
    </select>
   </td>
  </tr>
 </table>  
 <table border="0">
  <tr>
   <td colspan="3"><strong>Start Time:</strong></td>
  </tr>
  <tr>
   <td>
    <select class="changeDate" id="hour" name="hour">
     <?php
      for($i=1; $i<13; $i++){
         echo '<option id="hour'.$i.'" value="'.$i.'">'.$i.'</option>'; 
      }
     ?>
     </select>
    </td>
    <td>
     <select class="changeDate" id="minute" name="minute">
      <option id="minute00" value="00">00</option>
      <option id="minute01" value="01">01</option>
      <option id="minute02" value="02">02</option>
      <!-- etc... up to ten -->
      <?php
       for($i=10; $i<60; $i++){
         echo '<option id="minute'.$i.'" value="'.$i.'">'.$i.'</option>'; 
       }
      ?>
     </select>
    </td>
    <td>
     <select class="changeDate" id="ampm" name="ampm">
      <option id="am" value="am">am</option>
      <option id="pm" value="pm">pm</option>
     </select>
    </td>
   </tr>
  </table>   
 <input id="closeButton" type="button" value="Close"/>
</div>

The Javascript

I have condensed my code to just the basics. Please see comments for more specifics.


 $(function(){
   var globalFocus = 'required-date'; //I used this to see which date field was currently in focus
                
   $('#month<?php echo date(n);?>').attr('selected', 'selected');
   $('#day<?php echo date(j);?>').attr('selected', 'selected');
   $('#hour<?php echo date(g);?>').attr('selected', 'selected');
   $('#minute<?php echo date(i);?>').attr('selected', 'selected');
   $('#<?php echo date(a);?>').attr('selected', 'selected');
   //I used the above code to set up the defaults for the datepicker
   updateDate(globalFocus);//This sets the focused date field value
    
   $('.date').focus(function() { //corresponds to all of the date fields 
         globalFocus = $(this).attr('id');
         $('#datepicker').show();
         var position = $(this).position(); //Return position of date field to position the date picker right below it
         var height = $(this).height(); 
         $('#datepicker').css('top', position.top+height); 
         $('#datepicker').css('left', position.left);
  });

  $('.changeDate').change(function(){
        updateDate(globalFocus);
  });
  
  $('#closeButton').click(function(){
        $('#datepicker').hide();
  });
 });

 function updateDate(currentFocus){
     $('#'+currentFocus).val($('#month').val()+'/'+$('#day').val()+'/'+$('#year').val()+" "+$('#hour').val()+':'+$('#minute').val()+$('#ampm').val()+" - "+$('#hourend').val()+':'+$('#minuteend').val()+$('#ampmend').val());
 }

Saturday, August 4, 2012

HTML5 Video

A very beautiful yet frustrating improvement in HTML5 is the browser support of native video without any third party plugin with the use of the video tag.

<video controls="controls" width="352" height="288" poster="poster.jpg">
     <source src="video.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"'>
     <source src="video.ogv" type='video/ogg; codecs="theora, vorbis"'>
     <track kind="captions" src="captions.vtt" srclang=en label=English />
</video>

The controls tells the browser to use its default controls with the video. The poster is the image that should be shown while the video is being downloaded or until the user pushes the play button. I include two different source files with the video because not all browser play nicely together. Browsers like Firefox require the open video file type ogv while browser like IE 9 and Safari want the mp4 file type. The track is used to display text for captions/subtitles on the video.

There are a few problems that can keep your video from playing and the biggest ones I have run into are incorrect encoding and incorrect MIME type. Internet Explorer is the most unforgiving in both of these regards. The video needs to be encoded with H.264. I like to use ffmpeg to do this with the following command:

ffmpeg -i input.mpeg -s 352x288 -vcodec -libx264 -preset slow output.mp4
Here are two samples for webm and ogv file types.
ffmpeg -i input.mpeg -vcodec libvpx -acodec libvorbis -f webm output.webm

ffmpeg -i input.mpeg -vcodec libtheora -acodec libvorbis output.ogv

Another great utility is Miro.

Your server needs to be set up to send the correct MIME type to the browser. In apache you need to add the following to the httpd.conf file. Remember to reboot the server after doing so.

AddType video/mp4 .mp4 .m4v
AddType video/ogg .ogv
AddType video/webm .webm

I hope this is enough to get you started in the right direction. If you still have questions here are some good links to check out ffmpeg commands, trouble shooting IE9. Good luck!

Thursday, June 7, 2012

All About HTML Forms

The two things you must have when it comes to using the form tag is one the action attribute and second the method attribute. I also often use the enctype attribute when doing file uploads.

<form action="get-data.html" method="post" enctype="multipart/form-data"> </form>

The method attribute takes 'get' or 'post'. Get will send the data in plain text in the URL (not secure for more sensitive information) while post sends data as a http post transaction (more secure).

The enctype attribute specifies how the form data is encoded when submitting it to the server. I generally use enctype="multipart/form-data" when uploading a file. No characters are encoded, but it is necessary for file transactions.