function fp_render_element

6.x render.inc fp_render_element($name, $element, $use_session_submission_values_for_callback = "")
5.x render.inc fp_render_element($name, $element, $use_session_submission_values_for_callback = "")

Returns the HTML to render this form (or content) element to the screen. $name is the HTML machine name. $element is an array containing all we need to render it. If you want default values to be taken from the SESSION (because we had form_errors, say, and we want values to keep what we had between submissions) specify the callback to use in the use_session_submission_values_for_callback variable.

1 call to fp_render_element()
fp_render_array in includes/render.inc
This takes a render_array and generates the HTML for it. This usually is not called directly, but instead you should call fp_render_content() or fp_render_form()

File

includes/render.inc, line 494

Code

function fp_render_element($name, $element, $use_session_submission_values_for_callback = "") {
  $rtn = "";

  $type = @$element ["type"];
  if ($type == "") {
    $type = "markup_no_wrappers";
  }

  // Make sure the "css name" is friendly.
  $cssname = fp_get_machine_readable($name);



  if ($type == "do_not_render") {
    return; // not supposed to render this element.
  }

  // Does the name start with a # character?  If so, do not attempt to render.
  if (substr($name, 0, 1) == "#") {
    return;
  }

  $value = @$element ["value"];
  $label = @$element ["label"];
  $options = @$element ["options"];
  $description = @$element ["description"];
  $popup_description = @$element ["popup_description"];
  $prefix = @$element ["prefix"];
  $suffix = @$element ["suffix"];
  $multiple = @$element ["multiple"];
  $spinner = @$element ["spinner"];
  if ($multiple == TRUE) {
    $multiple = "multiple=multiple";
  }
  else {
    $multiple = "";
  }

  $autocomplete_path = @$element ["autocomplete_path"];
  $required = @$element ["required"];
  $no_please_select = @$element ["no_please_select"];
  if (isset($element ["hide_please_select"])) {
    $no_please_select = @$element ["hide_please_select"];
  }
  $confirm = @$element ["confirm"];

  // Let's also add our cssname as a class to the element, so that even markup will get it...
  if ($type == "markup") {
    if (!isset($element ["attributes"]) || is_array($element ["attributes"])) {
      @$element ["attributes"]["class"] .= " markup-element form-element markup-element-$cssname";
    }
  }



  $attributes = @$element ["attributes"];
  if (!is_array($attributes)) {
    $attributes = array();
    $attributes ['style'] = '';
    $attributes ['class'] = '';
  }

  if ($type == 'textarea_editor') {
    // Add the "html-editor" class to attributes.    
    $attributes ['class'] .= ' html-editor';
  }


  if ($spinner) {
    $attributes ['class'] .= " show-spinner ";
  }


  $popup_help_link = "";
  if ($popup_description) {

    //$popup_help_link = " <a href='javascript: alert(\"" . $popup_description . "\");' class='form-popup-description'>[?]</a>";
    $popup_help_link = fp_get_js_alert_link($popup_description, "<span class='pop-q-mark'><i class='fa fa-question-circle'></i></span>", "form-popup-description");
  }

  $element_error_css = "";
  if (isset($_SESSION ["fp_form_errors"]) && is_array($_SESSION ["fp_form_errors"])) {
    foreach ($_SESSION ["fp_form_errors"] as $err) {
      if ($err ["name"] == $name) {
        // There is an error on this element!  Add an extra CSS element.
        $element_error_css .= " form-element-error ";
      }
    }
  }

  if ($use_session_submission_values_for_callback && is_array(@$_SESSION ["fp_form_submissions"][$use_session_submission_values_for_callback]["values"])) {
    // Check the SESSION for a previous value which we should use.
    $ignore_types = array("hidden", "markup", "markup_no_wrappers", "submit", "password");
    if (!in_array($type, $ignore_types)) {
      $value = $_SESSION ["fp_form_submissions"][$use_session_submission_values_for_callback]["values"][$name];
    }
  }


  if ($type == "markup" && $element_error_css) {
    if (!isset($attributes)) {
      $attributes = array();
    }
    if (is_array($attributes)) {
      $attributes ['class'] .= $element_error_css;
    }
  }


  $extra_wrapper_class = ""; // We will give the wrapper a similar class as are defined in attributes, if any.
  if (is_array($attributes)) {
    // Convert the attributes array into a string.

    $new_attr = "";
    foreach ($attributes as $key => $val) {
      $new_attr .= " $key='$val' ";
      if ($key == 'class') {
        $extra_wrapper_class .= " element-wrapper--" . trim($val);
      }
    }
    $attributes = $new_attr;
  }








  if ($type != "markup" && $type != "markup_no_wrappers") {
    $rtn .= "<div id='element-wrapper-$cssname' class='form-element element-type-$type $extra_wrapper_class'>";
  }

  if ($prefix) {
    $rtn .= $prefix;
  }


  if ($type != "markup" && $type != "markup_no_wrappers") {
    $rtn .= "<div id='element-inner-wrapper-$cssname' class='form-element element-type-$type $element_error_css'>";
  }


  if ($type == 'datetime-local') {
    // As of the time of this comment (8-16-2021) FireFox STILL does not support datetime-local as a field type for their desktop browser,
    // even though they support it for mobile.  Every other modern browser supports it as well.
    // Anyway, we will need to include a workaround in jquery as a result if this field is being used:
    fp_add_js(fp_get_module_path("system") . '/lib/jquery.datetimepicker/jquery.datetimepicker.min.js');
    fp_add_css(fp_get_module_path("system") . '/lib/jquery.datetimepicker/jquery.datetimepicker.min.css');

    fp_add_js(fp_get_module_path("system") . '/lib/fp_datetimepicker_shim/fp_datetimepicker_shim.js');
  }



  $ast = "";
  if ($required) {
    $ast = "<span class='form-required-ast'>*</span>";
  }

  // First of all, what is it's "type"?
  if ($type == "markup") {
    if (is_string($attributes) && $attributes != "") {
      $rtn .= "<div $attributes>";
    }

    // If a label is set, go ahead and display, even though its markup...
    if ($label != "") {
      $rtn .= "<label>$ast$label$popup_help_link</label>";
    }

    $rtn .= $value;

    if (is_string($attributes) && $attributes != "") {
      $rtn .= "</div>";
    }
  }
  else if ($type == "markup_no_wrappers") {

    // If a label is set, go ahead and display, even though its markup...
    if ($label != "") {
      $rtn .= "<label>$ast$label$popup_help_link</label>";
    }

    $rtn .= $value; // plain value, no wrapper divs at all.
  }
  else if ($type != "hidden" && $type != "checkbox") {
    $rtn .= "<label>$ast$label$popup_help_link</label>";
  }

  if ($type == "textarea" || $type == 'textarea_editor') {
    $rows = (isset($element ["rows"])) ? $element ["rows"] : "5";
    $maxlength = (isset($element ["maxlength"])) ? $element ["maxlength"] : "";
    $extra_span = "";
    // if maxlength is set, then we want to show the char count upon change.
    if ($maxlength != "") {
      fp_add_css(fp_get_module_path('system') . '/css/style.css');
      fp_add_js(fp_get_module_path('system') . '/js/textarea-maxlength.js');
      $extra_span = "<span class='textarea-maxlength-count' id='textarea-maxlength-count___$cssname'>
                          <span class='current-count' id='element-{$cssname}__current_count'>0</span>/<span class='maxlength-chars'>$maxlength</span>
                          <span class='maxlength-description'>" . t("Max Characters") . "</span>
                      </span>";

    }

    $rtn .= "<textarea name='$name' id='element-$cssname' rows='$rows' maxlength='$maxlength' $attributes>$value</textarea>$extra_span";
  }

  if ($type == "textfield" || $type == "text" || $type == "search" || $type == "password" || $type == 'datetime-local' || $type == 'time' || $type == 'date') {
    if ($type == "textfield") {
      $type = "text";
    }
    $size = (isset($element ["size"])) ? $element ["size"] : "60";
    $maxlength = (isset($element ["maxlength"])) ? $element ["maxlength"] : "255";

    // if there is an autocomplete_path, we need to include some javascript.
    if ($autocomplete_path != "") {
      fp_add_js(array("autocomplete_fields" => array(array("id" => "element-$cssname", "path" => $autocomplete_path))), 'setting');
    }


    $value = htmlentities($value, ENT_QUOTES);
    $rtn .= "<input type='$type' name='$name' id='element-$cssname' size='$size' maxlength='$maxlength' value='$value' $attributes>";
  }

  if ($type == "hidden" || $type == "value") {
    $value = htmlentities($value, ENT_QUOTES);
    $rtn .= "<input type='hidden' name='$name' id='element-$cssname' value='$value'>";
  }


  if ($type == "file") {
    $tname = $name;
    // Always going to put [] for a file, no matter what.
    //if ($multiple != "") {
    $tname .= "[]"; // if we allow uploading multiple files, we MUST put a [] behind it, or HTML will not upload correctly.  Weird but true.
    //}
    $rtn .= "<input type='file' name='$tname' id='element-$cssname' $multiple $attributes>";
  }


  if ($type == "radios") {
    $rtn .= "<div class='form-radios form-radios-$cssname'>";
    foreach ($options as $key => $val) {
      $checked = "";

      // For radios, it's possible we've been sent an array for the value (though a string is more common and prefered).
      // We need to check both.  
      if (is_array($value) && $value [$key] == $key) {
        $checked = "checked=checked";
      }
      else if (!is_array($value) && $value == $key) {
        $checked = "checked=checked";
      }

      $csskey = fp_get_machine_readable($key);
      $rtn .= "<div class='radio-element radio-element-$csskey'>
                 <label class='label-for-radio'><input type='radio' name='$name' id='element-$cssname-$csskey' value='$key' $checked $attributes> $val</label>
               </div>";
    }
    $rtn .= "</div>";
  }

  if ($type == "select") {
    $rtn .= "<select name='$name' id='element-$cssname' $attributes>";
    if ($no_please_select != TRUE) {
      $rtn .= "<option value=''>- Please select -</option>";
    }

    foreach ($options as $key => $val) {

      if (is_array($val)) {
        // We need to establish an optgroup and then descend one level.
        $rtn .= "<optgroup label='" . htmlentities($key) . "'>";
        foreach ($val as $k => $v) {
          $selected = "";
          if ($value == $k) {
            $selected = "selected";
          }
          $rtn .= "<option value='$k' $selected>$v</option>";

        }
        $rtn .= "</optgroup>";
      }
      else {
        // This is just a normal string, so we can continue as-is  
        $selected = "";
        if ($value == $key) {
          $selected = "selected";
        }
        $rtn .= "<option value='$key' $selected>$val</option>";
      }
    }
    $rtn .= "</select>";
  }


  // Multiple checkboxes...
  if ($type == "checkboxes") {
    $rtn .= "<div class='form-checkboxes form-checkboxes-$cssname'>";
    foreach ($options as $key => $val) {

      if (is_array($val)) {
        // Similar to select lists above, we need to simulate having "optgroup"s for checkboxes.
        $rtn .= "<div class='checkbox-pseudo-optgroup-wrapper'>
                  <label>$key</label>";
        foreach ($val as $k => $v) {
          $checked = "";
          if (is_array($value) && isset($value [$k]) && $value [$k] == $k) {
            $checked = "checked=checked";
          }

          $csskey = fp_get_machine_readable($key);
          $rtn .= "<div class='checkbox-element checkbox-element-$csskey'>
                     <label class='label-for-checkbox'><input type='checkbox' name='$name" . "[$k]' id='element-$cssname-$csskey' value='$k' $checked $attributes> $v</label>
                   </div>";
        }
        $rtn .= "</div>"; // close the pseudo-optgroup-wrapper
      }
      else {
        $checked = "";
        if (is_array($value) && isset($value [$key]) && $value [$key] == $key) {
          $checked = "checked=checked";
        }
        $csskey = fp_get_machine_readable($key);
        $rtn .= "<div class='checkbox-element checkbox-element-$csskey'>
                   <label class='label-for-checkbox'><input type='checkbox' name='$name" . "[$key]' id='element-$cssname-$csskey' value='$key' $checked $attributes> $val</label>
                 </div>";
      }
    }
    $rtn .= "</div>";
  }

  // A single checkbox... The values will be with 0 (zero) or 1 (one), and boolean
  // values are accepted/saved
  if ($type == "checkbox") {
    $rtn .= "<div class='form-checkbox form-checkbox-$cssname'>";

    $checked = "";
    if ((bool) ($value) == TRUE) {
      $checked = "checked=checked";
    }
    $rtn .= "<div class='checkbox-element'>
               <label class='label-for-checkbox'><input type='checkbox' name='$name' id='element-$cssname' value='1' $checked $attributes> $label$popup_help_link</label>
             </div>";

    $rtn .= "</div>";
  }



  if ($type == "submit") {

    if ($confirm != "") {
      $confirm = htmlentities($confirm, ENT_QUOTES);
      $confirm = str_replace("\n", "\\n", $confirm);

      $attributes .= " onClick='return confirm(\"$confirm\");' ";
    }

    $rtn .= "<input type='$type' name='$name' value='$value' $attributes>";
  }

  if ($type == "button") {
    $rtn .= "<input type='button' name='$name' value='$value' $attributes>";
  }

  if ($spinner) {
    fp_add_css(fp_get_module_path("system") . "/css/style.css");
    fp_add_js(fp_get_module_path("system") . "/js/spinner.js");
    $rtn .= "<span class='loading-spinner loading-spinner-$name' style='display:none;'></span>";
  }


  if ($description) {
    $rtn .= "<div class='form-element-description'>$description</div>";
  }

  if ($type != "markup" && $type != 'markup_no_wrappers') {
    $rtn .= "</div>"; // close the inner wrapper
  }



  if ($suffix) {
    $rtn .= $suffix;
  }

  if ($type != "markup" && $type != 'markup_no_wrappers') {
    $rtn .= "</div>"; // close the over-all wrapper
  }






  return $rtn;
}