>> Welcome everyone. It is Monday.
Hopefully, you have
your coffee ready.
For those of you in
Europe and in Oceana,
hopefully, you've had
a couple of beers.
So we are here today
to start a webinar.
It is 10 O'clock here in
the Pacific in Northwest.
We have Ivan Ficko,
who's going to be talking about
PowerApps Component Framework and
what it means to Dynamics 365.
Ivan, what do you have for us?
>> Good to see you
guys. Today, I will
talk about component
framework and how we
can achieve better UX experience
in our implementations in
PowerApps and dynamics.
I hope you-all like it.
So should we start?
>> [inaudible].
>> Let's go into the PowerPoint.
So to start with,
WhoAmIRequest,
[inaudible]. So who am I?
I'm a software developer
based in Zagreb, Croatia.
I am working in Dynamic Space
for four years now and recently,
six months ago, I have been
awarded as a Business
Applications MVP.
You can find my social media down
there if you want to
contact me and feel
free to drop a question if you have
some thing about PCF
or anything else.
So first, let's start how
we did it in the past.
So how we did in the past,
there was a Holy Trinity:
HTML, TSS, and JavaScript.
We had those three files across
the system uploaded everywhere.
We didn't mind how we didn't do it,
we just did it.
After we created HTML,
we were just adding JavaScript file,
and more and more
JavaScript files in it,
and after a while,
there is a pretty big
mess in our system.
We need to maintain that
code and stop crowd it,
but how can we do that because
JavaScript is all around.
So we need another tool
to do the job for us in
the front-end development.
That's how the component
framework was born.
But let's talk about
history for a second.
I was pretty hyped when
I heard first time for
the custom control framework
that it was called that way.
In the past, in 2017,
it was I think an
Extreme or something.
We had an alpha version
there who were all hyped,
but there is no actual snippets
to be shared publicly with us,
so we didn't know how to
build those components.
Year after, the custom
controlled framework
evolved a bit more and I
call that a Beta Version.
We have their few snippets
so we can see how the actual
components can be made,
but as it was still in development,
nobody paid that much attention
to the custom control framework.
But last year in 2019,
there was a rebranding that was
called PowerApps Component
Framework as today,
and we had actual full documentation
and support for model-driven apps,
and as of now,
the support for Canvas is GA now too,
so we can create
components for [inaudible]
substitute at the moment.
But what actually BCF
Component Framework is,
it is the framework for
building the controls that
have a rich UX experience
and it provides us with
a powerful tool set that will
make the UX even better.
Because as you know,
back in Dynamics days,
there were like simple
components out there,
like text boxes, drop-downs
and stuff like that.
But we missed some part that we
wanted to create more rich component.
We used web resources for that stuff,
but I don't think that's
the best tool now.
Back then, it was,
but now, it isn't.
It's primarily focused on
that population because you
need to actually code them.
It's not usable.
It can be developed by the makers
or the citizen developers,
not only by developers.
The only limit is our imagination
because if you want
to create something,
you just need to have the idea,
everything else is
probably provided by
the framework and you can
create that stuff as long
as you have an idea.
The great thing about this is,
that you can use
modern technologies like
React and Office Fabric UI,
that I encourage you to use.
Today, I will not show
you the demo examples
with those technologies
because I think it's
better to start with JavaScript
and TouchScript to understand
the basics and then you evolve
to using React and Fabric UI.
There are two types of
controls that you can make.
So first one is a Field Control.
Field Control is bound to one
field on deform and it replaces,
in most scenarios, the original
mask on that controller.
For example, you have
textbooks control and you
want to replace it with,
I don't know, like in this example,
with the drop down
that shows countries,
just type in the name of the
country but it will give you
a much richer experience by showing
the flag and the country name.
Let's see another control.
For example, this one shows
the two options of control,
that just adds picture
on top of the value.
It can be pretty neat stuff.
So we're all focused more
on images than on tags.
So we can bring
the experience more better
with this kind of control.
Or for example, this one we
know that we don't have ability
to put suffixes or
prefixes on the text input
fields but this control,
for example, allows us to put
a suffix in this example.
For example, number and
the centimeters followed
by pretty cool stuff.
So the second type of control
is the Dataset Control.
That control is bound to
actual dataset or view
in our applications.
So we have a View of, I don't know,
Accounts and you want to
show the position of
that account on a map.
So you can have an address,
you can use Google Maps,
Azure maps and put that
information on the map.
As you can see, it's much
better if you show that on
a map instead of just showing
a text of an address.
Next one that we have here
is SharePoint control.
That is put under
SharePoint place and
that displays the thumbnails of
documents stored in SharePoint.
It's pretty nice to see
the actual document
before you download it or open it.
The last one here is
an example of [inaudible]
diagram that you can
put on any entity that has
and the start and end date
and some descriptions.
As you can see here, you
can see the progress also,
so it might ask this,
on a 100 percent,
it will show with a green color and
100 percent mark and it's [inaudible]
, it's organized control.
When you look at it, you get
data straight away from
the picture you see.
But how can we actually
make one control?
We need to meet some prerequisites.
So prerequisites that
we need has no JS,
that's not a familiar tool for
most of the people that
come from Dynamics world
because you're more focused on
back-end stuff for a long time,
and we didn't use the modern
technologies on our front-end.
So the first step is definitely
node and we need to use
long-term support because it's
recommended by the product group.
The second thing you need to have
is.Net Framework version 462.
I don't think that's a
big issue for most of
you because all the
plug-in development
is nowadays working on debt version
because the latest NuGet package
requires it as the
first prerequisite.
Third one is the Dev environment.
You can build your
controls in Visual Studio
2017 Plus or in Visual Studio Code,
but my recommendation is
to use Visual Studio Code.
Why? Because I do need
to move outside of
Visual Studio code while
I'm developing my control,
I can have a code opened
to code editor and
the terminal just below that to run
all the NPM commands that I need.
Also, the last one is ideas,
ideas, ideas. Why is that?
Because if you don't have idea,
certainly you will not
build anything at all.
When you want to start,
you need to download PowerApp CLI.
That's the tool that is
one stop developer
command line interface
that allows you everything
about the PCF framework.
You can initialize the repository,
run the debugging session,
you can deploy your controls
straight from the CLI,
you can pack your
solution as managed or
unmanaged for the distribution
and all the things around it.
I think that's the first step to ALM,
not only for the PCF,
but for the whole PowerApps
and Power Platform.
Lately, there is a support
for initializing the plugins,
project for uploading plug-ins
to the actual environments.
So I think you should
definitely keep your eye on
this two especially for the PCF,
but for the PowerApps in general.
As you can see in this picture,
a few simple commands that you can
run and initialize your repository.
So you do pick pack PCF in it,
and it will initialize
the project structure for
you and when you do it,
you will get the following.
So the basic project
structure is you have
a good control folder and that
will contain two main parts.
That's the control
manifest file, index.ts,
that holds the whole business
logic, and additionally,
you can have as many folders as you
like for the additional
resources like Stylesheets.
So the first one is manifest file,
that's the file that
describes your control
from the UI perspective
to configuration,
to what your PCF control will
use in terms of various
resources like codes,
scripts, CSS files, RSX for
translations, images, and etc.
First name is the control,
that's the name of
your control and how
it will be displayed to the
user and they install it.
The second part is property part,
that will contain as much properties
you want because with
these properties,
you can configure your tool to
work just the way you want.
So you can bind it like in this
example single line of text,
but you can have multiple
properties that don't
need to be bound to any field.
It can be just a text field that will
hold the band words that you will
use in your components later.
Other than that in fact
there is an index.js file.
That file is, as the
name says, TypeScript.
I didn't mention it before,
but the PCF controls are
built in TypeScript.
So if you're not familiar
with TypeScript,
it's a superset of JavaScript
and if you did.NET development,
you'll be pretty familiar
with the syntax.
I can say pretty much the same.
It's not the same, but you
get along with really fast.
When you build the project,
you will have four methods.
So init, updateView,
getOutputs and destroy.
Init as it's name says,
it is used for initializing
your component,
or the initialization code will go in
this method and it's
called once on load.
The second one is updateView that is
called every time
when Canvas changes.
For example, if you
resize the screen,
that method will be called
if some business tool,
so JavaScript triggered
that some field
is required read-only
or stuff like that,
this method will be called.
So you handle all the
changes in this method.
GetOutputs method is the method that
will send the values from your UI,
the UI that is used
by your component,
to the actual form.
So if you send a value from
this method through your form,
you will get an unsaved
changes on your form and
that way you know that you send
something back to your form.
The destroy method is the last one,
but not the least,
because I don't see
that people are using
that method that much and I
think that it's important.
The method is called when we
don't need the component anymore.
So when we change the
form for example,
and there you need to
clean up your code.
So for example, clean up all
the event handlers that you
use in your component
just to be sure that they're
not triggered anymore.
When we have our component,
we can put it on our
organization and configure it.
How to configure a component?
So easy. You open your form designer,
at a moment your
custom controls can be
only be modified in
the old lab interface.
So you open the old lab interface,
open the field properties,
select add control and at you right,
you can see the list of all controls.
Select one control, click, "Add",
and then you will have give
you those shown on the left.
The most important part here is
you can see the radio buttons.
You need to ensure that
you selected control for
all the interfaces that
you want to display it
to here because that's
where the most people fail.
They don't click on two
radio buttons and they say,
"I didn't see the control."
That's the most important part.
Then you can configure
your properties on the
bottom of the screen.
There is always one bound
property on the field,
and you can add as many
properties as you want,
but you configure all of that here.
When you're ready, you just hit
"Okay" and you're ready to go,
your controller will
be shown in the form.
Community is always a big part
of Microsoft technologies.
PCF, I think it's a pretty
special one because most of
controls are shared for public
from members from the community.
It's really good stuff.
There is a pretty big
thing made by Guido.
It's called PCF gallery.
There is a collection of PCF
controls made by the community.
Most of controls are open
source and you can find them on
the PCF galleries
because we are doing
great stuff to collect
all those controls.
There are almost 200 controls
at a moment and 100 authors.
So it's a pretty big
part in the community.
PCF was like [inaudible]
in community.
There's also an ideas section.
If you're not a developer,
you can go there,
post your great idea.
You hope that someone from the
community will take care of it,
and you will have your
control as soon as possible.
Now that's all for my overview
and we should jump straight to
the demo part and let
[inaudible] with us
because we'll try to do
pull component from zero,
and try to deploy it to our
environment at the end of the demo.
What will we make?
We'll make pretty simple
control that will have
an input field that will hold
the GitHub repository username.
Below that, there will be
an image tag that will hold
the image of the avatar
shown on GitHub.
I think it's a pretty basic control
that will show you-all the basic
stuff you need to know about
components and how to make them.
So let's jump into the demo part.
[inaudible] of course
that real quick.
First of all, we need
to make a directory for
our control, cd GitControl.
We need to run the first command
provided by the CLI tool.
So it's pac pcf init.
This method needs few parameters
to initialize the repository.
So the first one,
as you can see is the namespace.
Most of that component is fic.
So the name, let say it's
GitControl and template that
can be field or dataset.
I think that dataset which is a more,
more complex that will make the
field component in this example.
So now we have a field
component initialized.
As you can see, we need to run NPM
install to get all the
dependencies, so NPM.
If you're familiar with NPM,
you just find NPM by,
and it will start downloading
the dependencies.
While it's downloading
the dependencies,
let's try to open one
more command line
just to show you, so cd GitControl.
Sorry, GitControl, and
open Visual Studio,
you can open Visual Studio Coding.
That directory just by
typing code dot, code dot.
When we run that,
we'll open Visual Studio Code
with our new initialized project.
It's running so slow now.
Why that's so, but.
Now we see the basic
structure of our component.
There is a root folder that contains
manifest file and the index ts file.
The first stop here is
control manifest files.
So we have a control tack
here that will hold all
the information about
the control like just put
a space here just to
make it more readable.
You can add a description and
everything else up there.
But the just jump to property parts.
So the property part is
the part where you define
all the configuration
for your components.
In our example, there is a single
line of text property here,
so it will be bound,
as you can see on your right,
to the one of
the single line text fields on the
form that we want to put into.
Let's change the name to
gitUsername that we'll use.
That's a typo again, username.
That's the first one.
It will just send the
data back to our control.
Just let us open terminal real quick.
I just check it again.
NPMs on the lab,
it's still running, but
it will be finished soon.
Now we can switch to index ts.
As you can see,
you have some errors that because
the NPM is still working on.
But you can see the
basic structure here.
So init, updateView,
getOutputs, and destroy.
First thing we want to
use is init method.
It contains few parameters
that will be used in our demo.
So the first one is context.
The context holds the
data about your control.
So you need to retrieve the data
from the field that you
defined in your manifest.
You do it via context object and
all this stuff I will show
you later how to use it.
Now if I would change,
that's the matter,
that you need to call to go
through the getOutputs method.
Every time you bring that
notify output change method,
you will go to getOuts method
and do your logic there.
State, state is the object defaults,
the data about the state.
So if you wanted to stay
persistent state across the forms,
you need to add stuff in that state,
but we'll not use
that in this example.
The container, the container is
HTML div element that holds
everything in your control.
If you want to add
something to your control,
you add a child to get div element.
As I said before,
we need to create few HTML.
So one is the input and the
second one is the image,
one that will hold the image.
So we'll add textbox equals
document.createElement
input, textbox one.
Let image equals
document.createElement.
You have all elements there,
but those elements are here
and they're not added to
the actual Container.
So we need to add those elements
to the Container to be
visible in our control.
So Container add child.
Let's start once more and
add an image one too.
Now we have both elements on our
Canvas and how to change that.
First, we need to run NPM script,
NPM build just to check
that our syntax is
just right and that our
component is working fine.
It will initiate the
built for our component.
It can take a few
seconds or something,
but if we don't have any errors,
we can say that our component
is ready for testing.
How can we test our component?
We can test it by one
inc npm start watch.
What this command does,
it opens the lovely testing harness
that is included in a
framework that allows us to
test the framework inside
that harness before
uploading or deploying our component
to the actual environment.
We can do [inaudible] testing
here, especially I think.
I actually have one running.
So here we have our inputs
control that is just shown there,
and one image that is showing
just on the left because
it's not holding any data.
We can't see the difference,
but it's not doing anything
special at the moment.
We need to add some logic here.
What we need to do
is we can try to get
the initial state of our component
by expanding the context there.
So contexts, there are few
API codes that you hold
called here and the
most important one
from this phase is parameters.
So in parameters, we have
our gitUsername that is defined
in our manifest file up there.
So we have that single line
of text next about here.
When we gitUsername with raw,
we get the actual value of that
property bind to our form.
So let username equals context.raw.
But raw is not always
full string and we
need to ensure that we
handle that kind of errors,
sorry, that just here.
Let a textbox.value=username.
So this allows us to
preload our text field
with a value that is
used on the form before.
So we had a populated value.
We want to show that value to the
user is right here. Save that.
Changes are detected and we
can jump to the harness.
So if we jump to the harness,
for example, let's put this code
and it persists that stage.
So if I refresh it,
our component will be preloaded with
the text on the actual property.
What now, we go back
to our code and I
will now speed up the process
and walk you through,
okay, that's what we'll do now.
We need to add some event
handlers to our textbox
to download the avatar from GitHub
and show it in our image tack.
So I have a method here,
so that's a pretty basic
method that we'll call
the GitHub API with
username that is passed
in and put the source
of the image container to the
response that has power to add URL,
that's actual URL of
the avatar picture.
So now we need to add event
handler for our textbox control.
Now what do we have here?
I have code that is not
working at a moment.
But as you can see,
there are some variables
that we don't still have.
The Clark with thesis that you
need to initialize some
private variables that will be
accessible on the class
level so you can use it
all across your application control.
I pasted some here.
So we have a notifyOutputChanged
that is also here.
So in the initialization,
we need to initialize our
private variable with this one.
So we can use that in
all the other matters,
not just in init one.
Let's do this.
Also initialize our textbox on
change event just because we
need to persist our desk,
so our class, so we can access
the variables in the OnChange event.
OnChange event is down there.
So what is this value?
This value is actually a
variable that will hold
the current value of our
textbox input field.
So when the textbox input is changed,
we store the variable here,
so we can inserted it and
use it in the getOutputs.
This is why we OnChange,
we will save that value here,
pass the image in our method and
the value that is
put into the textbox
and run the notifyOutputChanged
to go here.
But first, we need to add
some line of codes up
there just to ensure that we have
initialized those private variables.
So this.textbox=textbox
and same for the image.
So this._image=image.
Now we have our private variables
exposed to the other methods.
Now, we will add event
listener to our textbox.
So we'll add a listener
that is listening
on input that is basically
when the user hits a key,
it will record that and call
the textbox OnChange method.
Now we have a pretty basic
scenario that will do something,
but let's add here.
So here, we call the
notifyOutputChange that will bring
us back to getOutput's method.
The return statement here has
all the properties defined in
our control bound properties.
So if we have the property here,
GitHub username, so we change
the value in our textbox.
We need to send that
value back to the UI.
How we do it? Just by using our
private variable called value.
We store that value in
our textbox OnChange,
so we can use it here.
Now we have a pretty basic
scenario and we can test it out.
Just hit "Save" and
open or harness again.
Okay, our API is working,
let's say my handle on
GitHub is dynamicsninja.
Here is the image from my GitHub.
You can add in there and
type something else.
So most of you know Jonas Rapp.
So I know his handle,
so I tried to display here,
and we can see that our control is
working as you can
see when I type here.
Also, the value here on
the right is changed.
So that value here is
sent back to the UI.
That's the whole point of the story.
So to get its method
and turning probably
here and that will cause the
unsaved changes on the form.
Now we need to spice things a bit.
Let's add a new property here.
Let's say that we want to
add some styling and we need
to make our shape of the
image circle or square,
depending on the situation.
Sometimes I want a square,
sometimes I want circle
and how can I do that?
I pasted another
property that is called
imageShape and its type of Enum,
and its usages input is not bound
to any controls on the form.
It's just an input field that we will
define on the configuration page of
our control and is
a required field and it calls
to value square and circle.
Depending on the value here,
we will change the shape
of file image tag.
Then you add something
new to the manifest you
need to run npm run build again
just to get the latest typing
generated by the framework
dot all the IntelliSense
in your index.ts.
When the build is running,
we can jump here and
let's paste the code that will
get us the value from there.
So here let's take shape.
Let's call the variable there and
read something from the
imageShape property.
As you can see it returns only
square and circle values.
Well, okay, we see.
Now we need to style our image tag,
but we need some CSS to
achieve that, of course.
How do we do that?
We get back to the manifest and
check the resources part of this.
You can see there is a
line that states CSS.
Let's copy that one
[inaudible]. Let's do this one.
You can see we need to create
the root CSS folder and create
a new file named dot CSS.
That way we forced our PCF to load
the CSS style sheet
from the CSS folder
called GitControl and that way we
can use the [inaudible] control.
If we didn't do that,
our CSS will not be packed,
will not be included in our control.
We couldn't get styling that way,
so we need to include it first
here and then add some code.
I have some code here just to
make our control a
little bit prettier.
So I pasted some CSS,
but you can see I have some
prefixes here. Why is that so?
Because our control can interfere
with the other UI parts
in our applications.
So we need to prefix our
CSS with the name-space,
and the control name is actually
that was under my test1.
You can find the name
infrastructure here.
So copy this one,
just replace everything with it.
So we have a little bit
of styling that shows
border and stuff, PowerApps purple.
Of course, we have this line that
will make us to use all
the available space for
input control and border-radius
for the circle plus
if we selected circle and
we didn't select circle.
But let's jump to the harness.
I forgot to one,
of course the npm start watch.
That way we'll get our
testing harness again,
so we can test our control.
It will be finished
in time as I think
and we'll see the newly created
property that is [inaudible].
So it will show as a drop
down and we can select
the value square or a circle shape.
Now we see there is val here.
You see that picture showing
again and we have here
the Enum square circle
that when we click on it,
it will not do anything because
we didn't process that.
But it's always needed
to know that you need to
initialize those value at start,
at one initial start-up
your component because
the value that is sent here is
always the same for the one load.
So on one load you can have
just one while we're here.
How can we do that?
We just get back to our code.
So we have the shape that
will bold circle or square.
Depending on that, we need
to add a class to our shape.
The shape, if our
shape equals circle,
then we will add the circle
class that is defined in
the CSS that we'll just round
up the border of our image.
It's the only thing it does.
You need to do that in order
to get the right shape.
Let's jump to the harness
again. We have square.
As I said before,
this state is preserved in a session,
so if I change this to circle,
refresh the harness, I will
get the round shape here.
But as you can see on load,
we have dynamics danger here but
there's no image. Why is that so?
Because we need to code
our method for setting
the actual image here.
We do it, of course with an image.
There, we have an image,
we've got the username.
If we save that,
open the harness again,
reload it, we have our image here.
I think it's a really good start,
that it shows you how you can add
simple comparative logic here.
Now, I wanted to share with you
simple best practices and what can
you do here to make a
control group pattern.
The first thing is updateView method.
So if you want your controls to
scale properly on
various display screens,
you need to add that
logic to updateView.
Or for example, if you have
fields that are sometimes locked,
maybe by the business logic or that
they implement field level security,
it's also handled here.
The other thing is we can add here
pretty simple code that will
make our component read-only.
So we have textbox disabled property,
set to context dark mode.
Dark mode has several
options and you can have it.
Is it control visible or
not or is it disabled?
In this case, if it's disabled,
your textbox control loaded
will also be disabled.
It's changed in real time,
if some business will change
the visibility or disable
state of your field,
it will be shown straight away.
So you'll handle those things here.
As I told before,
there is the destroy method.
You need to clean up all the
code here that you want to
clear and that you don't want
to be triggered anymore
when you leave the page.
You can do that just
by simple command.
So we have a textbox that
is exposed but here,
we just run removeEventListener
input on textbox change.
Now we are safe,
we did a clean up after
the destroy method,
and that's the way you do
it and you should always
clear all the event editors at
the end of your controller.
Now, we have quite a control
that is working and so now,
we need to deploy it.
We ended with our testing so we
are all good with our control.
What do we do next?
We first stop our watch function,
let's say go PHC because
we want to deploy.
What this does, it show us
the old authenticated
profile that we have here.
So we need to authenticate
our app, our Visual CDK,
to deploy for us
the control in the environment.
How do we do that?
So create, and in order create,
we need to provide basic
URL of our value cell.
Let's see. I have my
environment here.
So the URL of my
environment is that one,
we just copy, one more space here,
and the pop-up for
authentication will pop up.
We need to login.
I think I have to reload my account.
I just need to input my password.
Again. After successful
authentication,
we have a valid connection
that we can use to
push our command control
to the environment.
Pushing the component is done by
PAC PCF push unit. Easy as that.
You need to provide of
course, a few parameters.
There must be a valid
publisher prefix
on the environment and as I use,
most of the time take,
I will push it with a fit
prefix on my environment.
When we run that command,
our component is pushed
to the environment.
What it does in the background,
it creates a temporary
solution, unmanaged one,
that will pack everything
we have of our control,
put it in that solution,
publish it on the
environment and after that,
we have our component
live on the environment and
we can use it on the form.
It can take some time for
the first push because
it pushes everything,
and every time you
try to push it again,
it will just search for
the differences and
push only the differences that
were made to your control.
For example, if you made a
difference on in the CSS,
only the CSS file will be
pushed to your environment.
If you made a difference
on the index TS,
only the JavaScript that
there will be pushed,
and stuff like that.
But now, we should wait for
our solution to import.
The first step is the longest
one but after a few seconds,
we'll have successfully
published solution on
our environment and we will
check how it looks like
on the environment.
So one more step and
it should be online.
Today, it's going pretty
slow but it's usually
a little bit faster.
So now we have our
solution published.
How can we check it?
We go to our made
"PowerApps", to "Solutions".
As you can see,
there is a new created temporary
solution that has your prefix,
and when you open it,
you will see that there is
our control uploaded there.
Now when we have that control,
it's time to configure it.
We go to our solution that
I had prepared before,
that is basic one that has
only contact entity and that
contact entity I created,
fields that will hold
the GitHub username,
I added that field to the form
but the field is altered botsman.
We need to apply our
control forget field.
First of all, we need to use
that interface to achieve that.
It's possible in the maker
experience but with some hacks,
as I can say, with some
plugging registrations.
But for now, we need to go
to the web interface and do our
customers utilizations there.
We can go open the form and pick
the most basic form
that this contact one.
It's talking a while today.
We'll have the form shown soon.
So let's open the contact form.
First thing, we need to locate
the field that we want to
use control. Here's the one.
We'll make it a little bit bigger.
So GitHub username, it's a
simple single line of text.
You can bind your control
only to the type that you
defined in your manifest file.
So in our example,
our fields that is bounded
is single line of text.
So we need to make sure that we
have a single line of text field
on our form to kill the control one.
Go to the "Controls" tab,
"Add Control", and search
for our "Git Control".
Here we go. Click "Add".
Now we have our control.
First thing I do every time
is click all the radio
buttons to my control,
to be shown on the all interfaces.
But of course, you can
do some accommodations,
so show them web and
tablet and on phone.
For now, use it everywhere.
It's fine to GitHub username
with single line of text field,
you can change that
display property keys also
in the manifest file.
But for the sake of
time, we didn't do that.
But you can change the
display name here,
description here, and it will
be shown in the interface.
So now we have our second one that is
property that will be used to
show square or circle shape.
Let's move on to circle.
At the end, I don't want to use
out of the box control that's
highly out of the box control
and to use only our custom one.
Click "Okay", save publish as always,
and when the form is published,
we can go to check
our form application.
I have my application here,
so it's the same application
in that solution.
We get to create a new contact.
Okay, maybe, I just need to
refresh the hard reload to
keep up with the changes.
When we see the only text
box in the shape here,
you're ready here on top case
and then name, just to be sure.
Here we go [inaudible].
Here we go, we have
massive changes, save.
To know that our values are stored,
we can refresh the page and
see if the value persisted.
As we can see the
value is persisting,
but okay, it's loading and
every thing is working fine.
I hope that now you
have or knew how to
make your control and deploy
it on your environment.
Of course, there are methods to,
more advanced methods
that allow you to
define the solution
structure should be managed,
unmanaged to pack multiple controls
in this solution by a CLI.
But that's more
advanced stuff that you
can learn from the docs page.
I hope that with this method
you can create everything you
want and even there you can
just build your other solution,
add existing custom controlled
packet to your solution,
export it as managed
and you're good to go.
You have just controlling
the managed solution as
it should be at the end.
Now let's wrap it up with one slide.
One last one. One last slide.
So final thoughts, what do we want
to achieve with this supposed?
We want to, I want to
make all the controls in
PCF framework for the
future because it allows
me much more flexibility and
it has defined interface.
That's important because
Microsoft provided
us interface that we need to use in
order that our controls
will not break
with any updates that will
become available in future.
So as long as you do it by the
interface, you'll get this.
Second big thing is the
custom controls are reusable,
maintainable and easily upgradable.
That was not the case
with our web resources.
Our web resources were made
just for the one purpose.
We were using them on one project,
90 percent of the time.
We didn't use those web
resources on any other projects.
Of course, there are more exceptions,
but most of the time single use
only and that's why there is a PCF,
the only framework that force us
to make reusable and more
maintainable components.
Our JavaScript was
all around the place.
We should replace our event
handlers with custom controls.
For example, we have
complex JavaScript logic that
is doing some validations
in the field,
made data, PCF controls
do logic there.
If you are not a developer,
you're a maker, there's
also alternative,
and that's embedded canvas apps.
Embedded canvas app is also
PCF control that allows us to
data canvas app inside the form.
But I don't encourage to
use embedded canvas apps
in complex scenarios.
Use it for the simple ones
or the quick win situations.
But for the more complex logic,
definitely use PCF
controls that can be used
in no model apps or canvas
apps at the moment,
I think that the brightest
example is canvas app component.
Canvas app component can contain
multiple PCF components inside it.
So from small building blocks,
you build a bigger building block
called canvas app component and back
it as one big solution that can be
used all around your instances.
For example, that's the big
example for canvas apps.
But for model driven apps,
you can have a pretty big
implementations that have
a single big PCF control
that will hold all your logic and
the complex scenarios inside it.
Yeah, I think that that's all for me.
I hope you enjoyed it and you
will learn something new.
Since we are running out of time,
I'm open for some questions
if you want to ask me,
and thank you for attention.
Here we go. Do we
have some questions?
>> I think we're close
to the time on it here,
so I don't know if we'll have
time to gather any questions.
But if you do have after the facts,
we certainly shared different ways
through them to get a hold of you.
We certainly encourage everyone
to go to the community forms,
community.powerapps.com,
and certainly post
in the PCF section on any
questions that you might have.
>> Okay, sounds fine to me.
Anybody can reach me out for
some questions personally
on my social media.
But of course, there are questions
you can pose in [inaudible].
>> All right, with that said,
since we are at a one
hour time limits,
we will go ahead and wrap this up.
Thank you, Ivan, for coming on.
I know it's late in Croatia,
so certainly appreciate
you joining us.
>> Yeah, it's been a
pleasure, really. Thank you.
>> Okay. For everyone.
We will be back on next week
at same time at 10 o'clock.
If you certainly enjoyed
this, let us know.
>> Thank you. Bye-bye.
