Added JS source map extension to the white map in the .htaccess file. Minor fix in the forms styling. Implemented client-side validation for the Table widget. Updated the Table widget readme file.
This commit is contained in:
parent
bc287a9559
commit
cbc808520d
|
|
@ -22,6 +22,7 @@
|
||||||
##
|
##
|
||||||
RewriteCond %{REQUEST_FILENAME} -f
|
RewriteCond %{REQUEST_FILENAME} -f
|
||||||
RewriteCond %{REQUEST_URI} !\.js
|
RewriteCond %{REQUEST_URI} !\.js
|
||||||
|
RewriteCond %{REQUEST_URI} !\.map
|
||||||
RewriteCond %{REQUEST_URI} !\.ico
|
RewriteCond %{REQUEST_URI} !\.ico
|
||||||
RewriteCond %{REQUEST_URI} !\.jpg
|
RewriteCond %{REQUEST_URI} !\.jpg
|
||||||
RewriteCond %{REQUEST_URI} !\.jpeg
|
RewriteCond %{REQUEST_URI} !\.jpeg
|
||||||
|
|
|
||||||
|
|
@ -9017,6 +9017,7 @@ label {
|
||||||
}
|
}
|
||||||
.help-block.before-field {
|
.help-block.before-field {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
.field-textarea {
|
.field-textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
|
|
|
||||||
|
|
@ -190,6 +190,7 @@ label {
|
||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
&.before-field {
|
&.before-field {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
|
margin-bottom: 10px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,14 @@ class Table extends WidgetBase
|
||||||
public function loadAssets()
|
public function loadAssets()
|
||||||
{
|
{
|
||||||
$this->addCss('css/table.css', 'core');
|
$this->addCss('css/table.css', 'core');
|
||||||
|
|
||||||
|
// Include a combined and minified script.
|
||||||
|
// TODO: At the moment the files are combined with
|
||||||
|
// CodeKit 2, but we should have a method to
|
||||||
|
// combine files without external dependencies. -ab
|
||||||
|
$this->addJs('js/table-min.js', 'core');
|
||||||
|
|
||||||
|
/*
|
||||||
$this->addJs('js/table.js', 'core');
|
$this->addJs('js/table.js', 'core');
|
||||||
$this->addJs('js/table.helper.navigation.js', 'core');
|
$this->addJs('js/table.helper.navigation.js', 'core');
|
||||||
$this->addJs('js/table.datasource.base.js', 'core');
|
$this->addJs('js/table.datasource.base.js', 'core');
|
||||||
|
|
@ -135,6 +143,14 @@ class Table extends WidgetBase
|
||||||
$this->addJs('js/table.processor.string.js', 'core');
|
$this->addJs('js/table.processor.string.js', 'core');
|
||||||
$this->addJs('js/table.processor.checkbox.js', 'core');
|
$this->addJs('js/table.processor.checkbox.js', 'core');
|
||||||
$this->addJs('js/table.processor.dropdown.js', 'core');
|
$this->addJs('js/table.processor.dropdown.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.base.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.required.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.basenumber.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.integer.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.float.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.length.js', 'core');
|
||||||
|
$this->addJs('js/table.validator.regex.js', 'core');
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ All classes for the table widget are be defined in the **$.oc.table** namespace.
|
||||||
- **$.oc.table.processor** - cell processors
|
- **$.oc.table.processor** - cell processors
|
||||||
- **$.oc.table.datasource** - data sources
|
- **$.oc.table.datasource** - data sources
|
||||||
- **$.oc.table.helper** - helper classes
|
- **$.oc.table.helper** - helper classes
|
||||||
|
- **$.oc.table.validator** - validation classes
|
||||||
|
|
||||||
### Client-side performance and memory usage considerations
|
### Client-side performance and memory usage considerations
|
||||||
|
|
||||||
|
|
@ -271,7 +272,7 @@ public function onSave()
|
||||||
|
|
||||||
There are two ways to validate the table data - with the client-side and server-side validation.
|
There are two ways to validate the table data - with the client-side and server-side validation.
|
||||||
|
|
||||||
### Client-side validation
|
### Client-side validation ($.oc.table.validator)
|
||||||
|
|
||||||
The client-side validation is performed before the data is sent to the server, or before the user navigates to another page (if the pagination is enabled). Client-side validation is a fast, but simple validation implementation. It can't be used for complex cases like finding duplicating records, or comparing data with records existing in the database.
|
The client-side validation is performed before the data is sent to the server, or before the user navigates to another page (if the pagination is enabled). Client-side validation is a fast, but simple validation implementation. It can't be used for complex cases like finding duplicating records, or comparing data with records existing in the database.
|
||||||
|
|
||||||
|
|
@ -283,20 +284,107 @@ The client-side validation is configured in the widget configuration file in the
|
||||||
validation:
|
validation:
|
||||||
required:
|
required:
|
||||||
message: Please select the state
|
message: Please select the state
|
||||||
apply_if_has: country
|
applyIfNotEmpty: country
|
||||||
|
|
||||||
|
If a validator doesn't have any options (or default option values should be used), the declaration could look like this:
|
||||||
|
|
||||||
|
state:
|
||||||
|
title: State
|
||||||
|
type: dropdown
|
||||||
|
validation:
|
||||||
|
required: {}
|
||||||
|
|
||||||
|
The `applyIfNotEmpty` and `message` parameters are common for all validators.
|
||||||
|
|
||||||
Currently implemented client-side validation rules:
|
Currently implemented client-side validation rules:
|
||||||
|
|
||||||
- required
|
- required
|
||||||
|
- integer
|
||||||
|
- float
|
||||||
|
- length
|
||||||
|
- regex
|
||||||
|
|
||||||
Validation rules can be configured with extra parameters, which depend on a specific validator.
|
Validation rules can be configured with extra parameters, which depend on a specific validator.
|
||||||
|
|
||||||
#### required validator
|
#### required validator ($.oc.table.validator.required)
|
||||||
|
|
||||||
Checks if the user has provided a value for the cell. Parameters:
|
Checks if the user has provided a value for the cell.
|
||||||
|
|
||||||
- message - optional, error message if the message was not provided. If the error message is not provided, the default error message will be displayed.
|
#### integer validator ($.oc.table.validator.integer)
|
||||||
- apply_if_has - optional, allows to specify a column name which should have a value in order the validator to run. If the column doesn't have a value, the validation won't be performed. If the parameter is omitted, the validation always runs.
|
|
||||||
|
Checks if the value is integer. Parameters:
|
||||||
|
|
||||||
|
* `allowNegative` - optional, determines if negative values are allowed.
|
||||||
|
* `min` - optional object, defines the minimum allowed value and error message. Object fields:
|
||||||
|
* `value` - defines the minimum value.
|
||||||
|
* `message` - optional, defines the error message.
|
||||||
|
* `max` - optional object, defines the maximum allowed value and error message. Object fields:
|
||||||
|
* `value` - defines the maximum value.
|
||||||
|
* `message` - optional, defines the error message.
|
||||||
|
|
||||||
|
Example of defining the integer validator with the `min` parameter:
|
||||||
|
|
||||||
|
length:
|
||||||
|
title: Length
|
||||||
|
type: string
|
||||||
|
validation:
|
||||||
|
integer:
|
||||||
|
min:
|
||||||
|
value: 3
|
||||||
|
message: "The length cannot be less than 3"
|
||||||
|
|
||||||
|
#### float validator ($.oc.table.validator.float)
|
||||||
|
|
||||||
|
Checks if the value is a floating point number. The parameters for this validator match the parameters of the **integer** validator.
|
||||||
|
|
||||||
|
Valid floating point number formats:
|
||||||
|
|
||||||
|
* 10
|
||||||
|
* 10.302
|
||||||
|
* -10 (if `allowNegative` is `true`)
|
||||||
|
* -10.84 (if `allowNegative` is `true`)
|
||||||
|
|
||||||
|
#### length validator ($.oc.table.validator.length)
|
||||||
|
|
||||||
|
Checks if a string is not shorter or longer than specified values. Parameters:
|
||||||
|
|
||||||
|
* `min` - optional object, defines the minimum length and error message. Object fields:
|
||||||
|
* `value` - defines the minimum length.
|
||||||
|
* `message` - optional, defines the error message.
|
||||||
|
* `max` - optional object, defines the maximum length and error message. Object fields:
|
||||||
|
* `value` - defines the maximum length.
|
||||||
|
* `message` - optional, defines the error message.
|
||||||
|
|
||||||
|
Example column definition:
|
||||||
|
|
||||||
|
name:
|
||||||
|
title: Name
|
||||||
|
type: string
|
||||||
|
validation:
|
||||||
|
length:
|
||||||
|
min:
|
||||||
|
value: 3
|
||||||
|
message: "The name is too short."
|
||||||
|
|
||||||
|
#### regex validator ($.oc.table.validator.regex)
|
||||||
|
|
||||||
|
Checks a string against a provided regular expression:
|
||||||
|
|
||||||
|
* `pattern` - specifies the regular expression pattern string. Example: **^[0-9a-z]+$**
|
||||||
|
* `modifiers` - optional, a string containing regular expression modifiers (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/RegExp), for example **i** for "case insensitive".
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
login:
|
||||||
|
title: Login
|
||||||
|
type: string
|
||||||
|
validation:
|
||||||
|
regex:
|
||||||
|
pattern: "^[a-z0-9]+$"
|
||||||
|
modifiers: "i"
|
||||||
|
message: "The login name can contain only Latin letters and numbers."
|
||||||
|
|
||||||
|
Although the `message` parameter is optional for all validators it's highly recommended to provide a message for the regular expression validator as the default message "Invalid value format." is not descriptive and can be confusing.
|
||||||
|
|
||||||
### Server-side validation
|
### Server-side validation
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,19 @@
|
||||||
.control-table table.data tr {
|
.control-table table.data tr {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
.control-table table.data tr.error {
|
||||||
|
background-color: #fbecec!important;
|
||||||
|
}
|
||||||
|
.control-table table.data tr.error td.active.error {
|
||||||
|
border-color: #ec0000!important;
|
||||||
|
}
|
||||||
|
.control-table table.data tr.error td.active.error .content-container {
|
||||||
|
border-color: #ec0000!important;
|
||||||
|
}
|
||||||
|
.control-table table.data tr.error td.active.error .content-container:before,
|
||||||
|
.control-table table.data tr.error td.active.error .content-container:after {
|
||||||
|
background-color: #ec0000!important;
|
||||||
|
}
|
||||||
.control-table table.data tr:nth-child(2n) {
|
.control-table table.data tr:nth-child(2n) {
|
||||||
background-color: #fbfbfb;
|
background-color: #fbfbfb;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -147,6 +147,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
Navigation.prototype.gotoPage = function(pageIndex, onSuccess) {
|
Navigation.prototype.gotoPage = function(pageIndex, onSuccess) {
|
||||||
|
this.tableObj.unfocusTable()
|
||||||
|
|
||||||
|
if (!this.tableObj.validate())
|
||||||
|
return
|
||||||
|
|
||||||
this.pageIndex = pageIndex
|
this.pageIndex = pageIndex
|
||||||
|
|
||||||
this.tableObj.updateDataTable(onSuccess)
|
this.tableObj.updateDataTable(onSuccess)
|
||||||
|
|
|
||||||
|
|
@ -428,7 +428,7 @@
|
||||||
Table.prototype.commitEditedRow = function() {
|
Table.prototype.commitEditedRow = function() {
|
||||||
if (this.editedRowKey === null)
|
if (this.editedRowKey === null)
|
||||||
return
|
return
|
||||||
|
|
||||||
var editedRow = this.dataTable.querySelector('tr[data-row="'+this.editedRowKey+'"]')
|
var editedRow = this.dataTable.querySelector('tr[data-row="'+this.editedRowKey+'"]')
|
||||||
if (!editedRow)
|
if (!editedRow)
|
||||||
return
|
return
|
||||||
|
|
@ -492,13 +492,13 @@
|
||||||
|
|
||||||
if (this.activeCell !== cellElement) {
|
if (this.activeCell !== cellElement) {
|
||||||
if (this.activeCell)
|
if (this.activeCell)
|
||||||
this.activeCell.setAttribute('class', '')
|
this.elementRemoveClass(this.activeCell, 'active')
|
||||||
|
|
||||||
this.setActiveProcessor(processor)
|
this.setActiveProcessor(processor)
|
||||||
this.activeCell = cellElement
|
this.activeCell = cellElement
|
||||||
|
|
||||||
if (processor.isCellFocusable())
|
if (processor.isCellFocusable())
|
||||||
this.activeCell.setAttribute('class', 'active')
|
this.elementAddClass(this.activeCell, 'active')
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the cell belongs to other row than the currently edited,
|
// If the cell belongs to other row than the currently edited,
|
||||||
|
|
@ -536,11 +536,21 @@
|
||||||
currentRowIndex = this.getCellRowIndex(this.activeCell)
|
currentRowIndex = this.getCellRowIndex(this.activeCell)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.navigation.paginationEnabled())
|
|
||||||
this.navigation.pageIndex = this.navigation.getNewRowPage(placement, currentRowIndex)
|
|
||||||
|
|
||||||
this.unfocusTable()
|
this.unfocusTable()
|
||||||
|
|
||||||
|
if (this.navigation.paginationEnabled()) {
|
||||||
|
var newPageIndex = this.navigation.getNewRowPage(placement, currentRowIndex)
|
||||||
|
|
||||||
|
if (newPageIndex != this.navigation.pageIndex) {
|
||||||
|
// Validate data on the current page if adding a new record
|
||||||
|
// is going to create another page.
|
||||||
|
if (!this.validate())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.navigation.pageIndex = newPageIndex
|
||||||
|
}
|
||||||
|
|
||||||
this.recordsAddedOrDeleted++
|
this.recordsAddedOrDeleted++
|
||||||
|
|
||||||
// New records have negative keys
|
// New records have negative keys
|
||||||
|
|
@ -626,6 +636,52 @@
|
||||||
return this.tableContainer.querySelector('div.toolbar')
|
return this.tableContainer.querySelector('div.toolbar')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validaates data on the current page
|
||||||
|
*/
|
||||||
|
Table.prototype.validate = function() {
|
||||||
|
var rows = this.dataTable.querySelectorAll('tbody tr[data-row]')
|
||||||
|
|
||||||
|
for (var i = 0, len = rows.length; i < len; i++) {
|
||||||
|
var row = rows[i]
|
||||||
|
|
||||||
|
this.elementRemoveClass(row, 'error')
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0, rowsLen = rows.length; i < rowsLen; i++) {
|
||||||
|
var row = rows[i],
|
||||||
|
rowData = this.getRowData(row)
|
||||||
|
|
||||||
|
for (var j = 0, colsLen = row.children.length; j < colsLen; j++)
|
||||||
|
this.elementRemoveClass(row.children[j], 'error')
|
||||||
|
|
||||||
|
for (var columnName in rowData) {
|
||||||
|
var cellProcessor = this.getCellProcessor(columnName),
|
||||||
|
message = cellProcessor.validate(rowData[columnName], rowData)
|
||||||
|
|
||||||
|
if (message !== undefined) {
|
||||||
|
var cell = row.querySelector('td[data-column="'+columnName+'"]'),
|
||||||
|
self = this
|
||||||
|
|
||||||
|
this.elementAddClass(row, 'error')
|
||||||
|
this.elementAddClass(cell, 'error')
|
||||||
|
|
||||||
|
$.oc.flashMsg({text: message, 'class': 'error'})
|
||||||
|
|
||||||
|
window.setTimeout(function(){
|
||||||
|
self.focusCell(cell, false)
|
||||||
|
cell = null
|
||||||
|
self = null
|
||||||
|
cellProcessor = null
|
||||||
|
}, 100)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// EVENT HANDLERS
|
// EVENT HANDLERS
|
||||||
// ============================
|
// ============================
|
||||||
|
|
||||||
|
|
@ -688,6 +744,11 @@
|
||||||
if (data.handler == this.options.postbackHandlerName) {
|
if (data.handler == this.options.postbackHandlerName) {
|
||||||
this.unfocusTable()
|
this.unfocusTable()
|
||||||
|
|
||||||
|
if (!this.validate()) {
|
||||||
|
ev.preventDefault()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var fieldName = this.options.alias.indexOf('[') > -1 ?
|
var fieldName = this.options.alias.indexOf('[') > -1 ?
|
||||||
this.options.alias + '[TableData]' :
|
this.options.alias + '[TableData]' :
|
||||||
this.options.alias + 'TableData';
|
this.options.alias + 'TableData';
|
||||||
|
|
|
||||||
|
|
@ -28,8 +28,13 @@
|
||||||
|
|
||||||
this.activeCell = null
|
this.activeCell = null
|
||||||
|
|
||||||
|
this.validators = []
|
||||||
|
|
||||||
// Register event handlers
|
// Register event handlers
|
||||||
this.registerHandlers()
|
this.registerHandlers()
|
||||||
|
|
||||||
|
// Initialize validators
|
||||||
|
this.initValidators()
|
||||||
}
|
}
|
||||||
|
|
||||||
Base.prototype.dispose = function() {
|
Base.prototype.dispose = function() {
|
||||||
|
|
@ -175,5 +180,31 @@
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Base.prototype.initValidators = function() {
|
||||||
|
if (this.columnConfiguration.validation === undefined)
|
||||||
|
return
|
||||||
|
|
||||||
|
for (var validatorName in this.columnConfiguration.validation) {
|
||||||
|
if ($.oc.table.validator === undefined || $.oc.table.validator[validatorName] == undefined)
|
||||||
|
throw new Error('The table cell validator "'+validatorName+'" for the column "'+this.columnName+'" is not ' +
|
||||||
|
'found in the $.oc.table.validator namespace.')
|
||||||
|
|
||||||
|
var validator = new $.oc.table.validator[validatorName](
|
||||||
|
this.columnConfiguration.validation[validatorName]
|
||||||
|
)
|
||||||
|
|
||||||
|
this.validators.push(validator)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Base.prototype.validate = function(value, rowData) {
|
||||||
|
for (var i=0, len=this.validators.length; i<len; i++) {
|
||||||
|
var message = this.validators[i].validate(value, rowData)
|
||||||
|
|
||||||
|
if (message !== undefined)
|
||||||
|
return message
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$.oc.table.processor.base = Base
|
$.oc.table.processor.base = Base
|
||||||
}(window.jQuery);
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
/*
|
||||||
|
* Base class for the table validators.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// VALIDATOR NAMESPACES
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
$.oc.table.validator = {}
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = function(options) {
|
||||||
|
//
|
||||||
|
// State properties
|
||||||
|
//
|
||||||
|
|
||||||
|
this.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Base.prototype.validate = function(value, rowData) {
|
||||||
|
if (this.options.applyIfNotEmpty !== undefined && !this.rowHasValue(this.options.applyIfNotEmpty, rowData))
|
||||||
|
return
|
||||||
|
|
||||||
|
return this.validateValue(value, rowData)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined. This method should be redefined
|
||||||
|
* in descendant classes.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Base.prototype.validateValue = function(value, rowData) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Base.prototype.trim = function(value) {
|
||||||
|
if (String.prototype.trim)
|
||||||
|
return value.trim()
|
||||||
|
|
||||||
|
return value.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '')
|
||||||
|
}
|
||||||
|
|
||||||
|
Base.prototype.getMessage = function(defaultValue) {
|
||||||
|
if (this.options.message !== undefined)
|
||||||
|
return this.options.message
|
||||||
|
|
||||||
|
return defaultValue
|
||||||
|
}
|
||||||
|
|
||||||
|
Base.prototype.rowHasValue = function(columnName, rowData) {
|
||||||
|
if (rowData[columnName] === undefined)
|
||||||
|
return false
|
||||||
|
|
||||||
|
if (typeof rowData[columnName] == 'boolean')
|
||||||
|
return rowData[columnName]
|
||||||
|
|
||||||
|
var value = this.trim(String(rowData[columnName]))
|
||||||
|
|
||||||
|
return value.length > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.base = Base;
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
* Base class for number validators.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.base,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var BaseNumber = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
BaseNumber.prototype = Object.create(BaseProto)
|
||||||
|
BaseNumber.prototype.constructor = BaseNumber
|
||||||
|
|
||||||
|
BaseNumber.prototype.doCommonChecks = function(value) {
|
||||||
|
if (this.options.min !== undefined || this.options.max !== undefined) {
|
||||||
|
if (this.options.min !== undefined) {
|
||||||
|
if (this.options.min.value === undefined)
|
||||||
|
throw new Error('The min.value parameter is not defined in the table validator configuration')
|
||||||
|
|
||||||
|
if (value < this.options.min.value) {
|
||||||
|
return this.options.min.message !== undefined ?
|
||||||
|
this.options.min.message :
|
||||||
|
"The value should not be less than " + this.options.min.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.max !== undefined) {
|
||||||
|
if (this.options.max.value === undefined)
|
||||||
|
throw new Error('The max.value parameter is not defined in the table validator configuration')
|
||||||
|
|
||||||
|
if (value > this.options.max.value) {
|
||||||
|
return this.options.max.message !== undefined ?
|
||||||
|
this.options.max.message :
|
||||||
|
"The value should not be more than " + this.options.max.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.baseNumber = BaseNumber
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Float table validator.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator.baseNumber === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.baseNumber,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var Float = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
Float.prototype = Object.create(BaseProto)
|
||||||
|
Float.prototype.constructor = Float
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Float.prototype.validateValue = function(value, rowData) {
|
||||||
|
value = this.trim(value)
|
||||||
|
|
||||||
|
if (value.length == 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
var testResult = this.options.allowNegative ?
|
||||||
|
/^[-]?([0-9]+\.[0-9]+|[0-9]+)$/.test(value) :
|
||||||
|
/^([0-9]+\.[0-9]+|[0-9]+)$/.test(value)
|
||||||
|
|
||||||
|
if (!testResult) {
|
||||||
|
var defaultMessage = this.options.allowNegative ?
|
||||||
|
'The value should be a floating point number.' :
|
||||||
|
'The value should be a positive floating point number';
|
||||||
|
|
||||||
|
return this.getMessage(defaultMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.doCommonChecks(parseFloat(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.float = Float
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*
|
||||||
|
* Integer table validator.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator.baseNumber === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator.baseNumber namespace is not defined. Make sure that the table.validator.baseNumber.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.baseNumber,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var Integer = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
Integer.prototype = Object.create(BaseProto)
|
||||||
|
Integer.prototype.constructor = Integer
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Integer.prototype.validateValue = function(value, rowData) {
|
||||||
|
value = this.trim(value)
|
||||||
|
|
||||||
|
if (value.length == 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
var testResult = this.options.allowNegative ?
|
||||||
|
/^\-?[0-9]*$/.test(value) :
|
||||||
|
/^[0-9]*$/.test(value)
|
||||||
|
|
||||||
|
if (!testResult) {
|
||||||
|
var defaultMessage = this.options.allowNegative ?
|
||||||
|
'The value should be an integer.' :
|
||||||
|
'The value should be a positive integer';
|
||||||
|
|
||||||
|
return this.getMessage(defaultMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.doCommonChecks(parseInt(value))
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.integer = Integer
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* String length table validator.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.base,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var Length = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
Length.prototype = Object.create(BaseProto)
|
||||||
|
Length.prototype.constructor = Length
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Length.prototype.validateValue = function(value, rowData) {
|
||||||
|
value = this.trim(value)
|
||||||
|
|
||||||
|
if (value.length == 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (this.options.min !== undefined || this.options.max !== undefined) {
|
||||||
|
if (this.options.min !== undefined) {
|
||||||
|
if (this.options.min.value === undefined)
|
||||||
|
throw new Error('The min.value parameter is not defined in the Length table validator configuration')
|
||||||
|
|
||||||
|
if (value.length < this.options.min.value) {
|
||||||
|
return this.options.min.message !== undefined ?
|
||||||
|
this.options.min.message :
|
||||||
|
"The string should not be shorter than " + this.options.min.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.options.max !== undefined) {
|
||||||
|
if (this.options.max.value === undefined)
|
||||||
|
throw new Error('The max.value parameter is not defined in the Length table validator configuration')
|
||||||
|
|
||||||
|
if (value.length > this.options.max.value) {
|
||||||
|
return this.options.max.message !== undefined ?
|
||||||
|
this.options.max.message :
|
||||||
|
"The string should not be longer than " + this.options.max.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.length = Length
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Regex length table validator.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.base,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var Regex = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
Regex.prototype = Object.create(BaseProto)
|
||||||
|
Regex.prototype.constructor = Regex
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Regex.prototype.validateValue = function(value, rowData) {
|
||||||
|
value = this.trim(value)
|
||||||
|
|
||||||
|
if (value.length == 0)
|
||||||
|
return
|
||||||
|
|
||||||
|
if (this.options.pattern === undefined)
|
||||||
|
throw new Error('The pattern parameter is not defined in the Regex table validator configuration')
|
||||||
|
|
||||||
|
var regexObj = new RegExp(this.options.pattern, this.options.modifiers)
|
||||||
|
|
||||||
|
if (!regexObj.test(value))
|
||||||
|
return this.getMessage("Invalid value format.")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.regex = Regex
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,44 @@
|
||||||
|
/*
|
||||||
|
* Required table validator.
|
||||||
|
*/
|
||||||
|
+function ($) { "use strict";
|
||||||
|
|
||||||
|
// NAMESPACE CHECK
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
if ($.oc.table === undefined)
|
||||||
|
throw new Error("The $.oc.table namespace is not defined. Make sure that the table.js script is loaded.");
|
||||||
|
|
||||||
|
if ($.oc.table.validator === undefined)
|
||||||
|
throw new Error("The $.oc.table.validator namespace is not defined. Make sure that the table.validator.base.js script is loaded.");
|
||||||
|
|
||||||
|
// CLASS DEFINITION
|
||||||
|
// ============================
|
||||||
|
|
||||||
|
var Base = $.oc.table.validator.base,
|
||||||
|
BaseProto = Base.prototype
|
||||||
|
|
||||||
|
var Required = function(options) {
|
||||||
|
Base.call(this, options)
|
||||||
|
};
|
||||||
|
|
||||||
|
Required.prototype = Object.create(BaseProto)
|
||||||
|
Required.prototype.constructor = Required
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validates a value and returns the error message. If there
|
||||||
|
* are no errors, returns undefined.
|
||||||
|
* The rowData parameter is an object containing all values in the
|
||||||
|
* target row.
|
||||||
|
*/
|
||||||
|
Required.prototype.validateValue = function(value, rowData) {
|
||||||
|
value = this.trim(value)
|
||||||
|
|
||||||
|
if (value.length === 0)
|
||||||
|
return this.getMessage("The value should not be empty.")
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
$.oc.table.validator.required = Required
|
||||||
|
}(window.jQuery);
|
||||||
|
|
@ -120,6 +120,21 @@
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
|
||||||
|
&.error {
|
||||||
|
background-color: #fbecec!important;
|
||||||
|
|
||||||
|
td.active.error {
|
||||||
|
border-color: #ec0000!important;
|
||||||
|
|
||||||
|
.content-container {
|
||||||
|
border-color: #ec0000!important;
|
||||||
|
&:before, &:after {
|
||||||
|
background-color: #ec0000!important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr:nth-child(2n) {
|
tr:nth-child(2n) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue