public function toHtml($blnClientSide = true, $blnForceSubmitted = null, $strCustomJs = "")
    {
        $strOutput = "";

        if ($blnClientSide) {
            $strOutput .= $this->__toJS($strCustomJs);
        }

        $strClass = "validform";

        if (is_array($this->__meta)) {
            if (isset($this->__meta["class"])) {
                $strClass .= " " . $this->__meta["class"];
            }
        }

        $blnForceSubmitted = (is_null($blnForceSubmitted)) ? $this->isSubmitted() : $blnForceSubmitted;

        $strAutoComplete = (!$this->autocomplete) ? "autocomplete=\"off\" " : "";

        $strOutput .= "<form " .
            "id=\"{$this->__name}\" " .
            "method=\"post\" " .
            "enctype=\"multipart/form-data\" " .
            "action=\"{$this->__action}\" {$strAutoComplete}" .
            "class=\"{$strClass}\"{$this->__metaToData()}>\n";

        // *** Main error.
        if ($blnForceSubmitted && !empty($this->__mainalert)) {
            $strOutput .= "<div class=\"vf__main_error\"><p>{$this->__mainalert}</p></div>\n";
        }

        if (!empty($this->__description)) {
            $strOutput .= "<div class=\"vf__description\"><p>{$this->__description}</p></div>\n";
        }

        $blnNavigation = false;
        $strOutput .= $this->fieldsToHtml($blnForceSubmitted, $blnNavigation);

        if (!$blnNavigation) {
            $strOutput .= "<div class=\"vf__navigation\">\n";
            $strOutput .= "<input type=\"submit\" value=\"{$this->__submitlabel}\" class=\"vf__button\" />\n";
            $strOutput .= "</div>\n";
        }

        $strOutput .= "<input type=\"hidden\" name=\"vf__dispatch\" value=\"{$this->__name}\" />\n";

        if ($this->__usecsrfprotection) {
            $strOutput .= "<input type=\"hidden\" name=\"" . CSRF::TOKEN_NAME
                . "\" value=\"" . CSRF::getToken() . "\" />\n";
        }

        $strOutput .= "</form>";

        return $strOutput;
    }