How do I send data from a WYSIWYG to a database (Vue.js) - javascript

I just started using the Vue2Editor with the intention to replace the many forms that I use to send text and image data to my Firebase database.
My problem is that I cannot get it to add the data entered in the editor.
When using forms, I would just attach an event handler to the form itself and make a function that allowed the transfer.
Example:
<form #submit.prevent="addText">
<label for="fname">First name:</label>
<input type="text" id="fname" name="fname" v-model="fname">
</form>
<button type="submit" variant="success">Save</button>
But when using the Vue2Editor, I do not get any form tags.
I just get a "vue-editor" tag. I tried adding the event handler inside this tag, but nothing happens.
I don't get any errors, but the data is not transferred to the database upon submitting it.
This is the code:
<template>
<div class="container">
<div class="text_editor">
<h2>Add new content</h2>
<vue-editor #submit.prevent="addText" v-model="textblock" />
<button type="submit" class="textblock_btn" variant="success">Save</button>
</div>
</div>
</template>
<script>
import db from '#/firebase/init'
import Vue from "vue";
import Vue2Editor from "vue2-editor";
Vue.use(Vue2Editor);
export default {
name: 'textblock',
data () {
return {
textblock: null
}
},
methods: {
addText(){
db.collection('textblock').add({
textblock: this.textblock
}).then(() => {
this.$router.push({ name: 'Index' })
}).catch(err => {
console.log(err)
})
}
}
}
</script>

You can still wrap the component in a form as the WYSIWYG editor's data is bound to the v-model property.
<form #submit.prevent="addText">
<div class="text_editor">
<h2>Add new content</h2>
<vue-editor v-model="textblock" />
<button type="submit" class="textblock_btn" variant="success">Save</button>
</div>
</form>
Within the addText method you now have this.textblock with the appropriate data on form submission.

Related

Form not passing value on submit

I am struggling with getting my results from an API to show up on HTML page. Does work if the function is executed in the console.
<body>
<div>
<form>
<input type="text" id="search" placeholder="Enter person">
<input type="submit" value="Submit" name="submit" onclick="fetchPerson()" />
</form>
</div>
<div id="app"></div>
JS:
function fetchPerson() {
var input = document.getElementById('search').value;
fetch(`notrevealingapi/api/name=${input}`)
.then(res => res.json())
.then(data => {
console.log(data);
const html = data.data
.map(hit => {
return `<p>Hits: ${hit.person}</p>`;
})
.join("");
document.querySelector('#app').insertAdjacentHTML("afterbegin", html);
})
}
If I understand your need correctly.
you want to populate the result in the <div id="app"> when a user clicks on the submit button.
There is two basic mistakes I can think of.
You should use the button type instead of submit
And use innerHTML instead of the insertAdjacentHTML. So it would look like
document.querySelector('#app').innerHTML = html

Grab template form input in Vue 3 class components (like done in Angular)

I started vue 3 today, and opted for the class-based approach in the cli. I'm from the Angular background, so forgive me for thinking like Angular. Every example I see (even in the docs) is still using the Vue({...}) thing, however, I wanna do something like this (still thinking Angular-ish)
In angular, I can do this
<form #formData="ngForm" (ngSubmit)="onSubmit(formData.value)">
<input (ngModel)="name" name="name" placeholder="name">
</form>
Then in component
...
export class AppComponent {
public name!: string;
onSubmit(formData: string) {
console.log(formData)
}
}
What would be the vue 3 class components approach like the above?
I currently have this in vue 3
export default class Welcome extends Vue {
name!: string;
onSubmit(formData: any) {
console.log(formData)
}
}
<template>
<div>
<form #submit.prevent="onSubmit">
<p>
<label for="name">Name</label> <br>
<input type="text" placeholder="name" id="name" name="name" v-model="name"/>
</p>
<button type="submit">Send</button>
</form>
</div>
</template>
What changes do I need to do to the above to connect the form in template to the component?
Without a third party library there isn't the same type of functionality that angular provides. Angular is doing a bunch of additional things to enhance the form object for validation and value tracking, and Vue natively does not do that. However you could instead put your data properties in an object to group them together. That way when you need to access them in something like the submit event to perhaps send all the values to an API, you can simply refer to that object instead of having to handle/build each property separately:
Class:
export class AppComponent {
// create object with bound form properties
public values: { name: string; } = { name: '' };
onSubmit() {
console.log(this.values); // { name: '' }
// axios.post('/api', this.values).then(res => console.log(res.data));
}
}
Template:
<template>
<div>
<form v-on:submit.prevent="onSubmit">
<p>
<label for="name">Name</label> <br>
<input type="text" placeholder="name" id="name" name="name" v-model="values.name"/>
</p>
<button type="submit">Send</button>
</form>
</div>
</template>
That being said, if you do need advanced form features like validation, sanitization, and similar there are plenty of libraries that do it well.
Hopefully that helps!
The native FormData constructor takes a <form> element, which creates the values of the form for all named inputs (<input>s or <textarea>s with name attribute).
So you could update your onSubmit method to retrieve the form data values:
export default class Welcome extends Vue {
name!: string;
onSubmit(formData: any) {
const form = e.target
const formData = new FormData(form)
}
}
Example using the Options API:
<template>
<div>
<form #submit.prevent="onSubmit">
<p>
<label for="name">Name</label> <br>
<input type="text" placeholder="name" id="name" name="name" v-model="name"/>
</p>
<button type="submit">Send</button>
</form>
</div>
</template>
<script>
export default {
methods: {
onSubmit(e) {
const form = e.target
const formData = new FormData(form)
console.log({ formData: Array.from(formData.entries()) })
}
}
}
</script>
demo

How to set the default value of a dropdown list to a state variable in Reactjs

I have a React component which contains a textbox, dropdown list, and a submit button.
I capture values of the textbox and a dropdown list using an 'OnChange' event as follows.
<div className="form-group">
<label htmlFor="accountName">Account Name</label>
<input type="text" id="accountName" className="form-control" name="accountName" value={this.state.accountName} onChange={(e)=>this.change(e)}></input>
</div>
<div className="form-group">
<label htmlFor="originatedBy">Originated By</label>
<select className="form-control" id="originatedBy" name="originatedBy" value={this.state.originatedBy} onChange={(e)=>this.change(e)}>
<option>value1</option>
<option>value2</option>
<option>value3</option>
</select>
</div>
<div className="form-group row ml-md-1">
<button type="submit" className="btn btn-outline-primary btn-block" onClick={(e)=>this.addRecord(e)}>Add Record</button>
</div>
And in the Js section, I have,
class AddRecordView extends Component{
state={
accountName:"",
originatedBy:""
}
change(e){
this.setState({[e.target.name]:e.target.value});
}
addRecord(e){
e.preventDefault(e);
const user={
accountName : this.state.accountName,
originatedBy : this.state.originatedBy,
}
console.log(user);
var url = <url_of_the_endpoint>";
axios.post(url, {
user
},{
headers: {
'Accept': 'application/json'
}
})
.then(function(response){
console.log(response);
})
.catch(function(error){
console.log(error);
});
}
render(){
return(
<html_section>
);
}
}
export default AddRecordView;
The 'accountName' and the 'originatedBy' values are simply set when there is a change in the textbox and dropdown-list respectively.
However, if I let the default value (the value which shows when the form is loaded) of the dropdown-list remains unchanged and Submit the data, it doesn't trigger the 'OnChange' event and passes,
{accountName: 'some_value', originatedBy: ""} to the backend.
How can I make the 'originatedBy' attribute to take the default value of the dropdown-list. Please share your ideas on how to make it work (maybe from the constructor or any other suitable method).
Any suggestions will be helpful.

Whats the proper way to have a form submit data in a stateless react component?

I have a stateless react component that is a little pop up. It takes some data from the user, and passes that back to its parent, where it executes the work.
What is the best way for this component to have a handleSubmit() function, that takes the user input, and sends it back to the parent?
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="modal-background" onClick={props.onClick} />
<div className="modal-card">
<section className="modal-card-body">
<div className="content">
<h1 className="title"> Transfer Tokens </h1>
<p className="has-text-danger">
Requires that you are the owner of the token you are transferring
</p>
<p className="subtitle">How it works</p>
<p className="">
Enter the ID of the token you want to transfer, the address to
whom its going to, and thats it!
</p>
//problem area
<form onSubmit={props.onClickSubmit}>
<label htmlFor="text">Address to recieve token</label>
<input
name="Address"
className="input is-info "
required="true"
/>
<label htmlFor="number">Token ID</label>
<input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<a className="button is-pulled-right">Submit</a>
</form>
</div>
</section>
<footer className="modal-card-foot is-clearfix">
<a className="button" onClick={props.onClick}>
Cancel
</a>
</footer>
</div>
</div>
);
};
export default Transfer;
I pass in as a prop, onClickSubmit, in my parent component, and that contains the logic for what I'm trying to do.
Very new to stateless react components
It will be difficult to accomplish what you want with a stateless component since you cannot use either refs or state in a stateless component. You can think of a stateless component as a pure function that returns a piece of UI depending on the props you give it.
You could instead use a stateful component and e.g. store the input values in state and call the onClickSubmit prop function with this state when the user submits the form.
If you want to build stateless forms component, I send you a lib that I'm working on:
react-distributed-forms
This allow you to build your Transfer Component this way, (pay attention to use Input instead of input and Button instead of button):
import React, { Component } from "react";
import "../../../node_modules/bulma/css/bulma.css";
import { Input, Button } from "react-distributed-forms";
const Transfer = (props, token, web3) => {
return (
<div className="modal is-active">
<div className="myForm">
<label htmlFor="text">Address to receive token</label>
<Input name="Address" className="input is-info " required="true" />
<label htmlFor="number">Token ID</label>
<Input
className="input is-info"
name="Token ID"
type="number"
required="true"
/>
<Button name="submit" className="button is-pulled-right">
Cancel
</Button>
</div>
</div>
);
};
export default Transfer;
And then in your parent Component, wherever it is in the hierarchy, you simply do:
<Form onSubmit={({ name }) => { console.log(name); }} onFieldChange={({ name, value} ) => { console.log(name, value); }}>
...whatever
<Transfer />
...whatever
</Form>
onFieldChange will receive every input change.
onSubmit will receive the attribute "name" on the Button when you click it.
react-distributed-forms use React context API, so you don't have to pass directly props, it just works. Is built for really dynamic forms...

How we can have events in one form with angular 2

All I want is one form which has two different buttons with different actions behind. I was wondering in every angular 2 component we can have only one onSubmit to call service. how can I have two? and how can I tell angular which buttons is associate to which service call.
when there is one button every thing is Ok but not with two buttons.
this is my onSubmit code:
onSubmit() {
this.service.generatePhone(this.data)
.subscribe(
() => {
this.success = true;
},
(error) => {
},
I want another onSubmit to call service.updatePhone.
and in my shortened html file:
<div class="form-signin">
<form #myForm="ngForm" (ngSubmit)="onSubmit()">
<div class="form-group">
<p class="text-left">your phone number </p>
</div>
<button type="submit" >
generate
</button>
<br/>
</form>
</div>
I want another
<button type="submit" >update </button>
<button type="button" (click)="doSomething()">

Categories