Connecting one text field to another
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
Connecting one text field to another
How do I connect one text field to another so that a text entry in Field 1 produces a certain text output in Field 2? My information is currently contained in a lengthy two column word processor table. What I'd like is for the app to be able to match up the two columns along each row. That is, if the user types the information that matches that in column 1 in Field 1 for a certain row, then the text located in column 2 of the table for that row would appear in Field 2. I also obviously need a way to reference the information currently in my text table.
For example, suppose this were the information:
Apple...Fruit
Carrot...Vegetable
Ant...Insect
So, if the user typed "Apple" in Field 1, then Fruit would appear in Field 2.
Hope this all makes sense!
Thanks!
For example, suppose this were the information:
Apple...Fruit
Carrot...Vegetable
Ant...Insect
So, if the user typed "Apple" in Field 1, then Fruit would appear in Field 2.
Hope this all makes sense!
Thanks!
Re: Connecting one text field to another
Look at lineoffset() (could be done with wordoffset too)
If you have yoru sample data in field 1 (tab delimited)
field 2 is where the user can type
and field 3 is where matching data should appear, something like the following might work for you.
There are probably other ways to handle this, but it should work ok. If you have a HUGE number of lines to deal with, a faster method might be in order though. (this one is pretty fast, but as the number of lines in field 2 and 3 grow, there could be slowdowns.. again if the number of lines is HUGE)
EDIT: Forgot to say, I placed the script into field 2 since that is where the typing will occur in my sample.
If you have yoru sample data in field 1 (tab delimited)
field 2 is where the user can type
and field 3 is where matching data should appear, something like the following might work for you.
Code: Select all
on textchanged
lock screen
-- tData contains a table (tab delimted) with the information pairs
-- place the data into a variable so its faster
-- field 1 has my sample data, field 2 is the location I can type, field 3 contains the matchnt output.
put field 1 into tData
set the itemdelimiter to tab -- set the item delimiter
put 1 into tCount -- manually keep track of the current line number so that "for each" can be used
repeat for each line tLine in field 2 -- the field that is being added to. Cycle through it.
-- check for a match with lineoffset. If there is a match, returns the line num
-- I used tab as part of the match string as a way to force only full matches
-- could have used wordoffset() and "set the wholematches to true" but this was easier
put lineoffset((tLine & tab),tData) into tLineNo
--if tLineNo is greater than 0 then there was a match
if tLineNo is not 0 then
-- use tcount to know where to place the matching data in field 2
-- use tLineNo to grab the correct part of the data from tData
-- and place the info into a variable
put item 2 of line tLineNo of tdata into line tCount of tMatchdata
end if
-- increment the line counter
add 1 to tCount
end repeat
-- place the finalized dta into field 3
put tMatchData into field 3
unlock screen
end textchanged
EDIT: Forgot to say, I placed the script into field 2 since that is where the typing will occur in my sample.
-
- VIP Livecode Opensource Backer
- Posts: 3901
- Joined: Sat Mar 24, 2007 2:54 am
- Location: Palo Alto
Re: Connecting one text field to another
For the exercise I did it with muti-dimensional array.
I have 2 fields, Fruit and Veg, in each one is the names of various fruits or veg.
Fill up the array:
Then to sort through it a Search field and Result field:
Not sure if this is the best way or even if I am using a muti-dimensional array correctly but it works.
I guess offset was easier, but I got practice
Simon
I have 2 fields, Fruit and Veg, in each one is the names of various fruits or veg.
Fill up the array:
Code: Select all
global tMultiArray
on mouseUp
put "" into tMultiArray
repeat for each line tLine in fld "Fruit" --each line contains a different fruit
add 1 to x
put tLine into tMultiArray[Fruit][x]
end repeat
put "" into x
repeat for each line tLine in fld "Veg" --each line contains a different vegtable
add 1 to x
put tLine into tMultiArray[Veg][x]
end repeat
end mouseUp
Code: Select all
global tMultiArray
on returnInField
put false into tFound --what if the seach word is not in the to fields?
put fld "Search" into tSearch
repeat for each line tKey in the keys of tMultiArray
repeat for each element tContent in tMultiArray[tKey]
if tSearch = tContent then
put tKey into fld "Result"
put true into tFound
exit repeat
end if
end repeat
if tFound then exit repeat
end repeat
if not tFound then put "Item not found" into fld "Result"
end returnInField
I guess offset was easier, but I got practice
Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!
Re: Connecting one text field to another
Where do I locate my data table?
Re: Connecting one text field to another
If it were me, I'd use the array too.
Could probably use "split" to make the array from the existing data, but would probably adjust how the key was found.
Since it sounds like the user is looking to match multiple lines of text in 1 field with the matching pair in the other, i'd repeat through the field with the text to match, and assuming the array key is the text (apple, contents = fruit) you might be able to simply check for empty. Something like this pseudocode. it would require a diff array structure than your example though.
It might also be worthwhile to have 2 arrays for dual direction conversion.
One with
array[fruit] where it contains lines listing all fruit
and array[apple] which has "fruit"
Of course even better would be an sqlite database with the pairs. Loop through and select, that way either direction can be done. Select all fruit, or select apple to get its type.
Tons of ways to skin this cat.
Could probably use "split" to make the array from the existing data, but would probably adjust how the key was found.
Since it sounds like the user is looking to match multiple lines of text in 1 field with the matching pair in the other, i'd repeat through the field with the text to match, and assuming the array key is the text (apple, contents = fruit) you might be able to simply check for empty. Something like this pseudocode. it would require a diff array structure than your example though.
Code: Select all
put 1 into tCount
repeat for each line tLine in dataToLookFor
if myArray[tLine] is not empty then
-- put the information into the correct line for use in the matching output field.
end if
add 1 tCount
end repeat
One with
array[fruit] where it contains lines listing all fruit
and array[apple] which has "fruit"
Of course even better would be an sqlite database with the pairs. Loop through and select, that way either direction can be done. Select all fruit, or select apple to get its type.
Tons of ways to skin this cat.
-
- VIP Livecode Opensource Backer
- Posts: 9663
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Connecting one text field to another
I would have made a field that tracks its own contents using keydown messages. This can check the contents of the current entry on the fly, and if that entry ever matches a whole word in a line in the first column of your data, then it would send the associated word to your output field.
I made a card with three fields. One is called "output", one is named "theData". In my simple test, field "theData contained a few lines of text, each line containing two words separated by a space.The last field contains this script:
When you type into this field, as soon as you complete a word that is in your list, the associated word appears in the "output" field.
You need to set up your own delimiters, and there are probably other little features and caveats, but this should work.
Craig Newman
I made a card with three fields. One is called "output", one is named "theData". In my simple test, field "theData contained a few lines of text, each line containing two words separated by a space.The last field contains this script:
Code: Select all
local tData
on mouseenter
put fld "theData" into tData
end mouseenter
on keydown var
put var after me
if me is among the words of tData then
get lineOffset(me,tData)
put word 2 of line it of tData into fld "output"
end if
end keydown
You need to set up your own delimiters, and there are probably other little features and caveats, but this should work.
Craig Newman
Re: Connecting one text field to another
You could use a hidden table field. (or a visible one, hard to know what your end goal is)ICCS_User wrote:Where do I locate my data table?
You could store the data as a property.
You could create an array as simon did.
You could create the array and then store the array in a property.
You could use a database. (sqlite works well and is fast)
Once its set up, the database would be pretty great but there is some initial learning curve involved in that. Very useful to know of course so it might be worthwhile. Same with arrays. If you haven't dealt with them before you'll have to learn to get your head around some stuff.
Using regular fields (like table fields) is pretty easy but you'll need to understand some things about chunking, like how items, words, lines, chars work in lc, etc.
There is also the datagrid, but if anything it has a harsher learning curve (powerful but can get confusing really fast)
If you decide to go the direction of databases, first I'd get a handle on how things work with straight LC, then once you get proficient, you might consider Andres dblib http://www.andregarzia.com/page/dblib Its payware, but is very good. If you are looking for a more complex (but powerful) solution, sqlYoga is also really well done. I have never really gotten the hang of sqlyoga, but others swear by it. For me dbLib is a better solution. Either is great. Neither is required of course, you can do your own thing with just native lc.
Also just saw the Craig example. Does pretty much the same thing as mine, but is much more concise. Since i'm not positive you are creating a list of matching pairs, or just doing a single search, the Craig method (tm) may be the way to go. Otherwise you will still need loops to process and match up line for line.
Re: Connecting one text field to another
Thank you everyone! You guys are amazing! Very helpful stuff that will help me get on the right track.
Re: Connecting one text field to another
How do I insure that when a match is being made, it does so for the whole word, not just part. That is, if my list contains both "cheeseburger" and "cheese," and the user types in "cheese" the result is the match for cheese and not cheeseburger.
Re: Connecting one text field to another
Using craigs script as an example, you can adjust slightly so that it uses wordoffset rather than lineoffset, set the wholematches to true, and then get the lineindex of that word.
Here is the original script:
Here is an adjusted, untested version
Here is the original script:
Code: Select all
local tData
on mouseenter
put fld "theData" into tData
end mouseenter
on keydown var
put var after me
if me is among the words of tData then
get lineOffset(me,tData)
put word 2 of line it of tData into fld "output"
end if
end keydown
Code: Select all
on textchanged
if word 1 of me is among the words of field 1 then
set the wholematches to true -- force whole word match
-- since lineindex only works with field references, am not using tData
get the lineindex of word (wordOffset(me,field 1)) of field 1
-- it now contains the line number of the correct line with the full word match
put word 2 of line it of field 1 into fld 3 -- grab the word
else
put empty into field 3
end if
end textchanged
-
- VIP Livecode Opensource Backer
- Posts: 3901
- Joined: Sat Mar 24, 2007 2:54 am
- Location: Palo Alto
Re: Connecting one text field to another
Hi ICCS,
Just to make sure you can use craig's script, your data should be in this format in fld theData:
Apple Fruit
Banana Fruit
Bandana Clothing
Tomato Vegetable
(Name space Group) look up the "word" keyword
This might be overkill but I thought I'd add it.
Simon
Just to make sure you can use craig's script, your data should be in this format in fld theData:
Apple Fruit
Banana Fruit
Bandana Clothing
Tomato Vegetable
(Name space Group) look up the "word" keyword
This might be overkill but I thought I'd add it.
Simon
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!
Re: Connecting one text field to another
This latest change works great! Again, thank you!Simon wrote:Hi ICCS,
Just to make sure you can use craig's script, your data should be in this format in fld theData:
Apple Fruit
Banana Fruit
Bandana Clothing
Tomato Vegetable
(Name space Group) look up the "word" keyword
This might be overkill but I thought I'd add it.
Simon
One more tweak and I think we'll have it all. Suppose,using your example, the data looks like this:
Apple Fruit
Banana Fruit
Banana Yellow
Banana Peel
Bandana Clothing
Tomato Vegetable
How would I get the output to include all the characteristics associated with Banana. That is, Fruit, Yellow, Peel would all appear in the output field, each on a separate line.
Re: Connecting one text field to another
You've now turned the corner to a different problem. To accomplish your task you should probably look at filter.
This is untested, but something like:
At this point though it might be worth it to consider a database solution.
This is untested, but something like:
Code: Select all
local tData
on mouseenter
put fld "theData" into tData
end mouseenter
on keydown var
put var after me
put empty into field "output"
if me is among the words of tData then
put tData into tTemp -- put the data into a temp var
filter tTemp with (me & space & "*") -- filter lines that don't start with your keyword
repeat for each line tline in tTemp -- loop and place the remaining lines into the output field.
put word 2 of tLine & cr after field "output"
end repeat
delete the last char of field "output"
end if
end keydown
-
- VIP Livecode Opensource Backer
- Posts: 3901
- Joined: Sat Mar 24, 2007 2:54 am
- Location: Palo Alto
Re: Connecting one text field to another
Hi ICCS,
You almost made me tear my hair out
So I'll ask now. Will you want to also do the reverse? Type in "Peel" and get "Banana, Orange, Lemon"?
Well anyways:
This is not as slick as Craig's script.
Simon EDIT: sturgis beat me to it
EDIT2: changed code
You almost made me tear my hair out
So I'll ask now. Will you want to also do the reverse? Type in "Peel" and get "Banana, Orange, Lemon"?
Well anyways:
Code: Select all
on returnInField
put "" into fld "output
put me into tSearch
put fld theData into tData
filter tData with tSearch
if tData <> empty then
repeat for each line tLine in tData
put word 2 of tLine & comma & space after fld "output"
end repeat
else
put "Item not found" into fld "output"
end if
end returnInField
Simon EDIT: sturgis beat me to it
EDIT2: changed code
Last edited by Simon on Mon Dec 31, 2012 9:53 pm, edited 3 times in total.
I used to be a newbie but then I learned how to spell teh correctly and now I'm a noob!
-
- VIP Livecode Opensource Backer
- Posts: 9663
- Joined: Wed May 06, 2009 2:28 pm
- Location: New York, NY
Re: Connecting one text field to another
Hi.
Now you really must look at arrays. But, doing it the old-fashioned way...
I like Sturgis' use of "textChanged" instead of "keyDown", though both work just fine. Long ago, and I mean long ago, I wrote a simple function to find multiple instances of words in text. The function is based on Rinaldi's "fullFind" ( a HC external). Anyway, it will yield a return delimited list of integers, where the first value is the line number of a found word, and the second is the word number within that line (which you do not need). In your example, what this gives you is:
2,1
3,1
4,1
So you can now place this in the entry field script:
And the function is:
Are you OK with the somewhat condensed line in the repeat loop? It could be broken into several statements, but try to parse it out.
Again, you have to manage your own delimiters. As many have said, my examples were written with pairs of words in each line, that is, a word, a space, and another word. This was just to play with the example. Your text may be set up differently.
Now you really must look at arrays. But, doing it the old-fashioned way...
I like Sturgis' use of "textChanged" instead of "keyDown", though both work just fine. Long ago, and I mean long ago, I wrote a simple function to find multiple instances of words in text. The function is based on Rinaldi's "fullFind" ( a HC external). Anyway, it will yield a return delimited list of integers, where the first value is the line number of a found word, and the second is the word number within that line (which you do not need). In your example, what this gives you is:
2,1
3,1
4,1
So you can now place this in the entry field script:
Code: Select all
local tData
on mouseenter
put fld "theData" into tData
end mouseenter
on textchanged
if word 1 of me is among the words of fld "theData" then
set the wholematches to true -- force whole word match
get revFullFind(tData,me,"false")
repeat for each line tLine in it
put word 2 of line item 1 of tLine of tData & space after temp
end repeat
put me & ":" & temp into fld "output"
else
put empty into field "output"
end if
end textchanged
Code: Select all
function revFullFind tText,tFind,exactly --RETURNS LINE NUMBER & "," & WORD NUMBER ("EXACTLY " MEANS THE WORD = LINE OR IS MERELY WITHIN THE LINE
put 0 into counter
switch exactly
case "true"
case empty
repeat for each line tline in tText
add 1 to counter
if tFind = tline then
put counter & return after tResult
end if
end repeat
break
case "false"
repeat for each line tline in tText
add 1 to counter
if tFind is in tline then
repeat with y = 1 to the number of words in tLine
if word y of tLine = tFind then put y & "," after temp
end repeat
delete last char of temp
put counter & "," & temp & return after tResult
put "" into temp
end if
end repeat
break
end switch
return tResult
end revFullFind
Again, you have to manage your own delimiters. As many have said, my examples were written with pairs of words in each line, that is, a word, a space, and another word. This was just to play with the example. Your text may be set up differently.