Uploaded image for project: 'Kuali Rice Development'
  1. Kuali Rice Development
  2. KULRICE-9159

Show/hide active rows on a collection doesn't work

    Details

    • Type: Task
    • Status: Closed
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.2.1
    • Fix Version/s: 2.2.4
    • Component/s: Development
    • Security Level: Public (Public: Anyone can view)
    • Labels:
      None
    • Rice Module:
      KRAD
    • Application Requirement:
      Rice
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required
    • Include in Release Notes?:
      Yes

      Description

      Displaying toggle button to display inactive records of a collection doesn't work.

      The “show/hide active” toggle on collection calls the UifControllerBase.toggleInactiveRecordDisplay the show/hide indicator gets set correctly and the collection is processed via CollectionGroupBuilder.performCollectionFiltering.

      In 2.2 I noticed that this performCollectionFiltering was called a second time on this collection and another collection of the page that shouldn’t be updated. During this second time the show/hide indicator is back to its original state and thus preventing from it to function correctly. This doesn’t happen in 2.1. I investigated further and found a difference in UifWebUtils.postControllerHandle of 2.1 and UifControllerHelper.postControllerHandle of 2.2. The class was renamed and refactored between the branches and what changed in the postControllerHandle looks quite significant.

      In 2.1 it only continues processing if the full view is updated. So in the show/hide case it just returns at that point. However, in 2.2 this check doesn’t exist and it keeps on building the view.

        Attachments

          Issue Links

            Activity

            Hide
            jdomeyer Jeff Domeyer (Inactive) added a comment -

            The reason this doesn't work is because it is trying to pass the information about whether to show or hide through the view between the controller method invoked and the postControllerHandle of UifControllerHelper.

            The postControllerHandle's prepareViewForRendering will use ComponentFactory.getNewInstanceForRefresh which is going to grab the initial component state of the collection in which the show inactive is set to false. No matter what you do, that's going to be the result.

            What I did to hack around this problem is the following:

            krad.response.js line 138 change:

            jQuery("#" + id).css('display', 'none');
            

            to

            jQuery("#" + id).css('display', 'true');
            

            Otherwise the collections will disappear from lightboxes

            UifActionDefinitions line 145:

            p:additionalSubmitData="showInactiveRecords:true">
            

            to

            p:additionalSubmitData="showInactiveRecords:false">
            

            We actually want to toggle, not always show inactive no matter which button we click on.

            UifGroupDefinitions.xml line 931ish
            The 2 items in the Uif-InactiveItemsActionsGroup need some additional attributes in order to actually refresh the collection properly. (This solves the problem you noticed with the processing of unrelated collections)

            <bean parent="Uif-ShowInactiveCollectionItemsButton"
                          p:render="@{!#collectionGroup.showInactiveLines and #collectionGroup.renderInactiveToggleButton}"
                          p:additionalSubmitData="showInactiveRecords:true,reqComponentId:@{#component.context['collectionGroup'].id}"
                          p:refreshId="@{#collectionGroup.id}"/>
                    <bean parent="Uif-HideInactiveCollectionItemsButton"
                          p:render="@{#collectionGroup.showInactiveLines and #collectionGroup.renderInactiveToggleButton}"
                          p:additionalSubmitData="showInactiveRecords:false,reqComponentId:@{#component.context['collectionGroup'].id}"
                          p:refreshId="@{#collectionGroup.id}"/>
            
            

            And finally for the hack we need to add the following code (The removal of the performComponentLifecycle here gets rid of the double processing)
            UifControllerBase - toggleInactiveRecordDisplay(...)

            // update inactive flag on group
                    collectionGroup.setShowInactiveLines(showInactive);
            
            		// This part is to hack into the initial component states which is what
            		// the component refresh is going to use in order to render the
            		// collection group
            		 if(uifForm.getPostedView().getViewIndex().getInitialComponentStates().containsKey(collectionGroup.getBaseId())){
            		 	uifForm.getPostedView().getViewIndex().getInitialComponentStates().remove(collectionGroup.getBaseId());
            		 }
            		 collectionGroup.setBaseId(null);
            		 uifForm.getPostedView().getViewIndex().addInitialComponentStateIfNeeded(collectionGroup);
            		 //End of the hack
                         
                    // run lifecycle and update in view
            //        uifForm.getPostedView().getViewHelperService().performComponentLifecycle(uifForm.getPostedView(), uifForm,
            //                collectionGroup, collectionGroupId);
                    
                    return getUIFModelAndView(uifForm);
            

            This hack skips the view lifecycle part inside the toggle method, as the postControllerHandle will perform the component lifecycle itself. Then extra logic is inserted to for the initial component state of the collection group to have a new copy with the showinactive boolean set to the toggled value. In other words, we're faking out the view to change what it thought was previously rendered.

            This is what is necessary to do as long as a ComponentFactory.getNewInstanceForRefresh is being used in the postControllerHandle.

            Good luck!

            Show
            jdomeyer Jeff Domeyer (Inactive) added a comment - The reason this doesn't work is because it is trying to pass the information about whether to show or hide through the view between the controller method invoked and the postControllerHandle of UifControllerHelper. The postControllerHandle's prepareViewForRendering will use ComponentFactory.getNewInstanceForRefresh which is going to grab the initial component state of the collection in which the show inactive is set to false. No matter what you do, that's going to be the result. What I did to hack around this problem is the following: krad.response.js line 138 change: jQuery( "#" + id).css('display', 'none'); to jQuery( "#" + id).css('display', ' true '); Otherwise the collections will disappear from lightboxes UifActionDefinitions line 145: p:additionalSubmitData= "showInactiveRecords:true" > to p:additionalSubmitData= "showInactiveRecords:false" > We actually want to toggle, not always show inactive no matter which button we click on. UifGroupDefinitions.xml line 931ish The 2 items in the Uif-InactiveItemsActionsGroup need some additional attributes in order to actually refresh the collection properly. (This solves the problem you noticed with the processing of unrelated collections) <bean parent= "Uif-ShowInactiveCollectionItemsButton" p:render= "@{!#collectionGroup.showInactiveLines and #collectionGroup.renderInactiveToggleButton}" p:additionalSubmitData= "showInactiveRecords:true,reqComponentId:@{#component.context['collectionGroup'].id}" p:refreshId= "@{#collectionGroup.id}" /> <bean parent= "Uif-HideInactiveCollectionItemsButton" p:render= "@{#collectionGroup.showInactiveLines and #collectionGroup.renderInactiveToggleButton}" p:additionalSubmitData= "showInactiveRecords:false,reqComponentId:@{#component.context['collectionGroup'].id}" p:refreshId= "@{#collectionGroup.id}" /> And finally for the hack we need to add the following code (The removal of the performComponentLifecycle here gets rid of the double processing) UifControllerBase - toggleInactiveRecordDisplay(...) // update inactive flag on group collectionGroup.setShowInactiveLines(showInactive); // This part is to hack into the initial component states which is what // the component refresh is going to use in order to render the // collection group if (uifForm.getPostedView().getViewIndex().getInitialComponentStates().containsKey(collectionGroup.getBaseId())){ uifForm.getPostedView().getViewIndex().getInitialComponentStates().remove(collectionGroup.getBaseId()); } collectionGroup.setBaseId( null ); uifForm.getPostedView().getViewIndex().addInitialComponentStateIfNeeded(collectionGroup); //End of the hack // run lifecycle and update in view // uifForm.getPostedView().getViewHelperService().performComponentLifecycle(uifForm.getPostedView(), uifForm, // collectionGroup, collectionGroupId); return getUIFModelAndView(uifForm); This hack skips the view lifecycle part inside the toggle method, as the postControllerHandle will perform the component lifecycle itself. Then extra logic is inserted to for the initial component state of the collection group to have a new copy with the showinactive boolean set to the toggled value. In other words, we're faking out the view to change what it thought was previously rendered. This is what is necessary to do as long as a ComponentFactory.getNewInstanceForRefresh is being used in the postControllerHandle. Good luck!
            Hide
            jkneal Jerry Neal (Inactive) added a comment -

            All,

            What should be happening is the show and hide inactive buttons call the method toggleInactiveRecordDisplay on UifControllerBase. It should get the id of the associated collection and the 'showInactiveRecords' request parameter (set to true by the show button, false by the hide button). It then gets a new collection group, sets the showInactiveLines property, and runs the lifecycle.

            The problem is, this component is not used! This is the old way of doing component refreshes. Now when we return the component refresh is done by the helper class. Which does not get the request parameter update like Jeff explained.

            I am going to take a look and see what we can do. We'll need a general strategy for handling these sort of things in the future.

            thanks,
            Jerry

            Show
            jkneal Jerry Neal (Inactive) added a comment - All, What should be happening is the show and hide inactive buttons call the method toggleInactiveRecordDisplay on UifControllerBase. It should get the id of the associated collection and the 'showInactiveRecords' request parameter (set to true by the show button, false by the hide button). It then gets a new collection group, sets the showInactiveLines property, and runs the lifecycle. The problem is, this component is not used! This is the old way of doing component refreshes. Now when we return the component refresh is done by the helper class. Which does not get the request parameter update like Jeff explained. I am going to take a look and see what we can do. We'll need a general strategy for handling these sort of things in the future. thanks, Jerry
            Hide
            jkneal Jerry Neal (Inactive) added a comment -

            I reworked this to use client side state functionality. Examples added to the component library.

            Claus, do you have the 2.2 branch checked out? If so, would you mind to apply a patch for this?

            thanks,
            Jerry

            Show
            jkneal Jerry Neal (Inactive) added a comment - I reworked this to use client side state functionality. Examples added to the component library. Claus, do you have the 2.2 branch checked out? If so, would you mind to apply a patch for this? thanks, Jerry
            Hide
            jkneal Jerry Neal (Inactive) added a comment -

            Patch file for branch

            Show
            jkneal Jerry Neal (Inactive) added a comment - Patch file for branch
            Hide
            cniesen Claus Niesen added a comment -

            We are in the 2.2.2 code freeze till Thursday. Should put in before then?

            Show
            cniesen Claus Niesen added a comment - We are in the 2.2.2 code freeze till Thursday. Should put in before then?
            Hide
            jkneal Jerry Neal (Inactive) added a comment -

            Right, this is marked for 2.2.3 so I assume we should wait until after 2.2.2 is released.

            thanks,
            Jerry

            Show
            jkneal Jerry Neal (Inactive) added a comment - Right, this is marked for 2.2.3 so I assume we should wait until after 2.2.2 is released. thanks, Jerry
            Hide
            cniesen Claus Niesen added a comment -

            Ok,I'll commit it after the freeze is over.
            Thanks Jerry.

            Show
            cniesen Claus Niesen added a comment - Ok,I'll commit it after the freeze is over. Thanks Jerry.

              People

              • Assignee:
                cniesen Claus Niesen
                Reporter:
                cniesen Claus Niesen
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: