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:
|
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
* Redistributions of source code must retain the above copyright
|
2010-10-20 20:11:15 +02:00
|
|
|
notice, this list of conditions and the following disclaimer.
|
2011-08-04 22:37:14 +02:00
|
|
|
* Redistributions in binary form must reproduce the above
|
2010-10-20 20:11:15 +02:00
|
|
|
copyright notice, this list of conditions and the following disclaimer
|
|
|
|
in the documentation and/or other materials provided with the
|
|
|
|
distribution.
|
2011-08-04 22:37:14 +02:00
|
|
|
* Neither the name of Google Inc. nor the names of its
|
2010-10-20 20:11:15 +02:00
|
|
|
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
|
2018-09-23 20:42:33 +02:00
|
|
|
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
2010-10-20 20:11:15 +02:00
|
|
|
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.
|
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
*/
|
2010-10-20 20:11:15 +02:00
|
|
|
|
2010-08-09 03:13:57 +02:00
|
|
|
DataTableColumnHeaderUI.extendMenu(function(column, columnHeaderUI, menu) {
|
2011-08-04 22:37:14 +02:00
|
|
|
var doTextTransform = function(expression, onError, repeat, repeatCount) {
|
|
|
|
Refine.postCoreProcess(
|
|
|
|
"text-transform",
|
|
|
|
{
|
2018-09-23 20:42:33 +02:00
|
|
|
columnName: column.name,
|
2011-08-04 22:37:14 +02:00
|
|
|
onError: onError,
|
|
|
|
repeat: repeat,
|
|
|
|
repeatCount: repeatCount
|
|
|
|
},
|
2014-11-11 11:41:55 +01:00
|
|
|
{ expression: expression },
|
2011-08-04 22:37:14 +02:00
|
|
|
{ cellsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var doTextTransformPrompt = function() {
|
|
|
|
var frame = $(
|
|
|
|
DOM.loadHTML("core", "scripts/views/data-table/text-transform-dialog.html")
|
|
|
|
.replace("$EXPRESSION_PREVIEW_WIDGET$", ExpressionPreviewDialog.generateWidgetHtml()));
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var elmts = DOM.bind(frame);
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.dialogHeader.text($.i18n('core-views/custom-text-trans')+" " + column.name);
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.or_views_errorOn.text($.i18n('core-views/on-error'));
|
|
|
|
elmts.or_views_keepOr.text($.i18n('core-views/keep-or'));
|
|
|
|
elmts.or_views_setBlank.text($.i18n('core-views/set-blank'));
|
|
|
|
elmts.or_views_storeErr.text($.i18n('core-views/store-err'));
|
|
|
|
elmts.or_views_reTrans.text($.i18n('core-views/re-trans'));
|
|
|
|
elmts.or_views_timesChang.text($.i18n('core-views/times-chang'));
|
|
|
|
elmts.okButton.html($.i18n('core-buttons/ok'));
|
|
|
|
elmts.cancelButton.text($.i18n('core-buttons/cancel'));
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
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;
|
2010-08-09 03:13:57 +02:00
|
|
|
};
|
2011-08-04 22:37:14 +02:00
|
|
|
elmts.repeatCheckbox.click(function() {
|
|
|
|
previewWidget.update();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var doFillDown = function() {
|
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"fill-down",
|
2011-08-04 22:37:14 +02:00
|
|
|
{
|
|
|
|
columnName: column.name
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doBlankDown = function() {
|
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"blank-down",
|
2011-08-04 22:37:14 +02:00
|
|
|
{
|
|
|
|
columnName: column.name
|
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doJoinMultiValueCells = function() {
|
2018-11-21 18:30:00 +01:00
|
|
|
var separator = window.prompt($.i18n('core-views/enter-separator'), ", ");
|
2011-08-04 22:37:14 +02:00
|
|
|
if (separator !== null) {
|
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"join-multi-value-cells",
|
2011-08-04 22:37:14 +02:00
|
|
|
{
|
|
|
|
columnName: column.name,
|
|
|
|
keyColumnName: theProject.columnModel.keyColumnName,
|
2017-10-23 08:46:33 +02:00
|
|
|
separator
|
2011-08-04 22:37:14 +02:00
|
|
|
},
|
|
|
|
null,
|
|
|
|
{ rowsChanged: true }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-09-23 20:42:33 +02:00
|
|
|
var doReplace = function() {
|
2018-10-14 22:39:29 +02:00
|
|
|
function isValidRegexPattern(p) {
|
2018-09-23 20:42:33 +02:00
|
|
|
// check if a string can be used as a regexp pattern
|
|
|
|
// parameters :
|
|
|
|
// p : a string without beginning and trailing "/"
|
|
|
|
|
|
|
|
// we need a manual check for unescaped /
|
2018-11-18 12:27:55 +01:00
|
|
|
// the GREL replace() function cannot contain a pattern with unescaped /
|
2018-09-23 20:42:33 +02:00
|
|
|
// but javascript Regexp accepts it and auto escape it
|
|
|
|
var pos = p.replace(/\\\//g,'').indexOf("/");
|
|
|
|
if (pos != -1) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/warning-regex') + " : " + p);
|
2018-09-23 20:42:33 +02:00
|
|
|
return 0;}
|
|
|
|
try {
|
|
|
|
var pattern = new RegExp(p);
|
|
|
|
return 1;
|
|
|
|
} catch (e) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/warning-regex') + " : " + p);
|
2018-09-23 20:42:33 +02:00
|
|
|
return 0;}
|
|
|
|
}
|
|
|
|
function escapeInputString(s) {
|
2018-10-14 22:39:29 +02:00
|
|
|
// if the input is used as a plain string
|
2018-09-23 20:42:33 +02:00
|
|
|
// user input | result after escaping
|
|
|
|
// 4 characters : A\tA | 5 characters : A\\tA
|
|
|
|
// 4 characters : A\nA | 5 characters : A\\nA
|
|
|
|
// 1 characters : \ | 2 characters : \\
|
|
|
|
// 1 character : ' | 2 characters : \'
|
|
|
|
// 1 character : " | 2 characters : \"
|
2018-11-18 12:27:55 +01:00
|
|
|
// new line or tab | nothing
|
|
|
|
// other non printable char | nothing
|
2018-09-23 20:42:33 +02:00
|
|
|
// parameters :
|
2018-10-14 22:39:29 +02:00
|
|
|
// s : a string from an HTML input
|
2018-11-18 12:27:55 +01:00
|
|
|
// Note: if the input field is replaced with a textarea, it could be imaginable to escape new lines and tabs as \n and \t
|
2018-10-14 22:39:29 +02:00
|
|
|
if (typeof s != 'string') {
|
|
|
|
return "";
|
2018-09-23 20:42:33 +02:00
|
|
|
}
|
2018-11-18 12:27:55 +01:00
|
|
|
// delete new lines, tabs and other non printable characters, and escape \ ' and "
|
|
|
|
return s.replace(/[\x00-\x1F\x80-\x9F]/g, '').replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/"/g, '\\"')
|
2018-09-23 20:42:33 +02:00
|
|
|
}
|
|
|
|
function escapeInputRegex(s) {
|
2018-10-14 22:39:29 +02:00
|
|
|
// if the HTML input is used as a regex pattern
|
2018-11-18 12:27:55 +01:00
|
|
|
// delete new lines, tabs and other non printable characters
|
2018-09-23 20:42:33 +02:00
|
|
|
// no need to escape \ or /
|
|
|
|
// parameters :
|
2018-10-14 22:39:29 +02:00
|
|
|
// s : a string from a HTML input
|
2018-09-23 20:42:33 +02:00
|
|
|
return (typeof s == 'string') ? s.replace(/[\x00-\x1F\x80-\x9F]/g, '') : ""
|
|
|
|
}
|
2018-11-18 12:27:55 +01:00
|
|
|
function escapedStringToRegex(s) {
|
|
|
|
// converts a plain string (beforehand escaped with escapeInputString) to regex, in order to use the i flag
|
2018-09-23 20:42:33 +02:00
|
|
|
// escaping is needed to force the regex processor to interpret every character litteraly
|
|
|
|
// parameters :
|
2018-10-14 22:39:29 +02:00
|
|
|
// s : a string from a HTML input, preprocessed with escapeInputString
|
|
|
|
if (typeof s != 'string') {
|
|
|
|
return "";
|
|
|
|
}
|
2018-11-18 12:27:55 +01:00
|
|
|
// we MUST NOT escape \ : already escaped by escapeInputString
|
2018-09-23 20:42:33 +02:00
|
|
|
var EscapeCharsRegex = /[-|{}()[\]^$+*?.]/g;
|
|
|
|
// FIXME escaping of / directly by adding / or \/ or // in EscapeCharsRegex don't work...
|
|
|
|
return s.replace(EscapeCharsRegex, '\\$&').replace(/\//g, '\\/');
|
|
|
|
}
|
|
|
|
function escapeReplacementString(dont_escape,s) {
|
|
|
|
// in replacement string, the GREL replace function handle in a specific way the Java special escape sequences
|
|
|
|
// cf https://docs.oracle.com/javase/tutorial/java/data/characters.html
|
|
|
|
// Escape Sequence | Java documentation | GREL replace function
|
|
|
|
// \t | tab | tabs
|
|
|
|
// \n | new line | new line
|
|
|
|
// \r | carriage return | <blank>
|
|
|
|
// \b | backspace | b
|
|
|
|
// \f | formfeed | f
|
|
|
|
// \' | ' | ''
|
|
|
|
// \" | " | ""
|
|
|
|
// \\ | \ | \
|
|
|
|
// GREL replace function returns an error if a \ is not followed by an other character
|
|
|
|
// it could be unexpected for the user, so the replace menu escape the replacement string, but gives the possibility to choose the default behavior
|
2018-10-14 22:39:29 +02:00
|
|
|
// if dont_escape = 0, every \ are escaped as \\
|
|
|
|
// if dont_escape = 1, \t and \n are not escaped, but \r, \b, \f are escaped as \\r, \\b, \\f
|
|
|
|
// in both case, new lines and tabs manually typed in the input are converted into \n and \t, and non printable characters are deleted
|
2018-09-23 20:42:33 +02:00
|
|
|
// parameters :
|
|
|
|
// replace_dont_escape : 0 or 1
|
2018-10-14 22:39:29 +02:00
|
|
|
// s : a string from a HTML input
|
|
|
|
if (typeof s != 'string') {
|
|
|
|
return "";
|
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
var temp = s;
|
2018-10-14 22:39:29 +02:00
|
|
|
if (dont_escape == 0) {
|
|
|
|
temp = temp.replace(/\\/g, '\\\\');
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// replace "\n" with newline and "\t" with tab
|
|
|
|
temp = temp.replace(/\\n/g, '\n').replace(/\\t/g, '\t');
|
|
|
|
// replace "\" with "\\"
|
|
|
|
temp = temp.replace(/\\/g, '\\\\');
|
|
|
|
// replace "\newline" with "\n" and "\tab" with "\t"
|
|
|
|
temp = temp.replace(/\\\n/g, '\\n').replace(/\\\t/g, '\\t');
|
|
|
|
}
|
|
|
|
// replace newline with "\n" and tab with "\t"
|
2018-09-23 20:42:33 +02:00
|
|
|
return temp.replace(/\n/g, '\\n').replace(/\t/g, '\\t').replace(/[\x00-\x1F\x80-\x9F]/g,'');
|
|
|
|
}
|
|
|
|
var frame = $(DOM.loadHTML("core", "scripts/views/data-table/replace-dialog.html"));
|
|
|
|
var elmts = DOM.bind(frame);
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.dialogHeader.text($.i18n('core-views/replace'));
|
|
|
|
elmts.or_views_text_to_find.text($.i18n('core-views/text-to-find'));
|
|
|
|
elmts.or_views_replacement.text($.i18n('core-views/replacement-text'));
|
|
|
|
elmts.or_views_finding_info1.text($.i18n('core-views/finding-info1'));
|
|
|
|
elmts.or_views_finding_info2.text($.i18n('core-views/finding-info2'));
|
|
|
|
elmts.or_views_replacement_info.text($.i18n('core-views/replacement-info'));
|
|
|
|
elmts.or_views_find_regExp.text($.i18n('core-views/reg-exp'));
|
|
|
|
elmts.or_views_find_case_insensitive.text($.i18n('core-views/case-insensitive'));
|
|
|
|
elmts.or_views_find_whole_word.text($.i18n('core-views/whole-word'));
|
|
|
|
elmts.or_views_replace_dont_escape.text($.i18n('core-views/replace-dont-escape'));
|
|
|
|
elmts.okButton.html($.i18n('core-buttons/ok'));
|
|
|
|
elmts.cancelButton.text($.i18n('core-buttons/cancel'));
|
2018-09-23 20:42:33 +02:00
|
|
|
var level = DialogSystem.showDialog(frame);
|
|
|
|
var dismiss = function() { DialogSystem.dismissUntil(level - 1); };
|
|
|
|
elmts.cancelButton.click(dismiss);
|
|
|
|
elmts.okButton.click(function() {
|
2018-10-14 22:39:29 +02:00
|
|
|
var text_to_find = elmts.text_to_findInput[0].value;
|
|
|
|
var replacement_text = elmts.replacement_textInput[0].value;
|
2018-09-23 20:42:33 +02:00
|
|
|
var replace_dont_escape = elmts.replace_dont_escapeInput[0].checked;
|
|
|
|
var find_regex = elmts.find_regexInput[0].checked;
|
|
|
|
var find_case_insensitive = elmts.find_case_insensitiveInput[0].checked;
|
2018-10-14 22:39:29 +02:00
|
|
|
var find_whole_word = elmts.find_whole_wordInput[0].checked;
|
2018-09-23 20:42:33 +02:00
|
|
|
replacement_text = escapeReplacementString(replace_dont_escape, replacement_text)
|
2018-11-18 12:27:55 +01:00
|
|
|
if (find_regex) {
|
|
|
|
text_to_find = escapeInputRegex(text_to_find);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
text_to_find = escapeInputString(text_to_find);
|
|
|
|
}
|
2018-10-14 22:39:29 +02:00
|
|
|
if (!find_regex && (find_case_insensitive || find_whole_word)) {
|
2018-11-18 12:27:55 +01:00
|
|
|
text_to_find = escapedStringToRegex(text_to_find);
|
2018-09-23 20:42:33 +02:00
|
|
|
}
|
2018-10-14 22:39:29 +02:00
|
|
|
if (find_regex || find_case_insensitive || find_whole_word ) {
|
|
|
|
if (!isValidRegexPattern (text_to_find)) {
|
|
|
|
return;
|
2018-09-23 20:42:33 +02:00
|
|
|
}
|
2018-10-14 22:39:29 +02:00
|
|
|
if (find_whole_word) {
|
|
|
|
text_to_find = "\\b"+text_to_find+"\\b";
|
|
|
|
}
|
|
|
|
text_to_find = "/"+text_to_find+"/";
|
|
|
|
if (find_case_insensitive) {
|
|
|
|
text_to_find = text_to_find+"i";
|
2018-09-23 20:42:33 +02:00
|
|
|
}
|
|
|
|
}
|
2018-10-14 22:39:29 +02:00
|
|
|
else {
|
|
|
|
text_to_find = '"'+text_to_find+'"';
|
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
expression = 'value.replace('+text_to_find+',"'+replacement_text+'")';
|
|
|
|
doTextTransform(expression, "keep-original", false, "");
|
|
|
|
dismiss();
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var doSplitMultiValueCells = function() {
|
2017-10-23 00:53:18 +02:00
|
|
|
|
|
|
|
var frame = $(DOM.loadHTML("core", "scripts/views/data-table/split-multi-valued-cells-dialog.html"));
|
|
|
|
var elmts = DOM.bind(frame);
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.dialogHeader.text($.i18n('core-views/split-cells'));
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.or_views_howSplit.text($.i18n('core-views/how-split-cells'));
|
|
|
|
elmts.or_views_bySep.text($.i18n('core-views/by-sep'));
|
|
|
|
elmts.or_views_separator.text($.i18n('core-views/separator'));
|
|
|
|
elmts.or_views_regExp.text($.i18n('core-views/reg-exp'));
|
2017-10-23 00:53:18 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.or_views_fieldLen.text($.i18n('core-views/field-len'));
|
|
|
|
elmts.or_views_listInt.text($.i18n('core-views/list-int'));
|
2017-10-23 00:53:18 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.okButton.html($.i18n('core-buttons/ok'));
|
|
|
|
elmts.cancelButton.text($.i18n('core-buttons/cancel'));
|
2017-10-23 00:53:18 +02:00
|
|
|
|
|
|
|
var level = DialogSystem.showDialog(frame);
|
|
|
|
var dismiss = function() { DialogSystem.dismissUntil(level - 1); };
|
2019-08-28 19:35:33 +02:00
|
|
|
|
2019-08-31 06:50:34 +02:00
|
|
|
elmts.separatorInput.focus().select();
|
2019-08-28 19:59:59 +02:00
|
|
|
|
2017-10-23 00:53:18 +02:00
|
|
|
elmts.cancelButton.click(dismiss);
|
|
|
|
elmts.okButton.click(function() {
|
|
|
|
var mode = $("input[name='split-by-mode']:checked")[0].value;
|
|
|
|
var config = {
|
|
|
|
columnName: column.name,
|
|
|
|
keyColumnName: theProject.columnModel.keyColumnName,
|
2017-10-23 09:54:26 +02:00
|
|
|
mode
|
2017-10-23 00:53:18 +02:00
|
|
|
};
|
2017-10-23 08:46:33 +02:00
|
|
|
if (mode === "separator") {
|
2017-10-23 00:53:18 +02:00
|
|
|
config.separator = elmts.separatorInput[0].value;
|
|
|
|
if (!(config.separator)) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/specify-sep'));
|
2017-10-23 00:53:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
config.regex = elmts.regexInput[0].checked;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
var s = "[" + elmts.lengthsTextarea[0].value + "]";
|
|
|
|
try {
|
|
|
|
var a = JSON.parse(s);
|
|
|
|
|
|
|
|
var lengths = [];
|
2018-09-23 20:42:33 +02:00
|
|
|
$.each(a, function(i,n) {
|
2017-10-23 00:53:18 +02:00
|
|
|
if (typeof n == "number") {
|
2018-09-23 20:42:33 +02:00
|
|
|
lengths.push(n);
|
2017-10-23 00:53:18 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (lengths.length === 0) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/warning-no-length'));
|
2017-10-23 00:53:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
config.fieldLengths = JSON.stringify(lengths);
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2017-10-23 00:53:18 +02:00
|
|
|
} catch (e) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/warning-format'));
|
2017-10-23 00:53:18 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"split-multi-value-cells",
|
2017-10-23 00:53:18 +02:00
|
|
|
config,
|
2011-08-04 22:37:14 +02:00
|
|
|
null,
|
|
|
|
{ rowsChanged: true }
|
|
|
|
);
|
2017-10-23 00:53:18 +02:00
|
|
|
|
|
|
|
dismiss();
|
|
|
|
});
|
2011-08-04 22:37:14 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
MenuSystem.appendTo(menu, [ "core/edit-cells" ], [
|
|
|
|
{
|
|
|
|
id: "core/text-transform",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/transform')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: function() { doTextTransformPrompt(); }
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/common-transforms",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/common-transform'),
|
2011-08-04 22:37:14 +02:00
|
|
|
submenu: [
|
|
|
|
{
|
|
|
|
id: "core/trim-whitespace",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/trim-all'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.trim()", "keep-original", false, ""); }
|
2011-08-04 22:37:14 +02:00
|
|
|
},
|
2010-08-09 03:13:57 +02:00
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/collapse-whitespace",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/collapse-white'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.replace(/\\s+/,' ')", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
2011-08-04 22:37:14 +02:00
|
|
|
{},
|
2010-08-09 03:13:57 +02:00
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/unescape-html-entities",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/unescape-html'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.unescape('html')", "keep-original", true, 10); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
2018-12-09 12:03:11 +01:00
|
|
|
{
|
|
|
|
id: "core/replace-smartquotes",
|
|
|
|
label: $.i18n('core-views/replace-smartquotes'),
|
|
|
|
click: function() { doTextTransform("value.replace(/[\u2018\u2019\u201A\u201B\u2039\u203A\u201A]/,\"\\\'\").replace(/[\u201C\u201D\u00AB\u00BB\u201E]/,\"\\\"\")", "keep-original", false, ""); }
|
|
|
|
},
|
2010-08-09 03:13:57 +02:00
|
|
|
{},
|
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/to-titlecase",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/titlecase'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toTitlecase()", "keep-original", false, ""); }
|
2011-08-04 22:37:14 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/to-uppercase",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/uppercase'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toUppercase()", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/to-lowercase",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/lowercase'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toLowercase()", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/to-number",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/to-number'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toNumber()", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/to-date",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/to-date'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toDate()", "keep-original", false, ""); }
|
2011-08-04 22:37:14 +02:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/to-text",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/to-text'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("value.toString()", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
2011-08-04 22:37:14 +02:00
|
|
|
id: "core/to-blank",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/blank-out'),
|
2011-09-30 08:09:55 +02:00
|
|
|
click: function() { doTextTransform("null", "keep-original", false, ""); }
|
2018-02-19 00:35:00 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/to-empty",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/blank-out-empty'),
|
2018-02-19 00:35:00 +01:00
|
|
|
click: function() { doTextTransform("\"\"", "keep-original", false, ""); }
|
2010-08-09 03:13:57 +02:00
|
|
|
}
|
2011-08-04 22:37:14 +02:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
id: "core/fill-down",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/fill-down'),
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doFillDown
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/blank-down",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/blank-down'),
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doBlankDown
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
id: "core/split-multi-valued-cells",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/split-cells')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doSplitMultiValueCells
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/join-multi-valued-cells",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/join-cells')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doJoinMultiValueCells
|
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
id: "core/cluster",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/cluster-edit')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: function() { new ClusteringDialog(column.name, "value"); }
|
2018-09-25 08:14:32 +02:00
|
|
|
},
|
2018-10-14 22:39:29 +02:00
|
|
|
{},
|
2018-09-25 08:14:32 +02:00
|
|
|
{
|
|
|
|
id: "core/replace",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/replace'),
|
2018-09-25 08:14:32 +02:00
|
|
|
click: doReplace
|
2011-08-04 22:37:14 +02:00
|
|
|
}
|
|
|
|
]);
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var doTransposeColumnsIntoRows = function() {
|
|
|
|
var dialog = $(DOM.loadHTML("core", "scripts/views/data-table/transpose-columns-into-rows.html"));
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var elmts = DOM.bind(dialog);
|
|
|
|
var level = DialogSystem.showDialog(dialog);
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.dialogHeader.html($.i18n('core-views/transp-cell'));
|
|
|
|
elmts.or_views_fromCol.html($.i18n('core-views/from-col'));
|
|
|
|
elmts.or_views_toCol.html($.i18n('core-views/to-col'));
|
|
|
|
elmts.or_views_transpose.html($.i18n('core-views/transp-into'));
|
|
|
|
elmts.or_views_twoCol.html($.i18n('core-views/two-new-col'));
|
|
|
|
elmts.or_views_keyCol.html($.i18n('core-views/key-col'));
|
|
|
|
elmts.or_views_containNames.html($.i18n('core-views/contain-names'));
|
|
|
|
elmts.or_views_valCol.html($.i18n('core-views/val-col'));
|
|
|
|
elmts.or_views_containOrig.html($.i18n('core-views/contain-val'));
|
|
|
|
elmts.or_views_oneCol.html($.i18n('core-views/one-col'));
|
|
|
|
elmts.or_views_prependName.html($.i18n('core-views/prepend-name'));
|
|
|
|
elmts.or_views_followBy.html($.i18n('core-views/follow-by'));
|
|
|
|
elmts.or_views_beforeVal.html($.i18n('core-views/before-val'));
|
|
|
|
elmts.or_views_ignoreBlank.html($.i18n('core-views/ignore-blank'));
|
|
|
|
elmts.or_views_fillOther.html($.i18n('core-views/fill-other'));
|
|
|
|
elmts.okButton.html($.i18n('core-buttons/transpose'));
|
|
|
|
elmts.cancelButton.html($.i18n('core-buttons/cancel'));
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var dismiss = function() {
|
|
|
|
DialogSystem.dismissUntil(level - 1);
|
|
|
|
};
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var columns = theProject.columnModel.columns;
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
elmts.cancelButton.click(function() { dismiss(); });
|
|
|
|
elmts.okButton.click(function() {
|
|
|
|
var config = {
|
2011-11-06 03:50:33 +01:00
|
|
|
startColumnName: elmts.fromColumnSelect[0].value,
|
|
|
|
columnCount: elmts.toColumnSelect[0].value,
|
2011-11-07 20:39:23 +01:00
|
|
|
ignoreBlankCells: elmts.ignoreBlankCellsCheckbox[0].checked,
|
|
|
|
fillDown: elmts.fillDownCheckbox[0].checked
|
2011-08-04 22:37:14 +02:00
|
|
|
};
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-06 03:50:33 +01:00
|
|
|
var mode = dialog.find('input[name="transpose-dialog-column-choices"]:checked')[0].value;
|
|
|
|
if (mode == "2") {
|
|
|
|
config.keyColumnName = $.trim(elmts.keyColumnNameInput[0].value);
|
|
|
|
config.valueColumnName = $.trim(elmts.valueColumnNameInput[0].value);
|
|
|
|
if (config.keyColumnName == "") {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/spec-new-name'));
|
2011-11-06 03:50:33 +01:00
|
|
|
return;
|
|
|
|
} else if (config.valueColumnName == "") {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/spec-new-val'));
|
2011-11-06 03:50:33 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
config.combinedColumnName = $.trim(elmts.combinedColumnNameInput[0].value);
|
|
|
|
config.prependColumnName = elmts.prependColumnNameCheckbox[0].checked;
|
|
|
|
config.separator = elmts.separatorInput[0].value;
|
|
|
|
if (config.combinedColumnName == "") {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/spec-col-name'));
|
2011-11-06 03:50:33 +01:00
|
|
|
return;
|
|
|
|
} else if (config.prependColumnName && config.separator == "") {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/spec-separator'));
|
2011-11-06 03:50:33 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2011-08-04 22:37:14 +02:00
|
|
|
|
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"transpose-columns-into-rows",
|
2011-08-04 22:37:14 +02:00
|
|
|
config,
|
|
|
|
null,
|
2011-11-06 03:50:33 +01:00
|
|
|
{ modelsChanged: true },
|
|
|
|
{
|
|
|
|
onDone: dismiss
|
|
|
|
}
|
2011-08-04 22:37:14 +02:00
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
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;
|
2010-08-09 03:13:57 +02:00
|
|
|
|
2011-08-04 22:37:14 +02:00
|
|
|
var j = 0;
|
|
|
|
for (; j < columns.length; j++) {
|
|
|
|
var column2 = columns[j];
|
|
|
|
if (column2.name == toColumnName) {
|
|
|
|
break;
|
2010-08-09 03:13:57 +02:00
|
|
|
}
|
2011-08-04 22:37:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
for (var k = j + 1; k < columns.length; k++) {
|
|
|
|
var column2 = columns[k];
|
2011-10-19 15:42:50 +02:00
|
|
|
$('<option>').attr("value", k - j + 1).text(column2.name).appendTo(elmts.toColumnSelect);
|
2011-08-04 22:37:14 +02:00
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-10-19 15:42:50 +02:00
|
|
|
$('<option>')
|
|
|
|
.attr("value", "-1")
|
|
|
|
.attr("selected", "true")
|
|
|
|
.text("(last column)")
|
|
|
|
.appendTo(elmts.toColumnSelect);
|
2011-08-04 22:37:14 +02:00
|
|
|
};
|
|
|
|
populateToColumn();
|
|
|
|
|
|
|
|
elmts.fromColumnSelect.bind("change", populateToColumn);
|
|
|
|
};
|
|
|
|
|
|
|
|
var doTransposeRowsIntoColumns = function() {
|
2018-11-21 18:30:00 +01:00
|
|
|
var rowCount = window.prompt($.i18n('core-views/how-many-rows'), "2");
|
2011-10-08 01:44:11 +02:00
|
|
|
if (rowCount !== null) {
|
2011-08-04 22:37:14 +02:00
|
|
|
try {
|
2011-10-08 01:44:11 +02:00
|
|
|
rowCount = parseInt(rowCount,10);
|
2011-08-04 22:37:14 +02:00
|
|
|
} catch (e) {
|
|
|
|
// ignore
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isNaN(rowCount) || rowCount < 2) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/expect-two'));
|
2011-08-04 22:37:14 +02:00
|
|
|
} else {
|
|
|
|
var config = {
|
|
|
|
columnName: column.name,
|
|
|
|
rowCount: rowCount
|
|
|
|
};
|
|
|
|
|
|
|
|
Refine.postCoreProcess(
|
2018-09-25 08:14:32 +02:00
|
|
|
"transpose-rows-into-columns",
|
2011-08-04 22:37:14 +02:00
|
|
|
config,
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
var doKeyValueColumnize = function() {
|
|
|
|
var dialog = $(DOM.loadHTML("core", "scripts/views/data-table/key-value-columnize.html"));
|
|
|
|
|
|
|
|
var elmts = DOM.bind(dialog);
|
|
|
|
var level = DialogSystem.showDialog(dialog);
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2018-11-21 18:30:00 +01:00
|
|
|
elmts.dialogHeader.html($.i18n('core-views/columnize'));
|
|
|
|
elmts.or_views_keyCol.html($.i18n('core-views/key-col'));
|
|
|
|
elmts.or_views_valCol.html($.i18n('core-views/val-col'));
|
|
|
|
elmts.or_views_noteCol.html($.i18n('core-views/note-col'));
|
|
|
|
elmts.okButton.html($.i18n('core-buttons/ok'));
|
|
|
|
elmts.cancelButton.html($.i18n('core-buttons/cancel'));
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
var dismiss = function() {
|
|
|
|
DialogSystem.dismissUntil(level - 1);
|
|
|
|
};
|
|
|
|
|
|
|
|
var columns = theProject.columnModel.columns;
|
|
|
|
|
|
|
|
elmts.cancelButton.click(function() { dismiss(); });
|
|
|
|
elmts.okButton.click(function() {
|
|
|
|
var config = {
|
|
|
|
keyColumnName: elmts.keyColumnSelect[0].value,
|
|
|
|
valueColumnName: elmts.valueColumnSelect[0].value,
|
|
|
|
noteColumnName: elmts.noteColumnSelect[0].value
|
|
|
|
};
|
|
|
|
if (config.keyColumnName == null ||
|
|
|
|
config.valueColumnName == null ||
|
|
|
|
config.keyColumnName == config.valueColumnName) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/sel-col-val'));
|
2011-11-04 22:00:32 +01:00
|
|
|
return;
|
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
var noteColumnName = elmts.noteColumnSelect[0].value;
|
|
|
|
if (noteColumnName != null) {
|
|
|
|
if (noteColumnName == config.keyColumnName ||
|
|
|
|
noteColumnName == config.valueColumnName) {
|
2018-11-21 18:30:00 +01:00
|
|
|
alert($.i18n('core-views/cannot-same'));
|
2011-11-04 22:00:32 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
config.noteColumnName = noteColumnName;
|
|
|
|
}
|
|
|
|
|
|
|
|
Refine.postCoreProcess(
|
2018-09-23 20:42:33 +02:00
|
|
|
"key-value-columnize",
|
2011-11-04 22:00:32 +01:00
|
|
|
config,
|
|
|
|
null,
|
|
|
|
{ modelsChanged: true }
|
|
|
|
);
|
|
|
|
dismiss();
|
|
|
|
});
|
|
|
|
|
|
|
|
var valueColumnIndex = -1;
|
|
|
|
for (var i = 0; i < columns.length; i++) {
|
|
|
|
var column2 = columns[i];
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
var keyOption = $('<option>').attr("value", column2.name).text(column2.name).appendTo(elmts.keyColumnSelect);
|
|
|
|
if (column2.name == column.name) {
|
|
|
|
keyOption.attr("selected", "true");
|
|
|
|
valueColumnIndex = i + 1;
|
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
var valueOption = $('<option>').attr("value", column2.name).text(column2.name).appendTo(elmts.valueColumnSelect);
|
|
|
|
if (i === valueColumnIndex) {
|
|
|
|
valueOption.attr("selected", "true");
|
|
|
|
}
|
2018-09-23 20:42:33 +02:00
|
|
|
|
2011-11-04 22:00:32 +01:00
|
|
|
$('<option>').attr("value", column2.name).text(column2.name).appendTo(elmts.noteColumnSelect);
|
|
|
|
}
|
2020-03-02 13:57:02 +01:00
|
|
|
|
|
|
|
var currentHeight = dialog.outerHeight();
|
|
|
|
var currentWidth = dialog.outerWidth();
|
|
|
|
dialog.resizable({
|
|
|
|
alsoResize: ".dialog-border .dialog-body",
|
|
|
|
handles: "e, w, se",
|
|
|
|
minHeight: currentHeight,
|
|
|
|
maxHeight: currentHeight,
|
|
|
|
minWidth: currentWidth
|
|
|
|
});
|
2011-11-04 22:00:32 +01:00
|
|
|
};
|
2011-08-04 22:37:14 +02:00
|
|
|
|
|
|
|
MenuSystem.appendTo(menu, [ "core/transpose" ], [
|
|
|
|
{
|
|
|
|
id: "core/transpose-columns-into-rows",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/transp-cell-row')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doTransposeColumnsIntoRows
|
|
|
|
},
|
|
|
|
{
|
|
|
|
id: "core/transpose-rows-into-columns",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/transp-cell-col')+"...",
|
2011-08-04 22:37:14 +02:00
|
|
|
click: doTransposeRowsIntoColumns
|
2011-11-04 22:00:32 +01:00
|
|
|
},
|
|
|
|
{},
|
|
|
|
{
|
|
|
|
id: "core/key-value-columnize",
|
2018-11-21 18:30:00 +01:00
|
|
|
label: $.i18n('core-views/columnize-col')+"...",
|
2011-11-04 22:00:32 +01:00
|
|
|
click: doKeyValueColumnize
|
2011-08-04 22:37:14 +02:00
|
|
|
}
|
|
|
|
]
|
|
|
|
);
|
2018-09-23 20:42:33 +02:00
|
|
|
});
|