In the Turnkey Web application, you will find a folder named EXT_Components.
This article targets AngularJS components. To read on Blazor components, go here: EXT ComponentsBlazor
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 generated 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, do this when compiling your replacement HTML:
OverrideDiv.AppendHtml(args.ResultingOverrideHTML.Replace("[ViewModelColumnName]", e.ViewModelColumn.RuntimeName));
This means that you 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
