Solved

Text/combo box with type-ahead for list of directories

Posted on 2014-01-14
13
753 Views
Last Modified: 2014-01-21
I need to create a vbscript or Powershell script to get input from a user.  I would normally just do a text/input box, but want to allow the user the option to pick an existing subdirectory OR manually type in a new one.  Reason for this is we don't want to have a misspelling and cause a duplication directory.  

So first up the program needs to read in a directory list, then interface with the text/combo box for type-ahead.  Drop-down could be utilized instead of type-ahead if it's easier.  Then allow the user to select the directory OR manually type in the box for a new directory.

Make sense?

Here's the problem - I have very limited knowledge of Powershell or VBS.  I KNOW them both, but have only done very basic scripting.

Doable?
0
Comment
Question by:dipersp
  • 7
  • 6
13 Comments
 
LVL 37

Expert Comment

by:Jamie McKillop
ID: 39782163
Hello,

Yes, this is possible. For an example of this, see my ActiveSync admin tool here:

http://jamiemckillop.wordpress.com/2013/05/30/activesync-power-administrator-2-0-exchange-2010-support/

When you start typing in the email address field, it will start providing suggestions based on a directory lookup. The important parts of the code are the following lines on the combo box:

$EmailAddress.autocompletesource = "customsource"
$EmailAddress.autocompletemode = "suggest"
$EmailAddress.add_textchanged({EmailAddress_textchanged})

Open in new window


That causes the combo box to use autocomplete from a custom source and to call a function as text is typed into the box.

The function (below) then does a wildcard directory lookup on the text that has been typed to find partial matches in the directory and add them as suggestions to the drop-down.

function EmailAddress_textchanged
{
if ($DisableDynamic.checked -eq $false) {
	$emaillist = @()
	Get-QADUser -SizeLimit 0 -LdapFilter "(Name=$($EmailAddress.text)*)" | % {
		if ($_.mail -ne $null) {
			$emaillist += $_.mail
		}
	}
	$EmailAddress.AutoCompleteCustomSource.AddRange($emaillist)
}
}

Open in new window


As you can see, what you are looking to do is beyond basic powershell. Hopefully, you can use my example to create what you want. Let me know if you have any questions.

-JJ
0
 
LVL 9

Author Comment

by:dipersp
ID: 39783517
OK, so. . . I've never done a form/gui with Powershell.  I downloaded the Primalforms and made a simple text box.  It generated all the code and I've adjusted/mirrored what you have.  

So the form pops up, I get the single text box, and I start to type in it.  But it never autofills anything in the text box.  Just lets me keep typing.  Thoughts?

Thoughts?  Full code below.

#Generated Form Function
function GenerateForm {
########################################################################
# Code Generated By: SAPIEN Technologies PrimalForms (Community Edition) v1.0.10.0
# Generated On: 1/14/2014 5:31 PM
# Generated By: PDP
########################################################################

#region Import the Assemblies
[reflection.assembly]::loadwithpartialname("System.Windows.Forms") | Out-Null
[reflection.assembly]::loadwithpartialname("System.Drawing") | Out-Null
#endregion

#region Generated Form Objects
$form1 = New-Object System.Windows.Forms.Form
$ClientNames = New-Object System.Windows.Forms.TextBox
$InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
#endregion Generated Form Objects

#----------------------------------------------
#Generated Event Script Blocks
#----------------------------------------------
#Provide Custom Code for events specified in PrimalForms.

function ClientNames_textchanged
{
$clientlist = @()
get-childitem -path "d:\" | where-object{($_.PSIsContainer)} | where-object{$_.name -like "*$ClientNames.txt*"} | % {
    $clientlist += $_.name
  }
$ClientNames.AutoCompleteCustomSource.AddRange($clientlist)
}




$OnLoadForm_StateCorrection=
{#Correct the initial state of the form to prevent the .Net maximized form issue
	$form1.WindowState = $InitialFormWindowState
}

#----------------------------------------------
#region Generated Form Code
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 262
$System_Drawing_Size.Width = 284
$form1.ClientSize = $System_Drawing_Size
$form1.DataBindings.DefaultDataSourceUpdateMode = 0
$form1.Name = "form1"
$form1.Text = "Primal Form"

$ClientNames.AutoCompleteMode = "suggest"
$ClientNames.AutoCompleteSource = "customsource"
$ClientNames.DataBindings.DefaultDataSourceUpdateMode = 0
$System_Drawing_Point = New-Object System.Drawing.Point
$System_Drawing_Point.X = 31
$System_Drawing_Point.Y = 60
$ClientNames.Location = $System_Drawing_Point
$ClientNames.Name = "ClientNames"
$System_Drawing_Size = New-Object System.Drawing.Size
$System_Drawing_Size.Height = 20
$System_Drawing_Size.Width = 100
$ClientNames.Size = $System_Drawing_Size
$ClientNames.TabIndex = 0
$ClientNames.add_TextChanged({ClientNames_textchanged})

$form1.Controls.Add($ClientNames)

#endregion Generated Form Code

#Save the initial state of the form
$InitialFormWindowState = $form1.WindowState
#Init the OnLoad event to correct the initial state of the form
$form1.add_Load($OnLoadForm_StateCorrection)
#Show the Form
$form1.ShowDialog()| Out-Null

} #End Function

#Call the Function
GenerateForm

Open in new window

0
 
LVL 37

Expert Comment

by:Jamie McKillop
ID: 39783559
Add this block of code to the top of your script:

if ([threading.thread]::CurrentThread.GetApartmentState() -eq "MTA") {
   & $env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell.exe -sta $MyInvocation.ScriptName
   Exit
}

Open in new window


The script may exist right away after running it in the powershell windows. If that happens, just run it again without closing the powershell window.

-JJ
0
 
LVL 9

Author Comment

by:dipersp
ID: 39783641
No change.  It did exit just like you said and I ran it again.

As I'm typing in the textbox, it ever so slightly flashes (The textbox), so it's almost like it's doing something. . .
0
 
LVL 37

Expert Comment

by:Jamie McKillop
ID: 39783659
In this line: where-object{$_.name -like "*$ClientNames.txt*"}

.txt should be .text

-JJ
0
 
LVL 9

Author Comment

by:dipersp
ID: 39783718
Duh.  But still no dice.
0
Problems using Powershell and Active Directory?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 37

Expert Comment

by:Jamie McKillop
ID: 39785240
I would test your function to see is it works by itself. Manually set the $ClientNames.text variable and pass it to the function then have it output $clientlist and make sure you get what you expect.

-JJ
0
 
LVL 9

Author Comment

by:dipersp
ID: 39785280
Yes, did that first.  It does work when I manually run it at the Powershell prompt.
0
 
LVL 37

Accepted Solution

by:
Jamie McKillop earned 500 total points
ID: 39785321
OK, I see the issue.

Change: where-object{$_.name -like "*$ClientNames.text*"}

to: where-object{$_.name -like "*$($ClientNames.text)*"}

-JJ
0
 
LVL 9

Author Comment

by:dipersp
ID: 39785342
You da man!  

OK - now can you explain that last change/fix to me?

Also, what does the following block do?  I always have to start the file twice now to actually use it.

if ([threading.thread]::CurrentThread.GetApartmentState() -eq "MTA") {
   & $env:SystemRoot\system32\WindowsPowerShell\v1.0\powershell.exe -sta $MyInvocation.ScriptName
   Exit
}

Open in new window

0
 
LVL 37

Expert Comment

by:Jamie McKillop
ID: 39785369
When you place a variable inside quotes, you sometime need to put the variable in the format $($variable) in order to escape it otherwise the code interprets your variable as a literal string.

This post explains that block of code:

http://thepip3r.blogspot.ca/2011/06/powershell-gui-errors-referencing-sta.html

-JJ
0
 
LVL 9

Author Closing Comment

by:dipersp
ID: 39785382
OK, think it all makes sense.  So if I invoke PS in STA on the command line, I should be good. . .  Anyway, thanks a lot!  I may have other questions for you at some point!
0
 
LVL 9

Author Comment

by:dipersp
ID: 39797287
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Microsoft Windows Server Update Service (WSUS) is free for everyone, but it lacks of some desirable features like send an e-mail to the administrator with the status of all computers on the WSUS server. This article is based on my PowerShell script …
Synchronize a new Active Directory domain with an existing Office 365 tenant
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …
Delivering innovative fully-managed cloud services for mission-critical applications requires expertise in multiple areas plus vision and commitment. Meet a few of the people behind the quality services of Concerto.

932 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now