V5 Catalog - Automatic generation of multiple other info fields. Change log: 07-02-03 Added autocomplete="off" to input fields as IE was not firing onchange event on autocompleted entries. V1.0. -- 31/12/02 -- First Release. This code works only on Actinic V5. There's a different patch for V6. You don't need to change any templates as the extra code is generated automatically whenever you set the Other info prompt to something like Prompt1|Prompt2|Prompt3, etc. If you don't have a "|" character in your prompt, then the original single line prompt is created. Also you can have fields that are optional so the customer can leave them empty without error. Whenever you have a colon ":" character within any of these sub-prompt names, then these fields are optional and will not cause an error if the customer leaves them empty. You can control whether the prompt and input appear on the same or successive lines. If your prompt ends with a space then the input field will follow it on that row. No space and the input field will be on the next row. Finally you can control the width of the input field by starting your prompt with a number. This will be removed from display and and used instead as the field width. E.g. Other Info Prompt:- Name|E-mail|Phone: Optional|Fax: Optional|Postcode or:- 30Name |40E-mail|25Phone: Optional |25Fax: Optional |12Postcode These patches need a JavaScript 1.2 capable browser, so should work on most modern browsers. ########################################################################################### Patching instructions:- ########################################################################################### Put the following code into Actiniccore.js (make a backup first) at the bottom after all existing code. Our patches are the bits inside the long lines of ####'s. You don't need the ####... lines. ########################################################################################### var formno; var fieldno; var docform; function locatefield(fname){ formno = ''; fieldno = ''; // (V11) look through all forms 'till one containing field "fname" var tf = -1; var te = 0; var df = document.forms; var i = df.length - 1; for ( var j = 0; j <= i; j++ ) { var k = df[j].length - 1; for ( var l = 0; l <= k; l++ ) { if ( df[j].elements[l].name == (fname) ) { tf = j; te = l; } } } if ( tf < 0 ) { alert('Cannot find product form ' + fname); return false; } else { formno = tf; fieldno = te; docform = df[tf]; return true; } } function stripspecial( prodref ){ // find the form with the order field. if (locatefield(prodref)) { docform.elements[fieldno].value = docform.elements[fieldno].value.replace(/\¦/g, " "); } } function concat( prodref, numflds ){ // find the form with the order field. if (locatefield(prodref)){ docform.elements[fieldno].value = ''; for (var i = 0; i < numflds; i++) // add in all sub fields { if ( i > 0) docform.elements[fieldno].value += '¦'; docform.elements[fieldno].value += docform.elements[fieldno + i + 1].value.replace(/\¦/g, " "); } } } ######################################################################################### Patches are needed to ShoppingCart.pl (make a backup copy). Use a text editor not a word processor. ########################################################################################### SEARCH for the following line (there should only be one instance) # optional info field IMMEDIATELY below this is a section of code:- my ($sInfo); if (length $CartItem{"INFOINPUT"} > 0) # if there is any info { $sInfo = $$pProduct{"OTHER_INFO_PROMPT"}; # build the prompt $sInfo .= " "; $sInfo .= $CartItem{"INFOINPUT"}; # plus the response $sInfo =~ s/%0a/
/g; # restore line feeds $sInfo .= "

"; } REPLACE that section of code with:- # norman patching my $sInfo = ''; my $sInfoValue = $CartItem{"INFOINPUT"}; if (length $sInfoValue > 0) # if there is any info { if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my @aNames = split /\|/, $$pProduct{"OTHER_INFO_PROMPT"}; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sVal = $aValues[$nI]; my $sName = $aNames[$nI]; $sName =~ s/^(\d+)//; $sVal =~ s/%0a/
/g; $sInfo .= $sName . " " . $sVal . "
"; } } else { $sInfo = $$pProduct{"OTHER_INFO_PROMPT"}; # build the prompt $sInfo .= " "; $sInfo .= $CartItem{"INFOINPUT"}; # plus the response $sInfo =~ s/%0a/
/g; # restore line feeds $sInfo .= "

"; } } # END norman patching SEARCH for the following line (there should only be one instance) # insert the current values for the default values IMMEDIATELY below this is a section of code:- ######### my (%Variables); if (length $CartItem{"INFOINPUT"} > 0) # if there was any data in the info prompt { my ($sInfoValue); $sInfoValue = ACTINIC::EncodeText2($CartItem{"INFOINPUT"}); # retrieve the value $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; # make it the default for the next round } REPLACE that section of code with:- ######### my (%Variables); if (length $CartItem{"INFOINPUT"} > 0) # if there was any data in the info prompt { my ($sInfoValue); $sInfoValue = ACTINIC::EncodeText2($CartItem{"INFOINPUT"}); # retrieve the value $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; # make it the default for the next round #norman patching if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { $sInfoValue = $aValues[$nI]; # retrieve the value $Variables{"NAME=INFO_$nI"} = "NAME=INFO_$nI VALUE=\"$sInfoValue\""; # make it the default for the next round } } # END norman patching } SEARCH for the following line (there should only be one instance) if ($bInfoExists) IMMEDIATELY below this is a section of code:- { $sInfo = $::g_InputHash{"INFOINPUT"}; if (length $sInfo == 0) # if there is no info, reprompt { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sMessage .= ACTINIC::GetPhrase(-1, 55, "$sPrompt") . "

\n"; } elsif (length $sInfo > 1000) { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sMessage .= ACTINIC::GetPhrase(-1, 56, "$sPrompt") . "

\n"; } $sInfo =~ s/\n/%0a/g; # Preserve new lines $Values{"INFOINPUT"} = $sInfo; } REPLACE that section of code with:- { $sInfo = $::g_InputHash{"INFOINPUT"}; # Norman patching my $sInfoPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; if ( $sInfoPrompt =~ /\|/ ) { my @aNames = split /\|/, $sInfoPrompt; my @aValues = split /¦/, $sInfo; my $nJ = @aNames; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sName = $aNames[$nI]; $sName =~ s/^(\d+)//; if ( ($sName !~ /:/) && ($aValues[$nI] eq '') ) { $sMessage .= ACTINIC::GetPhrase(-1, 55, "$sName") . "

\n"; } } } elsif (length $sInfo == 0) # if there is no info, reprompt { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sMessage .= ACTINIC::GetPhrase(-1, 55, "$sPrompt") . "

\n"; } if (length $sInfo > 1000) { my ($sPrompt); $sPrompt = $$pProduct{"OTHER_INFO_PROMPT"}; $sPrompt =~ s/(^|\|)\d+/$1/g; # strip size info $sPrompt =~ s/\|/ /g; # replace | with spaces $sMessage .= ACTINIC::GetPhrase(-1, 56, "$sPrompt") . "

\n"; } # END Norman patching $sInfo =~ s/\n/%0a/g; # Preserve new lines $Values{"INFOINPUT"} = $sInfo; } SEARCH for the following line (there should only be one instance) # insert the old values for the default values IMMEDIATELY below this is a section of code:- ######### my (%Variables); if (length $Values{"INFOINPUT"} > 0) # if there was any data in the info prompt { my ($sInfoValue); $sInfoValue = $Values{"INFOINPUT"}; # retrieve the value $sInfoValue =~ s/%0a/\n/g; # Restore new lines $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; # make it the default for the next round } REPLACE that section of code with:- ######### my (%Variables); if (length $Values{"INFOINPUT"} > 0) # if there was any data in the info prompt { my ($sInfoValue); $sInfoValue = $Values{"INFOINPUT"}; # retrieve the value $sInfoValue =~ s/%0a/\n/g; # Restore new lines $Variables{"NAME=INFOINPUT"} = "NAME=INFOINPUT VALUE=\"$sInfoValue\""; # make it the default for the next round # norman patching if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { $sInfoValue = $aValues[$nI]; # retrieve the value $Variables{"NAME=INFO_$nI"} = "NAME=INFO_$nI VALUE=\"$sInfoValue\""; # make it the default for the next round } } # END norman patching } SEARCH for the following line (there should only be one instance) if (length $sInfoPrompt > 0) IMMEDIATELY below this is a section of code:- { $sLine = "

".$sInfoPrompt."
\n"; # add the prompt to the html $sLine .= "\n"; # add the text field to the list } REPLACE that section of code with:- { # norman patching if ($sInfoPrompt =~ m/\|/) { my @aValues = split /\|/, $sInfoPrompt; # change HIDDEN to TEXT for diagnostics $sLine = ""; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sSize = '35'; my $sText = $aValues[$nI]; my $sSpacer1 = '"; } $sLine .= '
'; my $sSpacer2 = '
'; if ( $sText =~ / $/ ) { $sSpacer1 = '
'; $sSpacer2 = ''; } $sText =~ s/^(\d+)//; if ( $1 ) { $sSize = $1; } if ($sText =~ /:/) { $sLine .= $sSpacer1 . $sText; } else { $sLine .= "$sSpacer1$sText"; } $sLine .= $sSpacer2 . "
'; } else { $sLine = "

".$sInfoPrompt."
\n"; # add the prompt to the html $sLine .= ""; } # END norman patching } ######################################################################################### Patches are needed to ActinicOrder.pm (make a backup copy). Use a text editor not a word processor. The modified subroutines are listed in full below just replace them:- ########################################################################################### SEARCH for the following line (there should only be one instance) if (length $CurrentItem{'INFOINPUT'} > 0) IMMEDIATELY below this is a section of code:- { $sOrderLines .= " " . $sFontOpen . " " . $$pProduct{'OTHER_INFO_PROMPT'} . "

"; my $sInfo = $CurrentItem{'INFOINPUT'}; $sInfo =~ s/%0a/
/g; # Restore new lines $sOrderLines .= $sInfo . "
" . $sFontClose . "\n"; } REPLACE that section of code with:- { # norman patching my $sInfo = ''; my $sInfoValue = $CurrentItem{"INFOINPUT"}; if (length $sInfoValue > 0) # if there is any info { if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my @aNames = split /\|/, $$pProduct{"OTHER_INFO_PROMPT"}; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sVal = $aValues[$nI]; my $sName = $aNames[$nI]; $sName =~ s/^(\d+)//; $sVal =~ s/%0a/
/g; $sOrderLines .= "" . $sFontOpen . $sName . ""; $sOrderLines .= "" . $sFontOpen . "" . $sVal . "" . $sFontClose . "\n"; } } else { $sOrderLines .= " " . $sFontOpen . " " . $$pProduct{'OTHER_INFO_PROMPT'} . "
"; my $sInfo = $CurrentItem{'INFOINPUT'}; $sInfo =~ s/%0a/
/g; # Restore new lines $sOrderLines .= $sInfo . "
" . $sFontClose . "\n"; } } # END norman patching } ######################################################################################### Patches are needed to ActinicSCCode.fil (make a backup copy). Use a text editor not a word processor. The modified subroutines are listed in full below just replace them:- ########################################################################################### SEARCH for the following line (there should only be one instance) if (length $CurrentItem{'INFOINPUT'} > 0) IMMEDIATELY below this is a section of code:- { $sOrderLines .= " " . $sFontOpen . " " . $$pProduct{'OTHER_INFO_PROMPT'} . "
"; my $sInfo = $CurrentItem{'INFOINPUT'}; $sInfo =~ s/%0a/
/g; # Restore new lines $sOrderLines .= $sInfo . "
" . $sFontClose . "\n"; } REPLACE that section of code with:- { # norman patching my $sInfo = ''; my $sInfoValue = $CurrentItem{"INFOINPUT"}; if (length $sInfoValue > 0) # if there is any info { if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my @aNames = split /\|/, $$pProduct{"OTHER_INFO_PROMPT"}; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sVal = $aValues[$nI]; my $sName = $aNames[$nI]; $sName =~ s/^(\d+)//; $sVal =~ s/%0a/
/g; $sOrderLines .= "" . $sFontOpen . $sName . ""; $sOrderLines .= "" . $sFontOpen . "" . $sVal . "" . $sFontClose . "\n"; } } else { $sOrderLines .= " " . $sFontOpen . " " . $$pProduct{'OTHER_INFO_PROMPT'} . "
"; my $sInfo = $CurrentItem{'INFOINPUT'}; $sInfo =~ s/%0a/
/g; # Restore new lines $sOrderLines .= $sInfo . "
" . $sFontClose . "\n"; } } # END norman patching } ########################################################################################### Finally patches are needed to OrderScript.pl (make a backup copy). Use a text editor not a word processor. ########################################################################################### SEARCH for the following line (there should only be one instance) if (defined $CurrentItem{"INFOINPUT"}) IMMEDIATELY below this is a section of code:- { push (@FieldList, $CurrentItem{"INFOINPUT"}); # the info field } REPLACE that section of code with:- { # Norman patching my $sInfoValue = $CurrentItem{"INFOINPUT"}; my $sInfoText = ''; if ( $sInfoValue =~ m/¦/ ) # have a complex selection { my @aValues = split /¦/, $sInfoValue; my @aNames = split /\|/, $$pProduct{"OTHER_INFO_PROMPT"}; my $nJ = @aValues; for (my $nI = 0; $nI < $nJ ; $nI++) { my $sVal = $aValues[$nI]; my $sName = $aNames[$nI]; $sName =~ s/^(\d+)//; $sInfoText .= $sName . " " . $sVal . "\r\n"; } push (@FieldList, $sInfoText); # the complex info field } else { push (@FieldList, $CurrentItem{"INFOINPUT"}); # the info field } } # END Norman patching ########################################################################################### That's all patching finished. Now do a site update. To refresh the modified scripts. Now in your product creation dialogue just set the Other Info Prompt to Prompt1|Prompt2|Prompt3, etc and the required code will be generated automatically. The "|" char is the one on the bottom left of most keyboards (not the one on some keybords top left). If you don't have a "|" character in your prompt, then the original single line prompt is created. Also you can have fields that are optional so the customer can leave them empty without error. Whenever you have a colon character within any of these sub-prompt names, then these fields are optional and will not cause an error if the customer leaves them empty. You can control whether the prompt and input appear on the same or successive lines. If your prompt ends with a space then the input field will follow it on that row. No space and the input field will be on the next row. Finally you can control the width of the input field by starting your prompt with a number. This will be removed from display and and used instead as the field width. E.g. Other Info Prompt:- Name|E-mail|Phone: Optional|Fax: Optional|Postcode or:- 20Name |40E-mail|25Phone: Optional| 25Fax: Optional |12Postcode These patches need a JavaScript 1.2 capable browser, so should work on most modern browsers. Bugs / Quirks. The patches make use internally of the "¦" character (top left ones on most keyboards) and will strip this character from the user input (and replace it with spaces). This shouldn't affect anyone as this is a very unusual character. You can have a maximum of 1000 characters of input (that's user input text + the "¦" delimiters). In practice you'll be limited by how many field names you can fit into the size limit of the Other Info Prompt.