Skip to content
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

update in b:commandButton fired but region not updated #891

Closed
turbobrick opened this issue Nov 28, 2017 · 14 comments
Closed

update in b:commandButton fired but region not updated #891

turbobrick opened this issue Nov 28, 2017 · 14 comments

Comments

@turbobrick
Copy link

turbobrick commented Nov 28, 2017

Hey guys,

I'm experimenting an issue in a special scenario when a commandButton, right when I try to refresh a form after an onclick event has finished its execution.

<b:commandButton value=""
                 onclick="ajax:panel.delete()"
                 update="myform">
    <f:param name="param" value="#{myparam}"/>
</b:commandButton>

The onclick event is fired and succesfully exeucted, but the form is not refreshed. The commandButton is a button generated per entry in a c:forEach, and is used to delete the given item from the DB. I have the exact same syntax in another page but as a single button outside any c:forEach and it works.

The loop is contained inside b:container > div 'main' > div > {here}

@chongma
Copy link
Collaborator

chongma commented Nov 28, 2017

Have you tried <b:commandButton action="#{panel.delete}"> <f:param name="param" value="#{myparam}"/><f:ajax render="@form"/></b:commandButton>

@turbobrick
Copy link
Author

Yes I did, which is pretty strange that neither the native ajax approach works.

@chongma
Copy link
Collaborator

chongma commented Nov 29, 2017

incidentally why are you using c:forEach and not ui:repeat? can you post a more complete code sample? is there no stack trace indicating an error? maybe try <b:commandButton>...<f:setPropertyActionListener target="#{panel.param}" value="#{myparam}"/>...</b:commandButton> replacing f:param where the bean has e.g. private MyParam param; public MyParam getParam() {return param;}public void setParam(MyParam param) {this.param = param;} param should be accessible inside delete function

@turbobrick
Copy link
Author

turbobrick commented Nov 29, 2017

As far as I can see, the event is fired and the region updated, but no changes are seen. Checking the Firefox inspector you can see that when you hover over "mainform", which is the one containing all the elements, it's like displaced to the left, it doesn't glow the right area, it's a little bit off to the left, like there's another ghost form in there.

@chongma
Copy link
Collaborator

chongma commented Nov 29, 2017

can you post more code? like the form <h:form>...All this...</h:form>

@turbobrick
Copy link
Author

turbobrick commented Nov 29, 2017

There you go.

<h:body>
  <h:form id="mainform">
    <b:button/>
    <b:container id="mycontainer">
      <div id="mylist">
        <c:if>
          <div style="margin-bottom: 10px;">&zwnj;</div>
          <p style="text-align: center;"></p>
        </c:if>
        <c:otherwise>
          <c:forEach>
            <div style="margin-top: -5px;">
              <b:jumbotron>
                <b:column span="2">
                  <img></img>
                </b:column>
                <b:column span="7">
                  <div id="content">
                    <b:row>
                    </b:row>
                    <b:row>
                    </b:row>
                    <b:row>
                      <c:forEach>
                        <c:if>
                        </c:if>
                        <c:otherwise>
                        </c:otherwise>
                      </c:forEach>
                    </b:row>
                  </div>
                </b:column>
                <b:column span="3">
                  <b:commandButton value="CONFIG" look="default"
                           action="#{panel.action}"
                           oncomplete="$('.config_modal').modal()">
                    <f:ajax render="otherform"/>
                  </b:commandButton>
                  <b:commandButton value="DELETE"
                           action="#{panel.delete}"
                           update="mycontainer">
                    <f:param name="test" value="#{bean.test}"/>
                  </b:commandButton>
                </b:column>
              </b:jumbotron>
            </div>
          </c:forEach>
        </c:otherwise>
      </div>
    </b:container>
  </h:form>
  ...
</h:body>

@turbobrick turbobrick changed the title update in b:commandButton not being fired update in b:commandButton fired but region not updated Nov 29, 2017
@chongma
Copy link
Collaborator

chongma commented Nov 29, 2017

firstly you should move the container outside the h:form. please read https://showcase.bootsfaces.net/layout/basic.jsf particularly Every BootsFaces page should have a <b:container />. That's the component providing the generous white space around your payload area. As a rule of thumb, everything must be put in a container, and every BootsFaces page needs a container. But only one. Don't try to nest containers.

you are using jstl a lot. it is recommended to use ui:repeat instead of c:forEach. and use the rendered attribute (there is one in ui:fragment) instead of c:if and c:otherwise. also if you use c:if ( c:when?) and c:otherwise you should wrap in a c:choose

@stephanrauh
Copy link
Collaborator

stephanrauh commented Nov 29, 2017

Two ideas:

  • First, I wonder about the "it's like displaced to the left" bit. Can you please have a look at the HTML code before and after the AJAX request? I suspect there's a div tag that's added after each request. This kind of error become more clearly visible if you click several times, because then there are many identical nested div tags.

  • Maybe @chongma is up to something. The problem with c:if and c:forEach is that these statements are evaluated at load time. In many cases, that's too early. For instance, AJAX requests aren't properly dealt with because they can't deal with c:forEach and c:if. If can only guess, but I gather your button is meant to delete a row. The java code is executed, and the c:forEach shows the array with one element less.

Only it doesn't. c:forEach has been executed much earlier, at load time, so it's not affected by the modified Java bean. It still displays the original number of rows.

Another problem with c:forEach is that it can't deal with the ids of the component correctly. ui:repeat adds the loop index to the id of the component, thus making it unique. AFAIK c:forEach fails to do so in many cases. However, I didn't test this, so don't take my word for it :).

@turbobrick
Copy link
Author

turbobrick commented Nov 30, 2017

Hey guys, thanks for the quick feedback.

I've just modified the page with the suggestions you've just made to me and nothing has changed, the region isn't updated.

@stephanrauh I've been checking the HTML code before and after its execution and nothing has changed, I can't see any extra divs. Maybe is a modal or something else what's causing the issue?

My actual code is the following one...

<b:container>
		<h:form id="mainform">
			<b:button />
			<div id="list">
				<c:choose>
					<c:when>
						<div>&zwnj;</div>
						<p>
							<h:outputText/>
						</p>
					</c:when>
					<c:otherwise>
						<ui:repeat var="st" value="#{bean.items}">
							<div style="margin-top: -5px;">
								<b:jumbotron
									style="border-radius: 0px; height: 200px; margin-bottom: 0px;">
									<b:column span="2">
										<img src="${st.img}">
										</img>
									</b:column>
									<b:column span="7">
										<div id="content" style="margin-top: 25px; margin-left: 50px;">
											<b:row>
												<font />
											</b:row>
											<b:row >
												<b:badge value="${st.property}" />
												<h:outputText />
												<b:badge value="${st.property}" />
												<h:outputText />
											</b:row>
											<b:row >
												<ui:repeat var="anotheritem" value="#{st.items}">
													<c:choose>
														<c:when>
															<b:label/>
														</c:when>
														<c:otherwise>
															<b:label/>
														</c:otherwise>
													</c:choose>
												</ui:repeat>
											</b:row>
										</div>
									</b:column>
									<b:column span="3">
										<b:commandButton 
											action="#{bean.action(item)}"
											oncomplete="$('.a_modal').modal()">
											<f:ajax render="aform" />
										</b:commandButton>
										<b:commandButton
											action="#{bean.delete}" update="mainform">
											<f:param/>
										</b:commandButton>
									</b:column>
								</b:jumbotron>
							</div>
						</ui:repeat>
					</c:otherwise>
				</c:choose>
			</div>
		</h:form>
	</b:container>
```xml

@chongma
Copy link
Collaborator

chongma commented Nov 30, 2017

can you remove the c:choose and change the c:when for <ui:fragment rendered="whatever was test in c:when"> and the c:otherwise for <ui:fragment rendered="opposite of whatever was test in c:when">. i hope that makes sense.

also...have you tried changing b:commandButton for an h:commandButton just as a test?

@turbobrick
Copy link
Author

@chongma I've also changed all the c:when for ui:fragment in all the places I had it and still the same situation as before. And also same scenario with h:commandButton, I'm getting the same behaviour as I did with the b:commandButton

@chongma
Copy link
Collaborator

chongma commented Dec 1, 2017

did you try using <b:commandButton action="#{bean.delete}"><f:setPropertyActionListener/><f:ajax render="@form"/> </b:commandButton> instead of <b:commandButton action="#{bean.delete}" update="mainform"> <f:param/> </b:commandButton>
is the code on github or somewhere? without looking at it directly it is hard to figure out the problem.

@chongma
Copy link
Collaborator

chongma commented Dec 1, 2017

also aform is not nested within the main form is it?

@stephanrauh
Copy link
Collaborator

I'll close the ticket now because we haven't heard from @turbobrick since November.

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

No branches or pull requests

3 participants