dynamic form (show/hide fields)

Susanne 27 Jun, 2010
Hello,
I tried the suggestion on Your FAQ http://www.chronoengine.com/faqs.html#T%20...%20ent_50_box

point 47) how to create a dynamic form.

You'll need to download v2.0 of the script. Now edit line 15 to read
var containerTag = 'DIV';
and copy the modified script to your site components/com_chronocontact/js/ folder.



So I took the following code and created a file calles test.js in the folder /js/

 Select all
    var containerTag = 'DIV';

    var compatible = (
       document.getElementById && document.getElementsByTagName && document.createElement
       &&
       !(navigator.userAgent.indexOf('MSIE 5') != -1 && navigator.userAgent.indexOf('Mac') != -1)
       );

    if (compatible)
    {
       document.write('<style>.accessibility{display: none}</style>');
       var waitingRoom = document.createElement('div');
    }

    var hiddenFormFieldsPointers = new Object();

    function prepareForm()
    {
       if (!compatible) return;
       var marker = document.createElement(containerTag);
       marker.style.display = 'none';

       var x = document.getElementsByTagName('select');
       for (var i=0;i<x.length;i++)
          addEvent(x[i],'change',showHideFields)

       var x = document.getElementsByTagName(containerTag);
       var hiddenFields = new Array;
       for (var i=0;i<x.length;i++)
       {
          if (x[i].getAttribute('rel'))
          {
             var y = getAllFormFields(x[i]);
             x[i].nestedRels = new Array();
             for (var j=0;j<y.length;j++)
             {
                var rel = y[j].getAttribute('rel');
                if (!rel || rel == 'none') continue;
                x[i].nestedRels.push(rel);
             }
             if (!x[i].nestedRels.length) x[i].nestedRels = null;
             hiddenFields.push(x[i]);
          }
       }

       while (hiddenFields.length)
       {
          var rel = hiddenFields[0].getAttribute('rel');
          if (!hiddenFormFieldsPointers[rel])
             hiddenFormFieldsPointers[rel] = new Array();
          var relIndex = hiddenFormFieldsPointers[rel].length;
          hiddenFormFieldsPointers[rel][relIndex] = hiddenFields[0];
          var newMarker = marker.cloneNode(true);
          newMarker.id = rel + relIndex;
          hiddenFields[0].parentNode.replaceChild(newMarker,hiddenFields[0]);
          waitingRoom.appendChild(hiddenFields.shift());
       }
       
       setDefaults();
       addEvent(document,'click',showHideFields);
    }

    function setDefaults()
    {
       var y = document.getElementsByTagName('input');
       for (var i=0;i<y.length;i++)
       {
          if (y[i].checked && y[i].getAttribute('rel'))
             intoMainForm(y[i].getAttribute('rel'))
       }

       var z = document.getElementsByTagName('select');
       for (var i=0;i<z.length;i++)
       {
          if (z[i].options[z[i].selectedIndex].getAttribute('rel'))
             intoMainForm(z[i].options[z[i].selectedIndex].getAttribute('rel'))
       }

    }

    function showHideFields(e)
    {
       if (!e) var e = window.event;
       var tg = e.target || e.srcElement;

       if (tg.nodeName == 'LABEL')
       {
          var relatedFieldName = tg.getAttribute('for') || tg.getAttribute('htmlFor');
          tg = document.getElementById(relatedFieldName);
       }
          
       if (
          !(tg.nodeName == 'SELECT' && e.type == 'change')
          &&
          !(tg.nodeName == 'INPUT' && tg.getAttribute('rel'))
          ) return;

       var fieldsToBeInserted = tg.getAttribute('rel');

       if (tg.type == 'checkbox')
       {
          if (tg.checked)
             intoMainForm(fieldsToBeInserted);
          else
             intoWaitingRoom(fieldsToBeInserted);
       }
       else if (tg.type == 'radio')
       {
          removeOthers(tg.form[tg.name],fieldsToBeInserted)
          intoMainForm(fieldsToBeInserted);
       }
       else if (tg.type == 'select-one')
       {
          fieldsToBeInserted = tg.options[tg.selectedIndex].getAttribute('rel');
          removeOthers(tg.options,fieldsToBeInserted);
          intoMainForm(fieldsToBeInserted);
       }
    }

    function removeOthers(others,fieldsToBeInserted)
    {
       for (var i=0;i<others.length;i++)
       {
          var show = others[i].getAttribute('rel');
          if (show == fieldsToBeInserted) continue;
          intoWaitingRoom(show);
       }
    }

    function intoWaitingRoom(relation)
    {
       if (relation == 'none') return;
       var Elements = hiddenFormFieldsPointers[relation];
       for (var i=0;i<Elements.length;i++)
       {
          waitingRoom.appendChild(Elements[i]);
          if (Elements[i].nestedRels)
             for (var j=0;j<Elements[i].nestedRels.length;j++)
                intoWaitingRoom(Elements[i].nestedRels[j]);
       }
    }

    function intoMainForm(relation)
    {
       if (relation == 'none') return;
       var Elements = hiddenFormFieldsPointers[relation];
       for (var i=0;i<Elements.length;i++)
       {
          var insertPoint = document.getElementById(relation+i);
          insertPoint.parentNode.insertBefore(Elements[i],insertPoint);
          if (Elements[i].nestedRels)
          {
             var fields = getAllFormFields(Elements[i]);
             for (var j=0;j<fields.length;j++)
             {
                if (!fields[j].getAttribute('rel')) continue;
                if (fields[j].checked || fields[j].selected)
                   intoMainForm(fields[j].getAttribute('rel'));
             }
          }
       }
    }

    function getAllFormFields(node)
    {
       var allFormFields = new Array;
       var x = node.getElementsByTagName('input');
       for (var i=0;i<x.length;i++)
          allFormFields.push(x[i]);
       var y = node.getElementsByTagName('option');
       for (var i=0;i<y.length;i++)
          allFormFields.push(y[i]);
       return allFormFields;
    }

    /** ULTRA-SIMPLE EVENT ADDING **/

    function addEvent(obj,type,fn)
    {
       if (obj.addEventListener)
          obj.addEventListener(type,fn,false);
       else if (obj.attachEvent)
          obj.attachEvent("on"+type,fn);
    }

    addEvent(window,"load",prepareForm);


    /** PUSH AND SHIFT FOR IE5 **/

    function Array_push() {
       var A_p = 0
       for (A_p = 0; A_p < arguments.length; A_p++) {
          this[this.length] = arguments[A_p]
       }
       return this.length
    }

    if (typeof Array.prototype.push == "undefined") {
       Array.prototype.push = Array_push
    }

    function Array_shift() {
       var A_s = 0
       var response = this[0]
       for (A_s = 0; A_s < this.length-1; A_s++) {
          this[A_s] = this[A_s + 1]
       }
       this.length--
       return response
    }

    if (typeof Array.prototype.shift == "undefined") {
       Array.prototype.shift = Array_shift
    }


Here the HTML code:


Code: Select all
    <script type="text/javascript" src="/components/com_chronocontact/js/usableforms.js"></script>
    <h3>Get a Quote</h3>
    <p>Please select Floor, Room, and what service you want to be done!.</p>

    <input name="1st_floor" type="checkbox" value="No" rel="1st_floor" />
    <label for="1st_floor">First floor</label>
    <div rel="1st_floor">
    First Floor Room
      <input type="checkbox" name="1st_Bathroom" value="Yes" />
      Bathroom
      <input type="checkbox" name="1st_Kitchen" value="Yes" />
      Kitchen
      <input type="checkbox" name="1st_Living_room" value="Yes" />
      Living room
    </div>
    <br />
    <input name="Submit" type="submit" />




If you Save and click the form link you *should* find that the 'First Floor Room' checkboxes are hidden until you check the 'First Floor' box.


On my form, I see all the fields, independant of the first floor checkbox.
Could You please help me? The form is displayed http://www.publigraphix.com/publigraphiX/index.php?option=com_chronocontact&chronoformname=testsusi1

Tanks for Your help!
Susanne
GreyHead 17 Jul, 2010
Hi Susanne ,

A bit late but I just found this post again and the URL is broken.

Most likely the problem was a Javscript error of some kind.

Bob
This topic is locked and no more replies can be posted.