I have built a simple component to display the contact information. But, its not showing in the page. no clue what is going on ?
I have checked apex controller is returning contact correctly. But, the component is not rendering with the received contact object.
<aura:application >
<aura:attribute name="contactId" type="String"/>
<c:PreferenceComponent contactId="{!v.contactId}"/>
</aura:application>
<aura:component controller="PreferenceComponentCtrlr">
<aura:attribute name="contactId" type="String"/>
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
<lightning:card variant="Narrow" title="{!v.contact.Name}"
iconName="standard:contact">
<p class="slds-p-horizontal_small">
{!v.contact.Phone}
</p>
<p class="slds-p-horizontal_small">
{!v.contact.MailingStreet}
</p>
</lightning:card>
</aura:component>
({
doInit : function(component, event, helper) {
var action = component.get("c.getContact");
action.setParams({
contactId : component.get("v.contactId")
});
action.setCallback(this, function(response) {
var state = response.getState();
if (state === 'SUCCESS'){
component.set("v.contact", response.getReturnValue());
}
});
$A.enqueueAction(action);
}
})
public class PreferenceComponentCtrlr {
#AuraEnabled
public static Contact getContact(Id contactId) {
System.debug('contactId - ' + contactId);
return [Select Id, Name, Phone, MailingStreet From Contact Where Id =: contactId LIMIT 1];
}
}
I found the answer, i need to add Contact attribute to the component,
<aura:attribute name="contact" type="Contact"/>
Related
Does anyone know the way to pass value from LWC to Flow variable?
When clicking "Add Name" button, I want input value to be passed to Flow valuable. "Manually assign variables (advanced)" is valid on the screen setting. But the variable is null and never changes.
xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>50.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__FlowScreen</target>
</targets>
<targetConfigs>
<targetConfig targets="lightning__FlowScreen">
<property name="sampleName" type="String" label="sampleName"/>
</targetConfig>
</targetConfigs>
</LightningComponentBundle>
js
import { LightningElement,api } from 'lwc';
import { FlowAttributeChangeEvent, FlowNavigationNextEvent } from 'lightning/flowSupport';
export default class sampleFlowComponent extends LightningElement {
#api
availableActions = [];
#api
sampleName;
handleAttributeChange() {
const attributeChangeEvent = new FlowAttributeChangeEvent('sampleName', this.sampleName);
this.dispatchEvent(attributeChangeEvent);
}
handleNext() {
if (this.availableActions.find(action => action === 'NEXT')) {
const navigateNextEvent = new FlowNavigationNextEvent();
this.dispatchEvent(navigateNextEvent);
}
}
}
html
<template>
<lightning-input
label="sampleName"
type="text">
</lightning-input>
<lightning-button
label="Add Name"
title="Add Name"
onclick={handleAttributeChange}>
</lightning-button>
<lightning-button
label="Go Next"
title="Go next"
onclick={handleNext}>
</lightning-button>
</template>
Any information would be helpful!
Add an onchange handler to the input to call:
onchange(event){
this.sampleName= event.target.value;
}
No need of a specific button.
I am trying to build a react page that shows a list of "messages subjects" received and when you click the down icon the messages relating to that subject appear directly below. (Imagine to help explain, when the user clicks the down icon on the line with 'Christmas' a white space needs to appear directly below and BEFORE the line with the 'New Year' text, so I can then display the message body, etc for each message relating to that subject.
Here is my code
import React from "react";
import "./Messages.css";
import { ReactComponent as DownIcon } from "../images/down-chevron.svg";
import Moment from 'moment';
class Messages extends React.Component {
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: false,
};
}
componentDidMount() {
this.setState({ isLoading: true });
const proxyurl = "https://cors-anywhere.herokuapp.com/";
const url =
"<my url>" +
this.props.location.state.userID;
fetch(proxyurl + url)
.then((res) => res.json())
.then((data) => this.setState({ data: data, isLoading: false }));
}
render() {
const { data, isLoading } = this.state;
if (isLoading) {
return <p>Loading ...</p>;
}
if (data.length === 0) {
return <p> no data found</p>;
}
return (
<div>
<div className="messageSubjectHeader">
<div className="innerMS">Message Subject</div>
<div className="innerMS">Number of linked messages</div>
<div className="innerMS">Latest message Date and Time</div>
<div className="innerMS">View Messages</div>
</div>
{data.message_Subjects.map((ms) => (
<div className="messageSubject">
<div className="innerMS">{ms.subject}</div>
<div className="innerMS">{ms.message_Chain.length}</div>
<div className="innerMS">{this.getLatestMessageDateTime(ms.message_Chain)}</div>
<div className="innerMS">
<DownIcon className="innerMSDownIcon" />
</div>
</div>
))}
</div>
);
}
getLatestMessageDateTime(messageChain){
const lastmessage = messageChain.length -1;
Moment.locale('en');
var dt = messageChain[lastmessage].dateTime;
return(Moment(dt).format('ddd DD MMM YYYY hh:mm:ss'))
}
}
export default Messages;
You have to define the selected record id in the state and Update the selected id on the click of view messages button. And also add a Content Panel inside the loop and toggle the visibility based on the selected recorded Id in the state.
{data.message_Subjects.map((ms) => (
<>
<div className="messageSubject">
<div className="innerMS">{ms.subject}</div>
<div className="innerMS">{ms.message_Chain.length}</div>
<div className="innerMS">{"12/08/2020"}</div>
<div className="innerMS">
<button onClick={() => this.handleClick(ms.id)}>
{this.state.selectedId === ms.id ? "hide" : "Show"}
</button>
</div>
</div>
// show/hide the content based on the selection --> Content Panel
{this.state.selectedId === ms.id && (
<div className="content">{ms.description}</div>
)}
</>
))}
I have created a sample Demo - https://codesandbox.io/s/vigorous-hertz-x89p8?file=/src/App.js
Let me know if your use case is different.
You should have an onClick() handler if you want something to happen when user clicks an element, and then define handleOnClick() elsewhere in the component.
And you have no sub-component for the messages of a particular dated group, so, you'll need to code that, too.
Sub-Messages Component
I see that you have not defined any sub-components for messages. I don't know how your API works, so, I'll be general in that regard, but you'll want a <DateMessages/> component. This should have a constructor and render like...
constructor(props) {
super(props);
this.state = {'messages':[]};
}
render() {
return (
this.state.map((message) => {
return message.date + ' ' message.text;
});
);
}
Then, you'll need to populate this. So, add it as a ref in your <Messages/> component, as a child of <div className="messageSubject">. Since it starts out with no messages, it should come out as blank when appended to each date group. That'll look like datekey = ms.subject; <DateMessages ref={(instance) => {this.$datekey = instance}} />.
onClick Handler
So, your onClick handler would look like: <div className="messageSubject" onClick={(e, ms.subject) => this.handleOnClick(e, ms.subject)}>. You might have a handleOnClick() like...
handleOnClick(e, ms.subject) {
var datekey = ms.subject;
this.$datekey.setState(this is where an array of messages for datekey would be stored);
}
Advantages
Why do it this way? By having the state accurately reflect the data that the user is seeing, you'll be taking advantage of all the speedups of using ReactJS.
i want to filter data based on the search query entered in input field from the values selected in dropdown menu.
What i am trying to do?
Consider the image below
From the select dropdown option user can select both messages and info or either of the options. Based on the option selected from dropdown menu and search query entered in the search input field it should filter data.
Suppose if user selected messages and entered search query "hello" it should retrieve messages containing text "hello" and similarly with info and messages option as well.
I am not sure how to do this. Could someone help me solve this?
Below is the code,
<div className='wrapper'>
<div>
{!state.expanded && <Svgsearch/>}
{state.expanded && props.active && <div onClick=
{this.collapse_input}><Svgsearch/></div>}
{state.expanded &&
<div className="search_input">
<input type="text" placeholder="search query" />
</div>}
<div className="search_dropdown">
<FieldDropdown on_dropdown_toggle=
{this.handle_dropdown_toggle} />
</div>
</div>
</div>);
export default class FieldDropdown extends react.component {
render = () => {
return (
<Dropdown className="category_dropdown" on_dropdown_open=
{this.handle_dropdown_open} on_dropdown_close=
{this.handle_dropdown_close}>
<div>
<button>{dropdown_text}</button>
</div>
{state.options.map((option, i) => {
return (
<DropdownItem key={i} on_select=
{this.handle_option_selection} value={i}>
<input type="checkbox" value={option.value}
checked="true" readOnly />
<span>
{option.text}</span>
</DropdownItem>)
})}
</Dropdown>);
};
Consider i have messages and info in an array of objects.
How can i write a method to filter data based on option selected from dropdown.
Thanks.
Html for query field
<input
id="searchId"
type="text"
value={this.state.queryValue}
onChange={this.handleTextChange}
/>
State
state = { data: [], filteredData:[],queryValue: '' ,value:'' };
Event Handling Method
handleTextChange = event => {
//read the value of the textbox with event.target.value
const filteredData = this.state.data.filter(d =>
// object where condition based on value(options value) & queryValue
);
this.setState({ queryValue: event.target.value, filteredData});
};
and bind UI to the filteredData.
class ProductTheme extends Component{
constructor(props){
super(props);
this.state = { activePage : 1 , formValues: {}, totalPages:10}
}
render(){
const {handleSubmit} = this.props;
const page = this.state.totalPages;
return(
<div><ThemesNavBar/>
<div className="container" id="PTConatiner">
<h2>Product Explainer Information</h2>
<div className = "container">
<form className="form-inline" onSubmit = {handleSubmit(this.onSubmit.bind(this))}>
<Field label="Meet" value={this.state.formValues["cname"]} onChange={this.handleChange.bind(this, 'svgObject','cname', 'cprofession')} name="cname" component={ this.renderField}/>
<Field label="He's" value={this.state.formValues["cprofession"]} onChange={this.handleChange.bind(this, 'svgObject','cname', 'cprofession')} name="cprofession" component={ this.renderField}/>
</form>
</div>
<object type="image/svg+xml" ref="svgObject" data={require("./images/svg files/Scene_01.svg")} id='svgObject' ></object>
<div id="screenPage02">
<Field label="He's Struggling To" value={this.state.formValues["struggling"]} onChange={this.handleChange.bind(this)} name="struggling" component={ this.renderField}/>
<object type="image/svg+xml" ref="svgObject01" data={require("./images/svg files/Scene_02.svg")} id='svgObject01' ></object>
</div>
{divData.map((data)=>{
console.log(data);
})}
<Pagination
prev
next
first
last
boundaryLinks
items={page}
maxButtons={2}
activePage={this.state.activePage}
onSelect={this.handleSelect.bind(this)}
/>
</div></div>
);
};
};
Hi , when user clicks on a particular no in pagination it should change to the div which is related to it how to do it with React ? i had a look at some NPM modules but those are not working for me ?
I guess you approach is not correct you must not load a new component or div each time , either you can go for changing div content as page changes only content must change that you can do with keeping data in state and load limited data what required for first page , once page changes , change div with that slot of data.
You should store your curent page data in component state or in Redux store.
Your source code is too short to understand your case. I don't know which Pagination library you use.
If you want similar solution with source check:
Demo
Github
I'm trying to wrap bootstrap into components with integrated form validation.
short:
Let's say I have
<Form>
<FieldGroup>
<Field rules={'required'}/>
</FieldGroup>
</Form>
Once Field pases validation, how can I notify FieldGroup (parent node) to add a class?
I created a simplified codepen version here
I would like depending on validation status, then change the state of FieldGroup So I can properly change the class name. (add has-warning has-danger etc) and ultimately add class to the Form component.
You need to pass a callback to the child component. I just forked your codepen and added some snippet as below.
http://codepen.io/andretw/pen/xRENee
Here is the main concept,
Make a callback function in "parent" component and pass it to the "child" component
i.e. The child component needs an extra prop to get the callback:
<Form>
<FieldGroup>
<Field rules={'required'} cb={yourCallbackFunc}/>
</FieldGroup>
</Form>
In <FieldGroup /> (parent):
class FieldGroup extends React.Component{
constructor(props){
super(props);
this.state = {
color: 'blue'
}
}
cb (msg) {
console.log('doing things here', msg)
}
render() {
const childrenWithProps = React.Children.map(this.props.children,
child => React.cloneElement(child, {
cb: this.cb
})
)
return (
<div class='fields-group'>
<label> field </label>
{ childrenWithProps }
</div>
);
}
};
In <Field /> (child):
class Field extends React.Component{
constructor(props){
super(props);
this.state = {
empty: true
}
this.validate = this.validate.bind(this);
}
validate(e){
let val = e.target.value;
console.log(!val);
this.setState({empty: !val});
//here to notify parent to add a color style!
// do call back here or you may no need to return.
this.props.cb(val)
return !val;
}
render() {
return (
<div>
<input type='text' onBlur ={(event) => this.validate(event)}/>
{this.state.empty && 'empty'}
</div>
);
}
};
And you can do the things you want in the callback function. (You can also pass a callback from <Form /> to the grandson and get it work, but you need to rethink the design of it is good or not.)