use of com.servoy.j2db.server.ngclient.IDataAdapterList in project servoy-client by Servoy.
the class PersistFieldInstanceTest method testFieldWithValueList.
@Test
public void testFieldWithValueList() throws RepositoryException {
Form form = solution.getForm("test");
Assert.assertNotNull(form);
ValueList vl = solution.getValueList("test");
Assert.assertNotNull(vl);
Field field = form.createNewField(new Point(0, 0));
field.setDataProviderID("mycolumn");
field.setFormat("#,###.00");
field.setDisplayType(Field.TYPE_AHEAD);
field.setValuelistID(vl.getID());
// needed for a valuelist property type that searches it's form's table via the webform ui
WebFormUI formUI = new WebFormUI(client.getFormManager().getForm(form.getName()));
IDataAdapterList dataAdapterList = formUI.getDataAdapterList();
List<FormElement> formElements = FormElementHelper.INSTANCE.getFormElements(form.getAllObjects(), new ServoyDataConverterContext(client));
Assert.assertEquals(1, formElements.size());
WebFormComponent wc = ComponentFactory.createComponent(client, dataAdapterList, formElements.get(0), formUI, form);
Object property = wc.getProperty("valuelistID");
Assert.assertTrue(property != null ? property.getClass().getName() : "null", property instanceof ValueListTypeSabloValue && ((ValueListTypeSabloValue) property).getValueList() instanceof CustomValueList);
Assert.assertEquals("#,###.00", ((CustomValueList) ((ValueListTypeSabloValue) property).getValueList()).getFormat().getDisplayFormat());
}
use of com.servoy.j2db.server.ngclient.IDataAdapterList in project servoy-client by Servoy.
the class ComponentTypeSabloValue method browserUpdatesReceived.
public void browserUpdatesReceived(Object jsonValue) {
if (childComponent == null)
return;
try {
JSONArray updates = (JSONArray) jsonValue;
for (int i = 0; i < updates.length(); i++) {
JSONObject update = (JSONObject) updates.get(i);
if (update.has("handlerExec")) {
// { handlerExec: {
// eventType: ...,
// args: ...,
// rowId : ...
// }});
update = update.getJSONObject("handlerExec");
if (update.has("eventType")) {
boolean selectionOk = true;
if (update.has("rowId")) {
String rowId = update.optString("rowId");
if (rowId != null) {
FoundsetTypeSabloValue foundsetValue = getFoundsetValue();
if (foundsetValue != null) {
if (!foundsetValue.setEditingRowByPkHash(rowId)) {
Debug.error("Cannot select row when component event was fired; row identifier: " + rowId + ", forFoundset: '" + foundsetValue + "', component: " + (childComponent != null ? childComponent : getName()));
selectionOk = false;
}
}
}
}
if (selectionOk) {
String eventType = update.getString("eventType");
// String beanName = update.getString("beanName");
JSONArray jsargs = update.getJSONArray("args");
Object[] args = new Object[jsargs == null ? 0 : jsargs.length()];
for (int j = 0; jsargs != null && j < jsargs.length(); j++) {
args[j] = jsargs.get(j);
}
Object result = null;
String error = null;
try {
result = childComponent.executeEvent(eventType, args);
} catch (ParseException pe) {
log.warn("Warning: " + pe.getMessage(), pe);
} catch (IllegalChangeFromClientException ilcae) {
log.warn("Warning: " + ilcae.getMessage());
} catch (Exception e) {
error = "Error: " + e.getMessage();
log.error(error, e);
}
int cmsid = update.optInt("defid", -1);
if (cmsid != -1) {
if (error == null) {
Object resultObject = result;
PropertyDescription objectType = null;
if (result instanceof TypedData) {
resultObject = ((TypedData<?>) result).content;
objectType = ((TypedData<?>) result).contentType;
}
CurrentWindow.get().getSession().getSabloService().resolveDeferedEvent(cmsid, true, resultObject, objectType);
} else {
CurrentWindow.get().getSession().getSabloService().resolveDeferedEvent(cmsid, false, error, null);
}
}
}
}
} else if (update.has("propertyChanges")) {
// { propertyChanges : {
// prop1: ...,
// prop2: ...
// }}
JSONObject changes = update.getJSONObject("propertyChanges");
Iterator<String> keys = changes.keys();
while (keys.hasNext()) {
String key = keys.next();
Object object = changes.get(key);
childComponent.putBrowserProperty(key, object);
}
} else if (update.has(ViewportDataChangeMonitor.VIEWPORT_CHANGED)) {
// component is linked to a foundset and the value of a property that depends on the record changed client side;
// in this case update DataAdapterList with the correct record and then set the value on the component
FoundsetTypeSabloValue foundsetPropertyValue = getFoundsetValue();
if (foundsetPropertyValue != null && foundsetPropertyValue.getFoundset() != null) {
JSONObject change = update.getJSONObject(ViewportDataChangeMonitor.VIEWPORT_CHANGED);
String rowIDValue = change.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
String propertyName = change.getString(FoundsetTypeSabloValue.DATAPROVIDER_KEY);
Object value = change.get(FoundsetTypeSabloValue.VALUE_KEY);
updatePropertyValueForRecord(foundsetPropertyValue, rowIDValue, propertyName, value);
foundsetPropertyValue.setDataAdapterListToSelectedRecord();
} else {
Debug.error("Component updates received for record linked property, but component is not linked to a foundset: " + update.get(ViewportDataChangeMonitor.VIEWPORT_CHANGED));
}
} else if (update.has("svyApply")) {
// { svyApply: {
// rowId: rowId, // only when linked to foundset
// propertyName: property,
// propertyValue: propertyValue
// }}
JSONObject changeAndApply = update.getJSONObject("svyApply");
String propertyName = changeAndApply.getString(ComponentPropertyType.PROPERTY_NAME_KEY);
Object value = changeAndApply.get(ComponentPropertyType.VALUE_KEY);
try {
if (forFoundsetTypedPropertyName != null && recordBasedProperties.contains(propertyName)) {
// changes component record and sets value
String rowIDValue = changeAndApply.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
foundsetLinkedPropOfComponentValueChangeHandler.setApplyingDPValueFromClient(true);
FoundsetTypeSabloValue foundsetValue = getFoundsetValue();
updatePropertyValueForRecord(foundsetValue, rowIDValue, propertyName, value);
// apply change to record/dp
foundsetValue.getDataAdapterList().pushChanges(childComponent, propertyName);
foundsetValue.setDataAdapterListToSelectedRecord();
} else {
childComponent.putBrowserProperty(propertyName, value);
IWebFormUI formUI = getParentComponent().findParent(IWebFormUI.class);
// apply change to record/dp
formUI.getDataAdapterList().pushChanges(childComponent, propertyName);
}
if (forFoundsetTypedPropertyName != null && !recordBasedProperties.contains(propertyName)) {
// a global or form var that in case of a foundset linked component will apply the value on the child component but, as it knows it is comming from the browser,
// the child component will not notify it as a changed value; we need that though as we need to resend that value for all rows back to client, not just currently selected one
childComponent.markPropertyAsChangedByRef(propertyName);
}
} finally {
if (foundsetLinkedPropOfComponentValueChangeHandler != null)
foundsetLinkedPropOfComponentValueChangeHandler.setApplyingDPValueFromClient(false);
}
} else if (update.has("svyStartEdit")) {
// { svyStartEdit: {
// rowId: rowId, // only if linked to foundset
// propertyName: property
// }}
JSONObject startEditData = update.getJSONObject("svyStartEdit");
String propertyName = startEditData.getString(ComponentPropertyType.PROPERTY_NAME_KEY);
IDataAdapterList dal;
if (forFoundsetTypedPropertyName != null && recordBasedProperties.contains(propertyName)) {
String rowIDValue = startEditData.getString(FoundsetTypeSabloValue.ROW_ID_COL_KEY);
IFoundSetInternal foundset = getFoundsetValue().getFoundset();
dal = getFoundsetValue().getDataAdapterList();
Pair<String, Integer> splitHashAndIndex = FoundsetTypeSabloValue.splitPKHashAndIndex(rowIDValue);
if (foundset != null) {
int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
if (recordIndex != -1) {
((FoundsetDataAdapterList) dal).setRecordQuietly(foundset.getRecord(recordIndex));
} else {
Debug.error("Cannot find record for foundset linked record dependent component property - startEdit (" + rowIDValue + "); property '" + propertyName, new RuntimeException());
}
} else {
Debug.error("Foundset is null while trying to startEdit for foundset linked record dependent component property (" + rowIDValue + "); property '" + propertyName, new RuntimeException());
}
} else {
IWebFormUI formUI = getParentComponent().findParent(IWebFormUI.class);
dal = formUI.getDataAdapterList();
}
// TODO last arg should be here the foundsetLinked row Id in case the property is itself a foundset-linked DP; this should be done as part of case SVY-10500
dal.startEdit(childComponent, propertyName, null);
}
}
} catch (Exception ex) {
Debug.error(ex);
}
}
use of com.servoy.j2db.server.ngclient.IDataAdapterList in project servoy-client by Servoy.
the class RelatedFormsTest method testRelatedFormsInTabPanels.
@Test
public void testRelatedFormsInTabPanels() throws RepositoryException {
// f1 is the main
//
// 3 forms on that main
//
// f2 "relation2"
// f3 "relation2.relation3"
// f4 "relation2.relation3.relation4"
Form f1 = solution.createNewForm(validator, null, "f1", null, false, new Dimension(600, 400));
IWebFormController f1Controller = new TestFormController(f1, client);
IDataAdapterList dataAdapterListF1 = f1Controller.getFormUI().getDataAdapterList();
Form f2 = solution.createNewForm(validator, null, "f2", null, false, new Dimension(600, 400));
IWebFormController f2Controller = new TestFormController(f2, client);
IDataAdapterList dataAdapterListF2 = f2Controller.getFormUI().getDataAdapterList();
Form f3 = solution.createNewForm(validator, null, "f3", null, false, new Dimension(600, 400));
IWebFormController f3Controller = new TestFormController(f3, client);
IDataAdapterList dataAdapterListF3 = f3Controller.getFormUI().getDataAdapterList();
Form f4 = solution.createNewForm(validator, null, "f4", null, false, new Dimension(600, 400));
IWebFormController f4Controller = new TestFormController(f4, client);
IDataAdapterList dataAdapterListF4 = f4Controller.getFormUI().getDataAdapterList();
TabPanel tabpanelF2 = f1.createNewTabPanel("tabpanelF2");
tabpanelF2.createNewTab("tab1", "relation2", f2);
TabPanel tabpanelF3 = f1.createNewTabPanel("tabpanelF3");
tabpanelF3.createNewTab("tab1", "relation2.relation3", f3);
TabPanel tabpanelF4 = f1.createNewTabPanel("tabpanelF4");
tabpanelF4.createNewTab("tab1", "relation2.relation3.relation4", f4);
dataAdapterListF1.addVisibleChildForm(f2Controller, "relation2", true);
// relatedForms of f1 has now f2
Assert.assertEquals(1, dataAdapterListF1.getRelatedForms().size());
Assert.assertEquals("relation2", dataAdapterListF1.getRelatedForms().get(f2Controller));
dataAdapterListF1.addVisibleChildForm(f3Controller, "relation2.relation3", true);
// relatedForms of f1 has now f2 and f3
Assert.assertEquals(2, dataAdapterListF1.getRelatedForms().size());
Assert.assertEquals("relation2.relation3", dataAdapterListF1.getRelatedForms().get(f3Controller));
// also f2 relatedForms has f3
Assert.assertEquals(1, dataAdapterListF2.getRelatedForms().size());
Assert.assertEquals("relation3", dataAdapterListF2.getRelatedForms().get(f3Controller));
// and f3 relatedParentsForms has f2
Assert.assertEquals(1, dataAdapterListF3.getParentRelatedForms().size());
Assert.assertEquals(dataAdapterListF3.getParentRelatedForms().toString() + " should have:" + f2Controller, 0, dataAdapterListF3.getParentRelatedForms().indexOf(f2Controller));
Assert.assertNotEquals(dataAdapterListF3.getParentRelatedForms().toString() + " should have:" + f2Controller, -1, dataAdapterListF3.getParentRelatedForms().indexOf(f2Controller));
dataAdapterListF1.addVisibleChildForm(f4Controller, "relation2.relation3.relation4", true);
// relatedForms of f1 has now f2 and f3 and f4
Assert.assertEquals(3, dataAdapterListF1.getRelatedForms().size());
Assert.assertEquals("relation2.relation3.relation4", dataAdapterListF1.getRelatedForms().get(f4Controller));
// relatedForms of f2 has now f3 and f4
Assert.assertEquals(2, dataAdapterListF2.getRelatedForms().size());
Assert.assertEquals("relation3", dataAdapterListF2.getRelatedForms().get(f3Controller));
Assert.assertEquals("relation3.relation4", dataAdapterListF2.getRelatedForms().get(f4Controller));
// and f4 relatedParentsForms has f2 and f3
Assert.assertEquals(2, dataAdapterListF4.getParentRelatedForms().size());
Assert.assertTrue(dataAdapterListF4.getParentRelatedForms() + " should have " + f2Controller, dataAdapterListF4.getParentRelatedForms().indexOf(f2Controller) >= 0);
Assert.assertTrue(dataAdapterListF4.getParentRelatedForms() + " should have " + f3Controller, dataAdapterListF4.getParentRelatedForms().indexOf(f3Controller) >= 0);
dataAdapterListF1.removeVisibleChildForm(f4Controller, true);
// relatedForms of f1 has now f2 and f3
Assert.assertEquals(2, dataAdapterListF1.getRelatedForms().size());
Assert.assertEquals("relation2", dataAdapterListF1.getRelatedForms().get(f2Controller));
Assert.assertEquals("relation2.relation3", dataAdapterListF1.getRelatedForms().get(f3Controller));
// relatedForms of f2 has now f3
Assert.assertEquals(1, dataAdapterListF2.getRelatedForms().size());
Assert.assertEquals("relation3", dataAdapterListF2.getRelatedForms().get(f3Controller));
dataAdapterListF2.removeVisibleChildForm(f3Controller, true);
// relatedForms of f1 has now f2 and f3
Assert.assertEquals(2, dataAdapterListF1.getRelatedForms().size());
Assert.assertEquals("relation2", dataAdapterListF1.getRelatedForms().get(f2Controller));
Assert.assertEquals("relation2.relation3", dataAdapterListF1.getRelatedForms().get(f3Controller));
// relatedForms of f2 has no related forms
Assert.assertEquals(0, dataAdapterListF2.getRelatedForms().size());
}
use of com.servoy.j2db.server.ngclient.IDataAdapterList in project servoy-client by Servoy.
the class ComponentTypeSabloValue method createComponentIfNeededAndPossible.
protected void createComponentIfNeededAndPossible() {
// so now we should be able to find a potentially linked foundset property value
if (componentIsCreated || webObjectContext == null)
return;
final FoundsetTypeSabloValue foundsetPropValue = getFoundsetValue();
if (foundsetPropValue != null)
foundsetPropValue.addStateChangeListener(getFoundsetStateChangeListener());
// foundset property value is not yet set or not yet attached to component
if ((foundsetPropValue == null || foundsetPropValue.getDataAdapterList() == null) && forFoundsetTypedPropertyName != null)
return;
componentIsCreated = true;
IWebFormUI formUI = getParentComponent().findParent(IWebFormUI.class);
final IDataAdapterList dal = (foundsetPropValue != null ? foundsetPropValue.getDataAdapterList() : formUI.getDataAdapterList());
if (foundsetPropValue != null) {
// do this before creating the component so that any attach() methods of it's properties that register data links get caught
((FoundsetDataAdapterList) dal).addDataLinkedPropertyRegistrationListener(createDataLinkedPropertyRegistrationListener());
foundsetLinkedPropOfComponentValueChangeHandler = new FoundsetLinkedValueChangeHandler(foundsetPropValue);
}
childComponent = ComponentFactory.createComponent(dal.getApplication(), dal, formElementValue.element, getParentComponent(), formUI.getController().getForm());
if (foundsetPropValue != null) {
dataLinkedPropertyRegistrationListener.componentIsNowAvailable();
}
childComponent.setDirtyPropertyListener(new IDirtyPropertyListener() {
@Override
public void propertyFlaggedAsDirty(String propertyName, boolean dirty, boolean granularUpdate) {
if (dirty) {
// this gets called whenever a property is flagged as dirty/changed/to be sent to browser
if (forFoundsetTypedPropertyName != null && recordBasedProperties.contains(propertyName)) {
if (!((FoundsetDataAdapterList) dal).isQuietRecordChangeInProgress() && foundsetPropValue.getFoundset() != null && // if forFoundsetTypedPropertyName != null we are using a foundset DAL, so just cast
!foundsetPropValue.getFoundset().isInFindMode()) {
// for example valuelist properties can get filtered based on client sent filter in which case the property does change without
// any actual change in the record; in this case we need to mark it correctly in viewport as a change
foundsetLinkedPropOfComponentValueChangeHandler.valueChangedInFSLinkedUnderlyingValue(propertyName, viewPortChangeMonitor);
} else {
// else this change was probably determined by the fact that we reuse components, changing the record in the DAL to get data for a specific row;
// so we need to clear component changes for this property because we do not notify the parent here (we want to ignore the change) so
// we shouldn't keep the property marked as dirty - thus blocking future property changes to generate a valueChanged on parent's monitor
childComponent.clearChangedStatusForProperty(propertyName);
}
} else {
// non-record related prop. changed...
monitor.valueChanged();
}
}
}
});
for (String initialChangedProperty : childComponent.getProperties().content.keySet()) {
if (forFoundsetTypedPropertyName == null || !recordBasedProperties.contains(initialChangedProperty)) {
// non-record related prop. initially changed...
monitor.valueChanged();
}
}
childComponent.setComponentContext(new ComponentContext(formElementValue.propertyPath));
if (componentPropertyDescription != null && Utils.getAsBoolean(componentPropertyDescription.getTag(TAG_ADD_TO_ELEMENTS_SCOPE))) {
formUI.contributeComponentToElementsScope(formElementValue.element, formElementValue.element.getWebComponentSpec(), childComponent);
}
for (String handler : childComponent.getFormElement().getHandlers()) {
Object value = childComponent.getFormElement().getPropertyValue(handler);
if (value instanceof String) {
IPersist function = formUI.getController().getApplication().getFlattenedSolution().searchPersist((String) value);
Form form = formUI.getController().getForm();
if (function == null) {
Debug.warn("Script Method of value '" + value + "' not found trying just the form " + form);
IPersist child = form.getChild(UUID.fromString((String) value));
if (child != null) {
Debug.warn("Script Method " + child + " on the form " + form + " with uuid " + child.getUUID());
function = child;
}
}
if (function != null) {
childComponent.add(handler, function.getID());
} else {
Debug.warn("Event handler for " + handler + " with value '" + value + "' not found (form " + form + ", form element " + childComponent.getFormElement().getName() + ")");
}
} else if (value instanceof Number && ((Number) value).intValue() > 0) {
childComponent.add(handler, ((Number) value).intValue());
}
}
if (foundsetPropValue != null) {
viewPortChangeMonitor = new ComponentTypeViewportDataChangeMonitor(monitor, new ComponentViewportRowDataProvider((FoundsetDataAdapterList) dal, childComponent, this), this);
foundsetPropValue.addViewportDataChangeMonitor(viewPortChangeMonitor);
setDataproviderNameToFoundset();
}
addPropagatingPropertyChangeListener(WebFormUI.READONLY, webObjectContext.getProperty(WebFormUI.READONLY));
if (childComponent.hasChanges())
monitor.valueChanged();
}
use of com.servoy.j2db.server.ngclient.IDataAdapterList in project servoy-client by Servoy.
the class WebFormController method propagateFindMode.
@Override
public void propagateFindMode(boolean findMode) {
if (!findMode) {
application.getFoundSetManager().getEditRecordList().prepareForSave(true);
}
IDataAdapterList dal = getFormUI().getDataAdapterList();
// disables related data en does getText instead if getValue on fields
dal.setFindMode(findMode);
}
Aggregations