Hans Karlsen (talk | contribs) No edit summary |
No edit summary |
||
Line 1: | Line 1: | ||
In the Turnkey Web application you will find a folder EXT_Components. | In the Turnkey Web application, you will find a folder named EXT_Components. | ||
In the EXT_Components folder you can | In the EXT_Components folder, you can create subfolders. | ||
* Each subfolder will constitute one Component - the name of the folder is the component name. | |||
- | * Each component can have js scripts to be loaded when the angular app starts. All js found here will be loaded, if the script filename contains '_module' - we will add type='module' to the script tag. | ||
* Each component must have a cshtml file for content structure - name this <component name>.cshtml | |||
* Each component probably has CSS style sheets - all CSS found here will be loaded. If <name>.min.css is found, then <name>.css is skipped. | |||
==== Use in the Model ==== | |||
==== Use in the | |||
Use a component in MDriven Designer by setting UIOverride on ViewModelColumn and: | Use a component in MDriven Designer by setting UIOverride on ViewModelColumn and: | ||
tagged value Angular_Ext_Component=<component name> | tagged value Angular_Ext_Component=<component name> | ||
==== Implement a | ==== Implement a Simple Column Override ==== | ||
If your component is very simple - you only want to change the HTML that we generate for the ViewModelColumn - you can do as [https://youtu.be/73egBsyzuP4 described in this video] | If your component is very simple - you only want to change the HTML that we generate for the ViewModelColumn - you can do as [https://youtu.be/73egBsyzuP4 described in this video] | ||
The binding in your replacement | The binding in your replacement HTML takes this form: | ||
<input ng-model='data.TheViewModelColumnToBindTo'/> | <input ng-model='data.TheViewModelColumnToBindTo'/> | ||
But that will require you to do a new component for each unique column (TheViewModelColumnToBindTo1,TheViewModelColumnToBindTo2). | But that will require you to do a new component for each unique column (TheViewModelColumnToBindTo1,TheViewModelColumnToBindTo2). | ||
To mitigate that need we do | To mitigate that need, we do this when compiling your replacement HTML: | ||
OverrideDiv.AppendHtml(args.ResultingOverrideHTML.Replace("[ViewModelColumnName]", e.ViewModelColumn.RuntimeName)); | OverrideDiv.AppendHtml(args.ResultingOverrideHTML.Replace("[ViewModelColumnName]", e.ViewModelColumn.RuntimeName)); | ||
This means that to write a more generic replacement control | This means that we can use an expression like this to write a more generic replacement control: | ||
<input ng-model='data.[ViewModelColumnName]'/> | <input ng-model='data.[ViewModelColumnName]'/> | ||
'''Update:''' We now also search and replace "[ViewModelClassName]". This means | '''Update:''' We now also search and replace "[ViewModelClassName]". This means you can write this ng-model='vCurrent_[ViewModelClassName]' to bind to the vCurrent variable of the ViewModelClass that has the component. | ||
''' | '''Update 2:''' We now also search and replace "[ViewModelColumnLabel]". This means you can write this <nowiki><div>[ViewModelColumnLabel]</div></nowiki> to use the columns designed presentation string in your component. | ||
==== Implement a Component with | ==== Implement a Component with Js, CSS, and HTML ==== | ||
Example: | Example: | ||
<pre> | <pre> | ||
Line 65: | Line 62: | ||
If you use Typescript instead of javascript you can use this code: | If you use Typescript instead of javascript, you can use this code: | ||
<pre> | <pre> | ||
****** Typescript if you prefer- save as EXT_Components/test1/test1.ts (js is generated by ts) ****** | ****** Typescript if you prefer- save as EXT_Components/test1/test1.ts (js is generated by ts) ****** | ||
Line 96: | Line 93: | ||
</pre> | </pre> | ||
When using Typescript you may want to include a file like the one below to trigger the correct output: | When using Typescript, you may want to include a file like the one below to trigger the correct output: | ||
<pre> | <pre> | ||
*********** IF YOU USE TYPESCRIPT Consider adding this file to your folder | *********** IF YOU USE TYPESCRIPT Consider adding this file to your folder | ||
Line 113: | Line 110: | ||
"node_modules" | "node_modules" | ||
] | ] | ||
}</pre>To get global scripts to run before loading of components look at [[AppWideAngularScriptIncludes]] | }</pre>To get global scripts to run before loading of components, look at [[AppWideAngularScriptIncludes]] | ||
An example of how to integrate [[TinyMCE editor]] in your app. | |||
Example on [[A simple table component for just listing a collection]] without actions / selections. | Example on [[A simple table component for just listing a collection]] without actions/selections. | ||
Another article describing Turnkey components https://blog.mdriven.net/svg-and-mdriven-turnkey-components/ | Another article describing Turnkey components: https://blog.mdriven.net/svg-and-mdriven-turnkey-components/ | ||
==== New 2023 ==== | ==== New 2023 ==== |
Revision as of 06:52, 20 February 2023
In the Turnkey Web application, you will find a folder named EXT_Components.
In the EXT_Components folder, you can create subfolders.
- Each subfolder will constitute one Component - the name of the folder is the component name.
- Each component can have js scripts to be loaded when the angular app starts. All js found here will be loaded, if the script filename contains '_module' - we will add type='module' to the script tag.
- Each component must have a cshtml file for content structure - name this <component name>.cshtml
- Each component probably has CSS style sheets - all CSS found here will be loaded. If <name>.min.css is found, then <name>.css is skipped.
Use in the Model
Use a component in MDriven Designer by setting UIOverride on ViewModelColumn and:
tagged value Angular_Ext_Component=<component name>
Implement a Simple Column Override
If your component is very simple - you only want to change the HTML that we generate for the ViewModelColumn - you can do as described in this video
The binding in your replacement HTML takes this form:
<input ng-model='data.TheViewModelColumnToBindTo'/>
But that will require you to do a new component for each unique column (TheViewModelColumnToBindTo1,TheViewModelColumnToBindTo2).
To mitigate that need, we do this when compiling your replacement HTML:
OverrideDiv.AppendHtml(args.ResultingOverrideHTML.Replace("[ViewModelColumnName]", e.ViewModelColumn.RuntimeName));
This means that we can use an expression like this to write a more generic replacement control:
<input ng-model='data.[ViewModelColumnName]'/>
Update: We now also search and replace "[ViewModelClassName]". This means you can write this ng-model='vCurrent_[ViewModelClassName]' to bind to the vCurrent variable of the ViewModelClass that has the component.
Update 2: We now also search and replace "[ViewModelColumnLabel]". This means you can write this <div>[ViewModelColumnLabel]</div> to use the columns designed presentation string in your component.
Implement a Component with Js, CSS, and HTML
Example:
****** HTML - save as EXT_Components/test1/test1.cshtml ****** <!-- notice the use of test1 - it is an angular directive that we defines in the js further down --> <div test1 class="test1background"> </div>
****** CSS - save as EXT_Components/test1/test1.css ****** .test1background { background: pink; }
****** Javascript - save as EXT_Components/test1/test1.js ****** function InstallTheDirectiveFor_test1(streamingAppController) { streamingAppController.directive('test1', ['$document', function ($document) { return { link: function (scope, element, attr) { // THIS IS WHERE YOU SEE THE HTML(element) AND THE DATA (scope) FOR EVERYTHING THAT USE OUR DIRECTIVE (test1) var c = document.createElement('canvas'); element[0].appendChild(c); } }; }]); console.trace("test1 component Loaded"); } InstallTheDirectiveFor_test1(angular.module(MDrivenAngularAppModule));
If you use Typescript instead of javascript, you can use this code:
****** Typescript if you prefer- save as EXT_Components/test1/test1.ts (js is generated by ts) ****** /// <reference path="../../Scripts/typings/jquery/jquery.d.ts" /> /// <reference path="../../Scripts/typings/angularjs/angular.d.ts" /> /// <reference path="../../js/MDrivenAngularApp.ts" /> namespace test1Namespace { function InstallTheDirectiveFor_test1(streamingAppController) { streamingAppController.directive('test1', ['$document', function ($document) { return { link: function (scope, element: HTMLDivElement[], attr) { let c: HTMLCanvasElement = document.createElement('canvas'); element[0].appendChild(c); } }; }]); console.trace("test1 component Loaded"); } InstallTheDirectiveFor_test1(angular.module(MDrivenAngularAppModule)); }
When using Typescript, you may want to include a file like the one below to trigger the correct output:
*********** IF YOU USE TYPESCRIPT Consider adding this file to your folder tsconfig.json with content: { "compileOnSave": true, "compilerOptions": { "noImplicitAny": false, "noEmitOnError": true, "removeComments": false, "sourceMap": true, "target": "es5" }, "exclude": [ "node_modules" ] }
To get global scripts to run before loading of components, look at AppWideAngularScriptIncludes
An example of how to integrate TinyMCE editor in your app.
Example on A simple table component for just listing a collection without actions/selections.
Another article describing Turnkey components: https://blog.mdriven.net/svg-and-mdriven-turnkey-components/
New 2023
Components ready to use are maintained in this repository: https://github.com/supportMDriven/MDrivenComponents