Control Wicket wizard's flow by setting setComplete(boolean) - wicket

Hey there I'm still trying to improve a customized Wicket Wizard to display the steps with following states: active, completed, pending. Therefore the information of isCompleted(); should return the right value. Refering to a previous question, isComplete(); returns true, if the wizard can go to the next step.
How can I manipulate this information to get the full advantage of my draft? E.g. in one WizardStep I have multiple input fields.
super(new ResourceModel("daten.title"), new ResourceModel("daten.summary"));
java.util.Collections.addAll(sprachen, "Deutsch","English","Français","Italiano");
add(name = new RequiredTextField<String>("name", Model.of("")));
add(vorname = new RequiredTextField<String>("vorname", Model.of("")));
add(strasse = new RequiredTextField<String>("strasse", Model.of("")));
add(ort = new RequiredTextField<String>("ort", Model.of("")));
...
I don't want the step to "be completed" until each field is filled out. To check the condition I'd have to add an AjaxListener to each component and check for it's state to setComplete(boolean);. Can I control this flow from outside the wizard form? For example with an implementation of ICondition or is there another way? Because basically I can't go to the next step, because all of my textfields are RequiredTextField and cannot be skipped.
Any suggestions are highly appreciated.
Update / Solution
Component buttonbar = getForm().get(Wizard.BUTTONS_ID);
buttonbar.setOutputMarkupId(true);
Just get(Wizard.BUTTONS_ID); won't work.
Thanks to Sven Meier for the hint!

You'll have to add an AjaxFormComponentUpdatingBehavior to all your form components.
Then override #onEvent() in your wizard:
public MyWizard(id, WizardModel model) {
super(id, model);
get(Wizard.BUTTONS_ID).setOutputMarkupId(true);
}
public void onEvent(IEvent<?> event) {
if (event.getPayload() instanceof AjaxRequestTarget) {
((AjaxRequestTarget)event.getPayload()).add(get(Wizard.BUTTONS_ID));
}
}
Let your step#isComplete() return true depending on its model values, this way the wizard buttons will always be up to date.

Related

Example showing Multi Edit in Nattable

I have a requirement wherein on a single click in the cell, normal editing must be possible and on double clicking in the cell a dialog should open for editing the cell. The two are possible individually. I see a method "boolean supportMultiEdit(IConfigRegistry configRegistry, List configLabels)" but there is no example to show the working. Has anyone used it or can show it's configuration.
Multi edit means it is possible to edit multiple cells at once. This is of course done in an editor, as it makes no sense to perform multi edit inline. You should rather have a look at openInline(IConfigRegistry, List<String>) or even better the EditConfigAttributes#OPEN_IN_DIALOG to solve what you are looking for.
But you are actually seeking for a way to handle opening an editor differently on different UI interactions. So you need to register the corresponding UI bindings. This is already discussed in the NatTable Forum.
And the EditorExample shows quite a lot of possible configuration options available for editing. And almost every editable example shows multi editing capabilities. You simply need to select multiple cells you want to edit and then start typing or pressing F2.
The following code would do the trick with a configuration based on a label that is added in the UI binding action:
public class OpenEditorConfiguration extends AbstractRegistryConfiguration {
#Override
public void configureRegistry(IConfigRegistry configRegistry) {
configRegistry.registerConfigAttribute(
EditConfigAttributes.OPEN_IN_DIALOG,
Boolean.TRUE,
DisplayMode.EDIT,
"open_in_dialog");
}
#Override
public void configureUiBindings(UiBindingRegistry uiBindingRegistry) {
uiBindingRegistry.registerDoubleClickBinding(
new CellEditorMouseEventMatcher(GridRegion.BODY),
new IMouseAction() {
#Override
public void run(NatTable natTable, MouseEvent event) {
int columnPosition = natTable.getColumnPositionByX(event.x);
int rowPosition = natTable.getRowPositionByY(event.y);
ILayerCell cell = natTable.getCellByPosition(columnPosition, rowPosition);
cell.getConfigLabels().add("open_in_dialog");
natTable.doCommand(new EditCellCommand(
natTable,
natTable.getConfigRegistry(),
cell));
}
});
}
}

How can I use a zk-chart on click?

I have a great problem with ZK charts!
I have 2 type of chart: a chart with data of the current day (so this chart is generated automatically) and a chart with data of a clicked date.
The first chart works correctely, the second not!
If I have clicked on a date, I build a graph! But it's impossible to modify the label position or name of label! And I need to modify these things. This is my graph:
<charts width="1700" style="height: 400px" type="line" model="#bind(vm.chart2)" title="">
</charts>
When I clicked I call this method:
#Command
#NotifyChange("chart2")
public ChartsModel viewGraph(#BindingParam("self") Group self){
String a = self.getLabel();//this is for passed a parameter
ServiceImpl usr = new ServiceImpl();
chart2 = usr.viewGraph(a);
return chart2;
}
viewGraph is so built:
#Override
public ChartsModel viewGraph(String data) {
//chart2 = new Charts();
chart2.setModel(LineLabelsData.setCategoryModel2(data));
chart2.getXAxis().getLabels().setRotation(180);
chart2.getYAxis().getTitle().setText("TEXT");
chart2.getTooltip().setEnabled(false);
chart2.getXAxis().getLabels().setRotation(180);
LinePlotOptions linePlotOptions =
chart2.getPlotData().getPlotOptions().getLine();
linePlotOptions.setEnableMouseTracking(false);
linePlotOptions.getDataLabels().setEnabled(true);
return chart2.getModel();
}
If I print something in this method my console view it correctely! The problem is that
chart2.getYAxis().getTitle().setText("TEXT");
does not work like
chart2.getXAxis().getLabels().setRotation(180);
How can I change that values?
To change yAxis title, you can simply call chart2.getYAxis().setTitle("title");
You may want to post your questions in ZK Forum rather than stackoverflow as our community users are experienced in ZK, and can help you quicker.

Symfony 2 Forms - add new item to Collection server-side, depending on button clicked

I have a form which contains a Collection of an unspecified number of subforms. I want to have functionality allowing the user to add a new, blank item to the Collection for them to fill in. The Symfony docs tell us how to do this using Javascript clientside to add new blank form controls, which are then submitted and persisted as normal, but I'd like to do it serverside in the controller, without Javascript.
The problem I'm encountering is to do with the way Symfony Forms work. I have an "Add" button added to my main form, and I intend to detect whether it is that button which has been clicked, so that I can add the blank item to the Collection and re-render the form. But to detect the click I need to call $this->createForm and at that point the form is fixed with the original set of items, it's too late to add an extra one.
//Symfony Action
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
$form->handleRequest($request);
//Ideally I'd somehow do this test earlier, but I need $form to do it...
if ($form->get('add')->isClicked() )
{
//TOO LATE!
$person->getSelections()->add(new Selection() );
}
if ($form->isValid())
{
if ($form->get('save')->isClicked() )
{
//Persist
}
}
//Render page etc
Things I've thought about:
Putting the Add button in a completely different form on the same page, which submits to a different Action which can then do some preparatory work before forwarding to the main Action above
Inspecting submitted HTTP data directly to note that Add has been clicked (shame not to use the standard Symfony method)
Give up and use Javascript as suggested (it might work in this example, but I'd like to have the option of carrying out server-side activity (without AJAX...) as part of adding the new blank item)
How can I best achieve this in a proper Symfony way?
EDIT Just seen this: https://github.com/symfony/symfony/issues/5231, which is essentially a feature request to allow what I'm after. One suggestion a commenter makes is to add a blank item to the Collection and then remove it if it's not needed - I don't know how one would do that, but it sounds promising.
ANOTHER EDIT It occurs to me that, because I need two different aspects of the $form I'm creating, I could maybe just make the $form, use it to handle the request, detect the button click, and then throw that $form away, before altering my model and creating another $form. I don't know if that would somehow fall foul of some rules about handling the submission twice.
I'm not 100% but I think you could do the following...
//Symfony Action with (Request $request, ...)
//A Person has many Selections
$person = $this->getPerson($id)
//All fields are frozen at this point, according to data in $person!
$form = $this->createForm(new SelectionsType($lookups), $person);
if ($request->isMethod('POST')) {
$form->submit($request);
if ($form->get('add')->isClicked()) {
// Add thing
} elseif ($form->isValid()) {
// or
// } elseif ($form->get('save')->isClicked() && $form->isValid()) {
// Persist and what not
}
}
//Render page etc
I haven't tested it so I don't know whether it will trigger the form errors (or if it will actually work) so if it does (or it doesn't) I apologise.
What I did in the end was have my Add button hit a separate Action, which then delegates to the main action with a flag to say "add a new Selection", as below:
public function selectionsAddAction(Request $request, $id)
{
return $this->selectionsAction($request, $id, true);
}
public function selectionsAction(Request $request, $id, $addNew = false)
{
$person = $this->getPerson($id);
//Also use "add mode" if we just deleted the last one!
if (!$person->getSelections()->count())
{
$addNew = true;
}
//$addNew is set by a separate action, hit by a different form with the Add button in
if ($addNew)
{
$person->getSelections()->add(new Selection() );
}
//We now have the right number of items, and can build the form!
$form = $this->createForm(new SelectionsType($lookups), $person);
//...
}

GXT ComboBox unselect after selection

I have a GXT ComboBox which is bound to a ListStore and has a addSelectionHandler that is called which is working fine. I have also used the combo.setEmptyText("Select an item..").
But, when the user makes a selection I'd like to have the ComboBox return to its' "no selection" state. How can I have it return to show the "Select an item.."?
StProperties props = GWT.create(StProperties.class);
ListStore<St> sts = new ListStore<St>(combo.id());
combo = new ComboBox<St>(sts, props.name());
combo.setTypeAhead(true);
combo.setTriggerAction(TriggerAction.ALL);
addHandlersForEventObservation(combo,props.name());
...
combo.addSelectionHandler(new SelectionHandler<T>() {
public void onSelection(SelectionEvent<T> event) {
System.out.println("value selected:"+event.getSelectedItem());
// handle selection
// unselect item in combo here ---
}
});
It appears there is presently a bug in GXT 3 around this issue, as reported at http://www.sencha.com/forum/showthread.php?234736, present as of GXT 3.0.4. As reported in that bug, it seems that you can call first setValue(null), followed by redraw(true) then setText(null) on the field.
This also happens to a few other fields - based on the details of the report it seems probable that the bug is in TriggerField itself, so this workaround may be required for all subclasses.

What would be a good way of filtering a GWT CellList using multiple CheckBoxes?

Working in Google Web Toolkit (GWT) I am using a CellList to render the details of a list of Tariffs (using a CompositeCell to show a CheckBoxCell next to a custom cell of my own).
I want to filter the list by tariff length (12, 18, 24, 36 months etc). I would like to render a checkbox for each tariff length at the top of the list, and update the dataProvider as necessary when users uncheck and recheck a box.
I do not know in advance the set of tariff lengths, they will be extracted from the result set when the page is rendered. There could just be two (requiring two checkboxes), but possibly there could be 10 (requiring 10 checkboxes) - I only want to render a checkbox for each as needed.
So somehow I need to associate an int value with each checkbox, and then pass that int to a function that updates the list by removing all tariffs that match. I'm just not sure how to add the handler for the checkboxes and how to get the value for that particular box.
This is what I'm thinking:
// panel to hold boxes
private Panel contractLengthPanel = new HorizontalPanel();
textPanel2.add(contractLengthPanel);
// create a set of the terms, by looping the result set
Set<String> contractTerms = new HashSet<String>();
for(ElecTariff tariff : tariffs)
{
contractTerms.add(Integer.toString(tariff.getContractLength()));
}
// loop that set, creating a CheckBox for each value
for(String term : contractTerms)
{
CheckBox box = new CheckBox(term + " Months");
// set all boxes with the same name, and a unique id
box.getElement().setAttribute("name", "termBoxes");
box.getElement().setAttribute("id", "termBox" + term);
contractLengthPanel.add(box);
}
Now I'm not sure if I'm along the right lines here, but now I have each box as part of the same group (they have the same name) I would like to use that to add a handler that is called when a box is checked or unchecked, passing the box id (which contains the tariff length) to that function.
I hope this wasn't too confusingly written. Help appreciated.
There really is nothing like a "group of checkboxes" in HTML, and neither there is in GWT. There are kind of "groups of radiobuttons" though, but it's only about having their checked state mutually exclusive, it doesn't change anything to the way you work with them from code.
You have to listen to changes on each and every checkbox.
What you can do though is to use the same event handler for all your checkboxes; something like:
ValueChangeHandler<Boolean> handler = new ValueChangeHandler<Boolean>() {
#Override
public void onValueChange(ValueChangeEvent<Boolean> event) {
CheckBox box = (CheckBox) event.getSource();
String id = box.getFormValue();
boolean checked = box.getValue();
…
}
};
(note: I used getFormValue() rather than getElement().getId(); I believe it's a better choice: it's specifically made to associate a value with the checkbox)