diff --git a/serializer.js b/serializer.js
index 6aad771..a206ffc 100644
--- a/serializer.js
+++ b/serializer.js
@@ -1,4 +1,4 @@
-HTMLElement.prototype.isChildOf = function(parent){
+HTMLElement.prototype.isChildOf = function(parent) {
var node = this.parentNode;
while (node != null) {
if (node == parent) {
@@ -7,7 +7,7 @@ HTMLElement.prototype.isChildOf = function(parent){
node = node.parentNode;
}
return false;
-}
+};
class SerializerField {
/**
@@ -16,11 +16,11 @@ class SerializerField {
* @param {HTMLElement} f Input field (input|select|textarea)
* @returns {SerializerField}
*/
- constructor(f){
+ constructor(f) {
this.name;
this.parent;
this.field = f;
- this.required = f.required
+ this.required = f.required;
this.type = this.field.getAttribute("type");
}
@@ -29,23 +29,36 @@ class SerializerField {
*
* @returns {(String|Number|Boolean|Date)}
*/
- serialize(){
- if(this.type == "number" || this.type == "range"){
+ serialize() {
+ if (this.field.tagName == "SELECT" && this.field.multiple) {
+ return Array.apply(null, this.field.options).filter(o => o.selected).map(o => o.value)
+ }
+
+ if (this.type == "number" || this.type == "range") {
return Number(this.field.value);
- } else if(this.type == "date" || this.type == "datetime-local" || this.type == "month" || this.type == "week") {
+ }
+
+ if (
+ this.type == "date" ||
+ this.type == "datetime-local" ||
+ this.type == "month" ||
+ this.type == "week"
+ ) {
return new Date(this.field.value);
- } else if(this.type == "checkbox") {
+ }
+
+ if (this.type == "checkbox") {
let checked = this.field.checked;
- if(this.field.hasAttribute("string")){
- if(!checked) {
+ if (this.field.hasAttribute("string")) {
+ if (!checked) {
return null;
}
- return this.field.value
+ return this.field.value;
}
return checked;
- } else {
- return this.field.value;
- }
+ }
+
+ return this.field.value;
}
}
@@ -56,8 +69,10 @@ class Serializer {
* @param {HTMLElement} element
* @returns {Serializer}
*/
- constructor(element){
- let fields = element.querySelectorAll(`:scope input:not([type="submit"]), :scope select, :scope textarea, :scope group`);
+ constructor(element) {
+ let fields = element.querySelectorAll(
+ `:scope input:not([type="submit"]), :scope select, :scope textarea, :scope group`
+ );
let groups = [].slice.call(element.querySelectorAll(`:scope group`));
this.name = ":root";
@@ -67,8 +82,8 @@ class Serializer {
this.required = element.getAttribute("required") !== null || this.min != -1;
- for(let f of fields){
- if(f.isChildOf(element) && groups.every(g => !f.isChildOf(g))){
+ for (let f of fields) {
+ if (f.isChildOf(element) && groups.every(g => !f.isChildOf(g))) {
this.addField(f);
}
}
@@ -79,39 +94,41 @@ class Serializer {
*
* @param {HTMLElement} f
*/
- addField(f){
+ addField(f) {
let fieldName = f.getAttribute("name");
- let isArray = fieldName.match(/^\[(\d*)\]/)
+ let isArray = fieldName.match(/^\[(\d*)\]/);
- fieldName = fieldName.replace(/^\[\d*\]/, '');
+ fieldName = fieldName.replace(/^\[\d*\]/, "");
+
+ console.log(f)
let field;
- if(f.tagName == "GROUP"){
- field = new Serializer(f)
+ if (f.tagName == "GROUP") {
+ field = new Serializer(f);
} else {
field = new SerializerField(f);
}
- if(field.type == "file"){
+ if (field.type == "file") {
return;
}
field.name = fieldName;
field.parent = this;
- f.serializer = field
+ f.serializer = field;
- if(isArray){
- if(!this._fields.has(fieldName)){
- this._fields.set(fieldName, [])
+ if (isArray) {
+ if (!this._fields.has(fieldName)) {
+ this._fields.set(fieldName, []);
}
- if(isArray[1] != ""){
- this._fields.get(fieldName)[isArray[1]] = field
+ if (isArray[1] != "") {
+ this._fields.get(fieldName)[isArray[1]] = field;
} else {
- this._fields.get(fieldName).push(field)
+ this._fields.get(fieldName).push(field);
}
} else {
- this._fields.set(fieldName, field)
+ this._fields.set(fieldName, field);
}
}
@@ -120,12 +137,12 @@ class Serializer {
*
* @param {(HTMLElement|Serializer|SerializerField)} f Serializer child
*/
- removeField(f){
- if(this._fields.has(f.name)){
- let fields = this._fields.get(f.name)
- if(Array.isArray(fields)){
+ removeField(f) {
+ if (this._fields.has(f.name)) {
+ let fields = this._fields.get(f.name);
+ if (Array.isArray(fields)) {
let index = fields.indexOf(f);
- this._fields.set(f.name, fields.splice(index, 1))
+ this._fields.set(f.name, fields.splice(index, 1));
} else {
this._fields.delete();
}
@@ -137,20 +154,20 @@ class Serializer {
*
* @returns {Object}
*/
- serialize(){
+ serialize() {
let json = {};
- for(let [k, f] of this._fields){
- if(Array.isArray(f)){
- if(k != ""){
+ for (let [k, f] of this._fields) {
+ if (Array.isArray(f)) {
+ if (k != "") {
json[k] = [];
} else {
json = [];
}
- for(let key in f){
- if(f[key]){
+ for (let key in f) {
+ if (f[key]) {
let d = f[key].serialize();
- if(d !== null){
- if(k == ""){
+ if (d !== null) {
+ if (k == "") {
json[key] = d;
continue;
}
@@ -160,14 +177,14 @@ class Serializer {
}
} else {
let d = f.serialize();
- if(f !== null){
- if(k == ""){
- json = d
+ if (f !== null) {
+ if (k == "") {
+ json = d;
continue;
}
- json[k] = d
+ json[k] = d;
}
- }
+ }
}
return json;
}
@@ -181,18 +198,18 @@ class Validator {
* @param {(erializer|SerializerField)} field
* @returns {Object}
*/
- static validateRequired(field){
+ static validateRequired(field) {
let e = {
valid: true,
- errors: {},
- }
+ errors: {}
+ };
let v;
- if(field instanceof Serializer){
+ if (field instanceof Serializer) {
v = Validator.validateRequiredSerializer(field);
} else {
- v = Validator.validateRequiredSerialzerField(field)
+ v = Validator.validateRequiredSerialzerField(field);
}
- if(!v.valid){
+ if (!v.valid) {
e.valid = false;
e.errors = v.errors;
}
@@ -206,43 +223,43 @@ class Validator {
* @param {Serializer} field
* @returns {Object}
*/
- static validateRequiredSerializer(field){
+ static validateRequiredSerializer(field) {
let e = {
valid: true,
- errors: {},
- }
-
+ errors: {}
+ };
+
let min = field.min;
let validFieldsCount = 0;
- for(let [k, f] of field._fields){
- if(Array.isArray(f)){
+ for (let [k, f] of field._fields) {
+ if (Array.isArray(f)) {
e.errors = {
- message: null,
+ message: null
};
let validCount = 0;
- for(let sf of f){
- if(!(sf.name in e.errors)){
+ for (let sf of f) {
+ if (!(sf.name in e.errors)) {
e.errors[sf.name] = [];
}
- let v = Validator.validateRequired(sf)
- if(!v.valid){
- console.log(e.errors)
- e.errors[sf.name].push(v.errors);
+ let v = Validator.validateRequired(sf);
+ if (!v.valid) {
+ console.log(e.errors);
+ e.errors[sf.name].push(v.errors);
continue;
}
- validCount++
+ validCount++;
}
-
- e.valid = min <= validCount
- if(e.valid){
- e.errors = {}
+
+ e.valid = min <= validCount;
+ if (e.valid) {
+ e.errors = {};
} else {
- e.errors.message = `Should contain atleast ${min} value(s)`
+ e.errors.message = `Should contain atleast ${min} value(s)`;
}
} else {
let v = Validator.validateRequired(f);
- if(!v.valid){
+ if (!v.valid) {
e.valid = false;
e.errors[f.name] = v.errors;
}
@@ -259,19 +276,19 @@ class Validator {
* @param {SerializerField} field
* @returns {Object}
*/
- static validateRequiredSerialzerField(field){
+ static validateRequiredSerialzerField(field) {
let e = {
valid: true,
- errors: {},
- }
+ errors: {}
+ };
- if(field.required || (field.parent && field.parent.required)){
- if(field.type != "checkbox"){
- e.valid = field.field.validity.valueMissing !== true
- e.errors = "Is required"
+ if (field.required || (field.parent && field.parent.required)) {
+ if (field.type != "checkbox") {
+ e.valid = field.field.validity.valueMissing !== true;
+ e.errors = "Is required";
} else {
- e.valid = field.field.checked
- e.errors = "Not checked"
+ e.valid = field.field.checked;
+ e.errors = "Not checked";
}
}
return e;
diff --git a/tests/main.go b/tests/main.go
index 4074621..a54198d 100644
--- a/tests/main.go
+++ b/tests/main.go
@@ -24,6 +24,10 @@ var testData = []*Person{
Surname: "Bar",
Age: 57,
BirthDate: time.Date(1960, 1, 1, 0, 0, 0, 0, time.UTC),
+ Animal: "Dog",
+ Checklist: []string{
+ "Milk",
+ },
},
nil,
&Person{
@@ -32,22 +36,26 @@ var testData = []*Person{
Age: 22,
BirthDate: time.Date(1995, 1, 5, 0, 0, 0, 0, time.UTC),
Languages: []Language{
- Language{
+ {
Language: "Dutch",
SkillLevel: 9.99,
Native: true,
},
- Language{
+ {
Language: "English",
SkillLevel: 8.4,
Native: false,
},
- Language{
+ {
Language: "Japanese",
SkillLevel: -9000.9,
Native: false,
},
},
+ Animal: "Dog",
+ Checklist: []string{
+ "Milk",
+ },
},
}
@@ -84,9 +92,11 @@ type Person struct {
Age int `json:"age"`
BirthDate time.Time `json:"birth_date"`
Languages []Language `json:"languages"`
+ Checklist []string `json:"checklist"`
+ Animal string `json:"animal"`
}
-// Languages ...
+// Language ...
type Language struct {
Language string `json:"language"`
SkillLevel float64 `json:"skill_level"`
@@ -129,14 +139,21 @@ func isEq(p1, p2 Person) {
assert(p1.Surname, p2.Surname, "Surname")
assert(p1.Age, p2.Age, "Age")
assert(p1.BirthDate, p2.BirthDate, "BirthDate")
+ assert(p1.Animal, p2.Animal, "Animal")
if !assert(len(p2.Languages), len(p1.Languages), "Languages length") {
return
}
+ if !assert(len(p2.Checklist), len(p1.Checklist), "Checklist length") {
+ return
+ }
for k := range p2.Languages {
assert(p1.Languages[k].Language, p2.Languages[k].Language, "Languages.Language")
assert(p1.Languages[k].SkillLevel, p2.Languages[k].SkillLevel, "Languages.SkillLevel")
assert(p1.Languages[k].Native, p2.Languages[k].Native, "Languages.Native")
}
+ for k := range p2.Checklist {
+ assert(p1.Checklist[k], p2.Checklist[k], "Checklist")
+ }
}
func assert(v, v2 interface{}, ident string) bool {
diff --git a/tests/templates/test.gohtml b/tests/templates/test.gohtml
index 5947be9..b75098a 100644
--- a/tests/templates/test.gohtml
+++ b/tests/templates/test.gohtml
@@ -32,6 +32,14 @@
{{ end }}
+
+
{{ end }}
{{ end }}