UNPKG

3.49 kBJavaScriptView Raw
1
2var Tag = require('./tag'),
3 contentTags = ['button','textarea','select'];
4
5var Field = module.exports = function Field (tag, options) {
6
7 if (tag === undefined || tag === null) {
8 throw new Error('You must supply a tag name for the field.');
9 }
10
11 this.tag = tag;
12 this.options = options || {};
13 this.attributes = this.options.attributes || {};
14 this.options.theme = this.options.theme || {};
15
16 // handle the label tag
17 if (this.options.label !== undefined && typeof this.options.label === 'string') {
18 this.options.label = {
19 label: this.options.label
20 };
21 }
22
23 // handle the helpText
24 if (this.options.helpText !== undefined && typeof this.options.helpText === 'string') {
25 this.options.helpText = {
26 text: this.options.helpText
27 }
28 }
29
30 // append the type to attributes, if not supplied, and if not a contentTag
31 if (contentTags.indexOf(this.tag) <= 0) {
32 this.attributes.type = this.attributes.type || 'text';
33 }
34
35 // handle select options
36 if (this.tag === 'select' && this.options.options) {
37
38 for (var i = 0; i < this.options.options.length; i++) {
39
40 // turn ['uk','us'] into [{label:'uk'},{label:'us'}]
41 if (typeof this.options.options[i] === 'string') {
42 this.options.options[i] = {
43 label: this.options.options[i]
44 };
45 }
46
47 // default the attributes object
48 this.options.options[i].attributes = this.options.options[i].attributes || {};
49
50 // attach value if it was passed in
51 if (this.options.options[i].value !== undefined) {
52 this.options.options[i].attributes.value = this.options.options[i].value;
53 }
54
55 }
56
57 }
58
59};
60
61Field.prototype.render = function(theme) {
62
63 var tag,
64 label,
65 small,
66 content = '',
67 attributes;
68
69 // certain tags (contentTags) have content not values, such as textarea and button
70 if (contentTags.indexOf(this.tag) >= 0) {
71 content = this.attributes.value || '';
72 delete this.attributes.value;
73 delete this.attributes.type;
74 }
75
76 // is this a select box?
77 if (this.tag === 'select' && this.options.options) {
78
79 for (var i = 0; i < this.options.options.length; i++) {
80
81 var tag = new Tag('option', this.options.options[i].attributes, this.options.options[i].label);
82 content = content + tag.render();
83
84 }
85
86 }
87
88 // is there a label?
89 if (this.options.label) {
90
91 // we want to append to the attributes, so default if it wasn't passed in
92 attributes = this.options.label.attributes || {};
93
94 // if the field has an id, create a for attribute unless pre-defined
95 if (this.attributes.id && attributes['for'] === undefined) {
96 attributes['for'] = this.attributes.id;
97 }
98
99 // generate the label tag and render it before the field itself
100 label = new Tag('label', attributes, this.options.label.label);
101
102 }
103
104 // this there some help text?
105 if (this.options.helpText) {
106
107 attributes = this.options.helpText.attributes || { 'class': 'help-text' };
108
109 small = new Tag((this.options.helpText.tag || 'small'), attributes, this.options.helpText.text);
110
111 }
112
113 // the tag to render, containing the content
114 tag = new Tag(this.tag, this.attributes, content);
115
116 // wrap the rendered field, using the themes field wrapper
117 return (this.options.theme.field || theme.field)(label !== undefined ? label.render() : '', (this.options.theme.control || theme.control)(tag.render(), this), (small !== undefined ? small.render() : ''), this);
118
119};
120
121Field.prototype.attribute = function (key, value) {
122
123 if (value === undefined) {
124 return this.attributes[key];
125 }
126
127 this.attributes[key] = value;
128
129 // for chaining
130 return this;
131
132};
\No newline at end of file