EXT Components
(Adding page to Category:TOC because it contains a TOC.)
 
(20 intermediate revisions by 6 users not shown)
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 put sub folders
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 sub folder will constitue 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.


Each component can have js scripts to be loaded when angular app starts - all js found here will be loaded
==== Use in the Model ====
Use a Component in MDriven Designer by setting UIOverride on ViewModelColumn and: tagged value Angular_Ext_Component=<component name>


Each component must have a cshtml file for content structure - name this <component name>.cshtml
==== 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 [https://youtu.be/73egBsyzuP4 described in this video.]


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
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).


==== Use in the model ====
To mitigate that need, do this when compiling your replacement HTML:
Use a component in MDriven Designer by setting UIOverride on ViewModelColumn and:
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.


tagged value Angular_Ext_Component=<component name>
'''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 js,css and html ====
==== Implement a Component with Js, CSS, and HTML ====
Example:
Example:
<pre>
<pre>
Line 47: Line 57:
     console.trace("test1 component Loaded");
     console.trace("test1 component Loaded");
}
}
InstallTheDirectiveFor_test1(angular.module(MDrivenAngularAppModule));</pre>If you use Typescript instead of javascript you can use this code:
InstallTheDirectiveFor_test1(angular.module(MDrivenAngularAppModule));</pre>
 
If you use Typescript instead of javascript, you can use this code:
<pre>
****** 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));
}
 
</pre>
 
When using Typescript, you may want to include a file like the one below to trigger the correct output:
<pre>
*********** 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"
  ]
}</pre>
* To get global scripts to run before loading of components, look at [[AppWideAngularScriptIncludes|AppWideAngularScriptIncludes.]]
* An example of how to integrate [[TinyMCE editor]] in your app.
* Example on [[Training:A simple table component for just listing a collection|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
 
[[Category:Content Override]]
[[Category:UI]]
{{Edited|July|12|2024}}
 
[[Category:TOC]]

Latest revision as of 13:46, 26 March 2024

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 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"
  ]
}

New 2023

Components ready to use are maintained in this repository: https://github.com/supportMDriven/MDrivenComponents

This page was edited 44 days ago on 03/26/2024. What links here