| 111 | |
| 112 | == Components == |
| 113 | |
| 114 | Components are supported (currently only direct foreign-key relationships). |
| 115 | |
| 116 | Components must be declared in the master table schema (see Table Schema Format). |
| 117 | |
| 118 | == Table Schema Format == |
| 119 | |
| 120 | The following format is used for both emDefaultSchema, and schema imports (as JSON). |
| 121 | |
| 122 | {{{#!js |
| 123 | var tableSchema = { |
| 124 | |
| 125 | // The table name |
| 126 | _name: 'person', |
| 127 | |
| 128 | // Fields in the table |
| 129 | 'first_name': { // Field name (key) |
| 130 | type: 'string', // Field type (required) |
| 131 | label: 'First Name', // Label in form |
| 132 | placeholder: 'Jane', // Placeholder (text fields only) |
| 133 | notnull: true // NOT NULL constraint |
| 134 | }, |
| 135 | 'last_name': { |
| 136 | type: 'string', |
| 137 | label: 'Last Name', |
| 138 | placeholder: 'Doe' |
| 139 | }, |
| 140 | 'date_of_birth': { |
| 141 | type: 'date', |
| 142 | label: 'Date of Birth' |
| 143 | }, |
| 144 | 'missing': { |
| 145 | type: 'boolean', |
| 146 | label: 'Missing' |
| 147 | }, |
| 148 | 'gender': { |
| 149 | type: 'integer', |
| 150 | label: 'Gender', |
| 151 | options: {2: 'female', // Fixed set of options |
| 152 | 3: 'male' // value: label |
| 153 | }, |
| 154 | defaultValue: 2 // Default value |
| 155 | }, |
| 156 | |
| 157 | // Fields in the form (in order) |
| 158 | _form: [ |
| 159 | 'first_name', |
| 160 | 'last_name', |
| 161 | 'gender', |
| 162 | 'missing', |
| 163 | 'date_of_birth' |
| 164 | ], |
| 165 | |
| 166 | // Data list card template |
| 167 | _card: { |
| 168 | |
| 169 | // Fields to extract (analogous to "list_fields", required) |
| 170 | fields: ['first_name', 'last_name'], |
| 171 | |
| 172 | // AngularJS expression for the card title |
| 173 | title: '{{record.first_name}} {{record.last_name}}' |
| 174 | }, |
| 175 | |
| 176 | // CRUD strings and icons |
| 177 | _strings: { |
| 178 | |
| 179 | // name and namePlural will be used as page titles |
| 180 | name: 'Person', |
| 181 | namePlural: 'Persons', |
| 182 | |
| 183 | // Icon for the form list |
| 184 | icon: 'ion-person-stalker' |
| 185 | }, |
| 186 | |
| 187 | // Component declaration |
| 188 | _components: { |
| 189 | |
| 190 | 'photo': { // Component name (alias) |
| 191 | title: 'Photos', // Component title ("tab" title) |
| 192 | resource: 'person_photo', // Component table name (required) |
| 193 | joinby: 'person_id', // Name of the the joinby-key (required) |
| 194 | multiple: true // Multiple-setting (default true) |
| 195 | } |
| 196 | } |
| 197 | }, |
| 198 | |
| 199 | { |
| 200 | // Component table |
| 201 | _name: 'person_photo', |
| 202 | |
| 203 | 'person_id': { |
| 204 | |
| 205 | // Lookup-field (component key) |
| 206 | type: 'reference person', |
| 207 | notnull: true, |
| 208 | |
| 209 | // Representation of foreign keys: |
| 210 | // - list of field names, values will be concatenated |
| 211 | // in order, separated by blanks |
| 212 | represent: ['first_name', 'last_name'] |
| 213 | |
| 214 | }, |
| 215 | 'photo': { |
| 216 | |
| 217 | // Upload-fields automatically use photo widget |
| 218 | type: 'upload' |
| 219 | } |
| 220 | } |
| 221 | }}} |