Does wicket lose hold of the HTML components after a rearrangement through JavaScript? - wicket

I have a repeating component in wicked which needs to be added and deleted as per the user requirement. The maximum number of component is predefined. So I am adding the components at start up and hiding and showing based on need. I am required to change the arrangement of the components in the HTML markup when there is any deletion of the component. I use JavaScript for this. I want to know if wicket would lose hold of the components if I do this.
<div wicket:id="borrowerTabs" id="borrowerTabs">
<span wicket:id="borrowerTab1" id="borrowerTab1" ></span>
<span wicket:id="borrowerTab2" id="borrowerTab2" ></span>
<span wicket:id="borrowerTab3" id="borrowerTab3" ></span>
<span wicket:id="borrowerTab4" id="borrowerTab4" ></span>
<button wicket:id="addBorrower" id="addBorrower" type="button"></button>
<button wicket:id="deleteBorrower" id="deleteBorrower" onclick="updateUIForDeleteBorrower()" type="button"></button>
</div>
If delete the borrowerTab3, contents inside borrowerTab4 will be replacing the contents inside borrowerTab3 and the model objects too will be swapped though I do not do a target.add(borrowerTab3). Now while form submission, I am not getting the values of the fields inside borrowerTab3.

I'm not sure if it helps but try component.setVisible(false) in your java code to hide it.

Related

Conditional processing within a Sightly/HTL component dependent upon position within a page

I've recently begun as an Ops dev on an AEM project, and we have a component (a table, that has a title, some copy and a field where the author can author some HTML to represent the contents of a table, with and elements. This, for whatever reason, has to sit within a component, called ArticleContainer. The title should have an H1 tag if the table is at the top of the page, and an H2 tag if it's anywhere lower down. I've tried using data-sly-test thus:
<sly data-sly-test.topOfPage="${table.firstPosition==true}">
<h1 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>
</sly>
<sly data-sly-test="${!topOfPage}">
<h2 data-sly-test="${table.headerCopy}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h2>
</sly>
Now, this kind of processing has worked elsewhere where the component doesn't sit within a container, but it seems that if it's in a container it always picks up the non-topOfPage condition. I assume there might be a way to maybe do the test within the container component & pass it down into the table component? How would one go about this, or if it's not possible, is there another method by which one might achieve this?
There are two things here:
What does table.firstPosition return? You should be able to debug this in your Sling Model or POJO and probably need to adjust the logic to account for intermediary containers.
HTL/Sightly has a data-sly-element that allows you to change the HTML element based on an expression, you could make your code shorter (and easier to maintain):
<h1 data-sly-test="${table.headerCopy}" data-sly-element="${table.firstPosition ? 'h1' : 'h2'}" class="heading fontH2 headingLinear headingThick">
<span class="tableHeadingWrapper">${table.headerCopy # context='html'}</span>
</h1>

#circlon/angular-tree-component: How to customize checkbox template

I want to use custom templates for the tree nodes as shown here on their website
https://angular2-tree.readme.io/docs/templates
But I also need the checkbox tri-state functionality as demonstrated here
https://angular2-tree.readme.io/docs/tri-state-checkboxes
In this custom treeNodeFullTemplate example they have a checkbox as part of the template but it doesn't have the tri-state relationship between the parents and children. Is there a way to have a custom checkbox and keep all the correct event listeners etc.? I can't seem to find any documentation on the checkboxes API if there is one.
<tree-root id="tree" [focused]="true" [nodes]="nodes">
<ng-template #treeNodeFullTemplate let-node let-index="index" let-templates="templates">
<div class="tree-node">
<input type="checkbox" [checked]="node.isActive" (change)="node.toggleActivated(true)" />
<tree-node-expander [node]="node"></tree-node-expander>
<div
class="node-content-wrapper"
[class.node-content-wrapper-active]="node.isActive"
[class.node-content-wrapper-focused]="node.isFocused"
(click)="node.toggleActivated(true)">
<span [class]="node.data.className + 'Index'">{{ index }}</span>
<span [class]="node.data.className" [class.title]="true">{{ node.data.title }}</span>
</div>
<tree-node-children [node]="node" [templates]="templates"></tree-node-children>
</div>
</ng-template>
</tree-root>
I can see that the (change) method on the checkbox is not right but do I need to write my own one to get the parent and children and determine state on click? It seems strange that I can't just tap into an existing API.

Change Component's content during rendering phase when loading its model fails

I have a widget components with simple markup inheritance like so
AbstractWidget
<wicket:panel>
<wicket:child />
<div wicket:enclosure="editButton" class="widget-edit-wrapper">
<button wicket:id="editButton" type="button" class="widget-edit">
<span class="glyphicon glyphicon-cog"></span>
</button>
<div style="display:none;">
<div wicket:id="editPanel" class="widget-settings"></div>
</div>
</div>
</wicket:panel>
LabelWidget
<wicket:extend>
<div wicket:id="container" class="label-widget flex-container">
<div wicket:id="label"></div>
</div>
</wicket:extend>
Now imagine the label content is taken from a loadable detachable model and loading the model throws an Exception.
I need to show some feedback to the user on this 'broken' widget component. Is there a way to replace the whole child's content when loading its model throws an Exception?
Note that LabelWidget is just one from many AbstractWidget childs so I need to solve this in the AbstractWidget and I also need to preserve all elements from the AbstractWidget component.
You can accomplish this by using a smarter model - a model that delegates to the original one and try/catches if it throws an exception. In case of an exception you will need to return an "empty" model object, where "empty" would mean different things for your different use cases.
Your smart model could implement IComponentAssignedModel so that it knows the Component it is used in. This way in the catch clause you can do component.error("..."). In AbstractWidget you should add a FeedbackPanel that will render the error message. The specialization widget, like LabelWidget, will render as "empty" (whatever this means for it) by using the fallback model.

Create repeatable custom form fields in web2py?

I want to create twitter bootstrap compliant form. According to the docs for Twitter Bootstrap v2.2.2 (the version included with web2py) the html should look like:
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="inputEmail">Email</label>
<div class="controls">
<input type="text" id="inputEmail" placeholder="Email">
</div>
</div>
...
I'm currently using SQLFORM which outputs html that doesn't really fit with this (even using formstyle='divs'). Besides I want my html output to be clean without web2py artifacts such as class="w2p_fl". So my thought is to use a custom form. However in doing this there would be a lot of repeated code. That is, the following would basically need to be repeated for each field.
{{=form.custom.begin}}
<div class="control-group">
{{=LABEL(form.custom.label['myfield'], _class='control-label',
_for='mytable_myfield')}}
<div class="controls">{{=form.custom.widget.myfield}}</div>
</div>
...
{{=form.custom.end}}
So how can I repeat the above unit of code so I could replace it with something like {{=bootstrap_field(db.mytable.myfield)}} or some other way to adhere to DRY?
What is the web2py way to do this? Create a view function? Pass a function in the dictionary returned by the controller? Create my own html helper? Create my own widget? Another way?
If you're using Bootstrap 2, you can just do:
form = SQLFORM(..., formstyle='bootstrap')
For Bootstrap 3 (or any other custom formstyle you'd like to create), the formstyle argument can be a function (or other callable) that produces the form DOM. The function will be passed the form and a fields object, which is a list of tuples, with each tuple containing a CSS id, label, input element, and (possibly empty) comment/help text. To get an idea of what such a function should look like, check out the one used for Bootstrap 2 forms.

Dynamic String in UiBinder (not for i18n)

I'm trying to make a Widget that generalizes a bootstrap style from twitter for collapsible items.
I got to make it work hardcoding it, but I find some dificulties abstracting it.
The widget looks like:
<div class="accordion" id="accordion1">
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="#accordion1" href="#collapseOne">
... text to show collapsed ...
</a>
</div>
<div id="collapseOne" class="accordion-body collapse">
<div class="accordion-inner">
... anything to show expanded ...
</div>
</div>
</div>
</div>
The thing is, this uses a javascript which depends on ids of some div tags. The generalized widget would need this to be randomized or depending on some seed passed in the constructor.
It would also be nice to have access to those generated Strings from Java part, as it would be a fancy way to set the text showing in the widget.
My first approach was to use something like <ui:with type="com.a.b.c.IdGenerator" field="idGenerator"></ui:with> but it seems to instanciate dynamically the class IdGenerator so no access to the Strings is obtained in Java part.
Is there any fancy way to dinamically generate those Strings having access to them from the Java part?
You simply need a #UiField IdGenerator idGenerator on the Java side to have the instance created by the <ui:with> injected in it (or you can #UiField(provided = true) it).