Message Boards Message Boards

Avoid Conditional to crash dynamic event handler and question about Length?

Posted 6 years ago

I'm reverse engineering an autosuggest/autocomplete field for my inputfield. It would be cool to have the enter key fill in the suggested word then the user presses enter again to continue through the program. ...at least that's my goal... My main problem is that I need to have InputField, ContinuousAction->True to catch all the letter suggestions. Now I have the "ReturnKeyDown" set up to fill in text with rest. I'm thinking from there I thought I could put in a conditional to control what "ReturnKeyDown" does, so that when you press enter when a valid word is entered it continues onto nextstep.

If[text == select,{"ReturnKeyDown":>(nextstep)},{"ReturnKeyDown" :> (text = text ~~ rest)}]

What I didn't count on was the conditional nearly crashes wolfram desktop. My dynamicmodule runs so slowly! :'( I isolated the problem to the conditional, but I don't know why it's lagging my program all to heck or how to work around it.

First question is: Is there a way to control what ReturnKeyDown does dynamically? Is it that I'm calling text==select in the If conditional? Is there an alternative solution that I'm not seeing?

In the program below most of the "string: " Dynamic[x_] are debugging information

DynamicModule[
 {text = "", select, commands, auto, rest, nextstep},
 EventHandler[
  Column[{
    Overlay[
     {Dynamic@Framed[
        Row[{Style[text, Transparent, 75, Bold],Style[rest, GrayLevel@.6, 75, Bold]}],
        ImageSize -> {480, 100}, Alignment -> Top,
        FrameMargins -> {{5, 0}, {0, 1}}],
      InputField[Dynamic@text,String, BaseStyle -> {Bold, Black, 75}, Alignment -> Top,
       ContinuousAction -> True, ImageSize -> {480, 100}, FrameMargins -> 0]},
     {2, 1}, 2], (*debugging information*)
    "text: " Dynamic[text], "text length:" Dynamic[StringLength@text],
    "select: " Dynamic[select], "rest: " Dynamic@rest, Dynamic[video],
    "select length: " Dynamic[Length[select]]}
   ], {"ReturnKeyDown" :> (text = text ~~ rest)} (*This is where I tried to put in the conditional that killed wolfram desktop*)],
 Initialization :> (
   auto := Autocomplete[commands];
   commands := {"hop", "skip", "jump", "spin", "walk", "run"};
   select := Dynamic@auto[text][[1]];
   rest := If[
     StringLength[text] > 1,
     StringDrop[
      First[select],
      Clip[StringLength@text, {0, StringLength@First[select]}]],""])]

Continuing from there I'm also looking for a solution for my rest and select commands. Right now the rest suggests a word when you type 2 or more characters. I get an error condition from select when there is no suggestion because using Part requires at least one element in a list throws hands in the air What I WANT to do is use the conditional below because it would only give a suggestion when there is exactly one suggestion.

rest := If[Length[text] == 1, (*etc etc etc*)

However it looks like Length only reads text as one element, the expression, and not as a list because my debug "select length:" is always 1.

How do I have Length look at the list that text represents?

Or

What other command is useful here for the same purpose?

Thank you so much Wolfram Community. You've always been a huge help to me every time I come here. Cheers :)

POSTED BY: Bill Norman
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract