DataForm: Getting Started

This quick start tutorial demonstrates how to create a simple iOS application with TKDataForm.

Prerequisites

This article assumes that you have followed the Downloading UI for iOS, Installing UI for iOS and Setting Up the project steps from the common Getting Started article.

Setting up TKDataForm

Now that our project is created and the TelerikUI.framework is added, we can start referencing and using the TelerikUI types:

Open your ViewController.m file and add a reference to the chart header file:

#import <TelerikUI/TelerikUI.h>

Note that starting with Xcode 6 Apple doesn't generate the precompiled headers file automatically. That is why you should add import the UIKit framework before importing TelerikUI:

#import <UIKit/UIKit.h>

If you are writing Swift, add the same line in your bridging header.

If you are using Xamarin, add a reference to TelerikUI.dll in your project and use the using directive:

using TelerikUI;

First you should create a bussiness object that will be displayed and edited by TKDataForm. Lets create a class called PersonalInfo

@implementation PersonalInfo

- (instancetype)init
{
    self = [super init];
    if (self) {
        _sendAllTraffic = YES;
    }
    return self;
}

@end
@interface PersonalInfo : NSObject

@property (nonatomic) NSInteger protocol;

@property (nonatomic, strong) NSString *details;

@property (nonatomic, strong) NSString *server;

@property (nonatomic, strong) NSString *account;

@property (nonatomic) BOOL secure;

@property (nonatomic, strong) NSString *password;

@property (nonatomic) NSInteger encryptionLevel;

@property (nonatomic) BOOL sendAllTraffic;

@end
class PersonalInfo: NSObject {

    var infoProtocol = 0;
    var details = "";
    var server = "";
    var account = "";
    var secure = false;
    var password = "";
    var encryptionLevel = 0;
    var sendAllTraffic = true;
}
public class PersonalInfo : NSObject
{
    [Export("Server")]
    public string Server { get; set;}

    [Export("Details")]
    public string Details { get; set;}

    [Export("Account")]
    public string Account { get; set;}

    [Export("Secure")]
    public bool Secure { get; set;}

    [Export("Password")]
    public string Password { get; set;}

    [Export("EncryptionLevel")]
    public int EncryptionLevel { get; set;}

    [Export("SendAllTraffic")]
    public bool SendAllTraffic { get; set;}

    [Export("InfoProtocol")]
    public int InfoProtocol{ get; set;}

    public PersonalInfo ()
    {
        this.InfoProtocol = 0;
        this.Details = "";
        this.Server = "";
        this.Secure = false;
        this.Password = "";
        this.EncryptionLevel = 0;
        this.Account = "";
        this.SendAllTraffic = true;
    }
}

The TKDataForm object should be created in viewDidLoad method:

_dataForm = [[TKDataForm alloc] initWithFrame:self.view.bounds];
_dataForm.delegate = self;
[self.view addSubview:_dataForm];
let dataForm = TKDataForm()
this.dataForm = new TKDataForm (this.View.Bounds);
this.dataForm.Delegate = this.dataFormDelegate;
this.View.AddSubview (this.dataForm);

You should adopt TKDataFormDelegate and implement its dataForm:updateEditor:forProperty: method in order to customize the editors:

- (void)dataForm:(TKDataForm *)dataForm updateEditor:(TKDataFormEditor *)editor forProperty:(TKEntityProperty *)property
{
    TKGridLayoutCellDefinition *feedbackDef = [editor.gridLayout definitionForView:editor.feedbackLabel];
    [editor.gridLayout setHeight:0 forRow:[feedbackDef.row integerValue]];

    if ([property.name isEqualToString:@"protocol"]) {
        editor.style.textLabelDisplayMode = TKDataFormEditorTextLabelDisplayModeHidden;
        TKGridLayoutCellDefinition *textLabelDef = [editor.gridLayout definitionForView:editor.textLabel];
        [editor.gridLayout setWidth:0 forColumn:[textLabelDef.column integerValue]];
    }
}
override func dataForm(_ dataForm: TKDataForm, update editor: TKDataFormEditor, for property: TKEntityProperty) {
    let feedbackDef = editor.gridLayout.definition(for: editor.feedbackLabel)
    editor.gridLayout.setHeight(0, forRow: (feedbackDef?.row.intValue)!)

    if property.name == "infoProtocol" {
        editor.style.textLabelDisplayMode = TKDataFormEditorTextLabelDisplayMode.hidden
        let textLabelDef = editor.gridLayout.definition(for: editor.textLabel)
        editor.gridLayout.setWidth(0, forColumn: (textLabelDef?.column.intValue)!)
    }

    if editor.isKind(of: TKDataFormTextFieldEditor.self) && property.name != "password" {
        property.hintText = "Required"
    }
}
public override void UpdateEditor (TKDataForm dataForm, TKDataFormEditor editor, TKEntityProperty property)
{
    TKGridLayoutCellDefinition feedbackDef = editor.GridLayout.DefinitionForView (editor.FeedbackLabel);
    editor.GridLayout.SetHeight (0, feedbackDef.Row.Int32Value);

    if (property.Name == "InfoProtocol") {
        editor.Style.TextLabelDisplayMode = TKDataFormEditorTextLabelDisplayMode.Hidden;
        TKGridLayoutCellDefinition textLabelDef = editor.GridLayout.DefinitionForView (editor.TextLabel);
        editor.GridLayout.SetWidth (0, textLabelDef.Column.Int32Value);
    }

    if (editor.IsKindOfClass (new Class(typeof(TKDataFormTextFieldEditor))) && !(property.Name.Equals("Password"))) {
        property.HintText = "Required";
    }
}

Setting up TKDataForm with TKDataFormViewController

In master/detail scenario the content of an editor will open on its own screen. It this case you should use TKDataFormViewController. This view controller contains a TKDataForm and adopts its TKDataFormDelegate and TKDataFormDataSouece protocols. TKDataFormOptionsEditor is used to display option lists on its own screen and it requires the usage of TKDataFormViewController.

We should create a view controller that inherits from TKDataFormViewController. For demonstration purposes we will be using the PersonalInfo class from the snippet above.

@interface DataFormGettingStarted : TKDataFormViewController

@end
class DataFormGettingStarted: TKDataFormViewController {
public class DataFormGettingStarted : TKDataFormViewController
{

TKDataFormViewController does not contain a navigation controller. You should provide one before using the TKDataFormViewController.

The setup of the TKDataForm is done in the viewDidLoad of the inheriting class. since the TKDataformViewController provides ready-to-use instance of the TKDataForm, you can used it and just setup the visual appereance and data properties.

- (void)viewDidLoad
{
    [super viewDidLoad];

    _personalInfo = [PersonalInfo new];
    self.dataForm.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    self.dataForm.backgroundColor = [UIColor colorWithRed:0.937 green:0.937 blue:0.960 alpha:1.0];

    _dataSource = [[TKDataFormEntityDataSource alloc] initWithObject:_personalInfo];
    _dataSource[@"password"].hintText = @"Ask every time";
    _dataSource[@"password"].editorClass = [TKDataFormPasswordEditor class];

    _dataSource[@"protocol"].valuesProvider = @[@"L2TP", @"PPTP", @"IPSec"];
    _dataSource[@"encryptionLevel"].valuesProvider = @[@"FIPS Compliant", @"High", @"Client Compatible", @"Low"];

    [_dataSource addGroupWithName:@"  " propertyNames:@[ @"protocol" ]];
    [_dataSource addGroupWithName:@" " propertyNames:@[ @"details", @"server", @"account", @"secure", @"password", @"encryptionLevel", @"sendAllTraffic" ]];

    self.dataForm.dataSource = _dataSource;
    self.dataForm.commitMode = TKDataFormCommitModeOnLostFocus;
    self.dataForm.groupSpacing = 20;
}
override func viewDidLoad() {
    super.viewDidLoad()

    self.dataForm.backgroundColor = UIColor(red: 0.937, green: 0.937, blue: 0.960, alpha: 1.0)
    dataSource.sourceObject = personalInfo

    dataSource["password"].hintText = "Ask every time"
    dataSource["password"].editorClass = TKDataFormPasswordEditor.self
    dataSource["infoProtocol"].valuesProvider = ["L2TP", "PPTP", "IPSec"]
    dataSource["encryptionLevel"].valuesProvider = [ "FIPS Compliant", "High", "Client Compatable", "Low" ]

    dataSource.addGroup(withName: " ", propertyNames: [ "infoProtocol" ])
    dataSource.addGroup(withName: " ", propertyNames: [ "details", "server", "account", "secure", "password", "encryptionLevel", "sendAllTraffic" ])

    self.dataForm.dataSource = dataSource
    self.dataForm.commitMode = TKDataFormCommitMode.onLostFocus
    self.dataForm.groupSpacing = 20
}
public override void ViewDidLoad()
{
    base.ViewDidLoad ();

    this.personalInfo = new PersonalInfo ();
    this.dataSource = new TKDataFormEntityDataSourceHelper (this.personalInfo);
    this.dataFormDelegate = new GettingStartedDataFormDelegate ();

    this.dataSource["Password"].HintText = "Ask every time";
    this.dataSource ["Password"].EditorClass = new Class (typeof(TKDataFormPasswordEditor));
    this.dataSource["InfoProtocol"].ValuesProvider = NSArray.FromStrings(new string[] { "L2TP", "PPTP", "IPSec" });
    this.dataSource["EncryptionLevel"].ValuesProvider = NSArray.FromStrings(new string[] { "FIPS Compliant", "High", "Client Compatible", "Low" });

    this.dataSource.AddGroup(" ", new string[] { "InfoProtocol" });
    this.dataSource.AddGroup (" ", new string[] {
        "Details",
        "Server",
        "Account",
        "Secure",
        "Password",
        "EncryptionLevel",
        "SendAllTraffic"
    });

    this.DataForm.BackgroundColor = new UIColor (0.937f, 0.937f, 0.960f, 1.0f);
    this.DataForm.GroupSpacing = 20;
    this.DataForm.Delegate = this.dataFormDelegate;
    this.DataForm.WeakDataSource = this.dataSource.NativeObject;
}