Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

  • Hirn
    replied
    >>CanvasItem + shouldSaveValue: true + storeValue() is still the way to go.

    Then tell me how do I distinguish between the selection from the drop-down list at the bottom and the selection from the top list? Which of these choices will cause storeValue()

    Leave a comment:


  • Blama
    replied
    In general I really like the idea of this FormItem. It can show more data than MultiComboBoxItem if your data is very short, like these ISO codes. But I assume building scrolling and paging into this might be difficult. But it will for sure work well for a limited dataset you set with setValueMap().

    Best regards
    Blama

    Leave a comment:


  • Blama
    replied
    Hi Hirn,

    I think I finally understand your 2nd screenshot from #3.
    The long list is your dropdown and the top list is what you selected. Correct?

    This is just what MultiComboBoxItem does. Only difference to your case is how the unselected data is displayed. Is this it? Are you trying to rebuild that FormItem, but with a different display? If so, this high-level information would have really helped.
    Even if built-in MultiComboBoxItem is not what you want, CanvasItem + shouldSaveValue: true + storeValue() is still the way to go.

    Best regards
    Blama

    Leave a comment:


  • Hirn
    replied
    Click image for larger version

Name:	Zwischenablage-2.jpg
Views:	75
Size:	75.5 KB
ID:	271214 >>Selecting values, e.g. in a SelectItem, is still changing its value, and the correct handlers for this are around valueChanged, nothing to do with selection.

    I know how SelectItem works. There is no way to select the selected values in it. And that's what I need.
    That's why I started writing my own component.
    Last edited by Hirn; 26 Oct 2023, 01:53.

    Leave a comment:


  • Hirn
    replied
    >>So that means someone in your codebase wrote code that requires this, because there is no such code in SmartGWT.

    My task managers are not guided by SmartGWT.
    I had to either write a new component in GWT myself or adapt the component in SmartGWT.
    The second I have more or less succeeded with the least amount of time.
    If my solution ever breaks, then there will be nothing left but to write the component in pure GWT.

    Leave a comment:


  • Blama
    replied
    Hi Hirn,

    please show a screenshot with descriptions of what you are trying to achieve.
    If the CanvasItem is not enough, two CanvasItems (1st selection, 2nd selection) surly will be.

    I think a big problem so far has been to differentiate between selection (e.g. ListGrid, selecting one or multiple rows; TileGrid, selecting one or multiple tiles) and editing values in a DynamicForm. These are not the same things, and trying to mix them will create problems along the way. Selecting values, e.g. in a SelectItem, is still changing its value, and the correct handlers for this are around valueChanged, nothing to do with selection.

    Best regards
    Blama
    Last edited by Blama; 25 Oct 2023, 22:41.

    Leave a comment:


  • Isomorphic
    replied
    You say the component must be “selectable” and apparently you think this implies there must be a SelectionChanged event.

    So that means someone in your codebase wrote code that requires this, because there is no such code in SmartGWT.

    And whether you wrote it or not, that’s the code that needs fixing.

    Again, your efforts to copy internal JSNI and produce a hack are worthless - they will break right away.

    Leave a comment:


  • Hirn
    replied
    >>It sounds like you have some crufty code elsewhere that absolutely requires a SelectionChanged handler, and you are reluctant to fix this code. Well, you need to - the code you are writing right now is completely throwaway and of negative value.

    it's absolutely not that I don't want to fix my code.
    I have such a task in front of me... write a component in which a list of elements was selected from a drop-down list as in (SelectItem) and additionally this selected list should be selectable.
    If it were not for the last condition, then your proposal with storeValue() would be more suitable than ever.
    Unfortunately, it's not me who sets the tasks for myself, but my superiors.


    Leave a comment:


  • Isomorphic
    replied
    This is not a correct approach and relies on undocumented internals. It is likely to be broken just by minor patches, and very unlikely to survive an actual version upgrade.

    We and Blama have already given you the correct approach multiple times.

    It sounds like you have some crufty code elsewhere that absolutely requires a SelectionChanged handler, and you are reluctant to fix this code. Well, you need to - the code you are writing right now is completely throwaway and of negative value.

    Leave a comment:


  • Hirn
    replied
    HI Blama
    >>
    This does seem very strange to me and I'd assume this is not the way forward, even if it is almost working

    it's not whether it seems strange or not. For further development, I need exactly this functionality. Now I have received a working version (though not a beautiful one). I will finish the rest as needed.

    >>TileListItem is your CanvasItem subclass, correct?
    Exactly. If you are interested, I give the code of my component below...

    Code:
    package com.cbtl.widgets.editors;
    
    import java.lang.reflect.Array;
    import java.util.Arrays;
    
    import com.cbtl.utils.JsUtils;
    import com.cbtl.widgets.CONSTANT;
    import com.google.gwt.event.shared.HandlerRegistration;
    import com.google.gwt.user.client.ui.PopupPanel;
    import com.smartgwt.client.types.Overflow;
    import com.smartgwt.client.types.SelectionType;
    import com.smartgwt.client.widgets.Button;
    import com.smartgwt.client.widgets.Canvas;
    import com.smartgwt.client.widgets.Label;
    import com.smartgwt.client.widgets.events.ClickEvent;
    import com.smartgwt.client.widgets.events.ClickHandler;
    import com.smartgwt.client.widgets.events.DoubleClickEvent;
    import com.smartgwt.client.widgets.events.DoubleClickHandler;
    import com.smartgwt.client.widgets.form.DynamicForm;
    import com.smartgwt.client.widgets.form.fields.CanvasItem;
    import com.smartgwt.client.widgets.form.fields.FormItemIcon;
    import com.smartgwt.client.widgets.form.fields.events.IconClickEvent;
    import com.smartgwt.client.widgets.form.fields.events.IconClickHandler;
    import com.smartgwt.client.widgets.layout.FlowLayout;
    import com.smartgwt.client.data.Record;
    
    import com.smartgwt.client.bean.*;
    
    @BeanFactory.FrameworkClass
    @BeanFactory.ScClassName("TileListItem")
    
    public class TileListItem extends CanvasItem {
        private FlowLayout tileList;
        private String[] valueMap;
        private String[] selectedValues;
        private PopupPanel selectionPanel;
        private TileListItem selectionList;
        public TileListItem parentList;
        private int pickListWidth;
        private int pickListtHeight;
    
        public TileListItem (String name) {
            scClassName = "TileListItem";
            setName(name);
            itit();
        }
    
        public TileListItem(String name, String title) {
            scClassName = "TileListItem";
            setName(name);
            setTitle(title);
            itit();
        }
    
        private void itit() {
            setEndRow(true);
            setStartRow(true);
            setColSpan("*");
            setShouldSaveValue(true);
            tileList = new FlowLayout();
            tileList.setWidth("100%");
            tileList.setStyleName("inputTextField");
            tileList.setLayoutMargin(CONSTANT.PADDING);
            tileList.setTileMargin(CONSTANT.PADDING);
            tileList.setAutoHeight();
            tileList.setOverflow(Overflow.VISIBLE);
    
            tileList.addDoubleClickHandler(new DoubleClickHandler() {
                @Override
                public void onDoubleClick(DoubleClickEvent event) {
                    if(valueMap != null) {
                           createSelectionPanel();
                    }
                }
            });
    
            setCanvas(tileList);
            setShouldSaveValue(true);
        }
    
        private void clearValues(String... values) {
            Canvas[] children = tileList.getChildren();
            if(children != null && children.length > 0) {
                for(Canvas child:children) {
                    if(JsUtils.indexOf(values, child.getTitle()) == -1) {
                        tileList.removeChild(child);
                    }
                }
            }
        }
    
        public CanvasItem setCanSelect(Boolean canSelect) {
            return (CanvasItem)setAttribute("canSelect", canSelect);
        }
    
        public Boolean getCanSelect() {
            Boolean result = getAttributeAsBoolean("canSelect", true);
            return result == null ? false : result;
        }
    
        public void setValueMap(String... values) {
            valueMap = values;
            if(values != null && values.length > 0) {
                FormItemIcon editIcon = new FormItemIcon();
                editIcon.setSrc(CONSTANT.BUTTONS_ICONS + "edit.png");
                editIcon.setShowOver(false);
                editIcon.setTabIndex(-1);
                setIcons(editIcon);
                addIconClickHandler(new IconClickHandler() {
                    public void onIconClick(IconClickEvent event) {
                           createSelectionPanel();
                    }
                });
            } else {
                setIcons(new FormItemIcon[] {});
            }
        }
    
        public void setValue(String value) {
            setValues(new String[] {value});
        }
    
        public void showValues(String[] newValues) {
            clearValues(newValues);
            Boolean multiple = getMultiple();
            String name = getName();
            Boolean canSelect = getCanSelect();
            String[] values = JsUtils.castObjectToStrings(getValue());
            for(String value:newValues) {
                if(canSelect) {
                    if(values == null || JsUtils.indexOf(values, value) == -1) {
                        Button item = new Button(value);
                        item.setPadding(CONSTANT.PADDING);
                        item.setAutoFit(true);
                        item.setCanFocus(false);
                        item.setShowRollOver(false);
                        if(multiple) {
                            item.setActionType(SelectionType.CHECKBOX);
                        } else {
                            item.setActionType(SelectionType.RADIO);
                            item.setRadioGroup(name);
                        }
                        item.addClickHandler(new ClickHandler() {
                            @Override
                            public void onClick(ClickEvent event) {
                                Button buttom = (Button) event.getSource();
                                String value = buttom.getTitle();
                                if(selectedValues == null) {
                                    selectedValues = new String[] {};
                                }
                                if(buttom.getSelected()) {
                                    Array.set(selectedValues, selectedValues.length, value);
                                } else {
                                    JsUtils.removeArrayValue(selectedValues, value);
                                }
                                if(parentList != null) {
                                    parentList.showValues(selectedValues);
                                    parentList.storeValue(selectedValues);
                                } else {
                                    Record record = new Record();
                                    record.setAttribute(CONSTANT.TITLE, value);
                                    doSelectionChanged(record, buttom.isSelected());
                                }
                            }
                        });
                        tileList.addTile(item);
                    }
                } else {
                    if(values == null || JsUtils.indexOf(values, value) == -1) {
                        Label item = new Label(value);
                        item.setHeight(25);
                        item.setAutoFit(true);
                        item.setStyleName("textButton");
                        item.setWrap(false);
                        tileList.addTile(item);
                    }
                }
            }
        }
    
        public void setValues(String[] newValues) {
            showValues(newValues);
            super.setValue(newValues);
        }
    
        public String[] getSelectValues() {
            if(selectedValues != null) {
                return Arrays.copyOf(selectedValues, selectedValues.length);
            } else {
                return new String[] {};
            }
        }
    
        public void selectValue(String value) {
            selectValue(value, true);
        }
    
        public void selectValue(String value, Boolean update) {
            if(getMultiple()) {
                if(selectedValues == null) {
                    selectedValues = new String[] {};
                }
                Array.set(selectedValues, selectedValues.length, value);
            } else {
                selectedValues = new String[] {value};
            }
            selectValues(selectedValues, update);
        }
    
        public void selectValues(String[] values) {
            selectValues(values, true);
        }
    
        public void selectValues(String[] values, Boolean update) {
            if(getCanSelect()) {
                if(getMultiple()) {
                    selectedValues = values;
                } else {
                    selectedValues = new String[] {values[0]};
                }
                if(update) {
                    Canvas[] children = tileList.getChildren();
                    for(Canvas child:children) {
                        Button button = (Button) child;
                        Boolean select = JsUtils.indexOf(selectedValues, button.getTitle()) != -1;
                        button.setSelected(select);
                    }
                }
            }
        }
    
        public Object getValues() {
            return super.getValue();
        }
    
        public void setPickListWidth(int value) {
            pickListWidth = value;
        }
    
        public int getPickListWidth() {
            return pickListWidth;
        }
    
        public void setPickListHeight(int value) {
            pickListtHeight = value;
        }
    
        public int getPickListHeight() {
            return pickListtHeight;
        }
    
        private void createSelectionPanel() {
            DynamicForm form = new DynamicForm();
            form.setWidth("100%");
            form.setMargin(0);
            form.setCellPadding(0);
            form.setAutoHeight();
    
            selectionList = new TileListItem(getName() + "selectionList");
            selectionList.parentList = this;
            selectionList.setWidth("100%");
            selectionList.setShowTitle(false);
            selectionList.setMultiple(getMultiple());
            selectionList.setCanSelect(true);
            selectionList.setValues(valueMap);
    
            form.setFields(selectionList);
    
            selectionPanel = new PopupPanel(true);
            selectionPanel.setStyleName("dropDownPanel");
            int width = getPickListWidth();
            if(width == 0) {
                width = tileList.getWidth();
            }
            selectionPanel.setWidth(Integer.toString(width));
            selectionPanel.setModal(false);
            selectionPanel.setWidget(form);
            selectionPanel.show();
            int x = tileList.getAbsoluteLeft();
            int y = tileList.getAbsoluteTop() + tileList.getBottom() - tileList.getTop();
            selectionPanel.setPopupPosition(x, y);
            selectionList.selectValues(JsUtils.castObjectToStrings(getValue()));
        }
    
        public HandlerRegistration addSelectionChangedHandler(com.smartgwt.client.widgets.tile.events.SelectionChangedHandler handler) {
            if(getHandlerCount(com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType()) == 0) setupSelectionChangedEvent();
            return doAddHandler(handler, com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType());
        }
    
        private native void setupSelectionChangedEvent() /*-{
            var obj;
            var selfJ = this;
            var hasDefaultHandler;
            var selectionChanged = $entry(function(){
                var param = {"_this": this, "value" : arguments[0], "state" : arguments[1]};
                var event = @com.smartgwt.client.widgets.tile.events.SelectionChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
                selfJ.@com.smartgwt.client.widgets.BaseWidget::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
                if (hasDefaultHandler) this.Super("selectionChanged", arguments);
            });
            if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()();
                hasDefaultHandler = $wnd.isc.isA.Function(obj.getProperty("selectionChanged"));
                obj.addProperties({selectionChanged: selectionChanged});
            } else {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()();
                var scClassName = this.@com.smartgwt.client.widgets.form.fields.FormItem::scClassName;
                var classValue = $wnd.isc[scClassName];
                hasDefaultHandler = $wnd.isc.isA.Function($wnd.isc[scClassName].getInstanceProperty("selectionChanged"));
                obj.selectionChanged = selectionChanged;
            }
        }-*/;
    
        private native void doSelectionChanged(Record record, Boolean state) /*-{
            var obj;
            var selfJ = this;
            obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()();
            hasDefaultHandler = $wnd.isc.isA.Function(obj.getProperty("selectionChanged"));
            if (hasDefaultHandler) obj.selectionChanged(record, state);
        }-*/;
    }

    Leave a comment:


  • Blama
    replied
    Hi Hirn


    TileListItem is your CanvasItem subclass, correct? And are you manually adding a method that takes a com.smartgwt.client.widgets.tile.events.SelectionChangedHandler as parameter with your addSelectionChangedHandler? This does seem very strange to me and I'd assume this is not the way forward, even if it is almost working.

    Again, describe what you want to do on a higher level. Also, big screenshots with remarks will help.

    Best regards
    Blama

    Leave a comment:


  • Hirn
    replied
    I have almost solved my problem, but there is one nuance left...
    I have the code...
    Code:
        public HandlerRegistration addSelectionChangedHandler(com.smartgwt.client.widgets.tile.events.SelectionChangedHandler handler) {
            if(getHandlerCount(com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType()) == 0) setupSelectionChangedEvent();
            return doAddHandler(handler, com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType());
        }
    
        private native void setupSelectionChangedEvent() /*-{
            var obj;
            var selfJ = this;
            var hasDefaultHandler;
            var selectionChanged = $entry(function(){
                var param = {"_this": this, "record" : arguments[0], "state" : arguments[1]};
                var event = @com.smartgwt.client.widgets.tile.events.SelectionChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
                selfJ.@com.smartgwt.client.widgets.BaseWidget::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
                if (hasDefaultHandler) this.Super("selectionChanged", arguments);
            });
            if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()();
                hasDefaultHandler = $wnd.isc.isA.Function(obj.getProperty("selectionChanged"));
                obj.addProperties({selectionChanged: selectionChanged});
            } else {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()();
                var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName;
                hasDefaultHandler = $wnd.isc.isA.Function($wnd.isc[scClassName].getInstanceProperty("selectionChanged"));
                obj.selectionChanged = selectionChanged;
            }
        }-*/;
    
        private native void doSelectionChanged(Record record, Boolean state) /*-{
            var obj;
            var selfJ = this;
            obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()();
            hasDefaultHandler = $wnd.isc.isA.Function(obj.getProperty("selectionChanged"));
            if (hasDefaultHandler) obj.selectionChanged(record, state);
        }-*/;
    but if I use

    Code:
    TileListItem projectLanguagesList = new TileListItem("projectLanguages", Strings.get("projectLanguages"));
    projectLanguagesList.addSelectionChangedHandler(new com.smartgwt.client.widgets.tile.events.SelectionChangedHandler() {
                @Override
                public void onSelectionChanged(SelectionChangedEvent event) {
                    int i = 0;
                }
            });
    that 's in my line
    var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName;

    scClassName == undefined
    and the program crashes with an error

    and if I use such code, then everything works fine
    Code:
    TileListItem projectLanguagesList = new TileListItem("projectLanguages", Strings.get("projectLanguages"));
    
    form.setFields(projectLanguagesList);
    addMember(form);
    
    projectLanguagesList.addSelectionChangedHandler(new com.smartgwt.client.widgets.tile.events.SelectionChangedHandler() {
                @Override
                public void onSelectionChanged(SelectionChangedEvent event) {
                    int i = 0;
                }
            });
    I understand why the error crashes, but I haven't found how to fix it yet



    Leave a comment:


  • Blama
    replied
    Sorry, this does not make sense to me.
    ItemChanged is what happens when you change the selected button by activating/deactivating them.
    No need for any other handlers.
    ClickHandlers in the Buttons: Call CanvasItem.storeValue()
    ItemChangedHandler in DynamicForm: Do your logic.

    Perhaps explain on a higher level what you are trying to build, if this is not what you want.

    Best regards
    Blama

    Leave a comment:


  • Hirn
    replied
    I have a Dynamic Form.addItemChangedHandler() triggered to change the number and quality of buttons in the component, and I need a handler that responds to the selection of these buttons. So that I can make an add Selection Change Handler in my component and it will trigger when the buttons are pressed. I found how to add this handler to the component, but unfortunately I didn't find how to call it.
    Code:
    public HandlerRegistration addSelectionChangedHandler(com.smartgwt.client.widgets.tile.events.SelectionChangedHandler handler) {
            if(getHandlerCount(com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType()) == 0) setupSelectionChangedEvent();
            return doAddHandler(handler, com.smartgwt.client.widgets.tile.events.SelectionChangedEvent.getType());
        }
    
        private native void setupSelectionChangedEvent() /*-{
            var obj;
            var selfJ = this;
            var hasDefaultHandler;
            var selectionChanged = $entry(function(){
                var param = {"_this": this, "record" : arguments[0], "state" : arguments[1]};
                var event = @com.smartgwt.client.widgets.tile.events.SelectionChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
                selfJ.@com.smartgwt.client.widgets.BaseWidget::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
                selfJ.@com.smartgwt.client.widgets.tile.TileGrid::handleTearDownSelectionChangedEvent()();
                if (hasDefaultHandler) this.Super("selectionChanged", arguments);
            });
            if(this.@com.smartgwt.client.widgets.BaseWidget::isCreated()()) {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getJsObj()();
                hasDefaultHandler = $wnd.isc.isA.Function(obj.getProperty("selectionChanged"));
                obj.addProperties({selectionChanged: selectionChanged});
            } else {
                obj = this.@com.smartgwt.client.widgets.BaseWidget::getConfig()();
                var scClassName = this.@com.smartgwt.client.widgets.BaseWidget::scClassName;
                hasDefaultHandler = $wnd.isc.isA.Function($wnd.isc[scClassName].getInstanceProperty("selectionChanged"));
                obj.selectionChanged = selectionChanged ;
            }
        }-*/;

    Leave a comment:


  • Blama
    replied
    You are talking about the situation when a user clicks and activates/deactivates one of the buttons, right?
    Doesn‘t DynamicForm.addItemChangedHandler() do this for you?

    Best regards
    Blama

    Leave a comment:

Working...
X