React - Can't change DOM's Style with JavaScript - javascript

I want to dynamically change my DOM's height. But I can't. No errors, console.log prints nothing, just blank with a number indicating how many times this blank line is printed on console. ref works but it seems that whatever I write to the ref won't be updated to the DOM.
On each keypress, my resizeTextInput function is invoked.
constructor(props) {
super(props);
this.state = {
textLen: 0,
commentError: false,
};
this.textInputRef = React.createRef();
this.commentBlockRef = React.createRef();
this.resizeTextInput = this.resizeTextInput.bind(this);
this.handleSearch = this.postComment.bind(this);
this.postComment = this.postComment.bind(this);
}
resizeTextInput() {
this.commentBlockRef.current.style.height = 300;
console.log(this.commentBlockRef.current.style.height);
}
postComment(event) {
this.resizeTextInput();
}
render() {
return (
<div className="comment-wrap">
<div className={`comment-block ${className}`} ref={this.commentBlockRef}>
<textarea className={`textarea-${className}`} type="text" placeholder="Write a comment..." onKeyUp={this.postComment} ref={this.textInputRef} size="55" />
<div className={`comment-block-len ${(commentError || postError) ? 'comment-error' : ''}`}>{textLen}/{MAX_LEN}</div>
</div>
</div>
);
}
}

It should be 300px in string instead 300 only.
this.commentBlockRef.current.style.height = '300px';

Related

Outside click of input field not working in react

I am trying to hide the field when user click on outside the input field and show the field when user click on input field. I have seen some example on stackoverflow where they said to use e.stopPropagation() I did it but still in my case its not working. I don't know whats I am doing wrong.
Here is my code.
class TodoApp extends React.Component {
constructor(props) {
super(props)
this.pasteRef = React.createRef();
this.state = {
showPastePopup: false,
fname: ''
}
}
onPasteClick = () =>{
this.setState({
showPastePopup: false
})
}
closePastePopup = e => {
console.log("called")
this.setState({
showPastePopup:false
})
}
showPastePopup = e => {
e.stopPropagation();
let posx = e.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
let posy = e.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
this.pasteRef.current.style.left = posx + "px";
this.pasteRef.current.style.top = posy + "px";
this.setState({
showPastePopup: true,
})
}
render() {
return (
<div>
<h2>Todos: Some text will be here.........</h2>
<span id="pasteBox" ref={this.pasteRef} onClick={this.onPasteClick} className={this.state.showPastePopup ? "showCopyBox control" : "hideCopyBox control"}>
paste
</span>
<div id="pasteArea" className="col w-50 border border-success " onClick={this.closePastePopup}>
<div className="mt-1">
First Name: <input onMouseUp={this.showPastePopup} value={this.state.fname || ''} type="text" id="fname" name="fname" /> {this.state.fname}
</div>
<br/>
<div className="mt-1">
Last Name: <input onMouseUp={this.showPastePopup} value='' type="text" id="lname" name="lname" />
</div>
<br/>
<div className="mt-1">
Address: <input onMouseUp={this.showPastePopup} value='' type="text" id="add" name="add" />
</div>
</div>
</div>
)
}
}
ReactDOM.render(<TodoApp />, document.querySelector("#app"))
If I comment on closePastePopup() then its show the popup but how can close the popup if user click outside of the input tag?
Any help will be appreciated.
Here is my jsfiddke
The problem is that you are using the different types of events, if you write onClick or onMouseUp for both elements, it works.
The stopPropagation method stops only the current event.
You didn't pass e to methods and didn't bind them in constructor.
Constructor should look like this:
constructor(props) {
super(props)
this.pasteRef = React.createRef();
this.state = {
showPastePopup: false,
fname: ''
}
this.onPasteClick = this.onPasteClick.bind(this);
this.closePastePopup = this.closePastePopup.bind(this);
this.showPastePopup = this.showPastePopup.bind(this);
}
And when you invoke methods:
<input onMouseUp={e => this.showPastePopup(e)} value='' type="text" id="add" name="add" />

If I use defaultChecked, sorting table columns does not change the position of the checkbox

If I use "defaultChecked", sorting table columns does not change the position of the checkbox.
If use "checked", I can change position but checkbox doesn't work correctly.
How can I fix it?
Here is the code: https://jsfiddle.net/sakanyan/e2a56mbk/29/
enter code here
<input type="checkbox" checked={item.hasItem} /*OR
defaultChecked={item.hasItem} */ />
Missing something like this:
constructor(props) {
//....
this.onCheck = this.onCheck.bind(this);
}
//...
onCheck(event) {
let s = Object.assign({}, this.state);
let d = s.data.find( s => s.id == e.target.name );
if( !d ) return;
d.hasItem = !d.hasItem;
this.setState(s);
}
render() {
//...
<input name = {item.id} type='checkbox' checked={item.hasItems} onChange={this.onCheck} />
//...
}
Previously, you're checkbox were never updated (in state) so the sort appears to be wrong.
Try this,
constructor(props) {
super(props)
state = {
hasItems = false;
}
}
handleCheck = event => {
this.setState({hasItems : !this.state.hasItems })
}
render(){
return(
//....
<input
type="checkbox"
checked={this.state.hasItem}
onChange={this.handleCheck}
>
//....
)
}

html5 input type range always pointing to min value and not getting onChange on text input

I am trying to use input type text along with input type range where three usecases are there.
1. defaultcase: when page is loaded the slider should point to the value as given in the text input field.
2. when user enters the text value, the slider pointer should also update.
3. when user uses the slider to change value, the text value should get updated.
In my below code
In default case: in input type range when i give defaultValue="200" the slider pointer points always to min value.
When i enter value in text area, the slider is not getting updated.
i tried some ways to fix it but failing.
if (
Type == "integer" &&
LowerBound &&
UpperBound !== 0
) {
editComponent = (
<div className="SettingsTreeValueNode__InputField">
<input
type="text"
pattern="[0-9]*"
ref="text"
value={this.state.value}
oninput={this.handleinputChanged.bind(this)}
className="inputtext"
onBlur={e => this.focusOfInputLost(e)}
/>
{LowerBound}
<input
type="range"
className="sliderinput"
defaultValue="200"
min={LowerBound}
max={UpperBound}
step="1"
oninput={this.handleSliderChange.bind(this)}
onMouseUp={this.handleWhenMouseReleased.bind(this)}
/>
{UpperBound}
</div>
);
}
handleSliderChange(event) {
var value = event.target.value;
var slidervalue = parseInt(value);
this.setState({ value: slidervalue });
}
handleInputChanged(event) {
var value = event.target.validity.valid
? event.target.value
: this.state.value;
this.setState(
{
value: value,
inputValid: this.isInputValid()
});
}
ยดยดยด[![slider along with text area][1]][1]
[1]: https://i.stack.imgur.com/w5MZ6.png
Below code will solve your problems, only use single state object to display value in both controls now it will works in both way either change value on input or slider.
class App extends Component {
constructor(props) {
super(props);
this.state = {
value: ""
};
}
handleSliderChange = (event) => {
var value = event.target.value;
var slidervalue = parseInt(value);
this.setState({ value: slidervalue });
}
handleInputChanged = (event) => {
var value = event.target.validity.valid
? event.target.value
: this.state.value;
this.setState(
{
value: value
});
}
render() {
let LowerBound = 0;
let UpperBound = 200
return (
<div>
<button onClick={this.handleCopy}>click me</button>
<div className="SettingsTreeValueNode__InputField">
<input
type="text"
pattern="[0-9]*"
ref="text"
value={this.state.value}
onInput={this.handleInputChanged}
className="inputtext"
/>
{LowerBound}
<input
type="range"
className="sliderinput"
defaultValue="200"
min="0"
max="200"
step="1"
value={this.state.value ? this.state.value : UpperBound}
onInput={this.handleSliderChange}
/>
{UpperBound}
</div>
</div>
);
}
}
export default App;

Component didn't re-renders on state change?

I am creating a random quote generator. There is a quote box that displays quote and author names. I created a method to invoke on a button click that may randomize the quote list and display a new quote and a next button to get next quote from my quote list. I can see the first quote but the component didn't re-renders on clicking buttons or something gets wrong that I can't get next quote or can't randomize. Here is the code:
class UI_qoutebox extends React.Component {
constructor(props) {
super(props);
this.state = { qoutes: props.qoutes, authors: props.authors, num: 0 };
this.UI_rq = this.UI_rq.bind(this);
this.UI_next = this.UI_next.bind(this);
}
UI_rq() {
let rnd = Math.floor(Math.random() * this.state.qoutes.length);
this.setState({ num: rnd });
}
UI_next() {
let p = this.state.num + 1;
if (p > this.state.qoutes.length) { p = 0 }
this.setState({ num: p })
}
render() {
const { qoutes, authors, num } = this.state;
return (
<div className="qoute-box">
<span className="qoute">{qoutes[num]}</span>
<span>{authors[num]}</span>
<input type="button" value="Randomize" onClick={() => this.UI_rq} />
<input type="button" value="Next" onClick={() => this.UI_next} />
</div>
)
}
}
I am working on Freecodecamp's project and I need quick help. Thanks in advance.
Change this
<input type="button" value="Randomize" onClick={this.UI_rq}/>
<input type="button" value="Next" onClick={this.UI_next}/>

uncheck checkbox programmatically in reactjs

I am messing with checkboxes and I want to know that is there a way in which I can uncheck a checkbox on click of a button by calling a function?? If so? How can I do that?
<input type="checkbox" className="checkbox"/>
<button onClick={()=>this.unCheck()}
How can I uncheck the checkbox programmatically and what if I have multiple checkboxes generated dynamically using map function.
How can I uncheck them If I want to?
There is property of checkbox checked you can use that to toggle the status of check box.
Possible Ways:
1- You can use ref with check boxes, and onClick of button, by using ref you can unCheck the box.
2- You can use controlled element, means store the status of check box inside a state variable and update that when button clicked.
Check this example by using ref, assign a unique ref to each check box then pass the index of that item inside onClick function, use that index to toggle specific checkBox:
class App extends React.Component{
constructor(){
super();
this.state = {value: ''}
}
unCheck(i){
let ref = 'ref_' + i;
this.refs[ref].checked = !this.refs[ref].checked;
}
render(){
return (
<div>
{[1,2,3,4,5].map((item,i) => {
return (
<div>
<input type="checkbox" checked={true} ref={'ref_' + i}/>
<button onClick={()=>this.unCheck(i)}>Toggle</button>
</div>
)
})}
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
Check this example of controlled element, means storing the state of checkbox inside state variable, and on click of button change the value of that:
class App extends React.Component{
constructor(){
super();
this.state = {value: []}
}
onChange(e, i){
let value = this.state.value.slice();
value[i] = e.target.checked;
this.setState({value})
}
unCheck(i){
let value = this.state.value.slice();
value[i] = !value[i];
this.setState({value})
}
render(){
return (
<div>
{[1,2,3,4,5].map((item,i) => {
return (
<div>
<input checked={this.state.value[i]} type="checkbox" onChange={(e) => this.onChange(e, i)}/>
<button onClick={()=>this.unCheck(i)}>Toggle</button>
</div>
)
})}
</div>
)
}
}
ReactDOM.render(<App/>, document.getElementById('app'))
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='app'/>
React
Checked
Using State
<input type="radio" name="count" value="minus" onChange={this.handleRadioChange} checked={this.state.operation == "minus"} /> Decrement
2.Using Refs
<input type="radio" name="count" ref="minus" /> Decrement
onSubmit(e){ this.refs.minus.checked = false }
Using plain javascript you can acheive like below.
function unCheck() {
var x = document.getElementsByClassName("checkbox");
for(i=0; i<=x.length; i++) {
x[i].checked = false;
}
}
Small DEMO
I was thinking of a thing like that:
<input onChange={(input) => this.onFilterChange(input)} className="form-check-input" type="checkbox" />
onFilterChange = (input) => { let { value, checked } = input.target;}
unCkeckAll = () => {
[...document.querySelectorAll('.form-check-input')].map((input) => {
if (input.checked) {
let fakeInput = {
target: {
value: input.value,
checked: false
}
}
input.checked = !input.checked;
this.onFilterChange(fakeInput);
}
return null;
})
}
Checkboxes have a checked property, you can hook it to the state and change it dynamically. Check these links:
https://facebook.github.io/react/docs/forms.html#handling-multiple-inputs
http://react.tips/checkboxes-in-react/
Sometime its good to use plain javascript. If you have of checkbox value in any of your state then try this
let checkboxValue = xyz
document.querySelectorAll("input[value="+checkboxValue+"]")[0].checked = false;

Categories

Resources