1

I am trying to display images from database and some entities can have many images some only one , so to make it easy I want to let user change pictures with button.

Here is code:

<ui:composition template="layout.xhtml">

        <ui:define name="content">
            <h:form id="form">


                #{flatJsfService.loadData(0,10)}
                <ui:repeat var="flat" value="#{flatJsfService.getListOfFlats()}" varStatus="status" >
                        <div class="container-fluid" >
                            <div class="row">
                                <div class="col-sm-4">

                                    <p:imageSwitch effect="wipe" widgetVar="switcher" id="manuelSwitcher"
                                                   slideshowAuto="false">
                                        <ui:repeat value="#{fileJsfService.getImages(flat.id)}" var="idd">
                                            <p:graphicImage  value="#{fileJsfService.image}"  style="width: 100%;height: auto;">
                                                <f:param name="fileId" id="fileId" value="#{idd}" />
                                            </p:graphicImage>
                                        </ui:repeat>
                                    </p:imageSwitch>
                                    <p:commandButton type="button" onclick="PF('switcher').previous();"
                                                     icon="pi pi-caret-left" id="prev" style="margin-bottom: 5px"/>
                                    <p:commandButton type="button" onclick="PF('switcher').next();"
                                                     icon="pi pi-caret-right" id="next" style="margin-bottom: 5px"/>


                                </div>

                                <div class="col-sm-8 ">
                                  some info
                                </div>
                            </div>

                        </div>

                </ui:repeat>


            </h:form>
        </ui:define>
    </ui:composition>

I used two ui:repeat , first for get all flats and second all images of flat.

When I display images they are displaying just under previous image, why <p:imageSwitch> doesn't work?

*primefaces version: 6.2.

jsf 2.2.13.

xmlns:p="http://primefaces.org/ui".*

Here is picture of page: What I have

FileJsfService two methods I Am using :

  public StreamedContent getImage() throws IOException {
        FacesContext context = FacesContext.getCurrentInstance();

        if(context.getCurrentPhaseId()==PhaseId.RENDER_RESPONSE){
            return new DefaultStreamedContent();
        }else{
            String flatid = context.getExternalContext().getRequestParameterMap().get("fileId");
            File file = fileRepository.findById(Long.valueOf(flatid)).get();
            byte[] data=file.getData();

//            return new DefaultStreamedContent(new ByteArrayInputStream(data));
            return DefaultStreamedContent.builder().contentType(file.getType()).name(file.getFileName())
                    .stream((SerializableSupplier<InputStream>) new ByteArrayInputStream(data)).build();

        }

            // So, browser is requesting the image. Return a real StreamedContent with the image
    }

    public List<String> getImages(long id){
        Flat flat = flatRepository.findById(id).get();
        List<File> files = flat.getFiles();
        List<String> ids = new ArrayList<String>();
        for(File file:files)
            ids.add(file.getId().toString());
        return ids;
    }
Danik
  • 115
  • 1
  • 2
  • 12
  • I think your issue might be `ui:repeat` inside of a `ui:repeat:`. Can you try it without the outer `ui:repeat`. Also PF 6.2 is getting quite old as 8.0 has been released. – Melloware Oct 10 '20 at 14:24
  • Maybe compare your code with showcase example: https://www.primefaces.org/showcase/ui/multimedia/switch.xhtml ??? – Melloware Oct 10 '20 at 14:33
  • @Melloware i also thought about ui:repeat inside of a ui:repeat but no , I created another page without outer ui:repeat and it didn't work – Danik Oct 10 '20 at 14:33
  • it's almost same, only difference I have f:param ,because of another problem(getting same images for each flat) – Danik Oct 10 '20 at 14:35
  • 1
    I would create a reproducible example using PF Test: https://github.com/primefaces/primefaces-test If you can reproduce it then i would say submit a bug on the PrimeFaces GitHub issues page. – Melloware Oct 10 '20 at 14:43
  • Did you try changing the `ui:repeat` to a `c:forEach`? I had some similiar problems when is was nesting `ui:repeat`s. – fuggerjaki61 Oct 11 '20 at 09:08
  • @fuggerjaki61 I don't know proper way to use c:forEach so I first changed outer ui:repeat to c:forEach it didn't show any images and later I changed inner ui:repeat , it gave me error that id which I am taking from outer ui:repeat element is null – Danik Oct 11 '20 at 11:33

2 Answers2

2

It's a discrepancy between the timing of the ui:repeat tag and f:param tags. f:param is a build-time component, so it goes first. At the time that it's executing, ui:repeat isn't active, so #{idd} isn't available to use. By the time ui:repeat kicks in, it's too late - f:param has been built without the necessary data.

Replace ui:repeat with c:forEach. c:forEach runs during the same phase of the view tree build as f:param. It's a drop-in replacement:

<c:forEach items="#{fileJsfService.getImages(flat.id)}" var="idd">
   <p:graphicImage  value="#{fileJsfService.image}"  style="width: 100%;height:auto;">
      <f:param name="fileId" id="fileId" value="#{idd}" />
   </p:graphicImage>
</c:forEach>

Related:

kolossus
  • 20,559
  • 3
  • 52
  • 104
  • Thank you, but when I replaced ui:reapeat to c:forEach it gave me an error that flat.id is null , so I changed also outer ui:repeat to c:forEach, now it's not even calling methods from fileJsfService Bean. – Danik Oct 20 '20 at 16:30
  • Post the definition of your `fileJsfService` here @Danik. You're not loading that data in a getter or something are you? – kolossus Oct 20 '20 at 16:47
  • I added 2 methods which is not calling when I change every ui:repeat to c:forEach – Danik Oct 21 '20 at 12:32
  • 1
    [Don't](https://stackoverflow.com/questions/14567920/request-parameter-is-null-during-postback/14570012#14570012) do business logic in [getters](https://stackoverflow.com/questions/15773350/initialization-of-list-in-a-jsf-managed-bean/15774143#15774143). It leads to unpredictable bugs and inconsistent behavior @Danik – kolossus Oct 21 '20 at 12:43
  • I found an problem ,its in – Danik Oct 26 '20 at 12:17
0

I have solved my problem , first problem was that I had to put in layout.xhtml into <ui:insert - <h:outputStylesheet and add <script in main page this way :
<ui:define name="script"><h:outputScript library="js" name="jquery-3.5.1.min.js"/> </ui:define>

Danik
  • 115
  • 1
  • 2
  • 12