Hide

YetaWF Documentation

Display
Print

Creating Your Own Components

The C# portion of your components you develop will always be located in your package's ./Components folder. When developing components using the YetaWF.ComponentsHTML package, they must be located in the folder ./Components/HTML.

Components must adhere to the following naming standard. This is important so dependent JavaScript and CSS files can automatically be included by YetaWF. You normally don't have to explicitly include JavaScript and CSS files, unless your component requires third-party JavaScript packages.

Component Name:

company_product_component

Company and product are the same identifiers used for the package. For example, a package named MyCompany.MyProduct would have a component named MyCompany_MyProduct_MyComponent. It is not possible to omit MyCompany_MyProduct_ from the component name.

UIHint Use:

UIHint("MyCompany_MyProduct_MyComponent")

Any JavaScript files and CSS files are defined in the ./Addons/_Templates/(component)/ folders for the package (see Component JavaScript Files and Component CSS Files) and are automatically included whenever a component is used.

Please see see Component JavaScript Files and Component CSS Files for more information about a component's JavaScript and CSS files.

C# - Server-Side Rendering

All components are rendered server-side, but they may be augmented using client-side JavaScript.

C# source code for a component is always added in the package's folder ./Components/HTML.

Components can be used for display and for edit purposes. Not all components implement both display and edit. A component is implemented by a class derived from YetaWF.Modules.ComponentsHTML.Components.YetaWFComponent.

A component is a simple class that is used to render small HTML portions. The following shows the simplest component that can be used for both display and edit.

Components are used in UIHint attributes and can also be rendered using ForDisplayAsync/ForEditAsync and other methods provided by the YetaWF.Core.Components.YetaWFComponentExtender class.

Example

namespace MyCompany.Modules.MyProduct.Components {

    public abstract class TestComponentComponentBase : YetaWFComponent {

        internal const string TemplateName = "Enum";

        public override Package GetPackage() { return Controllers.AreaRegistration.CurrentPackage; }
        public override string GetTemplateName() { return TemplateName; }

    }
    public class TestComponentDisplayComponent : TestComponentComponentBase, IYetaWFComponent<string> {

        public override ComponentType GetComponentType() { return ComponentType.Display; }

        public Task<string> RenderAsync(string model) {
            return Task.FromResult("I'm a simple test component");
        }
    }
    public class TestComponentEditComponent : TestComponentComponentBase, IYetaWFComponent<string> {

        public override ComponentType GetComponentType() { return ComponentType.Edit; }

        public async Task<string> RenderAsync(string model) {

            HtmlBuilder hb = new HtmlBuilder();
            hb.Append("<input type='input' value='test'>");
            return Task.FromResult(hb.ToString());

        }
    }
}

The above implements a display (using the ReadOnly attribute) and an edit component. It is used in UIHint attributes:

[UIHint("MyCompany_MyProduct_Test"), ReadOnly]
[UIHint("MyCompany_MyProduct_Test")]

JavaScript

By placing components in the correct folders and using appropriate namespaces in your package, the YetaWF framework automatically finds your component, registers them and injects any JavaScript and CSS that your component uses (see Component JavaScript Files and Component CSS Files).

If your component needs initialization using JavaScript, your rendering code can inject JavaScript for your component. The JavaScript section your component injects will be collected by the framework and combined with other code sections and possibly moved.

            HtmlBuilder hb = new HtmlBuilder();
            hb.Append(@$"
<input id='{ControlId}' type='input' value='test'>
<script>
    new MyCompany_MyProduct.TestComponentEdit('{ControlId}');
</script>");
            return Task.FromResult(hb.ToString());

Component JavaScript Class

A component's client-side code is written in TypeScript and must use the package area namespace (company and product name). The component's class name must match the short name of the component used when registering the component in C#. By using the proper conventions, the framework is able to connect the component client-side and server-side.

To follow the conventions outlined in Component JavaScript Files, the following JavaScript code must be located in the package's folder:

./Addons/_Templates/Test/
namespace MyCompany_MyProduct {

    export class TestComponentEdit extends YetaWF.ComponentBaseImpl {

        constructor(controlId: string) {
            super(controlId);

            . . .
        }

    }
}

A filelistJS.txt file is required in folder ./Addons/_Templates/Test/ with the following contents:

TestEdit.ts

CSS

Most components, except trivial components, may need to be styled using CSS. All components follow the same CSS class naming standard. The prefix letter "y" is reserved for YetaWF internal CSS classes, the prefix "yt_" is reserved for component CSS classes. See CSS Classes for more information.

Custom components in packages should follow this class naming standard. For example the component MyComponent in package MyCompany.MyProduct should use the CSS class yt_mycompany_myproduct_mycomponent.

The general CSS class name is as follows:

.yt_company_product_componentname

Components should be styled using CSS files (see Component CSS Files). Never use inline styles.

Public Components

Your newly developed components will always be located in a package (not YetaWF.Core). Your components will always be available to all other packages.

Client-Side Configuration Variables

Often it may be necessary to communicate certain site settings or other variables to the component's JavaScript files. Instead of "hard-coding" these values in your component's JavaScript files, such values can be added to the global JavaScript variable YConfigs which is available in all YetaWF generated pages.

By adding the IAddOnSupport interface to a class associated with a component, any configuration options will automatically be added to the YConfigs variable whenever the component is used.

The convention used throughout YetaWF (except YetaWF.Core) is to add such classes in the package folder ./Startup in the file named Info.cs.

namespace company.Modules.product.Addons.Components {
    /// <summary>
    /// Component specific config strings.
    /// </summary>
    public class component : IAddOnSupport {

        public void AddSupport(YetaWFManager manager) {

            ScriptManager scripts = manager.ScriptManager;
            string areaName = AreaRegistration.CurrentPackage.AreaName;

            scripts.AddConfigOption(areaName, "SomeValue", 99);
        }
    }
}

The namespace used for the class implementing the IAddOnSupport interface and the name for the class itself must follow the general naming convention:

namespace company.Modules.product.Addons.Components

class component

In the above example, JavaScript used by the component has access to the variable YConfigs.MyCompany_MyProduct.SomeValue which equals 99. The AddSupport method is executed every time the component is used so this can be a dynamically changing value.

All the classes implementing the IAddOnSupport interface are located during site startup. When adding new classes implementing the IAddOnSupport interface, it is necessary to restart the site.

Client-Side Localization

Often it may be necessary to localize strings in the component's JavaScript files. Instead of "hard-coding" these values in your component's JavaScript files, such values can be added to the global JavaScript variable YLocs which is available in all YetaWF generated pages.

By adding the IAddOnSupport interface to a class associated with a component, any localizable string will automatically be added to the YLocs variable whenever the component is used.

The convention used throughout YetaWF (except YetaWF.Core) is to add such classes in the package folder ./Startup in the file named Info.cs.

namespace company.Modules.product.Addons.Components {
    /// <summary>
    /// Component specific config strings.
    /// </summary>
    public class component : IAddOnSupport {

        public void AddSupport(YetaWFManager manager) {

            ScriptManager scripts = manager.ScriptManager;
            string areaName = AreaRegistration.CurrentPackage.AreaName;

            scripts.AddLocalization(areaName, "RemoveConfirm", this.__ResStr("removeConfirm", "Are you sure you want to remove this image?"));
        }
    }
}

The namespace used for the class implementing the IAddOnSupport interface and the name for the class itself must follow the general naming convention:

namespace company.Modules.product.Addons.Components

class component

In the above example, JavaScript used by the component has access to the variable YLocs.MyCompany_MyProduct.RemoveConfirm which equals "Are you sure you want to remove this image?". The AddSupport method is executed every time the component is used so this can be a dynamically changing value.

All the classes implementing the IAddOnSupport interface are located during site startup. When adding new classes implementing the IAddOnSupport interface, it is necessary to restart the site.