How to display page object field values in Lightning Component? - salesforce-lightning

I am attempting to build a simple lightning component that will display field values from the object that it is referencing on the page. I have applied the tutorial but cannot get the field values to display on the page.
It is not clear to me how to reference the id of the object on the page and/or whether it is necessary for the apex query or if the field value can be rendered without it.
Position__c is the reference object API with some fields:
This is my component:
<aura:component implements="flexipage:availableForAllPageTypes" controller="positionController" access="global">
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<aura:attribute name="recordId" type="Id" />
<aura:attribute name="position" type="Position__c"/>
{!v.position.Job_Posting_One_liner__c} //I really just need to print this field value
</aura:component>
Controller:
({
doInit : function(component, event, helper) {
var recordId = component.get("v.recordId");
var action = component.get("c.getPositionDetails");
action.setParams({
"PosId": recordId
});
action.setCallback(this, function(response){
var state = response.getState();
if (component.isValid() && state === "SUCCESS") {
var position = response.getReturnValue();
component.set("v.position", position);
}
});
$A.enqueueAction(action);
}
Apex:
public class positionController {
#AuraEnabled
public static Position__c getPositionDetails(Id PosId) {
Position__c positions =
[SELECT Id, Job_Posting_One_liner__c FROM Position__c Where Id= :PosId limit 1 ];
return positions;
}
}

In js controller try remove quotes from this line:
action.setParams({
"PosId": recordId
});
so that it reads like this:
action.setParams({ PosId: recordId });

Related

Salesforce Lightning datatable dynamic creation-adding onrowselection event issue

My requirement is to build lightning datatable dynamically.
I can able to dynamically create and view lightning data table. But as soon as I am adding "onrowselection":component.getReference("c.getSelectedRecord") line, datatable is not rendering. So adding this line is causing the issue, but I need to hookup onrowselection event.
What is the proper way to add onrowselection event dynamically to my dynamically created datatable?
Error Reproduce: I have prepared demo code below.
Component: demoDynamicDataTable.cmp
<aura:component controller="demoDynamicDataTableController">
<aura:attribute name="returnList" type="Contact[]" access="public"/>
<aura:attribute name="returnColumns" type="List" access="public"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}" />
<lightning:button label="Create Data Table" onclick="{!c.createDT}" variant="brand"/>
<div aura:id="newDtPlaceholder">
{!v.body}
</div>
</aura:component>
JS Controller: demoDynamicDataTableController.js
({
doInit : function(component,event,helper) {
console.log("doinit");
//Column data for the table
var columns = [
{
label:'Customer Name',
fieldName:'Name',
type:'text'
},
{
label:'Phone#',
fieldName:'Phone',
type:'text'
}
];
//pass the column information
component.set("v.returnColumns",columns);
//recriving data from server
helper.fetchData(component);
},
createDT : function(component, event, helper) {
//Creating dynamic Lightning datatable
var targetCmp=component.find("newDtPlaceholder");
targetCmp.set("v.body",[]); //destroying existing one
$A.createComponent(
"lightning:datatable",
{
"data":component.get("v.returnList"),
"columns":component.get("v.returnColumns"),
"keyField":"Id",
"maxRowSelection":"1",
"onrowselection":component.getReference("c.getSelectedRecord") //adding this line is causing the issue. But I need to hookup onrowselection event
},
function(tbl,state,message)
{
console.log(state +" - " +message);
var body=targetCmp.get("v.body");
body.push(tbl);
targetCmp.set("v.body",body);
}
);
},
getSelectedRecord: function(component, event, helper){
var selectedRows = event.getParam('selectedRows');
console.log(JSON.stringify(selectedRows[0]));
}
})
Helper: demoDynamicDataTableHelper.js
({
fetchData : function(cmp) {
var action = cmp.get("c.getContact");
action.setCallback(this,function(resp){
var state = resp.getState();
if(state === 'SUCCESS'){
var records = resp.getReturnValue();
//console.log(JSON.stringify(records));
//pass the records to be displayed
cmp.set("v.returnList",records);
}
});
$A.enqueueAction(action);
}
})
Apex Controller: demoDynamicDataTableController.apxc
public class demoDynamicDataTableController {
#AuraEnabled
public static List<Contact> getContact(){
return [Select Id,Name,Phone from Contact];
}
}
App: demoDynamicDataTableApp.app
<aura:application extends="force:slds">
<c:demoDynamicDataTable/>
</aura:application>

Angular2 interdependent form field validation

I have two form fields, where if the first field is filled in, the second field is mandatory. If I try to do this in Angular2, using a custom validator, the validator is only fired on initialization and when the specific field is changed.
Case:
- User fills in field 1
- Field 2 should become required, but isn't till the user actually changes field 2 (firing the custom validation).
private createForm():void {
this.testForm = this._formBuilder.group({
'field1': [],
'field2': ['', this.validateRequired()]
});
}
private validateRequired(){
console.log("something", this);
let component = this;
return (control: Control): { [s: string]: boolean } => {
return component.testModel.field1 && !control.value {"required":true} : null;
}
}
See this plunkr: http://plnkr.co/edit/PEY2QIegkqo8BW1UkQS5?p=preview
Edit:
For now I subscribed to field1's valueChange observable and when changed execute a manual check on field2, like:
this.testForm.controls['field1'].valueChanges.subscribe(
value => {
component.testForm.controls['field2].updateValueAndValidity();
}
)
But I feel like there must be a better way to do this.
You could use a global validator for the group like this:
private createForm():void {
this.testForm = this._formBuilder.group({
'field1': [],
'field2': ['', this.validateRequired()]
}, {
validator: this.someGlobalValidator // <-----
});
}
someGlobalValidator(group: ControlGroup) { // <-----
var valid = false;
for (name in group.controls) {
var val = group.controls[name].value
(...)
}
if (valid) {
return null;
}
return {
someValidationError: true
};
}
I want to expand on Thierry's answer a bit in order to address Arne's comment. In order to handle the validation of multiple fields and possibly multiple validations in your formgroup level validator the solution is to return a function from your validator that then returns an object that indicates the error type. Here is a example of a field matching validator that I added some extra errors to in order to illustrate the point. Note that it returns an object with possibly several properties where each object property is any string and the value is a boolean.
export function FieldMatchingValidator(field1: string, field2 :string) {
return (cg: FormGroup): { [s: string]: boolean } => {
let retVal = null;
let f1 = cg.controls[field1];
let f2 = cg.controls[field2];
retVal = f1.value === f2.value ? null : { fieldMismatch: true };
if(somecondition){
retVal['someerror'] = true;
}
if(someothercondition){
retVal['someothererror'] = true;
}
return retVal;
}
}
When this validator runs, if an error condition is encountered, then the form's errors property will be populated with the returned object with one or more properties indicating different errors. Then all you have to do it put the appropriate angular property setting on the controls that have the validation errors.
<div *ngIf="myForm.hasError('fieldMismatch')">
Field Mismatch
</div>
<div *ngIf="myForm.hasError('someerror')">
Some Error
</div>
<div [class.Errors]="myForm.hasError('someothererror')">
Some Other Error
</div>

Single Post subscription not working in my meteor code

I want to display only single elements based on the ID passed. I am using the subscribe and publish method of meteor for the same, also FlowRouter for Routing. When i try to get the data using findOne and pass the Id, it does't return any data, but when i do find({}), it gets all the data and displays it, not sure why findOne is not working..
Note : I am trying to fetch record based on the Object ID(_id) provided by MongoDB.
posts = Mongo.collection("allPosts");
<Template name="stdSingleView">
{{#if Template.subscriptionsReady}}
{{#with studenthistory}}
{{id}} - {{name}}
{{/with}}
{{else}}
Loading....
{{/if}}
</Template>
Template.stdSingleView.onCreated(function(){
var self = this;
self.autorun(function(){
var Id = FlowRouter.getParam('id');
self.subscribe('singlePost', Id);
});
});
Template.stdSingleView.helpers({
studenthistory: function(){
var id= FlowRouter.getParam('id');
return posts.findOne({_id: id});
}
});
if (Meteor.isServer) {
Meteor.publish("allposts", function() {
return posts.find({});
});
Meteor.publish('singlePost', function(id) {
check(id, String);
return posts.find({_id: id});
});
}
pages.route( '/:id', {
name: 'singleView',
action: function( params ) {
BlazeLayout.render('stdSingleView');
}
});
When you do findOne using _id, Please wrap it to the New Mongo.ObjectID and then pass it.
Try this code :
Meteor.publish('singleStudent', function(id) {
check(id, String);
return attendanceRegCol.find({"_id": new Mongo.ObjectID(id)});
});
Template.studentSingleView.helpers({
studenthistory: function(){
var id= FlowRouter.getParam('id');
return attendanceRegCol.findOne({"_id": new Mongo.ObjectID(id)});
}
});
find will return a cursor, which contains only one document. You need to loop through that in order to get the data, or You change the helper into findOne
Template.stdSingleView.helpers({
studenthistory: function(){
var id= FlowRouter.getParam('id');
return posts.findOne({_id: id});
}
});

load one drop down on selection of other in asp.net mvc

how can i load second dropdown on selection of first and third on second. in asp.net mvc 2
I have the dropdown trigger an ajax post that sends the selected ID selected to a controller and then return a partial view which overwrites the html for a placeholder div.
View; this sets the ActionUrl, you will also need a placeholder div (in my case called departments) for the drop down to be injected:
<script type="text/javascript">
var ActionUrl = '<%= Url.Action("RenderDepartments", "ControllerName") %>';
</script>
<script src="<%: ResolveUrl("~/Scripts/Custom/DepartmentFilter.js")%>" type="text/javascript"></script>
<%: Html.DropDownListFor(model => model.OfficeId, Model.ListItems, "-- Please Select --", new { onchange = "GetDepartments()" })%>
// ^^ ON CHANGE IS IMPORTANT ^^
<div id="departments"></div>
JQuery;
function GetDepartments() {
$.ajax(
{
type: "POST",
url: ActionUrl,
data: { officeId: $("#OfficeId").val() },
success: function (data) {
$("#departments").html(data);
}, error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('XMLHttpRequest:' + XMLHttpRequest.responseText);
alert('textStatus:' + textStatus);
//alert('errorThrown:' + errorThrown);
}
});
}
Controller Action;
public ActionResult RenderDepartments(int? officeId)
{
if (officeId.HasValue)
{
var departments = new SelectList(ents.GetDepartments(officeId), "departmentID", "Name");
var model = new DropdownListViewModel(departments);
return PartialView("DepartmentDropdown", model);
}
return null;
}
This is nullable because the user could submit "-- please select --" which will in this case return null and remove the departments dropdown.

ASP.net mvc Call Action on DropDown Value Change

Ive got a dropdown on one of my views. This dropdown only has for entries. Basically i need to know how to call an action when the dropdown value is changed?
My situation is: Im making a simple inbox page. The dropdown has the filter options: View All, View Invites, View Replies etc..
When the user selects a filter option from the dropdown I want to call to an action to return the new view with the filtered data.
Any ideas? Im guessing it is somehow going to be a script attached to the OnChange of the dropdown, but i wouldnt have a clue what the syntax is or how call MVC action from the script.
Thanks in advance
You need to use javascript for this. Here's an example. Suppose you have the following view model:
public class MyViewModel
{
public IEnumerable<SelectListItem> Values { get; set; }
}
which you would populate in your controller:
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
var model = new MyViewModel
{
Values = new[]
{
new Item { Value = "1", Text = "Item 1" },
new Item { Value = "2", Text = "Item 2" },
new Item { Value = "3", Text = "Item 3" }
}
};
return View(model);
}
}
And then the view which is strongly typed to this model:
<%: Html.DropDownListFor(x => x.SelectedValue,
new SelectList(Model.Values, "Value", "Text"),
new { id = "items" }
)%>
The last part is to register for the change event (using jquery in this example):
$(function () {
// Register for the change event of the drop down
$('#items').change(function () {
// When the value changes, get send an AJAX request to the
// Filter action passing the selected value and update the
// contents of some result div with the partial html returned
// by the controller action
$('#result').load('<%: Url.Action("filter") %>',
{ selectedValue: $(this).val() }
);
});
});