how to use carousel in Lightning web component see below code + need some sample example how to implement in lwc - salesforce-lightning

how to use carousel in Lightning web component.need some sample example how to implement in lwc.

this is quite simple similar to other LWC Components, find the below sample code:
HTML:
<lightning-carousel-image
key={myArray.Id}
src={myArray.imageURL}
href={myArray.pageURL}
>
</lightning-carousel-image>
JS:
export default class MyEvents extends LightningElement {
#track myArray = [];
connectedCallback() {
yourApexMethod()
.then(result => {
if (result) {
this.myArray = result;
}
}
}).catch(error => {
})
}
You must need to whitelist your image URL by adding it to CSP trusted sites and Remote Site Settings

Here's the official documentation on lightning-carousel-image
https://developer.salesforce.com/docs/component-library/bundle/lightning-carousel-image/documentation
<lightning-carousel>
<lightning-carousel-image
src="path/to/carousel-01.jpg"
header="First card"
description="First card description"
alternative-text="This is a card"
href="https://www.example.com">
</lightning-carousel-image>
<lightning-carousel-image
src="path/to/carousel-02.jpg"
header="Second card"
description="Second card description"
alternative-text="This is a card"
href="https://www.example.com">
</lightning-carousel-image>
</lightning-carousel>
Also, do the whitelisting as well :)

Related

Embedding a tableau dashboard into react messes up the formatting of the dashboard

I have a tableau dashboard that I am trying to embed into a react website using the tableau-api npm package. Although it looks fine on tableau public, the layout changes when I embed it. How do I ensure that the layout stays the same when I embed it in react?
Edit: here is my code. I used this answer as reference
import React, { Component } from 'react';
import tableau from 'tableau-api';
class Visualization extends Component {
componentDidMount() {
this.initTableau()
}
initTableau() {
const vizUrl = 'url';
const vizContainer = this.vizContainer;
let viz = new window.tableau.Viz(vizContainer, vizUrl)
}
render() {
return (
<div ref={(div) => { this.vizContainer = div }}>
</div>
)
}
}
export default Visualization;
There are a couple of options you should take a look at
Change the size of your dashboard from automatic to fixed (reference here). This will help if you have floating elements in your dashboard
Add your preferred device to the dashboard panel
Change the fit option to entire view
If none of these options work, I would recommend you share a photo of your dashboard and your code to be able to debug

In AEM6, How do I hide a specific component field based on pages for certain country only?

In AEM6, How do I hide a specific component field based on pages for certain country only ?
You can write custom dialog/widget plugin to do that. This is how you attach plugin to your widget:
<title jcr:primaryType="cq:Widget"
fieldLabel="Field to hide"
plugins="hideFieldPlugin"
name="./fieldToHide"
xtype="textfield" />
Next, we need to write plugin and register it:
(function ($) {
var plugin = CQ.Ext.extend(CQ.Ext.emptyFn, {
init: function (fieldToHide) {
var url = CQ.HTTP.getPath();
if (this.shouldBeHidden(url)) {
fieldToHide.hide().disable();
}
},
shouldBeHidden: function (url) {
// some logic
return true;
}
});
CQ.Ext.ComponentMgr.registerPlugin("hideFieldPlugin", plugin);
}($CQ));
JavaScript file needs to be included in Classic UI edit mode. Best way to do that is to use your own custom clientlib or use already existing category, cq.wcm.edit.
If you have more complex logic which goes across multiple widgets, you can attach plugin on dialog level and navigate to the widget objects using dialog.find method.

Changing the document title in React?

I'm trying to update the title of the document in a React app. I have very simple needs for this. The title is essentially used to put the Total component on display even when you're on a different tab.
This was my first instinct:
const React = require('react');
export default class Total extends React.Component {
shouldComponentUpdate(nextProps) {
//otherstuff
document.title = this.props.total.toString();
console.log("Document title: ", document.title);
return true;
}
render() {
document.title = this.props.total;
return (
<div className="text-center">
<h1>{this.props.total}</h1>
</div>
);
}
}
I thought this would just update the document.title every time this component was rendered, but it doesn't appear to do anything.
Not sure what I'm missing here. Probably something to do with how React runs this function - maybe somewhere that the document variable isn't available?
EDIT:
I'm starting a bounty for this question, as I still haven't found any solution. I've updated my code to a more recent version.
A weird development is that the console.log does print out the title I'm looking for. But for some reason, the actual title in the tab isn't updating. This issue is the same across Chrome, Safari, and Firefox.
I now use react-helmet for this purpose, as it allows to customize different meta tags and links, and it also supports SSR.
import { Helmet } from 'react-helmet'
const Total = () => (
<div className="text-center">
<Helmet>
<meta charSet="utf-8" />
<title>{this.props.total}</title>
</Helmet>
<h1>{this.props.total}</h1>
</div>
)
Original answer: there's actually a package by gaeron for this purpose, but in a declarative way:
import React, { Component } from 'react'
import DocumentTitle from 'react-document-title'
export default class Total extends Component {
render () {
return (
<DocumentTitle title={this.props.total}>
<div className='text-center'>
<h1>{this.props.total}</h1>
</div>
</DocumentTitle>
)
}
}
Inside your componentDidMount() function in App.js (or wherever), simply have:
componentDidMount() {
document.title = "Amazing Page";
}
The reason this works is anywhere in your react project you have access to the Js global scope. Go ahead and type window in your sites console. Basically everything there you will be able to access in your React project.
I think webpack-dev-server runs in an iframe mode by default:
https://webpack.github.io/docs/webpack-dev-server.html#iframe-mode
So that might be why your attempts to set the title are failing. Try setting the inline option to true on webpack-dev-server, if you haven't already.
If the react-document-title package isn't working for you, the quick'n'dirty way to do that would be in a lifecycle method, probably both componentDidMount and componentWillReceiveProps (you can read more about those here):
So you would do something like:
const React = require('react');
export default class Total extends React.Component {
// gets called whenever new props are assigned to the component
// but NOT during the initial mount/render
componentWillReceiveProps(nextProps) {
document.title = this.props.total;
}
// gets called during the initial mount/render
componentDidMount() {
document.title = this.props.total;
}
render() {
return (
<div className="text-center">
<h1>{this.props.total}</h1>
</div>
);
}
}
There is a better way of dynamically changing document title with react-helmet package.
As a matter of fact you can dynamically change anything inside <head> tag using react-helmet from inside your component.
const componentA = (props) => {
return (
<div>
<Helmet>
<title>Your dynamic document/page Title</title>
<meta name="description" content="Helmet application" />
</Helmet>
.....other component content
);
}
To change title, meta tags and favicon dynamically at run time react-helmet provides a simple solution. You can also do this in componentDidMount using the standard document interface. In the example below I am using the same code for multiple sites, so helmet is looking for favicon and title from an environment variable
import { Helmet } from "react-helmet";
import { getAppStyles } from '../relative-path';
import { env } from '../relative-path';
<Helmet>
<meta charSet="utf-8" />
<title>{pageTitle[env.app.NAME].title}</title>
<link rel="shortcut icon" href={appStyles.favicon} />
</Helmet>

Using search feature in Ionic framework

I am a UI person and very new to ionic framework.. I wanted to add search feature in my android app built using Ionic framework. After a research i found that I will need to use this plugin https://github.com/djett41/ionic-filter-bar. but there is no detail documentation available. Can anyone please guide how to use this plugin working. I have made all setup but stuck with actual code.
First of all you must install the plugin. You can use bower for that:
bower install ionic-filter-bar --save
and it will copy all the javascript and css needed in the lib folder inside www.
Then you must add the references to the css to your index.html:
<link href="lib/ionic-filter-bar/dist/ionic.filter.bar.css" rel="stylesheet">
same thing for the javascript:
<script src="lib/ionic-filter-bar/dist/ionic.filter.bar.js"></script>
You have to inject the module jett.ionic.filter.bar you your main module:
var app = angular.module('app', [
'ionic',
'jett.ionic.filter.bar'
]);
and you must reference the service $ionicFilterBar in your controller:
angular.module('app')
.controller('home', function($scope, $ionicFilterBar){
});
Now you can start using it.
In my sample I want to trigger the search-box when the user clicks/taps on a icon in the header. I would add this HTML to the view:
<ion-nav-buttons side="secondary">
<button class="button button-icon icon ion-ios-search-strong" ng-click="showFilterBar()">
</button>
</ion-nav-buttons>
The action trigger an event in my controller showFilterBar:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
items: $scope.places,
update: function (filteredItems, filterText) {
$scope.places = filteredItems;
}
});
};
which creates the $ionicFilterBar and shows it.
As you can see here I am using an array of objects $scope.places
$scope.places = [{name:'New York'}, {name: 'London'}, {name: 'Milan'}, {name:'Paris'}];
which I have linked to the items member of my $ionicFilterBar. The update method will give me in filteredItems the items (places) filtered.
You can play with this plunker.
Another option is to use the plugin to actually fetch some data remotely through $http.
If we want to achieve this we can use the update function again.
Now we don't need to bind the items to our array of objects cause we won't need the filtered elements.
We will use the filterText to perform some action:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
// items: $scope.places,
update: function (filteredItems, filterText) {
if (filterText) {
console.log(filterText);
$scope.fetchPlaces(filterText);
}
}
});
};
We will call another function which will, maybe, call $http and return some data which we can bind to our array of objects:
$scope.fetchPlaces = function(searchText)
{
$scope.places = <result of $http call>;
}
Another plunker here.
PS:
If you want to configure it using some sort of customization you must do it in your configuration using the provider $ionicFilterBarConfigProvider:
angular.module('app')
.config(function($ionicFilterBarConfigProvider){
$ionicFilterBarConfigProvider.clear('ion-ios-close-empty');
})
PPS:
In my plunker I've included the css and the script directly copying it from the source.
UPDATE:
Someone asked not to replace the list with the updated one.
My cheap and dirty solution is to check if the filterText contains some values. If it's empty (no searches) we go throught each element an set a property found = false otherwise we compare the places array we the filteredItems array.
Matching elements will be marked as found.
function allNotFound(filteredItems) {
angular.forEach($scope.places, function(item){
item.found = false;
});
}
function matchingItems(filteredItems) {
angular.forEach($scope.places, function(item){
var found = $filter('filter')(filteredItems, {name: item.name});
if (found && found.length > 0) {
console.log('found', item.name);
item.found = true;
} else {
item.found = false;
console.log('not found', item.name);
}
});
and now we can integrate the filter bar this way:
$scope.showFilterBar = function () {
var filterBarInstance = $ionicFilterBar.show({
cancelText: "<i class='ion-ios-close-outline'></i>",
items: $scope.places,
update: function (filteredItems, filterText) {
if (!filterText) {
allNotFound();
} else {
matchingItems(filteredItems);
}
}
});
};
We can use the found attribute of the object to change the style of the element.
As always, a Plunker to show how it works.
Ionic uses Angular, and Angular include an atributte filter very useful. Look this: https://docs.angularjs.org/api/ng/filter/filter and the example there. Regards

CrossRider: What library method scope can be used in a popup?

I have saved data in the appAPI.db.async database. And now I want to display it in the popup page.
Here's what I have in the popup page:
function crossriderMain($) {
var db_keys = appAPI.db.async.getKeys();
db_keys.forEach(
function(key)
{
$("ul#id").append("<li>" + appAPI.db.async.get(key).url + "</li>");
});
}
</script>
</head>
<body>
<ul id="history">History</ul>
</body>
</html>
which doesn't give the intended result.
What I want to know is what's available for me when inside a popup page?.
Also, as an aside question: how do I open a browser tab from an HTML page in my resources directory, instead of a popup that won't take the whole screen space, in the browserAction.onClick handler?
Something like that in background.js:
appAPI.browserAction.onClick(
function()
{
appAPI.tabs.create("/Resources/templates/history.html");
}
);
Thanks (:->)
Answer to question 1
appAPI.db.async is asynchronous by design and hence you must use a callback to receive and use the values from the database. Additionally, it is not necessary to get the keys first and then their associated data; you can simply achieve your goal in one step using appAPI.db.async.getList.
Hence, using your example the code should be:
function crossriderMain($) {
appAPI.db.async.getList(function(arrayOfItems) {
for (var i=0; i<arrayOfItems.length; i++) {
$("ul#id").append("<li>" + arrayOfItems[i].value + "</li>");
}
});
}
Answer to question 2
To create a new tab that opens a resource page, use the appAPI.openURL method.
Hence, using your example the code should be:
appAPI.ready(function($) {
// When using a button, first set the icon!
appAPI.browserAction.setResourceIcon('images/icon.png');
appAPI.browserAction.onClick(function() {
appAPI.openURL({
resourcePath: "templates/history.html",
where: "tab",
});
});
});
[Disclaimer: I am a Crossrider employee]