Solved

JavaScript Hide/Whens - Post Mortem

Posted on 2002-03-18
27
312 Views
Last Modified: 2013-12-18
Hi guys,

This question is with reference to my last question to do with manipulating notes hide/when using JavaScript.

The code I'm using is:

function switchField(Qn, fldID, fldName) {
  form = document.forms[0];
   if (Qn.value == "No") {
        form.all[fldID].style.display = 'none'
        form[fldName].value = ''
   } else {
        form.all[fldID].style.display = ''
   }
};

I would call this function from the onClick of a field:
switchField(this, 'HCM1a', 'ContManHowReg')

(as kindly supplied by Zvonko)

My new problem is:

If the document has already been saved, and we open the document, the fields/rows are hidden by default, because the div id and style is set in the table cell properties.

What is the best/quickest way to resolve this issue?

Thanks for all your help.
0
Comment
Question by:ashik1
  • 12
  • 9
  • 6
27 Comments
 
LVL 10

Expert Comment

by:zvonko
ID: 6877582
Sorry Ashik, I would like to give a chance to JM to see my answer to this question :-)

But because he is just now asleep, you can state more details about your problem. For example, my question is,would you like to have all table cells shown on initial open? Show all rows/cells, regardless when open as new document form or open old stored document in this form. Is this assumption true?
If not true, then what would be the matrix to define which cells to show and which to hide?

Is it to late for you to have an answer to your question tomorrow when JM is again online?


<|:-)
0
 

Author Comment

by:ashik1
ID: 6877625
hi Zvonko, thanks for your quick response.

I would appreciate a quick solution as I will need to test and deploy to the staging server tomorrow morning.  As you probably know, I'm in London (GMT).

Anyway, the form works well when composing a new document.  But the problem occurs when opening a saved document as the table cell style is set to "display:none".

I've tried to use html pass-thru computed text around the cells but it just messes up my form.

I've also tried to put some code in the onLoad of the form to check the values and set the style, but cannot get this to work.

If I can find out how to get it to work on a simple table with e.g.

[cell 1, contains field1] = set to "yes"
[cell 2, contains field2] (if field1 is "yes", then show, else hide)

How can i achieve this? Do i have to redesign completely?
0
 
LVL 10

Expert Comment

by:zvonko
ID: 6877791
no, you have not to redesign nothing. Let all things as is. Make improvements next time, but not in a hurry :-)

To make this as short as possible send me a saved html page from browser to a file and send this html file to zp@arcor.de

So I can use your table matrix and shorten this turnarounds.

Send best both html files saved: from an empty new opened form and from a opend saved document.

I have to go to church now, but will try to be as soon as possible here again to send you the JavaScript to update the cell hide whens according to field values.

Do you have the Form option enabled: GenerateHtmlForAllFields? If not enable it for this test and disable if not needed afterwards.


So long,
zvonko
0
 
LVL 10

Expert Comment

by:zvonko
ID: 6879133
Thank you for your email Ashik.

The best aproach to get this fixed is to make a new JavaScript function and to call this function onLoad.
Inside of the function you can define what rows to show.
My problem is to decide based on the infos I have so far what rows are to be shown in read modus. It is a problem because you have no default values for the Radio buttons.
Therefore is their default value "" and what should this JavaScript function onLoad assume: YES/NO

So let us start.

First important thing you have to do is to set an ID for the whole table. You have several tables, so give every table one unique general table ID.
For example myTab1, myTab2 (or some more meaningfull :-)

If you have table IDs, then you can hide and show complete rows by calling this JavaScript line:
document.all["myTab1"].rows[2].style.display="none";

and to show again:
document.all["myTab"].rows[2].style.display="block";

Knowing this, it is no problem to define a function to be called onLoad:

function showMultipleRows(rowDefs) {
 var rowDefArray = rowDefs.split(';')
 for(i=0; i<rowDefArray.length; i++) {
  rowDef = rowDefArray[i].split(',')
  alert('RowDef: '+rowDef[0]+'/'+rowDef[1])
  document.all[rowDef[0]].rows[(rowDef[1]*1)].style.display="block";
 }
}

and the call to this function looks like this:
<BODY onLoad="showMultipleRows('myTab1,1;myTab2,3;myTab3,1')">

After testing comment out, or remove, this alert call:
  //alert('RowDef: '+rowDef[0]+'/'+rowDef[1])


Good luck whit this all,
zvonko
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879142
Hey guys, here I am again.

If you open the saved form, do you mean in read mode in your browser? In this case no fields are available and thus you can't use JavaScript to check the values of fields on the form.

To be able to check the values of fields, you need to open the form in edit mode, even with the option "Generate HTML for all fields" enabled, no fields are generated for a document in read mode.

The problem with this is if you need a read and edit mode for the form (read for normal users, edit for editors for example). You have to create a computed for display-field or computed text to display the contents of the fields for regular users and add hide-when formula's to toggle if the display or edit field is visible.

I hope, my explanation is a bit clear to you guys.

Anyway, I'll elaborate with a working example if this is what you are looking for. If not, specify exactly what it is you want to do and we'll look into it further.
0
 
LVL 10

Expert Comment

by:zvonko
ID: 6879144
moin' JM :-)
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879218
Goodmorning to you to :-)
I've received your mail with the html-files and will have a look at it later on.
0
 

Author Comment

by:ashik1
ID: 6879363
Hey guys, thanks for all your help.  

Zvonko, the onLoad should diplay the row if the field values are not "".  But JM wrote that we cannot check with javascript the field values.

Perhaps we could check using javascript + @Formula in the Form HTML attributes.

Another idea would be to use computed subforms.  If in editmode, use a subform which uses computed for display fields to show the form.  When user clicks Edit document, the form loads another form which has editable fields?

What do you think?
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879374
Sounds like a possible solution. On the subform used for display, you can then use notes hide-whens to hide parts of the form that are set to be hidden.
0
 
LVL 10

Expert Comment

by:zvonko
ID: 6879419
If you have the Form option turned on GenerateHTMLforAllFields (and you have it), than you could use the content of the fields on client side in browser with JavaSCript.

But the problem is, that your VALUES for the RadioButtons are empty strings, because nothing was stored at submit time when last in Edit mode.

My question is also why do you not provide Default values for your RadioButtons? It would make life easier :-)


Have you stored my function showMultipleRows(rowDefs) and called it from Form onLoad with the correct table IDs and row numbers?


0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879499
Must be this headache, that's keeping me from thinking clearly.
You're right zvonko. If you specify the "Generate HTML for all fields" option, even in read mode the fields are defined and they are all of type hidden.

The problem with determining the value is that the radio-button in edit mode is an array of option elements and in read mode it's just a single field with type hidden.

So in read mode you can just get the value with
   nameOfField.value
and in edit mode you'd have to check the individual radio-buttons to see which one is selected and then return the text-value for this button.

I would suggest writing two formula's to do the checks:
checkRead for checking in read mode and checkEdit for checking in edit mode.
Then to call the correct function in onLoad, add the onLoad event through the HTML Body Attributes like this:
   "onLoad=\"" + @If(@DocIsBeingEdited; "checkEdit();"; "checkRead();") + "\""

What do you think about this, guys?
0
 

Author Comment

by:ashik1
ID: 6879565
Sounds good.  I am just coding in the default values for the radio and drop down lists fields. E.g. @If(field1="";"No";field1).

What would the checkEdit() and checkRead() function be doing? Should we code in zvonko's code within these functions?

I've also named my tables (whqTab1 to whqTab8).

Please note that the rows that require hide/when have cell IDs and have the style set to "display:none".

0
 
LVL 10

Expert Comment

by:zvonko
ID: 6879643
Ashik, for default value you have not to check former value for Default. Every field has an Default event. Values entered there do not apply when value is blank, but apply when NO value present (empty value is also a value :-)


0
What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879713
Yes you can use zvonko's code to perform the hide/show operations, depending on the values you checked.
checkRead is the simplest one to code all you need to check in that function is for every field you use to decide to show/hide a row, just check the value propertie of the field and decide based on that to hide/show the row.

for example:
if (document.forms[0].HideRowField1.value=="No")
   document.all["whqTab1"].rows[2].style.display="none"
else
   document.all["whqTab1"].rows[2].style.display="block";
could be a statement to decide to hide/show the second row of the table called whqTab1, based on the value of the field HideRowField1.

The checkEdit function is a bit more complicated, because here you have to write your checks depending on what type of field it is.
For a selection box you can the value like this:
   checkValue=document.forms[0].selectionField[document.forms[0].selectionField.selectedIndex].text;
To check if a radiobutton is yes or no use a function like the following :
if (document.forms[0].YesNoButton[0].checked=="1")
   document.all["whqTab2"].rows[2].style.display="block"
else
   document.all["whqTab2"].rows[2].style.display="none";

This statement would check for a radiobutton called YesNoButton if the first selection was checked (=yes), show the row, otherwise hide the row.

I hope this helps you on your way.

Regards,
JM
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6879721
Oops the word "get" disappeared in the following line:
For a selection box you can get the value like this:
   checkValue=....

Anyways, if you need any further info about the functions just let us know.
0
 

Author Comment

by:ashik1
ID: 6880323
Thank you so much guys.  I'll try this out and let you know how it went.  If I do not get back to you this evening (GMT), I will let you know tomorrow morning.  People in the office never leave me alone!! :-)
0
 

Author Comment

by:ashik1
ID: 6880598
hi guys, i'm really stuck here. i'm having problems trying to get it to work.

this is what i've done:

on my form HTML attributes:
@If( @IsDocBeingEdited ; "onLoad=\"f = document.forms[0] \" onbeforeunload=\"navigateAway()\";" ; "onLoad=\"f = document.forms[0] ;checkRead(); \"" )


in the JSHeader:

function checkRead() {
//Check hide/when of Web site Basics
if (document.forms[0].WebBasExProv.value=="No")
  document.all["whqTab1"].rows[6].style.display="block";
else
  document.all["whqTab1"].rows[6].style.display="none";
//
if (document.forms[0].WebBasExProv.value=="No")
  document.all["whqTab1"].rows[6].style.display="block";
else
  document.all["whqTab1"].rows[6].style.display="none"
//
if (document.forms[0].WebBasSerPlatform.value=="Other")
  document.all["whqTab1"].rows[9].style.display="block";
else
  document.all["whqTab1"].rows[9].style.display="none";
if (document.forms[0].WebBasRedirURL.value=="Yes")
  document.all["whqTab1"].rows[11].style.display="block";
else
  document.all["whqTab1"].rows[11].style.display="none";
if (document.forms[0].WebBasAudLocation.value=="Other")
  document.all["whqTab1"].rows[14].style.display="block";
else
  document.all["whqTab1"].rows[14].style.display="none";
//Check hide/when of Content Management
if (document.forms[0].ContManSiteChg.value=="Yes")
  document.all["whqTab3"].rows[4].style.display="block";
else
  document.all["whqTab3"].rows[4].style.display="none";
if (document.forms[0].ContManSiteChg.value=="Yes")
  document.all["whqTab3"].rows[5].style.display="block";
else
  document.all["whqTab3"].rows[5].style.display="none";
//Check hide/when of Third Party Applications
if (document.forms[0].ThirdPOtherApp.value=="Yes")
  document.all["whqTab4"].rows[3].style.display="block";
else
  document.all["whqTab4"].rows[3].style.display="none";
if (document.forms[0].ThirdPOtherApp.value=="Yes")
  document.all["whqTab4"].rows[4].style.display="block";
else
  document.all["whqTab4"].rows[4].style.display="none";
if (document.forms[0].ThirdPOtherApp.value=="Yes")
  document.all["whqTab4"].rows[7].style.display="block";
else
  document.all["whqTab4"].rows[7].style.display="none";
if (document.forms[0].ThirdPLicence.value=="Yes")
  document.all["whqTab4"].rows[5].style.display="none";
else
  document.all["whqTab4"].rows[5].style.display="block";
//
if (document.forms[0].ThirdPProcure.value=="Yes")
  document.all["whqTab4"].rows[6].style.display="block";
else
  document.all["whqTab4"].rows[6].style.display="none";
if (document.forms[0].ThirdPCorePlat.value=="Yes")
  document.all["whqTab4"].rows[8].style.display="block";
else
  document.all["whqTab4"].rows[8].style.display="none";
//Check hide/when of Authentication
if (document.forms[0].AuthenUserPass.value=="Yes")
  document.all["whqTab5"].rows[3].style.display="block";
else
  document.all["whqTab5"].rows[3].style.display="none";
if (document.forms[0].AuthenEncrypt.value=="Yes")
  document.all["whqTab5"].rows[4].style.display="block";
else
  document.all["whqTab5"].rows[4].style.display="none";
if (document.forms[0].AuthenEncrypt.value=="Other")
  document.all["whqTab5"].rows[5].style.display="block";
else
  document.all["whqTab5"].rows[5].style.display="none";
};

---------------------------------
I've tried the code with and without the table cell style set to "display:none" by default.

I haven't written the checkEdit() function, as I thought I'd write and test the checkRead() function first.

The way I'm testing the above code is opening a saved document from a view in read mode.

The "Generate HTML for all fields" option is selected and I've checked out the html from the browser and all the fields are there.

Where am I going wrong?
0
 

Author Comment

by:ashik1
ID: 6882020
Hi guys, i was wondering would it be ok if you could send me a demo db to my email address: naxalite@nme.com if you can get the above example working, please.

Essentially, there should be at a one table (5 rows x 3 columns).

Let me know if it's possible.  JM & Zvonko, thank you for all the help so far.  I've increased the points to 300 as I know you have spent more time on this.

0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6882039
Okay, I'll send you a small demo db with a table and some sample script.
You can probably work from there.
Hang on, working on it...
0
 
LVL 8

Accepted Solution

by:
Jean Marie Geeraerts earned 300 total points
ID: 6882162
Okay, the email is on its way.
Let me know if you need any further help, or if you need me to go into more detail.

For the people reading this question info about the demo application:

The applicaton includes one view and one form.

The view is just used to display the documents, so they can be opened for reading after they are saved.

The form has the property "Generate HTML for all fields" enabled.
On the form I created a table with 5 rows and 3 columns. The table's ID is set to "DemoTab", using the properties box of the table. -> Last tab < @ >

Inside the table the first column just contains a number.
The second contains a question and the third contains a field to hold the answer to the question.
Depending on the answer the following row is shown or hidden.

Included fields are :
YesNo1 : Radio-button field with values
         Yes |
         No | none
YesNo2 : Combox with values
         Yes |
         No | none
YesNo3, YesNo4 : radio-buttons defined as YesNo1
YesNo5 : ComboBox with a few values.
This field isn't used to hide a following row, so the values here don't matter. (I decided on that after I named the field, and was too lazy to rename the field afterwards;) )

In the JavaScript Header I have the following functions:
---------------------------------------------------------Begin
// Function used to show or hide a given row in a named table.
// args :
//   table : the ID-tag of the table
//   row : the number of the row you want to hide, first row is number 0
//   show : specify to hide or show the row :
//       'none' = hide
//       '' = show
function showHideRow(table, row, show)
      {
      document.all[table].rows[row].style.display=show;
      }

// Function used to determin what rows to show or hide in read mode
function checkRead()
      {
      var form=document.forms[0];
      // Because we use aliases to determin if the value should be '' or 'none', we don't need to perform
      // a check. We just use the value to show or hide the row.
      showHideRow("DemoTab", 1, form.YesNo1.value);
      showHideRow("DemoTab", 2, form.YesNo2.value);
      showHideRow("DemoTab", 3, form.YesNo3.value);
      showHideRow("DemoTab", 4, form.YesNo4.value);
      }
      
// Function used to determin what rows to show or hide in edit mode
function checkEdit()
      {
      var form=document.forms[0];
      // Check value of radio-button YesNo1
      if (form.YesNo1[0].checked=="1")
            showHideRow("DemoTab", 1, '')
      else
            showHideRow("DemoTab", 1, 'none');
      
      // Check value of selection box YesNo2
      if (form.YesNo2[form.YesNo2.selectedIndex].value=='')
            showHideRow("DemoTab", 2, '')
      else
            showHideRow("DemoTab", 2, 'none');

      // Check value of radio-button YesNo1
      if (form.YesNo3[0].checked=="1")
            showHideRow("DemoTab", 3, '')
      else
            showHideRow("DemoTab", 3, 'none');

      // Check value of radio-button YesNo4
      if (form.YesNo4[0].checked=="1")
            showHideRow("DemoTab", 4, '')
      else
            showHideRow("DemoTab", 4, 'none');      
      }
---------------------------------------------------------End

In the onClick event of the radio-buttons and combobox that determin to show the next row or not is the following line of JavaScript:
    showHideRow('DemoTab', 1, this.value);
Where the number 1 is replaced by 2, 3 or 4 for the consecutive fields, so it applies to different rows.

The functions checkRead and checkEdit are called from the forms HTML Body Attributes using the following formula :
"onLoad=\"" + @If(@IsDocBeingEdited; "checkEdit();"; "checkRead();") + "\""

This way the function checkRead is called when the document is opened for reading and checkEdit is called when the document is opened for editing.
The difference is necessary, because the way the field are represented in the form differ depending on whether the form is opened for reading or editing.

When you open the form for reading/editing the rows that were disabled, will not show thanks to these two functions.

I hope this is a bit clear.
Regards,
JM
0
 

Author Comment

by:ashik1
ID: 6882484
Thank you JM.  I've checked out your demo and it works excellently!!  I'll just implement the code to work with my form, which has 8 tables and numerous hide/whens.

I'll write back before I leave the office today and also give you the points. :-)  Many thanks for your help.  Zvonko, thanks for your advice and help.

I'm sure I'll get stuck on another problem soon and will submit another question ;-)
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6882520
You're welcome. We're always glad to help.
I'll probably be gone by the time you finish (I tend to start early and leave early).
So, if you need any additional info, I'll probably won't get back to you until tomorrow. (Or you have to post the comment before 14:30 UK time).
0
 

Author Comment

by:ashik1
ID: 6882571
Hi JM, one more thing -- some of my hide/whens are based upon keyword drops, which are not based on yes/no but they display a list of options, and if the user selects "Other", then the field below is shown.

How do I implement this, since we are setting the field value alias to '' or 'none' if user selects yes/no??
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6882598
For this type of selection, it's better not to provide aliases and use an if-statement to set the style property.

If you have a selection field "SearchEngine" that has the following choices:
   Yahoo, Google, MSN, AltaVista, Other...
you could use the following if-statement:
   var form=document.forms[0]:
   if (form.SearchEngine[form.SearchEngine.selectedIndex].value=="Other...")
      showHideRow("DemoTab", 4, '')
   else
      showHideRow("DemoTab", 4, 'none');

Where 4 is the row number that you want to hide/show of course.
Equally you could have a text field, for example Your NickName that has to have a value before the next field appears, then you can check if the value is not equal to an empty string.
To let the row appear when a value is entered, put the script in the onChange event of the field. This is how the check would look like:
   var form=document.forms[0]:
   if (form.NickName.value!='') /* value is not an empty string */
      showHideRow("DemoTab", 5, '')
   else
      showHideRow("DemoTab", 5, 'none');

Regards,
JM
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6882620
Oh yeah, above if statements are for the checkEdit function.
In checkRead it's much simpler, there you just check for the value of the hidden field:
   if (form.field.value!="Other...")

0
 

Author Comment

by:ashik1
ID: 6884953
It's finally working!  Thanks for all your help.
Best regards.
0
 
LVL 8

Expert Comment

by:Jean Marie Geeraerts
ID: 6884965
You're welcome! Thanks for the A.
These 1200 points I got from you, now put you on the third place in my top-sponsors list ;-)
0

Featured Post

Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

For users on the Lotus Notes 8 Standard client, this article provides information on checking the Java Heap size and adjusting it to half of your system RAM in attempt to get the Lotus Notes 8.x Standard client to run faster.  I've had to exercise t…
This is an old article, please see an updated version of this article, located here: http://www.experts-exchange.com/articles/23619/Notes-8-5x-Windows-7-Notes-info-and-tips.html
Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

747 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now