I have a table in ReactJS that is displaying data from a database using the map function. It works like so:
displayData(){
return this.state.legoParts.map((legoPart) => (
<tr key={legoPart.id} onClick={() => this.showForm(legoPart)}>
<td>
{legoPart.piece}
</td>
<td>
{legoPart.type}
</td>
</tr>
)
)
}
However I want a form, using the same data as the table row, to appear when the row is clicked so that I can then use the form to update the data. I honestly have no idea how to go about this- I'm not sure if I should put the form in the table and have it display when clicked or something else. Any help would be appreciated!
You'll need your app state to keep track of the part you're editing, and while you are rendering the table, decide whether to render a table row or the form based on that app state. I've put an example here: https://codesandbox.io/s/624p7zpzww
Related
New react developer here, here i have antd table with filtering system.
My question is like this: if there is much data in the table so that there are for example page 1 page 2 page 3(with these i mean )
for example if you click page 3 (in table) and above are filtering buttons and you click one of those buttons and scroll down, you can see it is still at page 3, how to make it so when button is clicked it should always go automatically to page 1. my code:
https://codesandbox.io/s/dreamy-surf-t9eh3?file=/src/Test.js
english is not my mother language so there could be mistakes
From Table docs https://ant.design/components/table/ you can pass pagination props to your table. This means that you can pass on onChange and current to pagination element in order to reset pagination page when filtering.
Here is an example of how to manage pages using state:
const [paginationPage, setPaginationPage] = useState(1);
return (
<Table
pagination={{
current: paginationPage,
onChange: (pageNum) => setPaginationPage(pageNum)
}}
dataSource={filteredEventsData}
columns={tableColumns}
/>
)
You can now reset the current page anywhere with:
setPaginationPage(youPageNumber);
https://codesandbox.io/s/nervous-banach-d7ff2?file=/src/Test.js
I am new to the react Js as well front end. Here, I have a table which is like
<div className="col-xs-12 " id="scrollableTable">
<Table striped condensed hover id="jobData">
<thead style={backgrounColour}>
<tr>
<th className='serial-column'>Sr.No.</th>
<th className='company-column'>Company Name</th>
<th className='technology-column'>Technology</th>
<th className='job-column'>Job Title</th>
<th className='total-score-column'>Total Score</th>
<th className='average-score-column'>Average Score</th>
</tr>
</thead>
<tbody>{this.props.jobData.map(function (item, key) {
return (
<tr key={key}>
<td><b style={compName}>{item.id}</b></td>
<td><b style={compName}>{item.attributes.companyName}</b></td>
<td>Xamarian Developer</td>
<td>{item.attributes.name}</td>
<td><b style={compName}>30</b></td>
<td><b style={compName}>30</b></td>
</tr>
)
})}</tbody>
</Table>
</div>
I do have one button which is like
<button className = "btn btn-default">Add Row </button>
It looks like
Now, What I want to have is that on click of this button,
This should get added as a first row in this table.
Actually, I want to have an idea how can I do this? I tried by adding a static row in this but It did not work. So, I am asking this question.
Any help will be great for me.
FOR SINGLE EDITABLE ROW
Create separate component holding the row you would like to add, after clicking the button.
Add state property that will be used to define if your 'edition row' is visible.
It should have default state false (as it should not be visible at initial render)
this.state = {
isRowAddingEditorVisible: false
}
When "Add row" button is clicked, set state of that above property, to true
this.setState({ isRowAddingEditorVisible: true });
And in your component that holds whole table implement it like this:
<tbody>
{this.state.isRowAddingEditorVisible && <RowAddingEditor />} // <--- HERE
{this.props.jobData.map(function (item, key) {
return (
<JobTableRow key={key} data={item}>
)
})}
</tbody>
This way you dont need to modify original data that forms the table.
And JobTableRow would hold everything you have as row currently.
It provides better separation, readability and your closer to SRP (Single Responsibility Princple - code/method/component doing one thing only)
Check this fiddle to get the idea:
https://jsfiddle.net/n5u2wwjg/167786/
Also {this.state.isRowAddingEditorVisible && <RowAddingEditor />} - this is called short circuting.
Am using the fact that $booleanValue && <ReactComponent/> will evaluate to <ReactComponent> when $booleanValue is true and will evaluate to nothing (visually speaking) when $booleanValue is false
FOR MULTIPLE EDITABLE ROWS
https://jsfiddle.net/n5u2wwjg/173218/
Hint 1:
I used Math.random() to get unique IDs for rows. It is just simple, fast, example solution and in that form should not be used in production code.
Usually unique IDs generators are based on Math.random(), but randomized bit more with some additional code.
Hint 2:
Remember that when POSTing row to server, you also need to remove its ID from state.
Hint 3:
Usually when you have method starting with get and returning some DOM elements you use in render method, it is signal that contents of this method should be moved to separate React component.
Hint 4:
In above example I use ES6 syntax. Learn it if you don't know it yet, it's your friend :). Search "ES6 features tutorial".
spread operator - ...
arrow function - => (anonymous also - not stored anywhere or named)
First you have to keep the this.props.jobData in state, Then OnClick of the button you have to update this.state.jobData
add a field in item to identify if it's an editable row or non editable. Let's say isEditable
The code will be:
<tbody>{this.state.jobData.map(function (item, key) {
if (!item.isEditable) {
return (
<tr key={key}>
<td><b style={compName}>{item.id}</b></td>
<td><b style={compName}>{item.attributes.companyName}</b></td>
<td>Xamarian Developer</td>
<td>{item.attributes.name}</td>
<td><b style={compName}>30</b></td>
<td><b style={compName}>30</b></td>
</tr>
)
} else {
return (
//Add your editable row here
)
}
})}</tbody>
#azrahel gave right answer about first problem (modify table view), below I'm writing about how it should work later - action triggered from that 'mini form'.
In short - it's data driven. Update data, view will be updated.
this.props.jobData.map shows that rows are from this.props.jobData array. Add row means then add to array. There is one problem - you can't mutate props. Props are passed from parent component then you have to update data in parent. To handle this you should have addJob method in parent and pass this handler as prop (like jobData, read docs).
But ... probably this array is not a local data, was fetched from server. If you want to update this on server (push to DB, to be available to others) then yon need to post data to server (it will store it in DB). In simplest scenario post request will return new, updated array. Updated data, passed to component should render component with new array (with new row). It's up to you if 'editing row' should be still visible or not.
I'm currently using Nightwatch to do some automated tests, but CSS selectors were extremely complex and did not do the job for me. I've instead started to look at XPath to do the job however the table in question is fairly complex.
I want to be able to .click() a button within a td value, where that specific row in the table contains a specific value. The table looks like this:
Username Email Display Name Buttons to Click (1st one wanted)
test test#example test (1st button)(2nd button)
test2 test2#example test (1st button)(2nd button)
Each of these values are within a tr > td so being able to find it is proving difficult. This is my currently XPath:
.click('/table[#id="admin-user-list"]/tbody/tr[td = "test2"]/td/button')
The HTML tree looks like this:
<div id>
<div class>
<table class>
<tbody>
<tr>
<td data-bind>(username)
<td data-bind>(email)
<td data-bind>(display name)
<td button>
(1st button)
(2nd button)
</tr>
</tbody>
Each row has its own tr with those exact tds inside.
Some help would be appreciated :)
.click('//table[#id="admin-user-list"]/tbody/tr[./td[text()='test2']/td/button')
logic: //table[#id="admin-user-list"]/tbody/tr[./td[text()='test2']
- tr with td that has text
/td/button -button in that row
but actually this is not really good idea to do that, as you are searching for that value in each column. Better to use combination of columnName+value
Let's check on that table sample: https://www.w3schools.com/css/css_table.asp
We'll search for table data in column by name, for example table column = Country, data = UK
//*[#id='customers']//tr/td[count(//*[#id='customers']//th[text()='Country']/preceding-sibling::*)+1][text()='UK']
again, logic is simple:
general locator is:
//*[#id='customers']//tr/td - we are searching for table data
with parameters: [text()='UK'] and position = same, as in column name [count(column_position)]
How to get column position:
just get column with needed text:
//*[#id='customers']//th[text()='Country'] and count it's preceding siblings:
//*[#id='customers']//th[text()='Country']/preceding-sibling::* , also we should add +1 , as we need current element's position. and count that staff, so here is the result: [count(//*[#id='customers']//th[text()='Country']/preceding-sibling::*)+1]
so having column position we can get general locator:
tableId = customers; columnName= Country; dataText = UK;
//*[#id='tableId']//tr/td[count(//*[#id='tableId']//th[text()='columnName']/preceding-sibling::*)+1][text()='dataText']
And here is locator to get hole row by data+columnName
//*[#id='customers']//tr[./td[count(//*[#id='customers']//th[text()='Country']/preceding-sibling::*)+1][text()='UK']]
and basically you can search anything inside of it, for example just add in the end
/td/button - to get button from it
I'm having a Laravel blade form which includes a table wihch displays some data from the database. And when i click on a certain column i wrote a js function to catch that id of the certain selected item to a js variable "var selectedItem".
Now i wanna pass this js variable to the 'edit.item.blade' page and load the relevant record corresponding to this value.
My question is what is the best way to edit a selected item in laravel ? and is there anyway to pass this JS variable to a route at a button click event and load the 'edit.item.blade' using the relevant record to edit.
What you usually do in laravel is pass the id of the record you want to see in the url. Say you want to view the details of a report with the id of 1 you'd go to the url "/reports/1" which points to a show function in the reports controller.
Routes
In your routes/web.php you'd add:
Route::get('/reports/{report}',RecordController#show);
What this is does is take anything typed after /reports/ and pass it to the show function. So if you'd go to /reports/1 the route would pass 1 to the show function
Controller
In your controller you have to make a show function which accepts the variable passed by your route. You'd then take that variable to look up the corresponding record and pass it along to a view.
Which would look like this
public function show($id){
$report = Report::find($id); // Find the corresponding report
// Pass the report along to the view resources/views/reports/show.blade.php
return view('reports.show',compact($report));
}
Show view
In your show view you can now use $report to get any information from the report like $report->name, depending on your database.
Index
Now in the index view, the view you were talking about I presume, you loop over all records from some table. Since you haven't included any code in your post I'm just going to assume you loop over your data using a foreach loop. Using that loop we can give each record a link depending on their id.
Which would look a bit like this
<table>
<tr>
<td> Name </td>
<td> Edit </td>
</tr>
#foreach($reports as $report)
<tr>
<td> $report->name </td>
<td>Edit</td>
</tr>
#endforeach
</table>
I have a table that is built from items in a DB and they contain sensitive information that I don't want to display until you click on a link contained in another table cell.
|item1|item2|click to show item3|(hidden span within cell)|
When you click on the link in cell 3 it will then show cell 4. I know how to accomplish this in typical jquery, but am not sure how to accomplish this in emberjs. Any ideas?
A JS fiddle of your setup would make this easier, but basically you would set a property on your controller from an action.
<span {{action showCell4}}>click to show item3</span>
on your controller have the showCell4 action:
actions: {
showCell4: function() {
this.set('cell4visible', true);
}
}
then for the table add a class binding
<td {{bind-attr class="cell4visible:visibleClassName:hiddenClassName">
sensitive info here
</td>