1. #1
    Ext User
    Join Date
    Nov 2008
    Posts
    19
    Vote Rating
    0
    shermdog01 is on a distinguished road

      0  

    Default [FIXED] 1.2.1 FormPanel.isValid() when using nested TabPanels

    [FIXED] 1.2.1 FormPanel.isValid() when using nested TabPanels


    When using a FormPanel with nested TabPanel items, form validation does not work correctly unless all Tab items have been viewed.

    GXT version : 1.2.1
    Browser and version : IE6
    Operating System : Windows XP

    I have added the following to the AdvancedFormsExample.java from the sample code:
    Code:
    home.setAllowBlank(false);
    
        panel.addButton(new Button("Submit", new SelectionListener<ButtonEvent>() {  
            @Override  
            public void componentSelected(ButtonEvent ce) {
                if (panel.isValid()){
                    Info.display("Form","Form is valid");
                }
                else{
                    Info.display("Form","Form is NOT valid");
                }
            }  
            }));
    Full Source
    Code:
    /*
     * Ext GWT - Ext for GWT
     * Copyright(c) 2007, 2008, Ext JS, LLC.
     * licensing@extjs.com
     * 
     * http://extjs.com/license
     */
    package com.extjs.gxt.samples.client.examples.forms;
    
    import com.extjs.gxt.ui.client.GXT;
    import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
    import com.extjs.gxt.ui.client.event.ButtonEvent;
    import com.extjs.gxt.ui.client.event.SelectionListener;
    import com.extjs.gxt.ui.client.widget.Info;
    import com.extjs.gxt.ui.client.widget.LayoutContainer;
    import com.extjs.gxt.ui.client.widget.TabItem;
    import com.extjs.gxt.ui.client.widget.TabPanel;
    import com.extjs.gxt.ui.client.widget.VerticalPanel;
    import com.extjs.gxt.ui.client.widget.button.Button;
    import com.extjs.gxt.ui.client.widget.form.DateField;
    import com.extjs.gxt.ui.client.widget.form.FormPanel;
    import com.extjs.gxt.ui.client.widget.form.Radio;
    import com.extjs.gxt.ui.client.widget.form.RadioGroup;
    import com.extjs.gxt.ui.client.widget.form.TextArea;
    import com.extjs.gxt.ui.client.widget.form.TextField;
    import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
    import com.extjs.gxt.ui.client.widget.layout.ColumnData;
    import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
    import com.extjs.gxt.ui.client.widget.layout.FitLayout;
    import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
    import com.extjs.gxt.ui.client.widget.layout.FormLayout;
    import com.google.gwt.user.client.Element;
    
    public class AdvancedFormsExample extends LayoutContainer {
    
      private VerticalPanel vp;
      private FormPanel panel;
    
      public AdvancedFormsExample() {
        vp = new VerticalPanel();
        vp.setSpacing(10);
      }
    
      @Override
      protected void onRender(Element parent, int index) {
        super.onRender(parent, index);
        createColumnForm();
        createTabForm();
    
        add(vp);
      }
    
      private void createTabForm() {
        panel = new FormPanel();
        panel.setFrame(false);
        panel.setHeaderVisible(false);
        panel.setBodyBorder(false);
        panel.setButtonAlign(HorizontalAlignment.CENTER);
        panel.setLayout(new FitLayout());
    
        TabPanel tabs = new TabPanel();
    
        TabItem personal = new TabItem();
        personal.setText("Personal Details");
        personal.setLayout(new FormLayout());
    
        TextField<String> name = new TextField<String>();
        name.setFieldLabel("First Name");
        name.setValue("Darrell");
        personal.add(name);
    
        TextField<String> last = new TextField<String>();
        last.setFieldLabel("Last Name");
        last.setValue("Meyer");
        personal.add(last);
    
        TextField<String> company = new TextField<String>();
        company.setFieldLabel("Company");
        personal.add(company);
    
        TextField<String> email = new TextField<String>();
        email.setFieldLabel("Email");
        personal.add(email);
    
        tabs.add(personal);
    
        TabItem numbers = new TabItem();
        numbers.setText("Phone Numbers");
        numbers.setLayout(new FormLayout());
    
        TextField<String> home = new TextField<String>();
        home.setFieldLabel("Home");
        home.setValue("800-555-1212");
        home.setAllowBlank(false);
        numbers.add(home);
    
        TextField<String> business = new TextField<String>();
        business.setFieldLabel("Business");
        numbers.add(business);
    
        TextField<String> mobile = new TextField<String>();
        mobile.setFieldLabel("Mobile");
        numbers.add(mobile);
    
        TextField<String> fax = new TextField<String>();
        fax.setFieldLabel("Fax");
        numbers.add(fax);
    
        tabs.add(numbers);
    
        panel.add(tabs);
        panel.addButton(new Button("Cancel"));
        panel.addButton(new Button("Submit", new SelectionListener<ButtonEvent>() {  
            @Override  
            public void componentSelected(ButtonEvent ce) {
                if (panel.isValid()){
                    Info.display("Form","Form is valid");
                }
                else{
                    Info.display("Form","Form is NOT valid");
                }
            }  
            }));  
    
        panel.setSize(340, 180);
    
        vp.add(panel);
      }
    
      private void createColumnForm() {
        FormPanel panel = new FormPanel();
        panel.setFrame(true);
        panel.setIconStyle("icon-form");
        panel.setCollapsible(true);
        panel.setHeading("FormPanel");
        panel.setSize(470, -1);
        panel.setButtonAlign(HorizontalAlignment.CENTER);
        panel.setLayout(new FlowLayout());
    
        LayoutContainer main = new LayoutContainer();
        main.setWidth(450);
        main.setLayout(new ColumnLayout());
    
        LayoutContainer left = new LayoutContainer();
    
        FormLayout layout = new FormLayout();
        layout.setLabelAlign(LabelAlign.TOP);
        left.setLayout(layout);
    
        TextField<String> first = new TextField<String>();
        first.setFieldLabel("First Name");
        left.add(first);
    
        TextField<String> company = new TextField<String>();
        company.setFieldLabel("Company");
        left.add(company);
    
        DateField birthday = new DateField();
        birthday.setFieldLabel("Birthday");
        left.add(birthday);
    
        LayoutContainer right = new LayoutContainer();
    
        layout = new FormLayout();
        layout.setLabelAlign(LabelAlign.TOP);
        right.setLayout(layout);
    
        TextField<String> last = new TextField<String>();
        last.setFieldLabel("Last");
        right.add(last);
    
        TextField<String> email = new TextField<String>();
        email.setFieldLabel("Email");
        right.add(email);
    
        Radio radio1 = new Radio();
        radio1.setBoxLabel("Yes");
    
        Radio radio2 = new Radio();
        radio2.setBoxLabel("No");
    
        RadioGroup group = new RadioGroup();
        group.setFieldLabel("Ext GWT User");
        group.add(radio1);
        group.add(radio2);
        right.add(group);
    
        main.add(left, new ColumnData(.5));
        main.add(right, new ColumnData(.5));
    
        panel.add(main);
    
        LayoutContainer area = new LayoutContainer();
        area.setStyleAttribute("padding", "0 10px 5px 10px");
        area.setWidth(450);
    
        layout = new FormLayout();
        layout.setLabelAlign(LabelAlign.TOP);
        layout.setPadding(0);
        area.setLayout(layout);
    
        TextArea a = new TextArea();
        a.setFieldLabel("Comment");
    
        String adj = GXT.isIE ? "100%" : "-20"; // looking into
        a.setData("anchorSpec", adj);
        area.add(a);
    
        panel.add(area);
    
        panel.addButton(new Button("Cancel"));
        panel.addButton(new Button("Submit"));
    
        vp.add(panel);
      }
    
    }

  2. #2
    Ext User
    Join Date
    Nov 2008
    Posts
    19
    Vote Rating
    0
    shermdog01 is on a distinguished road

      0  

    Default


    Has anyone been able to verify this?

  3. #3
    Ext User
    Join Date
    Nov 2008
    Posts
    19
    Vote Rating
    0
    shermdog01 is on a distinguished road

      0  

    Default


    This is still present in 1.2.2 --- has anyone had an opportunity to review this bug?

  4. #4
    Software Architect
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    I did. I introduced a new attribute to CardLayout (used by TabPanel) to render every item of set.

    You have to set that in formpanels than.

  5. #5
    Software Architect
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    Added to SVN.

  6. #6
    Ext User
    Join Date
    Apr 2007
    Posts
    20
    Vote Rating
    0
    cormet is on a distinguished road

      0  

    Default


    Hi there,

    GXT version : 1.2.3
    Browser and version : FF (Mac) and Safari
    Operating System : OS X

    I am still having the same problem on form validation.
    I have to click the tabs to perform the validation, otherwise it won't valid.

    Is there any workaround here?

    Cheers,

  7. #7
    Ext User
    Join Date
    Jun 2009
    Posts
    3
    Vote Rating
    0
    skahl is on a distinguished road

      0  

    Default


    Workaround by turning off deferred rendering of tab contents - eg:

    tabPanel.setDeferredRender(false);

    In my case I have many tabs with complex contents so I would rather not do this, but it does fix the problem.

  8. #8
    Ext User
    Join Date
    Jun 2009
    Posts
    3
    Vote Rating
    0
    skahl is on a distinguished road

      0  

    Default Deferred binding

    Deferred binding


    FYI - I am using 2.0-m3 and getting the described behaviour.

    I have another a workaround that allows deferred rendering by adding deferred binding. Basically the code I've written requires that the tab 'pages' do all the rendering in the onRender method and that the FormPanel rebinds the data after each tab rendering.

    Does anyone know if there is a more simple method in the API to do this?

    For reference here is my complete code.

    Code:
    import com.extjs.gxt.ui.client.binding.FormBinding;
    import com.extjs.gxt.ui.client.data.BaseModel;
    import com.extjs.gxt.ui.client.event.ButtonEvent;
    import com.extjs.gxt.ui.client.event.ComponentEvent;
    import com.extjs.gxt.ui.client.event.Events;
    import com.extjs.gxt.ui.client.event.Listener;
    import com.extjs.gxt.ui.client.event.SelectionListener;
    import com.extjs.gxt.ui.client.widget.Component;
    import com.extjs.gxt.ui.client.widget.LayoutContainer;
    import com.extjs.gxt.ui.client.widget.TabItem;
    import com.extjs.gxt.ui.client.widget.TabPanel;
    import com.extjs.gxt.ui.client.widget.button.Button;
    import com.extjs.gxt.ui.client.widget.form.Field;
    import com.extjs.gxt.ui.client.widget.form.FormPanel;
    import com.extjs.gxt.ui.client.widget.form.TextField;
    import com.google.gwt.user.client.Element;
    import com.google.gwt.user.client.Window;
    
    /**
     * Renders a form with two tabs each with one field. Both fields require values.
     */
    public class MustVisitTabs extends FormPanel {
    
      public MustVisitTabs() {
        // render tabs
        TabPanel tabPanel = new TabPanel();
    
        TabItem tabItem;
        tabItem = new TabItem("One");
        tabItem.add(new TabOne());
        tabPanel.add(tabItem);
    
        tabItem = new TabItem("Two");
        tabItem.add(new TabTwo());
        tabPanel.add(tabItem);
    
        add(tabPanel);
    
        // button to show validation state
        Button validate = new Button("Validate");
        validate.addSelectionListener(new SelectionListener<ButtonEvent>() {
          public void componentSelected(ButtonEvent be) {
            if (isValid()) {
              Window.alert("Valid\n"
                  + ((BaseModel) getModel()).getProperties());
            }
            else {
              StringBuffer sb = new StringBuffer("INVALID!!");
              for (Field<?> f : getFields()) {
                if (!f.isValid()) {
                  sb.append("\n").append(f.getFieldLabel()).append(" - ")
                    .append(f.getErrorMessage());
                }
              }
              Window.alert(sb.toString());
            }
          }
        });
        addButton(validate);
    
        // bind data
        final BaseModel model = new BaseModel();
        model.set("a", "XXX");
        model.set("b", "XXX");
    
        final FormBinding binding = new FormBinding(this);
        // binding.autoBind();
        // binding.bind(model);
        /*
         * Can get this working with deferred tab rendering by deferring field
         * binding as well. This requires that the tab 'pages' do all rendering in
         * the onRender method and that the FormPanel rebinds the data after each
         * tab rendering. Note: a specialized implementation of FormBinding autoBind +
         * bind methods could be produced to optimize performance by not rebinding
         * already bound fields.
         */
        for (TabItem item : tabPanel.getItems()) {
          for (Component component : item.getItems()) {
            component.addListener(Events.Render,
              new Listener<ComponentEvent>() {
                public void handleEvent(ComponentEvent be) {
                  binding.autoBind();
                  binding.bind(model);
                }
              });
          }
        }
    
        // done only so can dump values behind validate button
        setModel(model);
      }
    
      public class TabOne extends LayoutContainer {
        @Override
        protected void onRender(Element parent, int index) {
          super.onRender(parent, index);
    
          TextField<String> a = new TextField<String>();
          a.setName("a");
          a.setAllowBlank(false);
          add(a);
        }
      }
    
      public class TabTwo extends LayoutContainer {
        @Override
        protected void onRender(Element parent, int index) {
          super.onRender(parent, index);
    
          TextField<String> b = new TextField<String>();
          b.setName("b");
          b.setAllowBlank(false);
          add(b);
        }
      }
    }

  9. #9
    Sencha User
    Join Date
    Mar 2009
    Location
    Denver, CO
    Posts
    38
    Vote Rating
    0
    mabco is on a distinguished road

      0  

    Default


    This is still a problem in GXT 2.0.1 (with GWT 1.7). Is there a fix coming for this? Great options suggested by previous users, but, unfortunately, neither are perfect (ie. they solve one problem but cause another). The whole form binding implementation seems to be very fragile.

  10. #10
    Software Architect
    Join Date
    Sep 2007
    Posts
    13,971
    Vote Rating
    132
    sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light sven is a glorious beacon of light

      0  

    Default


    GXT 2.0.1 does not have this problem.

Turkiyenin en sevilen filmlerinin yer aldigi xnxx internet sitemiz olan ve porn sex tarzi bir site olan mobil porno izle sitemiz gercekten dillere destan bir durumda herkesin sevdigi bir site olarak tarihe gececege benziyor. Sitenin en belirgin ozelliklerinden birisi de Turkiyede gercekten kaliteli ve muntazam, duzenli porno izle siteleri olmamasidir. Bu yuzden iste. Ayrica en net goruntu kalitesine sahip adresinde yayinlanmaktadir. Mesela diğer sitelerimizden bahsedecek olursak, en iyi hd porno video arşivine sahip bir siteyiz. "The Best anal porn videos and slut anus, big asses movies set..."