package com.smartgwt.sample.showcase.client.dataintegration.java.transactions; import com.smartgwt.client.data.Criteria; import com.smartgwt.client.data.DSCallback; import com.smartgwt.client.data.DSRequest; import com.smartgwt.client.data.DSResponse; import com.smartgwt.client.data.DataSource; import com.smartgwt.client.data.Record; import com.smartgwt.client.data.ResultSet; import com.smartgwt.client.types.Alignment; import com.smartgwt.client.types.DSOperationType; import com.smartgwt.client.types.DragDataAction; import com.smartgwt.client.widgets.Canvas; import com.smartgwt.client.widgets.Img; 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.SelectItem; import com.smartgwt.client.widgets.form.fields.events.ChangedEvent; import com.smartgwt.client.widgets.form.fields.events.ChangedHandler; import com.smartgwt.client.widgets.form.fields.events.DataArrivedEvent; import com.smartgwt.client.widgets.form.fields.events.DataArrivedHandler; import com.smartgwt.client.widgets.grid.ListGrid; import com.smartgwt.client.widgets.grid.ListGridField; import com.smartgwt.client.widgets.grid.ListGridRecord; import com.smartgwt.client.widgets.grid.ListGridRemoveField; import com.smartgwt.client.widgets.grid.events.RecordDropEvent; import com.smartgwt.client.widgets.grid.events.RecordDropHandler; import com.smartgwt.client.widgets.grid.events.RemoveRecordClickEvent; import com.smartgwt.client.widgets.grid.events.RemoveRecordClickHandler; import com.smartgwt.client.widgets.layout.HStack; import com.smartgwt.client.widgets.layout.LayoutSpacer; import com.smartgwt.client.widgets.layout.VStack; import com.google.gwt.core.client.EntryPoint; public class ManyToManyDragSaveSample implements EntryPoint { private DataSource employeesDS; private DataSource teamsDS; private DataSource teamMembers2DS; // To remove entries of `employeesGrid` without deleting the corresponding rows from // the database, we can mock a "remove" DSResponse and post it to `employeesDS` via // DataSource#updateCaches(). All grids that are bound to the data source respond to // these events as appropriate. In this case, posting a "remove" DSResponse will cause // `employeesGrid` to remove the records from its list. private void mockRemoveEmployees(ListGridRecord... employeeRecords) { if (employeeRecords.length == 0) { return; } DSResponse mockRemoveResponse = new DSResponse("employees", DSOperationType.REMOVE, employeeRecords); employeesDS.updateCaches(mockRemoveResponse); } private void mockAddEmployeesFromTeamMemberRecords(ListGridRecord... teamMemberRecords) { if (teamMemberRecords.length == 0) { return; } ListGridRecord[] mockEmployeeRecords = new ListGridRecord[teamMemberRecords.length]; for (int i = 0; i < teamMemberRecords.length; ++i) { ListGridRecord teamMemberRecord = teamMemberRecords[i]; ListGridRecord mockEmployeeRecord = new ListGridRecord(); Record.copyAttributesInto(mockEmployeeRecord, teamMemberRecord, "EmployeeId"); mockEmployeeRecord.setAttribute("Name", teamMemberRecord.getAttributeAsString("EmployeeName")); mockEmployeeRecord.setAttribute("Job", teamMemberRecord.getAttributeAsString("EmployeeJob")); mockEmployeeRecords[i] = mockEmployeeRecord; } DSResponse mockAddResponse = new DSResponse("employees", DSOperationType.ADD, mockEmployeeRecords); employeesDS.updateCaches(mockAddResponse); } @Override public void onModuleLoad() { employeesDS = DataSource.get("employees"); teamsDS = DataSource.get("teams"); teamMembers2DS = DataSource.get("teamMembers2"); final DynamicForm teamSelectionForm = new DynamicForm(); teamSelectionForm.setWidth(300); teamSelectionForm.setHeight(30); final SelectItem teamSelectItem = new SelectItem("TeamId", "Team"); teamSelectItem.setOptionDataSource(teamsDS); teamSelectItem.setValueField("TeamId"); teamSelectItem.setDisplayField("TeamName"); final ListGrid employeesGrid = new ListGrid(employeesDS); employeesGrid.setWidth(300); employeesGrid.setHeight(224); employeesGrid.setCanDragRecordsOut(true); employeesGrid.setDragDataAction(DragDataAction.NONE); employeesGrid.setDragType("nonTeamMemberEmployee"); employeesGrid.setAutoFetchData(false); employeesGrid.setSortField("EmployeeId"); ListGridField employeeIdField = new ListGridField("EmployeeId", "ID"); employeeIdField.setWidth(50); ListGridField employeeNameField = new ListGridField("Name", "Employee Name"); employeesGrid.setFields(employeeIdField, employeeNameField); final ListGrid teamMembersGrid = new ListGrid(teamMembers2DS); teamMembersGrid.setWidth(300); teamMembersGrid.setHeight(264); teamMembersGrid.setCanAcceptDroppedRecords(true); teamMembersGrid.setDropTypes("nonTeamMemberEmployee"); teamMembersGrid.setCanRemoveRecords(true); teamMembersGrid.setAutoFetchData(false); teamMembersGrid.setSortField("EmployeeId"); teamMembersGrid.addRecordDropHandler(new RecordDropHandler() { @Override public void onRecordDrop(RecordDropEvent event) { ListGridRecord[] draggedRecords = event.getDropRecords(); mockRemoveEmployees(draggedRecords); } }); teamMembersGrid.addRemoveRecordClickHandler(new RemoveRecordClickHandler() { @Override public void onRemoveRecordClick(RemoveRecordClickEvent event) { final ListGridRecord record = teamMembersGrid.getRecord(event.getRowNum()); teamMembersGrid.removeData(record, new DSCallback() { @Override public void execute(DSResponse response, Object rawData, DSRequest request) { // Update `employeesGrid` now that an employee has been removed from // the selected team. This will add the employee back to `employeesGrid`, // the list of employees who are not in the team. mockAddEmployeesFromTeamMemberRecords(record); } }); } }); ListGridField employeeIdField2 = new ListGridField("EmployeeId", "EID"); employeeIdField2.setWidth("20%"); ListGridField employeeNameField2 = new ListGridField("EmployeeName", "Employee Name"); employeeNameField2.setWidth("40%"); ListGridField teamNameField = new ListGridField("TeamName", "Team Name"); teamMembersGrid.setFields(employeeIdField2, employeeNameField2, teamNameField); HStack hStack = new HStack(10); hStack.setHeight(160); VStack vStack = new VStack(); LayoutSpacer spacer = new LayoutSpacer(); spacer.setHeight(30); vStack.addMember(spacer); vStack.addMember(employeesGrid); hStack.addMember(vStack); Img arrowImg = new Img("icons/32/arrow_right.png", 32, 32); arrowImg.setLayoutAlign(Alignment.CENTER); arrowImg.addClickHandler(new ClickHandler() { @Override public void onClick(ClickEvent event) { ListGridRecord[] selectedEmployeeRecords = employeesGrid.getSelectedRecords(); teamMembersGrid.transferSelectedData(employeesGrid); mockRemoveEmployees(selectedEmployeeRecords); } }); hStack.addMember(arrowImg); VStack vStack2 = new VStack(); teamSelectItem.addChangedHandler(new ChangedHandler() { @Override public void onChanged(ChangedEvent event) { splitEmployeesByTeam(teamSelectionForm, employeesGrid, teamMembersGrid); } }); teamSelectItem.addDataArrivedHandler(new DataArrivedHandler() { @Override public void onDataArrived(DataArrivedEvent event) { if (teamSelectItem.getValue() == null && event.getStartRow() == 0 && event.getEndRow() > 0) { Record record = event.getData().get(0); Object value; if (record == null || record == ResultSet.getLoadingMarker()) { value = null; } else { String valueFieldName = teamSelectItem.getValueFieldName(); value = record.getAttributeAsObject(valueFieldName); } teamSelectItem.setValue(value); splitEmployeesByTeam(teamSelectionForm, employeesGrid, teamMembersGrid); } } }); teamSelectionForm.setFields(teamSelectItem); vStack2.addMember(teamSelectionForm); vStack2.addMember(teamMembersGrid); hStack.addMember(vStack2); hStack.draw(); } private void splitEmployeesByTeam( DynamicForm teamSelectionForm, ListGrid employeesGrid, ListGrid teamMembersGrid) { Criteria criteria = teamSelectionForm.getValuesAsCriteria(); teamMembersGrid.fetchData(criteria); DSRequest request = new DSRequest(DSOperationType.FETCH, "fetchEmployeesNotInTeam"); employeesGrid.fetchData(criteria, null, request); } }