... when invoked more than once from a ChangeHandler
[SmartClient Version: v11.0p_2016-09-30/PowerEdition Deployment (built 2016-09-30)]
This is an odd one and I think I've been thorough and accurate in documenting the characteristics. Let me know if anything I state below doesn't jive with your experience.
We have a need to replace a FormItem depending on a selection made from a SelectItem. The SelectItem and FormItem are on the same form. We are able to change the value of the SelectItem and the FormItem changes as expected because we call DynamicForm.setitems() in a ChangeHandler on that SelectItem.
However, subsequent invocations of the ChangeHandler result in a stack trace in the SmartClient Console. The following is actually the stack trace from the example shown below:
The following example starts by displaying a SelectItem that allows one of three different objects to be created: a TextItem, a SelectItem or a CheckboxItem. There are also four buttons to do the same thing, but we can ignore those for now.
Scenario 1
First, run the sample and select "Text Field" from the Field Type selector. This creates a TextItem as expected. Now select a different value and the stack trace shown above is generated in the console and there is no change in the main UI.
Scenario 2
Now, re-run the sample and instead of selecting a value from the Field Type selector, use the buttons to add fields of the various different types. Either remove the field or leave it there depending on your preference, and then select either a value from the Field Type selector. The field appears as expected, but subsequent changes to the Field Type selector result in the the same as in Scenario 1.
Scenario 3
Re-run the sample and select a value from the Field Type selector. The field is displayed as expected. Now use the buttons to add fields of the various different types. The field continues to change as many times as the buttons are clicked, but once attempting another selection from the Field Type selector the errant behavior occurs again.
Scenario 4
Change line 50 to set fieldTypeSelector.defaultToFirstOption(true) and re-run the sample. Note that since the ChangeHandler has not been invoked, the TextItem does not display, but that's Ok since we're simply testing what happens if the SelectItem already has a value. Select a different value from the Field Type selector. The field is displayed as expected. This suggests that it is not the fact that the SelectItem already has a value that causes the problem.
These results seem to indicate that it is not simply the invocation of setItems() that is the problem, nor that the SelectItem has a value already when another is selected, but rather the invocation of setItems() from within the SelectItem's ChangeHandler seems to cause the problem. But only the ChangeHandler has been invoked previously.
Note that the following warnings are generated in the console, but I believe I am OK ignoring these since I am simply trying to replace an object with itself when calling setItems() a second and subsequent times. Is this true?
Having said that, I do wonder if the first warning ("Unsupported 'form' property") is relevant to this problem.
My sample is a simple rewrite of buildinds as follows:
[SmartClient Version: v11.0p_2016-09-30/PowerEdition Deployment (built 2016-09-30)]
This is an odd one and I think I've been thorough and accurate in documenting the characteristics. Let me know if anything I state below doesn't jive with your experience.
We have a need to replace a FormItem depending on a selection made from a SelectItem. The SelectItem and FormItem are on the same form. We are able to change the value of the SelectItem and the FormItem changes as expected because we call DynamicForm.setitems() in a ChangeHandler on that SelectItem.
However, subsequent invocations of the ChangeHandler result in a stack trace in the SmartClient Console. The following is actually the stack trace from the example shown below:
Code:
11:34:51.428:MUP9:WARN:Log:TypeError: Cannot read property 'length' of undefined Stack from error.stack: PickListMenu.itemClick(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Forms.js:1824:404 PickListMenu.recordClick(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Forms.js:1823:41 ListGrid.rowClick(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Grids.js:1683:22 [c]Class.invokeSuper(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Core.js:296:93 [c]Class.Super(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Core.js:288:170 PickListMenu.rowClick(<no args: exited>) on [PickListMenu ID:isc_PickListMenu_0] @ ISC_Forms.js:1819:245 eval(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ [no file]:4:115 GridRenderer._rowClick(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Grids.js:717:183 [c]Class.invokeSuper(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Core.js:296:93 [c]Class.Super(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Core.js:288:170 GridBody._rowClick(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Grids.js:784:76 GridRenderer.click(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Grids.js:715:167 Canvas.handleClick(<no args: exited>) on [GridBody ID:isc_PickListMenu_0_body] @ ISC_Core.js:3043:400 [c]EventHandler.bubbleEvent(<no args: exited>) on [Class EventHandler] @ ISC_Core.js:1728:89 [c]EventHandler.handleClick(<no args: exited>) on [Class EventHandler] @ ISC_Core.js:1586:50 EventHandler._handleMouseUp(<no args: exited>) on [Class EventHandler] @ ISC_Core.js:1571:11 [c]EventHandler.handleMouseUp(<no args: exited>) on [Class EventHandler] @ ISC_Core.js:1562:57 [c]EventHandler.dispatch(_1=>[c]EventHandler.handleMouseUp(), _2=>[object MouseEvent]) on [Class EventHandler] @ ISC_Core.js:1806:108 HTMLDocument.eval(event=>[object MouseEvent]) @ [no file]:3:123
Scenario 1
First, run the sample and select "Text Field" from the Field Type selector. This creates a TextItem as expected. Now select a different value and the stack trace shown above is generated in the console and there is no change in the main UI.
Scenario 2
Now, re-run the sample and instead of selecting a value from the Field Type selector, use the buttons to add fields of the various different types. Either remove the field or leave it there depending on your preference, and then select either a value from the Field Type selector. The field appears as expected, but subsequent changes to the Field Type selector result in the the same as in Scenario 1.
Scenario 3
Re-run the sample and select a value from the Field Type selector. The field is displayed as expected. Now use the buttons to add fields of the various different types. The field continues to change as many times as the buttons are clicked, but once attempting another selection from the Field Type selector the errant behavior occurs again.
Scenario 4
Change line 50 to set fieldTypeSelector.defaultToFirstOption(true) and re-run the sample. Note that since the ChangeHandler has not been invoked, the TextItem does not display, but that's Ok since we're simply testing what happens if the SelectItem already has a value. Select a different value from the Field Type selector. The field is displayed as expected. This suggests that it is not the fact that the SelectItem already has a value that causes the problem.
These results seem to indicate that it is not simply the invocation of setItems() that is the problem, nor that the SelectItem has a value already when another is selected, but rather the invocation of setItems() from within the SelectItem's ChangeHandler seems to cause the problem. But only the ChangeHandler has been invoked previously.
Note that the following warnings are generated in the console, but I believe I am OK ignoring these since I am simply trying to replace an object with itself when calling setItems() a second and subsequent times. Is this true?
Having said that, I do wonder if the first warning ("Unsupported 'form' property") is relevant to this problem.
Code:
11:50:17.047:MUP7:WARN:DynamicForm:isc_DynamicForm_0:Unsupported 'form' property [[DynamicForm ID:isc_DynamicForm_0]] set on item:[SelectItem ID:isc_SelectItem_2 name:fieldTypeSelector]. Ignoring. 11:50:17.058:MUP7:WARN:Log:ID 'isc_SelectItem_2' for object '[SelectItem ID:isc_SelectItem_2 name:fieldTypeSelector]' collides with the ID of an existing object. This can occur when the specified ID for a new SmartClient Canvas is the same as a native attribute of 'window', or another variable already assigned in global scope. The global reference to this object will be replaced. Consider instead using a different ID to avoid this collision altogether, especially if the colliding ID is a native attribute of window. Replacing such objects often has serious and unintended consequences. In this case, the current value of window['isc_SelectItem_2'] is: SelectItem{eventParent: [DynamicForm ID:isc_DynamicForm_0], containerWidget: [DynamicForm ID:isc_DynamicForm_0], form: [DynamicForm ID:isc_DynamicForm_0], AUTOIDClass: "SelectItem", name: "fieldTypeSelector", editorType: "SelectItem", title: "Field Type", valueMap: Array[3], type: "text", validators: Array[1], ID: "isc_SelectItem_2", pendingStatus: false, }
Code:
package com.smartgwt.sample.client; import com.google.gwt.core.client.EntryPoint; import com.smartgwt.client.widgets.IButton; import com.smartgwt.client.widgets.events.ClickEvent; import com.smartgwt.client.widgets.events.ClickHandler; import com.smartgwt.client.widgets.form.DynamicForm; import com.smartgwt.client.widgets.form.fields.CheckboxItem; import com.smartgwt.client.widgets.form.fields.SelectItem; import com.smartgwt.client.widgets.form.fields.TextItem; import com.smartgwt.client.widgets.form.fields.events.ChangedEvent; import com.smartgwt.client.widgets.form.fields.events.ChangedHandler; import com.smartgwt.client.widgets.layout.HLayout; /** * Entry point classes define <code>onModuleLoad()</code>. */ public class BuiltInDS implements EntryPoint { /** * This is the entry point method. */ public void onModuleLoad() { final DynamicForm form = new DynamicForm(); final SelectItem fieldTypeSelector = new SelectItem("fieldTypeSelector", "Field Type"); final SelectItem selectItem = new SelectItem("Select"); final TextItem textItem = new TextItem("Text"); final CheckboxItem checkboxItem = new CheckboxItem("Checkbox","Checkbox"); fieldTypeSelector.setValueMap("Text Field", "Select Field", "Checkbox Field"); fieldTypeSelector.setDefaultToFirstOption(false); fieldTypeSelector.addChangedHandler(new ChangedHandler() { @Override public void onChanged(ChangedEvent event) { String value = event.getValue().toString(); if ("Text Field".equals(value)) { form.setItems(fieldTypeSelector, textItem); } else if ("Select Field".equals(value)) { form.setItems(fieldTypeSelector, selectItem); } else if ("Checkbox Field".equals(value)) { form.setItems(fieldTypeSelector, checkboxItem); } else { form.setItems(fieldTypeSelector); } } }); final IButton addTextItemBtn = new IButton("Text Field"); addTextItemBtn.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { form.setItems(fieldTypeSelector, textItem); } }); final IButton addSelectorItemBtn = new IButton("Select Field"); addSelectorItemBtn.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { form.setItems(fieldTypeSelector, selectItem); } }); final IButton addCheckboxItemBtn = new IButton("Checkbox Field"); addCheckboxItemBtn.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { form.setItems(fieldTypeSelector, checkboxItem); } }); final IButton removeItemBtn = new IButton("Remove Field"); removeItemBtn.addClickHandler(new ClickHandler() { public void onClick(ClickEvent event) { form.setItems(fieldTypeSelector); } }); form.setItems(fieldTypeSelector); HLayout hlayout = new HLayout(); hlayout.setMembers(form, addTextItemBtn, addSelectorItemBtn, addCheckboxItemBtn, removeItemBtn); hlayout.draw(); } }
Comment