react-native-print print of documents with data set in react native using html - react-native

Is there any way to display my data set into the html within async printHTML() I am using react native. Hope anyone can help me, It would be gladly appreciated, I've been working on it for how many hours. Thank you!
I tried using this way but it is not working, i just diaplay {dataSet1 ? dataSet1.map((dataSet1 , index) => ({dataSet1 .name} )) : No data} as a text
async printHTML() {
await RNPrint.print({
html: '<h1>Heading 1</h1>{dataSet1 ? dataSet1.map((dataSet1 , index) => (<div>{dataSet1 .name}</div> )) : <div>No data</div>}'
})
}
this is the dataset i want to display
const dataSet1 = [
{
name: "Johson",
amount: 30000,
sex: 'M',
is_married: true
},
{
name: "Monika",
amount: 355000,
sex: 'F',
is_married: false
},
{
name: "John",
amount: 250000,
sex: 'M',
is_married: false
},
{
name: "Josef",
amount: 450500,
sex: 'M',
is_married: true
}
];
Here is my Function
async printHTML() {
await RNPrint.print({
html: `<h1>Custom converted PDF Document</h1>
<h1>Custom converted PDF Document</h1>
<h1>Custom converted PDF Document</h1>
<h1>Custom converted PDF Document</h1>
`,
})
}
Andt this is my render component
render(){
return(
<Container style={{backgroundColor: '#f4f5f9'}}>
<View>
<View style={styles.container}>
<Button onPress={this.printHTML} title="Print HTML" />
</View>
</View>
</Container>
)
}
}

insert my data in an state
this.state = {
loading: false,
sound: 'off',
selectedPrinter: null,
dataSet1: [
{
name: "Johson",
amount: 30000,
sex: 'M',
is_married: true
},
{
name: "Monika",
amount: 355000,
sex: 'F',
is_married: false
},
{
name: "John",
amount: 250000,
sex: 'M',
is_married: false
},
{
name: "Josef",
amount: 450500,
sex: 'M',
is_married: true
}
]
}
Get the data to be displayed in table
renderTableData(){
return this.state.dataSet1.map((dataSet1, index) => {
const { name, amount, sex } = dataSet1
return (
`<tr key=${index}>
<td>${name}</td>
<td>${amount}</td>
<td>${sex}</td>
</tr>`
)
})
}
Call the function here
async printHTML() {
let html_content =
`<h1>Hello, UppLabs!</h1>
<table>
<tbody>
${this.renderTableData()}
</tbody>
</table>`
await RNPrint.print({
html : html_content })
}
change the button on press
render(){
return(
<Container style={{backgroundColor: '#f4f5f9'}}>
<View>
<Button onPress={() => {this.printHTML()}} title="Print HTML" />
</View>
</View>
</Container>
)
}

Related

Display search output using json data in react native

I am at a very primitive stage of learning react-native. And I am trying to solve a simple problem, which may sound silly, but I really want to know the answer.
I have a json file
data.js
export const PRODUCT_DATA = [
{
name: 'abc',
price: 90,
weight: '1 kg',
currency: 'INR',
liked: true,
image: require('../assets/images/carrots/Rectangle238.png')
},
{
name: 'bce',
price: 10,
weight: '1 kg',
currency: 'USD',
liked: false,
image: require('../assets/images/mango/Rectangle234.png')
},
{
AllCategoriesComponent: [
{
icon: "home-outline",
name: "Household",
shape: true,
},
{
icon: "basket-outline",
name: "Grocery",
shape: false,
},
{
icon: "ios-podium",
name: "Milk",
shape: true,
},
{
icon: "ios-rose",
name: "chilled",
shape: false,
},
{
icon: "hardware-chip",
name: "Drinks",
shape: true,
},
{
icon: "cloud",
name: "Pharmacy",
shape: true,
},
{
icon: "fast-food",
name: "Frozen Food",
shape: true,
},
{
icon: "football",
name: "Vegetable",
shape: true,
},
{
icon: "bulb",
name: "Meat",
shape: true,
},
{
icon: "football",
name: "Vegetable",
shape: true,
},
{
icon: "bulb",
name: "Meat",
shape: true,
},
]
},
];
ANd below is screen file
screen.js
import { SearchBar } from 'react-native-elements';
import { Text, View, TextInput } from 'react-native';
import React from 'react';
import { PRODUCT_DATA } from "./data";
export default class App extends React.Component {
constructor() {
super();
this.state = {
search: '',
}
}
updateSearch = (search) => {
this.setState({ search: search });
};
render() {
const { search } = this.state;
return (
<View>
<SearchBar onChangeText={this.updateSearch} value={search} />
{PRODUCT_DATA[2].AllCategoriesComponent.map((item, index) => {
if (item.name === this.state.search) {
return (
<View style={{ backgroundColor: "white" }}>
<Text>{search}</Text>
</View>
);
} else {
return (<Text></Text>);
}
})}
<Text>{this.state.search}</Text>
</View>
);
}
}
As you can see this is not a good solution. I am able to print the output only if I type full name in the SearchBar. Also it seems all the item.name are already on the screen, which comes up when value of search bar matches it. I want to start showing the output as soon as something is typed on the SearchBar
This might help please look into it
import { FlatList, Text, View, TextInput } from "react-native";
export default class Example extends Component {
constructor(props) {
super(props);
this.state = {
text: "",
data: [],
};
this.arrayholder = [];
}
componentDidMount() {
const data = PRODUCT_DATA[2].AllCategoriesComponent.map((item, index) => {
return item;
});
this.setState({ data }, () => {
this.arrayholder = data;
});
}
searchData(text) {
const newData = this.arrayholder.filter((item) => {
const itemData = item.name.toUpperCase();
const textData = text.toUpperCase();
return itemData.indexOf(textData) > -1;
});
this.setState({
data: newData,
text: text,
});
}
render() {
return (
<View style={styles.MainContainer}>
<TextInput
onChangeText={(text) => this.searchData(text)}
value={this.state.text}
placeholder="Search Here"
/>
<FlatList
data={this.state.data}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => <Text style={styles.row}>{item.name}</Text>}
/>
</View>
);
}
}

Filter DetailsList

Can anyone please let me know how to filter a DetailsList? For instance, let’s say I have the following list:
list
How do I filter the list such that when I type “Reject”, it will only show items with Status “Reject”
Here is the code I tried (from the documentation https://developer.microsoft.com/en-us/fabric#/components/detailslist):
private _onChangeText = (text: any) => {
this.setState({ items: text ? this.state.items.filter(i =>
i.Status.indexOf(text) > -1) : this.state.items });
}
<TextField
label="Filter by name:"
onChanged={this._onChangeText}
/>
Thanks!
Here's a Codepen where I'm filtering a collection of items to see if the text is present in any of the item's values (case-insensitive). It is similar to the documentation example you linked in your original question. I hope that helps!
let COLUMNS = [
{
key: "name",
name: "Name",
fieldName: "Name",
minWidth: 20,
maxWidth: 300,
},
{
key: "status",
name: "Status",
fieldName: 'Status',
minWidth: 20,
maxWidth: 300
}
];
const ITEMS = [
{
Name: 'xyz',
Status: 'Approve'
},
{
Name: 'abc',
Status: 'Approve'
},
{
Name: 'mno',
Status: 'Reject'
},
{
Name: 'pqr',
Status: 'Reject'
}
]
const includesText = (i, text): boolean => {
return Object.values(i).some((txt) => txt.toLowerCase().indexOf(text.toLowerCase()) > -1);
}
const filter = (text: string): any[] => {
return ITEMS.filter(i => includesText(i, text)) || ITEMS;
}
class Content extends React.Component {
constructor(props: any) {
super(props);
this.state = {
items: ITEMS
}
}
private _onChange(ev: React.FormEvent<HTMLInputElement | HTMLTextAreaElement>, text: string) {
let items = filter(text);
this.setState({ items: items });
}
public render() {
const { items } = this.state;
return (
<Fabric.Fabric>
<Fabric.TextField label="Filter" onChange={this._onChange.bind(this)} />
<Fabric.DetailsList
items={ items }
columns={ COLUMNS }
/>
</Fabric.Fabric>
);
}
}
ReactDOM.render(
<Content />,
document.getElementById('content')
);

How to set multiple select with #shoutem/ui DropDownMenu?

I use DropDownMenu and take a reference from official doumcn https://shoutem.github.io/docs/ui-toolkit/components/dropdown-menu
I want to set two DropDownMenu the first is for zone and the second is for city, if user select the zone like East the second DropDownMenu should set the value E1、E2
Here is my code:
import React, { Component } from 'react';
import { View } from 'react-native';
import { DropDownMenu, Text } from '#shoutem/ui';
class TestConfirm extends Component {
constructor(props) {
super(props);
this.state = {
zone: [
{
id: 0,
brand: "North",
models:
{
model: "Audi R8",
image: {
url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Audi-R8.jpg"
},
description: "North Description"
},
children: [{
name: "N1",
id: 10,
},{
name: "N2",
id: 17,
}]
},
{
id: 1,
brand: "West",
models: {
model: "Chiron",
image: {
url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Chiron.jpg"
},
description: "West Description"
},
children: [{
name: "W1",
id: 10,
},{
name: "W2",
id: 17,
}]
},
{
id: 2,
brand: "East",
models: {
model: "Dodge Viper",
image: {
url: "https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Dodge-Viper.jpg"
},
description: "East Description"
},
children: [{
name: "E1",
id: 10,
},{
name: "E2",
id: 17,
}]
},
],
}
}
render() {
const selectedZone = this.state.selectedZone || this.state.zone[0];
console.log('selectedZone =>');
console.log(selectedZone);
console.log('selectedZone.children =>');
console.log(selectedZone.children);
return (
<Screen>
<DropDownMenu
styleName="horizontal"
options={this.state.zone}
selectedOption={selectedZone ? selectedZone : this.state.zone[0]}
onOptionSelected={(zone) => this.setState({ selectedZone: zone })}
titleProperty="brand"
valueProperty="cars.model"
/>
<Text styleName="md-gutter-horizontal">
{selectedZone ?
selectedZone.models.description :
this.state.zone[0].models.description}
</Text>
<DropDownMenu
styleName="horizontal"
options={selectedZone.children}
selectedOption={selectedZone ? selectedZone : this.state.zone[0].children}
onOptionSelected={(city) => this.setState({ selectedZone: city })}
titleProperty="name"
valueProperty="cars.model"
/>
</Screen>
);
}
}
export default TestConfirm;
Here is my screen look like this:
If i select East it will show error
Invalid `selectedOption` {"id":2,"brand":"East","models":{"model":"Dodge Viper","image":{"url":"https://shoutem.github.io/img/ui-toolkit/dropdownmenu/Dodge-Viper.jpg"},"description":"East Description"},"children":[{"name":"E1","id":10},{"name":"E2","id":17}]}, DropDownMenu `selectedOption` must be a member of `options`.Check that you are using the same reference in both `options` and `selectedOption`.
I check my console.log will look like this:
The key children under the name is what i want to put it into my second DropDownMenu
I have no idea how to do next step. Any help would be appreciated.
Thanks in advance.
selectedOption property for the DropDownMenu component expects a single object but this.state.zone[0].children is an array. You can change it to this.state.zone[0].children[0] to fixed the problem.
Also when you change the city dropdown you are updating the zone value in state. This will cause a bug. Try fixing it with setting a different value in state and checking that value for the city dropdown
Sample
render() {
const { zone, selectedZone, selectedCity } = this.state
return (
<Screen>
<DropDownMenu
styleName="horizontal"
options={zone}
selectedOption={selectedZone || zone[0]}
onOptionSelected={(zone) =>
this.setState({ selectedZone: zone, selectedCity: zone.children[0] } )
}
titleProperty="brand"
valueProperty="cars.model"
/>
<Text styleName="md-gutter-horizontal">
{selectedZone ?
selectedZone.models.description :
this.state.zone[0].models.description}
</Text>
<DropDownMenu
styleName="horizontal"
options={selectedZone ? selectedZone.children : zone[0].children } // check if zone selected or set the defaul zone children
selectedOption={selectedCity || zone[0].children[0] } // set the selected city or default zone city children
onOptionSelected={(city) => this.setState({ selectedCity: city })} // set the city on change
titleProperty="name"
valueProperty="cars.model"
/>
</Screen>
);
}

React native component does not react to mobx observable data change

so I started to build a new app with react native and mobx.
I have a flat list component that gets his state data from the mobx store list. and when i'm adding new item to the mobx list, it won't re render the flat list view.
here is my code:
List Component:
#inject('TravelStore')
#observer
class TripsList extends Component {
constructor(props) {
super(props);
this.state = {
trips_list: props.TravelStore.trips_list
}
};
// set the navigation bar options
static navigationOptions = ({ navigation }) => {
const { params = {} } = navigation.state;
return {
title: 'Your Trips',
headerRight: (
<Button transparent primary onPress={ params.addNewTrip }>
<Icon name='ios-add' />
</Button>
)
};
};
// connect between component functions to header
componentDidMount() {
this.props.navigation.setParams({
addNewTrip: this._addNewTrip.bind(this),
});
}
_addNewTrip() {
this.props.TravelStore.addNewTrip('bla')
}
_renderListItem({ item }) {
return (
<TripsListItem details={item} navigation={this.props.navigation}/>
);
};
render() {
return (
<Container>
<FlatList
data = {this.state.trips_list}
renderItem = {this._renderListItem.bind(this)}
keyExtractor={(item, index) => index}
/>
</Container>
);
};
}
mobx store:
class ObservableTravelListStore {
#observable trips_list = [
{
name: 'to denver',
trip_cost: 400,
buying_list: [
{ name: 'pizza', price: 10 },
{ name: 'burger', price: 40 },
{ name: 'ipad', price: 44 },
{ name: 'bus', price: 45 },
]
},
{
name: 'to yafo',
trip_cost: 30,
buying_list: [
{ name: 'na na na', price: 10 },
{ name: 'burger', price: 40 },
]
},
{
name: 'to tel aviv',
trip_cost: 50,
buying_list: [
{ name: 'na na na', price: 10 },
{ name: 'no no no', price: 40 },
]
},
]
#action addNewTrip (trip_data) {
this.trips_list.push({
name: 'newTrip',
trip_cost: 6060,
buying_list: [
{ name: 'na na na', price: 10 },
{ name: 'burger', price: 40 },
]
})
console.log(this.trips_list[3])
}
}
const TravelStore = new ObservableTravelListStore()
export default TravelStore
any idea why the TripsList component won't rerender when addNewTrip function is called?
the problem is that you are not listening to the real observable but to a copy of it, you save in state in the constructor.
<FlatList
data = {this.state.trips_list}//change this
renderItem = {this._renderListItem.bind(this)}
keyExtractor={(item, index) => index}
/>
<FlatList
data = {this.props.TravelStore.trips_list}//change to this
renderItem = {this._renderListItem.bind(this)}
keyExtractor={(item, index) => index}
/>
the render function is like autobind of mobx and react to changes in the observable if it's a render function of an observer
if you want to react to inner changes in the items of the list,
you should add an observable scheme and this should do the trick,
something like this:
class TripModel {
#observable name = ''
#observable trip_cost = 0
#observable buying_list = []
constructor(name, cost, buy_list){
this.name = name
this.trip_cost = cost
this.buying_list = buy_list
}
/* class functions*/
}
class ObservableTravelListStore {
#observable trips_list = [
new Trip(
'to denver',
400,
[
{ name: 'pizza', price: 10 },
{ name: 'burger', price: 40 },
{ name: 'ipad', price: 44 },
{ name: 'bus', price: 45 },
]
),
new Trip(
'to yafo',
30,
[
{ name: 'na na na', price: 10 },
{ name: 'burger', price: 40 },
]
),
new Trip(
'to tel aviv',
50,
[
{ name: 'na na na', price: 10 },
{ name: 'burger', price: 40 },
]
)
]
#action addNewTrip (trip_data) {
this.trips_list.push(new Trip(
'newTrip',
6060,
[
{ name: 'na na na', price: 10 },
{ name: 'burger', price: 40 },
]
))
}
}
const TravelStore = new ObservableTravelListStore()
export default TravelStore
this is just better planning for reactive apps, so on change to inner content of the items in the list you will react to this change
hope that helps
Its an old post, but I also got stuck with something similar recently. Adding extraData in Flatlist prop list helped me.
<FlatList
data = {this.props.TravelStore.trips_list}
renderItem = {this._renderListItem.bind(this)}
keyExtractor={(item, index) => index}
extraData={this.props.TravelStore.trips_list.length} // list re-renders whenever the array length changes
/>
And as #Omri pointed out, you shouldn't be storing the observable in the Component state but make changes to it directly.

In react native how to append fetch response array object in to render function?

I Need to Display Below the Array Data into Render Function :
I would Know how to loop the data and display it in Render.
[{
profileid: 1,
enabled: 1,
attachment: '',
id: 233,
topicid: 47,
tstamp: 'January, 21 2016 15:06:31 +1100',
body: 'to check orders'
}, {
profileid: 2,
enabled: 1,
attachment: '',
id: 233,
topicid: 47,
tstamp: 'January, 21 2016 15:06:31 +1100',
body: 'to check orders'
} ]
I hope I help you
class Parent extends React.Component{
constructor(props){
super(props);
this.state = {
gists : []
}
}
componentDidMount() {
fetch('http://rest.......')
.then(response => response.json())
.then(gists => this.setState({ gists }))
}
render(){
return (
<ul>
{this.state.gists.map(gist => (
<li key={gist.countryId}>{gist.name}</li>
))}
</ul>
)
}
}
Parent.propTypes = {
data: React.PropTypes.array
}
Here is an example.
import React from 'react'
import { View, Text } from 'react-native'
...
const data = [{
profileid: 1,
enabled: 1,
attachment: '',
id: 233,
topicid: 47,
tstamp: 'January, 21 2016 15:06:31 +1100',
body: 'to check orders'
}, {
profileid: 2,
enabled: 1,
attachment: '',
id: 233,
topicid: 47,
tstamp: 'January, 21 2016 15:06:31 +1100',
body: 'to check orders'
} ]
...
render() {
return (
<View>
{data.map((dataItem) =>
<View key={dataItem.profileid}>
<Text>{dataItem.profileId}</Text>
<Text>{dataItem.enabled}</Text>
<Text>{dataItem.attachment}</Text>
<Text>{dataItem.id}</Text>
<Text>{dataItem.topicid}</Text>
<Text>{dataItem.tstamp}</Text>
<Text>{dataItem.body}</Text>
</View>
)}
</View>
)
}