akserg/dart_web_toolkit — pull request #84 by tgmauch (2013-05-02 00:19:40+00:00)
Title: Use null string in attributemap when removing an element.

When removing an element, the 'ui_object_id' can not be set to the null object because the attributemap expects it to be a string. This change uses the string 'null' instead of the null object for the value.

Thank you so much for this project! Excellent!

I hit a bug when trying to "removeRow()" from a FlexTable if the row contained a widget, such as a Button.

I am using:
dart_web_toolkit version 0.3.5
Dart Editor version 0.1.2_r22275
Dart SDK version 0.1.2.0_r22270

Here is a sample program that demonstrates the error (clicking on the "x" button behind a row that is added with the "add" button will cause a traceback):

```dart
import 'dart:html';
import 'package:dart_web_toolkit/ui.dart' as ui;
import 'package:dart_web_toolkit/event.dart';

class FlexTableErrorPanel extends ui.Composite {
ui.VerticalPanel mainPanel = new ui.VerticalPanel();
ui.FlexTable ftable = new ui.FlexTable();
ui.Button addButton = new ui.Button('add');

FlexTableErrorPanel() {
// Compose the main Panel.
mainPanel.add(ftable);
mainPanel.add(addButton);
initWidget(mainPanel);

// Listen for mouse events on the Add button.
addButton.addClickHandler(new ClickHandlerAdapter((ClickEvent event) {
addRow();
}));
}

void addRow() {
// Create a button that will delete the row
ui.Button removeRowButton = new ui.Button('x');
removeRowButton.addClickHandler(new ClickHandlerAdapter((ClickEvent event) {
int rowIndex = ftable.getCellForEvent(event).getRowIndex();
ftable.removeRow(rowIndex);
}));

// Add the new row
int row = ftable.getRowCount();
ftable.setText(row, 0, '$row');
ftable.setWidget(row, 1, removeRowButton);
}
}

void main() {
ui.RootLayoutPanel.get().add(new FlexTableErrorPanel());
}
```

Here is the relevent traceback:
```
Exception: String expected /mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/gen/webkit/bindings/dart/dart/html/Element.dart:351
Element.$dom_setAttribute /mnt/data/b/build/slave/dartium-lucid64-inc/build/src/out/Release/gen/webkit/bindings/dart/dart/html/Element.dart:351
_ElementAttributeMap.[]= /mnt/data/b/build/slave/dartium-lucid64-inc/build/src/dart/tools/dom/src/AttributeMap.dart:69
_DataAttributeMap.[]= /mnt/data/b/build/slave/dartium-lucid64-inc/build/src/dart/tools/dom/src/AttributeMap.dart:112
ElementMapperImpl.clearIndex package:dart_web_toolkit/src/ui/impl/element_mapper_impl.dart:16
ElementMapperImpl.removeImpl package:dart_web_toolkit/src/ui/impl/element_mapper_impl.dart:96
ElementMapperImpl.removeByElement package:dart_web_toolkit/src/ui/impl/element_mapper_impl.dart:92
HtmlTable.remove package:dart_web_toolkit/src/ui/html_table.dart:287
HtmlTable.internalClearCell package:dart_web_toolkit/src/ui/html_table.dart:578
HtmlTable.cleanCell package:dart_web_toolkit/src/ui/html_table.dart:695
HtmlTable.removeRow package:dart_web_toolkit/src/ui/html_table.dart:648
```
I traced it back to the ElementMapperImpl passing the null object as the value for the attributemap where it is expecting a string. I changed it to use "null" instead. I'm not sure if this is the best solution, but it appears to work.