====== Use Custom Form Elements ======

SoSci Survey offers a wide selection of [[:en:create:questions|question types]] -- however, sometimes these are insufficient to achieve the desired appearance required for a particular question. If this is the case, SoSci Survey is able to read custom (HTML) form elements as well. JavaScript or Flash based questions can easily be integrated in this way as well.  

These tools give the user a lot of freedom when designing the questionnaire -- however, the complexity involved in programming form elements can quickly get out of hand. 

**Tip:** Before you start programming your own forms, please check to see if there is a simpler option in [[:en:create:composition|Advanced Display Options]].



===== The Problem =====

HTML form elements (e.g. text input fields, checkboxes, drop-downs) can be programmed quickly: the essentials can be found on [[http://de.selfhtml.org/html/formulare/index.htm|SelfHTML]] (German only). Inserting HTML code into the questionnaire is quite simple with a text element (save the HTML code as a text element and drag into the questionnaire).

The problem is that SoSci Survey does not initially recognize any form elements and the data they transmit, and as a result it does not save the responses. Therefore, it is advisable to inform SoSci Survey that certain POST variables should be read and saved in the data record. [[:en:create:questions:internal|Internal variables]] and ''[[:en:create:functions:prepare_input|prepare_input()]]'' are used to do so.


===== Implementation =====

  * First of all, create a question with the type //Internal Variables// in the **List of Questions**.
  * Add at least one variable (item) to this question. It makes sense to give the variable a label: although this does not appear in the questionnaire, it can be seen in the data record. If you use multiple form elements, or if your form element will store several variables, create multiple variables (items) correspondingly. 
  * Create a new text element in **Text Elements and Labels**. In principle, you can insert the HTML code for the form element directly into the questionnaire, but using text elements offers some advantages. 
  * Of course, you can program the HTML code for your form element(s) yourself. You can see an example below for a drop-down selection field. It is important, however, that you use the item ID(s) of the internal variable(s) as the name(s) (attribute ''name'') of the form element. Therefore, if your variable's ID is "AB01_01", then ''%%name="AB01_01"%%'' is written in your form element. 
  * Please consider the position of the input box as well, e.g. in a table.
  * Now insert //PHP code// into the questionnaire (**Compose Questionnaire**) on the respective page and use the command ''prepare_input()'' in order to activate the internal variables, e.g. ''prepare_input('AB01_01');''. If you specfy the question ID (e.g. ''prepare_input('AB01');''), all variables in the question will be activated. 
  * Likewise, insert the text element with the HTML code for the form element onto the page -- the easiest way is by dragging & dropping the text element onto the page. 
  * Now start the page in debug mode (yellow arrow {{:button.debug.here.gif?nolink|Start in Debug Mode}}). If everything has worked as it should have, then you will see that you can use the ID for a form element together with your form element. This is used for information only and cannot be seen by the participant later on.
  * Enter a value in your form element and click on "Next". If you now click on the debug information (yellow corner at the top right of the page), there should be a note that the selected/entered value was stored.

If you program more sophisticated input elements -- e.g. with JavaScript and/or Flash -- then, as a rule, you need to have hidden input fields to store the measured/collected values (see [[:en:create:break-counter|Note when Browser Window Changes]]).

In this instance, do __not__ use the PHP function ''prepare_input()''; drag the "internal variables" question type directly into the questionnaire page instead. This generates hidden input fields in the questionnaire (''%%<input type="hidden">%%'') automatically, and their values can be changed using JavaScript. The HTML ID of the input field corresponds to the item ID. 



===== Limitations =====

There are two major limitations when using custom form elements:

  - The meaning of the answer code will not be saved in the data record. Whereas in a typical selection question, code 1 could be "student" and code 2 could be "employee", you have to keep an eye on this yourself when a custom form element is used. 
  - Making a response compulsory can be implemented with a [[:en:create:checks#individuelle_antwort-pruefung|Customized Response Check]]
  - If you want to give the participant the option of using the Back button, or if the page should be shown again if information is incomplete, you have to ensure that your form element shows a response given previously. In order to do so, you can read the value with ''[[:en:create:functions:value|value()]]'' and insert placeholders into the HTML code for the question. 


===== Example: Extensive Drop-Down Selection Questions =====

SoSci Survey allows a maximum of 99 options in a normal selection question. This also applies to selection options in a drop-down field. This amount is not enough to list all [[http://en.wikipedia.org/wiki/List_of_sovereign_states|countries in the world]]. Using the following HTML code, an input box can be created that supports this.  

**Tip:** A drop-down selection with more than 99 options can also be created with the question type [[:en:create:questions:extselect|Extended Selection]]. A pre-existing selection question can be converted into an extended selection in the tab //Extended//.

<code html>
<select name="AB01_01">
<option value="1">Afghanistan</option>
<option value="2">Albania</option>
<option value="3">Algeria</option>
<!-- etc. -->
<option value="206">Zimbabwe</option>
</select>
</code>

**Tip:** If you have the selection options to hand in Excel or OpenOffice Calc, the function ''CONCATENATE()'' can automatically create the majority of the HTML code. If, for example, the answer code is in column A, and the text in column B, enter the following formula into column C (first row). Then, drag the formula across the whole of column C, and simply copy the code created as a result.


<code excel>
=CONCATENATE("<option value=""";A1;""">";B1;"</option>")
</code>

''AB01_01'' was entered here as the name for the form element ''select'' -- this must be adjusted to the actual item ID (of the item in the "internal variables" question). An attribute ''value'' is specified for each selection option ''option'' -- this determines which numeric code will be submitted. If you want the actual text to be stored, just omit the attribute. 


==== Activating the Internal Variable ====

Only the corresponding PHP code is now missing -- the ID must also be adjusted here:

<code php>
prepare_input('AB01_01');
</code>

Done. Almost, at least. 


==== Display in the Questionnaire ====

At the moment, the drop-down would just be "stuck" on the left-hand side of the page. The following table gives it a little more style: 


<code html>
<table cellspacing="0" cellpadding="0" border="0">
<colgroup>
  <col width="100">
  <col>
</colgroup>
<tr>
  <td>
    <label for="AB01_01">Native Country:</label>
  </td>
  <td>
    <select name="AB01_01" id="AB01_01">
    <option value="1">Afghanistan</option>
    <option value="2">Albania</option>
    <option value="3">Algeria</option>
    <!-- etc. -->
    <option value="206">Zimbabwe</option>
    </select>
  </td>
</tr>
</table>
</code>

To stay with the style of the drop-down fields in SoSci Survey, the CSS classes from SoSci Survey can be used as well:


<code html>
<div class="spacing">
<div class="title">
<p>Question title here</p>
</div>
<div class="titleSpacing"></div>

<table class="question" cellspacing="0" cellpadding="0" width="100%" border="0">
<colgroup>
  <col width="380">
  <col>
</colgroup>

<tr class="shadeH0">
  <td><label for="AB01_01">Native Country:</label></td>
  <td class="dropdown input">
    <select name="AB01_01" id="AB01_01">
    <option value="1">Afghanistan</option>
    <option value="2">Albania</option>
    <option value="3">Algeria</option>
    <!-- etc. -->
    <option value="206">Zimbabwe</option>
    </select>
  </td>
</tr>
</table>
</div>
</code>

**Tip:** The CSS classes that SoSci Survey uses can just be looked up in a "normal" question: the HTML source code can be displayed in the browser by going on the respective page in the questionnaire. The source code for a particular question can easily be found by searching for the question ID. 


===== Example: Use of JavaScript =====

The solution outlined above assumes that the value from the custom input element (''<input>'' or ''<select>'') will be submitted into the data record.

However, it may be the case that you do not want to create this type of input field at all, and want to determine the value using JavaScript instead, and submit this value into the data record. Two changes are necessary if this is the case:

  - Remove ''prepare_input()'' from the questionnaire page.
  - Drag the question type "internal variables" into the questionnaire instead; onto the page where the custom question should appear. Put the question above the JavaScript used to save the value. 

**Tip:** If you only require certain internal variables of the question, set this with the {{:button.settings.png?nolink|Settings}} symbol in //Show items//. Alternatively, insert the question type "internal variables" onto the page using the PHP function ''question()'' and specify the respective item IDs. 

There is no visual change when you insert the question into the questionnaire. However, there will be a hidden input field (''%%type="hidden"%%'') stored for each internal variable. The content of these fields can be read and changed with JavaScript.


<code php>
// Use variables 1 und 2 from question AB01 (type "internal variables")
question('AB01', '1,2');
</code>

<code html>
<script type="text/javascript">
<!--
// Save value in variable 1
document.getElementById("AB01_01").value = "value A";

// Increase last value in variable 2 by 10 
var input2 = document.getElementById("AB01_02");
var curVal = parseInt(input2.value);
if (isNaN(curVal)) {
  input2.value = 10;
} else {
  input2.value = curVal + 10;
}
// -->
</script>
</code>