Mobile UI form
Posted: Thu Jan 01, 2026 5:49 pm
There is actually so little code available using Mobile UI which is a nice library.
So here is one solution to handle basic form and inputs built almost totally using Spiderbasic syntax.
It has also some debug code.
It is created using MiniMax 2.1 almost totally.
So here is one solution to handle basic form and inputs built almost totally using Spiderbasic syntax.
It has also some debug code.
It is created using MiniMax 2.1 almost totally.
Code: Select all
EnableExplicit
; Application constants
Enumeration
#MainPage
#JsonDialog
#ToolBar
#FirstNameInput
#LastNameInput
#AgeInput
#EmailInput
#SubmitButton
#DialogTitle
#CloseDialogButton
#CopyJsonButton
#URLInputDialog
#URLInput
#OpenURLDialogButton
#URLSubmitButton
#URLCancelButton
EndEnumeration
; Regular expression IDs for validation
Enumeration
#RegexEmail
#RegexNumeric
#RegexName
EndEnumeration
; Maximum field lengths
#MaxFirstNameLength = 30
#MaxLastNameLength = 30
; Global variables
Global FirstName$, LastName$, Age$, Email$, JSONString$
Global URLGenerated = 0 ; Track if URL has been generated and is ready to submit
;{ UI Creation
Procedure CreateJsonDialog()
; Create the dialog container for displaying JSON
If ContainerMobile(#JsonDialog, #PB_Mobile_Dialog, "padding:16px; border-radius:12px;")
; Dialog header with icon and title
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px 8px 0 0;")
IconMobile(#PB_Any, "fa-bolt", #PB_Mobile_Left)
TextMobile(#DialogTitle, "Generated JSON", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; JSON content area with monospace font
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:16px; background-color: #f5f5f5;")
HtmlMobile("<pre id='jsonDisplay' style='font-family: monospace; font-size: 14px; color: #333; background: white; padding: 12px; border-radius: 8px; overflow-x: auto; word-wrap: break-word; margin: 0; border: 1px solid #ddd;'>JSON will appear here</pre>")
CloseMobileContainer()
EndIf
; Action buttons row
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; gap: 12px;")
ButtonMobile(#CopyJsonButton, "Copy", #PB_Mobile_Left)
ButtonMobile(#CloseDialogButton, "Close", #PB_Mobile_Right)
CloseMobileContainer()
EndIf
CloseMobileContainer()
EndIf
EndProcedure
Procedure CreateURLInputDialog()
; Create the dialog for URL input
If ContainerMobile(#URLInputDialog, #PB_Mobile_Dialog, "padding:16px; border-radius:12px;")
; Dialog header with icon and title
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; background: linear-gradient(135deg, #11998e 0%, #38ef7d 100%); border-radius: 8px 8px 0 0;")
IconMobile(#PB_Any, "md-link", #PB_Mobile_Left)
TextMobile(#PB_Any, "Submit to URL", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; URL input field
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background: white; border-radius: 12px; margin-bottom: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "md-link", #PB_Mobile_Left)
InputMobile(#URLInput, "", "Enter URL (e.g., https://api.example.com) ", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; Output area to show the URL that will be submitted
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background-color: #f5f5f5;")
HtmlMobile("<pre id='urlOutput' style='font-family: monospace; font-size: 12px; color: #333; background: white; padding: 8px; border-radius: 8px; overflow-x: auto; word-wrap: break-word; margin: 0; border: 1px solid #ddd;'>URL will be displayed here</pre>")
CloseMobileContainer()
EndIf
; Info text
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px;")
HtmlMobile("<div style='font-size: 12px; color: #666;'>The form data will be submitted as URL parameters to this endpoint.</div>")
CloseMobileContainer()
EndIf
; Action buttons row
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; gap: 12px;")
ButtonMobile(#URLCancelButton, "Cancel", #PB_Mobile_Left)
ButtonMobile(#URLSubmitButton, "Submit", #PB_Mobile_Right)
CloseMobileContainer()
EndIf
CloseMobileContainer()
EndIf
EndProcedure
Procedure CreateMainPage()
; Create the main page container
If ContainerMobile(#MainPage, #PB_Mobile_Page, "padding:16px; background: linear-gradient(180deg, #e6dcfc 0%, #e4e8ec 100%);")
; Create toolbar with app title
ToolBarMobile(#ToolBar)
IconMobile(#PB_Any, "md-account-edit", #PB_Mobile_Left)
TextMobile(#PB_Any, "User Form", #PB_Mobile_Center)
IconMobile(#PB_Any, "md-information", #PB_Mobile_Right)
CloseMobileContainer()
; Form header section
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:20px 16px 10px;")
IconMobile(#PB_Any, "md-form", #PB_Mobile_Left)
TextMobile(#PB_Any, "Enter Your Information", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; First Name input field
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background: white; border-radius: 12px; margin-bottom: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "md-face", #PB_Mobile_Left)
InputMobile(#FirstNameInput, "", "First Name", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; Last Name input field
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background: white; border-radius: 12px; margin-bottom: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "ion-ios-pulse", #PB_Mobile_Left)
InputMobile(#LastNameInput, "", "Last Name", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; Age input field
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background: white; border-radius: 12px; margin-bottom: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "md-cake", #PB_Mobile_Left)
InputMobile(#AgeInput, "", "Age", #PB_Mobile_Center | #PB_Mobile_Numeric)
CloseMobileContainer()
EndIf
; Email input field
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; background: white; border-radius: 12px; margin-bottom: 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "md-email", #PB_Mobile_Left)
InputMobile(#EmailInput, "", "Email Address", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; Submit buttons row
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:8px; gap: 8px;")
ButtonMobile(#SubmitButton, "Generate JSON", #PB_Mobile_Left)
ButtonMobile(#OpenURLDialogButton, "Submit to URL", #PB_Mobile_Right)
CloseMobileContainer()
EndIf
; Info section JSON
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:16px; background: white; border-radius: 12px; margin-top: 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "fa-fighter-jet", #PB_Mobile_Left)
HtmlMobile("<div style='font-size: 14px; color: #666;'>Fill in all fields and tap 'Generate JSON' to create a JSON object from your input data.</div>")
CloseMobileContainer()
EndIf
; Info section Submit
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:16px; background: white; border-radius: 12px; margin-top: 16px; box-shadow: 0 2px 4px rgba(0,0,0,0.1);")
IconMobile(#PB_Any, "fa-fighter-jet", #PB_Mobile_Left)
HtmlMobile("<div style='font-size: 14px; color: #666;'>Fill in all fields and tap 'Submit to URL' to create a URL with parameters. Then you can Submit the data if you want.</div>")
CloseMobileContainer()
EndIf
CloseMobileContainer()
EndIf
EndProcedure
;}
;{ Event Handlers
Procedure.s ValidateFormInputs(FirstName$, LastName$, Age$, Email$)
; Validates form inputs and returns error message if invalid, empty string if valid
; Check first name is not empty
If Len(FirstName$) = 0
ProcedureReturn "Please enter a first name."
EndIf
; Check first name length
If Len(FirstName$) > #MaxFirstNameLength
ProcedureReturn "First name cannot exceed " + Str(#MaxFirstNameLength) + " characters."
EndIf
; Check first name contains valid characters (must start with letter)
If Not MatchRegularExpression(#RegexName, FirstName$)
ProcedureReturn "First name must start with a letter and contain only letters, spaces, hyphens, and apostrophes."
EndIf
; Check last name is not empty
If Len(LastName$) = 0
ProcedureReturn "Please enter a last name."
EndIf
; Check last name length
If Len(LastName$) > #MaxLastNameLength
ProcedureReturn "Last name cannot exceed " + Str(#MaxLastNameLength) + " characters."
EndIf
; Check last name contains valid characters (must start with letter)
If Not MatchRegularExpression(#RegexName, LastName$)
ProcedureReturn "Last name must start with a letter and contain only letters, spaces, hyphens, and apostrophes."
EndIf
; Check age is a valid number
If Len(Age$) = 0
ProcedureReturn "Please enter an age."
EndIf
; Use regular expression to check if age is numeric (positive integer only)
If Not MatchRegularExpression(#RegexNumeric, Age$)
ProcedureReturn "Age must be a valid number (no decimals or negative values)."
EndIf
; Check age is within reasonable range
If Val(Age$) < 1 Or Val(Age$) > 110
ProcedureReturn "Please enter a valid age (1-110)."
EndIf
; Check email format using regular expression
If Len(Email$) = 0
ProcedureReturn "Please enter an email address."
EndIf
; Validate email format with regex
If Not MatchRegularExpression(#RegexEmail, Email$)
ProcedureReturn "Please enter a valid email address (e.g., user@domain.com)."
EndIf
; All validations passed
ProcedureReturn ""
EndProcedure
;}
Procedure MobileEvents()
Select EventMobile()
Case #SubmitButton
; Get values from input fields
FirstName$ = GetMobileText(#FirstNameInput)
LastName$ = GetMobileText(#LastNameInput)
Age$ = GetMobileText(#AgeInput)
Email$ = GetMobileText(#EmailInput)
; Validate inputs using the validation procedure
Define ErrorMessage$
ErrorMessage$ = ValidateFormInputs(FirstName$, LastName$, Age$, Email$)
If ErrorMessage$ <> ""
AlertMobile(ErrorMessage$)
ProcedureReturn
EndIf
; Build JSON using SpiderBasic JSON functions
Define Person, FormattedJSON$
; Create JSON with ID 0
If CreateJSON(0)
; Get the JSON value and set it as an object
Person = SetJSONObject(JSONValue(0))
; Add members to the object using the correct syntax
SetJSONString(AddJSONMember(Person, "firstName"), FirstName$)
SetJSONString(AddJSONMember(Person, "lastName"), LastName$)
SetJSONInteger(AddJSONMember(Person, "age"), Val(Age$))
SetJSONString(AddJSONMember(Person, "email"), Email$)
SetJSONString(AddJSONMember(Person, "createdAt"), FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Date()))
; Compose the JSON string with pretty print formatting
JSONString$ = ComposeJSON(0)
; Debug output to verify
Debug "JSONString$: " + JSONString$
; Parse and format the JSON for pretty display
ParseJSON(0, JSONString$)
FormattedJSON$ = ComposeJSON(0, #PB_JSON_PrettyPrint)
; Debug output to verify formatted JSON
Debug "FormattedJSON$: " + FormattedJSON$
EndIf
; Close the current dialog
CloseMobileContainer()
; Create a new dialog with the JSON already embedded in the HTML
If ContainerMobile(#JsonDialog, #PB_Mobile_Dialog, "padding:16px; border-radius:12px;")
; Dialog header with icon and title
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); border-radius: 8px 8px 0 0;")
IconMobile(#PB_Any, "md-json", #PB_Mobile_Left)
TextMobile(#DialogTitle, "Generated JSON", #PB_Mobile_Center)
CloseMobileContainer()
EndIf
; JSON content area - embed the JSON directly in the HTML
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:16px; background-color: #f5f5f5;")
HtmlMobile("<pre id='jsonDisplay' style='font-family: monospace; font-size: 14px; color: #333; background: white; padding: 12px; border-radius: 8px; overflow-x: auto; word-wrap: break-word; margin: 0; border: 1px solid #ddd;'>" + FormattedJSON$ + "</pre>")
CloseMobileContainer()
EndIf
; Action buttons row
If ContainerMobile(#PB_Any, #PB_Mobile_Row, "padding:12px; gap: 12px;")
ButtonMobile(#CopyJsonButton, "Copy", #PB_Mobile_Left)
ButtonMobile(#CloseDialogButton, "Close", #PB_Mobile_Right)
CloseMobileContainer()
EndIf
CloseMobileContainer()
EndIf
; Show the dialog
ShowMobile(#JsonDialog, #True)
Case #CloseDialogButton
; Hide the dialog
ShowMobile(#JsonDialog, #False)
Case #CopyJsonButton
; Copy JSON to clipboard by reading from the HTML element
; Use querySelector to get the pre element in the current dialog
!var jsonElements = document.querySelectorAll('#jsonDisplay');
!var latestElement = jsonElements[jsonElements.length - 1]; // Get the most recent one
!if (latestElement && latestElement.textContent) {
! var jsonText = latestElement.textContent.trim();
! if (jsonText && jsonText !== 'JSON will appear here') {
! navigator.clipboard.writeText(jsonText).then(function() {
! alert('JSON copied to clipboard!');
! }).catch(function(err) {
! console.error('Failed to copy: ', err);
! });
! }
!}
Case #OpenURLDialogButton
; First get the current values from input fields
FirstName$ = GetMobileText(#FirstNameInput)
LastName$ = GetMobileText(#LastNameInput)
Age$ = GetMobileText(#AgeInput)
Email$ = GetMobileText(#EmailInput)
; Then validate the form data before opening URL dialog
Define ErrorMessage$
ErrorMessage$ = ValidateFormInputs(FirstName$, LastName$, Age$, Email$)
If ErrorMessage$ <> ""
AlertMobile(ErrorMessage$)
ProcedureReturn
EndIf
; Open the URL input dialog
ShowMobile(#URLInputDialog, #True)
Case #URLCancelButton
; Hide the URL input dialog and reset the generated URL state
URLGenerated = 0
ShowMobile(#URLInputDialog, #False)
Case #URLSubmitButton
; Check if URL has already been generated (second click = navigate)
If URLGenerated = 1
; Navigate to the URL using JavaScript
!window.location.href = v_fullurl$;
; Reset the state
URLGenerated = 0
; Hide the dialog
ShowMobile(#URLInputDialog, #False)
ProcedureReturn
EndIf
; First click: Generate the URL
; Get the URL from the input field
Define TargetURL$
TargetURL$ = GetMobileText(#URLInput)
; Validate URL is not empty
If TargetURL$ = ""
AlertMobile("Please enter a URL.")
ProcedureReturn
EndIf
; Validate URL format (basic check)
If Not MatchRegularExpression(#RegexEmail, TargetURL$)
; Use a simple check for http:// or https://
If Left(TargetURL$, 7) <> "http://" And Left(TargetURL$, 8) <> "https://"
AlertMobile("Please enter a valid URL starting with http:// or https://")
ProcedureReturn
EndIf
EndIf
; Build URL with parameters using SpiderBasic's URLEncoder
Define URLParams$
URLParams$ = "firstName=" + URLEncoder(FirstName$) + "&"
URLParams$ + "lastName=" + URLEncoder(LastName$) + "&"
URLParams$ + "age=" + URLEncoder(Age$) + "&"
URLParams$ + "email=" + URLEncoder(Email$)
; Construct the full URL
Define FullURL$
If FindString(TargetURL$, "?") > 0
; URL already has query string
FullURL$ = TargetURL$ + "&" + URLParams$
Else
; No query string, add one
FullURL$ = TargetURL$ + "?" + URLParams$
EndIf
; Display the URL in the output area using JavaScript
Define UpdateURLScript$
UpdateURLScript$ = "var urlOutput = document.getElementById('urlOutput'); if (urlOutput) { urlOutput.textContent = '" + ReplaceString(FullURL$, "'", "\'") + "'; }"
!eval(v_updateurlscript$)
; Set the state to indicate URL is generated and ready to submit
URLGenerated = 1
; Show confirmation alert
AlertMobile("URL generated! Tap Submit AGAIN to navigate, or Cancel to go back.")
EndSelect
EndProcedure
;{ Initialize Application
Procedure InitializeApp()
; Create the email validation regular expression
; Using [.] to match literal dot instead of \. escape
If Not CreateRegularExpression(#RegexEmail, "^.+@.+[.].+$")
Debug "Failed to create email regex: " + RegularExpressionError()
Else
Debug "Email regex created successfully"
EndIf
; Create the numeric validation regular expression
; Pattern matches positive integers only (no decimals, no negative numbers)
If Not CreateRegularExpression(#RegexNumeric, "^[0-9]+$")
Debug "Failed to create numeric regex: " + RegularExpressionError()
Else
Debug "Numeric regex created successfully"
EndIf
; Create the name validation regular expression
; Pattern: must start with a letter, can contain letters, spaces, hyphens, apostrophes
If Not CreateRegularExpression(#RegexName, "^[a-zA-Z][a-zA-Z\s\-']+$")
Debug "Failed to create name regex: " + RegularExpressionError()
Else
Debug "Name regex created successfully"
EndIf
; Debug: Test the email regex
Debug "Testing email 'tom@jones.com': " + MatchRegularExpression(#RegexEmail, "tom@jones.com")
Debug "Testing email 'invalid': " + MatchRegularExpression(#RegexEmail, "invalid")
Debug "Testing email 'test@test.com': " + MatchRegularExpression(#RegexEmail, "test@test.com")
; Create the dialogs first (hidden by default)
CreateJsonDialog()
CreateURLInputDialog()
; Create the main page
CreateMainPage()
; Bind mobile events
BindEvent(#PB_Event_Mobile, @MobileEvents())
EndProcedure
;}
; Start the application
InitializeApp()