You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
153 lines
4.6 KiB
153 lines
4.6 KiB
10 years ago
|
/**
|
||
|
* Copyright 2013-2015, Facebook, Inc.
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* This source code is licensed under the BSD-style license found in the
|
||
|
* LICENSE file in the root directory of this source tree. An additional grant
|
||
|
* of patent rights can be found in the PATENTS file in the same directory.
|
||
|
*
|
||
|
* @providesModule LinkedValueUtils
|
||
|
* @typechecks static-only
|
||
|
*/
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
var ReactPropTypes = require("./ReactPropTypes");
|
||
|
|
||
|
var invariant = require("./invariant");
|
||
|
|
||
|
var hasReadOnlyValue = {
|
||
|
'button': true,
|
||
|
'checkbox': true,
|
||
|
'image': true,
|
||
|
'hidden': true,
|
||
|
'radio': true,
|
||
|
'reset': true,
|
||
|
'submit': true
|
||
|
};
|
||
|
|
||
|
function _assertSingleLink(input) {
|
||
|
("production" !== process.env.NODE_ENV ? invariant(
|
||
|
input.props.checkedLink == null || input.props.valueLink == null,
|
||
|
'Cannot provide a checkedLink and a valueLink. If you want to use ' +
|
||
|
'checkedLink, you probably don\'t want to use valueLink and vice versa.'
|
||
|
) : invariant(input.props.checkedLink == null || input.props.valueLink == null));
|
||
|
}
|
||
|
function _assertValueLink(input) {
|
||
|
_assertSingleLink(input);
|
||
|
("production" !== process.env.NODE_ENV ? invariant(
|
||
|
input.props.value == null && input.props.onChange == null,
|
||
|
'Cannot provide a valueLink and a value or onChange event. If you want ' +
|
||
|
'to use value or onChange, you probably don\'t want to use valueLink.'
|
||
|
) : invariant(input.props.value == null && input.props.onChange == null));
|
||
|
}
|
||
|
|
||
|
function _assertCheckedLink(input) {
|
||
|
_assertSingleLink(input);
|
||
|
("production" !== process.env.NODE_ENV ? invariant(
|
||
|
input.props.checked == null && input.props.onChange == null,
|
||
|
'Cannot provide a checkedLink and a checked property or onChange event. ' +
|
||
|
'If you want to use checked or onChange, you probably don\'t want to ' +
|
||
|
'use checkedLink'
|
||
|
) : invariant(input.props.checked == null && input.props.onChange == null));
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {SyntheticEvent} e change event to handle
|
||
|
*/
|
||
|
function _handleLinkedValueChange(e) {
|
||
|
/*jshint validthis:true */
|
||
|
this.props.valueLink.requestChange(e.target.value);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param {SyntheticEvent} e change event to handle
|
||
|
*/
|
||
|
function _handleLinkedCheckChange(e) {
|
||
|
/*jshint validthis:true */
|
||
|
this.props.checkedLink.requestChange(e.target.checked);
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Provide a linked `value` attribute for controlled forms. You should not use
|
||
|
* this outside of the ReactDOM controlled form components.
|
||
|
*/
|
||
|
var LinkedValueUtils = {
|
||
|
Mixin: {
|
||
|
propTypes: {
|
||
|
value: function(props, propName, componentName) {
|
||
|
if (!props[propName] ||
|
||
|
hasReadOnlyValue[props.type] ||
|
||
|
props.onChange ||
|
||
|
props.readOnly ||
|
||
|
props.disabled) {
|
||
|
return null;
|
||
|
}
|
||
|
return new Error(
|
||
|
'You provided a `value` prop to a form field without an ' +
|
||
|
'`onChange` handler. This will render a read-only field. If ' +
|
||
|
'the field should be mutable use `defaultValue`. Otherwise, ' +
|
||
|
'set either `onChange` or `readOnly`.'
|
||
|
);
|
||
|
},
|
||
|
checked: function(props, propName, componentName) {
|
||
|
if (!props[propName] ||
|
||
|
props.onChange ||
|
||
|
props.readOnly ||
|
||
|
props.disabled) {
|
||
|
return null;
|
||
|
}
|
||
|
return new Error(
|
||
|
'You provided a `checked` prop to a form field without an ' +
|
||
|
'`onChange` handler. This will render a read-only field. If ' +
|
||
|
'the field should be mutable use `defaultChecked`. Otherwise, ' +
|
||
|
'set either `onChange` or `readOnly`.'
|
||
|
);
|
||
|
},
|
||
|
onChange: ReactPropTypes.func
|
||
|
}
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @param {ReactComponent} input Form component
|
||
|
* @return {*} current value of the input either from value prop or link.
|
||
|
*/
|
||
|
getValue: function(input) {
|
||
|
if (input.props.valueLink) {
|
||
|
_assertValueLink(input);
|
||
|
return input.props.valueLink.value;
|
||
|
}
|
||
|
return input.props.value;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @param {ReactComponent} input Form component
|
||
|
* @return {*} current checked status of the input either from checked prop
|
||
|
* or link.
|
||
|
*/
|
||
|
getChecked: function(input) {
|
||
|
if (input.props.checkedLink) {
|
||
|
_assertCheckedLink(input);
|
||
|
return input.props.checkedLink.value;
|
||
|
}
|
||
|
return input.props.checked;
|
||
|
},
|
||
|
|
||
|
/**
|
||
|
* @param {ReactComponent} input Form component
|
||
|
* @return {function} change callback either from onChange prop or link.
|
||
|
*/
|
||
|
getOnChange: function(input) {
|
||
|
if (input.props.valueLink) {
|
||
|
_assertValueLink(input);
|
||
|
return _handleLinkedValueChange;
|
||
|
} else if (input.props.checkedLink) {
|
||
|
_assertCheckedLink(input);
|
||
|
return _handleLinkedCheckChange;
|
||
|
}
|
||
|
return input.props.onChange;
|
||
|
}
|
||
|
};
|
||
|
|
||
|
module.exports = LinkedValueUtils;
|