Monday, January 14, 2019

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 jQueryjQuery 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<intstring> accList = new Dictionary<intstring>();
            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.

No comments: