├── .gitignore ├── example ├── .meteor │ ├── .gitignore │ ├── release │ ├── platforms │ ├── .finished-upgraders │ ├── .id │ ├── packages │ └── versions ├── packages.json ├── server │ └── collections.jsx ├── client │ ├── lib │ │ └── mui-themeManager.jsx │ ├── demo │ │ ├── demo.html │ │ └── demo.jsx │ ├── example.html │ ├── components.jsx │ └── example.jsx ├── packages │ └── npm-container │ │ ├── index.js │ │ └── package.js ├── router.jsx └── example.css ├── stylesheets └── rmui.css ├── inputTypes ├── color │ ├── color.js │ └── color.html ├── image │ ├── image.js │ └── image.html ├── datetime │ ├── datetime.html │ └── datetime.js ├── file │ ├── file.html │ └── file.jsx ├── radio │ ├── radio.html │ └── radio.jsx ├── email │ ├── email.html │ └── email.jsx ├── range │ ├── range.html │ └── range.jsx ├── reset │ ├── reset.html │ └── reset.jsx ├── button │ ├── button.html │ └── button.jsx ├── date │ ├── date.html │ └── date.jsx ├── number │ ├── number.html │ └── number.jsx ├── select │ ├── select.html │ ├── select-stylable.jsx │ └── select.jsx ├── tel │ ├── tel.html │ └── tel.jsx ├── textarea │ ├── textarea.html │ └── textarea.jsx ├── search │ ├── search.html │ └── search.jsx ├── time │ ├── time.html │ ├── time-stylable.jsx │ └── time.jsx ├── text │ ├── text.html │ └── text.jsx ├── checkbox │ ├── checkbox.html │ └── checkbox.jsx ├── password │ ├── password.html │ └── password.jsx ├── submit │ ├── submit.html │ └── submit.jsx ├── boolean-checkbox │ ├── boolean-checkbox.html │ └── boolean-checkbox.jsx ├── select-checkbox copy │ ├── select-checkbox.html │ └── select-checkbox.jsx ├── select-multiple │ ├── select-multiple.html │ └── select-multiple.jsx ├── select-radio │ ├── select-radio.html │ └── select-radio.jsx ├── boolean-radios │ ├── boolean-radios.html │ └── boolean-radios.jsx ├── datetime-local │ ├── datetime-local.html │ └── datetime-local.jsx ├── contenteditable │ ├── contenteditable.html │ └── contenteditable.jsx ├── label │ ├── label.js │ └── label.html ├── week │ ├── week.html │ └── week.js ├── boolean-select │ ├── boolean-select.html │ └── boolean-select.js ├── url │ ├── url.html │ └── url.js ├── month │ ├── month.html │ └── month.js ├── select-radio-inline │ ├── select-radio-inline.html │ └── select-radio-inline.js └── select-checkbox-inline │ ├── select-checkbox-inline.html │ └── select-checkbox-inline.js ├── components ├── quickform │ ├── quickform.jsx │ └── quickform.html ├── afArrayField │ ├── afArrayField.html │ └── afArrayField.jsx ├── afFormGroup │ ├── afFormGroup.html │ └── afFormGroup.jsx ├── afObjectField │ ├── afObjectField.html │ └── afObjectField.jsx └── autoform │ └── autoform.html ├── react-autoform-material-ui-tests.js ├── README.md ├── lib ├── rmui.jsx └── utility.jsx ├── .versions └── package.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | -------------------------------------------------------------------------------- /example/.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | -------------------------------------------------------------------------------- /example/packages.json: -------------------------------------------------------------------------------- 1 | { 2 | 3 | } -------------------------------------------------------------------------------- /example/.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.1.0.3 2 | -------------------------------------------------------------------------------- /example/.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /stylesheets/rmui.css: -------------------------------------------------------------------------------- 1 | .control-label, .help-block { 2 | display: none 3 | } 4 | -------------------------------------------------------------------------------- /example/server/collections.jsx: -------------------------------------------------------------------------------- 1 | sessionCollection = new Mongo.Collection('sessioncollection'); 2 | -------------------------------------------------------------------------------- /inputTypes/color/color.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("color", { 2 | template: "afInputColor" 3 | }); -------------------------------------------------------------------------------- /inputTypes/image/image.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("image", { 2 | template: "afInputImage" 3 | }); -------------------------------------------------------------------------------- /inputTypes/color/color.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/image/image.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/datetime/datetime.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/quickform/quickform.jsx: -------------------------------------------------------------------------------- 1 | Template['quickForm_reactAutoformMaterialUi'].helpers({ 2 | atts: function(){ 3 | return this.atts; 4 | } 5 | }); 6 | -------------------------------------------------------------------------------- /example/client/lib/mui-themeManager.jsx: -------------------------------------------------------------------------------- 1 | ThemeManager = new mui.Styles.ThemeManager(); 2 | rmui._themeManager = ThemeManager; 3 | injectTapEventPlugin(); 4 | -------------------------------------------------------------------------------- /inputTypes/file/file.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/radio/radio.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/email/email.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/range/range.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/reset/reset.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/button/button.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/date/date.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /inputTypes/number/number.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/select/select.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /inputTypes/tel/tel.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/textarea/textarea.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/search/search.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/time/time.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /inputTypes/text/text.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /react-autoform-material-ui-tests.js: -------------------------------------------------------------------------------- 1 | // Write your tests here! 2 | // Here is an example. 3 | Tinytest.add('example', function (test) { 4 | test.equal(true, true); 5 | }); 6 | -------------------------------------------------------------------------------- /inputTypes/checkbox/checkbox.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/password/password.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/submit/submit.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/boolean-checkbox/boolean-checkbox.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/select-checkbox copy/select-checkbox.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/select-multiple/select-multiple.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /inputTypes/select-radio/select-radio.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/boolean-radios/boolean-radios.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /inputTypes/datetime-local/datetime-local.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /components/afArrayField/afArrayField.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /components/afFormGroup/afFormGroup.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/afObjectField/afObjectField.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /inputTypes/contenteditable/contenteditable.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /inputTypes/label/label.js: -------------------------------------------------------------------------------- 1 | Template['afLabel_autoform-material-design-lite'].helpers({ 2 | atts: function() { 3 | var labelAtts; 4 | labelAtts = this.afFieldLabelAtts; 5 | 6 | return labelAtts; 7 | } 8 | }); -------------------------------------------------------------------------------- /inputTypes/week/week.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/boolean-select/boolean-select.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /inputTypes/label/label.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /components/quickform/quickform.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /inputTypes/url/url.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | notices-for-facebook-graph-api-2 9 | -------------------------------------------------------------------------------- /inputTypes/month/month.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/week/week.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("week", { 2 | template: "afInputWeek_autoform-material-design-lite", 3 | valueConverters: { 4 | "stringArray": function (val) { 5 | if (typeof val === "string" && val.length > 0) { 6 | return [val]; 7 | } 8 | return val; 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /inputTypes/month/month.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("month", { 2 | template: "afInputMonth_autoform-material-design-lite", 3 | valueConverters: { 4 | "stringArray": function (val) { 5 | if (typeof val === "string" && val.length > 0) { 6 | return [val]; 7 | } 8 | return val; 9 | } 10 | } 11 | }); -------------------------------------------------------------------------------- /example/packages/npm-container/index.js: -------------------------------------------------------------------------------- 1 | Meteor.npmRequire = function(moduleName) { 2 | var module = Npm.require(moduleName); 3 | return module; 4 | }; 5 | 6 | Meteor.require = function(moduleName) { 7 | console.warn('Meteor.require is deprecated. Please use Meteor.npmRequire instead!'); 8 | return Meteor.npmRequire(moduleName); 9 | }; -------------------------------------------------------------------------------- /components/autoform/autoform.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | vbtgip1fc8jvad3oqio 8 | -------------------------------------------------------------------------------- /example/router.jsx: -------------------------------------------------------------------------------- 1 | // let componentsController; 2 | Router.configure({ 3 | layoutTemplate: 'pageTemplate' 4 | }); 5 | Router.route('/', function() { 6 | 7 | this.render('home'); 8 | }) 9 | Router.route('/demo', function() { 10 | this.render('demo'); 11 | }) 12 | Router.route('/components', function() { 13 | componentsController = this; 14 | this.render('components'); 15 | }) 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /example/client/demo/demo.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/select-radio-inline/select-radio-inline.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /inputTypes/select-checkbox-inline/select-checkbox-inline.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/.meteor/packages: -------------------------------------------------------------------------------- 1 | # Meteor packages used by this project, one per line. 2 | # Check this file (and the other files in this directory) into your repository. 3 | # 4 | # 'meteor add' and 'meteor remove' will edit this file for you, 5 | # but you can also edit it by hand. 6 | 7 | meteor-platform 8 | autopublish 9 | insecure 10 | poetic:react-autoform-material-ui 11 | aldeed:simple-schema 12 | mizzao:bootstrap-3 13 | meteorhacks:npm 14 | 15 | 16 | npm-container 17 | entropy:ramjet 18 | iron:router 19 | aldeed:autoform 20 | msavin:mongol 21 | -------------------------------------------------------------------------------- /inputTypes/url/url.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("url", { 2 | template: "afInputUrl_autoform-material-design-lite", 3 | valueConverters: { 4 | "stringArray": function (val) { 5 | if (typeof val === "string" && val.length > 0) { 6 | return [val]; 7 | } 8 | return val; 9 | } 10 | }, 11 | contextAdjust: function (context) { 12 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 13 | context.atts.maxlength = context.max; 14 | } 15 | return context; 16 | } 17 | }); -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### React-Autoform-MaterialUi - Overview 2 | 3 | 4 | React-Autoform-MaterialUi, is a meteor package for Autoform that helps render your forms using Material-UI components. 5 | 6 | [Demo](http://ramui.meteor.com/) 7 | 8 | ## Installation 9 | 10 | 11 | In a Meteor app directory, enter: 12 | 13 | ```$ meteor add poetic:react-autoform-material-ui ``` 14 | 15 | ## Notes 16 | 17 | 18 | In order to use this package, please ensure you have the following packages installed 19 | 20 | Autoform 21 | 22 | ```$ meteor add aldeed:autoform ``` 23 | 24 | React 25 | 26 | ```$ meteor add react``` -------------------------------------------------------------------------------- /lib/rmui.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Styles, 3 | } from 'material-ui'; 4 | 5 | const { ThemeManager, LightRawTheme } = Styles; 6 | rmui = {}; 7 | 8 | rmui.setPalette = function(palette) { 9 | ThemeManager.setPalette(palette) 10 | } 11 | 12 | rmui._defaultTheme = ThemeManager.getMuiTheme(LightRawTheme); 13 | 14 | rmui.setComponentThemes = theme => { 15 | rmui.muiTheme = ThemeManager.getMuiTheme(theme); 16 | } 17 | 18 | rmui.getComponentThemes = () => { 19 | const { muiTheme, _defaultTheme } = rmui; 20 | return muiTheme || _defaultTheme; 21 | } 22 | 23 | rmui.getPalette = () => { 24 | return ThemeManager.palette 25 | } 26 | 27 | rmui.afObjectFieldReady = new ReactiveVar(false); 28 | 29 | rmui.afArrayFieldReady = new ReactiveVar(false); 30 | 31 | -------------------------------------------------------------------------------- /inputTypes/search/search.jsx: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("search", { 2 | template: "afInputSearch_reactAutoformMaterialUi", 3 | valueConverters: { 4 | "stringArray": function (val) { 5 | if (typeof val === "string" && val.length > 0) { 6 | return [val]; 7 | } 8 | return val; 9 | } 10 | }, 11 | contextAdjust: function (context) { 12 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 13 | context.atts.maxlength = context.max; 14 | } 15 | return context; 16 | } 17 | }); 18 | 19 | Template['afInputSearch_reactAutoformMaterialUi'].helpers({ 20 | atts() { 21 | let atts = this.atts; 22 | 23 | return atts; 24 | }, 25 | 26 | search() { 27 | 28 | return Search; 29 | } 30 | }) 31 | -------------------------------------------------------------------------------- /lib/utility.jsx: -------------------------------------------------------------------------------- 1 | ReactAutoformUtility = function(atts){ 2 | 3 | try 4 | { 5 | this.label = (AutoForm.getSchemaForField(atts.name).label == null || undefined) ? atts.name : AutoForm.getSchemaForField(atts.name).label ; 6 | }catch(e) 7 | { 8 | console.warn(e); 9 | } 10 | 11 | this.attributes = atts; 12 | this.formId = AutoForm.getFormId(); 13 | this.schema = AutoForm.getFormSchema(); 14 | this.id = atts.id; 15 | this.name = atts.name; 16 | this.dsk = atts['data-schema-key']; 17 | this.value = atts.value || ''; 18 | this.validationContext = this.schema.namedContext(this.formId); 19 | this.err = ''; 20 | this.errorStyle = atts.errorStyle; 21 | 22 | if (this.validationContext.keyIsInvalid(this.dsk) ) { 23 | this.err = this.validationContext.keyErrorMessage(this.dsk) 24 | } 25 | 26 | return this; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /example/packages/npm-container/package.js: -------------------------------------------------------------------------------- 1 | var path = Npm.require('path'); 2 | var fs = Npm.require('fs'); 3 | 4 | Package.describe({ 5 | summary: 'Contains all your npm dependencies', 6 | version: '1.1.0', 7 | name: 'npm-container' 8 | }); 9 | 10 | var packagesJsonFile = path.resolve('./packages.json'); 11 | try { 12 | var fileContent = fs.readFileSync(packagesJsonFile); 13 | var packages = JSON.parse(fileContent.toString()); 14 | Npm.depends(packages); 15 | } catch (ex) { 16 | console.error('ERROR: packages.json parsing error [ ' + ex.message + ' ]'); 17 | } 18 | 19 | // Adding the app's packages.json as a used file for this package will get 20 | // Meteor to watch it and reload this package when it changes 21 | Package.onUse(function(api) { 22 | api.add_files('index.js', 'server'); 23 | api.add_files('../../packages.json', 'server', { 24 | isAsset: true 25 | }); 26 | }); -------------------------------------------------------------------------------- /inputTypes/submit/submit.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { RaisedButton } from 'material-ui'; 3 | 4 | AutoForm.addInputType("submit", { 5 | template: "afInputSubmit_reactAutoformMaterialUi" 6 | }); 7 | const Submit = React.createClass({ 8 | 9 | childContextTypes: { 10 | muiTheme: React.PropTypes.object 11 | }, 12 | 13 | getChildContext: function() { 14 | return { 15 | muiTheme: ThemeManager.getCurrentTheme() 16 | }; 17 | }, 18 | 19 | render: function() { 20 | return ( 21 | 22 | 23 | ); 24 | } 25 | }); 26 | 27 | Template["afInputSubmit_reactAutoformMaterialUi"].helpers({ 28 | Submit: function(){ 29 | return Submit; 30 | }, 31 | atts(){ 32 | 33 | this.atts.label = this.atts.buttonContent ? this.atts.buttonContent.toLocaleUpperCase() : 'SUBMIT'; 34 | return this.atts; 35 | } 36 | }) 37 | -------------------------------------------------------------------------------- /example/example.css: -------------------------------------------------------------------------------- 1 | /* CSS declarations go here */ 2 | 3 | html, 4 | body, 5 | .componentContainer { 6 | height: 100%; 7 | } 8 | 9 | .panel-default > .panel-heading { 10 | border-color: transparent; 11 | background-color: transparent; 12 | } 13 | 14 | div#overview { 15 | padding-bottom: 60px; 16 | } 17 | 18 | .form-group { 19 | margin-bottom: 15px; 20 | border: 1px solid #cacaca; 21 | padding: 15px; 22 | border-radius: 5px; 23 | } 24 | 25 | h1 { 26 | text-align: center; 27 | margin-bottom: 15px; 28 | } 29 | 30 | .componentContainer { 31 | padding-top: 70px; 32 | } 33 | 34 | .menu { 35 | margin-right: 20px; 36 | left: -15px; 37 | padding-top: 65px; 38 | border: 2px solid #cacaca; 39 | border-radius: 5px; 40 | } 41 | 42 | .appBar { 43 | top: 0px; 44 | position: absolute; 45 | } 46 | 47 | .form { 48 | height: 95%; 49 | max-height: 95%; 50 | overflow-y: scroll; 51 | } 52 | 53 | #schema_entry pre { 54 | border: none; 55 | } -------------------------------------------------------------------------------- /inputTypes/contenteditable/contenteditable.jsx: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("contenteditable", { 2 | template: "afContenteditable_reactAutoformMaterialUi", 3 | valueOut: function () { 4 | return this.html(); 5 | }, 6 | contextAdjust: function (context) { 7 | if (typeof context.atts['data-maxlength'] === "undefined" && typeof context.max === "number") { 8 | context.atts['data-maxlength'] = context.max; 9 | } 10 | return context; 11 | } 12 | }); 13 | 14 | Template['afContenteditable_reactAutoformMaterialUi'].events({ 15 | 'blur div[contenteditable=true]': function (event, template) { 16 | template.$(event.target).change(); 17 | } 18 | }); 19 | 20 | Template['afContenteditable_reactAutoformMaterialUi'].helpers({ 21 | getValue(value) { 22 | if(Template.instance().view.isRendered){ 23 | Template.instance().$('[contenteditable]').html(value); 24 | } 25 | }, 26 | atts() { 27 | let atts = this.atts; 28 | atts.label ? atts.label : ""; 29 | return atts; 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /inputTypes/reset/reset.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { RaisedButton } = require('material-ui'); 10 | 11 | AutoForm.addInputType("reset", { 12 | template: "afInputReset_reactAutoformMaterialUi" 13 | }); 14 | const ResetButton = React.createClass({ 15 | 16 | childContextTypes: { 17 | muiTheme: React.PropTypes.object 18 | }, 19 | 20 | getChildContext: function() { 21 | return { 22 | muiTheme: ThemeManager.getCurrentTheme() 23 | }; 24 | }, 25 | 26 | render: function() { 27 | return ( 28 |
29 | 30 |
31 | ); 32 | } 33 | }); 34 | 35 | Template['afInputReset_reactAutoformMaterialUi'].helpers({ 36 | Reset: function(){ 37 | return ResetButton; 38 | }, 39 | atts: function(){ 40 | return this.atts; 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /inputTypes/button/button.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { RaisedButton } = require('material-ui'); 10 | 11 | AutoForm.addInputType("button", { 12 | template: "afInputButton_reactAutoformMaterialUi" 13 | }); 14 | 15 | const Button = React.createClass({ 16 | 17 | childContextTypes: { 18 | muiTheme: React.PropTypes.object 19 | }, 20 | 21 | getChildContext: function() { 22 | return { 23 | muiTheme: ThemeManager.getCurrentTheme() 24 | }; 25 | }, 26 | 27 | render: function() { 28 | return ( 29 |
30 | 32 |
33 | ); 34 | } 35 | }); 36 | 37 | Template['afInputButton_reactAutoformMaterialUi'].helpers({ 38 | Button: function(){ 39 | return Button; 40 | }, 41 | atts: function(){ 42 | let atts = new ReactAutoformUtility(this.atts); 43 | return atts; 44 | } 45 | }); 46 | -------------------------------------------------------------------------------- /components/afFormGroup/afFormGroup.jsx: -------------------------------------------------------------------------------- 1 | Template["afFormGroup_reactAutoformMaterialUi"].helpers({ 2 | addInputField() { 3 | var result, skipInputType, type; 4 | skipInputType = [ 5 | 'checkbox', 6 | 'checkbox-group', 7 | 'boolean-checkbox', 8 | 'select-radio', 9 | 'select-checkbox-inline', 10 | 'select-radio-inline', 11 | 'boolean-radios', 12 | 'toggle', 13 | 'switch' 14 | ]; 15 | type = AutoForm.getInputType(this); 16 | result = !_.contains(skipInputType, type); 17 | return result; 18 | }, 19 | skipLabel() { 20 | var result, skipLabelTypes, type; 21 | skipLabelTypes = [ 22 | 'checkbox', 23 | 'checkbox-group', 24 | 'boolean-checkbox', 25 | 'select-radio', 26 | 'select-checkbox-inline', 27 | 'select-radio-inline', 28 | 'boolean-radio', 29 | 'toggle', 30 | 'switch' 31 | ]; 32 | type = AutoForm.getInputType(this); 33 | result = this.skipLabel || _.contains(skipLabelTypes, type); 34 | return result; 35 | }, 36 | atts() { 37 | let atts = this; 38 | return atts; 39 | } 40 | }); -------------------------------------------------------------------------------- /inputTypes/time/time-stylable.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | const React = require('react'); 10 | const ReactDOM = require('react-dom'); 11 | 12 | rmui.stylableTime = React.createClass({ 13 | getInitialState() { 14 | const { value: timeValue } = this.props; 15 | return { timeValue } 16 | }, 17 | 18 | componentWillReceiveProps(newProps) { 19 | const { value: timeValue } = newProps; 20 | this.setState({ timeValue }); 21 | }, 22 | 23 | getValue() { 24 | return this.state.timeValue; 25 | }, 26 | 27 | onChange(e) { 28 | const { value: timeValue } = e.target; 29 | const { onChange } = this.props; 30 | _.isFunction(onChange) ? onChange(e.target, { value: timeValue }) : null; 31 | this.setState({ timeValue }); 32 | }, 33 | 34 | render() { 35 | const { timeValue } = this.state; 36 | const { disable } = this.props; 37 | 38 | return ( 39 | 47 | ); 48 | } 49 | }); 50 | -------------------------------------------------------------------------------- /inputTypes/checkbox/checkbox.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { Checkbox } = require('material-ui'); 10 | 11 | AutoForm.addInputType('checkbox', { 12 | template: 'afCheckboxGroup_reactAutoformMaterialUi', 13 | valueOut() { 14 | return this.value; 15 | }, 16 | contextAdjust(context) { 17 | context.value = context.selectOptions[0].value; 18 | context.atts.value = context.value; 19 | return context; 20 | } 21 | }); 22 | 23 | const CheckboxComponent = React.createClass({ 24 | 25 | childContextTypes: { 26 | muiTheme: React.PropTypes.object 27 | }, 28 | 29 | getChildContext() { 30 | return { 31 | muiTheme: ThemeManager.getCurrentTheme() 32 | }; 33 | }, 34 | 35 | render() { 36 | return ( 37 | 44 | ); 45 | } 46 | }); 47 | Template.afCheckboxGroup_reactAutoformMaterialUi.helpers({ 48 | atts() { 49 | let atts = new ReactAutoformUtility(this.atts); 50 | this.atts = atts; 51 | return atts; 52 | }, 53 | checkbox() { 54 | return CheckboxComponent; 55 | } 56 | }); 57 | -------------------------------------------------------------------------------- /inputTypes/email/email.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TextField } from 'material-ui'; 3 | 4 | AutoForm.addInputType("email", { 5 | template: "afInputEmail_reactAutoformMaterialUi", 6 | contextAdjust: function (context) { 7 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 8 | context.atts.maxlength = context.max; 9 | } 10 | context.atts.value = context.value; 11 | return context; 12 | }, 13 | valueOut() { 14 | return this.val(); 15 | } 16 | }); 17 | 18 | 19 | const Email = React.createClass({ 20 | 21 | childContextTypes: { 22 | muiTheme: React.PropTypes.object 23 | }, 24 | 25 | getChildContext: function() { 26 | const muiTheme = rmui.getComponentThemes(); 27 | return { 28 | muiTheme 29 | }; 30 | }, 31 | 32 | render: function() { 33 | return ( 34 | 35 | 44 | 45 | ); 46 | } 47 | }); 48 | 49 | Template['afInputEmail_reactAutoformMaterialUi'].helpers({ 50 | Email(){ 51 | return Email; 52 | }, 53 | atts() { 54 | let atts = new ReactAutoformUtility(this.atts); 55 | return atts; 56 | } 57 | }); 58 | -------------------------------------------------------------------------------- /inputTypes/select-radio-inline/select-radio-inline.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("select-radio-inline", { 2 | template: "afRadioGroupInline_autoform-material-design-lite", 3 | valueOut: function () { 4 | return this.find('input[type=radio]:checked').val(); 5 | }, 6 | contextAdjust: function (context) { 7 | var itemAtts = _.omit(context.atts); 8 | 9 | // build items list 10 | context.items = []; 11 | 12 | // Add all defined options 13 | _.each(context.selectOptions, function(opt) { 14 | context.items.push({ 15 | name: context.name, 16 | label: opt.label, 17 | value: opt.value, 18 | // _id must be included because it is a special property that 19 | // #each uses to track unique list items when adding and removing them 20 | // See https://github.com/meteor/meteor/issues/2174 21 | _id: opt.value, 22 | selected: (opt.value === context.value), 23 | atts: itemAtts 24 | }); 25 | }); 26 | 27 | return context; 28 | } 29 | }); 30 | 31 | Template["afRadioGroupInline"].helpers({ 32 | atts: function selectedAttsAdjust() { 33 | var atts = _.clone(this.atts); 34 | if (this.selected) { 35 | atts.checked = ""; 36 | } 37 | // remove data-schema-key attribute because we put it 38 | // on the entire group 39 | delete atts["data-schema-key"]; 40 | return atts; 41 | }, 42 | dsk: function dsk() { 43 | return { 44 | "data-schema-key": this.atts["data-schema-key"] 45 | } 46 | } 47 | }); -------------------------------------------------------------------------------- /inputTypes/radio/radio.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { RadioButton,RadioButtonGroup } = require('material-ui'); 10 | 11 | AutoForm.addInputType("radio", { 12 | template: "afRadio_reactAutoformMaterialUi", 13 | valueOut: function () { 14 | if (this.is(":checked")) { 15 | return this.val(); 16 | } 17 | }, 18 | valueConverters: { 19 | "stringArray": function (val) { 20 | if (typeof val === "string" && val.length > 0) { 21 | return [val]; 22 | } 23 | return val; 24 | } 25 | } 26 | }); 27 | const Radio = React.createClass({ 28 | 29 | childContextTypes: { 30 | muiTheme: React.PropTypes.object 31 | }, 32 | 33 | getChildContext: function() { 34 | return { 35 | muiTheme: ThemeManager.getCurrentTheme() 36 | }; 37 | }, 38 | 39 | render: function() { 40 | return ( 41 | 43 | 46 | 47 | ); 48 | } 49 | }); 50 | Template["afRadio_reactAutoformMaterialUi"].helpers({ 51 | atts() { 52 | let atts = new ReactAutoformUtility(this.atts); 53 | return atts; 54 | }, 55 | Radio(){ 56 | return Radio; 57 | } 58 | }); 59 | -------------------------------------------------------------------------------- /.versions: -------------------------------------------------------------------------------- 1 | aldeed:autoform@5.5.0 2 | aldeed:collection2@2.3.3 3 | aldeed:simple-schema@1.3.2 4 | allow-deny@1.0.4 5 | babel-compiler@6.6.4 6 | babel-runtime@0.1.8 7 | base64@1.0.8 8 | bigdsk:inputmask@3.1.63 9 | binary-heap@1.0.8 10 | blaze@2.1.7 11 | blaze-tools@1.0.8 12 | boilerplate-generator@1.0.8 13 | caching-compiler@1.0.4 14 | caching-html-compiler@1.0.6 15 | callback-hook@1.0.8 16 | check@1.2.1 17 | coffeescript@1.0.17 18 | cosmos:browserify@0.5.0 19 | ddp@1.2.5 20 | ddp-client@1.2.7 21 | ddp-common@1.2.5 22 | ddp-server@1.2.6 23 | deps@1.0.12 24 | diff-sequence@1.0.5 25 | ecmascript@0.4.3 26 | ecmascript-runtime@0.2.10 27 | ejson@1.0.11 28 | geojson-utils@1.0.8 29 | html-tools@1.0.9 30 | htmljs@1.0.9 31 | id-map@1.0.7 32 | jquery@1.11.8 33 | livedata@1.0.18 34 | logging@1.0.12 35 | meteor@1.1.14 36 | minifier-js@1.1.11 37 | minimongo@1.0.16 38 | modules@0.6.1 39 | modules-runtime@0.6.3 40 | momentjs:moment@2.10.6 41 | mongo@1.1.7 42 | mongo-id@1.0.4 43 | natestrauser:select2@4.0.0_1 44 | npm-mongo@1.4.43 45 | observe-sequence@1.0.11 46 | ordered-dict@1.0.7 47 | poetic:react-autoform-material-ui@0.1.9 48 | promise@0.6.7 49 | random@1.0.9 50 | react-runtime@0.13.3_4 51 | react-runtime-dev@0.13.3_3 52 | react-runtime-prod@0.13.3_2 53 | react-template-helper@0.1.2 54 | reactive-dict@1.1.7 55 | reactive-var@1.0.9 56 | retry@1.0.7 57 | routepolicy@1.0.10 58 | spacebars@1.0.11 59 | spacebars-compiler@1.0.11 60 | templating@1.1.9 61 | templating-tools@1.0.4 62 | tmeasday:check-npm-versions@0.2.0 63 | tracker@1.0.13 64 | ui@1.0.11 65 | underscore@1.0.8 66 | webapp@1.2.8 67 | webapp-hashing@1.0.9 68 | -------------------------------------------------------------------------------- /example/client/demo/demo.jsx: -------------------------------------------------------------------------------- 1 | let demo_schemas = {}; 2 | sessionCollection = new Mongo.Collection('sessioncollection'); 3 | sessionCollection.find().observe({ 4 | added: renderer, 5 | removed:renderer, 6 | changed: renderer, 7 | }) 8 | 9 | demo_schemas.sessionSchema = new SimpleSchema({ 10 | session_text: { 11 | type: String, 12 | label: 'Name' 13 | }, 14 | email: { 15 | type: String, 16 | regEx: SimpleSchema.RegEx.Email, 17 | label: "E-mail address" 18 | }, 19 | Time: { 20 | type: String, 21 | autoform: { 22 | type: "time" 23 | } 24 | }, 25 | }); 26 | 27 | 28 | sessionCollection.attachSchema(demo_schemas.sessionSchema); 29 | 30 | Template['demo'].helpers({ 31 | 32 | session_collection() { 33 | // Returns the session collection 34 | return sessionCollection; 35 | } 36 | }) 37 | 38 | Template['demo'].rendered = function() { 39 | renderer(); 40 | 41 | } 42 | 43 | function renderer() { 44 | let html = ''; 45 | sessionCollection.find().forEach( 46 | function(doc){ 47 | html += '
Got ' + doc['email'] +' for ' + doc['session_text'] + ' at ' + doc['Time'] +'
'; 48 | }) 49 | 50 | $('#schema_struct').html(html); 51 | } 52 | 53 | 54 | 55 | 56 | const hooksObj = { 57 | 58 | // Called when any submit operation succeeds 59 | onSubmit(formType, result) { 60 | this.event.preventDefault(); //Prevent default form submission 61 | sessionCollection.insert(result.$set) 62 | 63 | let formId = AutoForm.getFormId(); 64 | $('#'+formId)[0].reset();//clear form 65 | }, 66 | 67 | }; 68 | AutoForm.addHooks('session_form', hooksObj); 69 | -------------------------------------------------------------------------------- /inputTypes/file/file.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { RaisedButton } = require('material-ui'); 10 | 11 | 12 | 13 | AutoForm.addInputType("file", { 14 | template: "afInputFile_reactAutoformMaterialUi" 15 | }); 16 | const File = React.createClass({ 17 | childContextTypes: { 18 | muiTheme: React.PropTypes.object 19 | }, 20 | 21 | getChildContext: function() { 22 | return { 23 | muiTheme: ThemeManager.getCurrentTheme() 24 | }; 25 | }, 26 | _handleChange: function(e){ 27 | console.log(e.target.value) 28 | }, 29 | _openFileDialog: function(){ 30 | const fileUploadDom = this.refs.fileUpload; 31 | fileUploadDom.click(); 32 | }, 33 | 34 | render: function() { 35 | return ( 36 |
37 | 40 | 47 |
48 | ); 49 | } 50 | }); 51 | Template["afInputFile_reactAutoformMaterialUi"].helpers({ 52 | atts:function(){ 53 | let atts = new ReactAutoformUtility(this.atts); 54 | return atts; 55 | }, 56 | File: function(){ 57 | return File; 58 | } 59 | }) 60 | -------------------------------------------------------------------------------- /inputTypes/password/password.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { TextField } = require('material-ui'); 10 | 11 | AutoForm.addInputType("password", { 12 | template: "afInputPassword_reactAutoformMaterialUi", 13 | valueConverters: { 14 | "stringArray": function (val) { 15 | if (typeof val === "string" && val.length > 0) { 16 | return [val]; 17 | } 18 | return val; 19 | } 20 | }, 21 | contextAdjust: function (context) { 22 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 23 | context.atts.maxlength = context.max; 24 | } 25 | return context; 26 | } 27 | }); 28 | 29 | const Password = React.createClass({ 30 | childContextTypes: { 31 | muiTheme: React.PropTypes.object 32 | }, 33 | 34 | getChildContext: function() { 35 | const muiTheme = rmui.getComponentThemes(); 36 | return { 37 | muiTheme, 38 | }; 39 | }, 40 | 41 | render: function() { 42 | return ( 43 |
44 | 50 |
51 | ); 52 | } 53 | }); 54 | Template["afInputPassword_reactAutoformMaterialUi"].helpers({ 55 | Password: function(){ 56 | return Password; 57 | }, 58 | atts(){ 59 | let atts = new ReactAutoformUtility(this.atts); 60 | return atts; 61 | } 62 | }) 63 | -------------------------------------------------------------------------------- /components/afObjectField/afObjectField.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | const React = require('react'); 10 | const ReactDOM = require('react-dom'); 11 | const { 12 | Card, 13 | CardHeader, 14 | CardText, 15 | Avatar 16 | } = require('material-ui'); 17 | 18 | let set = false; 19 | const objectField = React.createClass({ 20 | 21 | childContextTypes: { 22 | muiTheme: React.PropTypes.object 23 | }, 24 | 25 | getChildContext: function() { 26 | return { 27 | muiTheme: ThemeManager.getCurrentTheme() 28 | }; 29 | }, 30 | componentDidMount() { 31 | const parentNode = this.refs.placeholder; 32 | rmui.afObjectFieldReady.set(parentNode); 33 | }, 34 | render: function() { 35 | return ( 36 |
37 | 38 | {this.props.atts.title[0].toLocaleUpperCase()}} 41 | showExpandableButton={true} 42 | > 43 | 44 | 45 |
46 |
47 |
48 |
49 |
50 | ); 51 | } 52 | }); 53 | 54 | 55 | Template.afObjectField_reactAutoformMaterialUi.helpers({ 56 | atts(){ 57 | let atts = {}; 58 | atts.title = this.name; 59 | return atts; 60 | }, 61 | objectField() { 62 | return objectField 63 | }, 64 | getFields() { 65 | if(typeof rmui.afObjectFieldReady.get() === 'object' && !set){ 66 | 67 | let qfTemplate = Template.afQuickFields; 68 | set = true; 69 | return Blaze.renderWithData(qfTemplate,{name:this.name,fields:this.name}, rmui.afObjectFieldReady.get()) 70 | } 71 | } 72 | }); 73 | -------------------------------------------------------------------------------- /inputTypes/datetime/datetime.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("datetime", { 2 | template: "afInputDateTime", 3 | valueIn: function (val) { 4 | //convert Date to string value 5 | return (val instanceof Date) ? AutoForm.Utility.dateToNormalizedForcedUtcGlobalDateAndTimeString(val): val; 6 | }, 7 | valueOut: function () { 8 | var val = this.val(); 9 | val = (typeof val === "string") ? val.replace(/ /g, "T") : val; 10 | if (AutoForm.Utility.isValidNormalizedForcedUtcGlobalDateAndTimeString(val)) { 11 | //Date constructor will interpret val as UTC due to ending "Z" 12 | return new Date(val); 13 | } else { 14 | return null; 15 | } 16 | }, 17 | valueConverters: { 18 | "string": function (val) { 19 | return (val instanceof Date) ? AutoForm.Utility.dateToNormalizedForcedUtcGlobalDateAndTimeString(val) : val; 20 | }, 21 | "stringArray": function (val) { 22 | if (val instanceof Date) { 23 | return [AutoForm.Utility.dateToNormalizedForcedUtcGlobalDateAndTimeString(val)]; 24 | } 25 | return val; 26 | }, 27 | "number": function (val) { 28 | return (val instanceof Date) ? val.getTime() : val; 29 | }, 30 | "numberArray": function (val) { 31 | if (val instanceof Date) { 32 | return [val.getTime()]; 33 | } 34 | return val; 35 | }, 36 | "dateArray": function (val) { 37 | if (val instanceof Date) { 38 | return [val]; 39 | } 40 | return val; 41 | } 42 | }, 43 | contextAdjust: function (context) { 44 | if (typeof context.atts.max === "undefined" && context.max instanceof Date) { 45 | context.atts.max = AutoForm.Utility.dateToNormalizedForcedUtcGlobalDateAndTimeString(context.max); 46 | } 47 | if (typeof context.atts.min === "undefined" && context.min instanceof Date) { 48 | context.atts.min = AutoForm.Utility.dateToNormalizedForcedUtcGlobalDateAndTimeString(context.min); 49 | } 50 | return context; 51 | } 52 | }); -------------------------------------------------------------------------------- /example/.meteor/versions: -------------------------------------------------------------------------------- 1 | aldeed:autoform@5.4.1 2 | aldeed:collection2@2.3.3 3 | aldeed:simple-schema@1.3.3 4 | aldeed:template-extension@3.4.3 5 | autopublish@1.0.3 6 | autoupdate@1.2.1 7 | babel-compiler@5.6.15 8 | babel-runtime@0.1.3 9 | babrahams:editable-json@0.4.3 10 | base64@1.0.3 11 | bigdsk:inputmask@3.1.63 12 | binary-heap@1.0.3 13 | blaze@2.1.2 14 | blaze-tools@1.0.3 15 | boilerplate-generator@1.0.3 16 | callback-hook@1.0.3 17 | check@1.0.5 18 | coffeescript@1.0.6 19 | cosmos:browserify@0.5.1 20 | dburles:mongo-collection-instances@0.3.4 21 | ddp@1.1.0 22 | deps@1.0.7 23 | ejson@1.0.6 24 | entropy:ramjet@0.4.6 25 | fastclick@1.0.3 26 | geojson-utils@1.0.3 27 | gwendall:session-json@0.1.7 28 | html-tools@1.0.4 29 | htmljs@1.0.4 30 | http@1.1.0 31 | id-map@1.0.3 32 | insecure@1.0.3 33 | iron:controller@1.0.8 34 | iron:core@1.0.8 35 | iron:dynamic-template@1.0.8 36 | iron:layout@1.0.8 37 | iron:location@1.0.9 38 | iron:middleware-stack@1.0.9 39 | iron:router@1.0.9 40 | iron:url@1.0.9 41 | jquery@1.11.3_2 42 | json@1.0.3 43 | jsx@0.1.6 44 | lai:collection-extensions@0.1.4 45 | launch-screen@1.0.2 46 | livedata@1.0.13 47 | logging@1.0.7 48 | meteor@1.1.6 49 | meteor-platform@1.2.2 50 | meteorhacks:async@1.0.0 51 | meteorhacks:npm@1.4.0 52 | meteortoys:toykit@0.8.7 53 | minifiers@1.1.5 54 | minimongo@1.0.8 55 | mizzao:bootstrap-3@3.3.1_1 56 | mobile-status-bar@1.0.3 57 | momentjs:moment@2.10.6 58 | mongo@1.1.0 59 | msavin:mongol@1.1.5 60 | npm-container@1.1.0 61 | observe-sequence@1.0.6 62 | ordered-dict@1.0.3 63 | poetic:react-autoform-material-ui@0.1.0 64 | poetic:react-material-ui@0.0.3 65 | random@1.0.3 66 | react@0.1.10 67 | react-meteor-data@0.1.6 68 | react-runtime@0.13.3_6 69 | react-runtime-dev@0.13.3_5 70 | react-runtime-prod@0.13.3_4 71 | react-template-helper@0.1.5 72 | reactive-dict@1.1.0 73 | reactive-var@1.0.5 74 | reload@1.1.3 75 | retry@1.0.3 76 | routepolicy@1.0.5 77 | session@1.1.0 78 | spacebars@1.0.6 79 | spacebars-compiler@1.0.6 80 | templating@1.1.1 81 | tracker@1.0.7 82 | ui@1.0.6 83 | underscore@1.0.3 84 | url@1.0.4 85 | webapp@1.2.0 86 | webapp-hashing@1.0.3 87 | -------------------------------------------------------------------------------- /inputTypes/select-radio/select-radio.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { RadioButton, RadioButtonGroup } from 'material-ui'; 3 | 4 | AutoForm.addInputType("select-radio", { 5 | template: "afRadioGroup_reactAutoformMaterialUi", 6 | valueOut: function () { 7 | return this.find('input[type=radio]:checked').val(); 8 | }, 9 | contextAdjust: function (context) { 10 | var itemAtts = _.omit(context.atts); 11 | 12 | // build items list 13 | context.items = []; 14 | 15 | // Add all defined options 16 | _.each(context.selectOptions, function(opt) { 17 | context.items.push({ 18 | name: context.name, 19 | label: opt.label, 20 | value: opt.value, 21 | // _id must be included because it is a special property that 22 | // #each uses to track unique list items when adding and removing them 23 | // See https://github.com/meteor/meteor/issues/2174 24 | _id: opt.value, 25 | selected: (opt.value === context.value), 26 | atts: itemAtts 27 | }); 28 | }); 29 | 30 | return context; 31 | } 32 | }); 33 | const selectRadio = React.createClass({ 34 | 35 | childContextTypes: { 36 | muiTheme: React.PropTypes.object 37 | }, 38 | 39 | getChildContext: function() { 40 | return { 41 | muiTheme: ThemeManager.getCurrentTheme() 42 | }; 43 | }, 44 | render: function() { 45 | 46 | return ( 47 | 48 | {this.props.atts.items.map(function(result) { 49 | return ; 51 | })} 52 | 53 | ); 54 | }, 55 | _handleFloatingInputChange: function(){ 56 | //Handle verification/validation here 57 | } 58 | }); 59 | 60 | Template["afRadioGroup_reactAutoformMaterialUi"].helpers({ 61 | atts() { 62 | let atts = this.atts; 63 | atts.items = this.items; 64 | return atts; 65 | }, 66 | selectRadio() { 67 | 68 | return selectRadio; 69 | } 70 | }); 71 | -------------------------------------------------------------------------------- /inputTypes/tel/tel.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { TextField } = require('material-ui'); 10 | 11 | AutoForm.addInputType("tel", { 12 | template: "afInputTel_reactAutoformMaterialUi", 13 | valueConverters: { 14 | "stringArray": function (val) { 15 | if (typeof val === "string" && val.length > 0) { 16 | return [val]; 17 | } 18 | return val; 19 | } 20 | }, 21 | contextAdjust: function (context) { 22 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 23 | context.atts.maxlength = context.max; 24 | } 25 | context.atts.value = context.value; 26 | return context; 27 | } 28 | }); 29 | 30 | const TelFieldClass = React.createClass({ 31 | childContextTypes: { 32 | muiTheme: React.PropTypes.object 33 | }, 34 | 35 | getChildContext: function() { 36 | const muiTheme = rmui.getComponentThemes(); 37 | return { 38 | muiTheme, 39 | }; 40 | }, 41 | render: function() { 42 | return ( 43 | 53 | ); 54 | } 55 | }); 56 | 57 | Template.afInputTel_reactAutoformMaterialUi.helpers({ 58 | TelField(){ 59 | return TelFieldClass; 60 | }, 61 | atts() { 62 | let atts = new ReactAutoformUtility(this.atts); 63 | return atts; 64 | } 65 | }); 66 | 67 | Template.afInputTel_reactAutoformMaterialUi.events({ 68 | 'keyup'(event) { 69 | let target = $(event.target)[0]; 70 | let targetLength = target.value; 71 | $(target).inputmask("mask", {"mask": "(999) 999-9999"}); 72 | } 73 | }) 74 | -------------------------------------------------------------------------------- /inputTypes/select-checkbox copy/select-checkbox.jsx: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType('select-checkbox', { 2 | template: 'afCheckboxGroup_reactAutoformMaterialUi', 3 | valueIsArray: true, 4 | valueOut: function () { 5 | var val = []; 6 | this.find('input[type=checkbox]').each(function () { 7 | if ($(this).is(":checked")) { 8 | val.push($(this).val()); 9 | } 10 | }); 11 | return val; 12 | }, 13 | contextAdjust: function (context) { 14 | var itemAtts = _.omit(context.atts); 15 | 16 | // build items list 17 | context.items = []; 18 | 19 | // Add all defined options 20 | _.each(context.selectOptions, function(opt) { 21 | context.items.push({ 22 | name: context.name, 23 | label: opt.label, 24 | value: opt.value, 25 | // _id must be included because it is a special property that 26 | // #each uses to track unique list items when adding and removing them 27 | // See https://github.com/meteor/meteor/issues/2174 28 | _id: opt.value, 29 | selected: (_.contains(context.value, opt.value)), 30 | atts: itemAtts 31 | }); 32 | }); 33 | 34 | return context; 35 | } 36 | }); 37 | 38 | const { Checkbox } = mui; 39 | const Checkbox = React.createClass({ 40 | 41 | childContextTypes: { 42 | muiTheme: React.PropTypes.object 43 | }, 44 | 45 | getChildContext() { 46 | return { 47 | muiTheme: ThemeManager.getCurrentTheme() 48 | }; 49 | }, 50 | 51 | render() { 52 | return ( 53 | 57 | ); 58 | } 59 | }); 60 | Template['afCheckboxGroup_reactAutoformMaterialUi'].helpers({ 61 | atts() { 62 | // let atts = _.clone(this.atts); 63 | let atts = new ReactAutoformUtility(this.atts); 64 | if (this.selected) { 65 | atts.checked = ""; 66 | } 67 | // remove data-schema-key attribute because we put it 68 | // on the entire group 69 | // delete atts['data-schema-key']; 70 | return atts; 71 | }, 72 | checkbox() { 73 | return Checkbox 74 | } 75 | }); 76 | -------------------------------------------------------------------------------- /inputTypes/select-checkbox-inline/select-checkbox-inline.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("select-checkbox-inline", { 2 | template: "afCheckboxGroupInline_autoform-material-design-lite", 3 | valueIsArray: true, 4 | valueOut: function () { 5 | var val = []; 6 | this.find('input[type=checkbox]').each(function () { 7 | if ($(this).is(":checked")) { 8 | val.push($(this).val()); 9 | } 10 | }); 11 | return val; 12 | }, 13 | contextAdjust: function (context) { 14 | var itemAtts = _.omit(context.atts); 15 | 16 | // build items list 17 | context.items = []; 18 | 19 | // Add all defined options 20 | _.each(context.selectOptions, function(opt) { 21 | context.items.push({ 22 | name: context.name, 23 | label: opt.label, 24 | value: opt.value, 25 | // _id must be included because it is a special property that 26 | // #each uses to track unique list items when adding and removing them 27 | // See https://github.com/meteor/meteor/issues/2174 28 | _id: opt.value, 29 | selected: (_.contains(context.value, opt.value)), 30 | atts: itemAtts 31 | }); 32 | }); 33 | 34 | return context; 35 | } 36 | }); 37 | 38 | Template["afCheckboxGroupInline_autoform-material-design-lite"].helpers({ 39 | atts: function selectedAttsAdjust() { 40 | var atts = _.clone(this.atts); 41 | if (this.selected) { 42 | atts.checked = ""; 43 | } 44 | // remove data-schema-key attribute because we put it 45 | // on the entire group 46 | delete atts["data-schema-key"]; 47 | return atts; 48 | }, 49 | dsk: function dsk() { 50 | return { 51 | "data-schema-key": this.atts["data-schema-key"] 52 | } 53 | } 54 | }); 55 | Template["afCheckboxGroupInline_autoform-material-design-lite"].rendered = function(){ 56 | var box = this.findAll('.mdl-checkbox__box-outline'); 57 | var checkbox = this.findAll('.mdl-checkbox'); 58 | 59 | checkbox.forEach(function(checkbox){ 60 | checkbox.style.display = "inline"; 61 | checkbox.style.margin = "3px"; 62 | }); 63 | box.forEach(function(box){ 64 | box.style.top = "-1px"; 65 | }); 66 | 67 | } -------------------------------------------------------------------------------- /inputTypes/select/select-stylable.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | const React = require('react'); 10 | const ReactDOM = require('react-dom'); 11 | const { RaisedButton } = require('material-ui'); 12 | 13 | export default StylableDropDown = React.createClass({ 14 | childContextTypes: { 15 | muiTheme: React.PropTypes.object 16 | }, 17 | 18 | getInitialState(){ 19 | const { selectedIndex } = this.props; 20 | return { selectedIndex }; 21 | }, 22 | 23 | getOptions(){ 24 | return this.props.options.map(function(option) { 25 | return 26 | }).join(' '); 27 | }, 28 | 29 | _getValue() { 30 | const stylableSelect = ReactDOM.findDOMNode(this.refs.stylableSelect); 31 | const value = $(stylableSelect).val(); 32 | 33 | this.props.onChange(null,null, { value }); 34 | }, 35 | 36 | reportChange(e) { 37 | const { target } = e; 38 | const {value , selectedIndex } = target; 39 | const options = { 40 | value, 41 | }; 42 | this.props.onChange(target, selectedIndex, options); 43 | this.setState({ value }); 44 | }, 45 | 46 | getChildContext() { 47 | const muiTheme = rmui.getComponentThemes(); 48 | return { 49 | muiTheme, 50 | }; 51 | }, 52 | 53 | render() { 54 | const defaultOptions = [ 55 | { 56 | label: 'Yes', 57 | value: true 58 | }, 59 | { 60 | label: 'No', 61 | value: false 62 | }, 63 | ]; 64 | const { defaultValue, options = defaultOptions, disable } = this.props; 65 | 66 | return ( 67 | 86 | ); 87 | } 88 | }); 89 | -------------------------------------------------------------------------------- /components/afArrayField/afArrayField.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { 10 | Card, 11 | CardHeader, 12 | CardText, 13 | CardActions, 14 | RaisedButton, 15 | FontIcon, 16 | Avatar 17 | } = require('material-ui'); 18 | 19 | let set = false; 20 | const afArrayField = React.createClass({ 21 | 22 | childContextTypes: { 23 | muiTheme: React.PropTypes.object 24 | }, 25 | 26 | getChildContext: function() { 27 | return { 28 | muiTheme: ThemeManager.getCurrentTheme() 29 | }; 30 | }, 31 | componentDidMount() { 32 | const parentNode = this.refs.placeholder; 33 | rmui.afArrayFieldReady.set(parentNode); 34 | }, 35 | render: function() { 36 | 37 | return ( 38 |
39 | 40 | {this.props.atts.title[0].toLocaleUpperCase()}} 44 | showExpandableButton={true} 45 | > 46 | 47 | 48 |
49 | 50 |
51 |
52 | 53 | 54 |
55 |
56 | ); 57 | } 58 | }); 59 | 60 | 61 | Template.afArrayField_reactAutoformMaterialUi.helpers({ 62 | atts(){ 63 | let atts = {}; 64 | atts.title = this.atts.name; 65 | atts.err = ""; 66 | 67 | //Check validity 68 | let isInvalid = Blaze._globalHelpers.afFieldIsInvalid({name:this.atts.name}) 69 | if(isInvalid){ 70 | atts.err = Blaze._globalHelpers.afFieldMessage(); 71 | } 72 | return atts; 73 | }, 74 | afArrayComp() { 75 | return afArrayField 76 | }, 77 | arrFields() { 78 | if((typeof rmui.afArrayFieldReady.get() === 'object') && !set){ 79 | let arrayObj = AutoForm.arrayTracker.getField(AutoForm.getFormId(),this.atts.name); 80 | arrayObj = arrayObj[0].current; 81 | 82 | let qfTemplate = Template.afQuickField; 83 | set = true; 84 | 85 | _.map(arrayObj,function(key){ 86 | 87 | return Blaze.renderWithData(qfTemplate,{name:key}, rmui.afArrayFieldReady.get()) 88 | }) 89 | } 90 | } 91 | }); 92 | -------------------------------------------------------------------------------- /example/client/example.html: -------------------------------------------------------------------------------- 1 | 2 | React-Autoform-MaterialUi 3 | 4 | 7 | 12 | 13 | 18 | 54 | 55 | 64 | 65 | -------------------------------------------------------------------------------- /inputTypes/textarea/textarea.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { TextField } from 'material-ui'; 3 | 4 | AutoForm.addInputType("textarea", { 5 | template: "afTextarea_reactAutoformMaterialUi", 6 | valueConverters: { 7 | "string": function (val) { 8 | return val; 9 | }, 10 | "stringArray": function (val) { 11 | if (typeof val === "string" && val.length > 0) { 12 | return linesToArray(val); 13 | } 14 | return val; 15 | }, 16 | "number": AutoForm.Utility.stringToNumber, 17 | "numberArray": function (val) { 18 | if (typeof val === "string" && val.length > 0) { 19 | var arr = linesToArray(val); 20 | return _.map(arr, function (item) { 21 | return AutoForm.Utility.stringToNumber(item); 22 | }); 23 | } 24 | return val; 25 | }, 26 | "boolean": AutoForm.Utility.stringToBool, 27 | "booleanArray": function (val) { 28 | if (typeof val === "string" && val.length > 0) { 29 | var arr = linesToArray(val); 30 | return _.map(arr, function (item) { 31 | return AutoForm.Utility.stringToBool(item); 32 | }); 33 | } 34 | return val; 35 | }, 36 | "date": AutoForm.Utility.stringToDate, 37 | "dateArray": function (val) { 38 | if (typeof val === "string" && val.length > 0) { 39 | var arr = linesToArray(val); 40 | return _.map(arr, function (item) { 41 | return AutoForm.Utility.stringToDate(item); 42 | }); 43 | } 44 | return val; 45 | } 46 | }, 47 | contextAdjust: function (context) { 48 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 49 | context.atts.maxlength = context.max; 50 | } 51 | return context; 52 | } 53 | }); 54 | 55 | function linesToArray(text) { 56 | text = text.split('\n'); 57 | var lines = []; 58 | _.each(text, function (line) { 59 | line = $.trim(line); 60 | if (line.length) { 61 | lines.push(line); 62 | } 63 | }); 64 | return lines; 65 | } 66 | const TextArea = React.createClass({ 67 | 68 | childContextTypes: { 69 | muiTheme: React.PropTypes.object 70 | }, 71 | 72 | getChildContext: function() { 73 | return { 74 | muiTheme: ThemeManager.getCurrentTheme() 75 | }; 76 | }, 77 | 78 | render: function() { 79 | return ( 80 | 81 | ); 82 | } 83 | }); 84 | Template["afTextarea_reactAutoformMaterialUi"].helpers({ 85 | atts: function(){ 86 | let atts = this.atts; 87 | return atts; 88 | }, 89 | TextArea : function(){ 90 | return TextArea; 91 | } 92 | }) 93 | -------------------------------------------------------------------------------- /inputTypes/select-multiple/select-multiple.jsx: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("select-multiple", { 2 | template: "afSelectMultiple_reactAutoformMaterialUi", 3 | valueIsArray: true, 4 | valueOut: function () { 5 | return AutoForm.Utility.getSelectValues(this[0]); 6 | }, 7 | contextAdjust: function (context) { 8 | // build items list 9 | context.items = _.map(context.selectOptions, function(opt) { 10 | if (opt.optgroup) { 11 | var subItems = _.map(opt.options, function(subOpt) { 12 | return { 13 | name: context.name, 14 | label: subOpt.label, 15 | value: subOpt.value, 16 | htmlAtts: _.omit(subOpt, 'label', 'value'), 17 | // _id must be included because it is a special property that 18 | // #each uses to track unique list items when adding and removing them 19 | // See https://github.com/meteor/meteor/issues/2174 20 | _id: subOpt.value, 21 | selected: _.contains(context.value, subOpt.value), 22 | atts: context.atts 23 | }; 24 | }); 25 | return { 26 | optgroup: opt.optgroup, 27 | items: subItems 28 | }; 29 | } else { 30 | return { 31 | name: context.name, 32 | label: opt.label, 33 | value: opt.value, 34 | htmlAtts: _.omit(opt, 'label', 'value'), 35 | // _id must be included because it is a special property that 36 | // #each uses to track unique list items when adding and removing them 37 | // See https://github.com/meteor/meteor/issues/2174 38 | _id: opt.value, 39 | selected: _.contains(context.value, opt.value), 40 | atts: context.atts 41 | }; 42 | } 43 | }); 44 | 45 | return context; 46 | } 47 | }); 48 | 49 | const { List,ListItem,Checkbox} = mui; 50 | const SelectMultiple = React.createClass({ 51 | 52 | childContextTypes: { 53 | muiTheme: React.PropTypes.object 54 | }, 55 | 56 | getChildContext()) { 57 | return { 58 | muiTheme: ThemeManager.getCurrentTheme() 59 | }; 60 | }, 61 | render() { 62 | let results = this.props.atts.items; 63 | 64 | return ( 65 | 66 | {results.map(function(result) { 67 | return } />; 68 | })} 69 | 70 | ); 71 | } 72 | }); 73 | Template["afSelectMultiple_reactAutoformMaterialUi"].helpers({ 74 | atts(){ 75 | let atts = this.atts; 76 | atts.items = this.items; 77 | return atts 78 | }, 79 | SelectMultiple() { 80 | return SelectMultiple; 81 | } 82 | }) 83 | -------------------------------------------------------------------------------- /inputTypes/boolean-radios/boolean-radios.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { RadioButtonGroup,RadioButton } = require('material-ui'); 10 | 11 | AutoForm.addInputType("boolean-radios", { 12 | template: "afBooleanRadioGroup_reactAutoformMaterialUi", 13 | valueOut: function () { 14 | if (this.find('input[value=false]').is(":checked")) { 15 | return false; 16 | } else if (this.find('input[value=true]').is(":checked")) { 17 | return true; 18 | } 19 | }, 20 | valueConverters: { 21 | "string": function (val) { 22 | if (val === true) { 23 | return "TRUE"; 24 | } else if (val === false) { 25 | return "FALSE"; 26 | } 27 | return val; 28 | }, 29 | "stringArray": function (val) { 30 | if (val === true) { 31 | return ["TRUE"]; 32 | } else if (val === false) { 33 | return ["FALSE"]; 34 | } 35 | return val; 36 | }, 37 | "number": function (val) { 38 | if (val === true) { 39 | return 1; 40 | } else if (val === false) { 41 | return 0; 42 | } 43 | return val; 44 | }, 45 | "numberArray": function (val) { 46 | if (val === true) { 47 | return [1]; 48 | } else if (val === false) { 49 | return [0]; 50 | } 51 | return val; 52 | } 53 | } 54 | }); 55 | const RadioButtonGroupClass = React.createClass({ 56 | 57 | childContextTypes: { 58 | muiTheme: React.PropTypes.object 59 | }, 60 | 61 | getChildContext() { 62 | return { 63 | muiTheme: ThemeManager.getCurrentTheme() 64 | }; 65 | }, 66 | 67 | render() { 68 | return ( 69 | 70 | 71 | 74 | 77 | 78 | 79 | ); 80 | } 81 | }); 82 | Template["afBooleanRadioGroup_reactAutoformMaterialUi"].helpers({ 83 | 84 | BooleanRadios(){ 85 | return RadioButtonGroupClass; 86 | }, 87 | atts() { 88 | let atts = new ReactAutoformUtility(this.atts); 89 | 90 | //Check atts object for label values, if not default to True or False 91 | 92 | atts.trueLabel = (this.atts.trueLabel == undefined || null) ? "True" : this.atts.trueLabel; 93 | atts.falseLabel = (this.atts.falseLabel == undefined || null) ? "False" : this.atts.falseLabel; 94 | 95 | return atts; 96 | } 97 | }); 98 | -------------------------------------------------------------------------------- /inputTypes/date/date.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { DatePicker } = require('material-ui'); 10 | 11 | AutoForm.addInputType("date", { 12 | template: "afInputDate_reactAutoformMaterialUi", 13 | valueIn: function (val) { 14 | //convert Date to string value 15 | return (val instanceof Date) ? AutoForm.Utility.dateToDateStringUTC(val) : val; 16 | }, 17 | valueOut: function () { 18 | let val = this.val(); 19 | if (AutoForm.Utility.isValidDateString(val)) { 20 | //Date constructor will interpret val as UTC and create 21 | //date at mignight in the morning of val date in UTC time zone 22 | return new Date(val); 23 | } else { 24 | return null; 25 | } 26 | }, 27 | valueConverters: { 28 | "string": function (val) { 29 | return (val instanceof Date) ? AutoForm.Utility.dateToDateStringUTC(val) : val; 30 | }, 31 | "stringArray": function (val) { 32 | if (val instanceof Date) { 33 | return [AutoForm.Utility.dateToDateStringUTC(val)]; 34 | } 35 | return val; 36 | }, 37 | "number": function (val) { 38 | return (val instanceof Date) ? val.getTime() : val; 39 | }, 40 | "numberArray": function (val) { 41 | if (val instanceof Date) { 42 | return [val.getTime()]; 43 | } 44 | return val; 45 | }, 46 | "dateArray": function (val) { 47 | if (val instanceof Date) { 48 | return [val]; 49 | } 50 | return val; 51 | } 52 | }, 53 | contextAdjust: function (context) { 54 | if (typeof context.atts.max === "undefined" && context.max instanceof Date) { 55 | context.atts.max = AutoForm.Utility.dateToDateStringUTC(context.max); 56 | } 57 | if (typeof context.atts.min === "undefined" && context.min instanceof Date) { 58 | context.atts.min = AutoForm.Utility.dateToDateStringUTC(context.min); 59 | } 60 | return context; 61 | } 62 | }); 63 | 64 | const DatePickerClass = React.createClass({ 65 | childContextTypes: { 66 | muiTheme: React.PropTypes.object 67 | }, 68 | 69 | getChildContext: function() { 70 | return { 71 | muiTheme: ThemeManager.getCurrentTheme() 72 | }; 73 | }, 74 | 75 | render: function() { 76 | return ( 77 | 79 | ); 80 | } 81 | }); 82 | Template["afInputDate_reactAutoformMaterialUi"].helpers({ 83 | DatePicker: function(){ 84 | return DatePickerClass; 85 | }, 86 | atts: function(){ 87 | let atts = new ReactAutoformUtility(this.atts); 88 | return atts; 89 | } 90 | }) 91 | -------------------------------------------------------------------------------- /inputTypes/boolean-select/boolean-select.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("boolean-select", { 2 | template: "afBooleanSelect_react-autoform-material-ui", 3 | valueOut: function () { 4 | var val = this.val(); 5 | if (val === "true") { 6 | return true; 7 | } else if (val === "false") { 8 | return false; 9 | } 10 | }, 11 | valueConverters: { 12 | "string": function (val) { 13 | if (val === true) { 14 | return "TRUE"; 15 | } else if (val === false) { 16 | return "FALSE"; 17 | } 18 | return val; 19 | }, 20 | "stringArray": function (val) { 21 | if (val === true) { 22 | return ["TRUE"]; 23 | } else if (val === false) { 24 | return ["FALSE"]; 25 | } 26 | return val; 27 | }, 28 | "number": function (val) { 29 | if (val === true) { 30 | return 1; 31 | } else if (val === false) { 32 | return 0; 33 | } 34 | return val; 35 | }, 36 | "numberArray": function (val) { 37 | if (val === true) { 38 | return [1]; 39 | } else if (val === false) { 40 | return [0]; 41 | } 42 | return val; 43 | } 44 | }, 45 | contextAdjust: function (context) { 46 | var atts = _.omit(context.atts, 'trueLabel', 'falseLabel', 'firstOption'); 47 | 48 | // build items list 49 | context.items = [ 50 | { 51 | name: context.name, 52 | value: "", 53 | // _id must be included because it is a special property that 54 | // #each uses to track unique list items when adding and removing them 55 | // See https://github.com/meteor/meteor/issues/2174 56 | _id: "", 57 | selected: (context.value !== false && context.value !== true), 58 | label: context.atts.firstOption || "(Select One)", 59 | atts: atts 60 | }, 61 | { 62 | name: context.name, 63 | value: "false", 64 | // _id must be included because it is a special property that 65 | // #each uses to track unique list items when adding and removing them 66 | // See https://github.com/meteor/meteor/issues/2174 67 | _id: "false", 68 | selected: (context.value === false), 69 | label: context.atts.falseLabel || "False", 70 | atts: atts 71 | }, 72 | { 73 | name: context.name, 74 | value: "true", 75 | // _id must be included because it is a special property that 76 | // #each uses to track unique list items when adding and removing them 77 | // See https://github.com/meteor/meteor/issues/2174 78 | _id: "true", 79 | selected: (context.value === true), 80 | label: context.atts.trueLabel || "True", 81 | atts: atts 82 | } 83 | ]; 84 | 85 | return context; 86 | } 87 | }); 88 | 89 | Template["afBooleanSelect_react-autoform-material-ui"].helpers({ 90 | 91 | }) -------------------------------------------------------------------------------- /inputTypes/number/number.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { TextField } = require('material-ui'); 10 | 11 | AutoForm.addInputType("number", { 12 | template: "afInputNumber_reactAutoformMaterialUi", 13 | valueOut: function () { 14 | return AutoForm.Utility.stringToNumber(this.val()); 15 | }, 16 | valueConverters: { 17 | "string": function (val) { 18 | if (typeof val === "number") { 19 | return val.toString(); 20 | } 21 | return val; 22 | }, 23 | "stringArray": function (val) { 24 | if (typeof val === "number") { 25 | return [val.toString()]; 26 | } 27 | return val; 28 | }, 29 | "numberArray": function (val) { 30 | if (typeof val === "number") { 31 | return [val]; 32 | } 33 | return val; 34 | }, 35 | "boolean": function (val) { 36 | if (val === 0) { 37 | return false; 38 | } else if (val === 1) { 39 | return true; 40 | } 41 | return val; 42 | }, 43 | "booleanArray": function (val) { 44 | if (val === 0) { 45 | return [false]; 46 | } else if (val === 1) { 47 | return [true]; 48 | } 49 | return val; 50 | } 51 | }, 52 | contextAdjust: function (context) { 53 | if (typeof context.atts.max === "undefined" && typeof context.max === "number") { 54 | context.atts.max = context.max; 55 | } 56 | if (typeof context.atts.min === "undefined" && typeof context.min === "number") { 57 | context.atts.min = context.min; 58 | } 59 | if (typeof context.atts.step === "undefined" && context.decimal) { 60 | context.atts.step = '0.01'; 61 | } 62 | return context; 63 | } 64 | }); 65 | 66 | const Number = React.createClass({ 67 | 68 | childContextTypes: { 69 | muiTheme: React.PropTypes.object 70 | }, 71 | 72 | getChildContext: function() { 73 | return { 74 | muiTheme: ThemeManager.getCurrentTheme() 75 | }; 76 | }, 77 | 78 | render: function() { 79 | return ( 80 | 89 | ); 90 | } 91 | }); 92 | Template['afInputNumber_reactAutoformMaterialUi'].helpers({ 93 | Number: function(){ 94 | return Number; 95 | }, 96 | atts: function() { 97 | let atts = this.atts; 98 | return atts; 99 | } 100 | }); 101 | -------------------------------------------------------------------------------- /inputTypes/text/text.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'material-ui': '0.13.4', 6 | }, 'poetic:react-autoform-material-ui'); 7 | 8 | const React = require('react'); 9 | const { TextField } = require('material-ui'); 10 | 11 | AutoForm.addInputType("text", { 12 | template: "afInputText_reactAutoformMaterialUi", 13 | valueOut: function () { 14 | return this.val(); 15 | }, 16 | valueConverters: { 17 | "stringArray": function (val) { 18 | if (typeof val === "string") { 19 | val = val.split(","); 20 | return _.map(val, function (item) { 21 | return $.trim(item); 22 | }); 23 | } 24 | return val; 25 | }, 26 | "number": AutoForm.Utility.stringToNumber, 27 | "numberArray": function (val) { 28 | if (typeof val === "string") { 29 | val = val.split(","); 30 | return _.map(val, function (item) { 31 | item = $.trim(item); 32 | return AutoForm.Utility.stringToNumber(item); 33 | }); 34 | } 35 | return val; 36 | }, 37 | "boolean": AutoForm.Utility.stringToBool, 38 | "booleanArray": function (val) { 39 | if (typeof val === "string") { 40 | val = val.split(","); 41 | return _.map(val, function (item) { 42 | item = $.trim(item); 43 | return AutoForm.Utility.stringToBool(item); 44 | }); 45 | } 46 | return val; 47 | }, 48 | "date": AutoForm.Utility.stringToDate, 49 | "dateArray": function (val) { 50 | if (typeof val === "string") { 51 | val = val.split(","); 52 | return _.map(val, function (item) { 53 | item = $.trim(item); 54 | return AutoForm.Utility.stringToDate(item); 55 | }); 56 | } 57 | return val; 58 | } 59 | }, 60 | contextAdjust: function (context) { 61 | if (typeof context.atts.maxlength === "undefined" && typeof context.max === "number") { 62 | context.atts.maxlength = context.max; 63 | } 64 | context.atts.value = context.value; 65 | return context; 66 | } 67 | }); 68 | 69 | const TextFieldClass = React.createClass({ 70 | childContextTypes: { 71 | muiTheme: React.PropTypes.object 72 | }, 73 | 74 | getChildContext: function() { 75 | const muiTheme = rmui.getComponentThemes(); 76 | return { 77 | muiTheme, 78 | }; 79 | }, 80 | render: function() { 81 | return ( 82 | 91 | ); 92 | } 93 | }); 94 | Template['afInputText_reactAutoformMaterialUi'].helpers({ 95 | TextField(){ 96 | return TextFieldClass; 97 | }, 98 | atts() { 99 | let atts = new ReactAutoformUtility(this.atts); 100 | return atts; 101 | } 102 | }); 103 | -------------------------------------------------------------------------------- /inputTypes/time/time.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | 10 | const React = require('react'); 11 | const ReactDOM = require('react-dom'); 12 | const { TimePicker } = require('material-ui'); 13 | 14 | AutoForm.addInputType("time", { 15 | template: "afInputTime_reactAutoformMaterialUi", 16 | valueConverters: { 17 | "stringArray": function (val) { 18 | if (typeof val === "string" && val.length > 0) { 19 | return [val]; 20 | } 21 | 22 | return val; 23 | } 24 | } 25 | }); 26 | const Time = React.createClass({ 27 | 28 | childContextTypes: { 29 | muiTheme: React.PropTypes.object 30 | }, 31 | 32 | getChildContext() { 33 | const muiTheme = rmui.getComponentThemes(); 34 | return { 35 | muiTheme, 36 | }; 37 | }, 38 | 39 | componentDidMount() { 40 | let comp = ReactDOM.findDOMNode(this.refs.timeContainer); 41 | $(comp).val(this.timeProcessor()); 42 | }, 43 | 44 | timeProcessor() { 45 | let {value} = this.props.atts; 46 | let timeValue = value || ''; 47 | 48 | if(timeValue) { 49 | let timeObject = timeValue.split(':'); 50 | 51 | //This step ensures there is a valid time format 52 | let hour = '0' + timeObject[0]; 53 | hour = hour.slice(hour.length-2); 54 | let minute = '0' + timeObject[1]; 55 | minute = minute.slice(minute.length-2); 56 | 57 | timeValue = hour +':'+ minute; 58 | } 59 | 60 | return timeValue; 61 | }, 62 | 63 | _getValue(event, obj) { 64 | let domNode = ReactDOM.findDOMNode(this); 65 | $(domNode).val(obj.value) 66 | }, 67 | 68 | render() { 69 | const defaultValue = this.timeProcessor(); 70 | const { atts } = this.props; 71 | 72 | const timeComponent = [ 73 | 80 | ]; 81 | 82 | timeComponent.push( 83 | 88 | ) 89 | 90 | let renderedComponent = this.props.atts.attributes.stylable ? timeComponent[1] : timeComponent[0] 91 | 92 | return ( 93 |
98 | {renderedComponent} 99 |
100 | ) 101 | } 102 | }); 103 | 104 | Template["afInputTime_reactAutoformMaterialUi"].helpers({ 105 | atts() { 106 | const atts = new ReactAutoformUtility(this.atts); 107 | atts.disable = this.disable || this.atts.disable; 108 | atts.stylable = this.stylable; 109 | atts.value = this.value; 110 | 111 | return atts; 112 | }, 113 | Time(){ 114 | return Time; 115 | } 116 | }); 117 | -------------------------------------------------------------------------------- /inputTypes/boolean-checkbox/boolean-checkbox.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | const React = require('react'); 10 | const ReactDOM = require('react-dom'); 11 | const { Checkbox } = require('material-ui'); 12 | 13 | AutoForm.addInputType("boolean-checkbox", { 14 | template: "afCheckbox_reactAutoformMaterialUi", 15 | valueOut: function () { 16 | return !!this.is(":checked"); 17 | }, 18 | valueConverters: { 19 | "string": function (val) { 20 | if (val === true) { 21 | return "TRUE"; 22 | } else if (val === false) { 23 | return "FALSE"; 24 | } 25 | return val; 26 | }, 27 | "stringArray": function (val) { 28 | if (val === true) { 29 | return ["TRUE"]; 30 | } else if (val === false) { 31 | return ["FALSE"]; 32 | } 33 | return val; 34 | }, 35 | "number": function (val) { 36 | if (val === true) { 37 | return 1; 38 | } else if (val === false) { 39 | return 0; 40 | } 41 | return val; 42 | }, 43 | "numberArray": function (val) { 44 | if (val === true) { 45 | return [1]; 46 | } else if (val === false) { 47 | return [0]; 48 | } 49 | return val; 50 | } 51 | }, 52 | contextAdjust: function (context) { 53 | if (context.value === true) { 54 | context.atts.checked = ""; 55 | } 56 | //don't add required attribute to checkboxes because some browsers assume that to mean that it must be checked, which is not what we mean by "required" 57 | delete context.atts.required; 58 | return context; 59 | } 60 | }); 61 | const CheckboxClass = React.createClass({ 62 | 63 | childContextTypes: { 64 | muiTheme: React.PropTypes.object 65 | }, 66 | 67 | getChildContext() { 68 | const muiTheme = rmui.getComponentThemes(); 69 | return { 70 | muiTheme, 71 | }; 72 | }, 73 | 74 | componenetDidMount() { 75 | this.onChange(); 76 | }, 77 | 78 | onChange() { 79 | const { checkbox, checkboxContainer } = this.refs; 80 | const checkboxNode = ReactDOM.findDOMNode(checkboxContainer); 81 | $(checkboxNode).val(checkbox.isChecked()); 82 | }, 83 | 84 | render() { 85 | const { 86 | label, 87 | err, 88 | id, 89 | dsk, 90 | value, 91 | } = this.props.atts; 92 | return ( 93 |
97 | 105 |
106 | ); 107 | } 108 | }); 109 | Template["afCheckbox_reactAutoformMaterialUi"].helpers({ 110 | BooleanCheckbox() { 111 | return CheckboxClass; 112 | }, 113 | atts() { 114 | const atts = new ReactAutoformUtility(this.atts); 115 | atts.value = this.value || atts.value; 116 | return atts; 117 | } 118 | }); 119 | 120 | -------------------------------------------------------------------------------- /inputTypes/range/range.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | 3 | checkNpmVersions({ 4 | 'react': '0.14.x', 5 | 'react-dom': '0.14.x', 6 | 'material-ui': '0.13.4', 7 | }, 'poetic:react-autoform-material-ui'); 8 | 9 | const React = require('react'); 10 | const ReactDOM = require('react-dom'); 11 | const { Slider } = require('material-ui'); 12 | 13 | AutoForm.addInputType("range", { 14 | template: "afInputRange_reactAutoformMaterialUi", 15 | valueOut: function () { 16 | return AutoForm.Utility.stringToNumber(this.val()); 17 | }, 18 | valueConverters: { 19 | "string": function (val) { 20 | if (typeof val === "number") { 21 | return val.toString(); 22 | } 23 | return val; 24 | }, 25 | "stringArray": function (val) { 26 | if (typeof val === "number") { 27 | return [val.toString()]; 28 | } 29 | return val; 30 | }, 31 | "numberArray": function (val) { 32 | if (typeof val === "number") { 33 | return [val]; 34 | } 35 | return val; 36 | }, 37 | "boolean": function (val) { 38 | if (val === 0) { 39 | return false; 40 | } else if (val === 1) { 41 | return true; 42 | } 43 | return val; 44 | }, 45 | "booleanArray": function (val) { 46 | if (val === 0) { 47 | return [false]; 48 | } else if (val === 1) { 49 | return [true]; 50 | } 51 | return val; 52 | } 53 | } 54 | }); 55 | 56 | const Range = React.createClass({ 57 | 58 | childContextTypes: { 59 | muiTheme: React.PropTypes.object 60 | }, 61 | getInitialState() { 62 | return ({ 63 | trackValue:this.props.atts.value 64 | }) 65 | }, 66 | componentDidMount(){ 67 | let defaultValue = this.props.atts.value 68 | this._getValue(null, defaultValue) 69 | 70 | let rmuiRange = this.refs.rmuiRange 71 | let handleStyle = rmuiRange.getStyles().handle 72 | 73 | 74 | 75 | }, 76 | _getValue(event, value) { 77 | let domNode = ReactDOM.findDOMNode(this); 78 | $(domNode).val(value) 79 | 80 | let trackerHandle = $(domNode).find('.react-draggable')[0] 81 | let trackValue = Math.round(value) 82 | 83 | }, 84 | getChildContext() { 85 | return { 86 | muiTheme: ThemeManager.getCurrentTheme() 87 | }; 88 | }, 89 | 90 | render() { 91 | return ( 92 |
93 | 101 | 102 |
103 | ); 104 | } 105 | }); 106 | 107 | Template.afInputRange_reactAutoformMaterialUi.helpers({ 108 | atts(){ 109 | 110 | let atts = new ReactAutoformUtility(this.atts); 111 | atts.min = _.isNumber(this.min) ? this.min : 0; 112 | atts.max = _.isNumber(this.max) ? this.max : 100; 113 | atts.value = _.isNumber(this.value) ? this.value: 0; 114 | return atts; 115 | }, 116 | Range(){ 117 | 118 | return Range; 119 | } 120 | }) 121 | -------------------------------------------------------------------------------- /inputTypes/datetime-local/datetime-local.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | AutoForm.addInputType("datetime-local", { 4 | template: "afInputDateTimeLocal_reactAutoformMaterialUi", 5 | valueIn: function (val, atts) { 6 | //convert Date to string value 7 | return (val instanceof Date) ? AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(val, atts.timezoneId) : val; 8 | }, 9 | valueOut: function () { 10 | var val = this.val(); 11 | val = (typeof val === "string") ? val.replace(/ /g, "T") : val; 12 | if (AutoForm.Utility.isValidNormalizedLocalDateAndTimeString(val)) { 13 | var timezoneId = this.attr("data-timezone-id"); 14 | // default is local, but if there's a timezoneId, we use that 15 | if (typeof timezoneId === "string") { 16 | if (typeof moment.tz !== "function") { 17 | throw new Error("If you specify a timezoneId, make sure that you've added a moment-timezone package to your app"); 18 | } 19 | return moment.tz(val, timezoneId).toDate(); 20 | } else { 21 | return moment(val).toDate(); 22 | } 23 | } else { 24 | return this.val(); 25 | } 26 | }, 27 | valueConverters: { 28 | "string": function (val) { 29 | return (val instanceof Date) ? AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(val, this.attr("data-timezone-id")) : val; 30 | }, 31 | "stringArray": function (val) { 32 | if (val instanceof Date) { 33 | return [AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(val, this.attr("data-timezone-id"))]; 34 | } 35 | return val; 36 | }, 37 | "number": function (val) { 38 | return (val instanceof Date) ? val.getTime() : val; 39 | }, 40 | "numberArray": function (val) { 41 | if (val instanceof Date) { 42 | return [val.getTime()]; 43 | } 44 | return val; 45 | }, 46 | "dateArray": function (val) { 47 | if (val instanceof Date) { 48 | return [val]; 49 | } 50 | return val; 51 | } 52 | }, 53 | contextAdjust: function (context) { 54 | if (typeof context.atts.max === "undefined" && context.max instanceof Date) { 55 | context.atts.max = AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(context.max, context.atts.timezoneId); 56 | } 57 | if (typeof context.atts.min === "undefined" && context.min instanceof Date) { 58 | context.atts.min = AutoForm.Utility.dateToNormalizedLocalDateAndTimeString(context.min, context.atts.timezoneId); 59 | } 60 | if (context.atts.timezoneId) { 61 | context.atts["data-timezone-id"] = context.atts.timezoneId; 62 | } 63 | delete context.atts.timezoneId; 64 | return context; 65 | } 66 | }); 67 | 68 | const dateTimeLocal = React.createClass({ 69 | render() { 70 | return ( 71 |
72 | 79 |
80 | ) 81 | } 82 | }) 83 | 84 | Template.afInputDateTimeLocal_reactAutoformMaterialUi.helpers({ 85 | dateTimeLocal(){ 86 | return dateTimeLocal; 87 | }, 88 | atts(){ 89 | let atts = new ReactAutoformUtility(this.atts); 90 | atts.value = this.value || moment().toDate(); 91 | return atts; 92 | } 93 | }) 94 | -------------------------------------------------------------------------------- /example/client/components.jsx: -------------------------------------------------------------------------------- 1 | Components = new Mongo.Collection("components"); 2 | 3 | ThemeManager = new mui.Styles.ThemeManager(); 4 | injectTapEventPlugin(); 5 | 6 | Schemas = {}; 7 | 8 | Schemas.ComponentForm = new SimpleSchema({ 9 | Text: { 10 | type: String, 11 | label: "Text Input" 12 | }, 13 | BooleanRadios: { 14 | type: String, 15 | optional: true, 16 | autoform: { 17 | trueLabel:'Custom label!', 18 | type: "boolean-radios" 19 | 20 | } 21 | }, 22 | SelectRadio: { 23 | type: String, 24 | optional: true, 25 | autoform: { 26 | type: "select-radio", 27 | options: function () { 28 | return [ 29 | {label: "2013", value: 2013}, 30 | {label: "2014", value: 2014}, 31 | {label: "2015", value: 2015} 32 | ]; 33 | } 34 | } 35 | }, 36 | Button: { 37 | type: String, 38 | optional: true, 39 | autoform: { 40 | label: "Button", 41 | type: "button" 42 | } 43 | }, 44 | Date: { 45 | type: String, 46 | optional: true, 47 | autoform: { 48 | type: "date" 49 | } 50 | }, 51 | Email: { 52 | type: String, 53 | autoform: { 54 | label: "Email", 55 | type: "email" 56 | } 57 | }, 58 | Number: { 59 | type: String, 60 | optional: true, 61 | autoform: { 62 | type: "number", 63 | afFieldInput: { 64 | label: "Number" 65 | } 66 | } 67 | }, 68 | Password: { 69 | type: String, 70 | optional: false, 71 | autoform: { 72 | type: "password", 73 | afFieldInput: { 74 | 75 | } 76 | } 77 | }, 78 | RadioButton: { 79 | type: String, 80 | optional: true, 81 | autoform: { 82 | type: "radio", 83 | afFieldInput: { 84 | 85 | } 86 | } 87 | }, 88 | Range: { 89 | type: String, 90 | optional: true, 91 | autoform: { 92 | type: "range", 93 | afFieldInput: { 94 | 95 | } 96 | } 97 | }, 98 | Reset: { 99 | type: String, 100 | optional: true, 101 | autoform: { 102 | type: "reset", 103 | afFieldInput: { 104 | 105 | } 106 | } 107 | }, 108 | SelectMultiple: { 109 | type: String, 110 | optional: true, 111 | autoform: { 112 | type: "select-multiple", 113 | options: function () { 114 | return [ 115 | {label: "multiple!", value: 2013}, 116 | {label: "2014", value: 2014}, 117 | {label: "2015", value: 2015} 118 | ]; 119 | } 120 | } 121 | }, 122 | TextArea: { 123 | type: String, 124 | optional: true, 125 | autoform: { 126 | type: "textarea", 127 | afFieldInput: { 128 | 129 | } 130 | } 131 | }, 132 | Time: { 133 | type: String, 134 | optional: true, 135 | autoform: { 136 | type: "time" 137 | } 138 | }, 139 | File: { 140 | type: String, 141 | autoform: { 142 | type:"file" 143 | } 144 | }, 145 | Select: { 146 | type: String, 147 | optional: true, 148 | autoform: { 149 | type: "select", 150 | options: function () { 151 | return [ 152 | {label: "2013", value: 2013}, 153 | {label: "2014", value: 2014}, 154 | {label: "2015", value: 2015} 155 | ]; 156 | } 157 | } 158 | } 159 | }); 160 | 161 | Components.attachSchema(Schemas.ComponentForm); 162 | -------------------------------------------------------------------------------- /package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'poetic:react-autoform-material-ui', 3 | version: '0.2.0', 4 | // Brief, one-line summary of the package. 5 | summary: 'Render your Autoform, using Material-UI components', 6 | // URL to the Git repository containing the source code for this package. 7 | git: 'https://github.com/poetic/react-autoform-material-ui', 8 | // By default, Meteor will default to using README.md for documentation. 9 | // To avoid submitting documentation, set this field to null. 10 | documentation: 'README.md' 11 | }); 12 | 13 | Package.onUse(function(api) { 14 | api.versionsFrom('1.3'); 15 | 16 | api.use([ 17 | 'tmeasday:check-npm-versions@0.2.0', 18 | 'ecmascript', 19 | 'react-template-helper@0.1.2', 20 | 'reactive-var', 21 | 'templating@1.1.1', 22 | 'natestrauser:select2@4.0.0_1', 23 | 'underscore@1.0.3', 24 | 'bigdsk:inputmask@3.1.63', 25 | 'aldeed:autoform@5.3.1', 26 | 'aldeed:collection2@2.3.3' 27 | ], 'client'); 28 | api.imply([ 29 | 'bigdsk:inputmask', 30 | ]); 31 | api.export([ 32 | 'rmui' 33 | ], 'client'); 34 | 35 | api.addFiles([ 36 | //Load Lib Files 37 | 'lib/rmui.jsx', 38 | 'lib/utility.jsx', 39 | 40 | //Load components here 41 | 'components/quickform/quickform.html', 42 | 'components/quickform/quickform.jsx', 43 | 'components/afObjectField/afObjectField.html', 44 | 'components/afObjectField/afObjectField.jsx', 45 | 'components/afArrayField/afArrayField.html', 46 | 'components/afArrayField/afArrayField.jsx', 47 | 'components/afFormGroup/afFormGroup.html', 48 | 'components/afFormGroup/afFormGroup.jsx', 49 | 50 | //Load custom input types here 51 | 'inputTypes/boolean-checkbox/boolean-checkbox.html', 52 | 'inputTypes/boolean-checkbox/boolean-checkbox.jsx', 53 | 'inputTypes/boolean-radios/boolean-radios.html', 54 | 'inputTypes/boolean-radios/boolean-radios.jsx', 55 | 'inputTypes/button/button.html', 56 | 'inputTypes/button/button.jsx', 57 | 'inputTypes/checkbox/checkbox.html', 58 | 'inputTypes/checkbox/checkbox.jsx', 59 | 'inputTypes/contenteditable/contenteditable.html', 60 | 'inputTypes/contenteditable/contenteditable.jsx', 61 | 'inputTypes/date/date.html', 62 | 'inputTypes/date/date.jsx', 63 | 'inputTypes/datetime-local/datetime-local.html', 64 | 'inputTypes/datetime-local/datetime-local.jsx', 65 | 'inputTypes/email/email.html', 66 | 'inputTypes/email/email.jsx', 67 | 'inputTypes/file/file.html', 68 | 'inputTypes/file/file.jsx', 69 | 'inputTypes/number/number.html', 70 | 'inputTypes/number/number.jsx', 71 | 'inputTypes/password/password.html', 72 | 'inputTypes/password/password.jsx', 73 | 'inputTypes/radio/radio.html', 74 | 'inputTypes/radio/radio.jsx', 75 | 'inputTypes/range/range.html', 76 | 'inputTypes/range/range.jsx', 77 | 'inputTypes/reset/reset.html', 78 | 'inputTypes/reset/reset.jsx', 79 | 'inputTypes/select/select.html', 80 | 'inputTypes/select/select-stylable.jsx', 81 | 'inputTypes/select/select.jsx', 82 | 'inputTypes/tel/tel.html', 83 | 'inputTypes/tel/tel.jsx', 84 | 'inputTypes/select-radio/select-radio.html', 85 | 'inputTypes/select-radio/select-radio.jsx', 86 | 'inputTypes/text/text.html', 87 | 'inputTypes/text/text.jsx', 88 | 'inputTypes/textarea/textarea.html', 89 | 'inputTypes/textarea/textarea.jsx', 90 | 'inputTypes/submit/submit.html', 91 | 'inputTypes/submit/submit.jsx', 92 | 'inputTypes/time/time.html', 93 | 'inputTypes/time/time-stylable.jsx', 94 | 'inputTypes/time/time.jsx', 95 | 96 | //load stylesheets 97 | 'stylesheets/rmui.css' 98 | ], 'client'); 99 | }); 100 | -------------------------------------------------------------------------------- /example/client/example.jsx: -------------------------------------------------------------------------------- 1 | AutoForm.setDefaultTemplate('reactAutoformMaterialUi'); 2 | 3 | const componentsLink ='/components/#'; 4 | 5 | const { 6 | LeftNav, 7 | AppBar, 8 | RaisedButton, 9 | Menu, 10 | MenuItem, 11 | FontIcon, 12 | Toolbar, 13 | ToolbarGroup, 14 | ToolbarTitle, 15 | MenuDivider 16 | } = mui; 17 | 18 | const AppBarComponent = React.createClass({ 19 | 20 | childContextTypes: { 21 | muiTheme: React.PropTypes.object 22 | }, 23 | 24 | getChildContext() { 25 | return { 26 | muiTheme: mui.Styles.ThemeManager().getCurrentTheme() 27 | }; 28 | }, 29 | _toggle(e){ 30 | e.preventDefault(); 31 | this.refs.leftNav.toggle(); 32 | }, 33 | render() { 34 | return ( 35 |
36 | 42 | 43 | 44 | } 45 | style={{position:'fixed'}} 46 | iconElementLeft={ 48 | } 49 | 50 | onLeftIconButtonTouchTap={this._toggle} 51 | iconElementRight={ 53 | 54 | } /> 55 |
56 | 57 | )} 58 | }); 59 | 60 | const MenuComponent = React.createClass({ 61 | 62 | childContextTypes: { 63 | muiTheme: React.PropTypes.object 64 | }, 65 | 66 | getChildContext() { 67 | return { 68 | muiTheme: mui.Styles.ThemeManager().getCurrentTheme() 69 | }; 70 | }, 71 | 72 | render() { 73 | let menuItems = []; 74 | menuItems.push({ 75 | type: MenuItem.Types.LINK, 76 | payload: '/#overview', 77 | text: 'Overview' 78 | }); 79 | menuItems.push({ 80 | type: MenuItem.Types.SUBHEADER, 81 | text: 'Components' 82 | }); 83 | 84 | for (let comp in Schemas.ComponentForm._schema){ 85 | menuItems.push({ 86 | type: MenuItem.Types.LINK, 87 | payload: '/components/#' + comp, 88 | text: comp 89 | }) 90 | } 91 | return ( 92 |
93 | 94 | 95 |
96 | 97 | )} 98 | }); 99 | 100 | const TabsComponent = React.createClass({ 101 | 102 | childContextTypes: { 103 | muiTheme: React.PropTypes.object 104 | }, 105 | 106 | getChildContext() { 107 | return { 108 | muiTheme: mui.Styles.ThemeManager().getCurrentTheme() 109 | }; 110 | }, 111 | render() { 112 | return ( 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | )} 122 | }); 123 | 124 | Template['menu'].helpers({ 125 | menu: function(){ 126 | return MenuComponent; 127 | } 128 | }); 129 | 130 | Template['components'].helpers({ 131 | components() { 132 | let hash = componentsController.getParams().hash; 133 | location = '/components/#'+hash; 134 | // console.dir(hash); 135 | return Components; 136 | } 137 | 138 | }); 139 | 140 | Template['appBar'].helpers({ 141 | appBar(){ 142 | return AppBarComponent; 143 | } 144 | }) 145 | 146 | Template['appBar'].rendered = function() { 147 | $('#demo_btn').parent().css({ 148 | 'margin-top': '1%', 149 | left: '30%', 150 | 'position': 'relative' 151 | }) 152 | } 153 | 154 | 155 | -------------------------------------------------------------------------------- /inputTypes/select/select.jsx: -------------------------------------------------------------------------------- 1 | import { checkNpmVersions } from 'meteor/tmeasday:check-npm-versions'; 2 | import StylableDropDown from './select-stylable.jsx'; 3 | 4 | checkNpmVersions({ 5 | 'react': '0.14.x', 6 | 'react-dom': '0.14.x', 7 | 'material-ui': '0.13.4', 8 | }, 'poetic:react-autoform-material-ui'); 9 | 10 | const React = require('react'); 11 | const ReactDOM = require('react-dom'); 12 | const { DropDownMenu } = require('material-ui'); 13 | 14 | AutoForm.addInputType("select", { 15 | template: "afSelect_reactAutoformMaterialUi", 16 | valueOut: function () { 17 | return this.val(); 18 | }, 19 | valueConverters: { 20 | "stringArray": function (val) { 21 | if (typeof val === "string") { 22 | val = val.split(","); 23 | return _.map(val, function (item) { 24 | return $.trim(item); 25 | }); 26 | } 27 | return val; 28 | }, 29 | "number": AutoForm.Utility.stringToNumber, 30 | "numberArray": function (val) { 31 | if (typeof val === "string") { 32 | val = val.split(","); 33 | return _.map(val, function (item) { 34 | item = $.trim(item); 35 | return AutoForm.Utility.stringToNumber(item); 36 | }); 37 | } 38 | return val; 39 | }, 40 | "boolean": AutoForm.Utility.stringToBool, 41 | "booleanArray": function (val) { 42 | if (typeof val === "string") { 43 | val = val.split(","); 44 | return _.map(val, function (item) { 45 | item = $.trim(item); 46 | return AutoForm.Utility.stringToBool(item); 47 | }); 48 | } 49 | return val; 50 | }, 51 | "date": AutoForm.Utility.stringToDate, 52 | "dateArray": function (val) { 53 | if (typeof val === "string") { 54 | val = val.split(","); 55 | return _.map(val, function (item) { 56 | item = $.trim(item); 57 | return AutoForm.Utility.stringToDate(item); 58 | }); 59 | } 60 | return val; 61 | } 62 | }, 63 | contextAdjust: function (context) { 64 | //can fix issues with some browsers selecting the firstOption instead of the selected option 65 | context.atts.autocomplete = "off"; 66 | 67 | var itemAtts = _.omit(context.atts, 'firstOption'); 68 | var firstOption = context.atts.firstOption; 69 | 70 | // build items list 71 | context.items = []; 72 | 73 | // If a firstOption was provided, add that to the items list first 74 | if (firstOption !== false) { 75 | context.items.push({ 76 | name: context.name, 77 | label: (typeof firstOption === "string" ? firstOption : "(Select One)"), 78 | value: "", 79 | // _id must be included because it is a special property that 80 | // #each uses to track unique list items when adding and removing them 81 | // See https://github.com/meteor/meteor/issues/2174 82 | // 83 | // Setting this to an empty string caused problems if option with value 84 | // 1 was in the options list because Spacebars evaluates "" to 1 and 85 | // considers that a duplicate. 86 | // See https://github.com/aldeed/meteor-autoform/issues/656 87 | _id: "AUTOFORM_EMPTY_FIRST_OPTION", 88 | selected: false, 89 | atts: itemAtts 90 | }); 91 | } 92 | 93 | // Add all defined options 94 | _.each(context.selectOptions, function(opt) { 95 | if (opt.optgroup) { 96 | var subItems = _.map(opt.options, function(subOpt) { 97 | return { 98 | name: context.name, 99 | label: subOpt.label, 100 | value: subOpt.value, 101 | htmlAtts: _.omit(subOpt, 'label', 'value'), 102 | // _id must be included because it is a special property that 103 | // #each uses to track unique list items when adding and removing them 104 | // See https://github.com/meteor/meteor/issues/2174 105 | // 106 | // The toString() is necessary because otherwise Spacebars evaluates 107 | // any string to 1 if the other values are numbers, and then considers 108 | // that a duplicate. 109 | // See https://github.com/aldeed/meteor-autoform/issues/656 110 | _id: subOpt.value.toString(), 111 | selected: (subOpt.value === context.value), 112 | atts: itemAtts 113 | }; 114 | }); 115 | context.items.push({ 116 | optgroup: opt.optgroup, 117 | items: subItems 118 | }); 119 | } else { 120 | context.items.push({ 121 | name: context.name, 122 | label: opt.label, 123 | value: opt.value, 124 | htmlAtts: _.omit(opt, 'label', 'value'), 125 | // _id must be included because it is a special property that 126 | // #each uses to track unique list items when adding and removing them 127 | // See https://github.com/meteor/meteor/issues/2174 128 | // 129 | // The toString() is necessary because otherwise Spacebars evaluates 130 | // any string to 1 if the other values are numbers, and then considers 131 | // that a duplicate. 132 | // See https://github.com/aldeed/meteor-autoform/issues/656 133 | _id: opt.value.toString(), 134 | selected: (opt.value === context.value), 135 | atts: itemAtts 136 | }); 137 | } 138 | }); 139 | 140 | return context; 141 | } 142 | }); 143 | 144 | class Select extends React.Component { 145 | constructor() { 146 | super(); 147 | this._getValue = _.bind(this._getValue, this); 148 | this._setIndex = _.bind(this._setIndex, this); 149 | this.getDropDown = _.bind(this.getDropDown, this); 150 | this.state = { 151 | selectedIndex: 0, 152 | dropDownMenu: null, 153 | }; 154 | } 155 | 156 | getChildContext() { 157 | const muiTheme = rmui.getComponentThemes(); 158 | return { 159 | muiTheme 160 | }; 161 | } 162 | 163 | _getValue(event, index, obj) { 164 | const domNode = ReactDOM.findDOMNode(this); 165 | $(domNode).val(obj.value) 166 | this._setIndex(index) 167 | } 168 | 169 | _setIndex(selectedIndex){ 170 | this.setState({ 171 | selectedIndex, 172 | }); 173 | } 174 | 175 | componentDidMount(){ 176 | let domNode = ReactDOM.findDOMNode(this); 177 | let selectParent = $(domNode).children()[0] 178 | 179 | $(selectParent).css({ 180 | width: '100%', 181 | height: '100%' 182 | }) 183 | 184 | let selectedIndex = this.props.atts.selectedIndex 185 | let value = this.props.atts.items[selectedIndex] 186 | 187 | this._getValue(null,selectedIndex,value) 188 | 189 | } 190 | 191 | getDropDown() { 192 | const { atts } = this.props; 193 | if (atts.stylable) { 194 | return ( 195 | 204 | ); 205 | } 206 | return ( 207 | 216 | ); 217 | } 218 | 219 | render() { 220 | const materialDropDown = 0; 221 | const stylableDropDown = 1; 222 | 223 | const dropDown = this.getDropDown(); 224 | 225 | return ( 226 |
230 | {dropDown} 231 |
232 | ); 233 | } 234 | }; 235 | 236 | Select.childContextTypes = { 237 | muiTheme: React.PropTypes.object 238 | } 239 | 240 | Template["afSelect_reactAutoformMaterialUi"].helpers({ 241 | atts() { 242 | const atts = new ReactAutoformUtility(this.atts); 243 | atts.disable = this.disable || this.atts.disable; 244 | atts.items = this.items; 245 | atts.selectedIndex = 0; 246 | atts.stylable = this.atts.stylable || false; 247 | atts.stylableOptions = this.atts.stylableOptions || {}; 248 | 249 | if (this.value){ 250 | atts.value = this.value 251 | let self = this 252 | _.each(self.selectOptions,function(item,index){ 253 | if(item.value === self.value ){ 254 | atts.selectedIndex = index 255 | atts.items = self.selectOptions 256 | } 257 | }) 258 | } 259 | return atts; 260 | }, 261 | Select() { 262 | return Select; 263 | } 264 | }) 265 | --------------------------------------------------------------------------------