Mobile UI form

Just starting out? Need help? Post your questions and find answers here.
Ken
Posts: 14
Joined: Sat Dec 19, 2015 6:28 pm

Mobile UI form

Post by Ken »

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.

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()
Fred
Site Admin
Posts: 1853
Joined: Mon Feb 24, 2014 10:51 am

Re: Mobile UI form

Post by Fred »

That's nice thanks for sharing !
Post Reply