Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

The contents of employees.ds.xml should now be:

Code Block
xml
xml
titleemployees.ds.xmlxml
<DataSource
    ID="employees"
    serverType="sql"
    tableName="employeeTable"
    recordName="employee"
    testFileName="shared/ds/test_data/employees.data.xml"

>
    <fields>
        <field name="userOrder"       title="userOrder"       type="integer"  canEdit="false"    hidden="true"/>
        <field name="Name"            title="Name"            type="text"     length="128"/>
        <field name="EmployeeId"      title="Employee ID"     type="integer"  primaryKey="true"  required="true"/>
        <field name="ReportsTo"       title="Manager"         type="integer"  required="true"
               foreignKey="employees.EmployeeId"  rootValue="1"/>
        <field name="Job"             title="Title"           type="text"     length="128"/>
        <field name="Email"           title="Email"           type="text"     length="128"/>
        <field name="EmployeeType"    title="Employee Type"   type="text"     length="40"/>
        <field name="EmployeeStatus"  title="Status"          type="text"     length="40"/>
        <field name="Salary"          title="Salary"          type="float"/>
        <field name="OrgUnit"         title="Org Unit"        type="text"     length="128"/>
        <field name="Gender"          title="Gender"          type="text"     length="7">
            <valueMap>
                <value>male</value>
                <value>female</value>
            </valueMap>
        </field>
        <field name="MaritalStatus"   title="Marital Status"  type="text"     length="10">
            <valueMap>
                <value>married</value>
                <value>single</value>
            </valueMap>
        </field>
    </fields>
</DataSource>

...

We will start with the following HTML template, which should be saved to src/main/webapp/index.html:

Code Block
html
html
titleindex.htmlhtml
<!DOCTYPE html>
<html>
  <head>
    <title>Persistent Reorderable ListGrid Sample</title>
    <script>var isomorphicDir = "isomorphic/";</script>
    <script src="isomorphic/system/modules/ISC_Core.js"></script>
    <script src="isomorphic/system/modules/ISC_Foundation.js"></script>
    <script src="isomorphic/system/modules/ISC_Containers.js"></script>
    <script src="isomorphic/system/modules/ISC_Grids.js"></script>
    <script src="isomorphic/system/modules/ISC_Forms.js"></script>
    <script src="isomorphic/system/modules/ISC_DataBinding.js"></script>
  </head>
  <body>
    <script src="isomorphic/skins/TreeFrog/load_skin.js"></script>
    <script src="isomorphic/DataSourceLoader?dataSource=employees"></script>
    <script src="app.js"></script>
  </body>
</html>

...

Also create a file at src/main/webapp/app.js containing the following:

Code Block
JavaScript
JavaScript
titleapp.jsJavaScript
var listGrid = isc.ListGrid.create({
    width:900,
    height:500,
    dataSource:window.employees,
    autoFetchData:true,
    canEdit:true,
    canReorderRecords:true,
    autoSaveEdits:true
});

...

The final app.js is:

Code Block
JavaScript
JavaScript
titleapp.jsJavaScript
var listGrid = isc.ListGrid.create({
    width:900,
    height:500,
    dataSource:window.employees,
    autoFetchData:true,
    canEdit:true,
    canGroupBy:false,
    canReorderRecords:true,
    canSort:false, // Disable user sorting because we rely on records being sorted by 'userOrder'.
    autoSaveEdits:true,

    recordDrop : function (dropRecords, targetRecord, targetIndex, sourceWidget) {
        if (this == sourceWidget && dropRecords.length != 0) {
            var data = this.data;
            var dropRecordIndices = dropRecords.map(function (record) {
                return data.findIndex("EmployeeId", record.EmployeeId);
            });

            var indicesMin = Math.min(dropRecordIndices.min(), targetIndex);
            var indicesMax = Math.max(dropRecordIndices.max(), targetIndex - 1);

            var startedQueue = !isc.RPCManager.startQueue();
            var ds = isc.DS.get(this.dataSource);
            var request = {
                operation:this.updateOperation,
                application:this.application,
                willHandleError:true,
                oldValues:{ userOrder:0 },
                componentId:this.ID
            };

            // Update the 'userOrder' fields for all records at indices [indicesMin, indicesMax].
            var userOrders = new Array(indicesMax + 1 - indicesMin);
            var i;
            for (i = indicesMin; i <= indicesMax; ++i) {
                var record = data.get(i);
                userOrders[i - indicesMin] = record.userOrder;
            }
            var numDropRecordsAfterOrAtTargetIndex = 0;
            for (i = indicesMax; i >= targetIndex; --i) {
                if (dropRecordIndices.contains(i)) {
                    ++numDropRecordsAfterOrAtTargetIndex;
                }
            }
            var numDropRecordsBeforeTargetIndex = dropRecords.length - numDropRecordsAfterOrAtTargetIndex;
            var j = 0; // how many drop records have been encountered so far.
            for (i = indicesMin; i < targetIndex; ++i) {
                var record = data.get(i);
                request.oldValues.userOrder = record.userOrder;
                request._originalRecord = isc.shallowClone(record);

                var updates = ds.filterPrimaryKeyFields(record);
                if (dropRecordIndices.contains(i)) {
                    updates.userOrder = record.userOrder = userOrders[targetIndex - numDropRecordsBeforeTargetIndex + j - indicesMin];
                    ++j;
                } else {
                    updates.userOrder = record.userOrder = userOrders[i - j - indicesMin];
                }
                ds.updateData(updates, null, request);
            }
            j = 0;
            for (i = indicesMax; i >= targetIndex; --i) {
                var record = data.get(i);
                request.oldValues.userOrder = record.userOrder;
                request._originalRecord = isc.shallowClone(record);

                var updates = ds.filterPrimaryKeyFields(record);
                if (dropRecordIndices.contains(i)) {
                    updates.userOrder = record.userOrder = userOrders[targetIndex + numDropRecordsAfterOrAtTargetIndex - 1 - j - indicesMin];
                    ++j;
                } else {
                    updates.userOrder = record.userOrder = userOrders[i + j - indicesMin];
                }
                ds.updateData(updates, null, request);
            }

            // If we're queuing, send the queue now.
            if (startedQueue) {
                isc.RPCManager.sendQueue(null, null, null, true);
            }
        }

        // Call the super implementation of recordDrop() to update the order of rows in the ListGrid.
        this.Super("recordDrop", arguments);
    }
});
listGrid.addSort({ property:"userOrder" });

...