Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

recordedit simple array support. #1726

Merged
merged 3 commits into from
Feb 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions common/templates/inputs/inputSwitch.html
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@
<textarea json ng-model="model.value" rows="5" name="{{::column.name}}" class="form-control" empty-to-null></textarea>
</div>

<!--array input -->
<div ng-switch-when="array">
<textarea array column-type="{{column.type.rootName}}" custom-error-message="model.customErrorMessage" ng-model="model.value" rows="5" name="{{::column.name}}" class="form-control" empty-to-null></textarea>
</div>

<!-- disabled -->
<input ng-switch-when="disabled" ng-model="model.value" name="{{::column.name}}" type="text" class="form-control" disabled="true" placeholder="getDisabledInputValue()" empty-to-null></input>

Expand All @@ -128,6 +133,7 @@
<div ng-message="float">Please enter a decimal value.</div>
<div ng-message="json">Please enter a valid JSON value.</div>
<div ng-message="fileExtension">Please select a file with the following type: {{fileExtensionTypes(column)}}</div>
<div ng-message="customError">{{model.customErrorMessage}}</div>
</div>

<!-- Validation error messages to show when the form is submitted -->
Expand Down
32 changes: 32 additions & 0 deletions common/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -1079,6 +1079,9 @@
function getInputType(type) {
var inputType;

if (type.isArray) {
return 'array';
}
switch (type.name) {
case 'timestamp':
case 'timestamptz':
Expand Down Expand Up @@ -1120,6 +1123,34 @@
return inputType;
}

/**
* given a typename string, will return a more human readable version of it.
* @param {string} typename
* @return {string}
*/
function getSimpleColumnType (typename){
switch (typename) {
case "timestamp":
return "timestamp";
case "timestamptz":
return "timestamp with timezone";
case "date":
return "date";
case "float4":
case "float8":
case "numeric":
return "number";
case "boolean":
return "boolean";
case "int2":
case "int4":
case "int8":
return "integer";
default:
return "text";
}
}

/**
* sets the height of domElements.container
* @param {Object} domElements - an object with the following properties:
Expand Down Expand Up @@ -1179,6 +1210,7 @@
getImageAndIframes: getImageAndIframes,
humanFileSize: humanFileSize,
getInputType: getInputType,
getSimpleColumnType: getSimpleColumnType,
setFooterStyle: setFooterStyle,
setDisplayContainerHeight: setDisplayContainerHeight
}
Expand Down
106 changes: 106 additions & 0 deletions common/validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
// updated float regex
// ^(Infinity|-Infinity|NaN|-?\d+(\.\d+)?([eE][-+]?\d+)?$
var FLOAT_REGEXP = /^\-?(\d+)?((\.)?\d+)?$/;

angular.module('chaise.validators', [])
// Validation directive for testing if an input value is an integer
// Use: <input type="number" required integer>
Expand Down Expand Up @@ -94,6 +95,111 @@
};
})

//Validation directive for array for testing if an input value is valid array
// Use: <textarea array>
.directive('array', ["UiUtils", function(UiUtils) {
return {
require: 'ngModel',
scope: {
columnType: "@",
customErrorMessage: "="
},
link: function(scope, elm, attrs, ctrl) {

// modify the placeholder
var placeholder = "";
switch (scope.columnType) {
case 'timestamptz':
placeholder = "example: [ \"2001-01-01T01:01:01-08:00\", \"2002-02-02T02:02:02-08:00\" ]"
case 'timestamp':
placeholder = "example: [ \"2001-01-01T01:01:01\", \"2002-02-02T02:02:02\" ]"
break;
case 'date':
placeholder = "example: [ \"2001-01-01\", \"2001-02-02\" ]"
break;
case 'numeric':
case 'float4':
case 'float8':
placeholder = "example: [ 1, 2.2 ]"
break;
case 'int2':
case 'int4':
case 'int8':
placeholder = "example: [ 1, 2 ]"
break;
case 'boolean':
placeholder = "example: [ true, false ]"
break;
default:
placeholder = "example: [ \"value1\", \"value2\" ]"
break;
}
attrs.$set('placeholder', placeholder);

// validate the array
ctrl.$validators.customError = function(modelValue, viewValue) {
var value = modelValue || viewValue;
if (ctrl.$isEmpty(value)) {
return true;
}

// make sure it's an array
var validArray = false, arr;
try {
arr = JSON.parse(value);
validArray = Array.isArray(arr);
} catch(e){}
if (!validArray) {
scope.customErrorMessage = "Please enter a valid array structure" + ((scope.columnType === "text") ? " e.g. [\"value1\", \"value2\"]" : ".");
return false;
}

// validate individual array values
for (var i = 0; i < arr.length; i++) {
var isValid = false;
var val = arr[i];

// null is a valid value for any type
if (val == null) continue;

switch (scope.columnType) {
case 'timestamptz':
case 'timestamp':
isValid = moment(val, moment.ISO_8601, true).isValid();
break;
case 'date':
isValid = moment(val, ['YYYY-MM-DD', 'YYYY-M-DD', 'YYYY-M-D', 'YYYY-MM-D'], true).isValid();
break;
case 'numeric':
case 'float4':
case 'float8':
isValid = FLOAT_REGEXP.test(val);
break;
case 'int2':
case 'int4':
case 'int8':
isValid = INTEGER_REGEXP.test(val);
break;
case 'boolean':
isValid = (typeof val === "boolean");
break;
default:
isValid = (typeof val === 'string' || val instanceof String);
break;
}

if (!isValid) {
scope.customErrorMessage = "`" + val + "` is not a valid " + UiUtils.getSimpleColumnType(scope.columnType) + " value.";
return false;
}
}

return true;
};
}
};
}])

// Validation directive for testing if an input value is a time
// Use: <input type="text" time>
.directive('time', function() {
Expand Down
18 changes: 12 additions & 6 deletions recordedit/form.controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
vm.prefillCookie = $cookies.getObject(context.queryParams.prefill);
vm.makeSafeIdAttr = DataUtils.makeSafeIdAttr;

vm.customErrorMessage = [];

// Takes a page object and uses the uri generated for the reference to construct a chaise uri
function redirectAfterSubmission(page) {
var rowset = vm.recordEditModel.rows,
Expand Down Expand Up @@ -100,9 +102,12 @@
var col = $rootScope.reference.columns[i];
var rowVal = row[col.name];
if (rowVal && !col.getInputDisabled(context.appContext)) {
switch (col.type.name) {
case "timestamp":
case "timestamptz":
if (col.type.isArray) {
rowVal = JSON.parse(rowVal);
} else {
switch (col.type.name) {
case "timestamp":
case "timestamptz":
if (vm.readyToSubmit) {
var options = {
outputType: "string",
Expand All @@ -118,17 +123,18 @@
rowVal = InputUtils.formatDatetime(value, options);
}
break;
case "json":
case "jsonb":
case "json":
case "jsonb":
rowVal=JSON.parse(rowVal);
break;
default:
default:
if (col.isAsset) {
if (!vm.readyToSubmit) {
rowVal = { url: "" };
}
}
break;
}
}
}
transformedRow[col.name] = rowVal;
Expand Down
6 changes: 6 additions & 0 deletions recordedit/index.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,11 @@
<textarea json id="form-{{rowIndex}}-{{::form.makeSafeIdAttr(column.displayname.value)}}-input" ng-model="form.recordEditModel.rows[rowIndex][column.name]" rows="5" name="{{::column.name}}" class="form-control" ng-required="::form.isRequired(column);" empty-to-null></textarea>
</div>

<!--array input -->
<div ng-switch-when="array">
<textarea array column-type="{{column.type.rootName}}" custom-error-message="form.customErrorMessage[rowIndex][column.name]" id="form-{{rowIndex}}-{{::form.makeSafeIdAttr(column.displayname.value)}}-input" ng-model="form.recordEditModel.rows[rowIndex][column.name]" rows="5" name="{{::column.name}}" class="form-control" ng-required="::form.isRequired(column);" empty-to-null></textarea>
</div>

<!-- disabled -->
<input ng-switch-when="disabled" id="form-{{rowIndex}}-{{::form.makeSafeIdAttr(column.displayname.value)}}-input" ng-model="form.recordEditModel.rows[rowIndex][column.name]" name="{{::column.name}}" type="text" class="form-control" disabled="true" placeholder="{{::form.getDisabledInputValue(column, form.recordEditModel.rows[rowIndex][column.name]);}}" empty-to-null></input>

Expand All @@ -244,6 +249,7 @@
<div ng-message="float">Please enter a decimal value.</div>
<div ng-message="json">Please enter a valid JSON value.</div>
<div ng-message="fileExtension">Please select a file with the following type: {{form.fileExtensionTypes(column)}}</div>
<div ng-message="customError">{{form.customErrorMessage[rowIndex][column.name]}}</div>
</div>

<!-- Validation error messages to show when the form is submitted -->
Expand Down
8 changes: 8 additions & 0 deletions recordedit/recordEdit.app.js
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,14 @@
// If input is disabled, and it's copy, we don't want to copy the value
if (colModel.inputType == "disabled" && context.mode == context.modes.COPY) continue;

// stringify the returned array value
if (column.type.isArray) {
if (values[i] !== null) {
recordEditModel.rows[j][column.name] = JSON.stringify(values[i], undefined, 2);
}
continue;
}

// Transform column values for use in view model
var options = { outputType: "object" }
switch (column.type.name) {
Expand Down
9 changes: 8 additions & 1 deletion test/e2e/data_setup/data/product/accommodation.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,5 +94,12 @@
"cover": 3005,
"opened_on": "2008-12-09T00:00:00-08:00",
"date_col": "12/9/2008",
"luxurious": true
"luxurious": true,
"text_array": ["v2", "v3"],
"boolean_array": [false],
"int4_array": [1],
"float4_array": [1.1, 2.2],
"date_array": null,
"timestamp_array": ["2003-03-03T03:03:03"],
"timestamptz_array": ["2002-02-02T02:02:02-08:00"]
}]
12 changes: 11 additions & 1 deletion test/e2e/data_setup/schema/recordedit/multi-add.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,21 @@
"type": {
"typename": "text"
}
},
{
"name": "int_array",
"type": {
"is_array": true,
"typename": "int4[]",
"base_type": {
"typename": "int4"
}
}
}
],
"annotations": {
"tag:isrd.isi.edu,2016:visible-columns" : {
"*": ["id", "text", "int", "date", "timestamp", ["multi-add", "fk1"], "uri"]
"*": ["id", "text", "int", "date", "timestamp", ["multi-add", "fk1"], "uri", "int_array"]
}
}
},
Expand Down
Loading