Search in sources :

Example 1 with IWebFormUI

use of com.servoy.j2db.server.ngclient.IWebFormUI in project servoy-client by Servoy.

the class RuntimeWebComponent method get.

@Override
public Object get(final String name, final Scriptable start) {
    if (specProperties != null && specProperties.contains(name)) {
        PropertyDescription pd = webComponentSpec.getProperties().get(name);
        if (WebFormComponent.isDesignOnlyProperty(pd))
            return Scriptable.NOT_FOUND;
        return NGConversions.INSTANCE.convertSabloComponentToRhinoValue(component.getProperty(name), pd, component, start);
    }
    if ("getFormName".equals(name)) {
        return new Callable() {

            @Override
            public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
                IWebFormUI parent = component.findParent(IWebFormUI.class);
                if (parent != null) {
                    return parent.getController().getName();
                }
                return null;
            }
        };
    }
    if ("getDesignTimeProperty".equals(name) && component.getFormElement().getPersistIfAvailable() instanceof AbstractBase) {
        return new Callable() {

            @Override
            public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
                return Utils.parseJSExpression(((AbstractBase) component.getFormElement().getPersistIfAvailable()).getCustomDesignTimeProperty((String) args[0]));
            }
        };
    }
    if ("getDesignProperties".equals(name) && component.getFormElement().getPersistIfAvailable() instanceof AbstractBase) {
        return new Callable() {

            @Override
            public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
                Map<String, Object> designProperties = ((AbstractBase) component.getFormElement().getPersistIfAvailable()).getMergedCustomDesignTimeProperties();
                Map<String, Object> parsedMap = new HashMap<String, Object>();
                designProperties.entrySet().forEach(entry -> {
                    parsedMap.put(entry.getKey(), Utils.parseJSExpression(entry.getValue()));
                });
                return parsedMap;
            }
        };
    }
    final Function func = apiFunctions.get(name);
    if (func != null && isApiFunctionEnabled(name)) {
        final List<Pair<String, String>> oldVisibleForms = getVisibleForms();
        return new BaseFunction() {

            @Override
            public Object call(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) {
                Object retValue;
                cx.putThreadLocal(SERVER_SIDE_SCRIPT_EXECUTE, Boolean.TRUE);
                try {
                    retValue = func.call(cx, scope, thisObj, args);
                } finally {
                    cx.removeThreadLocal(SERVER_SIDE_SCRIPT_EXECUTE);
                }
                if (!(func instanceof WebComponentFunction)) {
                    WebObjectFunctionDefinition def = webComponentSpec.getApiFunctions().get(name);
                    retValue = NGConversions.INSTANCE.convertServerSideRhinoToRhinoValue(retValue, def.getReturnType(), component, null);
                }
                updateVisibleContainers(oldVisibleForms);
                return retValue;
            }
        };
    }
    // check if we have a setter/getter for this property
    if (name != null && name.length() > 0) {
        String uName = new StringBuffer(name.substring(0, 1).toUpperCase()).append(name.substring(1)).toString();
        if (apiFunctions.containsKey("set" + uName) && apiFunctions.containsKey("get" + uName)) {
            // call getter
            Function propertyGetter = apiFunctions.get("get" + uName);
            return propertyGetter.call(Context.getCurrentContext(), start, start, new Object[] {});
        }
    }
    if ("svyMarkupId".equals(name)) {
        String formName = null;
        IWebFormUI parent = component.findParent(IWebFormUI.class);
        if (parent != null) {
            formName = parent.getController().getName();
        } else {
            formName = component.getFormElement().getForm().getName();
        }
        return ComponentFactory.getMarkupId(formName, component.getName());
    }
    // is this really needed? will not prototype be looked at automatically by Rhino code?
    if (prototypeScope != null) {
        return prototypeScope.get(name, start);
    }
    return Scriptable.NOT_FOUND;
}
Also used : Context(org.mozilla.javascript.Context) HashMap(java.util.HashMap) AbstractBase(com.servoy.j2db.persistence.AbstractBase) Scriptable(org.mozilla.javascript.Scriptable) WebServiceScriptable(com.servoy.j2db.server.ngclient.scripting.WebServiceScriptable) WebObjectFunctionDefinition(org.sablo.specification.WebObjectFunctionDefinition) Callable(org.mozilla.javascript.Callable) PropertyDescription(org.sablo.specification.PropertyDescription) WebComponentFunction(com.servoy.j2db.server.ngclient.scripting.WebComponentFunction) BaseFunction(org.mozilla.javascript.BaseFunction) Function(org.mozilla.javascript.Function) IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) BaseFunction(org.mozilla.javascript.BaseFunction) WebComponentFunction(com.servoy.j2db.server.ngclient.scripting.WebComponentFunction) Pair(com.servoy.j2db.util.Pair)

Example 2 with IWebFormUI

use of com.servoy.j2db.server.ngclient.IWebFormUI 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);
    }
}
Also used : TypedData(org.sablo.websocket.TypedData) IllegalChangeFromClientException(org.sablo.IllegalChangeFromClientException) IFoundSetInternal(com.servoy.j2db.dataprocessing.IFoundSetInternal) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) ParseException(java.text.ParseException) IllegalChangeFromClientException(org.sablo.IllegalChangeFromClientException) PropertyDescription(org.sablo.specification.PropertyDescription) IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) JSONObject(org.json.JSONObject) Iterator(java.util.Iterator) IDataAdapterList(com.servoy.j2db.server.ngclient.IDataAdapterList) JSONObject(org.json.JSONObject) ParseException(java.text.ParseException)

Example 3 with IWebFormUI

use of com.servoy.j2db.server.ngclient.IWebFormUI in project servoy-client by Servoy.

the class ComponentTypeSabloValue method fullToJSON.

/**
 * Writes the entire value of this property as JSON. This includes the template values, not just the runtime component properties.
 * This is currently needed and can get called if the property is nested inside other complex properties (json object/array) that sometimes
 * might want/need to send again the entire content.
 */
public JSONWriter fullToJSON(final JSONWriter writer, DataConversion conversionMarkers, ComponentPropertyType componentPropertyType) throws JSONException {
    // so that the client knows it must use the custom client side JS for what JSON it gets
    if (conversionMarkers != null)
        conversionMarkers.convert(ComponentPropertyType.TYPE_NAME);
    // create children of component as specified by this property
    final FormElement fe = formElementValue.element;
    writer.object();
    // get template model values
    final TypedData<Map<String, Object>> formElementProperties = fe.propertiesForTemplateJSON();
    // we'll need to update them with runtime values
    final TypedData<Map<String, Object>> runtimeProperties = childComponent.getProperties();
    // just for clear
    childComponent.getAndClearChanges();
    // add to useful properties only those formElement properties that didn't get overridden at runtime (so form element value is still used)
    boolean templateValuesRemoved = false;
    Iterator<Entry<String, Object>> formElementPropertyIterator = formElementProperties.content.entrySet().iterator();
    while (formElementPropertyIterator.hasNext()) {
        Entry<String, Object> fePropEntry = formElementPropertyIterator.next();
        if (runtimeProperties.content.containsKey(fePropEntry.getKey())) {
            // it has a non-default runtime value; so template value will be ignored/not sent
            if (!templateValuesRemoved) {
                // otherwise it's unmodifiable
                formElementProperties.content = new HashMap<String, Object>(formElementProperties.content);
                templateValuesRemoved = true;
            }
            formElementProperties.content.remove(fePropEntry.getKey());
        }
    }
    removeRecordDependentProperties(runtimeProperties);
    removeRecordDependentProperties(formElementProperties);
    IWebFormUI parent = childComponent.findParent(IWebFormUI.class);
    final FormElementContext formElementContext = new FormElementContext(fe, new ServoyDataConverterContext(parent.getController()), null);
    componentPropertyType.writeTemplateJSONContent(writer, formElementValue, forFoundsetTypedPropertyName, formElementContext, new IModelWriter() {

        @Override
        public void writeComponentModel() throws JSONException {
            writer.object();
            DataConversion dataConversion = new DataConversion();
            JSONUtils.writeData(FormElementToJSON.INSTANCE, writer, formElementProperties.content, formElementProperties.contentType, dataConversion, formElementContext);
            // always use full to JSON converter here; second arg. is null due to that
            childComponent.writeProperties(JSONUtils.FullValueToJSONConverter.INSTANCE, null, writer, runtimeProperties, dataConversion);
            JSONUtils.writeClientConversions(writer, dataConversion);
            writer.endObject();
        }
    }, recordBasedProperties, false);
    if (forFoundsetTypedPropertyName != null)
        recordBasedProperties.clearChanged();
    writeWholeViewportToJSON(writer);
    writer.endObject();
    return writer;
}
Also used : JSONException(org.json.JSONException) FormElement(com.servoy.j2db.server.ngclient.FormElement) DataConversion(org.sablo.websocket.utils.DataConversion) Entry(java.util.Map.Entry) IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) ServoyDataConverterContext(com.servoy.j2db.server.ngclient.ServoyDataConverterContext) IModelWriter(com.servoy.j2db.server.ngclient.property.ComponentPropertyType.IModelWriter) JSONObject(org.json.JSONObject) Map(java.util.Map) HashMap(java.util.HashMap) FormElementContext(com.servoy.j2db.server.ngclient.FormElementContext)

Example 4 with IWebFormUI

use of com.servoy.j2db.server.ngclient.IWebFormUI in project servoy-client by Servoy.

the class FoundsetTypeSabloValue method browserUpdatesReceived.

public void browserUpdatesReceived(Object jsonValue, PropertyDescription pd, IBrowserConverterContext dataConverterContext) {
    PushToServerEnum pushToServer = BrowserConverterContext.getPushToServerValue(dataConverterContext);
    if (getFoundset() == null)
        return;
    try {
        if (jsonValue instanceof JSONArray) {
            JSONArray arr = (JSONArray) jsonValue;
            for (int i = 0; i < arr.length(); i++) {
                JSONObject update = (JSONObject) arr.get(i);
                // {newViewPort: {startIndex : startIndex, size : size}}
                if (update.has("newViewPort")) {
                    JSONObject newViewport = update.getJSONObject("newViewPort");
                    int requestID = update.getInt(ID_KEY);
                    viewPort.clearSendingInitialPreferredViewport();
                    viewPort.setBounds(newViewport.getInt(START_INDEX), newViewport.getInt(SIZE));
                    changeMonitor.requestIdHandled(requestID, true);
                }
                if (update.has(PREFERRED_VIEWPORT_SIZE)) {
                    viewPort.setPreferredViewportSize(update.getInt(PREFERRED_VIEWPORT_SIZE));
                    if (update.has(FoundsetPropertyTypeConfig.SEND_SELECTION_VIEWPORT_INITIALLY))
                        viewPort.setSendSelectionViewportInitially(update.getBoolean(FoundsetPropertyTypeConfig.SEND_SELECTION_VIEWPORT_INITIALLY));
                    if (update.has(INITIAL_SELECTION_VIEWPORT_CENTERED))
                        viewPort.setInitialSelectionViewportCentered(update.getBoolean(INITIAL_SELECTION_VIEWPORT_CENTERED));
                } else // {loadExtraRecords: negativeOrPositiveCount}
                if (update.has("loadExtraRecords")) {
                    int requestID = update.getInt(ID_KEY);
                    viewPort.clearSendingInitialPreferredViewport();
                    viewPort.loadExtraRecords(update.getInt("loadExtraRecords"));
                    changeMonitor.requestIdHandled(requestID, true);
                } else // {loadLessRecords: negativeOrPositiveCount}
                if (update.has("loadLessRecords")) {
                    int requestID = update.getInt(ID_KEY);
                    viewPort.clearSendingInitialPreferredViewport();
                    viewPort.loadLessRecords(update.getInt("loadLessRecords"));
                    changeMonitor.requestIdHandled(requestID, true);
                } else if (update.has("sort")) {
                    int requestID = update.getInt(ID_KEY);
                    JSONArray columns = update.getJSONArray("sort");
                    StringBuilder sort = new StringBuilder();
                    Map<String, String> dp = dataproviders.size() > 0 ? dataproviders : recordDataLinkedPropertyIDToColumnDP;
                    String dataProviderID = null;
                    boolean sortAscending = true;
                    for (int j = 0; j < columns.length(); j++) {
                        JSONObject sortColumn = columns.getJSONObject(j);
                        String name = sortColumn.getString("name");
                        if (dp.containsKey(name)) {
                            sort.append(dp.get(name));
                            sort.append(" " + sortColumn.getString("direction"));
                            if (dataProviderID == null) {
                                dataProviderID = dp.get(name);
                                sortAscending = "asc".equalsIgnoreCase(sortColumn.getString("direction"));
                            }
                            if (j < columns.length() - 1)
                                sort.append(",");
                        }
                    }
                    IWebFormUI formUI = getFormUI();
                    IWebFormController fc = (formUI != null ? formUI.getController() : null);
                    if (fc != null && fc.getForm().getOnSortCmdMethodID() > 0 && dataProviderID != null) {
                        // our api only supports one dataproviderid sort at a time
                        JSEvent event = new JSEvent();
                        event.setFormName(fc.getName());
                        fc.executeFunction(String.valueOf(fc.getForm().getOnSortCmdMethodID()), Utils.arrayMerge((new Object[] { dataProviderID, Boolean.valueOf(sortAscending), event }), // $NON-NLS-1$
                        Utils.parseJSExpressions(fc.getForm().getFlattenedMethodArguments("onSortCmdMethodID"))), true, null, false, // $NON-NLS-1$
                        "onSortCmdMethodID");
                    } else {
                        try {
                            String currentSort = foundset.getSort();
                            String newSort = sort.toString();
                            foundset.setSort(newSort);
                            if (// really a new sort
                            !Utils.equalObjects(currentSort, newSort) || // not sorted, send back to client
                            !Utils.equalObjects(foundset.getSort(), newSort)) {
                                changeMonitor.foundsetSortChanged();
                            }
                        } catch (ServoyException e) {
                            Debug.error("Cannot sort foundset by " + sort.toString(), e);
                        }
                    }
                    changeMonitor.requestIdHandled(requestID, true);
                } else // {newClientSelection: newSelectedIndexesArray}
                if (update.has("newClientSelection")) {
                    JSONArray jsonSelectedIndexes = update.getJSONArray("newClientSelection");
                    int[] newSelectedIndexes = new int[jsonSelectedIndexes.length()];
                    for (int j = newSelectedIndexes.length - 1; j >= 0; j--) {
                        newSelectedIndexes[j] = jsonSelectedIndexes.getInt(j);
                    }
                    // this !Arrays.equals check in conjunction with pause()/resume() is needed to avoid an effect on the client that server always sends back changed selection in which case
                    // if the user quickly changes selection multiple times and the connection is slow, selection will jump all over
                    // the place until it stabilizes correctly
                    getListSelectionListener().pause();
                    try {
                        if (newSelectedIndexes.length == 1) {
                            foundset.setSelectedIndex(newSelectedIndexes[0]);
                        } else {
                            foundset.setSelectedIndexes(newSelectedIndexes);
                        }
                    } finally {
                        getListSelectionListener().resume();
                        // if server denies the new selection as invalid and doesn't change selection, send it to the client so that it doesn't keep invalid selection
                        if (!Arrays.equals(foundset.getSelectedIndexes(), newSelectedIndexes)) {
                            changeMonitor.selectionChanged(false);
                        }
                    }
                } else // {newClientSelectionRequest: newSelectedIndexesArray}
                if (update.has("newClientSelectionRequest")) {
                    int requestID = update.getInt(ID_KEY);
                    JSONArray jsonSelectedIndexes = update.getJSONArray("newClientSelectionRequest");
                    int[] newSelectedIndexes = new int[jsonSelectedIndexes.length()];
                    for (int j = newSelectedIndexes.length - 1; j >= 0; j--) {
                        newSelectedIndexes[j] = jsonSelectedIndexes.getInt(j);
                    }
                    int[] oldSelection = foundset.getSelectedIndexes();
                    // this !Arrays.equals check in conjunction with pause()/resume() is needed to avoid an effect on the client that server always sends back changed selection in which case
                    // if the user quickly changes selection multiple times and the connection is slow, selection will jump all over
                    // the place until it stabilizes correctly
                    getListSelectionListener().pause();
                    try {
                        if (newSelectedIndexes.length == 1) {
                            foundset.setSelectedIndex(newSelectedIndexes[0]);
                        } else {
                            foundset.setSelectedIndexes(newSelectedIndexes);
                        }
                    } finally {
                        getListSelectionListener().resume();
                        if (!Arrays.equals(oldSelection, foundset.getSelectedIndexes())) {
                            // if the selection is changed, send it back to the client so that its model is also updated
                            changeMonitor.selectionChanged(false);
                            changeMonitor.requestIdHandled(requestID, true);
                        } else {
                            if (!Arrays.equals(oldSelection, newSelectedIndexes)) {
                                // it was supposed to change but the server did not allow it
                                changeMonitor.requestIdHandled(requestID, false);
                            } else
                                changeMonitor.requestIdHandled(requestID, true);
                        }
                    }
                } else if (update.has(ViewportDataChangeMonitor.VIEWPORT_CHANGED)) {
                    if (PushToServerEnum.allow.compareTo(pushToServer) <= 0) {
                        // {dataChanged: { ROW_ID_COL_KEY: rowIDValue, dataproviderName: value }}
                        JSONObject dataChangeJSON = (JSONObject) update.get(ViewportDataChangeMonitor.VIEWPORT_CHANGED);
                        String rowIDValue = dataChangeJSON.getString(ROW_ID_COL_KEY);
                        String dpKey = dataChangeJSON.getString(DATAPROVIDER_KEY);
                        String dataProviderName;
                        if (dataproviders.containsKey(dpKey)) {
                            dataProviderName = dataproviders.get(dpKey);
                        } else {
                            dataProviderName = recordDataLinkedPropertyIDToColumnDP.get(dpKey);
                        }
                        Object value = dataChangeJSON.get(VALUE_KEY);
                        if (foundset != null) {
                            Pair<String, Integer> splitHashAndIndex = splitPKHashAndIndex(rowIDValue);
                            int recordIndex = foundset.getRecordIndex(splitHashAndIndex.getLeft(), splitHashAndIndex.getRight().intValue());
                            if (recordIndex != -1) {
                                IRecordInternal record = foundset.getRecord(recordIndex);
                                // convert Dates where it's needed
                                // this should be enough for when only foundset dataproviders are used
                                PropertyDescription dataProviderPropDesc = getDataProviderPropertyDescription(dataProviderName);
                                ValueReference<Boolean> returnValueAdjustedIncommingValueForRow = new ValueReference<Boolean>(Boolean.FALSE);
                                value = JSONUtils.fromJSONUnwrapped(null, value, dataProviderPropDesc, dataConverterContext, returnValueAdjustedIncommingValueForRow);
                                try {
                                    if (record.startEditing()) {
                                        try {
                                            record.setValue(dataProviderName, value);
                                        } catch (IllegalArgumentException e) {
                                            // TODO handle the validaton errors.
                                            IWebFormUI formUI = getFormUI();
                                            formUI.getController().getApplication().reportError("Validation for " + dataProviderName + " for value: " + value + " failed.", e);
                                        }
                                    }
                                // else cannot start editing; finally block will deal with it (send old value back to client as new one can't be pushed)
                                } finally {
                                    // if server denies the new value as invalid and doesn't change it, send it to the client so that it doesn't keep invalid value; the same if for example a double was rounded to an int
                                    if (!Utils.equalObjects(record.getValue(dataProviderName), value) || returnValueAdjustedIncommingValueForRow.value.booleanValue()) {
                                        changeMonitor.recordsUpdated(recordIndex, recordIndex, foundset.getSize(), viewPort, Arrays.asList(new String[] { dataProviderName }));
                                    }
                                }
                            } else {
                                Debug.error("Cannot set foundset record (" + rowIDValue + ") dataprovider '" + dataProviderName + "' to value '" + value + ". Record not found.");
                            }
                        }
                    } else {
                        log.error("Property (" + pd + ") that doesn't define a suitable pushToServer value (allow/shallow/deep) tried to modify foundset dataprovider value serverside. Denying and sending back full viewport!");
                        changeMonitor.viewPortCompletelyChanged();
                    }
                }
            }
        }
    } catch (JSONException e) {
        Debug.error("Error when getting browser updates for property (" + this.toString() + ") for " + jsonValue, e);
    }
}
Also used : JSEvent(com.servoy.j2db.scripting.JSEvent) IRecordInternal(com.servoy.j2db.dataprocessing.IRecordInternal) JSONArray(org.json.JSONArray) JSONException(org.json.JSONException) IWebFormController(com.servoy.j2db.server.ngclient.IWebFormController) ServoyException(com.servoy.j2db.util.ServoyException) PropertyDescription(org.sablo.specification.PropertyDescription) IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) JSONObject(org.json.JSONObject) ServoyJSONObject(com.servoy.j2db.util.ServoyJSONObject) JSONObject(org.json.JSONObject) ServoyJSONObject(com.servoy.j2db.util.ServoyJSONObject) PushToServerEnum(org.sablo.specification.WebObjectSpecification.PushToServerEnum) Map(java.util.Map) HashMap(java.util.HashMap) ValueReference(org.sablo.util.ValueReference)

Example 5 with IWebFormUI

use of com.servoy.j2db.server.ngclient.IWebFormUI in project servoy-client by Servoy.

the class ValueListTypeSabloValue method getTableForDp.

/**
 * If this valuelist is for a dataprovider and that dataprovider is for a foundset (or even from form's foundset) then this method gives the correct table to search in for that DP.
 * The DP might not be from this table though, it could still be a global variable or form variable.
 *
 * @return the table to search DP in
 */
private ITable getTableForDp() {
    ITable table;
    if (foundsetPropertySabloValue != null)
        table = foundsetPropertyTable;
    else {
        IWebFormUI formUI = ((WebFormComponent) webObjectContext.getUnderlyingWebObject()).findParent(WebFormUI.class);
        table = formUI.getController().getTable();
    }
    return table;
}
Also used : IWebFormUI(com.servoy.j2db.server.ngclient.IWebFormUI) WebFormComponent(com.servoy.j2db.server.ngclient.WebFormComponent) ITable(com.servoy.j2db.persistence.ITable)

Aggregations

IWebFormUI (com.servoy.j2db.server.ngclient.IWebFormUI)9 JSONObject (org.json.JSONObject)5 WebFormComponent (com.servoy.j2db.server.ngclient.WebFormComponent)4 Form (com.servoy.j2db.persistence.Form)3 FormElement (com.servoy.j2db.server.ngclient.FormElement)3 HashMap (java.util.HashMap)3 JSONException (org.json.JSONException)3 PropertyDescription (org.sablo.specification.PropertyDescription)3 IFormElement (com.servoy.j2db.persistence.IFormElement)2 JSForm (com.servoy.j2db.scripting.solutionmodel.JSForm)2 FormComponentCache (com.servoy.j2db.server.ngclient.FormElementHelper.FormComponentCache)2 IDataAdapterList (com.servoy.j2db.server.ngclient.IDataAdapterList)2 INGFormElement (com.servoy.j2db.server.ngclient.INGFormElement)2 Map (java.util.Map)2 JSONArray (org.json.JSONArray)2 Scriptable (org.mozilla.javascript.Scriptable)2 FlattenedSolution (com.servoy.j2db.FlattenedSolution)1 IFoundSetInternal (com.servoy.j2db.dataprocessing.IFoundSetInternal)1 IRecordInternal (com.servoy.j2db.dataprocessing.IRecordInternal)1 AbstractBase (com.servoy.j2db.persistence.AbstractBase)1