Communication between Portlets

I’ve been following this tutorial http://techcommunity.softwareag.com/documents/portlet_file_entry/10157/caf_search_app_tutorial.pdf/2209b019-6dff-4cc6-a2fe-2303abcc0c85.

I have 1 portlet with SearchBar and another portlet with SearchResult, tied together in administration panel (like in the tutorial). There is a clear button near the search bar - it clears every text input inside a search bar portlet. I would want it to clear all the data inside search result portlet, is that possible? The data in search portlet is populated from database connectors.

I tried to add a reference to SearchResult bean and do something with it but it was performing operations on SearchBar portlet, something like getSearchResult().goToPage(“something/default.view”) and it changed page on SearchBar portlet, not SearchResult. I even tried to execute an empty query from a custom action, but it didn’t work. Read something about portlet URLs but I couldn’t figure out how to use them in this case, and it’s seems overcomplicated for such problem.

Well, the searchbar portlet builds the query string and passes that value to the search result portlet via portlet preference wiring.

So if you want to want to re-render the search result portlet without any query executed (i.e. the “Ready to Search” state), you would simply have to set the source of the wiring (i.e. the “lastSearchState” portlet preference of the searchbar portlet) back to empty and then re-render the search result portlet so it would use that new information.

One way to accomplish that would be to provide a custom implementation of the “Clear Action” that sets the lastSearchState preference value back to null and attach a client-side “action complete listener” to the clear button that refreshes the other portlet.

For example, add this method to your page bean java class:

	/**
	 * Custom impl of the 'clear' action that also resets the
	 * lastSearchState value to null
	 */
	public String doCustomClear() {
		try {
			//clear the lastSearchState value
			getSearchBar().setLastSearchState(null);
		} catch (Exception e) {
			error(e);
		}
		
		//delegate to the original impl for the rest
		SearchBar searchBarControl = getSearchBarControl();
		SearchBarControlBean controlBean = searchBarControl.getControlBean();
		return controlBean.clearSearchForm();
	}

And then modify the “Clear Form Action” property of the searchbar control to bind to the doCustomClear method.

And then you can add a “Script Block” control to the searchbar portlet whose content would be something like this:

// lookup the client-side model for the 'Clear' button
var m = CAF.model('#{caf:cid("searchBarControl:clearSearchFormButton")}');
if (m) {
    // if already exists, remove the old listener
    if (window.refreshSearchBar) {
        m.removeActionCompleteListener(window.refreshSearchBar);
    }
    
    // define callback function to invoke after the 'clear' action has completed
    window.refreshSearchBar = function(id) {
        // lookup the client-side model for the form in the searchresult portlet
        // NOTE: the value before # is the alias of the search result portlet
        var m2 = CAF.model('#{caf:cid("searchapp_test1.searchresult#searchResultsForm")}');
        if (m2) {
             // refresh the content of the search result portlet
             m2.refresh();
        }
    };
    
    // start listening.
    m.addActionCompleteListener(window.refreshSearchBar);
}