I am not completely sure what it is that you mean when you say "current record"
but I imagine that it's related to some sort of event like onclick
, onkeyup
, etc.
As @rahulgawale mentioned you can leverage the use of HTML's data attributes. From the documentation:
data-* attributes allow us to store extra information on standard,
semantic HTML elements without other hacks such as non-standard
attributes, extra properties on DOM...
This is how you can add data attributes using the code you have provided:
<tbody>
<template for:each={testList} for:item="test">
<tr key={test.Id}>
<td data-id={test.Id} onclick={handleClick}>
{data}
</td>
</tr>
</template>
</tbody>
Next in the JS you will have to add a method to handle the click event:
handleClick(evt) {
// This will give you the id value that we just stored as a data attribute in the table cell.
const recordId = evt.target.dataset.id;
// Next you can iterate over your list and find which record the user interacted with.
for (let aRecord of this.testList) {
if (recordId === aRecord.Id) {
this.record = aRecord;
this.field = aRecord.Field__c;
}
}
}
Iterating over the list of records testList
and comparing each record's Id to recordId
is not very efficient.
You can improve the above code if you build an additional object-type variable when you first retrieve the testList
from Salesforce:
testListObj = {};
@wire(getTestList, { recordId: $recordId})
wireTestList({error, data}) {
if (data) {
this.testList = data;
// Populate the new object mapping every record to its id.
for (let testRecord of this.testList) {
this.testListObj[testRecord.Id] = testRecord;
}
} else if (error) {
// handle your error
}
}
At this point you can quickly find the record you are looking for when the user interacts with any table cell like so:
handleClick(evt) {
// This will give you the id value that we just stored as a data attribute in the table cell.
const recordId = evt.target.dataset.id;
// At this point you no longer need to iterate and compare each record's id because you have an object that holds all records so you can directly reference the correct record below.
this.record = this.testListObj[recordId];
this.field = this.testListObj[recordId].Field__c;
}
EDIT As per request by OP I am expanding my answer to include an onblur event on a textarea inside the <td></td>
.
If you want to use a placeholder you can go with this:
<tbody>
<template for:each={testList} for:item="test">
<tr key={test.Id}>
<td data-id={test.Id}>
<textarea data-id={test.Id} onblur={handleOnBlur} placeholder={test.Field__c}></textarea>
</td>
</tr>
</template>
</tbody>
JS:
handleOnBlur(evt) {
// This will give you the id value that we just stored as a data attribute in the table cell.
const recordId = evt.target.dataset.id;
const placeholderValue = evt.target.getAttribute('placeholder');
// Retrieve the value out of the textarea.
const textAreaValue = evt.target.value;
// Compare the value from the textarea to the original value for the record in SF.
if (placeholderValue !== textAreaValue) {
this.record = this.testListObj[recordId];
this.field = this.testListObj[recordId].Field__c;
}
}
Additionally if you don't want to use a placeholder but want to prepopulate the field value in the textarea instead you can do this:
<tbody>
<template for:each={testList} for:item="test">
<tr key={test.Id}>
<td data-id={test.Id}>
<textarea data-id={test.Id} onblur={handleOnBlur}
{test.Field__c}
</textarea>
</td>
</tr>
</template>
</tbody>
Now in the JS you can compare the textarea value to the value from the testListObj
:
handleOnBlur(evt) {
// This will give you the id value that we just stored as a data attribute in the table cell.
const recordId = evt.target.dataset.id;
// Retrieve the value out of the textarea.
const textAreaValue = evt.target.value;
// Compare the value from the textarea to the original value for the record in SF.
if (this.testListObj[recordId].Field__c !== textAreaValue) {
this.record = this.testListObj[recordId];
this.field = this.testListObj[recordId].Field__c;
}
}
lightning-datatable
?