Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular Js+ TypeScript: How to create a Dynamic table

I am new to typescript and angular.I have implemented a module using typescript and angular js. In which i need to create a dynamic table which will fetch the type of presentation and accordingly append to my view as previously i have done in C#.My c# code i have given below:

  private void ShowCustomFields()
    {
        Customer.CustomerController control = new Customer.CustomerController();

        DataTable fields = control.GetCustomFields();
        TableRow row = new TableRow();
        Int16 count = 0;
        foreach (DataRow dr in fields.Rows)
        {
            count++;
            string id = dr["Id"].ToString();
            string name = dr["Name"].ToString();
            string type = dr["Type"].ToString();
            string val = "";
            //Determine if the user can view/edit this custom field

            bool canEdit = false;
            if (Permissions.PermissionController.HasPermission(this.UserInfo.Username, "Custom Fields - Customer",
              dr["Name"].ToString(),
             Permissions.PermissionLevels.Edit))
            {

                canEdit = true;
            }


            TableCell cellId = new TableCell();
            cellId.Visible = false;
            cellId.EnableViewState = true;
            cellId.Text = id;

            TableCell cellName = new TableCell();
            cellName.Text = name + ": ";
            cellName.Width = 150;
            cellName.EnableViewState = true;

            TableCell cellControl = new TableCell();
            cellControl.EnableViewState = true;

            TextBox tb = new TextBox();
            if (!canEdit)
            {
                tb.Enabled = false;
            }
            tb.TabIndex = (Int16)(1000 + count);

            RangeValidator r = new RangeValidator();
            switch (type)
            {
                case "Text":

                    tb.Text = val;
                    tb.ID = "CustomField" + id;
                    tb.EnableViewState = true;
                    tb.CssClass = "NormalTextBox";
                    cellControl.Controls.Add(tb);
                    break;
                case "Integer":

                    tb.Text = val;
                    tb.ID = "CustomField" + id;
                    tb.EnableViewState = true;
                    tb.CssClass = "NormalTextBox";
                    cellControl.Controls.Add(tb);

                    r.ControlToValidate = tb.UniqueID;
                    r.Type = ValidationDataType.Integer;
                    r.MinimumValue = Int32.MinValue.ToString();
                    r.MaximumValue = Int32.MaxValue.ToString();
                    r.ErrorMessage = "Invalid Integer";
                    cellControl.Controls.Add(r);
                    break;
                case "Decimal":

                    tb.Text = val;
                    tb.ID = "CustomField" + id;
                    tb.EnableViewState = true;
                    tb.CssClass = "NormalTextBox";
                    cellControl.Controls.Add(tb);

                    r.ControlToValidate = tb.UniqueID;
                    r.Type = ValidationDataType.Double;
                    r.MinimumValue = "-1000000000000";
                    r.MaximumValue = "1000000000000";
                    r.ErrorMessage = "Invalid Decimal";
                    cellControl.Controls.Add(r);
                    break;
                case "Date":

                    tb.Text = val;
                    tb.ID = "CustomField" + id;
                    tb.EnableViewState = true;
                    tb.CssClass = "NormalTextBox";
                    cellControl.Controls.Add(tb);

                    r.ControlToValidate = tb.UniqueID;
                    r.Type = ValidationDataType.Date;
                    r.MinimumValue = "1/1/1900";
                    r.MaximumValue = "12/31/3000";
                    r.ErrorMessage = "Invalid Date";
                    cellControl.Controls.Add(r);
                    break;
                case "TrueFalse":
                    CheckBox cb = new CheckBox();
                    if (val.ToUpper().Equals("TRUE"))
                    {
                        cb.Checked = true;
                    }
                    cb.EnableViewState = true;
                    cb.CssClass = "NormalTextBox";
                    cb.TabIndex = (Int16)(1000 + count);
                    cellControl.Controls.Add(cb);

                    break;
                case "DropdownList":
                    DropDownList ddl = new DropDownList();
                    Vbos.Maintenance.MaintenanceController mcon = new Vbos.Maintenance.MaintenanceController();
                    ddl.DataSource = mcon.GetTypeItems("CF_" + name);
                    ddl.DataTextField = "Description";
                    ddl.DataValueField = "ShortDescription";
                    ddl.DataBind();

                    ListItem li = new ListItem();
                    li.Text = "--Select--";
                    li.Value = "-1";
                    li.Selected = true;

                    ddl.Items.Insert(0, li);
                    if (ddl.Items.FindByValue(val) != null)
                    {
                        ddl.SelectedIndex = -1;
                        ddl.Items.FindByValue(val).Selected = true;
                    }
                    cellControl.Controls.Add(ddl);
                    break;
            }

            row.Cells.Add(cellId);
            row.Cells.Add(cellName);
            row.Cells.Add(cellControl);
            row.EnableViewState = true;
            tableCustomFields.Rows.Add(row);
            //if( count%2 == 0 )
            //{
            row = new TableRow();
            //}
            tableCustomFields.EnableViewState = true;
        }
    }

As you can see i can fetching data on the basis of type.How can i implement the same using Angular Js and want to know how can i bind these values with my ng-model too.

like image 862
Shian JA Avatar asked Jul 16 '15 13:07

Shian JA


1 Answers

With Angular you could use a module like uiGrid like @Dean Ward (how's it going Dean?) suggests. Or you could do it yourself.

The meat of your C# code is imperative and could be translated to TypeScript in some fashion. This would not be recommended though. Much of the actual data driven table building can be done in a declarative way using existing Angular directives.

The heart of your code displays the cell based on its type. This could be implemented as a simple wrapper directive that will replace itself with a directive for the appropriate type.

For each cell type you can create a custom directive: integer-cell, decimal-cell, dropdown-cell, boolean-cell... Each would handle how the cell is displayed and what the control is rendered as.

Then you would be able to use ng-repeat for each column and row, and let the wrapper directive replace itself with a custom type directive.

Another advantage to this approach is that you have better separation of concerns, follows the open/closed principle and your components would just do one thing.

If the wrapper directive used a convention to display the type directives, you could add new types in the future without the need to open any existing components.

This is a lot of work for someone new to Angular. I would go with @Dean Ward's suggestion. There are a lot of editable grid solutions for angular. If uiGrid doesn't suit your needs, look at other existing components.

UPDATE A few examples

Your best bet is still to use an existing grid component, like uiGrid. If you want to write this yourself, which I don't recommend -- this would be one way of doing it.

function cellInteger(): ng.IDirective {
    return {
        scope: {data: '='},
        controller: 'CellIntegerController',
        controllerAs: 'vm',
        bindToController,
        templateUrl: 'path/to/integer.html'
    } 
}
gridMobule.directive('cellInteger', cellInteger);

export class CellIntegerController {

    public data: CellDataType;

    constructor() {}

    save(value: number) {
        this.data.value = number;
    }
}
gridModule.controller('CellIntegerController', CellIntegerController);

In your view for this you would have something like:

<input 
     type="number"
     class="cell-integer"
     ng-model="vm.data.value"
     ng-blur="save(vm.data.value)"
</
like image 77
Martin Avatar answered Oct 22 '22 20:10

Martin