You can build a custom lwc in which you embed some sort of 'popover' overlay component. So yes, this is possible.
If your Layout is, for example, a Table, as follows:
<template>
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset">
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Name">Name</div>
</th>
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Age">Age</div>
</th>
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Birthday">Birthday</div>
</th>
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Height">Height</div>
</th>
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Sex">Sex</div>
</th>
<th class="slds-cell-buffer_right" scope="col">
<div class="slds-truncate" title="Bear Weight">Weight</div>
</th>
</tr>
</thead>
<tbody>
<template if:true={bears.data}>
<div class="slds-m-around_medium">
<template for:each={bears.data} for:item="bear" for:index="index">
<tr class={assignClass} key={bear.Id} data-rangerid={bear.Supervisor__c} onmouseout={hideData} onmouseover={showData}>
<td data-label="Bear Name" class="slds-cell-buffer_right">
<div class=slds-truncate title="Bear Name">{bear.Name}</div>
</td>
<td data-label="Bear Age" class="slds-cell-buffer_right">
<div class="slds-truncate" title="Bear Age">{bear.Age__c}</div>
</td>
<td data-label="Bear Birthday" class="slds-cell-buffer_right">
<div class="slds-truncate" title="Bear Birthday">{bear.Birthday__c}</div>
</td>
<td data-label="Bear Height" class="slds-cell-buffer_right">
<div class="slds-truncate" title="Bear Height">{bear.Height__c}</div>
</td>
<td data-label="Bear Sex" class="slds-cell-buffer_right">
<div class="slds-truncate" title="Bear Sex">{bear.Sex__c}</div>
</td>
<td data-label="Bear Weight" class="slds-cell-buffer_right">
<div class="slds-truncate" title="Bear Weight">{bear.Weight__c}</div>
</td>
</tr>
</template>
</div>
</template>
</tbody>
</table>
you can "Build" a LWC that will act as a popover (a card for example, with an embeded lightning-record-view-form.
this is a sample lwc that I added at the bottom of my table:
<c-box-popover topmargin={top} leftmarginn={left} myranger={ranger}></c-box-popover>
it basically receives coordinates of where my cursor is located (you can do this as well in the child lwc).
my table component in return has uses onmouseover
and onmouseout
events for rendering/unrendering the card based on the id
that is being passed to it.
Example:
showData(event){
this.ranger = event.currentTarget.dataset.rangerid;
this.left = event.clientX;
this.top=event.clientY;
}
hideData(event){
this.ranger = "";
}
My popover in returns, simply passes the id attribute aka, myranger
to the record-view-form component:
<template>
<div>
<template if:true={ranger} >
<lightning-record-view-form
record-id={ranger}
object-api-name="Contact">
<div class="potato slds-box" style={boxClass}>
<lightning-output-field field-name="Name">
</lightning-output-field>
<lightning-output-field field-name="Email">
</lightning-output-field>
</div>
</lightning-record-view-form>
</template>
</div>
and as you can see, I dynamically assign a "style" attribute which I construct using Template literals
get boxClass() {
return `background-color:white; top:${this.top - 280}px; left:${this.left}px`;
}
I did not put much effort in calculating screensize to properly place the popover, but it should give you the general idea.
You can find a sample Gist here
The data i used ot work with can be found on the build-apps-with-lwc Trailhead repository
You can use pubsub
for sending data across components - whether wire service or any other event.
Below is listener
component:
import { LightningElement, api, track, wire } from 'lwc';
import { CurrentPageReference } from 'lightning/navigation';
import { registerListener, unregisterAllListeners } from 'c/pubsub';
export default class Poc extends LightningElement {
@track myResponse;
@wire(CurrentPageReference) pageRef;
connectedCallback() {
registerListener('wiredResponse', this.getWiredResponse, this);
}
disconnectedCallback() {
unregisterAllListeners(this);
}
getWiredResponse(response) {
this.myResponse = response;
}
}
HTML:
<template>
<template if:true={myResponse}>
<template if:true={myResponse.data}>
<div> data - {myResponse.data} </div>
</template>
<template if:true={myResponse.error}>
<div>error - {myResponse.error}</div>
</template>
</template>
</template>
You should download and save pubsub
module from HERE
Register listener on init (connectCallback) and implement the method to which the response has to be passed. Here its getWiredResponse
in which the response from wire service is assigned to myResponse
.
Also unregister in disconnected callback.
Firing component:
JS:
import { LightningElement, track, wire } from 'lwc';
import check from '@salesforce/apex/poc.check';
import { CurrentPageReference } from 'lightning/navigation';
import { fireEvent } from 'c/pubsub';
export default class PocTable extends LightningElement {
@wire(CurrentPageReference) pageRef;
@track checkResp;
@wire(check)
getcheckResp(result) {
this.checkResp = result;
console.log('poc table wire => ', JSON.stringify(this.checkResp));
fireEvent(this.pageRef, 'wiredResponse', this.checkResp);
}
}
HTML:
<template>
<template if:true={checkResp.data}>
<div> checkResp data - {checkResp.data} </div>
</template>
<template if:true={checkResp.error}>
<div> checkResp error - {checkResp.error}</div>
</template>
</template>
- In this you will need
fireEvent
import and you can fire the event whenever necessary. In this case inside wire service.
In both listener and firing component should have CurrentPageReference
.
@wire(CurrentPageReference) pageRef;
IMPORTANT:
When Wire service is implemented on any standard methods like getRecord
, it uses Lighning data service, so you dont need any custom functionality to optimise code here.
When wire service is used to invoke apex methods, we should be using Cacheable=true
on methods mandatorily. So, even if you use wire service on same method in multiple components, the apex method will return the response only once and the wire service will share the same data resource from client cache. So, it is not really logical/needed to handle the optimisation. If 1 wire output is the input for another wire service in another component, then it makes more sense to implement the same wire service in target component. pubsub
is application event and so it should not really be used in this case.
Component extension will not work on wire service. This is because wire service is already optimised and LWC does not really need it that way.
Best Answer
No, as there's already a solution available: getObjectInfo.
Here's the example from the documentation:
Since it's a wire method, this is actually reactive, in case the permissions change for some reason, your component will be notified of the change in permissions without having to reload the component.