Advertisement
Guest User

Untitled

a guest
Oct 15th, 2019
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.65 KB | None | 0 0
  1. import React, {Component, PropTypes} from 'react';
  2.  
  3. import Head from './TableComponents/Head';
  4. import Pagination from './TableComponents/Pagination';
  5. import Row from './TableComponents/Row';
  6. import SearchComponent from './TableComponents/SearchComponent';
  7.  
  8. export default class SimpleTable extends Component {
  9. constructor(props){
  10. super(props);
  11. this.state = {
  12. children: this._setChildren(),
  13. // just loaded, not set
  14. current_sort: undefined,
  15. // the array to tabulate
  16. data: props.data,
  17. // ascending at load
  18. descending: false,
  19. // is there pagination?
  20. pagination: props.pagination,
  21. // we just loaded the page so it's 1
  22. pagination_current_page: props.current_page || 1,
  23. // number of row to show (only matters if pagination.) Defaults to 25.
  24. pagination_items: props.pagination_items || 25,
  25. // the index of the first item to show (pagination only)
  26. pagination_range_low: 0,
  27. // the last index to show based on pagination preferences
  28. pagination_range_high: props.pagination_items ? props.pagination_items - 1 : 25,
  29. // value for the placeholder
  30. placeholder: props.placeholder || '',
  31. presearch_data: undefined,
  32. // the schema to read from
  33. schema: props.schema,
  34. // will there be a search function
  35. search: false,
  36. total_length: props.data.length
  37. }
  38. }
  39.  
  40. componentWillReceiveProps(nextProps){
  41. const {data, presearch_data} = this.state;
  42. nextProps.data !== data
  43. ? this._changeCurrentPage(1)
  44. : null
  45.  
  46. this.setState({
  47. children: this._setChildren(),
  48. data: nextProps.data,
  49. pagination: nextProps.pagination,
  50. pagination_items: nextProps.pagination_items || 25,
  51. // if presearch_data hasn't been populated, populate. Else, do not touch.
  52. presearch_data: !presearch_data || presearch_data.length === 0 || (data !== nextProps.data) ? nextProps.data : presearch_data,
  53. schema: nextProps.schema,
  54. search: nextProps.search,
  55. total_length: nextProps.data.length
  56. })
  57. }
  58.  
  59. // 'no' is the page number that was sent from pagination
  60. _changeCurrentPage(no){
  61. // how many to show at a time
  62. const {pagination_items} = this.state;
  63. // first to show based on which page. subtract one because indices start at zero
  64. const pagination_range_low = pagination_items * (no - 1);
  65. // show x number past the first one
  66. const pagination_range_high = (pagination_range_low + pagination_items - 1 );
  67. this.setState({
  68. pagination_current_page: no,
  69. pagination_range_low,
  70. pagination_range_high
  71. })
  72. }
  73.  
  74. _setChildren(){
  75. // React returns one child as an obj, multiple as an array. It always needs to be an array
  76. const {children} = this.props;
  77. if (children && !Array.isArray(children)) {
  78. return [children]
  79. } else {
  80. return children
  81. }
  82. }
  83.  
  84. _setSort(key){
  85. let data = this.state.data;
  86. //if we're already sorting by this key and user clicked that header cell again, we're changing the sort order
  87. const descending = this.state.sort_by === key && !this.state.descending;
  88.  
  89. // sort by the key. if the values a number, do nothing. If it's a string, equalize with lowercase
  90. const new_data = data.sort(function (a, b) {
  91. var key_a = isNaN(a[key]) ? a[key].toLowerCase() : a[key];
  92. var key_b = isNaN(b[key]) ? b[key].toLowerCase() : b[key];
  93. if (descending){
  94. if (key_a < key_b) return -1;
  95. if (key_a > key_b) return 1;
  96. return 0;
  97. } else {
  98. if (key_a > key_b) return -1;
  99. if (key_a < key_b) return 1;
  100. return 0;
  101. }
  102. });
  103.  
  104. //data equals the sorted data, sort-by key and order
  105. this.setState({
  106. data: new_data,
  107. sort_by: key,
  108. descending: descending,
  109. });
  110. }
  111.  
  112. _updateData(data){
  113. const {pagination_items} = this.state;
  114. this.setState({
  115. data,
  116. pagination_current_page: 1,
  117. pagination_range_low: 0,
  118. // the last index to show based on pagination preferences
  119. pagination_range_high: pagination_items ? pagination_items - 1 : 25,
  120. total_length: data.length,
  121. })
  122. }
  123.  
  124.  
  125. render(){
  126. const {data, pagination, search} = this.state;
  127. return(
  128. <div className="simple-table">
  129. {search && this._renderSearch()}
  130. <table>
  131. {this._renderCols()}
  132. {this._renderHead()}
  133. {this._renderRows()}
  134. </table>
  135. {
  136. pagination && data.length > 0
  137. && this._renderPagination()
  138. }
  139. </div>
  140. )
  141. }
  142.  
  143. _renderCols(){
  144. const {schema} = this.state;
  145. // set a class in the schema if you need to do something fancy, otherwise set the width if it's provided
  146. return (
  147. <colgroup>
  148. {
  149. schema.map(item =>{
  150. const colclass = item.class || '';
  151. const colwidth = item.width ? {width: `${item.width}%`} : {};
  152. return <col className={colclass} style={colwidth}></col>
  153. })
  154. }
  155. </colgroup>
  156. )
  157. }
  158.  
  159. _renderHead(){
  160. // needs to know whether we're sorting descending, the schema, the sort function for click event, and which row
  161. //we're sorting by
  162. const {descending, schema, sort_by} = this.state;
  163. return (
  164. <Head
  165. descending={descending}
  166. schema={schema}
  167. set_sort={this._setSort.bind(this)}
  168. sort_by={sort_by}
  169. />
  170. )
  171. }
  172.  
  173. _renderPagination(){
  174. // these are discussed in the constructor
  175. const {
  176. pagination_current_page,
  177. pagination_items,
  178. pagination_range_low,
  179. pagination_range_high,
  180. total_length
  181. } = this.state;
  182. return (
  183. <Pagination
  184. current = {pagination_current_page}
  185. items = {pagination_items}
  186. range_low = {pagination_range_low}
  187. range_high = {pagination_range_high}
  188. SetPage = {this._changeCurrentPage.bind(this)}
  189. total_length = {total_length}
  190. />
  191. )
  192. }
  193.  
  194. _renderRows(){
  195. const {children, data, pagination, pagination_range_low, pagination_range_high, schema} = this.state;
  196. // if the row falls between the index ranges that we're showing, render it.
  197. return (
  198. <tbody>
  199. {
  200. data.map((row,idx) => {
  201. if ( (pagination && idx >= pagination_range_low && idx <= pagination_range_high) || !pagination ) {
  202. return <Row
  203. {...this.props}
  204. children={children}
  205. index={idx}
  206. row_data={row}
  207. schema={schema}
  208. />
  209. }
  210. })
  211. }
  212. </tbody>
  213. )
  214. }
  215.  
  216. _renderSearch(){
  217. const {data, placeholder, presearch_data, schema} = this.state;
  218. return (
  219. <SearchComponent placeholder={placeholder} data={data} presearch_data={presearch_data} schema={schema} updateData={this._updateData.bind(this)} />
  220. )
  221. }
  222. }
  223.  
  224. SimpleTable.propTypes = {
  225. current_sort: PropTypes.string,
  226. data: PropTypes.array,
  227. descending: PropTypes.bool,
  228. pagination: PropTypes.bool,
  229. pagination_current_page: PropTypes.number,
  230. pagination_items: PropTypes.number,
  231. pagination_range_low: PropTypes.number,
  232. pagination_range_high: PropTypes.number,
  233. placeholder: PropTypes.string,
  234. presearch_data: PropTypes.array,
  235. schema: PropTypes.array,
  236. search: PropTypes.bool,
  237. total_length: PropTypes.number
  238. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement