2010-10-20 20:11:15 +02:00
|
|
|
/*
|
|
|
|
|
|
|
|
Copyright 2010, Google Inc.
|
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions are
|
|
|
|
met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above
|
|
|
|
copyright notice, this list of conditions and the following disclaimer
|
|
|
|
in the documentation and/or other materials provided with the
|
|
|
|
distribution.
|
|
|
|
* Neither the name of Google Inc. nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived from
|
|
|
|
this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
|
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
|
|
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
|
|
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
|
|
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
|
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
|
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
|
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2010-08-09 03:13:57 +02:00
|
|
|
DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
|
|
|
|
var doTextTransform = function(expression, onError, repeat, repeatCount) {
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"text-transform",
|
|
|
|
{
|
|
|
|
columnName: column.name,
|
|
|
|
expression: expression,
|
|
|
|
onError: onError,
|
|
|
|
repeat: repeat,
|
|
|
|
repeatCount: repeatCount
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ cellsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doTextTransformPrompt = function() {
|
|
|
|
var frame = $(
|
|
|
|
DOM.loadHTML("core", "scripts/views/data-table/text-transform-dialog.html")
|
|
|
|
.replace("$EXPRESSION_PREVIEW_WIDGET$", ExpressionPreviewDialog.generateWidgetHtml()));
|
|
|
|
|
|
|
|
var elmts = DOM.bind(frame);
|
|
|
|
elmts.dialogHeader.text("Custom text transform on column " + column.name);
|
|
|
|
|
|
|
|
var level = DialogSystem.showDialog(frame);
|
|
|
|
var dismiss = function() { DialogSystem.dismissUntil(level - 1); };
|
|
|
|
|
|
|
|
elmts.cancelButton.click(dismiss);
|
|
|
|
elmts.okButton.click(function() {
|
|
|
|
doTextTransform(
|
|
|
|
previewWidget.getExpression(true),
|
|
|
|
$('input[name="text-transform-dialog-onerror-choice"]:checked')[0].value,
|
|
|
|
elmts.repeatCheckbox[0].checked,
|
|
|
|
elmts.repeatCountInput[0].value
|
|
|
|
);
|
|
|
|
dismiss();
|
|
|
|
});
|
|
|
|
|
|
|
|
var o = DataTableView.sampleVisibleRows(column);
|
|
|
|
var previewWidget = new ExpressionPreviewDialog.Widget(
|
|
|
|
elmts,
|
|
|
|
column.cellIndex,
|
|
|
|
o.rowIndices,
|
|
|
|
o.values,
|
|
|
|
null
|
|
|
|
);
|
|
|
|
previewWidget._prepareUpdate = function(params) {
|
|
|
|
params.repeat = elmts.repeatCheckbox[0].checked;
|
|
|
|
params.repeatCount = elmts.repeatCountInput[0].value;
|
|
|
|
};
|
|
|
|
elmts.repeatCheckbox.click(function() {
|
|
|
|
previewWidget.update();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var doFillDown = function() {
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"fill-down",
|
|
|
|
{
|
|
|
|
columnName: column.name
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doBlankDown = function() {
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"blank-down",
|
|
|
|
{
|
|
|
|
columnName: column.name
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doJoinMultiValueCells = function() {
|
|
|
|
var separator = window.prompt("Enter separator to use between values", ", ");
|
|
|
|
if (separator !== null) {
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"join-multi-value-cells",
|
|
|
|
{
|
|
|
|
columnName: column.name,
|
|
|
|
keyColumnName: theProject.columnModel.keyColumnName,
|
|
|
|
separator: separator
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ rowsChanged: true }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
var doSplitMultiValueCells = function() {
|
|
|
|
var separator = window.prompt("What separator currently separates the values?", ",");
|
|
|
|
if (separator !== null) {
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"split-multi-value-cells",
|
|
|
|
{
|
|
|
|
columnName: column.name,
|
|
|
|
keyColumnName: theProject.columnModel.keyColumnName,
|
|
|
|
separator: separator,
|
|
|
|
mode: "plain"
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ rowsChanged: true }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
MenuSystem.appendTo(menu, [ "core/edit-cells" ], [
|
|
|
|
{
|
|
|
|
id: "core/text-transform",
|
|
|
|
label: "Transform ...",
|
|
|
|
click: function() { doTextTransformPrompt(); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/common-transforms",
|
|
|
|
label: "Common Transforms",
|
|
|
|
submenu: [
|
|
|
|
{
|
2010-10-18 03:53:23 +02:00
|
|
|
id: "core/trim-whitespace",
|
|
|
|
label: "Trim leading and trailing whitespace",
|
|
|
|
click: function() { doTextTransform("value.trim()", "store-blank", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/collapse-whitespace",
|
2010-10-18 03:53:23 +02:00
|
|
|
label: "Collapse consecutive whitespace",
|
2010-08-31 21:47:01 +02:00
|
|
|
click: function() { doTextTransform("value.replace(/\\s+/,' ')", "store-blank", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{},
|
2010-10-18 03:53:23 +02:00
|
|
|
{
|
|
|
|
id: "core/unescape-html-entities",
|
|
|
|
label: "Unescape HTML entities",
|
|
|
|
click: function() { doTextTransform("value.unescape('html')", "store-blank", true, 10); }
|
|
|
|
},
|
|
|
|
{},
|
2010-08-09 03:13:57 +02:00
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/to-titlecase",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "To Titlecase",
|
|
|
|
click: function() { doTextTransform("toTitlecase(value)", "store-blank", false, ""); }
|
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/to-uppercase",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "To Uppercase",
|
|
|
|
click: function() { doTextTransform("toUppercase(value)", "store-blank", false, ""); }
|
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/to-lowercase",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "To Lowercase",
|
|
|
|
click: function() { doTextTransform("toLowercase(value)", "store-blank", false, ""); }
|
|
|
|
},
|
2010-10-18 03:53:23 +02:00
|
|
|
{},
|
|
|
|
{
|
|
|
|
id: "core/to-number",
|
|
|
|
label: "To number",
|
|
|
|
click: function() { doTextTransform("toNumber(value)", "store-blank", false, ""); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/to-date",
|
|
|
|
label: "To date",
|
|
|
|
click: function() { doTextTransform("toDate(value)", "store-blank", false, ""); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/to-text",
|
|
|
|
label: "To text",
|
|
|
|
click: function() { doTextTransform("toString(value)", "store-blank", false, ""); }
|
|
|
|
},
|
|
|
|
{},
|
2010-08-09 03:13:57 +02:00
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/to-blank",
|
2010-10-18 03:53:23 +02:00
|
|
|
label: "Blank out cells",
|
2010-08-09 03:13:57 +02:00
|
|
|
click: function() { doTextTransform("null", "store-blank", false, ""); }
|
|
|
|
}
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/fill-down",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "Fill Down",
|
|
|
|
click: doFillDown
|
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/blank-down",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "Blank Down",
|
|
|
|
click: doBlankDown
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/split-multi-valued-cells",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "Split Multi-Valued Cells ...",
|
|
|
|
click: doSplitMultiValueCells
|
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/join-multi-valued-cells",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "Join Multi-Valued Cells ...",
|
|
|
|
click: doJoinMultiValueCells
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/cluster",
|
2010-08-09 03:13:57 +02:00
|
|
|
label: "Cluster & Edit ...",
|
|
|
|
click: function() { new ClusteringDialog(column.name, "value"); }
|
|
|
|
}
|
|
|
|
]);
|
|
|
|
|
|
|
|
var doTransposeColumnsIntoRows = function() {
|
|
|
|
var dialog = $(DOM.loadHTML("core", "scripts/views/data-table/transpose-columns-into-rows.html"));
|
|
|
|
|
|
|
|
var elmts = DOM.bind(dialog);
|
|
|
|
elmts.dialogHeader.text('Transpose Cells Across Columns into Rows');
|
|
|
|
|
|
|
|
var level = DialogSystem.showDialog(dialog);
|
|
|
|
var dismiss = function() {
|
|
|
|
DialogSystem.dismissUntil(level - 1);
|
|
|
|
};
|
|
|
|
|
|
|
|
var columns = theProject.columnModel.columns;
|
|
|
|
|
|
|
|
elmts.cancelButton.click(function() { dismiss(); });
|
|
|
|
elmts.okButton.click(function() {
|
|
|
|
var config = {
|
|
|
|
startColumnName: elmts.fromColumnSelect[0].value,
|
|
|
|
columnCount: elmts.toColumnSelect[0].value,
|
|
|
|
combinedColumnName: $.trim(elmts.combinedColumnNameInput[0].value),
|
|
|
|
prependColumnName: elmts.prependColumnNameCheckbox[0].checked,
|
|
|
|
separator: elmts.separatorInput[0].value,
|
|
|
|
ignoreBlankCells: elmts.ignoreBlankCellsCheckbox[0].checked
|
|
|
|
};
|
|
|
|
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"transpose-columns-into-rows",
|
|
|
|
config,
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
dismiss();
|
|
|
|
});
|
|
|
|
|
|
|
|
for (var i = 0; i < columns.length; i++) {
|
|
|
|
var column2 = columns[i];
|
|
|
|
var option = $('<option>').attr("value", column2.name).text(column2.name).appendTo(elmts.fromColumnSelect);
|
|
|
|
if (column2.name == column.name) {
|
|
|
|
option.attr("selected", "true");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var populateToColumn = function() {
|
|
|
|
elmts.toColumnSelect.empty();
|
|
|
|
|
|
|
|
var toColumnName = elmts.fromColumnSelect[0].value;
|
|
|
|
|
|
|
|
var j = 0;
|
|
|
|
for (; j < columns.length; j++) {
|
|
|
|
var column2 = columns[j];
|
|
|
|
if (column2.name == toColumnName) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var k = j + 1; k < columns.length; k++) {
|
|
|
|
var column2 = columns[k];
|
|
|
|
var option = $('<option>').attr("value", k - j + 1).text(column2.name).appendTo(elmts.toColumnSelect);
|
|
|
|
if (k == columns.length - 1) {
|
|
|
|
option.attr("selected", "true");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
populateToColumn();
|
|
|
|
|
|
|
|
elmts.fromColumnSelect.bind("change", populateToColumn);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doTransposeRowsIntoColumns = function() {
|
|
|
|
var rowCount = window.prompt("How many rows to transpose?", "2");
|
|
|
|
if (rowCount != null) {
|
|
|
|
try {
|
|
|
|
rowCount = parseInt(rowCount);
|
|
|
|
} catch (e) {
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNaN(rowCount) || rowCount < 2) {
|
|
|
|
alert("Expected an integer at least 2.");
|
|
|
|
} else {
|
|
|
|
var config = {
|
|
|
|
columnName: column.name,
|
|
|
|
rowCount: rowCount
|
|
|
|
};
|
|
|
|
|
2010-09-23 00:55:28 +02:00
|
|
|
Refine.postCoreProcess(
|
2010-08-09 03:13:57 +02:00
|
|
|
"transpose-rows-into-columns",
|
|
|
|
config,
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
MenuSystem.appendTo(menu, [ "core/transpose" ], [
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/transpose-columns-into-rows",
|
2010-10-18 03:53:23 +02:00
|
|
|
label: "Cells Across Columns into Rows ...",
|
2010-08-09 03:13:57 +02:00
|
|
|
click: doTransposeColumnsIntoRows
|
|
|
|
},
|
|
|
|
{
|
2010-10-08 03:54:00 +02:00
|
|
|
id: "core/transpose-rows-into-columns",
|
2010-10-18 03:53:23 +02:00
|
|
|
label: "Cells in Rows into Columns ...",
|
2010-08-09 03:13:57 +02:00
|
|
|
click: doTransposeRowsIntoColumns
|
|
|
|
}
|
|
|
|
]);
|
|
|
|
});
|