public function outputHTML()
 {
     //Add a remove button after the field. Not shown until jQuery kicks in.
     return parent::outputHTML() . ' <button style="display:none;" id="' . $this->getId() . '_remove" type="button">X</button>';
 }
 /**
  * JsonFormBuilder_elementHidden
  * 
  * Creates a hidden field.
  * @param string $id The ID of the hidden field
  * @param string $label The label of the hidden field
  * @param string $defaultValue The default value to be written into the hidden field
  */
 function __construct($id, $label, $defaultValue = NULL)
 {
     parent::__construct($id, $label, $defaultValue);
     $this->_fieldType = 'hidden';
     $this->_showInEmail = false;
 }
 /**
  * JsonFormBuilder_elementPassword
  * 
  * Creates a password field.
  * @param string $id The ID of the password field
  * @param string $label The label of the password field
  * @param string $defaultValue The default text to be written into the password field
  */
 function __construct($id, $label, $defaultValue = NULL)
 {
     parent::__construct($id, $label, $defaultValue);
     $this->_fieldType = 'password';
 }
 /**
  * outputHTML()
  * 
  * Outputs the HTML for the element.
  * @return string 
  */
 public function outputHTML()
 {
     $s_ret .= '<input type="hidden" name="' . htmlspecialchars($this->_id) . '_gridInfo" value="' . count($this->a_rows) . ',' . count($this->a_columns) . '" />';
     $s_ret .= '<table class="matrix ' . $this->s_type . '"><tr><th class="spaceCell">&nbsp;</th>';
     foreach ($this->a_columns as $column) {
         $s_ret .= '<th class="columnHead">' . htmlspecialchars($column) . '</th><th class="spaceCell">&nbsp;&nbsp;&nbsp;</th>';
     }
     $s_ret .= '</tr>';
     $r_cnt = 0;
     foreach ($this->a_rows as $row) {
         $s_ret .= '<tr><th class="rowHead">' . htmlspecialchars($row) . '</th>';
         $c_cnt = 0;
         foreach ($this->a_columns as $column) {
             switch ($this->s_type) {
                 case 'text':
                     $el = new JsonFormBuilder_elementText($this->_id . '_' . $r_cnt . '_' . $c_cnt, '');
                     $s_cellHTML = $el->outputHTML();
                     break;
                 case 'radio':
                     if ($this->postVal($this->_id . '_' . $r_cnt) === false) {
                         $s_postVal = -1;
                     } else {
                         $s_postVal = $this->postVal($this->_id . '_' . $r_cnt);
                     }
                     $s_cellHTML = '<input ' . ($s_postVal !== '' && $s_postVal == $c_cnt ? 'checked="checked" ' : '') . 'type="radio" id="' . htmlspecialchars($this->_id . '_' . $r_cnt . '_' . $c_cnt) . '" name="' . htmlspecialchars($this->_id . '_' . $r_cnt) . '" value="' . htmlspecialchars($c_cnt) . '" ' . $this->processExtraAttribsToStr() . ' />';
                     break;
                 case 'check':
                     $s_postVal = $this->postVal($this->_id . '_' . $r_cnt);
                     $s_cellHTML = '<input ' . ($s_postVal !== '' && is_array($s_postVal) && in_array($c_cnt, $s_postVal) === true ? 'checked="checked" ' : '') . 'type="checkbox" id="' . htmlspecialchars($this->_id . '_' . $r_cnt . '_' . $c_cnt) . '" name="' . htmlspecialchars($this->_id . '_' . $r_cnt . '[]') . '" value="' . $c_cnt . '" ' . $this->processExtraAttribsToStr() . ' />';
                     break;
             }
             $c_cnt++;
             $s_ret .= '<td class="optionCell">' . $s_cellHTML . '</td><th class="spaceCell">&nbsp;&nbsp;&nbsp;</th>';
         }
         $s_ret .= '</tr>';
         $r_cnt++;
     }
     $s_ret .= '</table>';
     return $s_ret;
 }