SPFx with REACT.js - Render table with variable number of TD - javascript

I am currently working on refactoring my existing javascript into a SharePoint Framework solution with REACT. I got most parts working but I am stumped on the Render function to return html contents for a table with a variable number of columns. The number of columns is set from a web part property. How can I convert the original javascript (below) into REACT code?
var html = "<table>";
for (var i = 0; i < data.d.results.length; i++) //data is from AJAX SP REST query
{
if ((i % tdWidth) == 0 ) { html += "<tr>"; } //if this is the first column in the row
html += "<td><div>" + data.d.results[i] + "</div></td>";
if ((i % tdWidth) == (tdWidth - 1) ) { html += "</tr>"; } //if this is the last column in the row
}
html += "</table>";
$("#tableContainerDiv").html(html); //Set the html tag of the container div

You have to create your own component to use. Check the below link.
http://buildwithreact.com/tutorial/components
OR
best thing in react is reuse the ready made component. instead of making the html from js try to use the react-super-responsive-table.
https://www.npmjs.com/package/react-super-responsive-table
You can easily loop through rows and count with headers. I hope it may help you.
OR
Another approach is to set the response into array i.e. data.d.results put in array and render your control inside the render method.
MyrenderItems = this.state.UserArray.map(function (item, i) {
.....
}

Related

Get id from foreach loop javascript

After looping the delete button, I've been trying to get the id so that I can use it with the onclick function but no luck yet.
var table = "";
res.data.forEach((value, key) => {
table += "<tr>";
table += "<td>"+value.post_held+"</td>";
table += "<td>"+value.established_officer+"</td>";
table += "<td>"+value.date_of_commencement+"</td>";
table += "<td>"+value.date_of_termination+"</td>";
table += "<td><button id=career"+value.id+" class='btn btn-danger'>Delete</button></td>";
table += "</tr>";
var career = document.querySelector("#career"+value.id);
career.addEventListener("click",()=>{
alert("done")
})
});
I think maybe you forgot to add table to DOM.
You just create a string value which contain html code, but you didn't add this html code into the DOM, so you can not find this DOM element by id.
You can use insertAdjacentHTML method to add this element which you want to DOM

Making a dynamic html table on basis of php response to ajax request

I have page which send request to a php for getting some data and in response to that request of php returns me something like this:-
[{"postID":"1","0":"1","userID":"3","1":"3","imagePath":"images\/31481440272.jpg","2":"images\/3-1481440272.jpg","postDate":"11 December 2016","3":"11 December 2016","postDescription":"trying","4":":D trying"}]
What I want is to make a dynamic html table inside a specific div
<div id="dataWillBeShownHere"></div>
What will I do if records will be more than 1.Should I use for each loop for more than one record.
I am really confused in this thing. Somehow I know the solution but cannot implement.
I hope you have understand my question.
You can do this with simple javascript and html:
<script type="text/javascript">
var records = [];
// This data could be retrieved from an ajax $.post
var data = {"postID":"1","0":"1","userID":"3","1":"3","imagePath":"images\/31481440272.jpg","2":"images\/3-1481440272.jpg","postDate":"11 December 2016","3":"11 December 2016","postDescription":"trying","4":":D trying"};
// Add our data to the records array
records.push(data);
// Get how many record we have
var record_count = records.length;
// Parse data to html tables
for (var i = records.length - 1; i >= 0; i--) {
var html = "";
// make your html additions here
html += "<div> ID: " + records[i]["postID"] + "</div>";
html += "<div> Date: " + records[i]["postDate"] + "</div>";
// html += ;
// html += ;
// Now use jquery selector to write to the div
$('#data-table').html(html);
};
</script>
<div id="data-table"></div>
Check my JSFiddle

Return every value in spreadsheet to web app table

What I'm trying to do:
Get every value from a spreadsheet (6 columns, ~10+ rows)
I can get the values. I will probably get each column individually with .getRange(row, column, sheet.getLastRow() - 1, 1).getValues();. Or I could get every single value with .getDataRange().getValues() and then put them in the table that way?
Or would it be better to just use a for loop? -- example at very bottom
Return those values [as Templated HTML?] surrounded by <table>, <tr>, <th>, <td> code -- example below
Display the table with the values on a web app when a name gets
clicked
Can the inserted <table> code start as style="display: none;", and then when the name gets clicked, have the table show? Or have it in a div that is invisible then visible once clicked?
Example of table:
<table>
<tr>
<th>header1</th>
<th>header2</th>
<th>header3</th>
<th>header4</th>
<th>header5</th>
<th>header6</th>
</tr>
<tr>
<td>value1</td>
<td>value2</td>
<td>value3</td>
<td>value4</td>
<td>value5</td>
<td>value6</td>
</tr>
//etc
</table>
I dont know if what I'm trying to do counts as Templated HTML or not, or if it would be better to do this using Templated Html...
The big thing I need help with is returning every value in a table and displaying it on the web app.
Example of for loop
If I do a for loop and return every value in a column or a row
column1[i]
column2[i]
etc
or
row1[i]
row2[i]
etc
How would I return those values as a table?
Would it be something like:
var x = "<tr>";
var y = row1[i];
var z = "</tr>";
return x + y + z
If so, how would I make a whole table out of all the row/column values?
Also, how would I style the table with css once it's fully built? I'm assuming I can still add an id to the table and style it from there.
I don't know the exact number of rows there will be in the spreadsheet, so making this dynamic would be best -- probably getting all the rows instead of columns and using a for loop for each row?
Any help would be appreciated. Thanks.
If I wanted to add another column to the table (not in the spreadsheet), how would I go about doing that? I'm trying to add an add row button to the header row, and a delete row button on the end of every row of table data.
Also, I know that you can set the <td> to <td contenteditable='true'>... but, how would I have it where the data is only editable on a newly added row AND the table cell cant be edited once a value is submitted? -- Would I need an event listener or some trigger that sees when a value is inputted and triggers that cell to contenteditable='false'?
Thanks again.
You can use a nested for loop.
var range = SpreadsheetApp.getActiveSpreadsheet().getDataRange().getValues();
var isHeader = true;
var html = "<table>\n";
for (var i = 0; i < range.length; i++) {
html += "<tr>\n";
for (var j = 0; j < range[i].length; j++) {
if (isHeader) {
html += "<th>" + range[i][j] + "</th>\n";
}
else {
html += "<td>" + range[i][j] + "</td>\n";
}
}
isHeader = false;
html += "</tr>\n";
}
html += "</table>";

How to render custom html in bootstrapTable but when using sidePagination and url?

I am using https://github.com/wenzhixin/bootstrap-table on some project.
I find that is really easy to use and implement pagination. However I have some problem regarding custom html in different rows. This is just peace of code.
$('#selector').bootstrapTable({
pagination: true,
url : some_rest_url,
sidePagination: 'server',
onLoadSuccess: function (res) {
var data_ = [];
var rows = res.rows;
for (var i =0; i < rows.length; i ++) {
var data = {};
var item = rows[i];
$.each(item, function (key, value) {
if (key == "cost") value = "< span class="cl" >"currency + " " + parseFloat(value).formatNumber(2, '.', ',')."< / span >";
//and so on some more styling and formatting for other elements/columns of table
data[key] = value;
});
data_.push(data);
}
$('#selector').bootstrapTable("load", data_);
So table should have one column and in each row span element with that class but that is not happening.
I just have that default plain text data from boostrapTable default load (json data).
BTW when using plain ajax call instead of that default boostrapTable pagination thingy everything works great but then i have to make custom pagination (and using sidePagination = client is just wrong and working slow when have like 1000 records ).
After wasting couple of hours, solution was to use formatter for columns. For example:
field: 'column_name',
formatter: operateFormatter
function operateFormatter(value, row, index){
//value is text from json
//row is all values from json for that row
}
well this way, code will be much more clearer.

Show/Hide Multiple DIVs in a variable

I am using nested for loops to generate multiple instances of a table with details of projects; under which I wish to have a show/hide button that will give a short description of each project at a high level.
I am tring to manipulate code I found here: https://forums.digitalpoint.com/threads/javascript-to-show-hide-tables.1009918/
The following code produces a "Show/Hide" link that does not work on my page (see screenshot). Am I missing something?
FYI - "Separate" in the code below is an array containing unique project references to facilitate the separation of the tables per project. So where Separate contains 4 elements, there should be 4 projects, 4 tables, and so on.
Many Thanks,
Karl
function showhide(id){
if (document.getElementById){
obj = document.getElementById(id);
if (obj.style.display == "none"){
obj.style.display = "";
} else {
obj.style.display = "none";
}
}
}
for(i in Separate){
DescID[i] = "DescID"+i;}
var Table = "";
for(i in Separate){
Table += "<table id='dashboard' summary='Project Dashboard'>";
Table += "<THEAD>";
Table += "<TR><TH scope='col' colspan=4><B>"+ Separate[i] +"</B></TH></TR>";
Table += "<TR><TH scope='col'>Task Names</TH><TH scope='col'>Task Summary</TH><TH scope='col'>RAG</TH><TH scope='col'>Timeline</TH></TR></THEAD>";
Table += "</THEAD>";
Table += "<TBODY>";
for(j in Project){
if(Project[j] == Separate[i]){
Table += "<TR><TD title='" + Comments[j] + "'>"+ Task[j] +"</TD><TD>"+ Summary[j] +"</TD><TD><img src='/images/RAG/" + RAG[j] + "'></TD><TD>"+ DateType[j] +" "+ Status[j].substring(0,10) +"</TD></TR>";
}
}
Table += "</TBODY>";
Table += "</table>";
Table += "<a onclick ='javascript:ShowHide('" + DescID[i] + "')' href='javascript:;' >Show/Hide Project Description</a>";
Table += "<div class='mid' id='" + DescID[i] + "' style='DISPLAY: none' >Placeholder for Project Description</div>";
Table += "<BR>";
}
You're missing the fact that HTML tag "id"s (e.g., for your Projects' tables) should be unique, otherwise "getElementById" won't work. Now they're all set to "dashboard". At the very least you could add the index, and make them "dashboard1", "dashboard2", etc...
Also, IIRC, a better opposite for 'display = "none";' is 'display = "inline";', instead of 'display = "";'. Although this needs more testing on different browsers to select the best option.
Thirdly, your JavaScript call within the onclick events use single quotes BOTH for the attribute value definition (surrounding the JS call) and for the string parameter (the id to show/hide)... That's not valid syntax, and you need one of these two use-cases to be double-quotes.
And the other main problem your code has is as mikez302 already spotted: "Javascript function names are case-sensitive. Your function is called showhide but you are trying to call ShowHide." Correcting these two issues (the quotes and the function name) will allow the code to work, i've just tested it. :)

Categories

Resources