forked from Business/BinStack
		
	
		
			
				
	
	
		
			276 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			276 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| /*
 | |
|  * This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | |
|  */
 | |
| 
 | |
| class FormBuilder {
 | |
| 
 | |
|     private $items = [];
 | |
|     private $hiddenitems = [];
 | |
|     private $title = "";
 | |
|     private $icon = "";
 | |
|     private $buttons = [];
 | |
|     private $action = "action.php";
 | |
|     private $method = "POST";
 | |
|     private $id = "editform";
 | |
| 
 | |
|     /**
 | |
|      * Create a form with autogenerated HTML.
 | |
|      *
 | |
|      * @param string $title Form title/heading
 | |
|      * @param string $icon FontAwesone icon next to the title.
 | |
|      * @param string $action URL to submit the form to.
 | |
|      * @param string $method Form submission method (POST, GET, etc.)
 | |
|      */
 | |
|     public function __construct(string $title = "Untitled Form", string $icon = "fas fa-file-alt", string $action = "action.php", string $method = "POST") {
 | |
|         $this->title = $title;
 | |
|         $this->icon = $icon;
 | |
|         $this->action = $action;
 | |
|         $this->method = $method;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the title of the form.
 | |
|      * @param string $title
 | |
|      */
 | |
|     public function setTitle(string $title) {
 | |
|         $this->title = $title;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the icon for the form.
 | |
|      * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
 | |
|      */
 | |
|     public function setIcon(string $icon) {
 | |
|         $this->icon = $icon;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the URL the form will submit to.
 | |
|      * @param string $action
 | |
|      */
 | |
|     public function setAction(string $action) {
 | |
|         $this->action = $action;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the form submission method (GET, POST, etc)
 | |
|      * @param string $method
 | |
|      */
 | |
|     public function setMethod(string $method = "POST") {
 | |
|         $this->method = $method;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the form ID.
 | |
|      * @param string $id
 | |
|      */
 | |
|     public function setID(string $id = "editform") {
 | |
|         $this->id = $id;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add an input to the form.
 | |
|      *
 | |
|      * @param string $name Element name
 | |
|      * @param string $value Element value
 | |
|      * @param string $type Input type (text, number, date, select, tel...)
 | |
|      * @param bool $required If the element is required for form submission.
 | |
|      * @param string $id Element ID
 | |
|      * @param array $options Array of [value => text] pairs for a select element
 | |
|      * @param string $label Text label to display near the input
 | |
|      * @param string $icon FontAwesome icon (example: "fas fa-toilet-paper")
 | |
|      * @param int $width Bootstrap column width for the input, out of 12.
 | |
|      * @param int $minlength Minimum number of characters for the input.
 | |
|      * @param int $maxlength Maximum number of characters for the input.
 | |
|      * @param string $pattern Regex pattern for custom client-side validation.
 | |
|      * @param string $error Message to show if the input doesn't validate.
 | |
|      */
 | |
|     public function addInput(string $name, string $value = "", string $type = "text", bool $required = true, string $id = null, array $options = null, string $label = "", string $icon = "", int $width = 4, int $minlength = 1, int $maxlength = 100, string $pattern = "", string $error = "") {
 | |
|         $item = [
 | |
|             "name" => $name,
 | |
|             "value" => $value,
 | |
|             "type" => $type,
 | |
|             "required" => $required,
 | |
|             "label" => $label,
 | |
|             "icon" => $icon,
 | |
|             "width" => $width,
 | |
|             "minlength" => $minlength,
 | |
|             "maxlength" => $maxlength
 | |
|         ];
 | |
|         if (!empty($id)) {
 | |
|             $item["id"] = $id;
 | |
|         }
 | |
|         if (!empty($options) && $type == "select") {
 | |
|             $item["options"] = $options;
 | |
|         }
 | |
|         if (!empty($pattern)) {
 | |
|             $item["pattern"] = $pattern;
 | |
|         }
 | |
|         if (!empty($error)) {
 | |
|             $item["error"] = $error;
 | |
|         }
 | |
|         $this->items[] = $item;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add a button to the form.
 | |
|      *
 | |
|      * @param string $text Text string to show on the button.
 | |
|      * @param string $icon FontAwesome icon to show next to the text.
 | |
|      * @param string $href If not null, the button will actually be a hyperlink.
 | |
|      * @param string $type Usually "button" or "submit".  Ignored if $href is set.
 | |
|      * @param string $id The element ID.
 | |
|      * @param string $name The element name for the button.
 | |
|      * @param string $value The form value for the button. Ignored if $name is null.
 | |
|      * @param string $class The CSS classes for the button, if a standard success-colored one isn't right.
 | |
|      */
 | |
|     public function addButton(string $text, string $icon = "", string $href = null, string $type = "button", string $id = null, string $name = null, string $value = "", string $class = "btn btn-success") {
 | |
|         $button = [
 | |
|             "text" => $text,
 | |
|             "icon" => $icon,
 | |
|             "class" => $class,
 | |
|             "type" => $type,
 | |
|             "id" => $id,
 | |
|             "href" => $href,
 | |
|             "name" => $name,
 | |
|             "value" => $value
 | |
|         ];
 | |
|         $this->buttons[] = $button;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Add a hidden input.
 | |
|      * @param string $name
 | |
|      * @param string $value
 | |
|      */
 | |
|     public function addHiddenInput(string $name, string $value) {
 | |
|         $this->hiddenitems[$name] = $value;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Generate the form HTML.
 | |
|      * @param bool $echo If false, returns HTML string instead of outputting it.
 | |
|      */
 | |
|     public function generate(bool $echo = true) {
 | |
|         $html = <<<HTMLTOP
 | |
| <form action="$this->action" method="$this->method" id="$this->id">
 | |
|     <div class="card">
 | |
|          <h3 class="card-header d-flex">
 | |
|             <div>
 | |
|                 <i class="$this->icon"></i> $this->title
 | |
|             </div>
 | |
|         </h3>
 | |
| 
 | |
|         <div class="card-body">
 | |
|             <div class="row">
 | |
| HTMLTOP;
 | |
| 
 | |
|         foreach ($this->items as $item) {
 | |
|             $required = $item["required"] ? "required" : "";
 | |
|             $id = empty($item["id"]) ? "" : "id=\"$item[id]\"";
 | |
|             $pattern = empty($item["pattern"]) ? "" : "pattern=\"$item[pattern]\"";
 | |
|             if (empty($item['type'])) {
 | |
|                 $item['type'] = "text";
 | |
|             }
 | |
|             $itemhtml = "";
 | |
|             $itemlabel = "";
 | |
|             if ($item['type'] != "checkbox") {
 | |
|                 $itemlabel = "<label class=\"mb-0\">$item[label]:</label>";
 | |
|             }
 | |
|             $strippedlabel = strip_tags($item['label']);
 | |
|             $itemhtml .= <<<ITEMTOP
 | |
| \n\n                <div class="col-12 col-md-$item[width]">
 | |
|                     <div class="form-group mb-3">
 | |
|                         $itemlabel
 | |
|                         <div class="input-group">
 | |
|                             <div class="input-group-prepend">
 | |
|                                 <span class="input-group-text"><i class="$item[icon]"></i></span>
 | |
|                             </div>
 | |
| ITEMTOP;
 | |
|             switch ($item['type']) {
 | |
|                 case "select":
 | |
|                     $itemhtml .= <<<SELECT
 | |
| \n                            <select class="form-control" name="$item[name]" aria-label="$strippedlabel" $required>
 | |
| SELECT;
 | |
|                     foreach ($item['options'] as $value => $label) {
 | |
|                         $selected = "";
 | |
|                         if (!empty($item['value']) && $value == $item['value']) {
 | |
|                             $selected = " selected";
 | |
|                         }
 | |
|                         $itemhtml .= "\n                                <option value=\"$value\"$selected>$label</option>";
 | |
|                     }
 | |
|                     $itemhtml .= "\n                            </select>";
 | |
|                     break;
 | |
|                 case "checkbox":
 | |
|                     $itemhtml .= <<<CHECKBOX
 | |
| \n                            <div class="form-group form-check">
 | |
|                                 <input type="checkbox" name="$item[name]" $id class="form-check-input" value="$item[value]" $required aria-label="$strippedlabel">
 | |
|                                 <label class="form-check-label">$item[label]</label>
 | |
|                               </div>
 | |
| CHECKBOX;
 | |
|                     break;
 | |
|                 default:
 | |
|                     $itemhtml .= <<<INPUT
 | |
| \n                            <input type="$item[type]" name="$item[name]" $id class="form-control" aria-label="$strippedlabel" minlength="$item[minlength]" maxlength="$item[maxlength]" $pattern value="$item[value]" $required />
 | |
| INPUT;
 | |
|                     break;
 | |
|             }
 | |
| 
 | |
|             if (!empty($item["error"])) {
 | |
|                 $itemhtml .= <<<ERROR
 | |
| \n                            <div class="invalid-feedback">
 | |
|                                 $item[error]
 | |
|                             </div>
 | |
| ERROR;
 | |
|             }
 | |
|             $itemhtml .= <<<ITEMBOTTOM
 | |
| \n                        </div>
 | |
|                     </div>
 | |
|                 </div>\n
 | |
| ITEMBOTTOM;
 | |
|             $html .= $itemhtml;
 | |
|         }
 | |
| 
 | |
|         $html .= <<<HTMLBOTTOM
 | |
| 
 | |
|             </div>
 | |
|         </div>
 | |
| HTMLBOTTOM;
 | |
| 
 | |
|         if (!empty($this->buttons)) {
 | |
|             $html .= "\n        <div class=\"card-footer\">";
 | |
|             foreach ($this->buttons as $btn) {
 | |
|                 $btnhtml = "";
 | |
|                 $inner = "<i class=\"$btn[icon]\"></i> $btn[text]";
 | |
|                 $id = empty($btn['id']) ? "" : "id=\"$btn[id]\"";
 | |
|                 if (!empty($btn['href'])) {
 | |
|                     $btnhtml = "<a href=\"$btn[href]\" class=\"$btn[class]\" $id>$inner</a>";
 | |
|                 } else {
 | |
|                     $name = empty($btn['name']) ? "" : "name=\"$btn[name]\"";
 | |
|                     $value = (!empty($btn['name']) && !empty($btn['value'])) ? "value=\"$btn[value]\"" : "";
 | |
|                     $btnhtml = "<button type=\"$btn[type]\" class=\"$btn[class]\" $id $name $value>$inner</button>";
 | |
|                 }
 | |
|                 $html .= "\n            $btnhtml";
 | |
|             }
 | |
|             $html .= "\n        </div>";
 | |
|         }
 | |
| 
 | |
|         $html .= "\n    </div>";
 | |
|         foreach ($this->hiddenitems as $name => $value) {
 | |
|             $value = htmlentities($value);
 | |
|             $html .= "\n    <input type=\"hidden\" name=\"$name\" value=\"$value\" />";
 | |
|         }
 | |
|         $html .= "\n</form>\n";
 | |
| 
 | |
|         if ($echo) {
 | |
|             echo $html;
 | |
|         }
 | |
|         return $html;
 | |
|     }
 | |
| 
 | |
| }
 |