我有一个ListGrid,它最初是空的,没有定义了三个ListGridFields的记录。第一个ListGridField是一个Name并且是可编辑的,第二个是'Low'值并且是不可编辑的,如果它是第一行添加的话,其值设置为0,或者如果它不是第一行,则设置为前一个记录的高值第三个ListGridField是'High'值,也是可编辑的。
'High'ListGridField是必需的,并且有两个验证器,一个是IntegerRangeValidator,最小值为0,最大值为Integer.MAX_INT。第二个验证器是我创建的自定义验证器,用于确保用户输入的值不等于或小于记录的“低”值。
final MXListGrid rangeGrid = new MXListGrid();
rangeGrid.setOverflow(Overflow.AUTO);
rangeGrid.setWidth100();
rangeGrid.setHeight100();
rangeGrid.setAutoFetchData(false);
rangeGrid.setSelectionType(SelectionStyle.SINGLE);
ListGridField l_description = new ListGridField("description", "Description");
l_description.setType(ListGridFieldType.TEXT);
ListGridField l_low = new ListGridField("low", "Low");
l_low.setType(ListGridFieldType.INTEGER);
l_low.setCanEdit(false);
l_low.setCellFormatter(new CellFormatter()
{
public String format(Object value, ListGridRecord record, int rowNum, int colNum)
{
if (value == null) return null;
NumberFormat nf = NumberFormat.getFormat("###,###,###,###");
try
{
return nf.format(((Number) value).longValue());
}
catch (Exception e)
{
return value.toString();
}
}
});
ListGridField l_high = new ListGridField("high", "High");
l_high.setType(ListGridFieldType.INTEGER);
l_high.setCellFormatter(new CellFormatter()
{
public String format(Object value, ListGridRecord record, int rowNum, int colNum)
{
if (value == null) return null;
NumberFormat nf = NumberFormat.getFormat("###,###,###,###");
try
{
return nf.format(((Number) value).longValue());
}
catch (Exception e)
{
return value.toString();
}
}
});
IntegerRangeValidator intRangeValidator = new IntegerRangeValidator();
intRangeValidator.setMax(Integer.MAX_VALUE);
intRangeValidator.setMin(0);
l_high.setValidators(new MXRangeClassificationValidator(), intRangeValidator);
l_high.setRequired(true);
rangeGrid.setFields(l_description, l_low, l_high);
rangeGrid.setCanEdit(true);
rangeGrid.setEditEvent(ListGridEditEvent.CLICK);
然后我在屏幕上有一个按钮,允许用户添加新记录。根据上面的逻辑,如果它是第一个添加的记录,则将低值设置为0并将高值设置为空字符串,或者如果存在预先存在的记录,则将新行添加到当前所选行或在底部,如果没有选择行,并且low设置为前一个记录的高,而high设置为空字符串,则始终将焦点和光标从它们所在的位置移动到新添加的行的“Name”字段
final MXButton addRowBtn = new MXButton("Add Row");
addRowBtn.addClickHandler(new ClickHandler()
{
public void onClick(ClickEvent event)
{
if (rangeGrid.getRecords().length == 0)
{
m_rowCount = 0;
ListGridRecord record = new ListGridRecord();
record.setAttribute("description", "");
record.setAttribute("low", 0);
record.setAttribute("high", "");
rangeGrid.addData(record);
rangeGrid.startEditing(m_rowCount, 0, false);
m_rowCount++;
}
else
{
RecordList list = rangeGrid.getDataAsRecordList();
int selectedRow = m_rowCount - 1;
if (rangeGrid.getSelectedRecord() != null)
{
selectedRow = rangeGrid.getDataAsRecordList().indexOf(rangeGrid.getSelectedRecord());
}
ListGridRecord prevRecord = rangeGrid.getRecord(selectedRow);
ListGridRecord record = new ListGridRecord();
record.setAttribute("description", "");
record.setAttribute("low", Long.valueOf(prevRecord.getAttribute("high")));
record.setAttribute("high", "");
list.addAt(record, selectedRow + 1);
rangeGrid.startEditing(selectedRow + 1, 0, false);
m_rowCount++;
}
}
});
我还在ListGrid中添加了一个RowEditorExitHandler,这样我就可以在返回手动触发刚刚退出的记录的记录验证时控制一些UI行为。
// add some row editing validation
rangeGrid.addRowEditorExitHandler(new RowEditorExitHandler() {
@Override
public void onRowEditorExit(RowEditorExitEvent event)
{
GWT.log("leaving row: " + event.getRowNum());
if (!rangeGrid.validateRow(event.getRowNum()))
{
saveBtn.disable();
addRowBtn.disable();
}
else
{
saveBtn.enable();
addRowBtn.enable();
}
}
});
如果我添加记录并立即在“高”字段中输入错误值,这一切都会很好用。如果我单击按钮并添加新行,然后单击屏幕上其他位置,在该行之外,从新添加的行中删除焦点,则存在问题。我的RowEditorExitHandler方法被触发,但我的手动listGrid.validateRow(event.getRownNum())在这种情况下永远不会被执行。它不喜欢单元格没有被手动编辑的事实......它忽略了用户没有提供有效“高”值的事实。我尝试了一些东西,比如在我的RowEditorExitHandler onRowEditorExit方法中添加逻辑来检查当前行的High值的值,如果它是一个空字符串或null,则将它的值更新为一堆空格,然后触发validateRow方法......仍然没有执行验证。只有当我点击返回新添加的记录的高字段并按空格键几次或输入无效值时,才会进行验证。
我需要知道如果用户添加行然后将焦点放在新添加的行之外,如何让新添加的行立即验证其值,以便我可以立即禁用添加行和保存按钮。我不想在单击保存或添加行按钮时进行验证,这类按钮会破坏此验证模型的目的,但如果这是唯一的解决方案,那么我将不得不这样做...但是很奇怪无论我尝试什么,只有实际输入字段然后退出行才会触发验证...甚至以编程方式在退出时更改此字段的值并以编程方式触发验证无效。
有什么想法?对不起啰嗦......
答案 0 :(得分:0)
我的项目中有类似的功能,对我有用。我将用户复制的文本转换为记录并将其作为新文本插入到网格中。我的代码中有一些细微的差别。 这就是我正在做的事情:
GWT版本:2.5.1,SmartGWT版本:4.0
答案 1 :(得分:0)
首先,如果您只是调用 listGrid.addData(record); ,它将始终将其添加到列表中,当列表为空或不插入新行时,您不需要区别对待列表的末尾。
RecordList list = rangeGrid.getDataAsRecordList();
int selectedRow = m_rowCount - 1;
if (rangeGrid.getSelectedRecord() != null)
{
selectedRow = rangeGrid.getDataAsRecordList().indexOf(rangeGrid.getSelectedRecord());
}
ListGridRecord prevRecord = rangeGrid.getRecord(selectedRow);
ListGridRecord record = new ListGridRecord();
record.setAttribute("description", "");
record.setAttribute("low", Long.valueOf(prevRecord.getAttribute("high")));
record.setAttribute("high", "");
list.addAt(record, selectedRow + 1);
rangeGrid.startEditing(selectedRow + 1, 0, false);
m_rowCount++;
如果单击按钮时未选择行,则此方法无效。
然后,对于验证问题,只需在addData之后添加 rangeGrid.validateRow(m_rowCount); 即可解决您的问题。