2

I'm trying to create a html tabbed form where each named tab has a common set of inputs defined in a common div. When submit is hit, I'd like all the inputs from all the tabs are returned. Not a problem if unchecked checkboxes are missed.

Each input needs a unique id based on the tab name. I've tried a couple of ways, but I can't seem to get it right.

A simple code example would be great. Using jquery,and ajax is not a problem,

cheers.

edit: The inputs are copied/appended to the correct div in the tab content div. I want to change the name and id of the inputs by combining them with tab name. The children in the destination div are undefined, so I can't rename the inputs.

Here is the code:

<script>

  // More hackery, list the tab divs
  var tabs = ["tab1","tab2"];
  var currenttab = '';

  function showTab( tab ){

      // Make sure all the tabs are hidden
      for(i=0; i < tabs.length; i++){
        var obj = document.getElementById(tabs[i]);
        obj.style.display = "none";
      }

      // show the 'one' tab we're interested in
      obj.style.display = "block";

  }

function aciOnload() {

  // Get the tab we're interested in
  var objs =[]; 

  for(var i = 0; i < tabs.length; i++){
    var obj= document.getElementById(tabs[i]);

    // Find the correct div
    var cldrn = obj.childNodes;
    for(var m = 0; m < cldrn.length; m++)
    {
      if(cldrn.item(m).id == "common")
      {
        // Copy the common content over to the tab
        var child = cldrn.item(m);
        child.innerHTML ='';
        child.innerHTML += document.getElementById("common_stuff").innerHTML;
        eval(child);

        var inputs = child.childNodes;
        // Change the input names
        // ***NOTE: there a 3 childNodes which are "undefined"***
        for (var n = 0; n< inputs.length; n++){            
          if (inputs.item(n).tag == 'input'){
            inputs.item(n).id= tabs[i] +'_' + inputs.item(n).id;
            inputs.item(n).name= tabs[i] +'_' + inputs.item(n).name;
          }
        }

        break;
      }
    }
  }
}
// run our loader
//    if(typeof aciOnload=='function')aciOnload();
</script>
</head>

<body onload='aciOnload()'>

<h1>Tabbed Form</h1>


<hr/>

<div class="tabs">
  <a class="tab" onclick="showTab('tab1')">Tab One</a>
  <a class="tab" onclick="showTab('tab2')">Tab Two</a>
</div>

<form name="myForm" action="#" >

        <!-- note that for the first tab we need to
             manually set the display to visible -->
  <div id="tab1" class="tabContent" style="display:block">
    <div id="common" >
    </div>
  </div>

  <div id="tab2" class="tabContent">
    <div id="common" >
    </div>
  </div>
  <input type="submit" action="http://example.com/" method="post">

</form>

<div id="common_stuff" class="common_stuff" >
    <table>
      <tr>
          <td>Field One: </td>
          <td><input type="text" name="fieldOne" id="exfieldOne" value=""/></td>
      </tr>
      <tr>
          <td>Field Two: </td>
          <td><input type="text" name="fieldTwo" id="exfieldTwo" value=""/></td>
      </tr>
      <tr>
          <td>Field Three: </td>
          <td><input type="text" name="fieldThree" id="exfieldThree" value=""/></td>
      </tr>
    </table>
 </div>    
<hr>
</body>

Edit2: Here is the working code:

    <script>

  // this is a bit of a hack here
  // just list the tab content divs here
  var tabs = ["tab1","tab2"];
  var currenttab = '';

  function showTab( tab ){

      // Make sure all the tabs are hidden
      for(i=0; i < tabs.length; i++){
        var obj = document.getElementById(tabs[i]);
        if (tabs[i] == tab){
          var currenttab = obj;
        }
        obj.style.display = "none";
      }

      // show the tab we're interested in
      currenttab.style.display = "block";

  }

function aciOnload() {

  // Get the tab we're interested in


  for(var i = 0; i < tabs.length; i++){
    var obj= document.getElementById(tabs[i]);

    // Find the correct div
    var cldrn = obj.childNodes;
    for(var m = 0; m < cldrn.length; m++)
    {
      if(cldrn[m].id == "common")
      {
        // Copy the common content over to the tab
        var child = cldrn[m];
        var cc = document.getElementById("common_stuff");
        var ccc = cc.childNodes;
        // collect and clone tables
        for (var n = 0; n< ccc.length; n++){
          if ( ccc[n].tagName == "TABLE"){
            var tbl = ccc[n].cloneNode(true);
            child.appendChild(tbl);
            for (r=0;r<tbl.rows.length;r++){
              var row = tbl.rows[r];
              for (c=0; c< row.cells.length;c++){
                var cell = row.cells[c];
                var inputs = cell.childNodes;
                for (s=0;s< inputs.length; s++){
                  if(inputs[s].tagName == "INPUT"){
                    inputs[s].id= tabs[i] +'_' + inputs[s].id;
                    inputs[s].name= tabs[i] +'_' + inputs[s].name;
                  }
                }
              }
            }
          }
        }     

        break;
      }
    }
  }
}

// run our loader
//    if(typeof aciOnload=='function')aciOnload();
</script>
</head>

<body onload='aciOnload()'>

<h1>Tabbed Form</h1>


<hr/>

<div class="tabs">
  <a class="tab" onclick="showTab('tab1')">Tab One</a>
  <a class="tab" onclick="showTab('tab2')">Tab Two</a>
</div>

<form name="myForm" action="#" >

        <!-- note that for the first tab we need to
             manually set the display to visible -->
  <div id="tab1" class="tabContent" style="display:block">
    <div id="common" >
    </div>
  </div>

  <div id="tab2" class="tabContent">
    <div id="common" >
    </div>
  </div>
  <input type="submit" action="http://example.com/" method="post">

</form>

<div id="common_stuff" class="common_stuff" >
    <table>
      <tr>
          <td>Field One: </td>
          <td><input type="text" name="fieldOne" id="exfieldOne" value=""/></td>
      </tr>
      <tr>
          <td>Field Two: </td>
          <td><input type="text" name="fieldTwo" id="exfieldTwo" value=""/></td>
      </tr>
      <tr>
          <td>Field Three: </td>
          <td><input type="text" name="fieldThree" id="exfieldThree" value=""/></td>
      </tr>
    </table>
 </div>    
<hr>
</body>
</html>
Mat
  • 202,337
  • 40
  • 393
  • 406
garyM
  • 802
  • 2
  • 12
  • 29
  • Can you please show your current structure, or a cut-down version thereof with at least, say, two tabs? When you say "each named tab has a common set of inputs defined in a common div" do you mean that multiple tabs have fields mapping to the same common field? This doesn't seem to fit with the requirement to submit all fields from all tabs. – nnnnnn Mar 04 '12 at 01:56
  • it doesn't matter what you have inside a div, whether hidden or not. what matters are elements such as checkbox,text, hidden etc.. btw sounds like you're looking for jquery ui tabs? http://jqueryui.com/demos/tabs – robert Mar 04 '12 at 01:58
  • 1
    If you wrapped your tabs in a form, isn't it just a case of getting all of the inputs on a form? http://stackoverflow.com/questions/169506/obtain-form-input-fields-using-jquery – Matt Esch Mar 04 '12 at 01:58
  • @nnnnn Here is the cut down version with 2 tabs. I marked the code "NOTE" showing where the issue is. – garyM Mar 04 '12 at 20:07
  • @robert - The problem isn't the s in the div. Its the names and ids of the s. The are all the same, I want to rename them once they are copied to the target div. – garyM Mar 04 '12 at 20:10
  • @me232 - no that's not the problem, its the name of the inputs in the form – garyM Mar 04 '12 at 20:11

3 Answers3

2

http://jsfiddle.net/5S7ea/

I've removed the common stuff from the page, assuming you don't want it to stay where it is. I refuse to use innerHTML except for the ie6/7 fix. I traverse the DOM looking for elements where the .form property is not undefined (it's not undefined on any type of form input, null when the element is not in a form), and rename these appropriately.

I have not used jQuery.

Matt Esch
  • 22,661
  • 8
  • 53
  • 51
  • Thanks... What you did pushed me onto the right track. I've the problem i was having was operator error. I placed the inputs in a table and forgot to parse the table nodes. too tired I guess. I got rid of the HTMLInner and just stuck with the DOM nodes. – garyM Mar 05 '12 at 07:24
  • This code is awesome. I've had a problem with jquery mobile in a specific case and provided a (dirty, unfortunately) solution here: http://stackoverflow.com/a/37790896/1272105 – Sasha Grievus Jun 13 '16 at 13:22
1

There are numerous form wizard plugins that will likley cut your efforts down . Configurable , step options and validation options

Examplee: http://www.techlaboratory.net/products.php?product=smartwizard

charlietfl
  • 170,828
  • 13
  • 121
  • 150
0

Here is the fiddle http://jsfiddle.net/RcrCJ/ in which you can see there are two tabs ul based and their respective div open and all the form is one page itself and you can fetch the code according to your id based on elements, demo is using jquery.

w3uiguru
  • 5,864
  • 2
  • 21
  • 25