在本质上是一个采访帮助界面上工作,该界面使访问者可以看到问题,向受访者询问问题,设置答案,然后转到下一个问题。
问题在于,实际答案(以数字形式存储)的字段需要使用箭头键进行导航,并且并非所有问题都具有有效答案的简单范围;有时,您可以从1-3、6-9和10、11和12中选择。它表示为“ 1-3,6-9,11,12,13”。 1,2,3和6,7,8,9和11,12,13都是有效选项。 4,5和10不是。 使用箭头键时,产品负责人要求跳过无效的选择。因此,将其从3直接提高到6。
我既没有使用React也没有Redux的经验,所以我不确定该选项在哪里,并且一直在尝试简单地更改该字段的onChange事件触发器。
基本上,它看起来像这样:
<input
type={input}
className={`interview-input interview-input-${input}`}
id="ResponseInput"
name="response"
onChange={event => {
console.log("Prev. value is "+previousValue)
if (
item.validate &&
validateNumeric(event.target.value, item.validate)
) {
dispatch(
setResponse({
key: item.key,
value: event.target.value
})
);
} else if (item.validate &&
isValueWithinWholeRangeOfRules(event.target.value, item.validate)
) {
dispatch(
setResponse({
key: item.key,
value: selectValueDifferentFromOldValue(
findClosestViableValueFromInvalidValue(event.target.value,item.validate),
previousValue
)
})
);
} else if (!item.validate) {
dispatch(
setResponse({
key: item.key,
value: event.target.value
})
);
}
}}
placeholder={item.validate}
value={response}
autoFocus
/>
我想做的是创建一个函数,该函数有助于检测有效值是否至少在最大和最小可能值(isValueWithinWholeRangeOfRules(x,y))的范围内,以便我可以使用( findClosestViableValueFromInvalidValue(x,y))查找2个有效的最近值(例如3和6),然后使用(selectValueDifferentFromOldValue(x,y))进行逻辑运算。 所有帮助程序功能都在这里:
export const isTextareaInFocus = () =>
document.activeElement.tagName === 'TEXTAREA';
// the value provided can be a string or a number
// rules look like [0-10, 98, 99]
export const validateNumeric = (value, rules) => {
let valid = false;
// allow empty input
if (value === '') return true;
rules.forEach(rule => {
// if the validator contains an interval string (like "0-10") we parse the
// numbers and check if the value is included in the interval
if (typeof rule === 'string' && rule.includes('-')) {
var range = rule.split('-').map(n => parseInt(n, 10));
if (value >= range[0] && value <= range[1]) {
valid = true;
}
} else if (typeof rule === 'string') {
if (rule === value.toString()) {
valid = true;
}
} else if (typeof rule === 'number' &&
(rule === parseInt(value, 10) || rule.toString().includes(value))
) {
// if the rule is a number we check it against the value provided
valid = true;
}
});
return valid;
};
//TODO rename func MRJ
//Brute forces a search for available options, then entering a non valid value into input; Based on it's own position, it will go high, then low, and then go for the option that it does NOT remember it has been; IE the old value
export const findClosestViableValueFromInvalidValue = (value, rules) =>{
var nearest_high = parseInt(value,10);
var nearest_low = parseInt(value,10);
while(!validateNumeric(nearest_high,rules)) {
nearest_high++;
if (nearest_high>20)
return false;
}
while(!validateNumeric(nearest_low,rules)){
nearest_low--;
if (nearest_low<-2)
return false;
}
return [nearest_low,nearest_high];
};
export const selectValueDifferentFromOldValue = (values, oldValue) =>{
if (oldValue = values[0])
return values[1];
else if (oldValue = values[1])
return values[0];
};
export const isValueWithinWholeRangeOfRules = (value, rules) =>{
var high=0;
var low=100;
rules.forEach(rule => {
// if the validator contains an interval string (like "0-10") we parse the
// numbers and check if the value is included in the interval
if (typeof rule === 'string' && rule.includes('-')) {
var range = rule.split('-').map(n => parseInt(n, 10));
if (low > range[0])
{low = range[0];}
if (high < range[0])
{high = range[0];}
if (low > range[1])
{low = range[1];}
if (high < range[1])
{high = range[1];}
} else if (typeof rule === 'string') {
rule === parseInt(value, 10)
if (low > rule)
{low = rule;}
if (high < rule)
{high = rule;}
} else if (
// if the rule is a number we check it against the value provided
typeof rule === 'number' &&
(rule === parseInt(value, 10) || rule.toString().includes(value))
) {
if (low > rule)
{low = rule;}
if (high < rule)
{high = rule;}
}
});
value = parseInt(value,10);
high = parseInt(high,10);
low = parseInt(low,10);
if (value >= low && value <= high){
return true;
}
else {
return false;
}
};
item.validate本质上只是一个包含验证要求的字符串(想想Regex,就这么简单)。
实际的问题是,当使用selectValueDifferentFromOldValue时,我需要能够以某种方式引用旧值。但是由于这是在输入字段的onChange事件中发生的,因此已经更改。 (这使我的整个调度设置变得很奇怪,但这是另一回事)。我尝试创建一个全局值来也存储该值,但是同样,onChange会在我将其全局保存之前更改该值,这意味着我必须在更改后保存它,但是这样做会使它超出范围,将它移到1,2,3,然后跳到6,但是保存的全局值为4。
如何可靠地从触发onChange事件之前获取旧值,还是应该找到获取期望结果的其他方法(可以在输入上使用箭头键,跳过无效数字)