6

Hi this is not strictly a question, I would like to share my solution to use the browser local storage with JSF2 and Primefaces.

I found very little information on using local storage with jsf2 and primefaces, so it seemed useful to share my work.

The backing bean:

@Component("pocLocalStorageBean")
@Scope(WebApplicationContext.SCOPE_REQUEST)
public class PocLocalStorageBean {

    private static final long serialVersionUID = 1L;

    private String[] selectedCities;
    private List<String> cities;

    @PostConstruct
    public void initialize() {
            List<String> cities = new ArrayList<String>();
            cities.add("Miami");
            cities.add("London");
            cities.add("Paris");
            cities.add("Istanbul");
            cities.add("Berlin");
            cities.add("Barcelona");
            cities.add("Rome");
            cities.add("Brasilia");
            cities.add("Amsterdam");

            setCities(cities);

    }

    //GETTER E SETTER HERE    
}

The page xhtml:

 <h:form id="yuorFormId" cache="false">

     <p:remoteCommand name="updateUiAfterLoadChoicesFromLocalStorage" update=":yuorFormId:yourSelectManyCheckboxId">
     </p:remoteCommand>
    <p:remoteCommand oncomplete="loadCitiesChoicesFromLocalStorage(#{pocLocalStorageBean.cities.size()});" autoRun="true">
     </p:remoteCommand>

    <div class="ui-g ui-fluid">

      <div class="ui-g-12 ui-md-12">

            <div class="card">

                    <p:selectManyCheckbox id="yourSelectManyCheckboxId" value="#{pocLocalStorageBean.selectedCities}" layout="responsive" columns="3">
                        <f:selectItems value="#{pocLocalStorageBean.cities}" var="city" itemLabel="#{city}" itemValue="#{city}"/>
                        <p:ajax oncomplete="setCitiesChoicesToLocalStorage(#{pocLocalStorageBean.cities.size()})"/>
                    </p:selectManyCheckbox>

                </div>

             </div>
        </div>

    </h:form>

And the javascript functions:

function findPreviousChoose(arrayChoicesFromLocalStorage,valueToFind){
    if(arrayChoicesFromLocalStorage != null && arrayChoicesFromLocalStorage.length > 0){
        var arrayLength = arrayChoicesFromLocalStorage.length;
        for (var j = 0; j < arrayLength; j++) {
            var iteratedChoose = arrayChoicesFromLocalStorage[j];
            if(iteratedChoose!=null){
                if(iteratedChoose.value == valueToFind){
                    return iteratedChoose;
                }
            }
        }
    }
    return null;
}

function parseSafeJSON(str){
    try {
        if(str!=null){
            var obj = JSON.parse(str);
            return obj;
        }
    } catch (ex) {
      return null;
    }
    return null;
}

function loadCitiesChoicesFromLocalStorage(citiesNumber){
    var arrayChoicesFromLocalStorageStringed = localStorage.getItem('CITIES_LOCAL_STORE_KEY');
    if(arrayChoicesFromLocalStorageStringed!=null){

        var arrayChoicesFromLocalStorage = parseSafeJSON(arrayChoicesFromLocalStorageStringed);
        var elementId = 'yuorFormId:yourSelectManyCheckboxId';
        var element = document.getElementById(elementId);

        var i;
        for (i = 0; i < citiesNumber; i++) {
            var elementIterated = document.getElementById(elementId+':'+i);
            var valueIterated = elementIterated.value;
            var previousChoose = findPreviousChoose(arrayChoicesFromLocalStorage,valueIterated);
            if(previousChoose != null) {
                elementIterated.defaultChecked = previousChoose.defaultChecked;
            }
        }

        //update the needed components:
        updateUiAfterLoadChoicesFromLocalStorage();

    }

}

function setCitiesChoicesToLocalStorage(citiesNumber) {

    var elementId = 'yuorFormId:yourSelectManyCheckboxId';
    var element = document.getElementById(elementId);

    var i;

    var arrayChoices = new Array();
    for (i = 0; i < citiesNumber; i++) {
        var elementIterated = document.getElementById(elementId+':'+i);
        var valueIterated = elementIterated.value;
        var defaultCheckedIterated = elementIterated.checked;
        var objIterated = { "value":valueIterated, "defaultChecked":defaultCheckedIterated};
        arrayChoices.push(objIterated);
    }

    var storageValuesArray = JSON.stringify(arrayChoices);
    localStorage.setItem('CITIES_LOCAL_STORE_KEY', storageValuesArray);

}

I also reported my solution to the primefaces forum: https://forum.primefaces.org/viewtopic.php?f=3&t=39051&p=180978#p180978

If you don't use primefaces but only jsf 2.3 it shoud work with h:commandScript instead of p:remoteCommand (but I have not tried):

How to invoke a JSF managed bean on a HTML DOM event using native JavaScript?

I don't know the solution for those who use jsf < 2.3 without primefaces (any suggestions for this scenario are welcome)

1

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.