18

i have the following component with datatables:

import React, { Component } from 'react'
import { Link } from 'react-router'


import { PanelContainer, Panel, PanelBody, Grid, Row, Col } from '@sketchpixy/rubix'

import $ from 'jquery'
import DataTable from 'datatables.net'

$.DataTable = DataTable

const columns = [{
  title: '<input type="checkbox" />',
  data: 'check',
}, {
  title: 'Foto',
  data: 'avatar',
}, {
  title: 'Nombre',
  data: 'name',
}, {
  title: 'Dirección',
  data: 'address',
}, {
  title: 'Clasificación',
  data: 'clasification',
}, {
  title: 'Editar',
  data: 'editLink',
  render: x => `<a href="${x}"><i class="icon-fontello-edit"></i></a>`, // <-- this line i'm interested!
}]

class Table extends Component {
  transform(content) {
    return content.map(x => ({
      ...x,
      check: '<input type="checkbox" />',
      avatar: '<img src="/public/imgs/app/nico.jpg" width="40" height="40" style="border-radius: 100%;">',
      clasification: `<i class="${x.clasification.icon}"></i> ${x.clasification.name}`,
    }))
  }

  componentDidMount(nextProps, nextState) {
    this.table = $(this.refs.main).DataTable({
      dom: '<"data-table-wrapper"tip>',
      data: [],
      columns,
      language: {
        info: 'Mostrando _START_-_END_ de _TOTAL_ puntos',
        infoEmpty: 'No hay puntos',
        paginate: {
          next: 'Siguiente',
          previous: 'Anterior',
        },
      },
    })
  }

  componentWillUpdate() {
    this.table.clear()
    this.table.rows.add(this.transform(this.props.data))
    this.table.draw()
  }

  componentWillUnmount() {
    $('.data-table-wrapper')
    .find('table')
    .DataTable()
    .destroy(true)
  }

  render() {
    return (
        <table
          className="table table-striped hover"
          cellSpacing="0"
          width="100%"
          ref="main"
        />
    )
  }
}

export default p =>
  <PanelContainer>
    <Panel>
      <PanelBody>
        <Grid>
          <Row>
            <Col xs={12}>
              <Table data={p.data} />

            </Col>
          </Row>
        </Grid>
      </PanelBody>
    </Panel>
  </PanelContainer>

The problem is that, with datatables, i need to render a Link with react router, using an anchorlink () is not a solution because it will re-render the whole page. So i need to render a custom component in the column with the specified link. The link is constructed with the ID.

4
  • Up!, in need of an answer :) Commented May 22, 2017 at 14:55
  • Been struggling with this for a while. Were you able to find an answer? Commented May 24, 2017 at 10:44
  • I have same issue with an oppened question for more than two weeks and anybody answer it. :( Commented May 24, 2017 at 10:48
  • 1
    I will post it here. If anyone knows answer, please, help me too. After a log time struggling with this, I have no resolve. stackoverflow.com/questions/43927638/… Commented May 24, 2017 at 10:50

3 Answers 3

21
+25

I will answer my own question for other developers. What i did is the following:

columnDefs: [{
  targets: 5,
  createdCell: (td, cellData, rowData, row, col) =>
    ReactDOM.render(
      <a style={{ cursor: 'pointer' }}
        onClick={() => this.props.goto(cellData) }>
        <i className="icon-fontello-edit"></i>
      </a>, td),
} // ... the rest of the code

The createdCell method receives the actual dom element, so you can render the react component directly there, the only problem is that you cannot render Links, that is because the router needs a context and that context is lost. So the best way is to use a method to go to the specific route, which in this case goto is this.props.router.push passed from the parent.

Sign up to request clarification or add additional context in comments.

4 Comments

but.. there you are rendering an a, not an Link of react router, right? . Could you put an example more extended? Or pass here, and answer me, please? stackoverflow.com/questions/43927638/… . Thank you.
Link will not work because it needs a context, thats why you need to add an onClick event to handle the routing.
to handle routing easy and without using <Link/> tag, using react router 4+, you can redirect to others page like that: this.props.history.push({ pathname: '/your_path', state: { id: some_value } }); refer to this for details: stackoverflow.com/a/31079244/960326
@Nico Could you please look into this, not very similar but I am stuck here, and in need a answer: stackoverflow.com/questions/53945879/… . Thank you.
1

Maybe you could utilize ReactDOM.render. The function takes in a component and a container, so you could initialize your links as empty nodes with your props as data-types. Then in componentDidMount, you could loop through and call a function that looks like this: edit: the Link component requires the react context to navigate around implicitly and I don't think reactDOM.render reconciles your context object with the one that it creates. Best bet would be to create a custom link component to use here that uses the browserHistory(react-router v3) or just history library to navigate.

componentDidMount() {
 function populateLinks(node) {
   const linkURL = node.dataset.linkURL;
   reactDOM.render(<Link to={linkURL}>Hello</Link>, node);
  }
$('.link-div').get().forEach(populateLinks);
}

It looks like you would specify a specific dom node to render with something like this:

$('#example').dataTable( {
  "columnDefs": [ {
    "targets": 0,
    "data": "download_link",
    "render": function ( data, type, full, meta ) {
      return `<div class="link-div" data-linkURL=${data}></div>`;
    }
  } ]
} );

Let me know how it goes!

9 Comments

I have tried it but it is not working. I import ReactDOM too: import ReactDOM from 'react-dom'; but I get error ReactDom is not defined
Warning: Failed prop type: The prop to is marked as required in Link, but its value is undefined. in Link ------ This is due to is not recognoised href prop
Warning: Failed context type: The context router is marked as required in Link, but its value is undefined. in Link ------ I do not know why is it
Uncaught TypeError: Cannot read property 'history' of undefined --- Neither this
4.1.1. Lastest. Also I add that on your render ReactDOM.render(<Link to={linkURL}>HELLO</Link>, node); due to link has a name
|
1

use ReactDOMServer to render as string

import ReactDOMServer from 'react-dom/server';
const [select, setSelect] = useState(false);

    render: (data) => ReactDOMServer.renderToString(<input type="checkbox" checked={select} />)

1 Comment

Be careful with this one as it will only load the component without registering any event listener. So any onClick event won't fire.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.