0

As in the title above I need some help for a good "feedback" on an user input...

Like if he is typing 4 things into an input window and one of those things should only consist of numbers, the second one shouldn't be null and much more...

Like the 4 input fields are:

  • ParID (should only be numbers and I need the user to enter exactly 6
  • Research Group (3 Letters using a dropdown and those should only be letters)
  • Customer (letters, numbers everything allowed but I shouldn't be empty!)
  • Projectname (same like customer input)

The problem is that my code doesn't work because it keeps telling me the same feedback for example:

Input:"123456" Error: "Is not a number"

My Code:

    $error_message = "Please fill out all of the form fields correctly!`n" #text which will be displayed
    $error_sign = "Exclamation" #sign veriable -> for a specific sign (picture) which will be displayed 

    if( #the program is going trough all the different types of wrong inputs that could happen and throws an error message!
      ($ParIDInbox.Text.Length -lt 1) -and
      ($ResearchGroupInbox.Text.Length -lt 1) -and
      ($CustomerInbox.Text.Length -lt 1) -and
      ($ProjectnameInbox.Text.Length -lt 1)) {
       $error_output = "All fields must be filled out!"
    } else {
        Write-Host -f Green "Everything seems right!"
    }

    #if($ParIDInbox.Text.Length
    if([string]::IsNullOrEmpty($ParID)) {
        $error_output = "ParID must be filled out!"
    } else {  
        if(($ParID -gt 0) -and ($ParID -lt 6)) { 
            $error_output = "ParID is too short!"
        } else {  
            $Sort = [int[]][char[]]$ParID #sorts the input ParID into an int and a char array
                foreach($Value in $ParID) { #goes trough every letter and checks if the ASCII Code for 0-9 is correct!
                     if (!(($Value -ge 48) -and ($Value -le 57))) {
                        $error_output = "ParID is not a number!"
                     } else {
                        #nothing else matters ...
                     }
                }
            }
        }       
    }     
    $error_message = $error_message + "$($error_output)"

    [System.Windows.Forms.MessageBox]::Show($error_message, "Warning", #messagebox text -> text which will be displayed in the error message box
    [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::$error_sign) #picture -> picture that will be shown in the window ($error_sign)!
    $error_output = ""

EDIT: WIndow Code

$objForm = New-Object System.Windows.Forms.Form #init -> initializing window form
$objForm.Text = "Input Window v0.5" #name -> the name which will be display in the top border of the window
$objForm.Size = New-Object System.Drawing.Size(300,290) #size -> set the size of the window
$objForm.StartPosition = "CenterScreen" #location -> where the window will appear on the screen
$objForm.FormBorderStyle = 'Fixed3D' #sizing -> fixes the size of the window so you cannot make it bigger       
$OKButton = New-Object System.Windows.Forms.Button #initialization -> initializes the button
$OKButton.Location = New-Object System.Drawing.Size(75,190) #Location -> where the button is located in the window
$OKButton.Size = New-Object System.Drawing.Size(75,23) #Size -> defines the size of the button
$OKButton.Text = "OK" #value -> sets the value of the button to 'OK'
$objForm.Controls.Add($OKButton) #adding -> adds the button to the window
$OKButton.Add_Click($OKButton_OnClick)   
$CancelButton = New-Object System.Windows.Forms.Button #initialization -> initializes the button
$CancelButton.Location = New-Object System.Drawing.Size(150,190) #Location -> where the button is located in the window 
$CancelButton.Size = New-Object System.Drawing.Size(75,23) #Size -> defines the size of the button
$CancelButton.Text = "Cancel" #value -> sets the value of the button to 'Cancel'
$CancelButton.Add_Click($CancelButton_Onclick) #closing -> closes the window after clicked
$objForm.Controls.Add($CancelButton) #adding -> adds the button to the window         
$Info_Label = New-Object System.Windows.Forms.Label #initialization -> initializes the label
$Info_Label.Location = New-Object System.Drawing.Size(10,220) #Location -> where the label is located in the window
$Info_Label.Size = New-Object System.Drawing.Size(280,50) #Size -> defines the size of the label
$Info_Label.Text = "If a browser window does not open up in 30 seconds please restart this script program!" #Info Text
$objForm.Controls.Add($Info_Label) #adding -> adds the label to the window    $ParIDLabel = New-Object System.Windows.Forms.Label #initialization -> initializes the label      
$ParIDLabel.Location = New-Object System.Drawing.Size(10,10) #Location -> where the label is located in the window     
$ParIDLabel.Size = New-Object System.Drawing.Size(280,20) #Size -> defines the size of the label
$ParIDLabel.Text = "Par ID (6 numbers!)" #value -> sets the value of the Label to 'Par ID (6 numbers)'
$objForm.Controls.Add($ParIDLabel) #adding -> adds the label to the window        $ParIDInbox = New-Object System.Windows.Forms.TextBox #initialization -> initializes the input box
$ParIDInbox.Location = New-Object System.Drawing.Size(10,30) #Location -> where the label is located in the window
$ParIDInbox.Size = New-Object System.Drawing.Size(260,20) #Size -> defines the size of the inputbox
$ParIDInbox.MaxLength = 6 #sets max. length of the input box to 6 
$objForm.Controls.Add($ParIDInbox) #adding -> adds the input box to the window
$ResearchGroupLabel = New-Object System.Windows.Forms.Label #initialization -> initializes the label
$ResearchGroupLabel.Location = New-Object System.Drawing.Size(10,55)     $ResearchGroupLabel.Size = New-Object System.Drawing.Size(280,20) #Size -> defines the size of the label
$ResearchGroupLabel.Text = "Research Group (3 letters!)" #value -> sets the value of the Label to 'Research Group (3 letters!)'
$objForm.Controls.Add($ResearchGroupLabel) #adding -> adds the label to the window
$ResearchGroupInbox = New-Object System.Windows.Forms.ComboBox #initialization -> initializes the combobox (dropdown)
$ResearchGroupInbox.Location = New-Object System.Drawing.Size(10, 75) 
$ResearchGroupInbox.Size = New-Object System.Drawing.Size(130,28) #Size -> defines the size of the box
$ResearchGroupInbox.MaxLength = 3 #sets max. length of the input box to 3
ForEach ($Item in $ResearchGroupShortcuts) { #loop -> put all variables from '$DropDownArray' into '$Item'
    $ResearchGroupInbox.Items.Add($Item) #adder -> add '$Item' to the dropdown
}
$objForm.Controls.Add($ResearchGroupInbox) #adding -> add the dropdown to the window
$CustomerLabel = New-Object System.Windows.Forms.Label #initialization -> initializes the label
$CustomerLabel.Location = New-Object System.Drawing.Size(10,100) #Location -> where the label is located in the window
$CustomerLabel.Size = New-Object System.Drawing.Size(280,20) #Size -> defines the size of the label
$CustomerLabel.Text = "Customer:" #value -> sets the value of the Label to 'Customer'
$objForm.Controls.Add($CustomerLabel) #adding -> adds the label to the window

$CustomerInbox = New-Object System.Windows.Forms.TextBox #initialization -> initializes the input box
$CustomerInbox.Location = New-Object System.Drawing.Size(10,120) #Location -> where the label is located in the window
$CustomerInbox.Size = New-Object System.Drawing.Size(260,20) #Size -> defines the size of the inputbox
$CustomerInbox.MaxLength = 50 #sets max. length of the input box to 50 
$objForm.Controls.Add($CustomerInbox) #adding -> adds the input box to the window    
$ProjectnameLabel = New-Object System.Windows.Forms.Label #initialization -> initializes the label
$ProjectnameLabel.Location = New-Object System.Drawing.Size(10,140)     $ProjectnameLabel.Size = New-Object System.Drawing.Size(280,20) #Size -> defines the size of the label
$ProjectnameLabel.Text = "Projectname:"  #value -> sets the value of the Label to 'Projectname'
$objForm.Controls.Add($ProjectnameLabel) #adding -> adds the label to the window
$ProjectnameInbox = New-Object System.Windows.Forms.TextBox #initialization -> initializes the input box
$ProjectnameInbox.Location = New-Object System.Drawing.Size(10,160)     $ProjectnameInbox.Size = New-Object System.Drawing.Size(260,20) #Size -> defines the size of the inputbox 
$ProjectnameInbox.MaxLength = 50 #sets max. length of the input box to 50 
$objForm.Controls.Add($ProjectnameInbox) #adding -> adds the input box to the window 
$objForm.Topmost = $True #topmost -> A topmost form is a form that overlaps all the other (non-topmost!) forms!

$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
Mister X CT
  • 163
  • 1
  • 11
  • Why not use a regex to validate the input? For example, `^\d{6}$` would match exactly six digits. – vonPryz Jul 21 '16 at 06:42
  • would be an idea but the problem is still here because my error outputs are shot out randomly (at least it seems like they are random). I don't know what is wrong with my code ^^ – Mister X CT Jul 21 '16 at 06:52
  • And I don't really know how to use regex because I am very new to powershell ^^ – Mister X CT Jul 21 '16 at 06:59
  • In order to debug the logic, [create a MVCE](http://stackoverflow.com/help/mcve). As of now, the code isn't working as such as it assumes Winforms and stuff. – vonPryz Jul 21 '16 at 07:04
  • **BTW** It throws me an error that '^\d' is not recognized as the name of cmdlet... – Mister X CT Jul 21 '16 at 07:04
  • If you wanna have to the window I can drop my full code here – Mister X CT Jul 21 '16 at 07:05

1 Answers1

1

As far as I remember your form from previous questions, I can suggest you adding TextChanged event to ypour $ParIDInbox like that:

#ParID Input Box -> Input box for the Par ID input
$ParIDInbox = New-Object System.Windows.Forms.TextBox #initialization -> initializes the input box
$ParIDInbox.Location = New-Object System.Drawing.Size(10,30) #Location -> where the label is located in the window
$ParIDInbox.Size = New-Object System.Drawing.Size(60,20) #Size -> defines the size of the inputbox
$ParIDInbox.MaxLength = 6

$ParIDInbox_OnTextEnter = {
    if ($ParIDInbox.Text -notmatch '^\d{1,6}$') {
        $ParIDInbox.Text = $ParIDInbox.Text -replace '\D'
    }
}

$ParIDInbox.add_TextChanged($ParIDInbox_OnTextEnter)
$objForm.Controls.Add($ParIDInbox)

This code removes any entered symbol except digit and has ParIDInbox MaxLength parameter set to 6. Thus you only need to check minimum length on your OK button click. I usually check each field independently instead of all in one if statement - it helps me to debug where exatly the error is thrown:

if ($ParIDInbox.Text.Length -lt 6) { # or whatever length is ok
   Show-MessageBox -Type Error -Message "Par ID field should contain 6 digits!"
}
elseif ($NextInputBox.Text ...) { ... }# etc
else {
    # Your OK button actions here
}

And there's Show-MessageBox function that should be defined at the start of the code:

function Show-MessageBox {
    param(
        [parameter(Mandatory=$true)]
        [string]$Message,
        [Validateset('Error', 'Warning', 'Information')]
        [string]$Type = 'Information'
    )

    [System.Windows.Forms.MessageBox]::Show($Message, $Type, `
        [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::$Type) 
}
n01d
  • 1,047
  • 8
  • 22
  • Thanks man (again ^^) and how do I have to change the (OnTextChange) method so I can only enter letters (for another field)? or for example filter for special signs like $% (because many of them are not permitted in a filename! – Mister X CT Jul 21 '16 at 07:28
  • @MisterXCT Letters would be `-match [a-zA-Z]`. If you also need any special symbols you should treat them with care according to regex rules. Symbols like `^[{(\|$?<>.*+` should be escaped with \. I can help you with regex pattern if you provide the exact criteria but it would be better if you read a little about regex youself - it is very useful thing, not only for powershell: http://www.regular-expressions.info/quickstart.html And there's nice regex cheatsheet here: https://www.cheatography.com/davechild/cheat-sheets/regular-expressions/ – n01d Jul 21 '16 at 07:39
  • Thanks and the special symbols I mean are: ~ " # % & * : < > ? / \ { | }. – Mister X CT Jul 21 '16 at 07:43
  • Okay I have read trough this but at the moment I do not know what the regex expression for those symbols above is – Mister X CT Jul 21 '16 at 07:57
  • If we are talking about filenames, there's a good regex pattern: http://stackoverflow.com/questions/6768779/test-filename-with-regular-expression Based on this topic your code should be: `if ($TextBox.Text -notmatch '^[\w,\s-]+\.[A-Za-z]{3}$') {...}`. – n01d Jul 21 '16 at 08:04
  • thanks everything works perfect (except that this regex pattern does not inclide $ and § on my keyboard – Mister X CT Jul 21 '16 at 09:27
  • @MisterXCT I've changed OnTextEnter function a bit to be more precise on killing non-digit characters. Previous variant killed only last non-digit chars. Now it kills any non-digit char. – n01d Jul 21 '16 at 10:23
  • Thanks man that worked without any problems and sorry for my late answer I was away – Mister X CT Jul 22 '16 at 07:04
  • ahm maybe you can help me again because I got the problem now that I want to search for **only** the following characters: `~ " # % & * : < > ? / \ { | }` and I tried it with your regex sheet but all I have mad is just some small code that doesn't work at all ^^ – Mister X CT Jul 25 '16 at 09:12
  • @MisterXCT Hi again! :) To search for theese symbols you need something like this: `-match '~|"|#|%|&|\*|:|\<|\>|\?|\\|/|\{|\||}'`. – n01d Jul 25 '16 at 12:39