How to use react semantic ui Dropdown to show number of pages and selected page on right side? - semantic-ui-react

I am new to react. I am following https://www.truecodex.com/course/react-js this example but in this example, it shows all the customers. I want to add a dropdown with no. of pages and on-page selection changes the values in the table.
I think, I should take one more customer{} and add 1-4customer 2-next4customer and then on dropdown selection on change change the table values
Here is my Customer view class where I am fetching all customers.
import React from 'react';
import { Table,Icon, Button } from 'semantic-ui-react';
export default class CustomerView extends React.Component {
constructor(props) {
super(props);
this.state = {
error: null,
deleteTitle: "customer",
isLoaded: false,
formClose: false,
singleCustomer: [],
users: []
}
}
//fetch data
componentDidMount() {
const customerApi = 'https://localhost:44387/api/Customers';
const myHeader = new Headers();
myHeader.append('Content-type', 'application/json');
myHeader.append('Accept', 'application/json');
myHeader.append('Origin', 'https://localhost:44387');
const options = {
method: 'GET',
myHeader
};
fetch(customerApi, options)
.then(res => res.json())
.then(
(result) => {
this.setState({
users: result,
isLoaded: true
});
},
(error) => {
this.setState({
isLoaded: false,
error
});
}
)
}
//Delete Customer
onDeleteCustomer = customerId => {
const { users } = this.state;
this.setState({
users: users.filter(customer => customer.customerId !== customerId)
});
const customerApi = 'https://localhost:44387/api/Customers/' + customerId;
const myHeader = new Headers({
'Accept': 'application/json',
'Content-type': 'application/json; charset=utf-8'
});
fetch(customerApi, {
method: 'DELETE',
headers: myHeader
})
.then(res => res.json())
.then(
(result) => {
this.setState({
})
}, (error) => {
this.setState({ error });
}
)
}
render() {
const { users } = this.state;
return (
<div>
<Button color='blue' onClick={() => this.props.onCreate()}>New Customer</Button>
<br/>
<br/>
<Table celled textAlign='center'>
<Table.Header>
<Table.Row>
<Table.HeaderCell>ID</Table.HeaderCell>
<Table.HeaderCell>Name</Table.HeaderCell>
<Table.HeaderCell>Address</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
<Table.HeaderCell>Action</Table.HeaderCell>
</Table.Row>
</Table.Header>
<Table.Body >
{
users.map(user => (
<Table.Row key={user.customerId}>
<Table.Cell>{user.customerId}</Table.Cell>
<Table.Cell>{user.name}</Table.Cell>
<Table.Cell>{user.address}</Table.Cell>
<Table.Cell>
<Button color='yellow' icon labelPosition='right'
onClick={() => this.props.onEditCustomer(user.customerId)}>
<Icon name='edit outline'/>
Edit</Button>
</Table.Cell>
<Table.Cell>
<Button color='red' icon labelPosition='right'
onClick={() => this.props.onDeleteClick(user.customerId)}>
<Icon name='trash alternate'/>
Delete</Button>
</Table.Cell>
</Table.Row>
))
}
</Table.Body>
<Table.Footer>
<Table.Row>
<Table.HeaderCell colSpan='5'>
No of Pages
</Table.HeaderCell>
</Table.Row>
</Table.Footer>
</Table>
</div>
)
}
}

Related

Invalid hook call. Hooks can only be called inside of the body of a function

I was trying to develop a login page with the Django rest framework as the backend. The backend is working perfectly whereas I can't even set up react js. I am getting an error in the Index.js file of react. It tells "Invalid hook call. Hooks can only be called inside of the body of a function component"
This is what the error I get
App.js
import React from 'react';
import './App.css';
import Paperbase from './Layout/Paperbase'
import { BrowserRouter, Route, Switch } from 'react-router-dom';
import Login from './Layout/Login/Login'
import Register from './Layout/Register/Register'
export function App() {
return (
<BrowserRouter>
<Switch>
<Route path="/dashboard" render={() => <Paperbase /> } />
<Route path="/account/login" render={() =><Login />} />
<Route path="/account/register" render={() => <Register />} />
</Switch>
</BrowserRouter>
)
}
export default App
Index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import store from './store';
import { Provider } from 'react-redux';
import { render } from 'react-dom';
ReactDOM.render(
(<Provider store={store}>
<App/>
</Provider>),
document.getElementById('root') || document.createElement('div') // for testing purposes
);
serviceWorker.unregister();
Login.js
import React from 'react';
import Avatar from '#material-ui/core/Avatar';
import Button from '#material-ui/core/Button';
import CssBaseline from '#material-ui/core/CssBaseline';
import TextField from '#material-ui/core/TextField';
import FormControlLabel from '#material-ui/core/FormControlLabel';
import Checkbox from '#material-ui/core/Checkbox';
import Grid from '#material-ui/core/Grid';
import LockOutlinedIcon from '#material-ui/icons/LockOutlined';
import Typography from '#material-ui/core/Typography';
import Container from '#material-ui/core/Container';
import { withStyles } from '#material-ui/core/styles';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import { login } from '../../actions/auth';
const styles = theme => ({
'#global': {
body: {
backgroundColor: theme.palette.common.white,
},
},
paper: {
marginTop: theme.spacing(25),
display: 'flex',
flexDirection: 'column',
alignItems: 'center',
},
avatar: {
margin: theme.spacing(1),
backgroundColor: theme.palette.primary.light,
},
form: {
width: '100%', // Fix IE 11 issue.
marginTop: theme.spacing(1),
},
submit: {
margin: theme.spacing(3, 0, 2),
backgroundColor: theme.palette.primary.light,
},
});
class SignIn extends React.Component {
state = {
email: '',
password: '',
};
static propTypes = {
login: PropTypes.func.isRequired,
isAuthenticated: PropTypes.bool,
};
onSubmit = (e) => {
e.preventDefault();
this.props.login(this.state.email, this.state.password);
};
onChange = (e) => this.setState({ [e.target.name]: e.target.value });
render() {
const { classes } = this.props;
const { email, password } = this.state;
return (
<Container component="main" maxWidth="xs">
<CssBaseline />
<div className={classes.paper}>
<Avatar className={classes.avatar}>
<LockOutlinedIcon />
</Avatar>
<Typography component="h1" variant="h5">
Sign in
</Typography>
<form className={classes.form} onSubmit={this.onSubmit}>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
id="email"
label="Email Address"
name="email"
autoComplete="email"
autoFocus
onChange={this.onChange}
value={email}
/>
<TextField
variant="outlined"
margin="normal"
required
fullWidth
name="password"
label="Password"
type="password"
id="password"
autoComplete="current-password"
onChange={this.onChange}
value={password}
/>
<FormControlLabel
control={<Checkbox value="remember" color="primary" />}
label="Remember me"
/>
<Button
type="submit"
fullWidth
variant="contained"
color="primary"
className={classes.submit}
>
Sign In
</Button>
<Grid container>
</Grid>
</form>
</div>
</Container>
);
}
}
const mapStateToProps = (state) => ({
isAuthenticated: state.auth.isAuthenticated,
});
export default (withStyles(styles)(SignIn));
authreducer.js
import {
USER_LOADED,
USER_LOADING,
AUTH_ERROR,
LOGIN_SUCCESS,
LOGIN_FAIL,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
REGISTER_FAIL,
} from '../actions/types';
const initialState = {
token: localStorage.getItem('token'),
isAuthenticated: null,
isLoading: false,
user: null,
};
export default function (state = initialState, action) {
switch (action.type) {
case USER_LOADING:
return {
...state,
isLoading: true,
};
case USER_LOADED:
return {
...state,
isAuthenticated: true,
isLoading: false,
user: action.payload,
};
case LOGIN_SUCCESS:
case REGISTER_SUCCESS:
localStorage.setItem('token', action.payload.token);
return {
...state,
...action.payload,
isAuthenticated: true,
isLoading: false,
};
case AUTH_ERROR:
case LOGIN_FAIL:
case LOGOUT_SUCCESS:
case REGISTER_FAIL:
localStorage.removeItem('token');
return {
...state,
token: null,
user: null,
isAuthenticated: false,
isLoading: false,
};
default:
return state;
}
}
authactions.js
import axios from 'axios';
import {
USER_LOADED,
USER_LOADING,
LOGIN_SUCCESS,
LOGOUT_SUCCESS,
REGISTER_SUCCESS,
} from './types';
// CHECK TOKEN & LOAD USER
export const loadUser = () => (dispatch, getState) => {
// User Loading
dispatch({ type: USER_LOADING });
axios
.get('http://localhost:8000/api/auth/user', tokenConfig(getState))
.then((res) => {
dispatch({
type: USER_LOADED,
payload: res.data,
});
})
.catch((err) => {
console.log(err)
});
};
// LOGIN USER
export const login = (email, password) => (dispatch) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
const body = JSON.stringify({ email, password });
axios
.post('http://localhost:8000/api/auth/login', body, config)
.then((res) => {
dispatch({
type: LOGIN_SUCCESS,
payload: res.data,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// REGISTER USER
export const register = ({ username, password, email }) => (dispatch) => {
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
// Request Body
const body = JSON.stringify({ username, email, password });
axios
.post('http://localhost:8000/api/auth/register', body, config)
.then((res) => {
dispatch({
type: REGISTER_SUCCESS,
payload: res.data,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// LOGOUT USER
export const logout = () => (dispatch, getState) => {
axios
.post('http://localhost:8000/api/auth/logout/', null, tokenConfig(getState))
.then((res) => {
dispatch({ type: 'CLEAR_LEADS' });
dispatch({
type: LOGOUT_SUCCESS,
});
})
.catch((err) => {
console.log(err.response.data)
});
};
// Setup config with token - helper function
export const tokenConfig = (getState) => {
// Get token from state
const token = getState().auth.token;
// Headers
const config = {
headers: {
'Content-Type': 'application/json',
},
};
// If token, add to headers config
if (token) {
config.headers['Authorization'] = `Token ${token}`;
}
return config;
};
Based on my experience, this error often occurs due to the fact that one of the packages in package.json (often it's React) is in dependencies (not in devDependencies). And this version conflicts with yours.

Iterate object list with VueJs from Django API

I try to iterate through a Django Rest API object list using VueJS. I can get the articles json list but I can't correctly view VueJs template component. In my Django views I use
<section class="blog-post-wrap medium-padding80">
<div class="container">
<div class="row">
<div id="starting">
<div class="" v-for="article in articles">
<articlelist title="article.title"></articlelist>
</div>
</div>
</div>
</div>
</section>
And I use VueJs component template
Vue.component('articlelist', {
template: `
<div class="col col-xl-4 col-lg-4 col-md-6 col-sm-12 col-12">
<div class="ui-block"
<div class="post-content">
THE COMMUNITY
{{title}}!
<p>Here’s a photo from last month’s photoshoot. We got really awesome shots for the new catalog.</p>
</div>
<!-- ... end Post -->
</div>
</div>
`,
props: ['title']
});
new Vue({
el: '#starting',
delimiters: ['${','}'],
components:{
'articlelist': articlelist,
},
data: {
articles: [],
loading: false,
currentArticle: {},
message: null,
newArticle: {
'title': null,
'content': null,
},
},
mounted: function() {
this.getArticles();
},
methods: {
getArticles: function() {
this.loading = true;
this.$http.get('/api/articles/')
.then((response) => {
this.articles = response.data;
console.log(response.data);
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
getArticle: function(id) {
this.loading = true;
this.$http.get(`/api/articles/${id}/`)
.then((response) => {
this.currentArticle = response.data;
this.loading = false;
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
addArticle: function() {
this.loading = true;
this.$http.post(`/api/articles/`,this.newArticle)
.then((response) => {
this.loading = false;
this.getArticles();
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
updateArticle: function() {
this.loading = true;
this.$http.put(`/api/articles/${this.currentArticle.article_id}/`, this.currentArticle)
.then((response) => {
this.loading = false;
this.currentArticle = response.data;
this.getArticles();
})
.catch((err) => {
this.loading = false;
console.log(err);
})
},
deleteArticle: function(id) {
this.loading = true;
this.$http.delete(`/api/articles/${id}/` )
.then((response) => {
this.loading = false;
this.getArticles();
})
.catch((err) => {
this.loading = false;
console.log(err);
})
}
}
});
I am aware that I could not manage to correct the naming of components and scripts but I can not find the correct way.
When I check chrome dev tools, I see error :
Uncaught ReferenceError: articlelist is not defined
Can you help me ?
Thanks

Vue.js + Avoriaz : how to test a watcher?

I am trying to test the following component w Avoriaz, but upon props change , the action in watch: {} is not triggered
ItemComponent.vue
switch checkbox
✗ calls store action updateList when item checkbox is switched
AssertionError: expected false to equal true
at Context.<anonymous> (webpack:///test/unit/specs/components/ItemComponent.spec.js:35:47 <- index.js:25510:48)
thanks for feedback
ItemComponent.vue
<template>
<li :class="{ 'removed': item.checked }">
<div class="checkbox">
<label>
<input type="checkbox" v-model="item.checked"> {{ item.text }}
</label>
</div>
</li>
</template>
<script>
import { mapActions } from 'vuex'
export default {
props: ['item', 'id'],
methods: mapActions(['updateList']),
watch: {
'item.checked': function () {
this.updateList(this.id)
}
}
}
</script>
here is my component test
ItemComponent.spec.js
import Vue from 'vue'
import ItemComponent from '#/components/ItemComponent'
import Vuex from 'vuex'
import sinon from 'sinon'
import { mount } from 'avoriaz'
Vue.use(Vuex)
describe('ItemComponent.vue', () => {
let actions
let store
beforeEach(() => {
actions = {
updateList: sinon.stub()
}
store = new Vuex.Store({
state: {},
actions
})
})
describe('switch checkbox', () => {
it('calls store action updateList when item checkbox is switched', () => {
const id = '3'
const item = { text: 'Bananas', checked: true }
const wrapper = mount(ItemComponent, { propsData: { item, id }, store })
// switch item checked to false
wrapper.setProps({ item: { text: 'Bananas', checked: false } })
expect(wrapper.vm.$props.item.checked).to.equal(false)
expect(actions.updateList.calledOnce).to.equal(true)
})
})
})
U mistaked the prop,use :checked instead
I should write my expect(actions.updateList() . within a $nextTick block
describe('switch checkbox', () => {
it('calls store action updateList when item checkbox is switched', (done) => {
const id = '3'
const item = { text: 'Bananas', checked: true }
const wrapper = mount(ItemComponent, { propsData: { item, id }, store })
// switch item.checked to false
wrapper.setProps({ item: { text: 'Bananas', checked: false } })
expect(wrapper.vm.$props.item.checked).to.equal(false)
wrapper.find('input')[0].trigger('input')
wrapper.vm.$nextTick(() => {
expect(actions.updateList.calledOnce).to.equal(true)
done()
})
})
})
then my test is OK
ItemComponent.vue
switch checkbox
✓ calls store action updateList when item checkbox is switched

Retrieving data from a couchdb

.Am working on an app using ionic 2. I have my data in couchdb about 9 differents items. How can i display each data from the database corresponding to the item clicked. The items are in a list?
This s the provider diagnosis.ts
import { Injectable } from '#angular/core';
import PouchDB from 'pouchdb';
#Injectable()
export class Diagnosis{
data: any;
db: any;
remote: any;
constructor() {
this.db = new PouchDB('ezy');
this.remote = 'http://localhost:5984/ezy';
let options = {
live: true,
retry: true,
continuous: true
};
this.db.sync(this.remote, options);
}
getTodos() {
if (this.data) {
return Promise.resolve(this.data);
}
return new Promise(resolve => {
this.db.allDocs({
include_docs: true
}).then((result) => {
this.data = [];
let docs = result.rows.map((row) => {
this.data.push(row.doc);
});
resolve(this.data);
this.db.changes({live: true, since: 'now', include_docs: true}).on('change', (change) => {
this.handleChange(change);
});
}).catch((error) => {
console.log(error);
});
});
}
createTodo(todo){
this.db.post(todo);
}
getTodo(todo){
this.db.get(todo);
}
updateTodo(todo){
this.db.put(todo).catch((err) => {
console.log(err);
});
}
deleteTodo(todo){
this.db.remove(todo).catch((err) => {
console.log(err);
});
}
handleChange(change){
let changedDoc = null;
let changedIndex = null;
this.data.forEach((doc, index) => {
if(doc._id === change.id){
changedDoc = doc;
changedIndex = index;
}
});
//A document was deleted
if(change.deleted){
this.data.splice(changedIndex, 1);
}
else {
//A document was updated
if(changedDoc){
this.data[changedIndex] = change.doc;
}
//A document was added
else {
this.data.push(change.doc);
}
}
}
}
provider usage is as
.ts
constructor(public navCtrl: NavController, public navParams: NavParams,public diagnose:Diagnosis) {
this.pet = "puppies";
console.log(diagnose.getTodos());
diagnose.getTodos().then(result=>{
this.pest = result;
console.log(result);
})
}
.html
<ion-grid>
<ion-row>
<ion-col *ngFor="let val of pest" width-100>
<ion-list>
<ion-item><h3>{{val.name}}</h3></ion-item>
<ion-item><h3>{{val.description}}</h3></ion-item>
<ion-item><h3>{{val.disease}}</h3></ion-item>
<ion-item><h3>{{val.prevention}}</h3></ion-item>
</ion-list>
</ion-col>
</ion-row>
</ion-grid>
I'm not sure what you want.. If you need to display clicked item what you have to do is add (click) event where you call a function sending the item (Again, I don't know if you are asking this)...
<ion-item (click)="viewItem(val.prevention)"><h3>{{val.prevention}}</h3></ion-item>

The changed value is not reflecting on the input field in ReactJS, TestUtils

I am using ReactJs and Mocha and trying few unit tests. I have two mandatory form fields First Name and Last Name. I am trying to test the validation where if only one field is entered, the other field displays the missing value validation error.
Below code simulates the changes to the value and simulates the form submit.
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
The changed value is reflected in the event handlers on First Name. But, not in the test. So, both the fields display missing value validation failing my test.
What I could be doing wrong here?
Below are code:
//NameForm.jsx
'use strict';
var React=require('react')
var forms = require('newforms')
var NameForm = forms.Form.extend({
firstName: forms.CharField({maxLength: 100, label: "First name(s)"}),
lastName: forms.CharField({maxLength: 100, label: "Last name"}),
cleanFirstName(callback) {
callback(null)
},
render() {
return this.boundFields().map(bf => {
return <div className={'form-group ' + bf.status()}>
<label className="form-label" htmlFor={bf.name}>
<span className="form-label-bold">{bf.label}</span>
</label>
{bf.errors().messages().map(message => <span className="error-message">{message}</span>)}
<input className="form-control" id={bf.name} type="text" name={bf.name} onChange = {this.onChangeHandler}/>
</div>
})
}
, onChangeHandler: function(e){
console.log("onchnage on input is called ----- >> " + e.target.value)
}
})
module.exports = {
NameForm
}
Here is NamePage.jsx:
'use strict';
var React = require('react')
var {ErrorObject} = require('newforms')
var superagent = require('superagent-ls')
var {API_URL} = require('../../constants')
var {NameForm} = require('./NameForm')
var NamePage = React.createClass({
contextTypes: {
router: React.PropTypes.func.isRequired
},
propTypes: {
data: React.PropTypes.object,
errors: React.PropTypes.object
},
statics: {
title: 'Name',
willTransitionTo(transition, params, query, cb, req) {
if (req.method != 'POST') { return cb() }
superagent.post(`${API_URL}/form/NameForm`).send(req.body).withCredentials().end((err, res) => {
if (err || res.serverError) {
return cb(err || new Error(`Server error: ${res.body}`))
}
if (res.clientError) {
transition.redirect('name', {}, {}, {
data: req.body,
errors: res.body
})
}
else {
transition.redirect('summary')
}
cb()
})
}
},
getInitialState() {
return {
client: false,
form: new NameForm({
onChange: this.forceUpdate.bind(this),
data: this.props.data,
errors: this._getErrorObject()
})
}
},
componentDidMount() {
this.setState({client: true})
},
componentWillReceiveProps(nextProps) {
if (nextProps.errors) {
var errorObject = this._getErrorObject(nextProps.errors)
this.refs.nameForm.getForm().setErrors(errorObject)
}
},
_getErrorObject(errors) {
if (!errors) { errors = this.props.errors }
return errors ? ErrorObject.fromJSON(errors) : null
},
_onSubmit(e) {
e.preventDefault()
var form = this.state.form
form.validate(this.refs.form, (err, isValid) => {
if (isValid) {
this.context.router.transitionTo('name', {}, {}, {
method: 'POST',
body: form.data
})
}
})
},
render() {
return <div>
<h1 className="heading-large">Your name</h1>
<form action='name' method="POST" onSubmit={this._onSubmit} ref="form" autoComplete="off" noValidate={this.state.client}>
{this.state.form.render()}
<button type="submit" className="button">Next</button>
</form>
</div>
},
})
module.exports = NamePage
Here is NameTest.js :
//NameTest.js
var React = require('react')
var ReactAddons = require('react/addons')
var TestUtils = React.addons.TestUtils
var InputFieldItem = require('../../src/page/name/NamePage')
describe('Name page component', function(){
var renderedComponent;
before('render element', function() {
console.log("*** in before")
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
});
it('Only First Name entered should display one error message', function() {
renderedComponent = TestUtils.renderIntoDocument(
<InputFieldItem />
);
var formElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'form').getDOMNode()
var firstNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[0].getDOMNode()
var lastNameElement = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input')[1].getDOMNode()
var buttonElement = TestUtils.findRenderedDOMComponentWithTag(renderedComponent, 'button').getDOMNode()
TestUtils.Simulate.change(firstNameElement , {target: {value: 'Joe'}});
TestUtils.Simulate.submit(formElement)
var errorSpans = TestUtils.scryRenderedDOMComponentsWithClass(renderedComponent, 'error-message')
console.log("First name value is :|"+ firstNameElement.value + "|")
expect (errorSpans.length).to.equal(1)
})
});