
HISTORY:

- 2017-03-13, MG, Inicijalni dokument

# Pagination component

Treba se odlučiti za jedan od predloženih layouta:

```
<Input control> <Prev btn> <Next btn> 
```

`<Input control>` sadrži text editabilni begin - end / count text napr. 91-101/218
`<Prev btn>` i `<Next btn>` kontrole za paging na previous i next stranicu.


[Primjer 1](https://bitbucket.org/sedmiodjel/espa-ui/downloads/Pagination.png)

Pagination je kontrolirani input. 
Consumer must pass back props received in onChange handler:

```javascript
class PaginationParent extends React.Component {
  state = { begin:1, end:10, limit:10, count:100};

  onPaginationChange = (next) => {
    let {begin, end, count, limit} = {...next};
    this.setState({ begin, end, count, limit });
    console.log(this.state);
  }

  render() {
    let {begin, end, limit, count} = this.state;
    return (<Pagination begin={begin} end={end} count={count} limit={limit} onChange={this.onPaginationChange} />);
  }
}
```

Na dnu stranice je implementacija koja najbolje objašnjava funkcionalnost
Pagination kontrole.


## Props proposal

`begin`: `PropTypes.number.isRequired`, first record to display.

`end`: `PropTypes.number.isRequired`, last record to display.

User može mijenjati `begin` i `end` kroz input kontrolu. To znači, ako je unešeni 
input izvan granica ili besmislen, Pagination kontrola treba korigirati input value.

`limit`: `PropTypes.number.isRequired`, max. number of records to display

`count`: `PropTypes.number.isRequired`, total number of records

`onChange`: `PropTypes.func.isRequired`, callback when user click Prev, Next or
changes range in editbox.

`size`: (small | medium ): Small for mini headers in (MD i MMD views).

## Primjer implementacije


```javascript
class Pager extends Component {
  static propTypes = {
    begin: PropTypes.number.isRequired,
    end: PropTypes.number.isRequired,
    limit: PropTypes.number.isRequired,
    count: PropTypes.number.isRequired,
    onChange: PropTypes.func.isRequired,
  };

  static defaultProps = {
    begin: 1,
    limit: 10,
    end: 10,
    count: 1,
  };

  constructor(props) {
    super(props);
    let inputValue = props.end === props.begin ? `${props.begin} `
      : `${props.begin} - ${props.end} `;
    this.state = { inputValue };
  }

  componentWillReceiveProps(nextProps) {
    let inputValue = nextProps.end === nextProps.begin ? `${nextProps.begin} `
      : `${nextProps.begin} - ${nextProps.end} `;
    this.setState({ inputValue });
  }

  // this calculates begin and end after user edit and calls onChange callback
  calculate = (inputValue) => {
    let end = null, begin = null, limit;
    let result = /(\D*)(\d+)(\D+)(\d+)/.exec(inputValue);
    if (result) {
      begin = parseInt(result[2], 10);
      end = parseInt(result[4], 10);
    } else {
      let result = /(\D*)(\d+)/.exec(inputValue);
      if (result) {
        begin = end = parseInt(result[2], 10);
      }
      else
        return false;
    }
    if (begin < 1) begin = 1;
    if (end > this.props.count) end = this.props.count;
    if (begin > this.props.count) {
      begin = this.props.count;
      end = begin;
    }
    if (end <= begin) {
      end = begin;
      limit = 1;
    } else {
      limit = end - begin + 1;
    }
    let next = { begin, end, count: this.props.count, limit };
    this.props.onChange(next);
  }

  onBlur = (e) => this.calculate(e.target.value);

  onKeyUp = (e) => {
    if (e.keyCode !== 13) return;
    document.activeElement.blur();
  }

  onInputChange = (e) => this.setState({ inputValue: e.target.value });

  // prev button clicked
  onPrev = () => {
    if (this.props.begin === 1) return;
    let begin = Math.max(1, this.props.begin - this.props.limit);
    let end = Math.max(1, this.props.begin - 1);
    let next = { begin, end, limit: this.props.limit, count: this.props.count };
    this.props.onChange(next);
  }

  // next button clicked
  onNext = () => {
    if (this.props.end === this.props.count) return;
    let begin = Math.min(this.props.end + 1, this.props.count);
    let end = Math.min(this.props.end + this.props.limit, this.props.count);
    let next = { begin, end, limit: this.props.limit, count: this.props.count };
    console.log(begin, end);
    this.props.onChange(next);
  }

  render() {
    const { count } = this.props;
    const labelText = ` / ${count}`;
    return (
      <div className="pager_container">
        <div className="pager">
          <Input
            label={{ basic: true, content: labelText }} labelPosition='right'
            value={this.state.inputValue}
            onChange={(e) => { this.setState({ inputValue: e.target.value }) }}
            onKeyUp={this.onKeyUp} onBlur={this.onBlur}
          />
          <Button.Group >
            <Button basic icon='left chevron' onClick={this.onPrev} />
            <Button basic icon='right chevron' onClick={this.onNext} />
          </Button.Group>
        </div>
      </div>
    );
  }
}

export default Pager;

```

