New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

columnToggler: Unselected Columns being displayed #4477

Closed
NOTiFYcouk opened this Issue Jan 28, 2019 · 12 comments

Comments

Projects
None yet
3 participants
@NOTiFYcouk
Copy link

NOTiFYcouk commented Jan 28, 2019

1) Environment

  • PrimeFaces version: 6.2.15
  • Does it work on the newest released PrimeFaces version? Version? No 6.2.15
  • Does it work on the newest sources in GitHub? No
  • Application server + version: JBoss WildFly 15.0.1.FINAL (EE8)
  • Affected browsers: Google Chrome/Safari

2) Expected behavior

7 columns I selected display as I move through the dataTable
...

3) Actual behaviour

All columns headimngs from dataTable are displayed. Albeit without data in non-selected tables.
..
I am using PrimeFaces 6.2.15. I have a page which has a dataTable with pagination, multiViewState="true" together with a columnToggler.

As expected the dataTable populates with all the dataTable’s columns display. I use the columnToggler to reduce the number of columns displayed from 21 to a more manageable level of 7.

When I navigate to the next page the 7 columns are displayed using about 40% of the page width and the remaining 14 columns displayed in the remaining 60%, with no data.

If I re-sort any one of the 3 ‘sortBy’ columns the page refreshes as it should be. As soon as I move back or forward the same error occurs.
screenshot 2019-01-28 at 18 50 40
Uploading Screenshot 2019-01-28 at 18.50.40.png…
Uploading Screenshot 2019-01-28 at 18.51.54.png…
Uploading Screenshot 2019-01-28 at 18.52.32.png…
Uploading Screenshot 2019-01-28 at 18.52.41.png…

4) Steps to reproduce

Have a dataTable populated with enough rows to paginate and enough columns to fill page. Select half of them and move to the next page.
..

5) Sample XHTML

<h:body>
    <h:form id="formMotorcycles">
        <h:outputLabel for="selectCheckboxMenuManufacturer" value="Manufacturer:"/>
        <p:selectCheckboxMenu id="selectCheckboxMenuManufacturer"
                              value="#{manufacturerController.selectedManufacturers}"
                              valueChangeListener="#{motorcycleController.selectedManufacturerChanged}"
                              converter="omnifaces.SelectItemsConverter"
                              label="Manufacturer"
                              multiple="true"
                              filter="true"
                              filterMatchMode="startsWith"
                              panelStyle="width:250px">
            <f:selectItems value="#{manufacturerController.allManufacturers}"/>
            <p:ajax event="change" process="@this"
                    update="tabHomeView:formMotorcycles:dataTableMotorcycles"></p:ajax>
        </p:selectCheckboxMenu>

        <p:dataTable value="#{motorcycleController.allMotorcycles}" style="width:100%" var="motorcycle" border="1"
                     id="dataTableMotorcycles"
                     rows="20"
                     paginator="true"
                     multiViewState="true"
                     paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
                     rowsPerPageTemplate="5,10,15,20,25,30,35,40,45,50"
                     resizableColumns="true"
                     draggableColumns="true"
                     scrollWidth="100%">

            <f:facet name="header">
                <p:commandButton id="columnTogglerMotorcycles" type="button" value="Columns" style="float:right"
                                 icon="pi pi-align-justify"/>
                <p:columnToggler datasource="dataTableMotorcycles" trigger="columnTogglerMotorcycles"/>
            </f:facet>

            <p:column sortBy="#{motorcycle.manufacturer}" headerText="Manufacturer">
                <h:outputText value="#{motorcycle.manufacturer}">
                </h:outputText>
            </p:column>

            <p:column sortBy="#{motorcycle.model}" headerText="Model">
                <h:outputText value="#{motorcycle.model}">
                </h:outputText>
            </p:column>

            <p:column sortBy="#{motorcycle.year}" headerText="Year">
                <div style="text-align: center;">
                    <h:outputText value="#{motorcycle.year}">
                        <f:convertDateTime pattern="yyyy"/>
                    </h:outputText>
                </div>
            </p:column>

            <p:column headerText="Colours">
                <div style="text-align: center;">
                    <p:selectOneMenu id="selectOneMenuColour" value="#{motorcycleController.currentColour}"
                                     converter="omnifaces.SelectItemsConverter"
                                     rendered="${motorcycle.colours.size() > 0}"
                                     valueChangeListener="#{motorcycleController.selectedColourChanged}">
                        <f:selectItems value="#{motorcycle.colours}" var='colours'
                                       itemValue="#{colours.colour}"
                                       itemLabel="#{colours.colour}"/>
                        <p:ajax event="valueChange" execute="@this" update=""></p:ajax>
                    </p:selectOneMenu>
                </div>
            </p:column>

            <p:column headerText="In Production">
                <div style="text-align: center;">
                    <h:outputText value="Yes" rendered="#{motorcycle.inProduction}"></h:outputText>
                    <h:outputText value="No" rendered="#{!motorcycle.inProduction}"></h:outputText>
                </div>
            </p:column>

            <!-- <ui:include src="getEngines.xhtml"/> -->

            <p:column sortBy="#{motorcycle.engine.type}" headerText="Engine Type">
                 <div style="text-align: center;">
                     <h:outputText value="#{motorcycle.engine.type}">
                     </h:outputText>
                 </div>
             </p:column>

             <p:column sortBy="#{motorcycle.engine.displacement}" headerText="Capacity">
                 <f:facet name="header">
                     <h:outputText value="Engine Capacity"/>
                 </f:facet>
                 <div style="text-align: center;">
                     <h:outputText value="#{motorcycle.engine.displacement}">
                         <f:convertNumber maxFractionDigits="0" />`
                     </h:outputText>
                 </div>
             </p:column>


             <p:column sortBy="#{motorcycle.engine.capacityUnit}" headerText="Capacity Unit">
                 <div style="text-align: center;">
                     <h:outputText value="#{motorcycle.engine.capacityUnit}">
                     </h:outputText>
                 </div>
             </p:column>


             <p:column sortBy="#{motorcycle.engine.bore}" headerText="Bore">
                 <div style="text-align: center;">
                     <h:outputText value="#{motorcycle.engine.bore}">
                         <f:convertNumber maxFractionDigits="0" />
                     </h:outputText>
                 </div>
             </p:column>


            <p:column sortBy="#{motorcycle.engine.boreMeasurement}" headerText="Bore Measurement">
                <div style="text-align: center;">
                    <h:outputText value="#{motorcycle.engine.boreMeasurement}">
                    </h:outputText>
                </div>
            </p:column>


           <p:column sortBy="#{motorcycle.engine.stroke}" headerText="Stroke">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.stroke}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.strokeMeasurement}" headerText="Stroke Measurement">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.strokeMeasurement}">
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.distribution}" headerText="Distribution">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.distribution}">
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maxiumPowerHp}" headerText="Power HP">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maxiumPowerHp}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maxiumPowerKilowatt}" headerText="Power Kw">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maxiumPowerKilowatt}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maxiumPowerRpm}" headerText="Power RPM">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maximumTorqueRpm}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maximumTorque}" headerText="Torque">
               <f:facet name="header">
                   <h:outputText value="Torque"/>
               </f:facet>
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maximumTorque}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maximumTorqueUnit}" headerText="Torque Unit">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maximumTorqueUnit}">
                   </h:outputText>
               </div>
           </p:column>

           <p:column sortBy="#{motorcycle.engine.maximumTorqueRpm}" headerText="Torque RPM">
               <div style="text-align: center;">
                   <h:outputText value="#{motorcycle.engine.maximumTorqueRpm}">
                       <f:convertNumber maxFractionDigits="0" />
                   </h:outputText>
               </div>
           </p:column>

        </p:dataTable>
    </h:form>
</h:body>

</f:view>

..

6) Sample bean

@nAmed
@RequestScoped
@path(FORWARD_SLASH)
public class MotorcycleController {

/**
 *
 */
private static final int ZERO = 0;

/**
 *
 */
public static String[] motorcycleManufacturers;

/**
 *
 */
public static List<Motorcycle> motorcycleList;

/**
 *
 */
public static List<MotorcycleFields> motorcycleFieldsList;

/**
 *
 */
private final Logger logger = LoggerFactory.getLogger(this.getClass());

/**
 *
 */
private String currentColour;

/**
 *
 */
private String selectedColour;

/**
 *
 */
@Inject
private MotorcyclesEJB motorcyclesEJB;

/**
 *
 */
public MotorcycleController() {
}

/**
 * @return List
 */
public List<Motorcycle> getAllMotorcycles() {
    if (this.motorcycleList == null) {
        logger.info(">>>>> getAllMotorcycles motorcycleList = {}", this.motorcycleList);
        motorcycleList = motorcyclesEJB.getAllMotorcycles();
    } else {
        logger.info(">>>>> getAllMotorcycles motorcycleList = {}", this.motorcycleList.size());
    }

    return motorcycleList;
}

/**
 * @return List
 */
public List<MotorcycleFields> getAllMotorcycleFields() {
    if (this.motorcycleFieldsList == null) {
        logger.info(">>>>> getAllMotorcycles motorcycleFieldsList = {}", this.motorcycleFieldsList);
        motorcycleFieldsList = motorcyclesEJB.getAllMotorcyclesFields();
    } else {
        logger.info(">>>>> getAllMotorcycles motorcycleFieldsList = {}", this.motorcycleFieldsList.size());
    }

    return motorcycleFieldsList;
}

/**
 * @param valueChangeEvent ValueChangeEvent
 */
public List<Motorcycle> selectedManufacturerChanged(ValueChangeEvent valueChangeEvent) {
    logger.info(">>>>> selectedManufacturerChanged valueChangeEvent getNewValue =  {}", valueChangeEvent.getNewValue());

    MotorcycleController.motorcycleManufacturers = (String[]) valueChangeEvent.getNewValue();
    logger.info(">>>>> selectedManufacturerChanged motorcycleManufacturers =  {}", (Object) MotorcycleController.motorcycleManufacturers);

    //for (int x = ZERO; x < MotorcycleController.motorcycleManufacturers.length; x++) {
    //    logger.info(">>>>> selectedManufacturerChanged motorcycleManufacturers =  {}",  MotorcycleController.motorcycleManufacturers[x]);
    //}

    return motorcyclesEJB.getAllMotorcycles();
}

/**
 * @param valueChangeEvent ValueChangeEvent
 */
public void selectedColourChanged(ValueChangeEvent valueChangeEvent) {
    logger.info(">>>>> selectedColourChanged valueChangeEvent getOldValue = {}", valueChangeEvent.getOldValue());
    logger.info(">>>>> selectedColourChanged valueChangeEvent getNewValue = {}", valueChangeEvent.getNewValue());
}

/**
 * @return Response
 */
@GET
@Produces(MediaType.APPLICATION_JSON)
@Path(GET_ALL_MOTORCYCLES)
public Response getAllMotorcyclesJSON() {
    logger.info(">>>>> getAllMotorcyclesJSON motorcyclesEJB {}", motorcyclesEJB);

    List<Motorcycle> motorcycleList = motorcyclesEJB.getAllMotorcycles();
    logger.info(">>>>> getAllMotorcyclesJSON motorcycleList = {}", motorcycleList.size());
    String json = "";

    return Response.ok(json, MediaType.APPLICATION_JSON).build();
}

// @get
// @Produces(MediaType.APPLICATION_JSON)
// @path(GET_ALL_MOTORCYCLES_FIELDS)
// public Response getAllMotorcyclesFieldsJSON() {
// logger.info(">>>>> getAllMotorcyclesFieldsJSON motorcyclesEJB {}", motorcyclesEJB);

// List motorcycleFieldsList = motorcyclesEJB.getAllMotorcyclesFields();
// logger.info(">>>>> getAllMotorcyclesFieldsJSON motorcycleFieldsList = {}", motorcycleFieldsList.size());
// String json = "";

// return Response.ok(json, MediaType.APPLICATION_JSON).build();
// }

/**
 * @return String
 */
public String getCurrentColour() {
    return currentColour;
}

/**
 * @param currentColour String
 */
public void setCurrentColour(String currentColour) {
    this.currentColour = currentColour;
}

/**
 * @return String
 */
public String getSelectedColour() {
    return selectedColour;
}

/**
 * @param selectedColour String
 */
public void setSelectedColour(String selectedColour) {
    this.selectedColour = selectedColour;
    logger.info(">>>>> setSelectedColour selectedColour = {}", selectedColour);

}

}
..
Screen 1:

@NOTiFYcouk NOTiFYcouk changed the title columnToggler: (just) Selected Columns not displayed columnToggler: (Not just) Selected Columns not displayed Jan 28, 2019

@NOTiFYcouk NOTiFYcouk changed the title columnToggler: (Not just) Selected Columns not displayed columnToggler: Unselected Columns being displayed Jan 28, 2019

@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 29, 2019

I was able to reproduce this.

Reproducible test case:
pf-4477.zip

Just run "mvn clean jetty:run-exploded" and navigate to http://localhost:8080/primefaces-test/test.xhtml

@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 29, 2019

I submitted a simple fix. I just looked at what Sort was doing and it was calling $this.updateColumnsView(); to repaint the visible columns. I simply added that same line to a successful completion of a Paginate request.

tandraschko added a commit that referenced this issue Jan 29, 2019

Merge pull request #4480 from melloware/PF4477
Fix #4477: Datatable paginator must update UI columns upon paging.

@tandraschko tandraschko added the defect label Jan 29, 2019

@tandraschko tandraschko added this to the 7.0 milestone Jan 29, 2019

@tandraschko

This comment has been minimized.

Copy link
Member

tandraschko commented Jan 29, 2019

thanks @melloware

@NOTiFYcouk

This comment has been minimized.

Copy link
Author

NOTiFYcouk commented Jan 29, 2019

@melloware Thanks very much. I'll give it a go ASAP.

@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 29, 2019

No problem let me know if it works for you.

@NOTiFYcouk

This comment has been minimized.

Copy link
Author

NOTiFYcouk commented Jan 30, 2019

When I deploy 6.2.15 I get in the console:

20:42:31,766 INFO [org.primefaces.webapp.PostConstructApplicationEventListener] (ServerService Thread Pool -- 90) Running on PrimeFaces 6.2.15

I've built the Master branch it created: primefaces-7.0-SNAPSHOT.jar Java JAR file - 5.2 MB

When I deploy my build using te new JAR nothing is shown in the log and when try & bring the page I get:

javax.el.ELException: /getListMotorcycles.xhtml: The class 'com.gostophandle.controller.MotorcycleController' does not have the property 'selectedManufacturerChanged'.
at com.sun.faces.facelets.compiler.AttributeInstruction.write(AttributeInstruction.java:95)
at com.sun.faces.facelets.compiler.UIInstructions.encodeBegin(UIInstructions.java:83)
at com.sun.faces.facelets.compiler.UILeaf.encodeAll(UILeaf.java:211)
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176)
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:918)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1905)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1908)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:491)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:194)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151)
at javax.faces.application.ViewHandlerWrapper.renderView(ViewHandlerWrapper.java:151)
at org.omnifaces.viewhandler.OmniViewHandler.renderView(OmniViewHandler.java:115)

@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 30, 2019

Are you positive you have a proper PUBLIC setter and getter for selectedManufacturerChanged in MotorcycleController

@NOTiFYcouk

This comment has been minimized.

Copy link
Author

NOTiFYcouk commented Jan 30, 2019

Works fine with 6.x.xx & 7.0.RC1

<p:selectCheckboxMenu id="selectCheckboxMenuManufacturer"
     value="#{manufacturerController.selectedManufacturers}"
      valueChangeListener="#{motorcycleController.selectedManufacturerChanged}"

the bean method:

/**
    *
    * @param valueChangeEvent ValueChangeEvent
    * @return List
    */
   public List<Motorcycle> selectedManufacturerChanged(ValueChangeEvent valueChangeEvent) {
       logger.info(">>>>> selectedManufacturerChanged valueChangeEvent getNewValue =  {}", valueChangeEvent.getNewValue());

       MotorcycleController.motorcycleManufacturers = (String[]) valueChangeEvent.getNewValue();
       logger.info(">>>>> selectedManufacturerChanged motorcycleManufacturers =  {}", (Object) MotorcycleController.motorcycleManufacturers);

       return motorcyclesEJB.getAllMotorcycles();
   }
@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 31, 2019

Try 7.0.RC2 which was just released it has this column toggler fix in it.

@NOTiFYcouk

This comment has been minimized.

Copy link
Author

NOTiFYcouk commented Jan 31, 2019

Perfect. Working as expected:

13:27:30,948 INFO [org.primefaces.webapp.PostConstructApplicationEventListener] (ServerService Thread Pool -- 87) Running on PrimeFaces 7.0.RC2

Thanks for the excellent support.

@melloware

This comment has been minimized.

Copy link
Contributor

melloware commented Jan 31, 2019

And the column toggle fix is working for you as expected?

@NOTiFYcouk

This comment has been minimized.

Copy link
Author

NOTiFYcouk commented Jan 31, 2019

Exactly as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment