Add-Edit-Delete-Duplicate rows in HTML table using AngularJS, jQuery and MVC


My client asked me to build the screen that will allow users to add/modify/delete/duplicate records and it should be in tabular format. In this post I am going to use MVC, angularJS, jQuery and HTML technologies to achieve this.
Lest get starts
Screen mock-up
Add

Delete/Edit/Duplicate

Update


Step – 1 CDN for jQuery, jQuery min & angularJS
Step -2 HTML Code
<script lang="javascript" type="text/javascript">
    var baseURL = '@Url.Action("Index")' + "/";
</script>
<div style="display:none;color:red" id="errContainer">
    <div class="span12" id="divMessage"></div>
</div>
<table id="tblFutureBulkUpload" style="font-size:12px;padding-left:5px;border-color:Black;border-width:1px;border-style:solid;border-collapse:collapse;">
    <tr>
        <th class="tblHeader">Action</th>
        <th class="tblHeader" style="width:75px">Account Type</th>
        <th class="tblHeader" style="width:75px">Account</th>
        <th style="display:none">Account Id</th>
    </tr>
    <tr ng-repeat="future in futureList" ng-class-odd="'odd'" ng-class-even="'even'">
        <td style="vertical-align:top">
            <input ng-disabled="!disableAction" ng-show="future.showNonEdit" type="button" ng-click="Remove($index);" value="Remove" class="btn btn-small btn-info" id="btnRemove" />
            <input ng-disabled="!disableAction" ng-show="future.showNonEdit" type="button" ng-click="toggleEdit(future);" value="Edit" class="btn btn-small btn-info" id="btnEdit" />
            <input ng-disabled="!disableAction" ng-show="future.showNonEdit" type="button" ng-click="Duplicate($index);" value="Duplicate" class="btn btn-small btn-info" id="btnBup" />
            <input ng-disabled="disableAction" ng-show="!future.showNonEdit" type="button" ng-click="Update($index);" value="Update" class="btn btn-small btn-info" id="btnUpdate" />
            <input ng-disabled="disableAction" ng-show="!future.showNonEdit" type="button" ng-click="Cancel(future);" value="Cancel" class="btn btn-small btn-info" id="btnCnacel" />
        </td>
        <td>
            <span ng-show="future.showEdit">{{future.AccountType}}</span>
            <select ng-model="AccountTypeEdit" id="accTypeEdit" ng-show="!future.showEdit" ng-change="populateEditAccount(AccountTypeEdit,false)" style="font-size:12px;width:75px">
                <option value="0">Select</option>
                <option ng-repeat="type in AccountTypeList" value="{{type.Key}}">{{type.Value}}</option>
            </select>
        </td>
        <td>
            <span ng-show="future.showEdit">
                {{future.Account}}
            </span>
            <select ng-model="AccountEdit" id="AccEdit" ng-show="!future.showEdit" ng-change="populateEditInstrument(AccountEdit,false)" style="font-size:12px;width:75px">
                <option value="0">Select</option>
                <option ng-repeat="acc in AccountListEdit" value="{{acc.Key}}">{{acc.Value}}</option>
            </select>
        </td>
    </tr>
    <tfoot>
        <tr>
            <td style="vertical-align:top">
                <input type="button" ng-disabled="!disableAction" ng-click="Add()" value="Add" class="btn btn-small btn-info" id="btnAdd" />
                @*  ng-disabled="!disableAction" src="~/Images/Futures/Add.ico" ng-click="Add()">
*@
            </td>
            <td>
                <select ng-model="AccountType" id="accType" ng-change="populateAccount(AccountType)" style="font-size:12px;width:75px">
                    <option value="0">Select</option>
                    <option ng-repeat="type in AccountTypeList" value="{{type.Key}}">{{type.Value}}</option>
                </select>
            </td>
            <td>
                <select ng-model="Account" id="Acc" ng-change="populateInstrument(Account)" style="font-size:12px;width:75px">
                    <option value="0">Select</option>
                    <option ng-repeat="acc in AccountList" value="{{acc.Key}}">{{acc.Value}}</option>
                </select>
            </td>
        </tr>
    </tfoot>
</table>
<div>
    <table class="table table-striped table-condensed" cellspacing="0" rules="all" style="font-size:12px;padding-left:5px;">
        <tr>
            <td style="vertical-align:top">
                <input ng-disabled="!disableAction" type="button" ng-click="Process()" value="Process" class="btn btn-small btn-info" id="btnProcess" />
            </td>
        </tr>
    </table>
</div>

Step 3 angularJS & jQuery Code

var app = angular.module('BulkUploadApp', []);
app.controller('BulkUploadCtrl', function ($scope, $http) {
    this.$onInit = function () {
        $scope.FillAccountType();
        $scope.populateClearingCParty();
        //$scope.populateExecutingCParty('');
    };

    $scope.futureList = [];

    //Add new Future Entry - Completed
    $scope.Add = function () {
        //Validation
        if ($scope.AccountType == "0" || $scope.Account == "0") {
            jQuery('#divMessage').css("color", "red");
            jQuery('#errContainer').show();
            jQuery('#errContainer').fadeOut(5000);
            jQuery('#divMessage').html('Correct the input data.');
            return;
        }
        //Add the new item to the Array.
        var future = {};
        future.AccountType = jQuery('#accType :selected').text();
        future.AccountTypeId = $scope.AccountType;
        future.Account = jQuery('#Acc :selected').text();
        future.AccountId = $scope.Account;
       

        future.showNonEdit = true;
        future.showEdit = true;
        $scope.disableAction = true;

        $scope.futureList.push(future);


        //Clear the controls.
        $scope.AccountType = "0";
        $scope.Account = "0";
       
        $scope.populateAccount('');
    };

    //Update Future Entry
    $scope.Update = function (index) {
        //Validation
        if (jQuery('#accTypeEdit :selected').val() == "0" || jQuery('#AccEdit :selected').val() == "0") {
            jQuery('#divMessage').css("color", "red");
            jQuery('#errContainer').show();
            jQuery('#errContainer').fadeOut(5000);
            jQuery('#divMessage').html('Correct the input data.');
            return;
        }

        $scope.futureList[index].AccountType = jQuery('#accTypeEdit :selected').text();
        $scope.futureList[index].AccountTypeId = jQuery('#accTypeEdit :selected').val();
        $scope.futureList[index].Account = jQuery('#AccEdit :selected').text();
        $scope.futureList[index].AccountId = jQuery('#AccEdit :selected').val();

        $scope.futureList[index].showNonEdit = true;
        $scope.futureList[index].showEdit = true;

        $scope.disableAction = true;
    };

    //Remove Future entry - Completed
    $scope.Remove = function (index) {
        //Find the record using Index from Array.
        var accType = $scope.futureList[index].AccountType;

        var conf = confirm("Do you want to delete: " + accType);
        if (conf == true) {
            $scope.futureList.splice(index, 1);
        }
    };

    //Duplicate Future Entry
    $scope.Duplicate = function (index) {
        var future = {};

        future.AccountType = $scope.futureList[index].AccountType;
        future.AccountTypeId = $scope.futureList[index].AccountTypeId;
        future.Account = $scope.futureList[index].Account;
        future.AccountId = $scope.futureList[index].AccountId;

        future.showNonEdit = true;
        future.showEdit = true;
        $scope.disableAction = true;

        $scope.futureList.push(future);
    };

    //Get the list of Account
    $scope.FillAccount = function () {
        var url = baseURL + 'GetAccountList';
        $http.get(url).then(function Success(response) {
            $scope.AccountList = response.data.dDeltaResult;
        })
    };

    //Set default values
    $scope.AccountType = "0";
    $scope.Account = "0";
    $scope.showRollField = false;
    $scope.disableAction = true;

    //Edit Future entry
    $scope.toggleEdit = function (future) {
        future.showEdit = future.showEdit ? false : true;
        future.showNonEdit = future.showNonEdit ? false : true;
        //Set values selected row values to edit controls
        $scope.AccountTypeEdit = future.AccountTypeId;
        $scope.populateEditAccount(future.AccountTypeId, true);
        $scope.AccountEdit = future.AccountId;

        $scope.disableAction = false;
    };

    //Cancel - edit future
    $scope.Cancel = function (future) {
        future.showEdit = future.showEdit ? false : true;
        future.showNonEdit = future.showNonEdit ? false : true;
        $scope.disableAction = true;
    };

    //Populate all kinds of list
    //Add/Edit Option
    //Get the list of account type
    $scope.FillAccountType = function () {
        var url = baseURL + 'GetAccountTypeList';
        $http.get(url).then(function Success(response) {
            $scope.AccountTypeList = response.data.futureResult;
        })
    };

    //Account List Add/Edit
    $scope.populateAccount = function (accType) {
        var url = baseURL + 'GetAccountList?hAccType=' + accType;
        $http.get(url).then(function Success(response) {
            $scope.AccountList = response.data.futureResult;
            $scope.Account = "0";
        });
    };

    //Populate Edit account list
    $scope.populateEditAccount = function (accType, isEdit) {
        var url = baseURL + 'GetAccountList?hAccType=' + accType;
        $http.get(url).then(function Success(response) {
            $scope.AccountListEdit = response.data.futureResult;
            if (!isEdit) {
                $scope.AccountEdit = "0";
            }
        });
    };

    //Save Changes
    $scope.Process = function () {
        var url = baseURL + 'SaveData';
        if ($scope.futureList.length == 0) {
            jQuery('#divMessage').css("color", "red");
            jQuery('#errContainer').show();
            jQuery('#errContainer').fadeOut(5000);
            jQuery('#divMessage').html('Add some data before start process.');
            return;
        }

        var req = {
            method: 'POST',
            url: url,
            headers: {
                'Content-Type': 'application/json;charset=utf-8'
            },
            data: JSON.stringify({ 'futureList': $scope.futureList })
        }

        $http(req).then(function Success(response) {
            if (response.data.futureResult.length == 0) {
                jQuery('#btnProcess').attr('disabled', true);
                jQuery('#divMessage').css("color", "green");
                jQuery('#errContainer').show();
                jQuery('#errContainer').fadeOut(5000);
                jQuery('#divMessage').html('Future trade(s) successfully created.');
                    $scope.futureList = [];
                    jQuery('#btnProcess').attr('disabled', false);
            } else {
                $scope.futureList = response.data.futureResult;

                var erroList = "";

                erroList = "Please correct the information and process again.";
                jQuery('#divMessage').css("color", "red");
                jQuery('#errContainer').show();
                jQuery('#errContainer').fadeOut(10000);
                jQuery('#divMessage').html(erroList);
            }
        }, function Failure(response) {
            jQuery('#divMessage').css("color", "red");
            jQuery('#errContainer').show();
            jQuery('#errContainer').fadeOut(5000);
            jQuery('#divMessage').html(result.statusText);
        });
    }
});

Step 4 – MVC Code – Declare below method in your control file
GetAccountList – This method will return the account list
[HttpGet]
        public JsonResult GetAccountList(int hAccType)
        {
            Dictionary<int, string> accList = new Dictionary<int, string>();
            accList.Add(1, "Acc1");

            object genericResult = new { futureResult = accList };
            return Json(genericResult, JsonRequestBehavior.AllowGet);
        }
GetAccountTypeList - This method will return the account Type list
SaveData - This method will save the data and return the bad entries if save is not successful for any reason.

Comments

Popular posts from this blog

SSIS Merge Join - Both inputs of the transformation must contain at least one sorted column, and those columns must have matching metadata SSIS

jsGrid

Add Item to SharePoint List with attachment using client object model