PropertyModel: what if it's target model changes? - wicket

The page has a model,I have done setDefaultModel(). I have a label added to the page:
Label name=new Label("name", new PropertyModel<String>(getDefaultModel(), "name"));
add(name);
Later, the page's model changes. But the property model's target model is still the original page's model.
What can I do to keep the property model updated when the target model changes?

Usually I advise against using setDefaultModel() or setModel(), exactly because of this type of problems.
Alternatively you can add another indirection:
new Label("name", new PropertyModel<String>(this, "defaultModel.name"));
... or with Wicket 8:
new Label("name", () -> ((Foo)getDefaultModel()).getName());

Related

Attaching Properties view to a custom XML Editor

I have created a custom editor in eclipse plugin which shows a XML in Tree-Table(TreeViewer) format with couple of its attributes. For showing remaining attributes I am trying to tie it up with "Properties View", but not really able to make progress on it.
I went through similar question on SO like
How to handle property sheet from customized editor in eclipse plugin development? where it talk about make your viewer contribute to workbench selection and implementing an IPropertySource on object which is selected in editor.
In my case I am directly setting an document object in treeviewer input like below.
IFileEditorInput editorInput = (IFileEditorInput) getEditorInput();
IFile inputIFile = editorInput.getFile();
File f = new File(inputIFile.getLocation().toString());
try {
doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
}
catch (SAXException | IOException | ParserConfigurationException e) {
e.printStackTrace();
}
//setting root element of doc as input
treeViewer.setInput(doc.getDocumentElement());
Now on what object should I implement an IPropertySource interface to contribute properties?
Let me know if I am going in right direction or missing something or doing it completely wrong.
Hope this make sense !!
When your selection provider fires a selection changed event the properties page will look at the new selection. If you are using a tree viewer as the provider the selection will be the current object from your tree content provider.
The properties view will try to get an IPropertySourceProvider from the selection. Your object can implement IPropertySourceProvider directly, or provide it view the IAdaptable interface or by using IAdapterFactory.
Once the view has the IPropertySourceProvier it will call the getPropertySource method. Your code must return an IPropertySource object - it is up to you to write this class.

sap.ui.layout.form.SimpleForm not updating data after updating Model

I have a form in sapui5, with empty entries and binded it with a model.
then a have a button "add data", when i press it I am setting some data to the model, which should papulate the form.
But it is not updating the form entries.
//I have console the form model after setting data - which has the new data too.
here is my code - link
please suggest
I suppose that (for some reason I do not know) the binding context is set wrong. So the controls try to get their values from a wrong path on the model. You can counter that by binding your controls to an absolute path by adding a / at the beginnin of the binding path:
new sap.m.Input({value:"{/ID}",width:"40%",editable : false}),
new sap.m.Input({value:"{/name}",width:"40%",editable : true}),
new sap.m.CheckBox({selected:"{/active}"}),

SAPUI5 - Remove oData Model bound to view

I am new to SAPUI5 and I am very much in need of your help.
I have created an XML view and bound an OData model to it like below. Now all the controls in the view got bound and I am able to see the data.
this.getView().setModel(oModel);
Now I have a requirement in which I have to completely remove this binding from the view. I destroyed the oModel and removed all its bindings. And now when I refresh the view, the data still exists in the screen. I want all the data from the view to disappear.
oModel.destroy();
oModel.refresh();
this.getView().getModel().refresh(true);
I assume that you're using an sap.ui.model.odata.ODataModel to retrieve odata, then done binding using, for example, a JSON model, like so,
var oJson = new sap.ui.model.json.JSONModel({data : oData);
/* Here 'data' is any name that you provide to identify your data model,
'oData' is the data that is received as response from the sap.ui.model.odata.ODataModel */
And set this model to the view like you have mentioned,
this.getView().setModel();
Now, to remove this data from the view you can try the following,
oJson.setData({data : null}, true);
This would set the previously set oData to null and therefore all data binding from the controls in the view would be removed(changed to null).
I believe oJson.refresh() is optional, but you can try adding that as well if the change is not reflected.
Its an approach until may be you find something better :) Here is the documentation for the APIs that I've used.
If you are using
var dataModel = new sap.ui.model.json.JSONModel();
dataModel.setData(oDataResponse); //Data returned from oData.Read()
this.getView().setModel(dataModel, "dataModel");
Retrieve the model, Set the model to null, Update the binding
var dataModel = this.getView().getModel("dataModel");
if(dataModel){
dataModel.setData(null);
dataModel.updateBindings(true);
}

In CQ How to disable any field in child page properties dialog?

I have added a new selection type field "Theme" in page properties>Basic.
Now if I add a new page using the same template in WCM, there also I
am getting the option "Theme", which is quite obvious.
Is there any way by which I can hide the field in child page?
P.S this is happening because I am using the same template for the child page.
You can't use the same template and have the page property dialogs be different.
What you can do is overload the dialog
create a new template and corresponding resourceType component that
inherit from your current.
copy the dialog, or tab that you want to be different from the lowest parent of the component. Make sure the dialog is the only node under the component.
Make the changes you want to the dialog.
You would then have to include code in the page jsp to get the parent page property something like:
// if the parent page is always a certain level below the root you can use
// currentPage.getAbsoluteParent(3); to get the third page down from the top
// of the current path tree.
Page parentPage = currentPage.getParent();
ValueMap parentPageProperties;
if (parentPage != null) {
parentPageProperties = parentPage.getProperties();
}
// This tries to get the property 'theme' from the current page. If that fails
// then it tries to get the property from the parent page. If that fails it
// defaults to blank.
theme = properties.get("theme", parentPageProperties.get("theme", ""));
A quick solution would also be to create a second set of template / page component. Let's assume you've got template A, that uses page component B as resource type:
Create template X and play with allowedParents allowedChildren and allowedPaths properties so that the two are exclusive (actual solution depends on your content architecture)
Give X same title as A
Create page component Y that extends B, and defines it's own dialog
Make Y's dialog re-use any tabs from B using xtype=cqinclude (see foundation page's dialog for reference)

Showing an initially selected object in an ObjectAutoCompleteField on page load in Wicket

I've followed the Wicket by Example guide to get the ObjectAutoCompleteField working, and it does so quite nicely.
I have a huge problem, though, and that is to show an initially set object in the field when the page loads. The object is retrieved from a model I use for the form where the ObjectAutoCompleteField is used. Changing the ObjectAutoCompleteField changes the model attribute it is "connected" to, and any subsequent changes in the field shows the appropriate label in its place, just not the initial one when the page loads—the only thing that shows is the edit link (to get to the autocomplete functionality).
I've looked around in the documentation for the ObjectAutoCompleteBuilder but haven't found any corresponding method to even set the initial value explicitly on page load.
I finally managed to find a solution by looking through the classes relating to ObjectAutoCompleteField.
The ObjectAutoCompleteField is constructed by the build method in ObjectAutoCompleteBuilder. So, by calling the readOnlyRenderer method on the builder, creating a new ObjectReadOnlyRenderer creating a label inside its getObjectRenderer, I got the ObjectAutoCompleteField to render a preselected object on page load.
ObjectAutoCompleteBuilder<Author, Long> builder = new ObjectAutoCompleteBuilder<Author, Long>(provider);
builder.readOnlyRenderer(new ObjectReadOnlyRenderer<Long>() {
public Component getObjectRenderer(String id, IModel<Long> pModel, IModel<String> pSearchTextModel) {
return new Label(id, new PropertyModel<Author>(model, "author"));
}
});
One would think that this was the standard behaviour, but now I know for future reference.