Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Is it possible to manually move caret in a FormItem?

    In our app, we have a function where forms enter and exit "editmode" i.e. it can be seen when the form starts to be editable. When that happens we put focus on one specific item in the form.

    All this works, but if the formitem is not empty (i.e we're editing rather then creating a new item), the caret appears at the end of the text. It would be better if the caret was at the start of the formitem (a dateitem). So that you can just start typing.

    Is this at all possible?

    #2
    Yes, you can call setSelectionRange(0, 0) on your item

    Comment


      #3
      Ah - i did not find this because it's not in FormItem. This means that i somehow have to check manually what type it is and cast it to the respective class if i want to change it. Would have loved for it to be in FormItem instead and not do anything for SelectItems :)

      Anyway - thanks!

      Comment


        #4
        Hmm. I can't get this call to have any effect. I made a small method i call whenever i put focus on a formitem:

        Code:
        private void checkSelectBeginning(FormItem item){
                if(item instanceof DateItem){
                    GWT.log("is dateitem, setting selectionrange to 0,0 : " + ((DateItem) item).getUseTextField());
                    ((DateItem)item).setSelectionRange(0,0);
                }else if(item instanceof TextItem){
                    ((TextItem)item).setSelectionRange(0,0);
                    GWT.log("is textitem, setting selectionrange to 0,0" + ((DateItem) item).getUseTextField());
                }
            }
        I do get the printout:
        is dateitem, setting selectionrange to 0,0 : true
        So the object seems to be valid? However, the caret stays at the end of the formitem. Any suggestions?

        Comment


          #5
          This could be an issue with timing, perhaps due to how/where you're putting focus in the item.

          We would expect setSelectionRange() to work if you called it from an EditorEnter handler, which runs only when focus enters the editor itself.

          Comment


            #6
            Hi, thanks for response. I've tried focushandlers, and couldn't that get to work either.

            I made a small testcase below, perhaps you can see something obvious? As you can see i've tried various different approaches to no avail. What seems to happen is that the caret does move to the beginning, but then immediately jumps back to the end.


            My desired outcome is: When the form goes into editmode, put focus on a specific item and put caret in the beginning so that the user can start overwriting the current value. by typing without having to do anything first.


            Code:
            public void onModuleLoad() {
                    final DynamicForm form = new DynamicForm();
                    form.setNumCols(3);
                    form.setWidth(300);
            
                    TextItem firstName = new TextItem("name");
                    firstName.setTitle("Name");
                    firstName.setWrapTitle(false);
            
                    DateTimeItem dateTimeItem = new DateTimeItem("time");
                    dateTimeItem.setAlign(Alignment.LEFT);
                    dateTimeItem.setTextAlign(Alignment.LEFT);
                    dateTimeItem.setUseMask(true);
                    dateTimeItem.setTitle("Time");
                    dateTimeItem.setWrapTitle(false);
            
                    form.setCanEdit(false);
                    form.setFields(firstName, dateTimeItem);
            
            
                    Button button = new Button("Do test");
                    button.addClickHandler(clickEvent -> {
                        form.setCanEdit(true);
                        form.editRecord(createRecord());
                        doTheFocusThing(dateTimeItem);
                    });
            
            
                    //does not work either, not with form focushandler, not with formitem focushandler
                    /*dateTimeItem.addFocusHandler(focusChangedEvent -> {
                        GWT.log("FOCUS CHANGED HANDLER");
                        doTheFocusThing(dateTimeItem);
                    }); */
            
                    VLayout layout = new VLayout();
                    layout.setPadding(30);
                    layout.setMembersMargin(15);
                    layout.addMember(button);
                    layout.addMember(form);
                    layout.draw();
                    button.focus();
                }
            
                private void doTheFocusThing(FormItem item){
                    GWT.log("DOING FOCUS THING");
                    item.focusInItem();
                    checkSelectBeginning(item);
                }
            
                private void checkSelectBeginning(FormItem item) {
                    if (item instanceof DateItem) {
                        GWT.log("is dateitem, setting selectionrange to 0,0 : " + ((DateItem) item).getUseTextField());
                        ((DateItem) item).setSelectionRange(0, 0);
                    } else if (item instanceof TextItem) {
                        ((TextItem) item).setSelectionRange(0, 0);
                        GWT.log("is textitem, setting selectionrange to 0,0" + ((DateItem) item).getUseTextField());
                    }
                }

            Comment


              #7
              Hi Mathias
              The problem here is that your setSelectionRange call is "fighting with" some framework logic for items with useMask set to true, whereby on focus we automatically put the caret after the last populated character in the mask.

              We agree that this framework logic shouldn't be preventing you explicitly setting the selection range in this way and have a developer assigned to take a look at this as a possible bug. You could work around it by putting the "setSelectionRange()" call in a timer so it executes asynchronously after focus completes:
              Code:
              ...
                Timer t = new Timer() {
                  @Override
                  public void run() {
                    ((DateItem)item).setSelectionRange(0,0);
                  }
                };
              
                t.schedule(100);
              ...
              However it seems like the "selectOnFocus" attribute may actually be a better option for you. If you call setSelectOnFocus(true) for your item, it should ensure that even for items with useMask:true, the default behavior on focus is to select the whole value of the item. This would allow the user to start typing and overwrite the existing value without any problems.

              * If this setting doesn't behave as described for you, let us know exactly which version of SmartGWT you're using, and show us the code from your modified attempt.

              Thanks
              Isomorphic Software

              Comment


                #8
                Hi, thanks for getting back. I am currently using 13.0-p20220208.

                Yeah, that does indeed sound like a bug to me. Would be fantastic if you took a look at it.



                Regarding "selectonfocus()", i tried amending my testcase so that i call setselectonfocus on the dataitem (code below).

                adding selectonfocus has no effect on the formitem. All text is not selected when i click on the button, and the caret moves as before.

                ( If i call "selectonclick", all text in the field is selected when i click on it with the mouse, so that works. )


                So, i can't see that this helps my use case, unfortunately. It's not exactly what i'd like, anyway. I think it would be better if the old value is seen while typing. If all text is selected, the field will be emptied as soon as the user clicks the first key.



                Code:
                public void onModuleLoad() {
                        final DynamicForm form = new DynamicForm();
                        form.setNumCols(3);
                        form.setWidth(300);
                
                        TextItem firstName = new TextItem("name");
                        firstName.setTitle("Name");
                        firstName.setWrapTitle(false);
                
                        DateTimeItem dateTimeItem = new DateTimeItem("time");
                        dateTimeItem.setAlign(Alignment.LEFT);
                        dateTimeItem.setTextAlign(Alignment.LEFT);
                        dateTimeItem.setUseMask(true);
                        dateTimeItem.setTitle("Time");
                        dateTimeItem.setWrapTitle(false);
                
                //----> NEW ROWS HERE
                        dateTimeItem.setSelectOnFocus(true); //no visible effect from what i can see
                        //dateTimeItem.setSelectOnClick(true); this makes the form text be "all selected" when clicked on with mouse
                
                        form.setCanEdit(false);
                        form.setFields(firstName, dateTimeItem);
                
                
                        Button button = new Button("Do test");
                        button.addClickHandler(clickEvent -> {
                            form.setCanEdit(true);
                            form.editRecord(createRecord());
                            doTheFocusThing(dateTimeItem);
                        });
                
                
                        //does not work either, not with form focushandler, not with formitem focushandler
                        /*dateTimeItem.addFocusHandler(focusChangedEvent -> {
                            GWT.log("FOCUS CHANGED HANDLER");
                            doTheFocusThing(dateTimeItem);
                        }); */
                
                        VLayout layout = new VLayout();
                        layout.setPadding(30);
                        layout.setMembersMargin(15);
                        layout.addMember(button);
                        layout.addMember(form);
                        layout.draw();
                        button.focus();
                    }
                
                    private void doTheFocusThing(FormItem item){
                        GWT.log("DOING FOCUS THING");
                        item.focusInItem();
                        checkSelectBeginning(item);
                    }
                
                    private void checkSelectBeginning(FormItem item) {
                        if (item instanceof DateItem) {
                            GWT.log("is dateitem, setting selectionrange to 0,0 : " + ((DateItem) item).getUseTextField());
                            ((DateItem) item).setSelectionRange(0, 0);
                        } else if (item instanceof TextItem) {
                            ((TextItem) item).setSelectionRange(0, 0);
                            GWT.log("is textitem, setting selectionrange to 0,0" + ((DateItem) item).getUseTextField());
                        }
                    }

                Comment

                Working...
                X