I have a little problem.
this code is used as password validator.
classlist.add create checked icon when regexp return true.
How can I add a new class for all, when all regexp are true ?
Sorry for my English and thks for your help.
elf.controlPassword = function (event) {
const lenthNoSpace = new RegExp(/^(\S{8,20})$/);
const hasNumber = new RegExp(/\d+/);
const hasUpperCaseLowerCase = new RegExp(/(?=.*[A-Z])(?=.*[a-z])/);
const hasSpecialChar = new RegExp(/[^A-Za-z0-9\s]/);
const value = event.target.value;
toggleCheck(value, lenthNoSpace, validLenth);
toggleCheck(value, hasNumber, validNumber);
toggleCheck(value, hasUpperCaseLowerCase, validCase);
toggleCheck(value, hasSpecialChar, validSpecialChar);
}
const toggleCheck = function (value, regex, display) {
if (regex.test(value) === true) {
display.classList.remove('icon-dot');
display.classList.add('coucoutest');
return 1;
}
else
{
display.classList.remove('coucoutest');
display.classList.add('icon-dot');
return 0;
}
};
You can put the results of all the toggleCheck calls into an array, then check that all values are 1:
const results = [
toggleCheck(value, lenthNoSpace, validLenth),
toggleCheck(value, hasNumber, validNumber),
toggleCheck(value, hasUpperCaseLowerCase, validCase),
toggleCheck(value, hasSpecialChar, validSpecialChar),
];
if (results.every(r => r === 1)) {
for (const display of [validLenth, validNumber, validCase, validSpecialChar]) {
display.classList.add('somethingWhenAllRegexPass');
}
}
I'd also recommend
Using proper spelling to avoid bugs - you probably want length instead of lenth
Use more precise variable names - it sounds like validNumber and validCase, for example, are elements, which is not clear from their name
Related
I'm creating a NoteEditor, using react. I have 2 textarea in my popup, and when i'm trying to add my array of strings into object, i have a mistake, that my variable, which is contains this arrayOfStrings returns 'undefined', when i'm clicking the button add note.
There is my function onDescriptionChange, i take the e.target.value from my textarea and add to variable arrayOfStrings, where split this string into array with words:
let onDescriptionChange = (e) => {
setTextAreaHeight(e, '100px');
let stringToSplit = e.target.value;
let arrayOfStrings = stringToSplit.split(' ');
return arrayOfStrings;
};
There is a function addArrayToNote, where I'm trying to add this arrayOfStrings into description:
let addArrayToNote = (arrayOfStrings) => {
setNote({
...note,
description: arrayOfStrings,
});
addNote();
};
I will be very grateful if you help...
I believe you want to invoke the method addArrayToNote after generating the arrayOfStrings.
let onDescriptionChange = (e) => {
setTextAreaHeight(e, '100px');
let stringToSplit = e.target.value;
let arrayOfStrings = stringToSplit.split(' ');
// return arrayOfStrings; instead of returning the value
addArrayToNote(arrayOfStrings) // invoke the addArrayToNote with the strings.
};
let addArrayToNote = (arrayOfStrings) => {
setNote({
...note,
description: arrayOfStrings,
});
addNote();
};
I hope this helps.
I implement WYSIWYG editor with draftjs and I have a set of rules for typography fixing. I use Modifier.replaceText to replace what I want, but the problem is, when I call it, it removes inlineStyles in replaced text.
Here is a block of code that I use for typography. Inputs are rules (array with rules) and editorState.
rules.forEach(({ toReplace, replace }) => {
const blockToReplace = [];
let contentState = editorState.getCurrentContent();
const blockMap = contentState.getBlockMap();
blockMap.forEach(contentBlock => {
const text = contentBlock.getText();
let matchArr;
while ((matchArr = toReplace.exec(text)) !== null) {
const start = matchArr.index;
const end = start + matchArr[0].length;
const blockKey = contentBlock.getKey();
const blockSelection = SelectionState.createEmpty(blockKey).merge({
anchorOffset: start,
focusOffset: end,
});
blockToReplace.push(blockSelection);
}
});
blockToReplace.reverse().forEach((selectionState) => {
contentState = Modifier.replaceText(
contentState,
selectionState,
text.replace(search, replace)
);
});
editorState = EditorState.push(editorState, contentState);
});
So, my input is: *bold...*
The wrong output is: *bold*…
Should be: *bold…*
Note: asterisks are for bold designation, change is three dots to horizontal ellipsis (U+2026)
Anybody any idea? I google it for two days and nothing...
I am in almost desperate need of help. I am a mechanical engineer and I'm doing a type of calculator for my line of work. I have had an issue I've spent weeks on. I can't seem to solve it.
To not bore you with long code I will try to generalise it as much as possible.
I will first present an example code.
Then I will explain the expected behaviour and what is actually happening for me.
Finally I will explain what I have tried so far to solve this issue.
I will add more content at the bottom based on comments to help clarify my question.
CODE EXAMPLE
THE PARENT OBJECT
import {childObject} from "./childObject"
// in my code "childObject" are actually different from each other
const object1 = Object.assign({}, childObject);
const object2 = Object.assign({}, childObject);
const object3 = Object.assign({}, childObject);
const object4 = Object.assign({}, childObject);
const object5 = Object.assign({}, childObject);
const object6 = Object.assign({}, childObject);
const exampleObject = {
name: "foo",
otherInfo: "bar",
nestedObject:{
standardType: [object1, object2, object3],
specialType: [object4, object5, object6]
},
sumfunc(){}
}
THE CHILD OBJECT
export const childObject = {
name: "I'm losing my mind",
value: "" //<-- this will change
otherInfo: "please help me",
sumfunc(){}
}
EXPLAINING
What I am doing is the following:
Searchbar with all types of parentObjects.
Allowing user to select one or multiple of same or different parentObjects.
Storing the copied selection in a redux store.
Displaying the selection, each parentObject as a form. [see picture]
When typing in form the value of the nested object will change
Now... The issue is when I open the searchbar and select the same parentObject, thus copying it, all its values are mutated. As seen in picture above.
WHAT I HAVE TRIED
I have tried to use lodash clone and deepClone on the selected parentObject.
I have tried to use loads clone and deepClone on the selected childObjects.
I have tried, since the object have the same structure, to go through all key value pairs and shallow copy them.
I have tried to not send the parentObject via the searchbar component to the reducer, instead I just send a string and the reducer itself will add the parentObject to the store.
All methods that I've tried have not stopped the mutation. The deepClone method stopped the mutations, but in return the functions in the objects stopped working (maybe I need to bind it somehow?)
MORE CONTENT
The code that updates the value of the nestedObject
const inputsHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
const formCopy = Object.assign({}, formEQ);
const inputFieldName = e.target.name;
// if anything other than a empty, number or decimal inputted, then return
const isNum = e.target.value.match(/^(?:\d{1,8}(?:\.\d{0,8})?)?$/);
if (!isNum) return;
// Update priority list to calculate the last updated input
formCopy.priorityList = formCopy.priorityList.sort((a, b) => {
if (a === inputFieldName) return 1;
if (b === inputFieldName) return -1;
else return 0;
});
// Update selected input field
formCopy.inputs[calcmode] = formCopy.inputs[calcmode].map((input) => {
if (input.name === inputFieldName) {
input.value = e.target.value;
}
return input;
});
// If more than two inputs empty do not calculate
const emptyInputs = formCopy.inputs[calcmode].reduce(
(acc, nV) => (nV.value === "" ? (acc += 1) : acc),
0
);
// Calculate the last edited input field
formCopy.inputs[calcmode] = formCopy.inputs[calcmode].map((input) => {
if (input.name === formCopy.priorityList[0] && emptyInputs <= 1) {
const calculatedValue = formCopy.calculate(
formCopy.priorityList[0],
calcmode
);
input.value = Number(calculatedValue).toFixed(2);
}
return input;
});
// Final set hook, now with calculated value
setformEQ({ ...formCopy });
};
Please good people of StackOverFlow... Help me!
Your code has few problems :
you are filtering based on name property of child object and all of them has the same name. Always provide unique id to the objects so that they can be differentiated in easy manner.
Your filter logic is so wrong :
formCopy.inputs[calcmode] = formCopy.inputs[calcmode].map((input) => {
if (input.name === inputFieldName) {
input.value = e.target.value; // < -- Culprit
}
return input;
});
Never mutate inline, always create a new copy.
This is how your code change function should be (I have removed dynamic key selection for clarity) :
const change = (e, id) => {
const inputFieldName = e.target.name;
// local copy of array
const nestedArr = [...qform.nestedObject.standardType];
// finding item to be updated
const index = nestedArr.findIndex((i) => i.id === id);
console.log({ index, inputFieldName, e, id });
if (index !== -1) {
const item = nestedArr[index];
item.value = e.target.value;
nestedArr[index] = item;
// deep copy till k depth where k is the key to be updated
const newObject = {
...qform,
nestedObject: {
...qform.nestedObject,
standardType: [...nestedArr],
},
};
setQform(newObject);
}}
Check this Example : Demo
I am working on a React project where i need a multidimensional constant using useState which stores +/- symbols on some condition.
const [button, setButton] = useState([["+"]]);
and i have the condition something like:
const handleAddFields = (data_index, index, e) => {
console.log("aaaaa!!!", data_index)
console.log("bbbbb!!!",index)
if (button[data_index][index] === "+") {
const btn = [...button]
btn[data_index][index] = "-"
btn[data_index].push(["+"])
setButton(btn)
const btnColour = [...btnClass]
btnColour[index] = "danger"
btnColour.push("primary")
setBtnClass(btnColour)
} else {
const btn = [...button]
btn.splice(index, 1);
setButton(btn)
const btnColour = [...btnClass]
btnColour.splice(index, 1);
setBtnClass(btnColour)
const values = [...inputFields];
values.splice(index, 1);
setInputFields(values);
}
};
i am getting an error as
Cannot assign to read only property '0' of string '+'
at
btn[data_index][index] = "-"
this line
The Place where the function handleAddFields is called is a button
<Button name="btn" id="button" type="button" color={btnClass[data_index][index]} block onClick={(e) => handleAddFields(data_index, index, e)}>{button[data_index][index]}</Button>
I think React does not allow assigning value to multidimensional array. What could be the possible solution to this?
Looks like your input is empty, try to assigning it some value
useEffect(() => {
setShowProducts(true);
if (_cloneArray(currentProducts) > 0) {
sortByPrice();
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const defaultProducts = () => {
let sortedProducts = _cloneArray(currentProducts);
return sortedProducts;
}
const sortByPrice = (e) => {
let sortValue = e.value;
let sortedProducts = _cloneArray(currentProducts);
if (sortValue === "lowest") {
sortedProducts = _sortArray(sortedProducts, "locationPrice");
} else if (sortValue === "highest") {
sortedProducts = _sortArray(sortedProducts, "locationPrice", "desc");
} else if (sortValue === "default") {
sortedProducts = defaultProducts();
}
setCurrentProducts(sortedProducts);
}
return (
<Menu menuButton={<MenuButton><CgSortAz size={20}/></MenuButton>} onClick={sortByPrice}>
<MenuItem value="default">Default</MenuItem>
<MenuItem value="lowest">Price: Low to High</MenuItem>
<MenuItem value="highest">Price: High to Low</MenuItem>
</Menu>
)
So here I've created the sort items feature in ascending and descending order and I want to return to default state, which is not working after so many trials. Please I need some help here
The issue is that once you sort an array and you override your variable there is no way to tell what the original order was.
const numbers = [9,1,8,2,7,3,6,4,5];
numbers.sort((a, b) => a - b);
console.log(numbers); // [1,2,3,4,5,6,7,8,9]
There is no way to turn back [1,2,3,4,5,6,7,8,9] into the initial value, because there is no info stored about the initial value.
To solve this we should keep the original array around.
const numbers = [9,1,8,2,7,3,6,4,5];
// `sort()` mutates the array, so we have to make a copy first
// to prevent `numbers` from changing
let sorted = Array.from(numbers).sort((a, b) => a - b);
console.log(sorted); // [1,2,3,4,5,6,7,8,9]
Now if we want to restore the original order we can simply do:
sorted = numbers;
// or create a copy `Array.from(numbers)` if you intent to mutate `sorted`
The same applies for React. A common way to solve this would be to have 2 states. One containing the initial/default array, the second containing the sorted variant.
const [currentProducts, setCurrentProducts] = useState(...);
const [sortedProducts, setSortedProducts] = useState(currentProducts);
When sorting, store the result as sortedProducts. If you want to reset sortedProducts simply assign it to currentProducts.
const sortByPrice = (e) => {
let sortValue = e.value;
let products = _cloneArray(sortedProducts);
if (sortValue === "lowest") {
products = _sortArray(products, "locationPrice");
} else if (sortValue === "highest") {
products = _sortArray(products, "locationPrice", "desc");
} else if (sortValue === "default") {
products = currentProducts;
}
setSortedProducts(products);
}
Note that you should use sortedProducts in your view instead of currentProducts.
Since we never update currentProducts there is no real reason for it to be a state. This could just be a constant or a property (wherever the values comes from). If the values comes from an external API (or something async) it makes sense to keep currentProducts as an state, because it has to be set once fetched.
Here is an example that keeps the original order NUMBERS around and stores the sorted variant in a separate state sorted:
const NUMBERS = [9,1,8,2,7,3,6,4,5];
function Numbers() {
const [sorted, setSorted] = React.useState(NUMBERS);
const sort = (e) => {
switch (e.target.value) {
case "asc":
setSorted(Array.from(NUMBERS).sort((a, b) => a - b));
break;
case "desc":
setSorted(Array.from(NUMBERS).sort((a, b) => b - a));
break;
case "default":
setSorted(NUMBERS);
break;
}
};
return <React.Fragment>
<div className="sort-actions">
<button onClick={sort} value="asc">asc</button>
<button onClick={sort} value="desc">desc</button>
<button onClick={sort} value="default">default</button>
</div>
<p>{JSON.stringify(sorted)}</p>
</React.Fragment>;
}
ReactDOM.render(<Numbers />, document.querySelector("#numbers"));
<script src="https://unpkg.com/react#17/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom#17/umd/react-dom.production.min.js"></script>
<div id="numbers"></div>