type to select value from table/list

LiveCode is the premier environment for creating multi-platform solutions for all major operating systems - Windows, Mac OS X, Linux, the Web, Server environments and Mobile platforms. Brand new to LiveCode? Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller

Post Reply
billworld
Posts: 188
Joined: Sat Oct 25, 2008 12:32 am

type to select value from table/list

Post by billworld » Mon Nov 03, 2008 10:11 pm

IMO this should work by default, but, doesn't. Can it be coded in such that a user can type the lead characters of a value in a list and then be taken to that list item?

In the hundreds of computers apps. I've used I've never entered a multi-field list that I couldn't do this in, so, why it's not a default behavior in RR and why it's not present with all of the lists within the IDE is beyond me.

I'm hoping it can be coded around, but, as it's lacking in the IDE, I have to ask whether it's possible.

Thanks for any pointers.

Bill

Janschenkel
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 977
Joined: Sat Apr 08, 2006 7:47 am
Contact:

Post by Janschenkel » Tue Nov 04, 2008 6:41 am

Hi Bill,

At work I use both Java (for general-purpose development) and Progress (for database development) and neither 'list' fields there have it out-of-the-box.

The good thing is, with Revolution it's a breeze to add it yourself. Here's what I cooked up in about 5 minutes.

Code: Select all

local sBuffer

on focusIn
   put empty into sBuffer
end focusIn

on focusOut
   put empty into sBuffer
end focusOut

on keyUp pKey
   put pKey after sBuffer
   ScrollToBuffer
end keyUp

on backspaceKey
   delete char -1 of sBuffer
   ScrollToBuffer
end backspaceKey

on ScrollToBuffer
   put lineOffset(sBuffer, the text of me) into tLineOffset
   if tLineOffset is 0 then
      beep
      set the hilitedLine of me to empty
   else
      set the hilitedLine of me to tLineOffset
   end if
end ScrollToBuffer
Put the above script into your list field, and you should see it work. And you can always tweak it to your liking :-)

Best regards,

Jan Schenkel.
Quartam Reports & PDF Library for LiveCode
www.quartam.com

billworld
Posts: 188
Joined: Sat Oct 25, 2008 12:32 am

Post by billworld » Tue Nov 04, 2008 3:38 pm

Thanks for the effort, but, this doesn't really work, either basically or actually (e.g. as should be expected based on standard list field typed selection behavior in standard desktop applications).

For example. Put the following values in a list.

Code: Select all

Apple
Orange
Diamond
Gold
Platinum
Sugar
Salt
Demons
Angels
Now enter the field, select "Apple" then type "P". You don't get "Platinum". Oddly, if you do the same thing and type "S" you do go to the first "S" which is "Sugar". And, typing "sa" does take you to "Salt".

Further oddity is that selecting "Apple" then typing "G" takes you to "Orange" rather than "Gold".

Also, after a successful type-to event occurs (e.g. select "Apple", type "s" and go to "Sugar") you can't do it again while remaining in focus in the field. Whatever you type afterwards simply deselects everything. It appears you need to focus out of the field and re-focus into the field to re-initialize to do it again. As well, after a non-successful type-to event, the same thing occurs.

Would it take possibly another 5 mins to make this work as expected? :)

Just looking for controls which initially work as expected. The fact that all of this stuff in RR can be customized is really cool, however, it would be a heck of a lot easier for newbies to have the basic controls working as expected.

Thanks

Bill
Janschenkel wrote:
Put the above script into your list field, and you should see it work. And you can always tweak it to your liking :-)

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Post by bn » Tue Nov 04, 2008 9:32 pm

Hi Bill,
try this (based on Jan's script) with your apples, oranges and platinum

Code: Select all

local sBuffer, sMyText
on focusIn
    put the text of me into sMyText
    put empty into sBuffer 
    ScrollToBuffer 
end focusIn 

on focusOut
    put value (the selectedline of me)
    put empty into sBuffer 
end focusOut 

on keyUp pKey 
   put pKey after sBuffer 
   ScrollToBuffer 
end keyUp 

on backspaceKey 
   delete char -1 of sBuffer 
   ScrollToBuffer 
end backspaceKey 

on ScrollToBuffer
    put lineoffset(sBuffer, sMyText) into tLineOffset
    if sBuffer >"" then 
        repeat with i = 1 to the number of lines of sMyText
            if line i of sMyText begins with sBuffer then
                lock screen
                set the textstyle of line 1 to -1 of me to plain
                set the hilitedline of me to i
                set the textstyle of char 1 to (length (sBuffer)) of line i of me to box
                exit ScrollToBuffer
            end if
        end repeat
    end if
    set the textstyle of line 1 to -1 of me to plain
    select line 1 of me
    put empty into sBuffer
end ScrollToBuffer
change to your needs, that is half the fun and the power of revolution
cheers
bernd

billworld
Posts: 188
Joined: Sat Oct 25, 2008 12:32 am

Post by billworld » Tue Nov 04, 2008 10:15 pm

Thanks. This overcomes most of the problems. Although, there's still the issue that it requires one to lose focus and re-focus (if you will) in order to make another "type-to" selection after completing the first one. Just need list selection capabilities similar to what's offered default out-of-the-box in FileMaker Pro (and other apps) whereby you can continuously "type-to" select values in the list without exiting/re-entering the list. This helps if a user mis-types something and ends up in the right place as far as the computer is concern, but, really it's not the correct place. So, they need to be able to re-type without being forced to exit and re-enter the field.

I'm not good enough with this stuff yet to experience the fun of making the necessary tweaks (although I hope to someday!). :) Currently, I'm just trying to build a good UI which follows basic UI conventions most users expect. And, as I've already encountered some obstacles with the RR environment for this which cannot be worked around via custom coding, I'm now careful to make sure I understand the capabilities of each UI control before becoming too wedded to it. In this way, the UI design process is being effected by the capabilities (both pro and con) of the environment.

Anyway, if it's not asking too much for help on how to get this to overcome this last obstacle (e.g. able to make another new selection in the same list without having to re-focus) that would be most graciously appreciated.

Thanks

Bill
bn wrote:Hi Bill,
try this (based on Jan's script) with your apples, oranges and platinum

Code: Select all

local sBuffer, sMyText
on focusIn
    put the text of me into sMyText
    put empty into sBuffer 
    ScrollToBuffer 
end focusIn 

on focusOut
    put value (the selectedline of me)
    put empty into sBuffer 
end focusOut 

on keyUp pKey 
   put pKey after sBuffer 
   ScrollToBuffer 
end keyUp 

on backspaceKey 
   delete char -1 of sBuffer 
   ScrollToBuffer 
end backspaceKey 

on ScrollToBuffer
    put lineoffset(sBuffer, sMyText) into tLineOffset
    if sBuffer >"" then 
        repeat with i = 1 to the number of lines of sMyText
            if line i of sMyText begins with sBuffer then
                lock screen
                set the textstyle of line 1 to -1 of me to plain
                set the hilitedline of me to i
                set the textstyle of char 1 to (length (sBuffer)) of line i of me to box
                exit ScrollToBuffer
            end if
        end repeat
    end if
    set the textstyle of line 1 to -1 of me to plain
    select line 1 of me
    put empty into sBuffer
end ScrollToBuffer
change to your needs, that is half the fun and the power of revolution
cheers
bernd

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Post by bn » Wed Nov 05, 2008 12:27 am

Hi Bill,
I tried to make it as filemakersish as possible, they have a timeout after which a new entry is considered a new search, I built that in. Filemaker sorts the entries alphabetically, which is not done in your example. That makes for the selection of the last line if you type a "z" although there is no "z" in the entries. That could probably be done, is more work though.
The way the code is now 1 second after the last keyUp the buffer is cleared and the next letters you type start a new search/selection. I you mistype within the 1 second timeframe the first line is selected and no box around the found letters.
Adjust the 1 second interval in the script where marked for smaller/bigger intervall by decreasing/increasing 1000. Test a little for slow and fast typers.

Code: Select all

local sBuffer, sMyText, sTimer
on focusIn
    put the text of me into sMyText
    put empty into sBuffer 
    ScrollToBuffer 
end focusIn 

on focusOut
    -- do what you want with the selection when field loses focus
    put value (the selectedline of me)
    put empty into sBuffer 
end focusOut 

on keyUp pKey
    put the milliseconds into sTimer
    send "clearBuffer" to me in 1 milliseconds
    put pKey after sBuffer
    ScrollToBuffer 
end keyUp 

on backspaceKey 
   delete char -1 of sBuffer 
   ScrollToBuffer 
end backspaceKey 

on ScrollToBuffer
    put lineoffset(sBuffer, sMyText) into tLineOffset
    if sBuffer >"" then 
        repeat with i = 1 to the number of lines of sMyText
            if line i of sMyText begins with sBuffer then
                lock screen
                set the textstyle of line 1 to -1 of me to plain
                set the hilitedline of me to i
                -- block next line to get rid of the box
                set the textstyle of char 1 to (length (sBuffer)) of line i of me to box
                exit ScrollToBuffer
            end if
        end repeat
    end if
    set the textstyle of line 1 to -1 of me to plain
    select line 1 of me
    put empty into sBuffer	
end ScrollToBuffer

on clearBuffer
    -- adjust for typing speed
    -- after 1000 milliseconds the buffer is cleared and you can type for a new selection
    if the milliseconds - sTimer > 1000  then
        put "" into sBuffer
    else 
        send "clearBuffer" to me in 100 milliseconds
    end if
end clearBuffer
is it this what you mean? Maybe someone has a smarter solution, this is what I came up with.
regards
Bernd

billworld
Posts: 188
Joined: Sat Oct 25, 2008 12:32 am

Post by billworld » Wed Nov 05, 2008 3:40 am

Bravo. Good job. Thanks. BTW, in FMP you can have unsorted lists. Not sure what you mean by "a new entry is considered a new search." But, regardless, what you've provided here is the behavior users expect. Good to see this in RR!

Thanks again!
bn wrote:Hi Bill,
I tried to make it as filemakersish as possible, they have a timeout after which a new entry is considered a new search, I built that in. Filemaker sorts the entries alphabetically, which is not done in your example.

Janschenkel
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 977
Joined: Sat Apr 08, 2006 7:47 am
Contact:

Post by Janschenkel » Wed Nov 05, 2008 7:06 am

Hi Bill,

Of course my originbal script wasn't the penultimate solution - it was just a quick try while I was eating my breakfast cereal, meant as a starting point. One of the best bits about Revolution is how you can tweak every aspect of your application's user interface to your liking.

The key thing to remember is: Revolution is not FileMaker Pro - there will be more differences than just the language, the layouting options, etc. And like any programming language and development environment, it comes with a learning curve.

Luckily, the learning curve is not nearly as steep as Java or VB.NET but there will be challenging times where you'll need creativity and will have to cobble together a complete solution based on pointers by others that only offer partial solutions.

Anyway, just in the interest of completing my response, here's a tweaked version of my earlier script :-)

Code: Select all

constant kBUFFERLIFETIME = 2000  -- milliseconds

local sBuffer, sTimer

on focusOut 
   put empty into sBuffer 
end focusOut 

on keyUp pKey 
   put pKey after sBuffer 
   ScrollToBuffer 
end keyUp 

on backspaceKey 
   delete char -1 of sBuffer 
   ScrollToBuffer 
end backspaceKey 

on ScrollToBuffer 
   put the milliseconds into sTimer
   send "ClearBuffer" to me in kBUFFERLIFETIME milliseconds
   put the text of me into tText
   lock screen
   set the textStyle of char 1 to -1 of me to "plain"
   put 0 into tFirst
   if sBuffer is not empty then
      put 0 into tIndex
      repeat for each line tLine in tText
         add 1 to tIndex
         if tLine begins with sBuffer then
            set the textStyle of line tIndex of me to "bold"
            if tFirst is 0 then
               put tIndex into tFirst
            end if
         end if
      end repeat
   end if
   if tFirst is 0 then
      set the hilitedLine of me to empty
   else
      set the hilitedLine of me to tFirst
   end if
   unlock screen
end ScrollToBuffer

on ClearBuffer
   if the milliseconds - sTimer >= kBUFFERLIFETIME then
      put empty into sBuffer
      set the textStyle of char 1 to -1 of me to "plain"
   end if
end ClearBuffer
HTH,

Jan Schenkel.
Quartam Reports & PDF Library for LiveCode
www.quartam.com

bn
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 4172
Joined: Sun Jan 07, 2007 9:12 pm

Post by bn » Wed Nov 05, 2008 3:32 pm

Hi Jan,

I like your code, its less convoluted than mine. And thanks for the initial code, I learn a lot from playing around with these concepts.

Hi Bill,
glad you liked it.
I cooked up a version that is even more 'filemakerish' (I like that word although it probably does not exist). The list should be sorted for this to work nicely. Now when you type a letter that is not in the list it selects the line after the closest match on letter 1 of the entries. Say you have entries starting with A C M P and you type N then it will select the line that starts with P.
I always liked that in Filemaker. If you are not shure what the word is and you dont feel like scrolling the whole list type any letter and it gets you to the bottom of the list (Z) or the middle of the list (N).
I couldnt resist to try this out. Not extensively tested and based on my version of Jan's script, so a little less concise. Tweak as needed.

Code: Select all

local sBuffer, sMyText, sTimer, sTheLetters

on focusIn
    put the text of me into sMyText
    put "" into sTheLetters
    put 0 into tCounter
    repeat for each line aLine in sMyText
        add 1 to tCounter
        put char 1 of aLine & " " & tCounter & "," after sTheLetters
    end repeat
    delete last char of sTheLetters
    sort items of sTheLetters by char 1 of each 
    put empty into sBuffer 
    ScrollToBuffer 
end focusIn 

on focusOut
    -- do what you want with the selection when field loses focus
    put value (the selectedline of me)
    put empty into sBuffer 
end focusOut 

on keyUp pKey
    put the milliseconds into sTimer
    send "clearBuffer" to me in 1 milliseconds
    put pKey after sBuffer
    ScrollToBuffer 
end keyUp 

on backspaceKey 
   delete char -1 of sBuffer 
   ScrollToBuffer 
end backspaceKey 

on ScrollToBuffer
    put lineoffset(sBuffer, sMyText) into tLineOffset
    if sBuffer >"" then 
        lock screen
        repeat with i = 1 to the number of lines of sMyText
            if line i of sMyText begins with sBuffer then
                set the textstyle of line 1 to -1 of me to plain
                set the hilitedline of me to i
                -- block next line to get rid of the box
                set the textstyle of char 1 to (length (sBuffer)) of line i of me to box
                exit ScrollToBuffer
            end if
        end repeat
        -- if we get here there was not hit before
        -- compare the letters to find the closest letter and select the line after it
        put char 1 of sBuffer into tcompare
        repeat for each item anItem in sTheLetters
            -- breakpoint
            if tcompare > char 1 of anItem then select line word 2 of anItem + 1 of me
        end repeat
    end if
    set the textstyle of line 1 to -1 of me to plain
end ScrollToBuffer

on clearBuffer
    -- adjust for typing speed
    -- after 1000 milliseconds the buffer is cleared and you can type for a new selection
    if the milliseconds - sTimer > 1000  then
        put "" into sBuffer
    else 
        send "clearBuffer" to me in 100 milliseconds
    end if
end clearBuffer
regards
Bernd

billworld
Posts: 188
Joined: Sat Oct 25, 2008 12:32 am

Post by billworld » Wed Nov 05, 2008 4:05 pm

Thanks. This makes sense for lists which are sorted. Not all FileMaker lists are auto-sorted. For unsorted lists, FMP does NOT operate this way.

Regardless, thanks much to you and Jan for helping out here. Great to see the RR community so helpful!

Best,

Bill
bn wrote: I cooked up a version that is even more 'filemakerish' (I like that word although it probably does not exist). The list should be sorted for this to work nicely. Now when you type a letter that is not in the list it selects the line after the closest match on letter 1 of the entries. Say you have entries starting with A C M P and you type N then it will select the line that starts with P.
I always liked that in Filemaker.

asayd
Livecode Opensource Backer
Livecode Opensource Backer
Posts: 107
Joined: Mon Apr 10, 2006 7:02 pm
Contact:

type to select value from table/list

Post by asayd » Wed Nov 05, 2008 5:40 pm

I'm coming to the discussion late, but FWIW I created a type ahead search for an app a few months back. I wanted my solution to feel more like the type to select URL feature in Safari. If you're interested you can go to Rev Online and look for my user space, 'devin', and grab the Type Ahead Search stack.

HTH

Devin Asay
Devin Asay
Learn to code with LiveCode University
https://livecode.com/store/education/

Post Reply