Detailed Explanation on how to use ListView renderSectionHeader - javascript

const users =
[
{
name: "Joy soap",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 24,
images:
"https://snack1.amazonaws.com/~asset/9d799c33cbf767ffc1a72e53997218f7"
},
{
name: "Closeup tooth paste",
customerName: "Salomy",
date: "19 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 20,
images:
"https://1.amazon4d99c3d76575cc03c2a7f816280"
},
{
name: "Iman Powder",
customerName: "Emanbe",
date: "20 March 2018",
time: "11:25am",
amount: 3000,
status: "paid",
number: 12,
images:
"https://1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
},
{
name: "John Bellion",
customerName: "Okonkwo Chioma",
date: "20 March 2018",
time: "08:46am",
amount: 3000,
status: "paid",
number: 3,
images:
"https://sn1.amazonaws.com/~asset/ee06c63d01543a44631c3421df6ee5fa"
}
];
Please I have an array of objects like the above that I want to render in a ListView with a Section Header function pointing to user.date... I want it to render a list of all the items on 19 March 2018, and then render the items on 20 March 2018 under the header also.
I have used ListView several times but I have never been able to use the section header in this way with the above arrays of object. Please a detailed explanation would be greatly appreciated. I know its probably a simple task to some of you but please be kind. I need a renderSectionHeader() function that can organize the data with respect to their dates so I can render it in my listview like this
`<ListView
ref={ref => (this.scrollView = ref)}
onContentSizeChange={() => {
this.scrollView.scrollToEnd({ animated: false});
}}
dataSource={this.state.userDataSource}
renderRow={this.renderRow.bind(this)}
renderSectionHeader={this.renderSectionHeader.bind(this)}
/>`
An example of what I want is here but I want to know how it can be done with the above array

ListView is no longer available in React-Native. You can use FlatList. Its very simple then ListView as well.
1) Import FlatList from react-native:
import { FlatList } from 'react-native';
2) Copy Below code into your render() method.
<FlatList
horizontal={true/false}
style={YOUR_COSTOM_STYLE}
data={YOUR_ARRAY}
renderItem={this.renderItem.bind(this)}
keyExtractor={(item, index) => String(index)}
/>
3) You do necessary stuff for your cell in renderItem method.
// Render Methods
renderItem({ item }) {
return (
// DO_YOUR_STUFF
);
}
You can more detail about FlatList from here.
One more example for header in FlatList

Related

VueJs: How to paginate an array items with a load more button

I have an array of objectsand I want to show only 3 at a time with a button that when clicked,show 3 more, making 6 in total and so on.
This is what I have currently:
// vue template
<ul>
<li v-for="(order, index) in orders" :key="index">
{{order.item_description}}
</li>
</ul>
<button #click="loadMore">load more </button>
For the script, I have the data and some computed properties:
data() {
return {
orders: [
{
id: 1,
item_description: "One",
created_at: "23, Dec 2019",
delivery_address: "Location",
cost: "2500"
},
{
id: 2,
item_description: "Two",
created_at: "23, Dec 2019",
delivery_address: "Location",
cost: "2500"
},
{
id: 3,
item_description: "Three",
created_at: "23, Dec 2019",
delivery_address: "Location",
cost: "2500"
}
// .... upto 12 items
],
currentPage: 1,
maxPerPage: 3
}
},
computed: {
totalResults() {
return Object.keys(this.orders).length
},
pageCount() {
return Math.ceil(this.totalResults / this.maxPerPage)
},
pageOffest() {
return this.maxPerPage * this.currentPage
}
},
methods: {
loadMore() {
this.currentPage += 1
}
}
}
My confusion is how to get the orders to be paginated using the maxPerPage and then add more using the loadMore
Here is a codesandbox for demo
You can add computed property like:
paginatedOrders() {
return this.orders.slice(0, this.currentPage * this.maxPerPage);
}
And then make your loop with this property:
<li v-for="(order, index) in paginatedOrders" :key="index">{{order.item_description}}</li>
additonnaly you can hide read more button if you already display all items
<button #click="loadMore" v-if="currentPage * maxPerPage < orders.length">load more</button>
Check it on codesandbox
Note: Keep in mind that the most common use of the "load more" button is to load other items with an api call or ajax request. This only works if you load all your orders beforehand.

How do I add Internet Explorer 10 support to a simple VueJs component?

I have a simple VueJs component I'm building that doesn't render at all in IE 10.
Background: The Vue component is a listing of company events, that supports basic filtering and sorting. Unfortunately, I have to support IE10. I am not using babel, but tried to use it in troubleshooting this problem - had no effect
The error I'm getting is 'city' is undefined. IE10 is the only browser experiencing this issue.
Here's a CodePen of just the relevant code. I've added comments to clarify what's going on. Here is just the JS (see CodePen for full code and better context):
/* Server rendered data */
var events = [{
path: "events/residuals-biosolids",
name: "Residuals & Biosolids Conference",
sortDate: "1536165900000",
startDate: "4 September 2018",
endDate: "5 October 2018",
displayDate: "September 4 - October 5, 2018",
state: "WI",
city: "Milwaukee",
booth: "342",
featuredImg: "https://cdn2.hubspot.net/hubfs/4299619/event%20thumb.png"
}, {
path: "events/bio-expo",
name: "Biosolid Expo",
sortDate: "1548979200000",
startDate: "6 February 2019",
endDate: "5 March 2019",
displayDate: "February 6 - March 5, 2019",
state: "MN",
city: "Eagan",
booth: "12",
featuredImg: ""
}, {
path: "events/world-ag-expo",
name: "World AG Expo",
sortDate: "1549670400000",
startDate: "7 February 2019",
endDate: "2 February 2019",
displayDate: "February 7 - 2, 2019",
state: "CA",
city: "Tulare",
booth: "3815",
featuredImg: ""
}];
var eventsDesc = [{
path: "world-ag-expo",
name: "World AG Expo",
sortDate: "1549670400000",
startDate: "7 February 2019",
endDate: "2 February 2019",
displayDate: "February 7 - 2, 2019",
state: "CA",
city: "Tulare",
booth: "3815",
featuredImg: ""
}, {
path: "bio-expo",
name: "Biosolid Expo",
sortDate: "1548979200000",
startDate: "6 February 2019",
endDate: "5 March 2019",
displayDate: "February 6 - March 5, 2019",
state: "MN",
city: "Eagan",
booth: "12",
featuredImg: ""
}, {
path: "residuals-biosolids",
name: "Residuals & Biosolids Conference",
sortDate: "1536165900000",
startDate: "4 September 2018",
endDate: "5 October 2018",
displayDate: "September 4 - October 5, 2018",
state: "WI",
city: "Milwaukee",
booth: "342",
featuredImg: "https://cdn2.hubspot.net/hub/4299619/hubfs/event%20thumb.png?width=760&name=event%20thumb.png"
}];
var selectedStates = ["CA", "MN", "WI", ];
var selectedCities = ["Eagan", "Milwaukee", "Tulare", ];
/*
Vue code below
*/
var app = new Vue({
el: "#sg-events-wrapper",
data: {
message: "Hello Vue!",
dateOrder: "ascending",
selectedCity:"none",
selectedState:"none",
/*the data below is pulled from the script tag in the page.*/
eventCities:selectedCities,
eventStates:selectedStates,
eventList: events,
eventListDesc:eventsDesc,
},
computed: {
eventsSorted:function(){
/*chooses which server generated list to use for rendering events*/
if(this.dateOrder=="ascending"){
return this.eventList;
}
else{
return this.eventListDesc;
}
},
},
methods:{
/*handles the visual filtering when someone sets city and or state*/
isInStateAndCity:function(eventsCity,eventsState){
var citiesMatch;
var statesMatch;
if(eventsCity == this.selectedCity || this.selectedCity=="none"){
citiesMatch = true;
}else{
citiesMatch = false;
}
if(eventsState == this.selectedState ||this.selectedState=="none"){
statesMatch = true;
}else{
statesMatch = false;
}
if(citiesMatch && statesMatch){
return true;
}else{
return false;
}
}
}
});
Troubleshooting steps I've tried:
Used babel, though my code originally isn't written that way.
I used the babel-polyfill - did not seem to have an effect.
I tried to place the js that's in the script tag in the body into the main JS file to see if there was an issue with the js file being loaded for some reason before the code in the HTML. Had no effect.
What I think could be causing the issue: IE10 doesn't like assigning property values to objects like I'm doing. Not certain of this. It's just a guess and I can't think of another way to do it.
Screenshot of IE 10 console error and failed rendering in CodePen in-case it helps.
If you have any ideas but don't have a way to test: I can test any changes and send back a recording of what I see and the console if it has errors.
Posting the answer myself, as others will likely come across this issue too, and there isn't much info out there.
There were two issues. My selectedCities and selectedStates arrays had a comma at the end. Newer browsers don't care about that, but <=IE10 do.
In addition there is a VueJS issue. Someone updated Vue JS to use a new regex string that IE 10 and down do not understand. The fix is to either use an older version of VueJS or replace the regex. Instructions at the source of where I found this info:
https://github.com/vuejs/vue/issues/7946#issuecomment-393713941

How to render JSON Array using handlebars

I am trying to render a repeating UI component with Handlebars.js..
<div class="container-fluid article-container">
{{#each this}}
<h1>{{header}}</h1>
<h1>{{url}}</h1>
<h1>{{body}}</h1>
{{/each}}
</div>
The JSON Data coming back from the API Server is given below..
router.get("/api/fetch", function(req, res) {
var respData = [
{
header: "U.S. Releases Surveillance Records of Ex-Trump Aide",
url:
"https://www.nytimes.com/2018/07/21/us/politics/carter-page-fisa.html",
body:
"The release offered a rare glimpse of national security wiretap files and raised echoes of a fight in February over the Russia inquiry between Republicans and Democrats on the House Intelligence Committee."
}
];
res.render("index", respData);
});
The H1 tags are showing up empty in the UI when the browser renders the page.. Can someone please help me out?
For example, if you api data is coming back as this:
var icecreams = [
{ name: "vanilla", price: 10, awesomeness: 3 },
{ name: "chocolate", price: 4, awesomeness: 8 },
{ name: "banana", price: 1, awesomeness: 1 },
{ name: "greentea", price: 5, awesomeness: 7 },
{ name: "jawbreakers", price: 6, awesomeness: 2 },
{ name: "vanilla", price: 10, awesomeness: 3 }
];
Then your handlebar file would be
{{#each ics}}
<p>Flavor: {{name}}</p>
<p>Price: ${{price}}</p>
<p>Awesomeness: {{awesomeness}}</p>
<hr>
{{/each}}
Express route:
app.get("/icecreams", function(req, res) {
res.render("ics", { ics: icecreams });
});
This will render all the ice-creams. For your example, it will just render one.
This example is taken from one of my demos.

ReactJS - nested loops with map js

I'm trying to have a nested map but i'm getting an undefined error.
So i'm passing the profile props to Link router in navbar.jsx, profile: this.state.profile. Then I fetching the data in profilePage.jsx, where I want to pass the data in an element.
Profile json has 3 components -> experience, education, and skills. So i need to have a nested loop for the data to show up in the element. For example; calling `{experience.company} so the company name will show up.
When i called the profile page, in the console i see profile.experience getting called but then it goes undefined:
(3) [{...}, {...}, {...}] "passing"
undefined "passing"
I tried different ways, splitting the json components but still getting the same error. I know it's mapping issue but I'm not sure if I'm missing something, maybe in React; new to React so learning as much as I can through errors. Your help will be appreciated!
Eventually I want the profile page to look like this:
Education
Company A
August 2016 - present
salesman
Company B
Feb 2016 - August 2016
developer
Company C
August 2012 - October 2015
clerk
Education
school A
fall 2015
mathematics
school B
may 2008
business
Skills
tools: html, css, js, sql
profilePage.jsx
import React, { Component } from "react";
import ProfileItem from "./profileItem"
class Profile extends Component {
render(){
// let profile = this.props.location.profile.map((experience) => <li>{experience.experience}</li>);
// console.log(profile);
const experience = this.props.location.profile.map((profile,idx) => {
console.log(profile.experience, 'passing');
return profile.experience.map((experience,idx) =>
<div>
<p key={idx}>{experience.company}</p>
</div>
);
});
}
}
export default Profile;
navbar.jsx
import React, { Component } from "react";
import { Link } from "react-router-dom";
class Navbar extends Component {
constructor(props){
super(props);
this.state = {
profile: [
{'experience': [
{
'company': 'company A',
'date': 'August 2016 - Present',
'jobTitle': 'salesman'
},
{
'company': 'company B',
'date': 'February 2016 - August 2016',
'jobTitle': 'Developer'
},
{
'company': 'company C',
'date': 'August 2012 - October 2015',
'jobTitle': 'clerk'
}
]},
{'education': [
{
'school': 'shcool A',
'date': 'Fall 2015',
'degree': 'mathematics'
},
{
'school': 'school B',
'date': 'May 2008',
'degree': 'business'
}
]},
{'skills': [
{
'Tools': 'HTML, CSS, Javascript, SQL, Python'
}
]}
],
experience: [],
education: [],
skills: []
};
}
render(){
return (
<div className="navFrame">
<Link to="/">
<div className="topNav"><div className="navBar"><h3>name</h3></div></div>
</Link>
<Link to="/projects">
<div className="rightNav"><div className="navBar"><h3>Projects</h3></div></div>
</Link>
<Link to="/contact">
<div className="bottomNav"><div className="navBar"><h3>Contact</h3></div></div>
</Link>
<Link to={{pathname: '/profile', profile: this.state.profile}}>
<div className="leftNav"><div className="navBar"><h3>Profile</h3></div></div>
</Link>
</div>
);
}
}
export default Navbar;
Try to run this on browser's console =>
From your given Json:
var response = {profile: [
{'experience': [
{
'company': 'company A',
'date': 'August 2016 - Present',
'jobTitle': 'salesman'
},
{
'company': 'company B',
'date': 'February 2016 - August 2016',
'jobTitle': 'Developer'
},
{
'company': 'company C',
'date': 'August 2012 - October 2015',
'jobTitle': 'clerk'
}
]},
{'education': [
{
'school': 'shcool A',
'date': 'Fall 2015',
'degree': 'mathematics'
},
{
'school': 'school B',
'date': 'May 2008',
'degree': 'business'
}
]},
{'skills': [
{
'Tools': 'HTML, CSS, Javascript, SQL, Python'
}
]}
],
experience: [],
education: [],
skills: []
}
when we try to run response.profile.map() it will iterate over all the elements present in this array
response.profile.map(ele => console.log(ele)) will give 3 elements i.e. experience, education and skills
now within an inner block of your code when you will iterate over this element for the first time you will get experience key as defined but for next two iterations it will fail since the key is not present. you can add a filter in between the way I've done below !
const experience = this.props.location.profile
.filter(profile => profile.hasOwnProperty("experience"))
.map((profile, idx) => {
return profile.experience.map((experience, idx) => (
<div>
<p key={idx}>{experience.company}</p>
</div>
));
});
Hope this might help !

Using 3rd Party Components in React

I am a noob at React and have gotten myself a little lost. I am creating my react in a .jsx file which I run grunt-babel on, this then gets put through grunt-uglify to concatenate it with react.js and react-dom.js (in a set order) and finally the single outputted file is then added to my html.
I am using react to build a table. I pass in an array of data for the table, but then I want to splice the array and paginate it.
I've found a 3rd party component that looks like it will do the job (https://github.com/SimonErich/react-paginatr). Now my problem is that I don't know how to actually use this with my workflow. I have tried various other 3rd party components and don't know how to get them to work either.
If I simply add the compiled PaginatrComponent.js PaginatrMixin.js in the libs folder to my uglify command after react and react-dom I get this in the console
Uncaught ReferenceError: module is not defined at react.min.js:8320
And I doing something completely wrong? I see people making references to CommonJs and Webpack and Browserify? But am not sure what they do or how they would fit in my workflow.
My code is on codepen here http://codepen.io/rmaspero/pen/LxQNYY:
var INVOICES = [
{
state: "processing",
number: "INV-31",
customer: "Dael ltd",
total: 60000,
currency: "£",
due: "5 Days",
uri: "https://www.example.com/",
id: 1,
},
{
state: "rejected",
number: "INV-765",
customer: "Dael ltd",
total: 7430,
currency: "€",
due: "30 Days",
uri: "https://www.example.com/2",
id: 2,
},
{
state: "rejected",
number: "INV-001",
customer: "JB Towers ltd",
total: 943,
currency: "£",
due: "15 Days",
uri: "https://www.example.com/3",
id: 3,
},
{
state: "draft",
number: "INV-043",
customer: "JB Towers ltd",
total: 72,
currency: "£",
due: "10 Days",
uri: "https://www.example.com/4",
id: 4,
},
{
state: "processing",
number: "INV-341",
customer: "Dael ltd",
total: 3045,
currency: "£",
due: "45 Days",
uri: "https://www.example.com/5",
id: 5,
},
{
state: "processing",
number: "INV-501",
customer: "JB Towers ltd",
total: 453,
currency: "£",
due: "65 Days",
uri: "https://www.example.com/6",
id: 6,
},
];
function Invoice(props) {
return (
<tr className='invoice-table--row' onClick={props.onLink}>
<td className='invoice-table--cell invoice__state'><span className={"state__indicator indicator--" + props.state}></span><span className="state__text">{props.state}</span></td>
<td className='invoice__number'>{props.number}</td>
<td className='invoice__customer small-mobile-hide'>{props.customer}</td>
<td className='invoice-table--cell'>{props.currency}{props.total}</td>
<td className='invoice__due'>{props.due}</td>
</tr>
);
}
Invoice.propTypes = {
onLink: React.PropTypes.func.isRequired,
}
function TableHeadings() {
return (
<thead>
<tr className='invoice-table--header'>
<th className='invoice-table--head invoice-head__state'>State</th>
<th className='invoice-table--head'>Inv No.</th>
<th className='invoice-table--head small-mobile-hide'>Customer</th>
<th className='invoice-table--head'>Total</th>
<th className='invoice-table--head invoice-head__due'>Due</th>
</tr>
</thead>
);
}
function TableTitle(props) {
return (
<div className="section-divider">
<h3 className="section-divider__title">Processing React</h3>
<div className="paginate">
<a className='paginate__button' href="#"><span className="icon icon--arrow icon--large arrow--previous" data-grunticon-embed></span></a>
<span className="paginate__text">Page 1 of 3</span>
<a className='paginate__button' onClick={props.onPage}><span className="icon icon--arrow icon--large" data-grunticon-embed></span></a>
</div>
</div>
);
}
TableTitle.propTypes = {
onPage: React.PropTypes.func.isRequired,
}
var Dashboard = React.createClass({
propTypes: {
rows: React.PropTypes.number.isRequired,
startrow: React.PropTypes.number,
initialInvoices: React.PropTypes.arrayOf(React.PropTypes.shape({
state: React.PropTypes.string.isRequired,
number: React.PropTypes.string.isRequired,
customer: React.PropTypes.string.isRequired,
total: React.PropTypes.number.isRequired,
currency: React.PropTypes.string.isRequired,
due: React.PropTypes.string.isRequired,
id: React.PropTypes.number.isRequired,
})).isRequired,
},
getDefaultProps: function() {
return {
startrow: 0,
}
},
getInitialState: function() {
return {
invoices: this.props.initialInvoices,
rows: this.props.rows,
};
},
onPageUp: function() {
this.state.invoices.slice(this.props.startrow + this.props.row, this.props.rows);
},
onLinkClick: function(uri) {
console.log(uri);
window.location.href = (uri);
},
render: function() {
return (
<div>
<TableTitle onPage={function() {this.onPageUp()}.bind(this)}/>
<table className='invoice-table'>
<TableHeadings/>
<tbody>
{this.state.invoices.slice(this.props.startrow, this.props.rows).map(function(invoice, index) {
return (
<Invoice
state={invoice.state}
number={invoice.number}
customer={invoice.customer}
total={invoice.total}
currency={invoice.currency}
due={invoice.due}
key={invoice.id}
uri={invoice.uri}
onLink={function() {this.onLinkClick(invoice.uri)}.bind(this)}
/>
);
}.bind(this))}
</tbody>
</table>
</div>
);
}
});
ReactDOM.render(<Dashboard initialInvoices={INVOICES} rows={3} totalRows={6} />, document.getElementById('dashboard-processing__table'));
I think that you should definitely use a tool like Webpack or Browserfy. They allow you to pack your project making references of files way easier. This is good explanation about Webpack. I would also add babel and use React with ES6. The official React docs are using ES6 and I find its syntax way better. All these tools will help you to keep each component in a separate file and they will allow you to reference and use them (or 3rd party components) straightforwardly.
You should probably check out a tutorial/boilerplate. This one looks pretty good to me but there are plenty of resources out there.

Categories