Proper way to implement Pikaday in Meteor React - meteor

I'm trying to implement Pikaday in Meteor React. I've searched through numerous solutions and I can't get any of them to work. As I understand it, this is supposed to work:
I installed pikaday as follows: npm install -- save react react-pikaday.
Below is my code - What am I doing wrong?
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import Pikaday from 'react-pikaday';
export default class TestForm extends Component {
ComponentDidMount() {
new Pikaday({
field: ReactDOM.findDOMNode(this.refs.TestForm),
format: 'DD/MM/YYYY',
firstDay: 0,
minDate: new Date(new Date()),
maxDate: new Date('2050-12-31'),
yearRange: [2000,2050],
});
}
render() {
return(
<div>
<form>
<div className="row">
<div className="input-field col s6">
<input ref="TestForm" type="text" />
</div>
</div>
</form>
</div>
)
}
}

From the github page, there is a component that can be used:
<Pikaday value={date} onChange={this.handleChange} />
If you want to do the componentDidMount way, add an id to the div tag. and use document.getElementById('textId'); instead of using ReactDOM.
I also noticed a typo in ComponentDidMount() {. It should be componentDidMount (c - lowercase).

Related

Integrating modal component onto page on load React JS

I have webpage with React JS. The structure of site is MainContent.js --> Main.js -->ReactDOM render. I wanted to have modal popup when page opens so built modal component Modal.js--> DashModal.js which worked on its own project but not when imported to my site.
How do I import it correctly to have modal popup on load like it does on its own project? Thanks. I provided code below.
**Index JS**
import React from "react";
import ReactDOM from "react-dom";
import Main from "./containers/Main";
import { CookiesProvider } from "react-cookie";
import DashModal from "./components/DashModal"
// Import main sass file to apply global styles
import "./static/sass/style.scss";
ReactDOM.render(
<CookiesProvider>
<Main />
</CookiesProvider>,
document.getElementById("app")
);
**DashModal.js - the modal component**
import React from 'react'
import ReactDOM from 'react-dom'
import Modal from "../components/modal"
import "../components/modal.css"
import AppStore from "../static/images/AppLogoBlue.png";
class DashModal extends React.Component {
constructor(props) {
super(props)
this.state = {show:true}
}
showModal = () => {
this.setState({show: true});
};
hideModal = () => {
this.setState({show:false});
};
render() {
return(
<main>
<h1> React Modal </h1>
<Modal show = {this.state.show} handleClose ={this.hideModal}>
<div className = "left">
<a>
<img src={AppStore} alt= ""></img>
</a>
</div>
<div className = "left">
<button className= "button" onClick={this.hideModal}>Regular site </button>
</div>
</div>
</Modal>
<button type = "button" onClick = {this.showModal}>
open
</button>
</main>
);
}
}
const container = document.createElement("div");
document.body.appendChild(container);
ReactDOM.render(<DashModal/>, container);
export default DashModal;
**modal.js- part of modal which goes into DashModal.js**
import React from 'react';
import "./modal.css"
const Modal = ({ handleClose, show, children}) => {
const showHideClassName = show? "modal display-block" : "modal display-none"
return(
<div className={showHideClassName}>
<section style={ModalBox} className= "modal-main">
{children}
<button onClick={handleClose}>close</button>
</section>
</div>
);
};
export default Modal;
Thanks in advance
From my understanding, you want to open the modal by default when the <DashModal /> was imported into another component.
You can pass a prop show={true|false} to DashModal component <DashModal show={true} /> and inside that component add a componentDidMount lifecycle method
componentDidMount = () =>{
const {show} = this.props;
if(show){
this.showModal()
}
}
This will check the props and call the showModal when the component is loaded.

Is there a way to use either a nz-checkbox Or nz-checkbox-group Or nz-checkbox-wrapper inside a reactive form

Following code works great if is used independently,
<nz-checkbox-group [(ngModel)]="field.options" [formControlName]="field.id" (ngModelChange)="updateValue($event)"></nz-checkbox-group>
Angular6.0 does not allow [(ngModel)] with FormGroup (Reactive Forms). As is deprecated in angular 6.0 and will be removed in angular 7.0 version.
Is there any method to write nz-checkbox-group for ReactiveForm ?
I got a similar problem solved that using the following method. SourceCode
import { Component } from '#angular/core';
import { FormGroup, FormControl, FormBuilder, FormArray } from '#angular/forms';
#Component({
selector: 'nz-demo-checkbox-layout',
template: `
<nz-checkbox-wrapper style="width: 100%;" (nzOnChange)="log($event)">
<div nz-row >
<div [formGroup]="myFormGroup">
<label nz-checkbox nzValue="A" formControlName="a">A</label>
<label nz-checkbox nzValue="B" formControlName="b">B</label>
<label nz-checkbox nzValue="C" formControlName="c">C</label>
<label nz-checkbox nzValue="D" formControlName="d">D</label>
</div>
</div>
</nz-checkbox-wrapper>`
})
export class NzDemoCheckboxLayoutComponent {
constructor(private fb: FormBuilder) { }
public myFormGroup = this.fb.group({
a:this.fb.control(true),
b:this.fb.control(false),
c:this.fb.control(false),
d:this.fb.control(false)
});
}

Pushing data to object in different component using POST

TL;DR I want to show submitted posts instantly instead of having to refresh my page
Using the Wordpress REST API I am able to create a new post without any issue. The post is being displayed as soon as the page refreshes, so what I want to do is update the posts object in my Hello.vue file as soon as I create that post so I don't need to refresh to show my newest posts.
I'm not really sure where to start - I've removed all of the experiments I've done so far (importing Post in Create, defining props, pushing to an array, reading about object reactivity on the official Vue documentation, nothing helped).
My App.js consists of the <router> object which shows Hello.vue and a component called Create which displays the Create.vue component. This is how my app currently looks like:
My App.vue file:
<template>
<div id="app">
<section class="posts">
<router-view></router-view>
<create></create>
</section>
</div>
</template>
<script>
import Create from '#/components/Create.vue'
export default {
name: 'app',
components: {
Create
}
}
</script>
<style lang="scss">
#import '../src/assets/styles/style.scss'
</style>
My Hello.vue which displays all the posts:
<template>
<div>
<section class="posts__Feed">
<ul class="posts__List">
<post v-for="item in posts" :item="item" :key="item.id"></post>
</ul>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
import Post from '#/components/Post.vue'
export default {
name: 'hello',
props: ['responseData'],
components: {
Post
},
data () {
return {
posts: []
}
},
beforeCreate () {
this.$http.get(postsUrl).then((response) => {
this.posts = response.data
})
}
}
</script>
And finally, the Create.vue file which creates the post:
<template>
<div>
<section class="posts__Create">
<form class="posts__CreateForm" v-on:submit="createPosts">
<div class="posts__CreateFormWrapper" v-bind:class="{ 'is-Loading': loading }">
<p>
<input v-model="formInfo.title" type="text" name="title" id="title" placeholder="Name" :disabled="formSent">
</p>
<p>
<textarea v-model="formInfo.content" name="content" id="content" cols="20" rows="10" maxlength="140" placeholder="Message" :disabled="formSent"></textarea>
</p>
<p>
<button :disabled="formSent">Send</button>
</p>
</div>
</form>
</section>
</div>
</template>
<script>
var postsUrl = '/wp-json/wp/v2/posts/'
export default {
name: 'create',
data () {
return {
formInfo: [],
responseData: [],
loading: false,
formSent: false
}
},
methods: {
createPosts (e) {
e.preventDefault()
var info = this.formInfo
// Check if fields are empty
if (this.formInfo.title && this.formInfo.content) {
this.loading = true
// POST
this.$http.post(postsUrl, info).then((response) => {
this.formSent = true
this.loading = false
// get body data
this.responseData = response.data
})
}
} // EOF createPosts
}
}
</script>
Any help would be much appreciated!
I ended up using an event bus as suggested by wotex. First, I've createad a file called bus.js with the below code:
import Vue from 'vue'
export const EventBus = new Vue()
Next, import bus.js to both .vue layouts using:
import { EventBus } from '#/bus.js'
Now emit the event as soon as a new post is created (this is sitting in my axios POST request inside the Create.vue file):
EventBus.$emit('newPost', this.responseData)
And finally, check if the event has happened on the other end (my Hello.vue file):
EventBus.$on('newPost', function (postData) {
Thanks for pointing me in the right direction!

(login) submit with FormControl in react

iam using the latest version of meteor & react. Yesterday I switched to the newest version of bootstrap. Before that everything worked just fine now I canĀ“t fix my (really noobish) problem.
import React, {Component} from 'react';
import { FormControl, , etc. } from 'react-bootstrap';
export default class Login extends Component {
login(event) {
event.preventDefault();
var username = this.refs.inputName.refs.input.value.trim();
var password = this.refs.inputPw.refs.input.value.trim();
Meteor.loginWithPassword(username, password, function (error) {
if (error) {
...
}
else {
FlowRouter.go('/c/' + Meteor.user().username);
}
});
this.refs.password.refs.input.value = "";
}
render() {
return (
<Row>
<Col xs={3} xsOffset={4}>
<form onSubmit={this.login.bind(this)}>
<FormGroup>
<ControlLabel>Willkommen</ControlLabel>
<FormControl
type="text"
placeholder="Benutzername"
ref="inputName"
name="username"/>
</FormGroup>
<FormGroup>
<FormControl
placeholder="Password"
ref="inputPw"
name="password"
type="password"/>
</FormGroup>
<FormGroup>
<Col smOffset={2} sm={10}>
<Button bsStyle="primary" label="Login" id="loginButton" type="submit" active>Login</Button>
</Col>
</FormGroup>
</form>
</Col>
</Row>
);
}
In my previous solution I used a simple input form. Due to deprecation I switched to this formControl stuff. Now it seems that
<form onSubmit={this.login.bind(this)}>
login never gets called. Console.log(username) returns undefined.
Thanks in advance and many greetings.
//edit 1:
It seems like Iam not the only one with this problem.
React-bootstrap Form getValue not a function
This helped me a lot to find my solution:
import ReactDom from 'react-dom';
var username = ReactDom.findDOMNode(this.refs.inputName).value;
var password = ReactDom.findDOMNode(this.refs.inputPw).value;

getting this npm react component to work with meteor

Using react-typeahead-component
I used browserify to change it from npm into a meteor local package. Nothing is showing on the screen when i run meteor.
OptionTemplate.jsx
module.exports = React.createClass({
render: function() {
return (
<div>
<p>HELLO</p>
</div>
);
},
handleChange: function(event) {
console.log('HELLO');
}
});
main.jsx
var OptionTemplate = require('./OptionTemplate.jsx');
SearchBox = React.createClass({render() {
return (
<div className="col-xs-12 col-lg-12">
<OptionTemplate />
</div>
)}
});
You aren't using components properly. You might want to re-read the react documentation.
In your main.jsx, you are importing the component 'OptionTemplate' but you are trying to render the component 'Typeahead' and passing in 'OptionTemplate' as a prop. The 'Typeahead' component now lives in 'OptionTemplate'. Your main.jsx should like like:
var OptionTemplate = require('./OptionTemplate.jsx');
SearchBox = React.createClass({render() {
return (
<div className="col-xs-12 col-lg-12">
<OptionTemplate />
</div>
)}
});

Resources