How I can change a Button into a input text? - javascript

So, I'm trying to create a button that when I click it, it should change into a input with a another button for submit. I'm using react and bootstrap.
<div className="cold-md-2 col-sm-3">
<div className="card-body">
<button class="btn btn-lg btn-block btn-group py-3" type="button">New group
<i class="fas fa-plus"></i></button>
</div>
</div>

You should probably create a state indicating wheter should render a button or an input, then on your render you check wich one you should render.
export default class Test extends PureComponent {
constructor(props) {
super(props);
this.state = {
type: 'button'
};
}
toggleType() {
this.setState({
type: this.state.type === 'button' ? 'input' : 'button'
});
}
render() {
if (this.state.type === 'input')
return <span>In here its the input HTML</span>;
return (
<button onClick={this.toggleType.bind(this)} type="button">Toggle</button>
);
}
}

To change the text of a button that has been declared with <input type="button"> tag: use the button's value property. For example:
<input type="button" value="Button Text" id="myButton">Submit</input>

Related

Same Name to Parent and Child Tag in JSX gives undefined

class Button extends Component
{
changeHandler = (event)=>{
console.log(event.target.name);
}
render() {
return (
<div>
<button type="button" name="text" className="btn btn-primary" onClick={(event)=>this.changeHandler(event)}>
<i className="fas fa-plus" name="text" onClick={(event)=>this.changeHandler(event)}></i>
</button>
</div>
);
}
}
I have given same name to Button(Bootstrap) and icon (using font Awesome) and when I click on icon the console gives the value as undefined, but gives the value of name in case of button click.
The name property only exists for certain DOM elements. <button> has a name property but <i> does not.
https://developer.mozilla.org/en-US/docs/Web/API/Element/name
If you want to get the name attribute for <i>, you'll have to use getAttribute("name").
In your case it would be event.target.getAttribute("name").

Is it possible to pass the onClick function of reactbootstrap table inside of Component using ReactJS

I have a question regarding declaring handler, is it possible to call the onclick function inside of parent component? because the error shows
Cannot read property 'DeleteUser' of undefined.
So outside of extends Component, I have const column and I have formatter function that look like this.
formatter: (cellContent, row) => {
<div class="btn-group" role="group" aria-label="Basic example">
<button className="btn btn-primary
form-control btn-small" data-toggle="modal" data-target="#myModal" value={row.id}><i class="far fa-edit" style={{fontSize:12}}></i></button>
<button className="btn btn-danger
form-control btn-small" onClick={this.DeleteUser} value={row.id}><i class="fas fa-trash-alt" style={{fontSize:12}}></i></button>
</div>
}
Inside my Component, I have this.
constructor(props) {
super(props);
this.state = {
list_user:[],
}
this.DeleteUser = this.DeleteUser.bind(this);
}
DeleteUser() {
alert('george');
}
So now when I refresh my page error shows Undefined DeleteUser.

On a Keydown.enter event in input element within a child component is also calling a method that is defined in Parent Component

I have a parent component where user can select skills from a range of options and a child component where user can add their own skill if its not available on the parent component.
The issue is in child component, when a user enters skill into an input element on which I have an #keydown.enter event defined to call a method, to take the input and push it to an array and that all works. The only problem is when keydown.enter event is fired it's also calling a method that is defined in the parent component which changes the state of the options element.
// parent component
<div class="card-body">
<p class="card-subtitle font-weight-bold mb-1">Select Skills</p>
<button
v-for="skill in skills"
:key="skill.id"
:class="[skill.state ? skillSelectedState : skillNotSelectedState]"
class="btn btn-sm m-2" #click="addSkill(skill)"
:value="skill.category">
{{skill.skills}}
</button>
<clientInput></clientInput> // child component
</div>
<script>
import clientInput from './ClientSkillInput.vue'
export default {
data() {
return {
skills: [], // getting skills from an axios call
selectedSkills: [],
}
}
}
methods: {
addSkill(skill) { // this is the method getting called
if (!skill.state) {
this.selectedSkills.push(skill.skills);
skill.state = true;
} else {
let position = this.selectedSkills.indexOf(skill.skills);
this.selectedSkills.splice(position, 1);
// skill.state = false;
}
},
}
// child component
<template>
<div class="form-group mt-2">
<label class="d-block">Not what you're looking for?</label>
<div class="customWraper">
<div class="userSkillbox d-inline bg-secondary"> // will be using v-for to loop on userProvidedSkills and show the user inputs
Rrby on rails
<button class="userSkillboxBtn btn-sm border-0 text-white"> // to remove the input item
<i class="fas fa-times"></i>
</button>
</div>
<input v-model="userInput" type="text" class="d-inline border-0" placeholder="Type to add different skill" #Click="">
</div>
</div>
</template>
<script>
export default {
data() {
return {
isEditable: true,
userInput: '',
userProvidedSkills: [],
}
},
methods: {
addUserInput() {
this.userProvidedSkills.push(this.userSkill);
this.userSkill = '';
}
}
}
</script>
It is not clear where you’re adding the keydown event, but there 2 possible solutions:
1.Use a event modifier on the input to stop propagation
<input #keydown.enter.stop
2.Use the self event modifier on the parent component button
<button
v-for="skill in skills"
#click.self="addSkill(skill)"
:value="skill.category">
{{skill.skills}}
More about event modifiers here

Remove v-on:click event programmatically from an element (VueJs)

How do I remove the v-on:click event from a div?
<div v-on:click="RegistroT(1)" class="btn btn-secondary btn-block"
:disabled="HoraIngreso !== '00:00'">
<i class="fa fa-clock-o"></i>
<span id="TxtHoraIngreso" v-text="HoraIngreso"></span>
</div>
I tried this in a function called from the VueJS method created when the data is retrieved (from a JsonResult):
$('#TxtHoraIngreso').parent().addClass(this.HoraIngreso !== '00:00' ? 'disabled' : '');
But it does not work.
Basically, when a user registers his time of entry, the next time he enters the web the button must be deactivated.
How do I remove the v-on:click event from a div?
An easy way is to only call the event handler if the state is valid.
<button
type="button"
v-on:click="e => valid && onClickSubmit()"
>
Sign Up
</button>
onClickSubmit() will only be executed if valid = true
<template>
<div class="button-wrapper">
<button class="btn btn-secondary btn-block" :class="{'disabled': isDisabled}" #click="someMethodName"></button>
</div>
</template>
<script>
export default
{
data()
{
return {
isDisabled: false
}
},
methods:
{
someMethodName()
{
setTimeout(() => {
this.isDisabled = true;
}, 3600);
}
}
}
</script>
But maybe I didn't understand your question ;>

ReactJS - state not updated or has not effect?

I'm creating so called recipe box, where you should be able to add/edit/delete recipes. Initial rendering part seems to be working fine, but I'm struggling when it comes to states and updating html depending what was changed: whether existing recipe was modified, deleted or new one added.
Currently I implemented state change trigger when recipe is edited. By reading various articles I came to conclusion that if you want to read values from another element when some other element is interacted (in my case from input element when button element is clicked), I need to add state to track input directly while it is typed and then use that state to trigger what I want (In my case I just use value from so called pending state and set to normal state when that button is pressed).
But it seems it is not working. Though I'm probably doing something wrong.
Here is the part I implemented states I talked about:
class RecipeComponent extends React.Component {
constructor(props){
super(props);
this.state = {
title: '',
pendingTitle: '',
ingredients: '',
pendingIngredients: '',
}
}
handleChange(e, key){
let obj = {};
obj[key] = e.target.value;
this.setState(obj);
}
handleClick(){
this.setState(
{title: this.pendingTitle, ingredients: this.pendingIngredients});
}
_renderModal(target, ctx){
return (
<div className="modal fade" id={target} role="dialog">
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" data-dismiss="modal">×</button>
<h4 className="modal-title">{ctx.title}</h4>
</div>
<div className="modal-body">
<div className="form-group">
<label htmlFor="title" className="control-label"><span>Recipe</span></label>
<input type="text" id="title" className="form-control" placeholder="Recipe Name" defaultValue={ctx.recipeTitle ? ctx.recipeTitle : ''}
onKeyUp={(e) => this.handleChange(e, 'pendingTitle')}
/>
</div>
<div className="form-group">
<label htmlFor="ingredients" className="control-label"><span>Ingredients</span></label>
<input type="text" id="ingredients" className="form-control" placeholder="Enter Ingredients, separated by commas" defaultValue={ctx.ingredients ? ctx.ingredients : ''}
onChange={(e) => this.handleChange(e, 'pendingIngredients')}
/>
</div>
</div>
<div className="modal-footer">
{/*Seems to not update state properly*/}
<button type="button" className="btn btn-primary" onClick={() => this.handleClick()} data-dismiss="modal">{ctx.title}</button>
<button type="button" className="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
);
}
...
...
{/*Here title from state is never set*/}
// Should this.state.title replace default title?
recipeTitle: this.state.title || recipe.title,
}
Full code can be found here (you can also test how it is currently working if it was hard to understand what I meant. Try to open any recipe, edit it and press button Edit Recipe and nothing will happen, recipe title will not be changed): https://codepen.io/andriusl/pen/LjxYQo
You directly accessed this.pendingTitle instead of this.state.pendingTitle. so change this to
handleClick(){
this.setState(
{title: this.state.pendingTitle, ingredients: this.state.pendingIngredients});
}
and change this code to
<a data-toggle="collapse" data-target={anchor_target}
href={anchor_target} className="collapsed">{this.state.title||recipe.title}

Categories

Resources