How to create a custom field control
- 100%
- 6.3
- Enterprise
- Community
Planned
Overview
We introduce how to create a custom field control that allows you to store a list of values as related "metadata". How to customize field view and field editing options on the admin surface.
Steps
1. Add a the new field control to the solution
Add the new Field Control file to Source/SenseNet/Portal/UI/Controls/FieldControls folder. The file name must match with the ControlHint name applied on the CTD (MyFieldControl.cs). Add a script, which the field calls on init and initialize UI by.
protected override void OnInit(EventArgs e) { UITools.AddScript("myCustomScript.js"); base.OnInit(e); }
2. Update CTD of the required content
On the chosen field add a new configuration option which allows to configure a custom field control:
<Field name="myCustomField" type="LongText"> ... <Configuration> <ControlHint>sn:MyFieldControl</ControlHint> </Configuration> </Field>
3. Create the script
In a custom script (e.g. /Root/Global/scripts/sn/SN.CallToAction.js) custom functions have to be defined that need to be executed on the field when new content is added or existing content is edited. The content of the LongText-field can be parsed here to a JSON string and pushed to an array. By hiding the longtext-field an displaying a newly created markup, that shows the array-elements separately, allows to manipulate them as metadata belonging to this filed.
Button = { Add: function () { var buttonPath = $('.innner-link-table .sn-button-innerlinkpath').val(); var buttonText = $('.innner-link-table .sn-button-buttontext').val(); var contentId = $('.innner-link-table .sn-button-contentId').val(); var linkTarget = $('.innner-link-table .sn-button-target').val(); var linkTitle = $('.innner-link-table .sn-button-title').val(); // give metadata to functions Button.AddItemToList(buttonPath, buttonText, contentId, linkTitle, linkTarget); // a hidden textbox holds all metadata of all buttons Button.AddItemToHiddenTextbox(buttonPath, buttonText, contentId, linkTitle, linkTarget); }, // add new button to buttonlist AddItemToList: function (buttonPath, buttonText, contentId, linkTitle, linkTarget) { // create newbutton markup ... }, AddItemToHiddenTextbox: function (buttonPath, buttonText, contentId, linkTitle, linkTarget) { // add metadata as JSON to hidden textbox var tb = $('.sn-button-innerdata'); var button = new Button.button(buttonPath, buttonText, contentId, linkTitle, linkTarget); if (tb.val() !== '') { buttonArray = JSON.parse(tb.val()); } else { buttonArray = []; } buttonArray.push(button); tb.val(JSON.stringify(buttonArray)); }, // create this button with all metadata button: function (buttonPath, buttonText, contentId, linkTitle, linkTarget, id) { this.buttonPath = buttonPath; this.buttonText = buttonText; this.contentId = contentId; this.linkTitle = linkTitle; this.linkTarget = linkTarget; if (typeof id !== 'undefined') this.id = id; else this.id = 'button-' + buttonArray.length; }, Load: function () { ... }, Delete: function (id, $button) { ... }, Edit: function (id, $button) { ... }, Change: function ($button) { var tb = $('.sn-button-innerdata'); var buttonPath = $button.find('.sn-button-innerlinkpath').val(); var buttonText = $button.find('.sn-button-buttontext').val(); var contentId = $button.attr('data-contentid'); var linkTarget = $button.find('.sn-button-target').val(); var linkTitle = $button.find('.sn-button-title').val(); ... buttonArray = JSON.parse(tb.val()); var button = new Button.button(buttonPath, buttonText, contentId, linkTitle, linkTarget, $button.attr('id')); for (var i = 0; i < buttonArray.length; i++) { if (buttonArray[i].id === $button.attr('id')) { buttonArray[i].buttonPath = button.buttonPath; buttonArray[i].contentId = button.contentId; buttonArray[i].buttonText = button.buttonText; buttonArray[i].linkTarget = button.linkTarget; buttonArray[i].linkTitle = button.linkTitle; } } tb.val(''); tb.val(JSON.stringify(buttonArray)); ... }, Populate: function () { ... } }
As you can see above we've defined some methods for the Button object like Add, Delete, Change, etc. These methods helps us to create or change markup of the field/buttonlist and if you check the change function you can see how the field values are transformed to a button object which is put as string into the actual Longtext field in the background.
4. Add custom field-control template
To display this new field one needs to create a new custom template for. In the /Root/Global/fieldcontroltemplates folder add a new folder with the name of the field-control (MyFieldControl). In this folder add BrowseTemplate.ascx and EditTemplate.ascx files, where you can define the appearance of the fields.