@@ -48,6 +48,205 @@ public static function dropdownButton($title, $contents, $class)
4848 </div> ' ;
4949 }
5050
51+ /**
52+ * creates a simple one column form from the following array:
53+ * array(
54+ * array("title","type","fieldname","value",{size | array(select options) | cols, rows}),
55+ * ...
56+ * )
57+ *
58+ * valid field types are:
59+ * text, password, autocomplete, static, date, textarea, section,
60+ * select, multiselect, checkbox, hidden
61+ *
62+ * Field type auto uses ui hints from a DbObject.
63+ *
64+ * when prefixing a fieldname with a minus sign '-' this field will be read-only
65+ */
66+ public static function form ($ data , $ action = null , $ method = "POST " , $ submitTitle = "Save " , $ id = null , $ class = null , $ target = "_self " , $ enctype = null )
67+ {
68+ if (empty ($ data )) {
69+ return ;
70+ }
71+
72+ $ buffer = "" ;
73+
74+ if (null !== $ action ) {
75+ $ form = new \Html \FormBootstrap5 ();
76+
77+ // If form tag is needed print it
78+ $ class .= " col " ;
79+ $ form ->id ($ id )->setClass ($ class )->method ($ method )->action ($ action )->target ($ target );
80+
81+ if (in_modified_multiarray ("file " , $ data , 1 )) {
82+ $ form ->enctype ("multipart/form-data " );
83+ }
84+
85+ $ buffer .= $ form ->open ();
86+ }
87+
88+ foreach ($ data as $ row ) {
89+ $ buffer .= "<div class='row'><div class='col-12'> " ;
90+
91+ // Backwards compatibility - provide option to pass additional data
92+ $ field = null ;
93+ $ tooltip = null ;
94+ if (is_object ($ row )) {
95+ $ field = property_exists ($ row , 'field ' ) ? $ row ->field : $ row ;
96+ $ tooltip = property_exists ($ row , 'tooltip ' ) ? $ row ->tooltip : null ;
97+ } else {
98+ $ field = array_key_exists ('field ' , $ row ) ? $ row ['field ' ] : $ row ;
99+ $ tooltip = array_key_exists ('tooltip ' , $ row ) ? $ row ['tooltip ' ] : null ;
100+ }
101+
102+ // Check if the row is an object like an InputField
103+ if (!is_array ($ field ) && is_object ($ field )) {
104+ $ label_class = 'form-label ' ;
105+ $ field ->setClass (str_replace (['small-12 ' , 'columns ' , 'column ' ], '' , $ field ->class ?? '' ));
106+ switch (get_class ($ field )) {
107+ case 'Html\Form\Select ' :
108+ case 'Html\Cmfive\SelectWithOther ' :
109+ $ field ->setClass ($ field ->class . ' form-select ' );
110+ break ;
111+ case 'Html\Form\InputField\Checkbox ' :
112+ case 'Html\Form\InputField\Radio ' :
113+ $ field ->setClass ($ field ->class . ' form-check-control ' );
114+ // $label_class = 'form-check-label';
115+ break ;
116+ case 'Html\Form\InputField\Text ' :
117+ case 'Html\Form\InputField\Date ' :
118+ case 'Html\Form\InputField\File ' :
119+ case 'Html\Form\InputField\Number ' :
120+ default :
121+ $ field ->setClass ($ field ->class . ' form-control ' );
122+ break ;
123+ }
124+ if ((property_exists ($ field , "type " ) && $ field ->type !== "hidden " ) || !property_exists ($ field , "type " )) {
125+ $ buffer .= '<div class="col"><label class=" ' . $ label_class . '" '
126+ . (property_exists ($ field , 'id ' ) && !empty ($ field ->id ) ? ' for=" ' . $ field ->id . '" ' : '' )
127+ . '> '
128+ . $ field ->label
129+ . (property_exists ($ field , "required " ) && $ field ->required ? " <small>Required</small> " : "" )
130+ . "</label> "
131+ . $ field ->__toString () . '</div> ' ;
132+ } else {
133+ $ buffer .= $ field ->__toString ();
134+ }
135+ continue ;
136+ }
137+
138+ $ title = !empty ($ field [0 ]) ? $ field [0 ] : '' ;
139+ $ type = !empty ($ field [1 ]) ? $ field [1 ] : '' ;
140+ $ name = !empty ($ field [2 ]) ? $ field [2 ] : '' ;
141+ $ value = !empty ($ field [3 ]) ? $ field [3 ] : '' ;
142+ $ readonly = "" ;
143+
144+ // handle disabled fields
145+ if (substr (($ name ?? "" ), 0 , 1 ) == '- ' ) {
146+ $ name = substr (($ name ?? "" ), 1 );
147+ $ readonly = " readonly='true' " ;
148+ }
149+ // Add title field
150+ if ("section " === $ type ) {
151+ $ buffer .= "<h4> {$ title }</h4></div></div> " ;
152+ continue ;
153+ }
154+
155+ if (!empty ($ title ) && "static " !== $ type && "hidden " !== $ type ) {
156+ $ buffer .= "<label class='col-12'> $ title " ;
157+ }
158+
159+ switch ($ type ) {
160+ case "text " :
161+ case "password " :
162+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
163+ $ required = !empty ($ field [5 ]) ? $ field [5 ] : '' ;
164+ $ buffer .= '<input ' . $ readonly . ' style="width:100%;" type=" ' . $ type . '" name=" ' . $ name . '" value=" ' . htmlspecialchars ($ value ) . '" size=" ' . $ size . '" id=" ' . $ name . '" ' . $ required . '/> ' ;
165+ break ;
166+ case "autocomplete " :
167+ $ options = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
168+ $ minValue = !empty ($ field [5 ]) ? $ field [5 ] : 1 ;
169+ $ required = !empty ($ field [6 ]) ? $ field [6 ] : '' ;
170+ $ buffer .= HtmlBootstrap5::autocomplete ($ name , $ options , $ value , null , "width: 100%; " , $ minValue , $ required );
171+ break ;
172+ case "date " :
173+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
174+ $ buffer .= HtmlBootstrap5::datePicker ($ name , $ value , $ size );
175+ break ;
176+ case "datetime " :
177+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
178+ $ buffer .= HtmlBootstrap5::datetimePicker ($ name , $ value , $ size );
179+ break ;
180+ case "time " :
181+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
182+ $ buffer .= HtmlBootstrap5::timePicker ($ name , $ value , $ size );
183+ break ;
184+ case "static " :
185+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
186+ $ buffer .= "<div class='col-6 col-md-3'> {$ title }</div><div class='col-6 col-md-9'> {$ value }</div> " ;
187+ break ;
188+ case "textarea " :
189+ $ c = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
190+ $ r = !empty ($ field [5 ]) ? $ field [5 ] : '' ;
191+ $ custom_class = true ;
192+ if (isset ($ field [6 ])) {
193+ $ custom_class = $ field [6 ];
194+ }
195+ $ buffer .= '<textarea ' . $ readonly . ' style="width:100%; height:auto; " name=" ' . $ name . '" rows=" ' . $ r . '" cols=" ' . $ c . '" ' .
196+ (!empty ($ custom_class ) ? ($ custom_class === true ? "class='ckeditor' " : "class=' $ custom_class' " ) : '' ) . ' id=" ' . $ name . '"> ' . $ value . '</textarea> ' ;
197+ break ;
198+ case "select " :
199+ $ items = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
200+ $ default = !empty ($ field [5 ]) ? ($ field [5 ] == "null " ? '' : $ field [5 ]) : "-- Select -- " ;
201+ $ class = !empty ($ field [6 ]) ? $ field [6 ] : '' ;
202+ if ($ readonly == "" ) {
203+ $ buffer .= HtmlBootstrap5::select ($ name , $ items , $ value , $ class , "width: 100%; " , $ default , $ readonly != "" );
204+ } else {
205+ $ buffer .= $ value ;
206+ }
207+ break ;
208+ case "multiSelect " :
209+ $ items = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
210+ if ($ readonly == "" ) {
211+ $ buffer .= HtmlBootstrap5::multiSelect ($ name , $ items , $ value , null , "width: 100%; " );
212+ } else {
213+ $ buffer .= $ value ;
214+ }
215+ break ;
216+ case "checkbox " :
217+ $ defaultValue = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
218+ $ class = !empty ($ field [5 ]) ? $ field [5 ] : '' ;
219+ $ buffer .= HtmlBootstrap5::checkbox ($ name , $ value , $ defaultValue , $ class );
220+ break ;
221+ case "radio " :
222+ $ group = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
223+ $ defaultValue = !empty ($ field [5 ]) ? $ field [5 ] : '' ;
224+ $ class = !empty ($ field [6 ]) ? $ field [6 ] : '' ;
225+ $ buffer .= HtmlBootstrap5::radio ($ name , $ group , $ value , $ defaultValue , $ class ) . " " . htmlentities ($ title );
226+ break ;
227+ case "hidden " :
228+ $ buffer .= '<input type="hidden" name=" ' . $ name . '" value=" ' . htmlspecialchars ($ value ) . '" id=" ' . $ name . '"/> ' ;
229+ break ;
230+ case "file " :
231+ $ size = !empty ($ field [4 ]) ? $ field [4 ] : '' ;
232+ $ buffer .= '<input style="width:100%;" type=" ' . $ type . '" name=" ' . $ name . '" size=" ' . $ size . '" id=" ' . $ name . '"/> ' ;
233+ break ;
234+ case "multifile " :
235+ $ buffer .= HtmlBootstrap5::multiFileUpload ($ name );
236+ break ;
237+ }
238+ if (!empty ($ title ) && "static " !== $ type && "hidden " !== $ type ) {
239+ $ buffer .= "</label> " ;
240+ }
241+ $ buffer .= "</div></div> " ;
242+ }
243+
244+ if (null !== $ action ) {
245+ $ buffer .= $ form ->close ($ submitTitle );
246+ }
247+ return $ buffer ;
248+ }
249+
51250 /**
52251 * Creates a complex form where each section can have
53252 * a different number of columns.
0 commit comments