[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 231
  • Last Modified:

"Unlimited" Expandable Sections

Hi guys... I have recently had a requirement change (joy!) and would please like to have some advice on how to best go about implementing the change. I have stripped out a piece of my order page so that you know what I am working with.

Previously, Product X was one of many products that could be ordered, if it was available for the region ($product_available), but it could be ordered only once. Now, however, the customer should be able to select Product X again and again and again if they want to - completing the additional info for each item as they go. (In the real version there is a drop down list containing 'n' Product X types that the user can select from that will differentiante between the line items).

I envision there being a checkbox at the bottom of each section that if clicked, a new section of Info fields will be displayed for another line item... at the bottom of this section will be another checkbox that will do the same thing... I think you get the idea. I could hard code 20 or 50 lines, but I would like to know if there was a way to dynamically create this for let's say 100 sections.

Thanks for your help with this!

Sorry for the mess of the code that follows... it should look better in an editor!?

<html>
<head>
<script type="text/javascript">
function init(){
      document.account_edit.doc_copy.onclick();
} // end function init

function onDocSelect(frm, tp) {
      frm.className = frm.className.replace(/Doc_[a-z]+/i,''); //clear ordertype from classname
      frm.className += ' Doc_' + tp; //set net doctype
}
      
</script>
<style>
.onDoc {display:none;}
form.Doc_on                           .onDoc                 {display:block;}
form.Doc_off                           .onDoc                 {display:none;}
</style>
</head>

<body onLoad="init()">
<form>
                            <table width="398" border="0" cellpadding="0" cellspacing="0">
                                    
                                          <?php // remove query
                                          $product_available = 1;
                                          ?>                                          
                              <tr>
                                    <td class="main"><img src="/images/1ptrans.gif" width="1" height="2"><br>&nbsp;
                                <?php if ($_SESSION['doc_copy'] == '1') { ?>
                                                               <input type="checkbox" name="doc_copy" value="1" checked="checked"
                                                            onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                                                <?php } else { ?>                                                            
                                      <?php if ($product_available == 1) { ?>
                                                               <input type="checkbox" name="doc_copy" value="1"
                                                            onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                                                      <?php } else { ?>
                                                               <input type="checkbox" name="doc_copy" value="1" disabled />
                                                      <?php } ?>            
                                                <?php } ?>                                                      
                                                <b>Product X</b>                                                </td>
                              </tr>                                           
                              <tr>
                                <td class="main">                                                
                                                       <div class="onDoc" align="center">
                                                      <table width="367" border="0" cellspacing="0" cellpadding="0">
                                      <tr>
                                        <td class="main">&nbsp;&nbsp;Info 1:</td>
                                        <td class="main">
                                                                  <input type="text" name="info_1" id="info_1">      
                                                            </td>
                                      </tr>
                                      <tr>
                                        <td class="main">&nbsp;&nbsp;Info 2:</td>
                                        <td class="main">
                                                                  <input type="text" name="info_2" id="info_2">
                                                            </td>
                                      </tr>
                                      <tr>
                                        <td class="main">&nbsp;&nbsp;Info 3:</td>
                                        <td class="main">
                                                                  <input type="text" name="info_3" id="info_3">                                                                  
                                                            </td>
                                      </tr>
                                      <tr>
                                        <td class="main">&nbsp;&nbsp;Info 4:</td>
                                        <td class="main">
                                                                  <input type="text" name="info_4" id="info_4" >                                                            
                                                            </td>
                                      </tr>                                                       
                                                      </table>
                                          <input name="" type="checkbox" value=""> if this ia selected a new set of info 1-4 is displayed...
                                    </div>                                                
                                                      </td>
                              </tr>
                            </table>

                          <form>

</body>
</html>
0
JasonDell
Asked:
JasonDell
  • 3
  • 3
1 Solution
 
SirCroftyCommented:
Give something like this a shot (You'll have to modify the generated ids if you want to use it for multiple Products, but that should be easy enough to do, just append it on to the id creation part)

<html>
<head>
<script type="text/javascript">

var cnt = 0;

var TABLE_START = "<table width='367' border='0' cellspacing='0' cellpadding='0'>";
var TABLE_END = "</table>";
var TR_START = "<tr>";
var TR_END = "</tr>";
var INFO_TD = "<td class='main'>&nbsp;&nbsp;";
var INPUT_TD = "<td class='main'><input type='text'";
var CHECKBOX_FLD_START = "<input id='createCheck";
var CHECKBOX_FLD_END = "' type='checkbox' value='' onclick='createFields(this);'>";
var DIV_START_ID_START = "<div id='appendDiv";
var DIV_START_ID_END = "'>";
var DIV_END = "</div>";

function init(){
    // document.account_edit.doc_copy.onclick();
} // end function init

function onDocSelect(frm, tp) {
      frm.className = frm.className.replace(/Doc_[a-z]+/i,''); //clear ordertype from classname
      frm.className += ' Doc_' + tp; //set net doctype
}

function createFields(elem)
{
      var ar = new Array();
      var cur = elem.id.split("createCheck")[1];
      var temp = parseInt(cur) + 1;
      var appendDivElem = document.getElementById("appendDiv" + cur);
      var test = document.getElementById("appendDiv" + temp);
      if (elem.checked && cur <= cnt && (test == null || test == "undefined"))
      {

                  ++cnt;
                  ar.push(TABLE_START);
                  for (i = 1; i < 5; i++)
                  {
                        ar.push(TR_START);
                        ar.push(INFO_TD);
                        ar.push("Info " + i + ":</td>");
                        ar.push(INPUT_TD);
                        ar.push(" name='info_" + i + "' id='info_" + i + "'></td>");
                        ar.push(TR_END);
                  }
                  ar.push(TABLE_END);
                  ar.push(CHECKBOX_FLD_START);
                  ar.push(cnt);
                  ar.push(CHECKBOX_FLD_END);

                  var newDiv = document.createElement("DIV");
                  newDiv.id = "appendDiv" + cnt;
                  newDiv.innerHTML = ar.join("");

                  appendDivElem.appendChild(newDiv);
      }
      else
      {
            appendDivElem.removeChild(test);
            cnt = cur;
      }
}

</script>
<style>
.onDoc {display:none;}
form.Doc_on                        .onDoc               {display:block;}
form.Doc_off                        .onDoc               {display:none;}
</style>
</head>

<body onLoad="init()">
<form>
      <table width="398" border="0" cellpadding="0" cellspacing="0">

               <?php // remove query
               $product_available = 1;
               ?>
        <tr>
               <td class="main"><img src="/images/1ptrans.gif" width="1" height="2"><br>&nbsp;
            <?php if ($_SESSION['doc_copy'] == '1') { ?>
                                           <input type="checkbox" name="doc_copy" value="1" checked="checked"
                                      onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                        <?php } else { ?>
                   <?php if ($product_available == 1) { ?>
                                           <input type="checkbox" name="doc_copy" value="1"
                                      onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                               <?php } else { ?>
                                           <input type="checkbox" name="doc_copy" value="1" disabled />
                               <?php } ?>
                        <?php } ?>
                        <b>Product X</b>                                        </td>
        </tr>
        <tr>
            <td class="main">
                  <div class="onDoc" align="center">
                  <div id="appendDiv0">
                  <table width="367" border="0" cellspacing="0" cellpadding="0">
                    <tr>
                        <td class="main">&nbsp;&nbsp;Info 1:</td>
                        <td class="main"><input type="text" name="info_1" id="info_1"></td>
                    </tr>
                    <tr>
                        <td class="main">&nbsp;&nbsp;Info 2:</td>
                        <td class="main"><input type="text" name="info_2" id="info_2"></td>
                    </tr>
                    <tr>
                        <td class="main">&nbsp;&nbsp;Info 3:</td>
                        <td class="main"><input type="text" name="info_3" id="info_3"></td>
                    </tr>
                    <tr>
                        <td class="main">&nbsp;&nbsp;Info 4:</td>
                        <td class="main"><input type="text" name="info_4" id="info_4" ></td>
                    </tr>
                  </table>
               <input id="createCheck0" type="checkbox" value="" onclick="createFields(this);">
               </div>
                  </div>
            </td>
        </tr>
      </table>

<form>

</body>
</html>
0
 
JasonDellAuthor Commented:
Hi Sir!

What you have provided really works well...

I have been thinking more about the necessary solution and would appreciate any comments / feedback you can help me with the following thoughts.

1. If I wanted a drop down list of product types to be part of each product type section - it would have to be a static list of items as opposed to a dynamic call to a mysql database (client side vs server side) as I have it now? Correct?

2. The user needs to be able to select Product X and n product types and hit submit and then also be able to come back to this page to edit any errors in the info they provided. Thus, only those sections that contain data should be redisplayed for review. How would you suggest I handle this scenario without hardcoding: if !empty($info_99) { echo ... }. Hardcoding for each section obviously defeats the object of the question. But it may be necessary...

Thanks again and I appreciate any more comments / feedback you have on the matter.




0
 
SirCroftyCommented:
You could still use a drop down box populated by your database - you would probably just need to edit the script accordingly to possibly create ids using the value or label of the selected element, if you are interested in unique ids for each input section created. You just need to bind your select items to your sql data - this can usually be accomplished in most server side languages, or those languages that handle database interaction. But I do believe trying to include a dynamically created list in the dynamically created product sections would make life a little more difficult, but it is not impossible. A lot may have to do with what languages you choose to use.

For the second part, there is really a multitude of options - you can use cookies, you can store the data in the session and then recreate it when the user re enters the page, write the data to a database, serialize it out, so on and such. I would use either of the first two options here. Actually, since cookies can be disabled, I would probably recommend setting the information in the session and then getting it back out of there.

Hope that helps
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
JasonDellAuthor Commented:
Thanks a ton for the detailed feedback... So, I am making good progress on the on the drop down list piece, but would appreciate some more detail on the second part when you get a chance. I am using php btw.

I am familiar with session variables and use them throughout my site to confirm that the user is logged in, to store data collected from the user and displaying it back to them to be edited if necessary, etc. What I do not understand is if I have seperate values for each of the n fields stored in session variables how I display them within the appropriately named fields to the user without hardcoding a ton.

As shown below, I have added a variable 'field' that increments as each field is created... (info_1, info_2... info_99) and a submit button. Looking at the post variables that are sent to test5a.php, I have a seperate variable and its associated value for each field - great! I can store these values into session variables... but I am not sure how to use a similar loop as with the creation of the fields for re-display purposes?

Please let me know what I am missing...

<html>
<head>
<script type="text/javascript">

var cnt = 0;
var field = 4;

var TABLE_START = "<table width='367' border='0' cellspacing='0' cellpadding='0'>";
var TABLE_END = "</table>";
var TR_START = "<tr>";
var TR_END = "</tr>";
var INFO_TD = "<td class='main'>&nbsp;&nbsp;";
var INPUT_TD = "<td class='main'><input type='text'";
var CHECKBOX_FLD_START = "<input id='createCheck";
var CHECKBOX_FLD_END = "' type='checkbox' value='' onclick='createFields(this);'>";
var DIV_START_ID_START = "<div id='appendDiv";
var DIV_START_ID_END = "'>";
var DIV_END = "</div>";

function init(){
    // document.account_edit.doc_copy.onclick();
} // end function init

function onDocSelect(frm, tp) {
      frm.className = frm.className.replace(/Doc_[a-z]+/i,''); //clear ordertype from classname
      frm.className += ' Doc_' + tp; //set net doctype
}

function createFields(elem)
{
     var ar = new Array();
     var cur = elem.id.split("createCheck")[1];
     var temp = parseInt(cur) + 1;
     var appendDivElem = document.getElementById("appendDiv" + cur);
     var test = document.getElementById("appendDiv" + temp);
     if (elem.checked && cur <= cnt && (test == null || test == "undefined"))
     {

               ++cnt;
               ar.push(TABLE_START);
               for (i = 1; i < 5; i++)
               {
                              ++field;                    
                              ar.push(TR_START);
                    ar.push(INFO_TD);
                    ar.push("Info " + i + ":</td>");
                    ar.push(INPUT_TD);
                    ar.push(" name='info_" + field + "' id='info_" + field + "'></td>");
                    ar.push(TR_END);

               }
               ar.push(TABLE_END);
               ar.push(CHECKBOX_FLD_START);
               ar.push(cnt);
               ar.push(CHECKBOX_FLD_END);

               var newDiv = document.createElement("DIV");
               newDiv.id = "appendDiv" + cnt;
               newDiv.innerHTML = ar.join("");

               appendDivElem.appendChild(newDiv);
     }
     else
     {
          appendDivElem.removeChild(test);
          cnt = cur;
     }
}

</script>
<style>
.onDoc {display:none;}
form.Doc_on                        .onDoc               {display:block;}
form.Doc_off                        .onDoc               {display:none;}
</style>
</head>

<body onLoad="init()">
<FORM action="test5a.php" method="post">

     <table width="398" border="0" cellpadding="0" cellspacing="0">

             <?php // remove query
             $product_available = 1;
             ?>
       <tr>
             <td class="main"><img src="/images/1ptrans.gif" width="1" height="2"><br>&nbsp;
          <?php if ($_SESSION['doc_copy'] == '1') { ?>
                                    <input type="checkbox" name="doc_copy" value="1" checked="checked"
                                onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                    <?php } else { ?>
                <?php if ($product_available == 1) { ?>
                                    <input type="checkbox" name="doc_copy" value="1"
                                onclick="onDocSelect(this.form, this.checked ? 'on' : 'off');"/>
                          <?php } else { ?>
                                    <input type="checkbox" name="doc_copy" value="1" disabled />
                          <?php } ?>
                    <?php } ?>
                    <b>Product X</b>                                        </td>
       </tr>
       <tr>
          <td class="main">
               <div class="onDoc" align="center">
               <div id="appendDiv0">
               <table width="367" border="0" cellspacing="0" cellpadding="0">
                 <tr>
                    <td class="main">&nbsp;&nbsp;Info 1:</td>
                    <td class="main"><input type="text" name="info_1" id="info_1"></td>
                 </tr>
                 <tr>
                    <td class="main">&nbsp;&nbsp;Info 2:</td>
                    <td class="main"><input type="text" name="info_2" id="info_2"></td>
                 </tr>
                 <tr>
                    <td class="main">&nbsp;&nbsp;Info 3:</td>
                    <td class="main"><input type="text" name="info_3" id="info_3"></td>
                 </tr>
                 <tr>
                    <td class="main">&nbsp;&nbsp;Info 4:</td>
                    <td class="main"><input type="text" name="info_4" id="info_4" ></td>
                 </tr>
               </table>
             <input id="createCheck0" type="checkbox" value="" onclick="createFields(this);">
             </div>
               </div>
          </td>
       </tr>
     </table>
<input name="" type="submit" value="submit">
</form>

</body>
</html>
0
 
JasonDellAuthor Commented:
Thanks for your help with this SirCrofty... I have awarded you the points. FYI - I have opened a new question in the php section for the session variable piece --> http://www.experts-xchange.com/Web/Web_Languages/PHP/Q_21796218.html
0
 
SirCroftyCommented:
Hi Jason,

Sorry about the delay, I was tremendously busy at work. I'm not very skilled at php, it's one of those things on my to do list, so I don't know how much help I'm going to be with this part. Off hand knowledge, I would maybe use a hidden variable to tell whether the user had come back and then returned, and then store the number of displayed sections for each object in the session as well? That way you would know what they currently had open. This would probably be a lot easier in a framework like JSF, but I hope the php guys can give you more help with this. Post any follow ups for JavaScript here and I'll be sure to take a look at them and try to help!

0

Featured Post

Prep for the ITIL® Foundation Certification Exam

December’s Course of the Month is now available! Enroll to learn ITIL® Foundation best practices for delivering IT services effectively and efficiently.

  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now