I'm trying to display subqueries columns on my Visualforce page but I can't.
Apex controller:
public class FormController {
private final FormularioDeVisita__c formulario;
public FormularioVisitaPdfController() {
if(ApexPages.currentPage().getParameters().get('id') != null){
formulario = [
SELECT
ChequeEmpresa__c, SedePropria__c, CNPJ__c, MercadoExternoCliente__c, DataFundacao__c,
(SELECT
FormInfoPercent__c, FormInfoText__c, FormInfoCheckbox__c, FormInfoDate__c, FormInfoCurrency__c,
FormInfoPercentDecimal__c, FormularioVisita__c
from FormularioVisitaChild__r)
from FormularioDeVisita__c
WHERE Id = :ApexPages.currentPage().getParameters().get('id')];
}
}
public FormularioDeVisita__c getformularioVisita() {
return formulario;
}
public PageReference save() {
update formulario;
return null;
}
}
Example from Visualforce page:
<tr>
<td class="table td">Mercado livre?</td>
<td class="table td_right">{!formularioVisita.MercadoLivre__c}</td>
</tr>
Using like that I can display the columns from the father without problems, but when I try to display from children, I can't.
I didn't find any information about it.
Display children columns in my HTML in Visualforce.
You need <apex:repeat>, <apex:datatable>, <apex:pageBlockTable> tags.
https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_compref_repeat.htm contains example of using repeat to access Account.Cases. In your code it'll be repeat over {!formularioVisita.FormularioVisitaChild__r}
I am working on an infinite scroll in angular 8. I am using an angular materials table to display my data.
Html:
<mat-table [dataSource]="displayOfMassSendObjects"
infinite-scroll
[infiniteScrollDistance]="scrollDistance"
[infiniteScrollUpDistance]="scrollUpDistance"
(scroll)="onScrollDown()"
(scrollup) = "onScrollUp()"
>
<ng-container id = "companyNameColumn" matColumnDef="companyName">
<mat-header-cell id = "companyNameTitle"
*matHeaderCellDef>CompanyName</mat-header-cell>
<mat-cell class = "companyNameData" *matCellDef="let row">
{{row.companyName}}</mat-cell>
</ng-container>
<ng-container id = "emailColumn" matColumnDef="email">
<mat-header-cell id = "emailTitle"
*matHeaderCellDef>Email</mat-header-cell>
<mat-cell class = "emailData" class="email" *matCellDef="let row">
{{row.email}}</a></mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="tableColumns"></mat-header-row>
<mat-row *matRowDef="let row; columns: tableColumns"> </mat-row>
</mat-table>
On load I have 10 records showing up in the table. When I scroll down, I am expecting that more records will populate in the HTML but they are not. The records are however being added to the array in the console.log(). I think the problem is that the HTML Angular Materials is not recognizing the .push because when I substitute .push for .slice, the records show up in the HTML, however don't want the app to work like that.
Here is my component for the table where I want the scroll bar:
export class MassSendComponent implements OnInit {
sum = 10;
globalList = [];
displayOfMassSendObjects: MassSend[];
tableColumns : string[] = ['ispNumber','companyName', 'email', 'taxId']
constructor(
private mockMassSendService: MockMassSendService,
) {}
ngOnInit(): void {
this.getMassSendData();
}
getMassSendData() {
this.mockMassSendService.getMassSendData()
.subscribe(massSendObjects => {
this.globalList = massSendObjects;
this.displayOfMassSendObjects = massSendObjects.slice(0,
this.sum);
});
}
getMoreData() {
this.displayOfMassSendObjects.push(this.globalList[this.sum]);
}
onScrollDown(): void {
console.log(this.displayOfMassSendObjects);
this.getMoreData();
this.sum += 1;
}
}
I also have a service method being called:
export class MockMassSendService {
constructor() { }
getMassSendData(): Observable<MassSend[]> {
return of(mockMassSend);
}
}
You can use displayOfMassSendObjects = new MatTableDataSource(this.displayOfMassSendObjects); every time you fetcb new data, this will initialize a new datasource object.
The reason you are not able to see newly added rows is that
Mat table only reflects changes when the reference to datasource is changed that's why when you use slice method it works fine.
Creation of a complex formula blot, such as the one below, is successful using an Embed, but it works only in a single instance. All other instances are truncated. Attempts to create it as an Inline or Block resulted in errors.
I am developing a graphic formula editor, with a dialog and toolbars of its own, and it is successfully getting the delta from an existing blot. Unfortunately, saving more than one formula fails, and replacing an existing formula fails. When saving more than one formula, only the top level spans are saved for all but the first.
It isn't clear from the documentation if the tag hierarchy can be used as an Inline or Block element.
As a side note, I am building a complete Quill npm module for Angular 7+ apps that includes a number of other quill modules as well, translated to Typescript. The npm module will support WCAG compliance with large buttons, etc. that can be toggled.
Example tag hierarchy to be used as a blot:
<span class="pl3-quill-formula-blot" data-id="pl3qfml_1560288135645" data-editors="[{"id":1560288133767,"parentId":null,"depth":0,"position":0,"fElement":{"name":"cube root","text":"∛","type":"O","shape":"R","latex":null,"values":["x"],"nValues":1}},{"id":1560288133768,"parentId":0,"depth":0,"position":1,"fElement":{"name":"-EMPTY-","text":"","type":"S","shape":"C","latex":null,"latexCb":null,"values":[""],"nValues":1}}]">
<span contenteditable="false">
<span class="katex">
<span class="katex-mathml"><math><semantics><mrow><mroot><mi>x</mi><mn>3</mn></mroot></mrow><annotation encoding="application/x-tex">\sqrt[3] {x} </annotation></semantics></math></span><span class="katex-html" aria-hidden="true"><span class="base"><span class="strut" style="height: 1.04em; vertical-align: -0.23972em;"></span><span class="mord sqrt"><span class="root"><span class="vlist-t"><span class="vlist-r"><span class="vlist" style="height: 0.658556em;"><span class="" style="top: -2.83634em;"><span class="pstrut" style="height: 2.5em;"></span><span class="sizing reset-size6 size1 mtight"><span class="mord mtight"><span class="mord mtight">3</span></span></span></span></span></span></span></span><span class="vlist-t vlist-t2"><span class="vlist-r"><span class="vlist" style="height: 0.80028em;"><span class="svg-align" style="top: -3em;"><span class="pstrut" style="height: 3em;"></span><span class="mord" style="padding-left: 0.833em;"><span class="mord mathdefault">x</span></span></span><span class="" style="top: -2.76028em;"><span class="pstrut" style="height: 3em;"></span><span class="hide-tail" style="min-width: 0.853em; height: 1.08em;"><svg width="400em" height="1.08em" viewBox="0 0 400000 1080" preserveAspectRatio="xMinYMin slice"><path d="M95,702c-2.7,0,-7.17,-2.7,-13.5,-8c-5.8,-5.3,-9.5,
-10,-9.5,-14c0,-2,0.3,-3.3,1,-4c1.3,-2.7,23.83,-20.7,67.5,-54c44.2,-33.3,65.8,
-50.3,66.5,-51c1.3,-1.3,3,-2,5,-2c4.7,0,8.7,3.3,12,10s173,378,173,378c0.7,0,
35.3,-71,104,-213c68.7,-142,137.5,-285,206.5,-429c69,-144,104.5,-217.7,106.5,
-221c5.3,-9.3,12,-14,20,-14H400000v40H845.2724s-225.272,467,-225.272,467
s-235,486,-235,486c-2.7,4.7,-9,7,-19,7c-6,0,-10,-1,-12,-3s-194,-422,-194,-422
s-65,47,-65,47z M834 80H400000v40H845z"></path></svg></span></span></span><span class="vlist-s"></span></span><span class="vlist-r"><span class="vlist" style="height: 0.23972em;"><span class=""></span></span></span></span></span></span></span>
</span>
</span>
</span>
Blot Code:
import {Pl3QuillFormulaResult} from './pl3-quill-formula.component';
const Quill = require('quill');
const Embed = Quill.import('blots/embed');
class Pl3QuillFormulaBlotComponent extends Embed {
static blotName = 'pl3-quill-formula';
static className = 'pl3-quill-formula-blot';
static tagName = 'span';
constructor(domNode: Element, value: any) {
super(domNode);
}
static create(result: Pl3QuillFormulaResult) {
const node = super.create(result.id);
node.setAttribute('data-id', result.id);
node.setAttribute('data-editors', result.editorsAsString);
node.appendChild(result.domElement);
return node;
}
/**
* Quill uses this to return a Delta with the attributes in the return.
*/
static formats(domNode: Element) {
return {
editors: domNode.getAttribute('data-editors'),
id: domNode.getAttribute('data-id')
};
}
static value(domNode: HTMLElement) {
return {
id: domNode.dataset.id,
editors: domNode.dataset.editors
};
}
public remove() {
if (this.prev == null && this.next == null) {
this.parent.remove();
}
else {
super.remove();
}
}
}
Quill.register('formats/pl3-quill-formula', Pl3QuillFormulaBlotComponent);
This is the call to insert the formula that is not working for subsequent instances, although it works for the first formula:
if (result) {
const range = this.quill.getSelection(true);
this.quill.insertEmbed(range.start, 'pl3-quill-formula', result, Quill.sources.API);
this.quill.setSelection(range.length + 1);
}
Formula Editor UI Snapshot
The expected results are to be able to insert the formula within the editor, inline, and to be able to replace it when the formula is updated.
I have a list of objects stored in firebase database:
I am getting this list using angular http get request. After getting it I want to iterate on a li in html template using ngFor="let subject of subjects" which gives Error:
ERROR Error: Cannot find a differ supporting object '[object Object]'
of type 'object'. NgFor only supports binding to Iterables such as
Arrays.
As I searched online, I came to know that ngFor can only be used on arrays while I am getting nested objects. Can anyone please suggest me what should I do iterate these objects.
So far I have tried Array.of which converts whole list into someArray[0]. I also tried to manually change the unique ids of objects into array indexes [0, 1, 2] which worked but when I add new subject using http post firebase automatically assigns unique id to new subject making it uniteratable.
In simple words tell me to convert nested objects into an arrayList or how can I change the firebase default behavior of assigning unique id in angular (I found something like firebase push function which I couldn't understand).
Update:
(Code from ExaminerService)
getBatchSubjects(batch){
return this.http.get(firebaseLinkGoesHere);
}
(Code from Component)
onBatchSelected(event){
this.selectedBatch = event.target.value; //getting value of a html select
this.examinerService.getBatchSubjects(this.selectedBatch)
.subscribe(
(response : Response) => {
this.selectedBatchData = response.json();
}
),(error) => {
console.log(error);
}
}
(Code from HTML Template)
<div class="batchDetails">
<table class="table table-striped">
<thead>
<tr>
<th class="text-center">S.No</th>
<th>Subject Name</th>
<th>Facilitator</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let subject of selectedBatchData.subjects; let i = index">
<td class="text-center"> {{i + 1}} </td>
<td> {{subject.name}} </td>
<td> {{subject.facilitator}} </td>
</tr>
</tbody>
</table>
</div>
You can use Object.values to turn the properties into an array. This can be done in several ways.
Method 1 - By applying the map operator to the observable data (see this stackblitz):
import { Observable } from "rxjs/Rx";
public subjects: Array<any>;
this.examinerService.getBatchSubjects(this.selectedBatch)
.map(x => (Object as any).values(x.json().subjects))
.subscribe(
(values) => { this.subjects = values; },
(error) => { console.log(error); }
);
Method 2 - With a property getter or a method of the component class (see this stackblitz):
get subjects(): Array<any> {
return (Object as any).values(this.selectedBatchData.subjects);
}
Method 3 - By converting the values in the subscribe callback (see this stackblitz):
public subjects: Array<any>;
...
this.selectedBatchData = response.json();
this.subjects = (Object as any).values(this.selectedBatchData.subjects);
Template
In the template, the ngFor directive would iterate over the subjects array:
<tr *ngFor="let subject of subjects; let i = index">
<td class="text-center"> {{i + 1}} </td>
<td> {{subject.name}} </td>
<td> {{subject.facilitator}} </td>
</tr>
try following code snippet.
ngFor="let subject of subjects|async
Update
In your ExaminerService you should import FirebaseListObservable in order to define return type FirebaseListObservable<any[]>
import { AngularFireDatabase, FirebaseListObservable } from 'angularfire2/database';
export class ExaminerService{
constructor(private db: AngularFireDatabase) {}
getBatchSubjects(batch){
return this.db.list('/subjects');
}
}
In your Component should look like this
export class ExaminerComponent implements OnInit {
movies: any[];
constructor(private examinerDb: ExaminerService) { }
ngOnInit() {
this.examinerDb.get().subscribe((snaps) => {
this.selectedBatchData = snaps;
});
}
}
Angular has pipe "keyvalue" which will let you parse your object into pairs like subject.key and subject.value
I am trying to dynamically load the optionset of select tag on ng-click event. clicking on expand arrow fires ng-click event. Since I fetch the data at that point and bind to the select control, angularjs omits the expand event somehow, select does not expand. User has to click on the arrow one more time to see the results of the dynamically loaded options.
How can I ensure to expand the select correctly in one click while loading the options?
I tried to find a way to dynamically expand the select when the load is complete, but afaik there is no cross browser way of achieving that.
Here is the code, onclick retrieve method is being called to fetch and bind the data to the select. But click does not expand the control...
<div style="position: relative;">
<input type="text" class="inputTextFieldCell"
style="width: 215px; position: relative; top: 0; left: 0; z-index: 2; padding: 0; margin: 0;"
ng-model="subscriptionResource.Value" />
<select class="optionsCellInput selectTextFieldCell"
style="width:240px;position: absolute; top: 0; left: 0; padding: 0; margin: 0;"
ng-click="resources.retrieve(subscriptionResource, $event)"
ng-model="item" ng-options="resource as resource.Serial for resource in subscriptionResource.resourceList"
ng-change="selectChange(subscriptionResource, item)" >
</select>
</div>
Javascript:
$scope.resources = {
retrieve: function (resource, event) {
if (resource.resourceList == null) {
var reqDataRetrieveResources = { "request": null };
reqDataRetrieveResources = window.createRequest(window.definitions.messages.RetrieveResourceRequest, reqDataRetrieveResources);
reqDataRetrieveResources.request["ResourceType"] = 1;
reqDataRetrieveResources.request["SearchCount"] = 5;
$http.post(window.definitions.url, reqDataRetrieveResources).success(function (result) {
if ((result.d !== null) && (result.d.Resources !== null)) {
resource.resourceList = result.d.Resources;
return true;
}
});
return true;
}
}
}
Try to use ng-mousedown instead of ng-click. If it don't works, try to call $scope.$apply after bind your data.