From couple of days,I am struggling to get tirx-change event fired when trix-editor's content changes.But not able to figure out the issue.I am using react js for view.
Below is my code :
class Desc extends React.Component {
handleChangeTrix(event){this.setState({[event.target.description.name]:
event.target.description.value});
}
render(){
return(
<div className="container-fluid">
<form onSubmit = {this.handleSubmit.bind(this)}
className="form-horizontal" >
<input id="description"
name="description"
className="form-control"
value={this.state.description}
hidden="True" type="hidden">
</input>
<trix-editor trix-change={this.handleChangeTrix.bind(this)}
classname="trix-content"
input="description"
placeholder="Start typing here...." >
</trix-editor>
<button type="submit">submit</button>
</form>
</div>);
}
}
If you feel some details are missing please ask in comment.If you feel question is inappropriate and deserve a down vote,i would love to know mistake via your valueable comment.
Thanks in advance.
you call setState was wrong. It should be changed to
handleChangeTrix(event){this.setState({description:
event.target.description.value});
Related
I am currently building my first, very basic react app. There is a button that triggers an API call using onClick. However, react just doesn't seem to be rendering the onclick to the DOM.
Within index.js I have, among other, the following content:
<NumberSelect
label={"Can I get your number?"}
id_input1={"number-input"}
placeholder={42}
onClickEvent={RequestFact}
cta={"Get Fact"}
/>
This is my NumberSelect.js:
import Button from "./Button.js";
import InputNumber from "./InputNumber.js";
import "./NumberSelect.css";
const NumberSelect = (props) => {
return (
<form id="number-select">
<label htmlFor={props.id_input1}>{props.label}</label>
<InputNumber
placeholder={props.placeholder}
id_input1={props.id_input1}
/>
<Button
cta={props.cta}
class={"btn mt-10"}
href={props.href}
onClickEvent={props.onClickEvent}
/>
</form>
);
};
export default NumberSelect;
And this is the entire Button.js
import "./Button.css";
const Button = (props) => {
return (
<a
id={props.id}
className={props.class}
href={props.href}
onClick={props.onClickEvent}
>
{props.cta}
</a>
);
};
export default Button;
What I would expect the HTML to look like is this (note: is defined in a separate Component):
<form id="number-select">
<label for="number-input">Can I get your number?</label
><input
type="text"
inputmode="numeric"
pattern="[0-9]*"
id="number-input"
placeholder="42"
spellcheck="false"
data-ms-editor="true"
/><a class="btn mt-10" onclick="RequestFact()">Get Fact</a>
</form>
But this is what the HTML actually looks like:
<form id="number-select">
<label for="number-input">Can I get your number?</label
><input
type="text"
inputmode="numeric"
pattern="[0-9]*"
id="number-input"
placeholder="42"
spellcheck="false"
data-ms-editor="true"
/><a class="btn mt-10">Get Fact</a>
</form>
Almost everything is the same, only the onclick="RequestFact() is missing.
Can anybody help me out? Do you need any other info?
Thanks for your help!
Edit: I tried to simplify the code a bit and not post everything here. But it seems I took away too much and it became unclear. Sorry for that. Above some additional code.
Info regarding the additional questions:
RequestFact ist located in index.js
Thanks for the tip regarding { for strings - will implement
I am creating a Sign in and Sign up page. Both sign in and sign up will be shown on the same page, without redirecting it to another page.
Right now, I have two functions showSignUp and showSignIn. These two returns the form. I then render them by calling {this.showSignIn()}. I have a button says "Sign In", and a Link saying "Create a new account". Clicking on the create a new account should show the "Sign up" form. I inserted my showSignIn() function below. The showSignUp function is similar to this.
But I am unsure how should I solve the clicking on a link calls another function.
{I solved the problem by creating one js file for sign in and one for sign up previously. But this cause alot of repetitive code. That is why I am trying to merging them.}
return (
<form>
<div className="login-screen">
<div className="formField">
<label className="formField-Label" htmlFor="name">
E-mail
</label>
<input
type="email"
id="email"
className="formField-Input"
placeholder="Enter your e-mail address"
name="email"
value={email}
onChange={this.handleChange}
/>
</div>
<div className="formField">
<label className="formField-Label" htmlFor="password">
Password
</label>
<input
type="password"
id="password"
className="formField-Input"
placeholder="Enter your password"
name="password"
value={password}
onChange={this.handleChange}
/>
</div>
<div className="formField">
<button className="form-button" onClick={this.signin}>
Sign In
</button>
<Link to={this.showSignUp} className="form-link">
Create a new account
</Link>
</div>
</div>
</form>
);
I suppose your Link comes from react-router-dom, so it only accepts string or object as to prop, see https://reacttraining.com/react-router/web/api/Link.
You should replace it with a <button onClick={this.showSignUp}>Create...</button>
Note that your showSignUp function should trigger a state change in order to render again and change the form displayed. It would look something like :
state = {
showSignUp: false,
}
renderSignUp() {
return (
<form>
// ...
<button onClick={() => this.setState({ showSignUp: false })} className="form-link">Create a new account</button>
</form>
);
}
renderSignIn() {
// Returns your sign in form
}
render() {
return this.state.showSignUp ? this.renderSignUp() : this.renderSignIn();
}
I second adesurirey's answer, but it doesn't have to be a button, you can attach and onClick listener to just about any html element so if you wanted it to behave more like a normal link it could even be an <a /> tag with no new route or a <span> that you style to look like a <Link>
So I’ve spent the last few weeks learning react and now I’m trying to do so with firebase.
Right now, I am trying to make it possible to edit and delete a blog post. I’ve made a few similar things over the last few weeks with express, rails etc so I thought I got a pretty good handle on it so right now I’m trying to compare and know the differences between them.
Most of the functions have been easily refactored to work with what I’m doing now so I’m not sure exactly how to tweak this one to work here or if it won’t work at all which would then turn to how do I properly do it here.
The original code I used last time that I tried to edit for this was:
getInitialState(){
return {editable: false}
},
handleEdit(){
if( this.state.editable){
var title = this.refs.title.value;
var article= this.refs.article.value;
var id = this.props.post.id;
var post = {id: id, title: title, article: article};
this.props.handleUpdate(post);
}
this.setState({editable: !this.state.editable})
},
render: function(){
var title= this.state.editable? <input className= "form-control" type='text' ref='title' defaultValue={this.props.post.title}/>:
<h3>{this.props.post.title}</h3>;
var article= this.state.editable ? <input className= "form-control" type='text' ref='article' name="logEntryEdit" defaultValue={this.props.post.article}/>:
<p className="postText">{this.props.post.article}</p>;
return(
<div >
<div className="text-center postTitle">
{title}
</div>
<hr/>
<br/>
<div className="text-center" id="postText">
{article}
</div>
<br/>
<hr/>
<button className="btn btn-danger delete-button" onClick={this.props.handleDelete}>Delete</button>
<button className="btn btn-primary" onClick={this.handleEdit}>{this.state.editable ? 'Submit' : 'Edit'}</button>
</div>
)
Naturally I edited the item names and such. How I set up my edit page was by first passing the selected post via the id that firebase generates into a single view page and then pass it in into the edit page. The delete should be from that view page as well.
This is the edit where I tried to put in the above function:
constructor(props){
super(props);
this.state = {
title: '',
body: '',
post:{},
};
}
componentDidMount(){
database.ref(`posts/${this.props.match.params.postId}`)
.on('value', snapshot => {
this.setState({post: snapshot.val()});
});
this.postId= this.props.match.params.postId;
}
//edit function goes here
render() {
return (
<div className="container">
<form onSubmit={this.onHandleUpdate}>
<div className="form-group">
<input value={this.state.post && this.state.post.title} className="form-control" type="text" name="title" ref="title" placeholder="Title" onChange={this.onInputChange}/>
</div>
<br/>
<div className="form-group">
<input value={this.state.post && this.state.post.body} className="form-control" type="text" name="body" ref="body" placeholder="Body" onChange={this.onInputChange}/>
<br/>
</div>
<button className="btn btn-success">Submit</button>
</form>
</div>
);
}
When I tried adding it in I also got a
A component is changing an uncontrolled input of type text to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component
It linked me to the docs which I went over as well.
Can you please tell me how to make the original code I had fit in and work for this time or how it is supposed to be done so I can compare and understand the difference?
This error stems from the fact that you are stating that the input fields are updated via a this.onInputChangefunction and yet that function is not defined anywhere. This means there is no way to update the inputs and react does not like that. either define your this.onInputChange function or switch to using refs (when you use ref react call that an uncontrolled component).
I have a problem with the appendTo function.
I am currently working on a responsive design.
If the window is smaller than a certain size, login and search are appended to another div.
If it gets bigger again, they will be moved to where they come from, theoretically.
And what happens instead? With ".login", it works perfectly. But the ".search" is f*cking things up. Everytime you resize the window, instead of being appended TO, it just get appended, so resize the window with 100px and you will have a 2^100 of those ".search"-forms.
Funny thing is, they are all the same.
HTML
...
<div class="wrap1">
<div class="login">
<form method="post" action="#">
<input type="text" name="user" placeholder="Username"/>
<input type="text" name="pass" placeholder="Password"/>
<input type="submit" value="Submit"/>
</form>
</div>
</div>
<div class="wrap2">
<div class="search">
<form method="get" action="#">
<input type="text" name="search" placeholder="Search"/>
<input type="submit" value="Search"/>
</form>
</div>
</div>
<div class="wrap3">
</div>
...
JavaScript / jQuery
$(document).ready(function(){
$(window).resize(function(){
if ($(window).width() < 461) {
$(".login, .search").prependTo($(".wrap3"));
} else {
$(".login").appendTo(".wrap1");
$(".search").appendTo(".wrap2");
}
})
})
Any ideas?
I'd be happy with jQ but pure JS answers are also welcome.
I hope below answer will help you.
function searchPos(){
if ($(window).width() < 461) {
$(".wrap1 .login, .wrap2 .search").prependTo($(".wrap3"));
} else {
$(".wrap3 .login").appendTo(".wrap1");
$(".wrap3 .search").appendTo(".wrap2");
}
}
searchPos();
$(window).resize(function(){
searchPos();
});
See Demo
Found it!
#nnnnnn was actually right:
There were multiple wraps. My JS is actually $(".login").appendTo(".wrap1 .centerwrap")
(it's still called wrap1 for comprehension)
So there wouldn't be any problems, but I forgot that there were multiple nested (bc of pos:abs navigation) centerwraps in .wrap2. That's why the .wrap1 .login worked perfectly but the .wrap2 .search didn't.
Solved it with
$(".login").appendTo(".wrap1 > .centerwrap");
$(".search").appendTo(".wrap2 > .centerwrap");
And yes, I feel dumb. Have been looking for the answer for 2 days now.
I am using Jquery validate to provide feedback to a user and provide them updates on the validity of the details they enter in the form. But I am having trouble customising the behaviour Jquery validate creates.
I have a simple form like this:
<form id="form1">
<label for="input1" />
<input name="input1" />
<input type="submit" />
</form>
When the user enters invalid information I want Jquery validate to output something like this:
<form id="form1">
<label for="input1" />
<input name="input1" class="error"/><span class="errorIcon">Error</span>
<p class="errorText">Error message</p>
<input type="submit" />
</form>
When the user fills out the field with valid information I want Jquery validate to output:
<form id="form1">
<label for="input1" />
<input name="input1" /><span class="successIcon">Success</span>
<input type="submit" />
</form>
I have set up the required rules and custom validation messages so they fire fine but I am having trouble getting the behaviour described above.
I have this currently:
$('#form1').validate({
showErrors: function(errorMap, errorList) {
if (errorList < 1 ) {
$('span.errorIcon').remove();
$('p.errorText').remove();
$('input.error').removeClass('error');
$('select.error').removeClass('error');
return;
}
$.each(errorList, function(index, error) {
if ($(error.element).siblings('.errorText').length === 0 && $(error.element).siblings('.errorIcon').length === 0) {
$(error.element).next('p.errorText').remove();
$(error.element).addClass('error');
$(error.element).after(
$('<p/>')
.addClass('errorText')
.append(error.message)
);
$(error.element).after(
$('<span>There is an issue with this field</span>')
.addClass('errorIcon')
);
}
});
},
//rules and messages defined here
);
So the above doesn't achieve what I want need currently and it also feels like I might be over complicating this issue. I am fairly inexperienced with javascript and Jquery. Any guidance in getting this sorted would be appreciated.
Cheers
EDIT:
Here is a link to a jsfiddle: http://jsfiddle.net/WJ9Vt/4/ with the sample form.
Could also post you css file, or do a jsfiddle on it ? Because you errorIcon is probably not shown because <span> will not display something as long as it has no content or you set display:block; and a special height and width.