In FXML Controller, fxml fields are null, only the action responds [duplicate] - intellij-idea

Maybe a really newbie's question....
I'm starting learning JavaFX in a FMXL Application using the Scene Builder, by reading this tutorials:
http://docs.oracle.com/javase/8/javafx/get-started-tutorial/fxml_tutorial.htm
So once i applied some changes, an issue with this 2 IDs came up... I might have missed or confused something about them...
Can anyone tell me in which cases they are used one or another?

id you use to set a CSS ID to your Component, for example <Text id="welcome-text" .../> and in your stylesheet you have something like #welcome-text { font-size: 16pt; } so this will be applied to your Text.
fx:id you use if you want to work with your Components in your Controller class, where you annotate them with #FXML Text myWelcomeText.

The fx:id is the identity associated to component in fxml to build a controller, and the id is used for css.

I took a look at an FXML document generated using the JavaFX Scene Builder. You access controls from Java Controller with the fx:id. (edit) I stand corrected, the id does matter.
You can apply css from the FXML document like this:
<Slider id="css_id" fx:id="myslider" styleClass="style_name" .../>
(Replace slider with any control)
And Java controller interaction:
#FXML
Slider myslider;

In JavaFX id is used to set a CSS ID to a component. And fx:id is used for accessing that component in code (i.e. in a controller class). fx:id works like a components name.

Related

Does OutletService support dynamically adding component in button handler

i used this.outletService.add('BottomHeaderSlot', factory, OutletPosition.BEFORE); during the search button click handler to add a custom component in the BottomHeaderSlot. I intended to add searchOverlay under the header to add customized search behavior.
But my custom component is not shown under the header after calling outletService.add. I refered to this https://sap.github.io/cloud-commerce-spartacus-storefront-docs/outlets/ . Does outletService support dynamic adding component during runtime?
Following is my button handler
open(): void {
const factory = this.componentFactoryResolver.resolveComponentFactory<SearchOverlayComponent>(SearchOverlayComponent);
this.outletService.add('BottomHeaderSlot', <any>factory, OutletPosition.BEFORE);
this.cd.markForCheck();
That's a good question. At the moment it is a not a feature supported from our outlets.
A solution you could do is inject the component in a more static manner (either CMS or outlet when the app initializes like seen here https://github.com/SAP/cloud-commerce-spartacus-storefront/blob/develop/projects/storefrontlib/src/cms-components/asm/services/asm-enabler.service.ts)?
Your component could then be wrapped with an <ng-container *ngIf="open$ | async></ng-container> where open$ is an observable for the state of the search box. That way the component only appears in the dom when the searchbox is open.
The idea of dynamically adding a components through outlets is a good one we will keep in mind. I will open an issue on Github as an improvement.

Aurelia - dynamically create custom element in a view-model

I have an Aurelia app where a user can click on a button and create a new tab. The tab and its content (a custom element) do not exist on the page before the user clicks the button. I am generating the HTML for the content at runtime (via Javascript) in my view model.
I keep seeing mention of using the template engine's compose or enhance functions, but neither are working for me. I don't know how I would use the <compose> element (in my HTML) since I am creating the element based on the user clicking a button.
My thought was that the button has a click.delegate to a function that does ultimately does something like
const customElement = document.createElement('custom-element');
parentElement.appendChild(customElement);
const view = this.templatingEngine.enhance({
element : customElement,
container : this.container, // injected
resources : this.viewResources, // injected
bindingContext: {
attrOne: this.foo,
attrTwo: this.bar,
}
});
view.attached();
But all this does is create an HTML element <custom-element></custom-element> without actually binding any attributes to it.
How can I create a custom element analogous to <custom-element attr-one.bind="foo" attr-two.bind="bar"></custom-element> but via Javascript?
As you pointed out in your own answer, it's the missing resources that caused the issue. One solution is to register it globally. That is not always the desired behavior though, as sometimes you want to lazily load the resources and enhance some lazy piece of HTML. Enhance API accepts an option for the resources that you want to compile the view with. So you can do this:
.enhance({
resources: new ViewResources(myGlobalResources) // alter the view resources here
})
for the view resources, if you want to get it from a particular custom element, you can hook into the created lifecycle and get it, or you can inject the container and retrieve it via container.get(ViewResources)
I found the problem =\ I had to make my custom element a global resource.

Does the windowClass property or NgbModalOptions actually do anything?

I am opening an NgbModal passing a TemplateRef to create the dialog body, and passing in a custom class via the windowClass property of the NgbModalOptions object that I pass to the open() method. I define the class in a referenced styleUrl in the component and am serving the modal via an injectable service in the component. The modal is loading fine, and I can see the class name when I inspect the DOM, but the class appears to have no bearing on the modal. I would like to use it to customize the size of the modal (css is defined to affect the child div where the size is set), but I have also played with properties that I can see in the Styles tab of the Chrome dev tools, but cannot see it affecting anything. When I inspect in Firefox dev tools, I can find the CSS as an inline style sheet and it has a reference to the ngContent identifier assigned by Angular, so I am assuming that is does not affect the entire document, nor those parts added by ng-bootstrap that constitute the modal wrapper. Has anyone been able to make this work successfully? I am at my wit's end. I would even be happy if I could get an ElementRef of the modal-header dive, but since I am using a template (which is not fully loaded in the DOM at init time) I have not been able to. One of my requirements is that we do all DOM manipulation via Angular to maintain platform independence in the project ... so no jQuery. Any thoughts? And thanks in advance!!
I use windowClass and size attributes of NgbModalOptions to customize the modal. Sample code follows:
this.modalService.open(<your_template_ref_var>, {size: 'lg', windowClass: 'modal-adaptive-s1'});
Whereas
.modal-adaptive-s1 .modal-lg {width: 400px !important; max-width: 400px;}

Xpages, Bootstrap and Data Views

I have a Data View in an Xpage application which is using the Bootstrap theme. I started to use a View, but could never get the pagers lines up, and the data view is working better.
But I do not understand where to put my table class css. For example, if I want a stripped table I enter "table table-striped" in the styleClass of the view (or maybe it is the dataStyleClass). If I do that in the styleClass of the data view, I do not get strips.
I tried the suggestion from Mark below, but something is not working. I added a script call and used the id of the tableview. It already has a class of "cleearfix table" on it.
I have added Chrome's web inspector to show what is going on.
The xe:dataView control does have a styleClass attribute, but classes that you set there are added to the div element that wraps the dataview, not the table (and that's where Bootstrap needs the table-striped class. I would solve this with some JavaScript to add the classes you need on the table element
<xp:scriptBlock
id="scriptBlock1">
<xp:this.value><![CDATA[
$("table.dataview").addClass("table-striped table-hover")
]]></xp:this.value>
</xp:scriptBlock>

JavaFX 2 define onChange listener in FXML

I am busy teaching myself FXML.
I'm doing this by following this example.
It's a simple text editor.
However, in the tutorial everything is Java code.
I myself am using FXML to seperate the view of the logic.
I currently face the following challenge:
I have defined an TextArea in my FXML like so:
<TextArea id="taTextArea" fx:id="taContent" wrapText="true" />
Usually you add action listeners using onAction="#actionName"
What I want to know is, how can I do something similar for text changes. So I can detect wether a save is needed, modify the status bar label etc.
I want to avoid having to attach the TextArea to a change listener in the init method of the controller(implementing Initializable).
Also.. when I complete this application, I will write a blog about it.
With the lacking FXML documentation, I think itll be helpfull to other newbies.
So I want my code to be as clean as possible.
EDIT 1
No progress yet. I need to know if theres a thing such as code completion in FXML
So I can check what kind of properties I can use in FXMl. There should be a textLength property. In the provided link the author uses lengthProperty.addListener. I need an FXML equivilant
You could use the onKeyPressed property:
onKeyPressed="#textChanged"
which calls the textChanged method in the specified controller.
For the second question: The best reference for FXML currently is the javadoc of JavaFX, since all properties are listed there.