Question- How do I point to my image inside the public folder from within a react class without using jsx?
FYI - The console shows the full 'string' path I give the img element with the appended filename with 'aData[6]'. For example, if I use "%PUBLIC_URL%" as shown below, it prints out that full string, unlike in the base html class where this is converted.
I know this isn't the best way to go about this, but I'm trying to re-use the existing code without re-writing it.
I have a react class that generates an 'expandable' table with an avatar image included. In order for the image to be properly loaded, the table has an 'init' method to write out all the proper tags, etc. I'm not sure how to go about telling react where the image is. In my base index.html class, I used '%PUBLIC_URL%' to point at the public folder, but here I'm inside an active react class so not sure about it. The images will be dynamic moving forward so importing them directly won't work even if I was using JSX to generate this table.
I'm trying to avoid re-writing this particular class and it's methods, just trying to port them over to my react project structure.
Here's the code:
import React, { Component } from 'react'
import $ from 'jquery'
import datatables from 'datatables.net'
import { Link } from 'react-router-dom'
class EmployeeTablev2 extends Component {
constructor(props) {
super(props)
this.init = this.init.bind(this)
}
componentDidMount() {
this.init()
}
init() {
/* Formatting function for row details */
function fnFormatDetails(oTable, nTr) {
var aData = oTable.fnGetData(nTr);
var sOut = '<table>';
sOut += '<tr><td rowspan="5" style="padding:0 10px 0 0;"><img src="/assets/img/avatars/' + aData[6] + '"/></td><td>Name:</td><td>' + aData[1] + '</td></tr>'
sOut += '<tr><td>Age: </td><td>' + aData[3] + '</td></tr>'
sOut += '<tr><td>Address: </td><td>' + aData[2] + '</td></tr>'
sOut += '<tr><td>Position: </td><td>' + aData[4] + '</td></tr>'
sOut += '<tr><td>Others: </td><td><a href="">Something here</a></td></tr>'
sOut += '</table>'
return sOut
}
/*
* Insert a 'details' column to the table
*/
var nCloneTh = document.createElement('th');
var nCloneTd = document.createElement('td');
nCloneTd.innerHTML = '<i class="fa fa-plus-square-o row-details"></i>';
$('#expandabledatatable thead tr').each(function() {
this.insertBefore(nCloneTh, this.childNodes[0]);
});
$('#expandabledatatable tbody tr').each(function() {
this.insertBefore(nCloneTd.cloneNode(true), this.childNodes[0]);
});
/*
* Initialize DataTables, with no sorting on the 'details' column
*/
var oTable = $('#expandabledatatable').dataTable({
"sDom": "Tflt<'row DTTTFooter'<'col-sm-6'i><'col-sm-6'p>>",
"aoColumnDefs": [
{ "bSortable": false, "aTargets": [0] },
{ "bVisible": false, "aTargets": [6] }
],
"aaSorting": [[1, 'asc']],
"aLengthMenu": [
[5, 15, 20, -1],
[5, 15, 20, "All"]
],
"iDisplayLength": 5,
"oTableTools": {
"aButtons": [
"copy",
"print",
{
"sExtends": "collection",
"sButtonText": "Save <i class=\"fa fa-angle-down\"></i>",
"aButtons": ["csv", "xls", "pdf"]
}
],
"sSwfPath": "assets/swf/copy_csv_xls_pdf.swf"
},
"language": {
"search": "",
"sLengthMenu": "_MENU_",
"oPaginate": {
"sPrevious": "Prev",
"sNext": "Next"
}
}
})
$('#expandabledatatable').on('click', ' tbody td .row-details', function() {
var nTr = $(this).parents('tr')[0];
if (oTable.fnIsOpen(nTr)) {
/* This row is already open - close it */
$(this).addClass("fa-plus-square-o").removeClass("fa-minus-square-o");
oTable.fnClose(nTr);
} else {
/* Open this row */
$(this).addClass("fa-minus-square-o").removeClass("fa-plus-square-o");;
oTable.fnOpen(nTr, fnFormatDetails(oTable, nTr), 'details');
}
})
$('#expandabledatatable_column_toggler input[type="checkbox"]').change(function() {
var iCol = parseInt($(this).attr("data-column"));
var bVis = oTable.fnSettings().aoColumns[iCol].bVisible;
oTable.fnSetColumnVis(iCol, (bVis ? false : true));
})
$('body').on('click', '.dropdown-menu.hold-on-click', function(e) {
e.stopPropagation();
})
}
eachEmployee(employee, i) {
return (
<tr key={employee.id}>
<td data-value={employee.id}>
{employee.name}
</td>
<td data-value={employee.id}>
{employee.address}
</td>
<td data-value={employee.id}>
{employee.age}
</td>
<td>
{employee.position}
</td>
<td>
<div>
<Link to={`/employee/${employee.id}`} className="btn btn-default">
View
</Link>
</div>
</td>
<td>
{employee.pic}
</td>
</tr>
)
}
render() {
return (
<div className="row">
<div className="col-xs-12 col-md-12">
<div className="widget">
<div className="widget-header ">
<span className="widget-caption">Expandable DataTable</span>
<div className="widget-buttons">
<a href="#" data-toggle="maximize">
<i className="fa fa-expand"></i>
</a>
<a href="#" data-toggle="collapse">
<i className="fa fa-minus"></i>
</a>
<a href="#" data-toggle="dispose">
<i className="fa fa-times"></i>
</a>
</div>
</div>
<div className="widget-body">
<table className="table table-striped table-bordered table-hover" id="expandabledatatable">
<thead>
<tr>
<th>
Name
</th>
<th>
Address
</th>
<th>
Age
</th>
<th>
Position
</th>
<th>
View
</th>
<th>Picture</th>
</tr>
</thead>
<tbody>
{this.props.employees.map(this.eachEmployee)}
</tbody>
</table>
</div>
</div>
</div>
</div>
)
}
}
export default EmployeeTablev2
So inside this init method, there's a method named 'fnFormatDetails, which pulls the data from the table and creates an inner table that will display it when the table row is 'expanded'. Included is a picture in the 6th position. Any help is appreciated, but as I stated, just trying to figure out how to load the image in this way without having to re-write to use jsx.
Thanks