Announcement

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

    Align DynamicForm to the Center o VLayout

    Is there any possible way to align a DynamicForm horizontally to the center of a VLayout? I've tried what is done in this showcase demo, but it won't work for the form (it does work correctly for the IButton).

    Here is my
    Code:
    package co.focuss.bmsimulator.client.ui.widgets;
    
    import com.google.gwt.core.client.GWT;
    import com.smartgwt.client.data.DSCallback;
    import com.smartgwt.client.data.DSRequest;
    import com.smartgwt.client.data.DSResponse;
    import com.smartgwt.client.data.DataSource;
    import com.smartgwt.client.types.Alignment;
    import com.smartgwt.client.types.TitleOrientation;
    import com.smartgwt.client.util.SC;
    import com.smartgwt.client.widgets.IButton;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.layout.VLayout;
    import com.smartgwt.client.widgets.layout.SectionStackSection;
    import co.focuss.bmsimulator.client.internationalization.BMSimulatorConstants;
    
    public class PreferencesStackSection extends SectionStackSection {
    
        private static final String SAVE_ICON = "icons/save.png";
        private static final int COMPONENT_GAP = 10;
        
        // Object used to get access to internationalization constants and messages
        private BMSimulatorConstants constants = GWT.create(BMSimulatorConstants.class);
        
        private DataSource ds;
        private DynamicForm form;
        private IButton saveBtn;
        
        public PreferencesStackSection(String title) {
            super(title);
            ds = DataSource.get("preferences");
            buildPreferencesLayout();
        }
    
    
        private void buildPreferencesLayout() {
            VLayout layout = new VLayout(COMPONENT_GAP);
            layout.setMargin(COMPONENT_GAP * 2);
            layout.setDefaultLayoutAlign(Alignment.CENTER);
            createPreferencesForm(layout);
            createSaveButton(layout);
            this.addItem(layout);
        }
    
        private void createPreferencesForm(VLayout layout) {
            form = new DynamicForm();
            form.setNumCols(1);
            form.setTitleOrientation(TitleOrientation.TOP);
            form.setDataSource(ds);
            layout.addMember(form);
        }
    
        private void createSaveButton(VLayout layout) {
            
            saveBtn = new IButton(constants.preferencesSaveButton());
            saveBtn.setIcon(SAVE_ICON);
            saveBtn.addClickHandler(new ClickHandler() {
                public void onClick(ClickEvent event) {
                    
                    DSCallback callback = new DSCallback() {
                        public void execute(DSResponse response, Object rawData, DSRequest request){
                            SC.say(constants.preferencesSavedOK());
                        }
                    };
                    
                    form.saveData(callback);
                }
            });
            layout.addMember(saveBtn);
        }
    }
    Last edited by carlossierra; 16 Dec 2015, 09:01.

    #2
    Look in the Watch tab of the Developer Console so you can see the size of the form and the containing layout. Most likely the form as a whole is centered, but the elements you've placed within the form don't take up the form's full width.

    You can either reduce the specified width of the form to match the elements, or size the elements to match the form using the techniques described in the Form Layout overview.

    Comment


      #3
      Thanks for your answer, but I don't think that's the problem because of these things I've tried:

      1. Resizing dynamically the HLayout that contains the VLayout (in the class that uses the PreferencesStackSection class): the IButton will move dynamically to the center of the control. The form stays anchored to the left of the screen/control.
      2. I also tried making that container HLayout control bigger (50% of the screen), but the behavior stays the same.

      It's like the DynamicForm control refuses to comply with the layout.setDefaultLayoutAlign(Alignment.CENTER) instruction.

      By the way, I also tried these (each on a separate attempt to make this work):
      Code:
      form.setLayoutAlign(Alignment.CENTER); // seemed like a reasonable enough option
      form.setAlign(Alignment.CENTER); // didn't spect much, but tried anyway...
      form.setNumCols(2); // maybe the setting of 1 column was making the form act strange, as two columns are required minimum when the titles are to the left
      form.setTitleOrientation(TitleOrientation.LEFT); // maybe it was a conflict with the TitleOrientation that I want (TOP)

      Comment


        #4
        If you have not yet looked at the Watch Tab to see the component sizes, do that now - there's no point speculating.

        Comment


          #5
          Ok. I did what you suggested (sorry for not doing it before... as you said, speculating is pointless... lesson learned!). And you were right.

          The form is taking all the available space (after taking out the margins), but the form titles and fields only use a small (and fixed) portion of that allocated space.

          Click image for larger version

Name:	DynamicForm.png
Views:	653
Size:	89.9 KB
ID:	233510

          So now the question is how can I make the form fields span to the full width of the canvas? I have tried different things after finding this, and can't seem to get the desired result, which would be to have the set of titles and controls as shown above, but centered in the canvas' available space, and aligned with the button below?

          Also, I think there's something wrong when using the TitleOrientation.TOP setting, since the form would leave some additional blank space for each column of fields in the form). This is what I tried:
          Code:
              private void createPreferencesForm(VLayout layout) {
                  form = new DynamicForm();
                  form.setNumCols(2);
                  form.setTitleOrientation(TitleOrientation.TOP);
                  form.setColWidths("50%", "50%");
                  form.setDataSource(ds);
                  layout.addMember(form);
              }
          And the result:

          Click image for larger version

Name:	DynamicForm2.png
Views:	609
Size:	8.3 KB
ID:	233511
          Thanks again for all the help!
          Attached Files

          Comment


            #6
            You just need a closer read of the Form Layout overview, and also perhaps to turn on some of the diagnostics mentioned there.

            The main thing you are missing is that the TextItems have a fixed width of 150px by default. They will stick to that width unless you set the width to "*", which tells them to fill their column.

            Comment


              #7
              Thanks for your reply. I have to make clear that I have read the Form Layout review (and various other things in the past two days trying to solve this). In fact, this is how I came to the idea that:
              Code:
              form.setColWidths("50%", "50%");
              should help the form in the second image above display like I wanted. But this didn't help. As I understand it, I am telling the form to use 50% of the available space for the first column, and the other 50% for the other column, since I have only two columns and none of the has a fixed width. The two columns do take 50% of the available space, but the white unused space is still there.

              I also tried going back to my one column configuration, and following this advice found on the Form Layout overview: "FormItems that have "*" for FormItem.width will fill the column". Again, the result is that part of white space to the right of the column.

              Since I am not explicitly defining any fields in the data source xml file, nor in the class, I tried to iterate through all the FormItem elements, setting their widths to "*" or "100%". The result is the same.
              Code:
              for(FormItem item: form.getFields()){
                  item.setWidth("*");
              }
              Sorry to keep asking, but I have spent my last two days reading, trying to learn and trying to solve it before asking again, and I am really not seeing how to solve this.

              ps. this is my preferences.ds.xml file content, in case it is of any help:
              Code:
              <DataSource
                  ID="preferences"
                  serverType="sql"
                  tableName="preferences"
                  autoDeriveSchema = "true"
              ></DataSource>

              Comment


                #8
                Aha. The problem is that you're missing even more fundamental information: go back to the QuickStart Guide, Data Binding chapter, to see how you can specify widths for your fields (or any other setting) even though you are using a DataSource.

                However, from a design perspective, you should also consider whether you want the inputs to span all that space. Super-wide inputs look odd if the expected values are quite short. Another approach would be to set the form to be about 308px width (2x default width of TextItem, plus padding), in which case it will be centered, with fixed width input fields.

                Comment


                  #9
                  Well, I appreciate the design advice. I agree with it, and I have to make clear that I don't want to make a huge form with huge fields. The example images I have posted are for clarity, because the issue I'm trying to solve is less evident with narrower forms (and stack sections).

                  Regarding your comment on me missing the information from the Data Binding chapter, I just re-read it again, and I have to respectfully disagree with you. I understand how to set the properties for the fields, but wouldn't that defeat the purpose of being able to use autoDeriveSchema = "true" in the data source definition?

                  Anyway, I finally got it to behave as I want it, but I don't think I know why. What I did was to move the layout.addMember(form) line before the loop where I set all column widths to take all the space, and also to define the form width after adding it to the layout, and now each column takes all available space. Here is my code:
                  Code:
                  ds = DataSource.get("preferences");
                  form = new DynamicForm();
                  form.setDataSource(ds);
                  form.setNumCols(1);
                  form.setTitleOrientation(TitleOrientation.TOP);
                  layout.addMember(form);
                  form.setWidth("70%");
                  for(FormItem item: form.getFields()){
                      item.setWidth("*");
                  }
                  Here is the result :)
                  Click image for larger version

Name:	DynamicForm3.png
Views:	639
Size:	8.7 KB
ID:	233533

                  Could it be because the fields are not defined explicitly, so they are only being "created" after adding the form to the layout, hence making it only possible to set their widths at that moment?

                  Comment


                    #10
                    No, specifying a single, presentation-oriented property per field doesn't defeat the purpose of autoDeriveSchema - everything else is still auto-derived, and doesn't need to be repeated.

                    It would instead be a serious problem if you could not add presentation oriented information in this way, since obviously, every aspect of the presentation isn't going to be able to be derived from the database.

                    Iterating through the fields after databinding is another, valid way of doing things, and can be a line or two shorter for the unusual situation that you need to set exactly one property for each field, to the same value for all fields, and no other properties need to be set for any field. But the general-purpose strategy is to use the approach shown in the Data Binding chapter.

                    Comment


                      #11
                      Ok. Thanks.

                      Comment

                      Working...
                      X