Charm PopupView doing unnecessary layout pass? - gluon

I have a button which shows a choicelist as the content of a PopupView when it is pressed.
The content of the PopupView calculates its maxWidth based on the scene of the button.
Now I have noticed that switching Views results in a layout pass of thePopupView, although it's not showing. Since the scene is null at that time I get a NPE. This behaviour seems to be different from the Java PopupControl, so I wonder if this is intended?
EDIT
It seems the layout pass is triggered by an update of the ListView in the PopupView. When I switch the View I clear the items of the choicelist and the layout gets refreshed.
Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at com.energymeter.control.skin.ChoiceMenuSkin.computeMaxWidth(ChoiceMenuSkin.java:120)
at javafx.scene.control.Control.computeMaxWidth(Control.java:506)
at javafx.scene.layout.Region.maxWidth(Region.java:1451)
at javafx.scene.layout.Region.computeChildPrefAreaWidth(Region.java:1728)
at javafx.scene.layout.BorderPane.getAreaWidth(BorderPane.java:610)
at javafx.scene.layout.BorderPane.computePrefWidth(BorderPane.java:445)
at javafx.scene.Parent.prefWidth(Parent.java:915)
at javafx.scene.layout.Region.prefWidth(Region.java:1419)
at com.sun.javafx.scene.control.skin.ScrollPaneSkin.computeScrollNodeSize(ScrollPaneSkin.java:929)
at com.sun.javafx.scene.control.skin.ScrollPaneSkin.layoutChildren(ScrollPaneSkin.java:822)
at javafx.scene.control.Control.layoutChildren(Control.java:576)
at javafx.scene.Parent.layout(Parent.java:1087)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Parent.layout(Parent.java:1093)
at javafx.scene.Scene.doLayoutPass(Scene.java:552)
at javafx.scene.Scene$ScenePulseListener.pulse(Scene.java:2397)
at com.sun.javafx.tk.Toolkit.lambda$runPulse$30(Toolkit.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.tk.Toolkit.runPulse(Toolkit.java:354)
at com.sun.javafx.tk.Toolkit.firePulse(Toolkit.java:381)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:510)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:490)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$404(QuantumToolkit.java:319)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191)
at java.lang.Thread.run(Thread.java:745)

Related

I want to run aos fade up animation only once

When you enter the page for the first time, it should be fade up, but it's fade down. This problem seems to be caused by not only the fade-up effect when scrolling down the page, but also the fade-down effect when scrolling up the page. I only set the fade-up effect to the code.
How can I make it only fade up?
The web page and code are below.
https://www.dorothycard.com/v/48dc3e5f
<div class="mx-4" data-aos="fade-up" data-aos-duration="1500" data-aos-once=“true”>
When I inspect your page, all the animated elements have the following attribute:
data-aos-once=""true""
when that attribute should be:
data-aos-once="true"
The first sets the attribute to the string "true" which is quite different from the boolean true (which is what is expected).
I do not know how you set this attribute in your source, but you will want to look there for a fix to your issue.
Note that if you want ALL your animations in the page to only run once, you could also pass that option in the AOS.init() function call:
AOS.init({
// ... your other initialisation options here ...
once: true,
});
and you could then remove all individual data-aos-once attributes.

Xamarin custom control in a datatemplate created with CreateContent()

I have implemented a custom DataTemplateSelector according to: GitHub Xamarin Forms.
This allows for a datatemplate to be selected based on an item, which is received through a data binding. This works fine to select a proper datatemplate and render it. However, I am now at a point where I want to add custom controls to this datatemplate (custom buttons). This works on any other page, but for some reason not in this datatemplate.
The relevant lines in the datatemplate:
xmlns:controls="clr-namespace:Universal_ONE.Views.Controls"
<controls:IconButton Command="{Binding RobotLocationSave}"
Image="{StaticResource BoltBlack}"/>
The part the datatemplate is selected and created:
var templateToUse = templateSelector.SelectTemplate(item, null);
View view = (View)templateToUse.CreateContent();
view.BindingContext = bindingContext;
In the catch block I get the error (after calling CreateContent()):
Xamarin.Forms.Xaml.XamlParseException: Position 371:26. Type controls:IconButton not found in xmlns clr-namespace:Universal_ONE.Views.Controls
The problem has to be with the CreateContent(), since using the control outside of this datatemplate works.
EDIT 1
I've created a Minimal Working Example: GitHub.
The datatemplate is now hardcoded, so I'm sure that one is selected.
The same parseexception gets thrown.
I am trying to compile Xamarin.Forms myself so I can debug the framework itself. However, compiling is not going smooth; thus might take a bit longer.
EDIT 2
A bit more info on the MWE:
The MainPage.xaml has the default Xamarin.Forms app code. Below I've added a custom control, which is simply a frame with a label. The text of this label is set via a bindableproperty (not really relevant). Below this control is the datatemplatecontrol added, which in turn calls the datatemplateselector, which returns the datatemplate. This datatemplate contains the same control as the mainpage. Thus the rendered app should have 2 controls. However, in de datatemplatecontrol you can breakpoint on the catch statement (look for my comment). This is where the parseexception will show, which is caused after calling CreateContent() on the datatemplate.
EDIT 3
I've not been clear enough I think. But you have to put a breakpoint on line 41 of datatemplatecontroler.cs. Since the content of the datatemplate is set to null if the createcontent() fails, thus fails gracefully. When hitting the breakpoint you can read the parseexception.
EDIT 4
I've made an issue and a pull request on the Xamarin repository: GitHub. The problem resides with the XamlParser, which has a small bug where it selects the wrong assembly. Inside the issue I've mentioned a workaround which can be used for now.
I try to download your example and run it. When I run to Content = CreateTemplateForItem(ItemTemplate); the program does not report an error, so the program skips the catch method. Here is a screenshot of the runtime:
Then I tried to actively throw an exception in the try statement (throw new Exception();) to make the program enter the catch method, Here is a screenshot of the runtime:

JSF Command button F param goes missing on AJAX re-render of button - Workaround ActionListener

I am facing - and not for the first time i believe - JSF composite component re-render pain.
The issue I am facing sounds like it is pretty much the same as:
https://forum.primefaces.org/viewtopic.php?t=27870
Essentially I am reconverting an application from full page navigation to ajax navigation, to avoid reloading javascripts etc...
So this application has a bottom navigation menu, where each button is essentially composite component
composite:implementation
Based on the primefaces
p:commandButton
These buttons used to be non ajax, define the attribute action and return as output of the action the new XHTML page to navigate into.
You would get the full page and that would be it.
Now if we enable ajax based navigation, we instead get a nice little ajax p:commandd button.
<myTagLib:commandButton id="btn_#{pl.newPageLinkKey}" title="#{i18n.static[pl.newPageLinkKey]}"
action="#{box001.navigateToPageAjax}"
disabled="#{box001.selectedBoxPageLink eq pl.pageLink ? true : false}"
icon="#{box001.getIconByKey(pl.newPageLinkKey)}" value="#{i18n.static[pl.newPageLinkKey]}"
update=":pageForm:pageTitle :pageForm:footer-main :popupDialogRegion :pageForm:MainPageContent"
rendered="#{useAjaxPageNavigation}"
>
<f:param name="pageLink" value="#{pl.pageLink}" />
</mytaglib:commandButton>
Something along these lines.
So the first tive we navigate to this SINGLE page application and see our menu being rendered, if we go debug what the command button looks all nice and dandy.
The onclick action is all setup do a super nice ajax request with parameters...
PrimeFaces.ab({
s:"pageForm:mainMenuButtonsTouchBoxFramework:btn_controls:confirmSubmit",
u:"pageForm:pageTitle pageForm:footer-main popupDialogRegion pageForm:MainPageContent",
onco:function(xhr,status,args){boxFrameworkHelperJavascript.updateHeadPageTitle('Control / Events'); ;},
pa:[{name:"pageLink",value:"/blalallaba/WHATEVENEPAGE.xhtml"},{name:"pageLinkDummyValue1",value:"dummtValue001"}]
});
return false;
And these command buttons exist in hundreds of pages and they work perfectly 99 percent of the time.
But we see on complex pages with several layers of templates that the JSF composite components sometimes sart showing off arifacts on re-rendering...
So what comes next is the, pain.
We do our click on the button.
On the server side
FacesContext fc = FacesContext.getCurrentInstance();
Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
String pageLink = params.get("pageLink");
Is looking good.
But then... Re-render disaster.
The menu area, being updated :pageForm:footer-main, comes back with button looking selected. All the mnu buttons are there.
But voila, the problem is that our onclick event this time around is poor poor...
PrimeFaces.ab({
s:"pageForm:mainMenuButtonsTouchBoxFramework:btn_controls:confirmSubmit",
u:"pageForm:pageTitle pageForm:footer-main popupDialogRegion pageForm:MainPageContent",
onco:function(xhr,status,args){boxFrameworkHelperJavascript.updateHeadPageTitle('Control / Events'); ;}});return false;
See the difference between the two on clicks?
The PArguments are gone.
The composite:insert children our composite component is ignored on the re-rendering of the area.
<p:commandButton id="confirmSubmit"
style="display:none;"
ajax="#{cc.attrs.ajax}"
async="#{cc.attrs.async}"
global="#{cc.attrs.global}"
immediate="#{cc.attrs.immediate}"
oncomplete="#{func:object(cc.attrs.oncomplete)}"
onerror="#{func:object(cc.attrs.onerror)}"
onstart="#{func:object(cc.attrs.onstart)}"
onsuccess="#{func:object(cc.attrs.onsuccess)}"
partialSubmit="#{cc.attrs.partialSubmit}"
process="#{func:object(cc.attrs.process)}"
update="#{func:object(cc.attrs.update)}"
type="#{func:object(cc.attrs.type)}">
<composite:insertChildren/>
</p:commandButton>
Work around?
Yes... there is one.
A decent one luckily.
We can instead of make use of the attribute actionListener instead of action.
And we get away with this...
Why because instead of being dependent on having a proper ajax request to the server with all request parameter specified we get the parameter from the Server side view structure.
That is :
public void navigateToPageAjaxActionListener(ActionEvent actionListenerEvent) {
// (a) We use an action lister because we have problems with the composite component if we render it when we
// navigate from page to page
UIComponent component = actionListenerEvent.getComponent();
UIParameter param = (UIParameter) component.getChildren().get(0);
String pageLink = (String) param.getValue();
Not pretty and also not easily reproducible.
There are many pages where the re-rendering of such buttons do not corrupt the parameters.
Is this a known issue?
Is it a primefaces issue or a a JSF version issue.
JSF 2.2.8-35.jar.

Issue with navigateTo in NativeScript Vue modal

I am attempting to use navigateTo() within a modal in my NativeScript Vue application.
My modal components is wrapped in a <Frame>, which I understand is how to allow it to be a navigation controller. However, when I attempt to navigate to the sub-component of the modal, it actually opens behind the modal in the main frame.
You can see this behavior here: https://play.nativescript.org/?template=play-vue&id=azowAE&v=3
Click the "Open Modal" button and then click the "Show subpage" button. Seemingly nothing happens, but if you then click the "Close" button, you'll see the sub page opened behind the modal.
In order to navigate to a frame that is used in a modal, you should utilize the second argument to the $navigateTo method. This can reference a frame by reference or id. The easiest way I found was to give the frame in the modal an id:
<Frame id="modal-frame">...</Frame>
Then you can navigate inside the modal as as example
this.$navigateTo(OtherComponent, {frame: 'modal-frame'});
Note, you do not put a # in front of the ID like a CSS selector. Only the id value.
See for code reference: https://github.com/nativescript-vue/nativescript-vue/blob/master/platform/nativescript/plugins/navigator-plugin.js#L48
Another cause for this same issue is when the sub-component that the modal is navigating to isn't wrapped in a <Page> tag.
When you add a catch to your navigate code then it gives the following errors, depending on whether you use the ref or id.
this.$navigateTo(NewModal, {
frame: "frame-id" // or "frame-ref"
}).catch(e => console.log(e));
"frame-ref" throws TypeError: Cannot read property 'id' of undefined
"frame-id" throws TypeError: backstackEntry.resolvedPage.onNavigatingTo is not a function

Wicket replacing panel with ajax fails with MarkupNotFoundException

the page markup has
<div wicket:id="stepPanel" />
tag in it and when the page is first loaded it works great that is
add(new MyFirstPanel("stepPanel"));
works fine. But then when I trigger an Ajax event and request redrawing
addOrReplace(new MySecondPanel("stepPanel"));
target.add(MyPage.this);
i get the following error
Last cause: Failed to find markup file associated. MyFirstPanel: [MyFirstPanel [Component id = stepPanel]]
please note that it tries to find the wrong markup (should look for markup for MySecondPanel) and it fails regardless it succedded to do so before!
I instantiate panels using reflection, but could it be a problem here? No exceptions thrown.
Anwser:
Actually it was something else - I have noticed that one of my AjaxSubmitLinks had reference to a form that was no longer placed in a markup... so whatever you do just remember not to leave that reference.
You are adding MyPage after replacing the Panel causing MyPage to re-render.
There is a good example on how to replace panels here.
Yes you can call panels via reflection. I don't clearly know what you are trying to do with event here but if you want you can attach your panel with AjaxSelfUpdatingTimerBehavior and define the duration which will update this component in the given time period.
Hope its useful.

Resources