Edit box execute action when Enter is pressed

Edit box execute action when Enter is pressed

apottsDRQ8Z
Participant Participant
1,005 Views
9 Replies
Message 1 of 10

Edit box execute action when Enter is pressed

apottsDRQ8Z
Participant
Participant

My goal is to hit enter in the search box, instead of having to click the search button, and have the list_box update.

 

Context of the code:

Searches a text file for notes and populates them in a list_box.  An edit box acts as a search field to filter the list.  Currently, I have to use the mouse to click the search button, but I'd prefer to be able to just hit Enter on the keyboard.

I have not been able to find an example of exactly what I'm trying to do and I've tried a number of different things that seemed close, so the code is probably overly complicated at this point.  So, a cleaner implementation would be welcome.

 

Thanks,

Aaron

0 Likes
Accepted solutions (1)
1,006 Views
9 Replies
Replies (9)
Message 2 of 10

scot-65
Advisor
Advisor

@apottsDRQ8Z 

 

Edit box behavior is much different to all the other tiles.

Assigning an allow_accept will not work as the action will invoke when one enters the edit box (I think). Nothing happens when leaving the edit box or while entering values in the edit box.

 

Documentation mentions a trigger/tracer when adding values/leaving the edit box but I have not seen working examples.

 

Possible Workaround:

Is the number of search terms lengthy? Meaning over 20 keywords over the lifetime of usage.

Consider using the edit box to populate a list that will be stored as an external file and use that external file to populate a list box or popup. If the keyword is not in the list, enter it in the edit box and have the program add to list as well as use the value for the search. It is pretty easy to use/read CSV or INI structured files. Parsing would be minimal.

Now by selecting a line in the list box or popup, an action_tile can be triggered.

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 3 of 10

paullimapa
Mentor
Mentor
Accepted solution

These are the changes I made:

notesearch.dcl

1) Instead of placing the is_default attribute under the Search button, I placed this under the Search edit_box so that when the dialog box first opens it'll land on the Search edit_box and not the Search button

2) I added the mnemonic attribute so you can use the Alt+mnemonic letter combination to jump from one location of the dialog to another

note_selector : dialog {
    label = "Note Selector";
    : column {
        : row {
            : edit_box {
                key = "search";
                label = "Search:";
                edit_width = 30;
                action = "do_search";

                is_default = true;
                mnemonic = "S";

            }
            : button {
                key = "do_search";
                label = "Search";
                width = 10;
//                is_default = true;
            }
        }
        : list_box {
            key = "notelist";
            label = "Matching Notes:";
            height = 10;
            width = 40;
            fixed_width = true;
            allow_accept = true;

            mnemonic = "M";

        }
        : text {
            key = "preview";
            label = "Preview:";
            width = 40;
            height = 5;
        }
        : row {
            : button {
                key = "insert";
                label = "Insert";

                 mnemonic = "I";

            }
            : button {
                key = "cancel";
                label = "Cancel";
                is_cancel = true;
            }
        }
    }
}

 notesearch.lsp

1) By changing the search edit_box action call back to match with the do_search button action call back  you should then can just hit the Enter key to cause the Matching Notes list_box to update. Then you really no longer need the separate Search button at all.

  ;; Add action for search edit box
;  (action_tile "search"
;    "(if (= $reason \"key\")
;       (if (= $value \"\\r\")
;         (do-search)))"
;  )
   (action_tile "search" "(do-search)") 

 2) I added a mode_tile function to disable the Insert button at dialog startup. The Insert button should only be enabled when the Preview notelist is updated with text.

  ;; Update preview when selection changes
  (action_tile "notelist"
    "(if filtered_notes
      (progn
        (setq selected_note (nth (atoi $value) filtered_notes))
        (if selected_note
         (progn     
          (mode_tile \"insert\" 0)    
          (set_tile \"preview\" selected_note)     
         )
         (progn
          (mode_tile \"insert\" 1)    
          (set_tile \"preview\" \"\")
         )
        )
      )
      (progn         
       (mode_tile \"insert\" 1)    
       (set_tile \"preview\" \"\")
      )
    )"
  )
   (action_tile "search" "(do-search)") 
  
  (mode_tile "insert" 1) ; start with insert disabled

  ;; Show dialog
  (setq result (start_dialog))

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
Message 4 of 10

Sea-Haven
Mentor
Mentor

Just a side ways answer, we made our Notes in word with item numbering, copied and pasted into Acad, so whilst "insert notes" does a full display you can delete any item, and the notes are auto renumbered. very easy to do say "don't need that clause". Select and erase.

0 Likes
Message 5 of 10

apottsDRQ8Z
Participant
Participant

@paullimapa 
Thank you, I spent hours trying to figure that out, and I appreciate the detailed explanation.  The mode_tile and mnemonic additions are good ideas as well.

 

Thanks,

Aaron

0 Likes
Message 6 of 10

paullimapa
Mentor
Mentor

You are welcome…cheers!!!


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 7 of 10

scot-65
Advisor
Advisor

@apottsDRQ8Z 

@paullimapa 

 

Paul,

Replicating what you show as a simple exercise I ran into a few issues.

Assigning an action_tile to the edit box DID work, however when leaving the edit box the trigger occurred again.

Trial and error (and re-reading the developers guide) showed there will be a $reason added to the callback.

 

(do-search $reason)

 

where $reason = 1 to prevent the callback trigger when leaving the edit box (when pressing [Tab], mode_tile, or mouse action, etc.).

 

The other issue I came across involves advancing the focus to the list box after the search query.

The dialog was not behaving and by removing the "is_default=true" from the DCL everything behaved correctly.

Mode_tile = 2 to the list box tile now works.

 

Assigning an "action" inside the DCL is the same as "action_tile" in the LSP. I prefer the later.

Here's one example why I prefer the later - it will be easier to debug:

 

(action_tile "EditBox1" "(if (= $reason 1)(do-search))")

 

"mnemonic=" inside the DCL I do not use. Instead, label="&Accept"; works just fine.

 

The other half of the exercise involves double-clicking or pressing [Enter] while in the list box.

For this to behave correctly, we have to look for $reason = 4.

 

test-EdiBox.gif

The attached files demonstrate pressing [Enter] while in an edit box and demonstrate a double-click or pressing [Enter] while inside a list box.

This also demonstrates the use of mode_tile.

No mouse action is needed to navigate the dialog.

 

To use, the DWG, DCL and LSP must all be in the same directory (a trusted location issue).

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 8 of 10

paullimapa
Mentor
Mentor

@apottsDRQ8Z 

Here are my comments Scot:

You are correct if you want to restrict the callback trigger actions on the edit_box.

I've added these options to your code commenting out the ones not used:

    (action_tile "Edi1" "(if (= $reason 1) (Edi_Search $value))") ; pass entered value to Edi_Search function
;    (action_tile "Edi1" "(Edi_Search)") ; both enter & tab triggers
;    (action_tile "Edi1" "(if (= $reason 1) (Edi_Search))") ; only enter triggers
;    (action_tile "Edi1" "(if (= $reason 2) (Edi_Search))") ; other methods like tab to leave triggers

Notice I added an argument to pass the $value which represents the current text entered into the edit_box onto the Edi_Search function and I made some additional modifications to that Edi_Search function as well:

 ;==== Function Edit Box [Enter] to start query and move to List Box ========
 ; Argument:
 ; val = value from edit box 
 (defun Edi_Search ( val / idx ) ; arguments & localize variables
  (alert val) 
;  (alert (get_tile "Edi1"))
  (mode_tile "Lis1" 0)   ;enable tile
  (start_list "Lis1")(mapcar 'add_list (setq a (list "Apple" "Orange" "Peach")))(end_list)
   
  (if (setq idx (vl-position val a)) ; chk if entered value matches with an index item in list
   (set_tile "Lis1" (itoa idx)) ; then when matches set position as entered value by converting index # to string
   (progn  ; else when no match
    (setq idx 0) ; set position as first item  
    (set_tile "Lis1" (itoa idx)) ; select item on list
    (set_tile "Edi1" (nth idx a)) ; change edit box value to use selected item 
   )
  ) ; if
   
  (mode_tile "Lis1" 2)   ;set focus to this tile
  (mode_tile "insert" 0) ;enable tile
 );end Edi_Search

I then updated the "But1" callback function to reflect this change to the Edi_Search function:

    (action_tile "But1" "(Edi_Search (get_tile \"Edi1\"))")
;    (action_tile "But1" "(Edi_Search)")

Instead of having to deal with the issue of having to locate a separate dcl file in the same folder as the lsp file I added a function that writes your dcl file on the fly to the temp folder which is what gets loaded:

 ;==== Function writes dcl on the fly
 ; Argument:
 ; fil = dcl file name
 (defun wri_dcl ( fil / dcl-fn dcl-fp dcl-fn )
  (if (and (setq dcl-fn (vl-filename-mktemp fil)) (setq dcl-fp (open dcl-fn "w")))
    (mapcar 
      '(lambda (x)(write-line x dcl-fp))
       (list
         "//"
         "//  test-EditBox-Enter.DCL"
         "//"
         "swh0 :spacer {width=0.0; height=0.0;}"
         "rfwtac :row {fixed_width=true; alignment=centered; height=3.5;}"
         "but12 :button {fixed_width=true; width=12.0;}"
         "//"
         "EdiBox"
         ":dialog {label=\"Edit and List Box Exercise\";"
         " swh0;"
         " :text_part {key=\"Tex1\"; width=23.0; alignment=centered;}"
         "// :edit_box {key=\"Edi1\"; fixed_width=true; width=23.0; alignment=centered;}"
         " :edit_box {key=\"Edi1\"; label=\"S&earch\"; fixed_width=true; width=23.0; alignment=centered; is_default = true;}"
         " swh0;"
         " :but12 {key=\"But1\"; label=\"&Search\"; alignment=centered;}"
         " swh0;"
         "// :list_box {key=\"Lis1\"; fixed_width=true; width=26.2; alignment=centered;}"
         " :list_box {key=\"Lis1\"; label=\"Select Ite&m\"; fixed_width=true; width=26.2; alignment=centered;}"
         " :rfwtac {"
         "  swh0;"
         "  :but12 {key=\"insert\"; label=\"&Insert <\";}"
         "  swh0;"
         "  :but12 {key=\"cancel\"; label=\"&Cancel\"; is_cancel=true;}"
         "  swh0;"
         " }"
         "}"
      )
    )
  )
  (if dcl-fp (progn (close dcl-fp) dcl-fn))   ; return filename if successful
 )
;==== DASHBOARD ============================================================
 (princ "Test Edit and List Box Behavior ")
 (setq sd 0)           ;Initialize flag to enter main program
 (setq dcl (wri_dcl "test-EditBox-Enter.dcl"))  ; write dcl on the fly
 (if dcl
  (progn
   (EdiBox_Dialog)       ;Get User Input
   (vl-file-delete dcl)  ; delete dcl
   (if (and sd (> sd 0)) ;Enter "Main Program"
    (progn
    ;*** Execute or send to function(s) ***
     (alert a)
     (princ)
    );progn
    ; else alert user
    (alert "Cancel Button Selected") 
   );if
  )
  (alert "Failed to Write DCL") 
 )
;

Also I made the following minor changes:

(defun c:EdiBox 
 ; localize functions & variables
 ( / a dcl Edi_List Edi_Search EdiBox_Dialog sd wri_dcl )
 ; ( / a sd )  
 ;
 (vl-load-com) ; load vl functions
  
; the following line not necessary since these variables are localized at beginnning
; (setq a nil sd nil)

As for the dcl, I did not encounter any differences with or without the "is_default=true".

In either case I could not get a double click to work on the edit_box.

The double click on the list_box as you have it in the code with $reason works fine.

I did make the following changes to your dcl by adding labels so you can use the Alt+mnemonic key to jump to those locations:

//
//  test-EditBox-Enter.DCL
//
swh0 :spacer {width=0.0; height=0.0;}
rfwtac :row {fixed_width=true; alignment=centered; height=3.5;}
but12 :button {fixed_width=true; width=12.0;}
//
EdiBox
:dialog {label="Edit and List Box Exercise";
 swh0;
 :text_part {key="Tex1"; width=23.0; alignment=centered;}
// :edit_box {key="Edi1"; fixed_width=true; width=23.0; alignment=centered;}
 :edit_box {key="Edi1"; label="S&earch"; fixed_width=true; width=23.0; alignment=centered; is_default = true;}
 swh0;
 :but12 {key="But1"; label="&Search"; alignment=centered;}
 swh0;
// :list_box {key="Lis1"; fixed_width=true; width=26.2; alignment=centered;}
 :list_box {key="Lis1"; label="Select Ite&m"; fixed_width=true; width=26.2; alignment=centered;}
 :rfwtac {
  swh0;
  :but12 {key="insert"; label="&Insert <";}
  swh0;
  :but12 {key="cancel"; label="&Cancel"; is_cancel=true;}
  swh0;
 }
}

Like you I also prefer assigning "action_tile" in the LSP over "action" inside the DCL along with others like the list items that would go into a list_box.

As for preference on using "mnemonic=" vs "&Accept"; I've actually used both. But in most instances I do prefer "mnemonic=" because then the actual label like "Accept" is not interrupted with "&Accept" so when I do a search for "Accept" it can be found.

I've attached both the updated lsp & dcl along with the lsp routine I use to convert dcl to lsp: DCL2LSP.lsp

This function can be executed by entering the following at the command prompt:

(load "DCL2LSP")
(DCL2LSP)

 


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes
Message 9 of 10

scot-65
Advisor
Advisor

@paullimapa 

This was an exercise only.

When ready I will incorporate the DCL into the LSP (the two lines I use to call and load the temp. writing purposely left out).

The list for the list box is a testing mechanism only.

 

Perhaps I misunderstood the OP's query (I did not review his code).

I took the message as to populate the list box with the results only instead of indexing to the first occurrence within a master list as you seem to show.

From my point of view example: A block library containing 1400 blocks in a single directory where the blocks are typically grouped using a 2-character prefix to the block name.

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

0 Likes
Message 10 of 10

paullimapa
Mentor
Mentor

I just wanted to carry your exercise a bit further to show that when an entry in the edit box does not match with anything on the list then not only is the first item in the list is selected but also transfer that selection into the edit box


Paul Li
IT Specialist
@The Office
Apps & Publications | Video Demos
0 Likes