views:

23

answers:

0

I'm using jQuery UI tabs to display a few pages of a pretty big form my users have to fill out. The form is, unfortunately, Web 2.0. It has the 'Add more' buttons to add extra inputs to the array, there's one tab that utilizes jQuery UI's draggable() functionality as a kind of 'add more alternative'.

Basically, there's a lot of Javascript stuff going in for each tab and it's making load callback for jQuery UI tabs quite huge.

Here's an extract of my code:

$(document).ready(function()
{
   $tabs  = $('#tabs');
   $flash = $('div#flash');

   $tabs.tabs({ cache: true, disabled: tabArray, load: function(ui)
   {
      // set the globals
      tabIndex     = $tabs.tabs('option', 'selected');
      $currentTab  = $tabs.children('div:eq(' + tabIndex + ')');
      $tabForm     = $currentTab.children('form');

      // ajax up the form
      $tabForm.ajaxForm({ beforeSend: function() { $flash.innerHTML = ''; }, success: function(response) { handleFormResponse(response); } });

      // call the tab's function
      switch (tabIndex)
      {
         case 0: tab1();
            break;
         case 1: tab2();
            break;
         case 2: tab3();
            break;
      }
   }});
});

function tab3()
{
   // cache the fieldset
   var addmore = $tabForm.find('fieldset.group:eq(0)')[0].innerHTML;

   styleElements($tabForm);
   initRemoveset();

   $tabForm.find('.addmore').bind('click', function()
   {
      var $current = $(this);
      var type     = $current[0].tagName;
      var newIndex = $tabForm.find('fieldset.group').length + 1;

      if (type == 'INPUT')
      {
         // add in a new set and clear all the inputs
         var $addmore = $('<fieldset class="group droppable" style="background: #E0DFDE; padding: 5px; margin-bottom: 15px; border: 1px solid #8B8A88; position: relative;">' + addmore + '</fieldset>');
         $addmore.insertBefore($current);

         updateNamesArray($addmore, newIndex);
         clearinputs($addmore, true);

         styleElements($addmore);
      }

      if (type == 'LABEL')
      {
         // add in a new set, clear the inputs and then add the inputs in from the clicked set
         var $addmore  = $('<fieldset class="group droppable" style="background: #E0DFDE; padding: 5px; margin-bottom: 15px; border: 1px solid #8B8A88; position: relative;">' + addmore + '</fieldset>');
         var $fieldset = $current.parents('fieldset');
         $addmore.insertAfter($fieldset);

         updateNamesArray($addmore, newIndex);
         clearinputs($addmore, true);

         // aight, put the old data back in the new set
         var replacements  = {};
         replacements['1'] = $fieldset.find('input:eq(2)')[0].value;
         replacements['2'] = $fieldset.find('input:eq(3)')[0].value;
         replacements['3'] = $fieldset.find('input:eq(4)')[0].value;
         replacements['4'] = $fieldset.find('input:eq(5)')[0].value;

         for (input in replacements)
         {
            $addmore.find('input:eq(' + input + ')')[0].value = replacements[input];
         }

         styleElements($addmore);
      }

      if (type == 'IMG')
      {
         var $input = $current.prev('input');
         var skill  = $input[0].value;

         if (skill == '') return;

         var $output  = $tabForm.find('ul#data');
         var $skill   = $('<li><input type="checkbox" checked="checked" value="' + skill + '" name="skill-0" /\> <label>' + skill + '</label></li>');
         var newIndex = $output.children('li').length + 1;

         updateNamesArray($skill, newIndex);
         styleElements($skill);

         $skill.appendTo($output);
         $input[0].value = '';
      }
   });
}

function clearinputs($set, inputs)
{
   $set.find('ul#resp')[0].innerHTML = '';
   $set.find('input[type="checkbox"]')[0].checked = false;

   $set.find('select').each(function()
   {
      var $select = $(this);

      $select[0].disabled = false;
      $select.children('option:eq(0)')[0].selected = true;
   });

   if (typeof(inputs) == 'boolean')
   {
      $set.find('input[type="text"]').each(function()
      {
         $(this)[0].value = '';
      });
   }
   else
   {
      for (var i = 0, j = inputs.length; i < j; i++)
      {
         var $input = $set.find('input[name="' + inputs[i] + '"]')[0].value = '';
      }

      $input = null;
   }

   $set = null;
}

function updateNamesArray($set, newIndex)
{
   var findnametype = function(inputname)
   {
      if (inputname.indexOf('-') != -1 && inputname.indexOf('.') != -1)
      {
         var data1 = inputname.split('-');
         var data2 = data1[1].split('.');

         // [type, set, index]
         return [1, data1[0], parseInt(data2[0])]
      }

      if (inputname.indexOf('-') != -1 && inputname.indexOf('.') == -1)
      {
         var data = inputname.split('-');

         return [2, data[0], data[1]];
      }

      return false;
   };

   var type = findnametype($set.find('input:eq(0)')[0].name);

   $set.find('input, select').each(function()
   {
      var $input   = $(this);

      var oldname  = $input[0].name;
      var newname  = false;

      switch (type[0])
      {
         case 1: newname = oldname.replace('-' + type[2], '-' + newIndex);
            break;
         case 2: newname = oldname.replace('-' + type[2], '-' + newIndex);
            break;
      }

      $input[0].name = newname;
   });

   $set = null;

   return type;
}

It's at the point where I hate it. I'm looking for some pointers on improving it.

How should I handle the javascript for each tab? Any pointers on improving the code would be much appreciated.