# \[DATATABLE] JQuery Datatables Editor - Alternative to the official one (ok)

<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2Fs70XErPbi0WVsesgjXtT%2Fimage.png?alt=media&#x26;token=48fbcf92-82a8-4510-a353-bc0fbd36bc7e" alt=""><figcaption></figcaption></figure>

1. [In memory arrays](https://belongstomany.com/example/01_in_memory_arrays/example1.html)
2.

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FHJj7zGS3zF70sep17uLN%2Fimage.png?alt=media&#x26;token=597924f5-cc7d-4cb6-b82e-d1701851c3aa" alt=""><figcaption></figcaption></figure>
```

C:\xampp\htdocs\belongstomany\example\01\_in\_memory\_arrays\example1.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DataTable-AltEditor - Example #1</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <h1>DataTable-AltEditor - Example #1</h1>
        <h2>with array-based datatable rows</h2>
        <p>Rows are contained in some .js file in the form: [1,"Tiger Nixon", "System Architect", "Edinburgh", "5421",
          "2011/04/25", "$320,800"] <br />
          Data is managed in memory. A "Refresh" button is meaningless here.
        </p>
      </div>
    </div>
  </div>
  <div class="container">
    <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
  <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
  <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
  <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
  <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
  <script src="../../src/dataTables.altEditor.free.js"></script>
  <script src="./example1.js"></script>
</body>
</html>

```

C:\xampp\htdocs\belongstomany\example\01\_in\_memory\_arrays\example1.html

```javascript
$(document).ready(function () {
  var dataSet = [
    [1, "Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
    [2, "Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
    [3, "Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
    [4, "Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
    [5, "Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
    [6, "Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
    [7, "Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
    [8, "Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
    [9, "Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
    [10, "Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008/12/13", "$103,600"],
    [11, "Jena Gaines", "Office Manager", "London", "3814", "2008/12/19", "$90,560"],
    [12, "Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013/03/03", "$342,000"],
    [13, "Charde Marshall", "Regional Director", "San Francisco", "6741", "2008/10/16", "$470,600"],
    [14, "Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012/12/18", "$313,500"],
    [15, "Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010/03/17", "$385,750"],
    [16, "Michael Silva", "Marketing Designer", "London", "1581", "2012/11/27", "$198,500"],
    [17, "Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010/06/09", "$725,000"],
    [18, "Gloria Little", "Systems Administrator", "New York", "1721", "2009/04/10", "$237,500"],
    [19, "Bradley Greer", "Software Engineer", "London", "2558", "2012/10/13", "$132,000"],
    [20, "Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012/09/26", "$217,500"],
    [21, "Jenette Caldwell", "Development Lead", "New York", "1937", "2011/09/03", "$345,000"],
    [22, "Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009/06/25", "$675,000"],
    [23, "Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011/12/12", "$106,450"],
    [24, "Doris Wilder", "Sales Assistant", "Sidney", "3023", "2010/09/20", "$85,600"],
    [25, "Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009/10/09", "$1,200,000"],
    [26, "Gavin Joyce", "Developer", "Edinburgh", "8822", "2010/12/22", "$92,575"],
    [27, "Jennifer Chang", "Regional Director", "Singapore", "9239", "2010/11/14", "$357,650"],
    [28, "Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011/06/07", "$206,850"],
    [29, "Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010/03/11", "$850,000"],
    [30, "Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011/08/14", "$163,000"],
    [31, "Michelle House", "Integration Specialist", "Sidney", "2769", "2011/06/02", "$95,400"],
    [32, "Suki Burks", "Developer", "London", "6832", "2009/10/22", "$114,500"],
    [33, "Prescott Bartlett", "Technical Author", "London", "3606", "2011/05/07", "$145,000"],
    [34, "Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008/10/26", "$235,500"],
    [35, "Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011/03/09", "$324,050"],
    [36, "Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009/12/09", "$85,675"]
  ];
  var columnDefs = [{
    title: "Id",
    type: "readonly"
  }, {
    title: "Name",
    type: "text"
  }, {
    title: "Position",
    type: "textarea"
  }, {
    title: "Office"
    //no type = text
  }, {
    title: "Extn.",
    type: "text"
  }, {
    title: "Start date",
    type: "readonly"
  }, {
    title: "Salary",
    type: "text"
  }];
  var myTable;
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    data: dataSet,
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: false,     // Enable altEditor
    buttons: [
      {
        text: 'Add',
        name: 'add'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Edit',
        name: 'edit'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Delete',
        name: 'delete'      // do not change name
      }
    ]
  });
});

```

1. [In memory objects](https://belongstomany.com/example/02_in_memory_objects/example2.html)

<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FN5Qb3BJ8guDrFN1iuk99%2Fimage.png?alt=media&#x26;token=153a00ec-1b19-40f2-8a9e-f516291ed022" alt=""><figcaption></figcaption></figure>

C:\xampp\htdocs\belongstomany\example\02\_in\_memory\_objects\example2.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DataTable-AltEditor - Example #2</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <h1>DataTable-AltEditor - Example #2</h1>
        <h2>with object-based datatable rows</h2>
        Rows are contained in some .js file in the form:
        {id:1, name:"Tiger Nixon", position:"System Architect", office:"Edinburgh", extension:"5421",
        startDate:"2011/04/25",
        salary:"Tiger Nixon"} <br />
        Data is managed in memory. A "Refresh" button is meaningless here.
      </div>
    </div>
  </div>
  <div class="container">
    <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
  <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
  <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
  <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
  <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
  <script src="../../src/dataTables.altEditor.free.js"></script>
  <script src="./example2.js"></script>
</body>
</html>

```

C:\xampp\htdocs\belongstomany\example\02\_in\_memory\_objects\example2.js

```javascript
$(document).ready(function () {
  var dataSet = [
    { id: 1, name: "Tiger Nixon", position: "System Architect", office: "Edinburgh", extension: "5421", startDate: "2011/04/25", salary: "Tiger Nixon" },
    { id: 2, name: "Garrett Winters", position: "Accountant", office: "Tokyo", extension: "8422", startDate: "2011/07/25", salary: "Garrett Winters" },
    { id: 3, name: "Ashton Cox", position: "Junior Technical Author", office: "San Francisco", extension: "1562", startDate: "2009/01/12", salary: "Ashton Cox" },
    { id: 4, name: "Cedric Kelly", position: "Senior Javascript Developer", office: "Edinburgh", extension: "6224", startDate: "2012/03/29", salary: "Cedric Kelly" },
    { id: 5, name: "Airi Satou", position: "Accountant", office: "Tokyo", extension: "5407", startDate: "2008/11/28", salary: "Airi Satou" },
    { id: 6, name: "Brielle Williamson", position: "Integration Specialist", office: "New York", extension: "4804", startDate: "2012/12/02", salary: "Brielle Williamson" },
    { id: 7, name: "Herrod Chandler", position: "Sales Assistant", office: "San Francisco", extension: "9608", startDate: "2012/08/06", salary: "Herrod Chandler" },
    { id: 8, name: "Rhona Davidson", position: "Integration Specialist", office: "Tokyo", extension: "6200", startDate: "2010/10/14", salary: "Rhona Davidson" },
    { id: 9, name: "Colleen Hurst", position: "Javascript Developer", office: "San Francisco", extension: "2360", startDate: "2009/09/15", salary: "Colleen Hurst" },
    { id: 10, name: "Sonya Frost", position: "Software Engineer", office: "Edinburgh", extension: "1667", startDate: "2008/12/13", salary: "Sonya Frost" },
    { id: 11, name: "Jena Gaines", position: "Office Manager", office: "London", extension: "3814", startDate: "2008/12/19", salary: "Jena Gaines" },
    { id: 12, name: "Quinn Flynn", position: "Support Lead", office: "Edinburgh", extension: "9497", startDate: "2013/03/03", salary: "Quinn Flynn" },
    { id: 13, name: "Charde Marshall", position: "Regional Director", office: "San Francisco", extension: "6741", startDate: "2008/10/16", salary: "Charde Marshall" },
    { id: 14, name: "Haley Kennedy", position: "Senior Marketing Designer", office: "London", extension: "3597", startDate: "2012/12/18", salary: "Haley Kennedy" },
    { id: 15, name: "Tatyana Fitzpatrick", position: "Regional Director", office: "London", extension: "1965", startDate: "2010/03/17", salary: "Tatyana Fitzpatrick" },
    { id: 16, name: "Michael Silva", position: "Marketing Designer", office: "London", extension: "1581", startDate: "2012/11/27", salary: "Michael Silva" },
    { id: 17, name: "Paul Byrd", position: "Chief Financial Officer (CFO)", office: "New York", extension: "3059", startDate: "2010/06/09", salary: "Paul Byrd" },
    { id: 18, name: "Gloria Little", position: "Systems Administrator", office: "New York", extension: "1721", startDate: "2009/04/10", salary: "Gloria Little" },
    { id: 19, name: "Bradley Greer", position: "Software Engineer", office: "London", extension: "2558", startDate: "2012/10/13", salary: "Bradley Greer" },
    { id: 20, name: "Dai Rios", position: "Personnel Lead", office: "Edinburgh", extension: "2290", startDate: "2012/09/26", salary: "Dai Rios" },
    { id: 21, name: "Jenette Caldwell", position: "Development Lead", office: "New York", extension: "1937", startDate: "2011/09/03", salary: "Jenette Caldwell" },
    { id: 22, name: "Yuri Berry", position: "Chief Marketing Officer (CMO)", office: "New York", extension: "6154", startDate: "2009/06/25", salary: "Yuri Berry" },
    { id: 23, name: "Caesar Vance", position: "Pre-Sales Support", office: "New York", extension: "8330", startDate: "2011/12/12", salary: "Caesar Vance" },
    { id: 24, name: "Doris Wilder", position: "Sales Assistant", office: "Sidney", extension: "3023", startDate: "2010/09/20", salary: "Doris Wilder" },
    { id: 25, name: "Angelica Ramos", position: "Chief Executive Officer (CEO)", office: "London", extension: "5797", startDate: "2009/10/09", salary: "Angelica Ramos" },
    { id: 26, name: "Gavin Joyce", position: "Developer", office: "Edinburgh", extension: "8822", startDate: "2010/12/22", salary: "Gavin Joyce" },
    { id: 27, name: "Jennifer Chang", position: "Regional Director", office: "Singapore", extension: "9239", startDate: "2010/11/14", salary: "Jennifer Chang" },
    { id: 28, name: "Brenden Wagner", position: "Software Engineer", office: "San Francisco", extension: "1314", startDate: "2011/06/07", salary: "Brenden Wagner" },
    { id: 29, name: "Fiona Green", position: "Chief Operating Officer (COO)", office: "San Francisco", extension: "2947", startDate: "2010/03/11", salary: "Fiona Green" },
    { id: 30, name: "Shou Itou", position: "Regional Marketing", office: "Tokyo", extension: "8899", startDate: "2011/08/14", salary: "Shou Itou" },
    { id: 30, name: "Michelle House", position: "Integration Specialist", office: "Sidney", extension: "2769", startDate: "2011/06/02", salary: "Michelle House" },
    { id: 32, name: "Suki Burks", position: "Developer", office: "London", extension: "6832", startDate: "2009/10/22", salary: "Suki Burks" },
    { id: 33, name: "Prescott Bartlett", position: "Technical Author", office: "London", extension: "3606", startDate: "2011/05/07", salary: "Prescott Bartlett" },
    { id: 34, name: "Gavin Cortez", position: "Team Leader", office: "San Francisco", extension: "2860", startDate: "2008/10/26", salary: "Gavin Cortez" },
    { id: 35, name: "Martena Mccray", position: "Post-Sales support", office: "Edinburgh", extension: "8240", startDate: "2011/03/09", salary: "Martena Mccray" },
    { id: 36, name: "Unity Butler", position: "Marketing Designer", office: "San Francisco", extension: "5384", startDate: "2009/12/09", salary: "Unity Butler" },
  ];
  var columnDefs = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "position",
    title: "Position"
  },
  {
    data: "office",
    title: "Office"
  },
  {
    data: "extension",
    title: "Extn."
  },
  {
    data: "startDate",
    title: "Start date"
  },
  {
    data: "salary",
    title: "Salary"
  }];
  var myTable;
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    data: dataSet,
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [{
      text: 'Add',
      name: 'add'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Edit',
      name: 'edit'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Delete',
      name: 'delete'      // do not change name
    }]
  });
});

```

1. [AJAX objects](https://belongstomany.com/example/03_ajax_objects/example3.html)

<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2F2v7JdcsxWskYSFDIa6ma%2Fimage.png?alt=media&#x26;token=403e8675-499b-4667-a108-19d5660b1860" alt=""><figcaption></figcaption></figure>

C:\xampp\htdocs\belongstomany\example\03\_ajax\_objects\example3.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DataTable-AltEditor - Example #3</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <h1>DataTable-AltEditor - Example #3</h1>
        <h2>with object-based datatable rows loaded via Ajax</h2>
        Rows are retrieved from some AJAX webservice, in the form:
        {id:1, name:"Tiger Nixon", position:"System Architect", office:"Edinburgh", extension:"5421",
        startDate:"2011/04/25",
        salary:"Tiger Nixon"}<br />
        INSERT and UPDATE will fail because there is no real server set up here.
      </div>
    </div>
  </div>
  <div class="container">
    <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
  <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
  <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
  <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
  <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
  <script src="../../src/dataTables.altEditor.free.js"></script>
  <script src="./example3.js"></script>
</body>
</html>

```

C:\xampp\htdocs\belongstomany\example\03\_ajax\_objects\example3.js

```javascript
$(document).ready(function () {
  var columnDefs = [
    {
      data: "id",
      title: "Id",
      type: "readonly"
    },
    {
      data: "name",
      title: "Name"
    },
    {
      data: "position",
      title: "Position"
    },
    {
      data: "office",
      title: "Office"
    },
    {
      data: "extension",
      title: "Extn."
    },
    {
      data: "startDate",
      title: "Start date"
    },
    {
      data: "salary",
      title: "Salary"
    }
  ];
  var myTable;
  var url_ws_mock_get = './mock_svc_load.json';
  var url_ws_mock_ok = './mock_svc_ok.json';
  if (location.href.startsWith("file://")) {
    // local URL's are not allowed
    url_ws_mock_get = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/03_ajax_objects/mock_svc_load.json';
    url_ws_mock_ok = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/03_ajax_objects/mock_svc_ok.json';
  }
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_get,
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [
      {
        text: 'Add',
        name: 'add'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Edit',
        name: 'edit'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Delete',
        name: 'delete'      // do not change name
      },
      {
        text: 'Refresh',
        name: 'refresh'      // do not change name
      }
    ],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
});

```

C:\xampp\htdocs\belongstomany\example\03\_ajax\_objects\mock\_svc\_load.json

```json
[
  {
    "id": 1,
    "name": "Tiger Nixon",
    "position": "System Architect",
    "office": "Edinburgh",
    "extension": "5421",
    "startDate": "2011/04/25",
    "salary": "Tiger Nixon"
  },
  {
    "id": 2,
    "name": "Garrett Winters",
    "position": "Accountant",
    "office": "Tokyo",
    "extension": "8422",
    "startDate": "2011/07/25",
    "salary": "Garrett Winters"
  },
  {
    "id": 3,
    "name": "Ashton Cox",
    "position": "Junior Technical Author",
    "office": "San Francisco",
    "extension": "1562",
    "startDate": "2009/01/12",
    "salary": "Ashton Cox"
  },
  {
    "id": 4,
    "name": "Cedric Kelly",
    "position": "Senior Javascript Developer",
    "office": "Edinburgh",
    "extension": "6224",
    "startDate": "2012/03/29",
    "salary": "Cedric Kelly"
  },
  {
    "id": 5,
    "name": "Airi Satou",
    "position": "Accountant",
    "office": "Tokyo",
    "extension": "5407",
    "startDate": "2008/11/28",
    "salary": "Airi Satou"
  },
  {
    "id": 6,
    "name": "Brielle Williamson",
    "position": "Integration Specialist",
    "office": "New York",
    "extension": "4804",
    "startDate": "2012/12/02",
    "salary": "Brielle Williamson"
  },
  {
    "id": 7,
    "name": "Herrod Chandler",
    "position": "Sales Assistant",
    "office": "San Francisco",
    "extension": "9608",
    "startDate": "2012/08/06",
    "salary": "Herrod Chandler"
  },
  {
    "id": 8,
    "name": "Rhona Davidson",
    "position": "Integration Specialist",
    "office": "Tokyo",
    "extension": "6200",
    "startDate": "2010/10/14",
    "salary": "Rhona Davidson"
  },
  {
    "id": 9,
    "name": "Colleen Hurst",
    "position": "Javascript Developer",
    "office": "San Francisco",
    "extension": "2360",
    "startDate": "2009/09/15",
    "salary": "Colleen Hurst"
  },
  {
    "id": 10,
    "name": "Sonya Frost",
    "position": "Software Engineer",
    "office": "Edinburgh",
    "extension": "1667",
    "startDate": "2008/12/13",
    "salary": "Sonya Frost"
  },
  {
    "id": 11,
    "name": "Jena Gaines",
    "position": "Office Manager",
    "office": "London",
    "extension": "3814",
    "startDate": "2008/12/19",
    "salary": "Jena Gaines"
  },
  {
    "id": 12,
    "name": "Quinn Flynn",
    "position": "Support Lead",
    "office": "Edinburgh",
    "extension": "9497",
    "startDate": "2013/03/03",
    "salary": "Quinn Flynn"
  },
  {
    "id": 13,
    "name": "Charde Marshall",
    "position": "Regional Director",
    "office": "San Francisco",
    "extension": "6741",
    "startDate": "2008/10/16",
    "salary": "Charde Marshall"
  },
  {
    "id": 14,
    "name": "Haley Kennedy",
    "position": "Senior Marketing Designer",
    "office": "London",
    "extension": "3597",
    "startDate": "2012/12/18",
    "salary": "Haley Kennedy"
  },
  {
    "id": 15,
    "name": "Tatyana Fitzpatrick",
    "position": "Regional Director",
    "office": "London",
    "extension": "1965",
    "startDate": "2010/03/17",
    "salary": "Tatyana Fitzpatrick"
  },
  {
    "id": 16,
    "name": "Michael Silva",
    "position": "Marketing Designer",
    "office": "London",
    "extension": "1581",
    "startDate": "2012/11/27",
    "salary": "Michael Silva"
  },
  {
    "id": 17,
    "name": "Paul Byrd",
    "position": "Chief Financial Officer (CFO)",
    "office": "New York",
    "extension": "3059",
    "startDate": "2010/06/09",
    "salary": "Paul Byrd"
  },
  {
    "id": 18,
    "name": "Gloria Little",
    "position": "Systems Administrator",
    "office": "New York",
    "extension": "1721",
    "startDate": "2009/04/10",
    "salary": "Gloria Little"
  },
  {
    "id": 19,
    "name": "Bradley Greer",
    "position": "Software Engineer",
    "office": "London",
    "extension": "2558",
    "startDate": "2012/10/13",
    "salary": "Bradley Greer"
  },
  {
    "id": 20,
    "name": "Dai Rios",
    "position": "Personnel Lead",
    "office": "Edinburgh",
    "extension": "2290",
    "startDate": "2012/09/26",
    "salary": "Dai Rios"
  },
  {
    "id": 21,
    "name": "Jenette Caldwell",
    "position": "Development Lead",
    "office": "New York",
    "extension": "1937",
    "startDate": "2011/09/03",
    "salary": "Jenette Caldwell"
  },
  {
    "id": 22,
    "name": "Yuri Berry",
    "position": "Chief Marketing Officer (CMO)",
    "office": "New York",
    "extension": "6154",
    "startDate": "2009/06/25",
    "salary": "Yuri Berry"
  },
  {
    "id": 23,
    "name": "Caesar Vance",
    "position": "Pre-Sales Support",
    "office": "New York",
    "extension": "8330",
    "startDate": "2011/12/12",
    "salary": "Caesar Vance"
  },
  {
    "id": 24,
    "name": "Doris Wilder",
    "position": "Sales Assistant",
    "office": "Sidney",
    "extension": "3023",
    "startDate": "2010/09/20",
    "salary": "Doris Wilder"
  },
  {
    "id": 25,
    "name": "Angelica Ramos",
    "position": "Chief Executive Officer (CEO)",
    "office": "London",
    "extension": "5797",
    "startDate": "2009/10/09",
    "salary": "Angelica Ramos"
  },
  {
    "id": 26,
    "name": "Gavin Joyce",
    "position": "Developer",
    "office": "Edinburgh",
    "extension": "8822",
    "startDate": "2010/12/22",
    "salary": "Gavin Joyce"
  },
  {
    "id": 27,
    "name": "Jennifer Chang",
    "position": "Regional Director",
    "office": "Singapore",
    "extension": "9239",
    "startDate": "2010/11/14",
    "salary": "Jennifer Chang"
  },
  {
    "id": 28,
    "name": "Brenden Wagner",
    "position": "Software Engineer",
    "office": "San Francisco",
    "extension": "1314",
    "startDate": "2011/06/07",
    "salary": "Brenden Wagner"
  },
  {
    "id": 29,
    "name": "Fiona Green",
    "position": "Chief Operating Officer (COO)",
    "office": "San Francisco",
    "extension": "2947",
    "startDate": "2010/03/11",
    "salary": "Fiona Green"
  },
  {
    "id": 30,
    "name": "Shou Itou",
    "position": "Regional Marketing",
    "office": "Tokyo",
    "extension": "8899",
    "startDate": "2011/08/14",
    "salary": "Shou Itou"
  },
  {
    "id": 30,
    "name": "Michelle House",
    "position": "Integration Specialist",
    "office": "Sidney",
    "extension": "2769",
    "startDate": "2011/06/02",
    "salary": "Michelle House"
  },
  {
    "id": 32,
    "name": "Suki Burks",
    "position": "Developer",
    "office": "London",
    "extension": "6832",
    "startDate": "2009/10/22",
    "salary": "Suki Burks"
  },
  {
    "id": 33,
    "name": "Prescott Bartlett",
    "position": "Technical Author",
    "office": "London",
    "extension": "3606",
    "startDate": "2011/05/07",
    "salary": "Prescott Bartlett"
  },
  {
    "id": 34,
    "name": "Gavin Cortez",
    "position": "Team Leader",
    "office": "San Francisco",
    "extension": "2860",
    "startDate": "2008/10/26",
    "salary": "Gavin Cortez"
  },
  {
    "id": 35,
    "name": "Martena Mccray",
    "position": "Post-Sales support",
    "office": "Edinburgh",
    "extension": "8240",
    "startDate": "2011/03/09",
    "salary": "Martena Mccray"
  },
  {
    "id": 36,
    "name": "Unity Butler",
    "position": "Marketing Designer",
    "office": "San Francisco",
    "extension": "5384",
    "startDate": "2009/12/09",
    "salary": "Unity Butler"
  }
]

```

C:\xampp\htdocs\belongstomany\example\03\_ajax\_objects\mock\_svc\_ok.json

```json
{
  "id": 1,
  "name": "Name modified by server",
  "position": "Modified position",
  "office": "",
  "extension": "",
  "startDate": "",
  "salary": ""
}

```

1. [Some more](https://belongstomany.com/example/04_more/DataTableExample.html)
2.

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FyTArhj6knMLi4CkP99oI%2Fimage.png?alt=media&#x26;token=d5996bcf-a419-4716-ba97-fa572a826e2c" alt=""><figcaption></figcaption></figure>
```

3. C:\xampp\htdocs\belongstomany\example\04\_more\DataTableExample.html
4. ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #4</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
   </head>
   <body>
     <div class="container">
       <div class="row">
         <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
           <h1>DataTable-AltEditor - Example #4</h1>
           This is the original example, not sure everything works yet.
           <table class="table table-striped" id="testTableData">
             <thead>
               <tr>
                 <th></th>
                 <th></th>
                 <th></th>
                 <th></th>
                 <th></th>
               </tr>
             </thead>
             <tbody>
               <tr>
                 <td></td>
                 <td></td>
                 <td></td>
                 <td></td>
                 <td></td>
               </tr>
             </tbody>
           </table>
           <!--
           - saveButton    - onClick, takes all the data from the datatable and sends it to the server
           - cancelButton  - onClick, asks the user if the wants to undo unsaved changes and (if yes)
                             reloads the datatable with the data from the server.
           - messages      - Displays the response from the server.
           -->
           <div>
             <button type='button' class='btn btn-default' id='saveButton' value='Save'>Save</button>
             <button type='button' class='btn btn-default' id='cancelButton' value='Cancel' disabled='true'>Cancel</button>
             <span id='messages'>&nbsp;</span>
           </div>
         </div>
       </div>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script>
       $(document).ready(function () {
         //////////////////////////////////////////
         /*
         IMPORTANT - COLUMNDEFS
         Always add the DT_RowId row and always add it as the first column!
         - Visibility state doesnt matter but searchable
           state should be set to the same value.
         Always add a type!
         Current supported type parameters:
         text      - for editable textfields (including numbers, emails etc.)
         select    - for select menues, if used then options should be specified aswell
         readonly  - for fields with readonly attribute.
         Other parameters:
         MANDATORY:
         id        - Should be set to same value as data-parameter.
         data      - Identifier of value in data from AJAX call.
         title     - Title of column.
         OPTIONAL:
         pattern   - For inputvalidation of the textfield. Specify a regex for the pattern to use.
         errorMsg  - Message that is shown when mismatch with pattern is found.
         hoverMsg  - Message that is shown on mouseover on text fields (hints).
         unique    - Data that can only exist once in the datatable. Shows an error on input if found.
         special   - Only working setting is "portRange". This is in relation to input validation.
                     If used then validation will check for a portrange in format (startPort:endPort)
                     and validate both with the supplied regex.
         */
         //////////////////////////////////////////
         //Example of column definitions.
         var columnDefs = [{
           id: "DT_RowId",
           data: "DT_RowId",
           type: "hidden"
         }, {
           title: "Select example",
           id: "status",
           data: "status",
           type: "select",
           "options": [
             "on",
             "off"
           ]
         }, {
           title: "Text example",
           id: "ipAddress",
           data: "ipAddress",
           type: "text",
           pattern: "^((?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){0,1}$",
           errorMsg: "*Invalid address - Enter valid ip.",
           hoverMsg: "(Optional) - Ex: 82.84.86.88",
           unique: true
         }, {
           title: "Port example",
           id: "port",
           data: "port",
           type: "text",
           special: "portRange",
           pattern: "^([0-9]{1,4}|[1-5][0-9]{4}|6[0-4][0-9]{3}|65[0-4][0-9]{2}|655[0-2][0-9]|6553[0-5])$",
           errorMsg: "*Invalid port - Enter valid port or range.",
           hoverMsg: "Ex: 6112 (single)   or   6111:6333 (range)",
           unique: true
         }, {
           title: "Readonly example",
           id: "read",
           data: "read",
           type: "readonly"
         }]
         var url_ws_mock_get = './example4.json';
         if (location.href.startsWith("file://")) {
           // local URL's are not allowed
           url_ws_mock_get = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/04_more/example4.json';
         }
         //Table creation
         var myTable = $('#testTableData').dataTable({
           dom: 'Bfrltip',                   //Element order: Button container(B) is essential.
           ajax: url_ws_mock_get,   //Receiving data from this source.
           columns: columnDefs,            //Columns defined above.
           select: 'single',               //Only single column selection is implemented.
           altEditor: true,                //Enable altEditor.
           responsive: true,               //Enable responsiveness.
           buttons: [{                     //All implemented buttons. Do not change name attribute.
             text: 'Createddd',
             name: 'add'
           }, {
             extend: 'selected',
             text: 'Edit',
             name: 'edit'
           }, {
             extend: 'selected',
             text: 'Delete',
             name: 'delete'
           }, {
             text: 'Refresh',
             name: 'refresh'
           }]
         });
       });
       // If the user has unsaved changes when reloading/leaving the page, then
       // an alert is displayed asking the user to confirm the action
       $(window).bind('beforeunload', function () {
         if (!$('#cancelButton').is(':disabled')) {
           return "";
         }
       });
     </script>
   </body>
   </html>

   ```

C:\xampp\htdocs\belongstomany\example\04\_more\example4.json

```json
{
  "data": [
    {
      "DT_RowId": 1,
      "ipAddress": "1.2.3.4",
      "status": "on",
      "port": "8080",
      "read": "Hello"
    },
    {
      "DT_RowId": 2,
      "ipAddress": "5.6.7.8",
      "status": "off",
      "port": "8080",
      "read": "World"
    }
  ]
}

```

1. [More datatables in one page](https://belongstomany.com/example/05_two_datatables/example5.html)
2.

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2F1Pc3m9Oc38dXrwadxdB5%2Fimage.png?alt=media&#x26;token=08b54bcf-a6ff-4c08-be1f-4746955c72b8" alt=""><figcaption></figcaption></figure>
```

3. C:\xampp\htdocs\belongstomany\example\05\_two\_datatables\example5.html
4. ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #5</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
   </head>
   <body>
     <div class="container">
       <div class="row">
         <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
           <h1>DataTable-AltEditor - Example #5</h1>
           <h2>with object-based datatable rows loaded via Ajax. Two different datatables.</h2>
           Rows are retrieved from some AJAX webservice, in the form:
           {id:1, name:"Tiger Nixon", position:"System Architect", office:"Edinburgh", extension:"5421",
           startDate:"2011/04/25",
           salary:"Tiger Nixon"}<br />
           INSERT and UPDATE will fail because there is no real server set up here.
         </div>
       </div>
     </div>
     <div class="container">
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example2">
       </table>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example5.js"></script>
   </body>
   </html>

   ```

C:\xampp\htdocs\belongstomany\example\05\_two\_datatables\example5.js

```javascript
$(document).ready(function () {
  var columnDefs = [
    {
      data: "id",
      title: "Id",
      type: "readonly"
    },
    {
      data: "name",
      title: "Name"
    },
    {
      data: "position",
      title: "Position"
    },
    {
      data: "office",
      title: "Office"
    },
    {
      data: "extension",
      title: "Extn."
    },
    {
      data: "startDate",
      title: "Start date"
    },
    {
      data: "salary",
      title: "Salary"
    }
  ];
  var myTable;
  var url_ws_mock_get = '../03_ajax_objects/mock_svc_load.json';
  var url_ws_mock_ok = '../03_ajax_objects/mock_svc_ok.json';
  if (location.href.startsWith("file://")) {
    // local URL's are not allowed
    url_ws_mock_get = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/03_ajax_objects/mock_svc_load.json';
    url_ws_mock_ok = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/03_ajax_objects/mock_svc_ok.json';
  }
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_get,
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [
      {
        text: 'Add',
        name: 'add'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Edit',
        name: 'edit'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Delete',
        name: 'delete'      // do not change name
      },
      {
        text: 'Refresh',
        name: 'refresh'      // do not change name
      }
    ],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
  // ======================================================================================
  var columnDefs2 = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "office",
    title: "Office"
  },
  {
    data: "startDate",
    title: "Start date"
  },
  {
    data: "position",
    title: "Position"
  }];
  var myOtherTable = $('#example2').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_get,
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs2,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [
      {
        text: 'Add',
        name: 'add'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Edit',
        name: 'edit'        // do not change name
      },
      {
        extend: 'selected', // Bind to Selected row
        text: 'Delete',
        name: 'delete'      // do not change name
      },
      {
        text: 'Refresh',
        name: 'refresh'      // do not change name
      }
    ],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
});

```

1. [\
   Select2 and Datetimepicker](https://belongstomany.com/example/06_select_datepicker/example6.html)

<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FPqFcN7u579xxvwYkC9IM%2Fimage.png?alt=media&#x26;token=fcd296e1-aac4-4804-92e5-93046c03b0d9" alt=""><figcaption></figcaption></figure>

C:\xampp\htdocs\belongstomany\example\06\_select\_datepicker\example6.html

```html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>DataTable-AltEditor - Example #6</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
  <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/css/select2.css" />
  <link rel="stylesheet"
    href="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.css" />
</head>
<body>
  <div class="container">
    <div class="row">
      <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
        <h1>DataTable-AltEditor - Example #6</h1>
        <h2>Select2 and Datepicker</h2>
        <p>In this example there is a "single" select2, a "multiple" select2, a date picker, a date/time picker, and a
          "single" select2 with nested objects </p>
      </div>
    </div>
  </div>
  <div class="container">
    <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
    </table>
  </div>
  <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
  <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
  <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
  <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
  <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
  <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/js/select2.js"></script>
  <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jquery-datetimepicker/2.5.20/jquery.datetimepicker.full.js"></script>
  <script src="../../src/dataTables.altEditor.free.js"></script>
  <script src="./example6.js"></script>
</body>
</html>

```

C:\xampp\htdocs\belongstomany\example\06\_select\_datepicker\example6.js

```javascript
var employeeOptions = { "1": "Employee", "2": "Official", "3": "Director" };
var friendsOptions = { "G": "Goofy", "D": "Donald duck", "M": "Mickey", "D": "Daisy" };
var degreesOptions = { "0": "None", "1": "Degree", "2": "High school" };
$(document).ready(function () {
  var columnDefs = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "position",
    title: "Position",
    type: "select",
    options: employeeOptions,
    select2: { width: "100%" },
    render: function (data, type, row, meta) {
      if (data == null || !(data in employeeOptions)) return null;
      return employeeOptions[data];
    }
  },
  {
    data: "startDate",
    title: "Start date",
    datetimepicker: { timepicker: false, format: "Y/m/d" }
  },
  {
    data: "creationTimestamp",
    title: "Creation timestamp",
    datetimepicker: { timepicker: true, format: "Y/m/d H:i" }
  },
  {
    data: "friends",
    title: "Friends",
    type: "select",
    options: friendsOptions,
    multiple: true,
    select2: { width: "100%" },
    render: function (data, type, row, meta) {
      if (data == null || row == null || row.degree == null) return null;
      return data.map(function (x) { return friendsOptions[x]; });
    }
  },
  {
    data: "degree.id",
    title: "Degree (nested obj.)",
    type: "select",
    options: degreesOptions,
    select2: { width: "100%" },
    render: function (data, type, row, meta) {
      if (data == null || row == null || row.degree == null) return null;
      return row.degree.caption;
    }
  }];
  var myTable;
  var url_ws_mock_get = './mock_svc_load.json';
  var url_ws_mock_ok = './mock_svc_ok.json';
  if (location.href.startsWith("file://")) {
    // local URL's are not allowed
    url_ws_mock_get = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/06_select_datepicker/mock_svc_load.json';
    url_ws_mock_ok = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/06_select_datepicker/mock_svc_ok.json';
  }
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_get,
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [{
      text: 'Add',
      name: 'add'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Edit',
      name: 'edit'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Delete',
      name: 'delete'      // do not change name
    },
    {
      text: 'Refresh',
      name: 'refresh'      // do not change name
    }],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
});

```

C:\xampp\htdocs\belongstomany\example\06\_select\_datepicker\mock\_svc\_load.json

```json
[
  {
    "id": 1,
    "name": "Tiger Nixon",
    "position": "1",
    "office": "Edinburgh",
    "extension": "5421",
    "startDate": "2011/04/25",
    "salary": "Tiger Nixon",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [
      "G",
      "D"
    ],
    "degree": {
      "id": 0,
      "caption": "None"
    }
  },
  {
    "id": 2,
    "name": "Garrett Winters",
    "position": "1",
    "office": "Tokyo",
    "extension": "8422",
    "startDate": "2011/07/25",
    "salary": "Garrett Winters",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [
      "D"
    ],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 3,
    "name": "Ashton Cox",
    "position": "2",
    "office": "San Francisco",
    "extension": "1562",
    "startDate": "2009/01/12",
    "salary": "Ashton Cox",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 4,
    "name": "Cedric Kelly",
    "position": "1",
    "office": "Edinburgh",
    "extension": "6224",
    "startDate": "2012/03/29",
    "salary": "Cedric Kelly",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 5,
    "name": "Airi Satou",
    "position": "1",
    "office": "Tokyo",
    "extension": "5407",
    "startDate": "2008/11/28",
    "salary": "Airi Satou",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 6,
    "name": "Brielle Williamson",
    "position": "1",
    "office": "New York",
    "extension": "4804",
    "startDate": "2012/12/02",
    "salary": "Brielle Williamson",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 7,
    "name": "Herrod Chandler",
    "position": "1",
    "office": "San Francisco",
    "extension": "9608",
    "startDate": "2012/08/06",
    "salary": "Herrod Chandler",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 8,
    "name": "Rhona Davidson",
    "position": "1",
    "office": "Tokyo",
    "extension": "6200",
    "startDate": "2010/10/14",
    "salary": "Rhona Davidson",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 9,
    "name": "Colleen Hurst",
    "position": "2",
    "office": "San Francisco",
    "extension": "2360",
    "startDate": "2009/09/15",
    "salary": "Colleen Hurst",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 10,
    "name": "Sonya Frost",
    "position": "3",
    "office": "Edinburgh",
    "extension": "1667",
    "startDate": "2008/12/13",
    "salary": "Sonya Frost",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 11,
    "name": "Jena Gaines",
    "position": "2",
    "office": "London",
    "extension": "3814",
    "startDate": "2008/12/19",
    "salary": "Jena Gaines",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 12,
    "name": "Quinn Flynn",
    "position": "1",
    "office": "Edinburgh",
    "extension": "9497",
    "startDate": "2013/03/03",
    "salary": "Quinn Flynn",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 13,
    "name": "Charde Marshall",
    "position": "1",
    "office": "San Francisco",
    "extension": "6741",
    "startDate": "2008/10/16",
    "salary": "Charde Marshall",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 14,
    "name": "Haley Kennedy",
    "position": "1",
    "office": "London",
    "extension": "3597",
    "startDate": "2012/12/18",
    "salary": "Haley Kennedy",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 15,
    "name": "Tatyana Fitzpatrick",
    "position": "1",
    "office": "London",
    "extension": "1965",
    "startDate": "2010/03/17",
    "salary": "Tatyana Fitzpatrick",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 16,
    "name": "Michael Silva",
    "position": "1",
    "office": "London",
    "extension": "1581",
    "startDate": "2012/11/27",
    "salary": "Michael Silva",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 17,
    "name": "Paul Byrd",
    "position": "1",
    "office": "New York",
    "extension": "3059",
    "startDate": "2010/06/09",
    "salary": "Paul Byrd",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 18,
    "name": "Gloria Little",
    "position": "2",
    "office": "New York",
    "extension": "1721",
    "startDate": "2009/04/10",
    "salary": "Gloria Little",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 19,
    "name": "Bradley Greer",
    "position": "2",
    "office": "London",
    "extension": "2558",
    "startDate": "2012/10/13",
    "salary": "Bradley Greer",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 20,
    "name": "Dai Rios",
    "position": "1",
    "office": "Edinburgh",
    "extension": "2290",
    "startDate": "2012/09/26",
    "salary": "Dai Rios",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 21,
    "name": "Jenette Caldwell",
    "position": "1",
    "office": "New York",
    "extension": "1937",
    "startDate": "2011/09/03",
    "salary": "Jenette Caldwell",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 22,
    "name": "Yuri Berry",
    "position": "1",
    "office": "New York",
    "extension": "6154",
    "startDate": "2009/06/25",
    "salary": "Yuri Berry",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 23,
    "name": "Caesar Vance",
    "position": "1",
    "office": "New York",
    "extension": "8330",
    "startDate": "2011/12/12",
    "salary": "Caesar Vance",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 24,
    "name": "Doris Wilder",
    "position": "1",
    "office": "Sidney",
    "extension": "3023",
    "startDate": "2010/09/20",
    "salary": "Doris Wilder",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 25,
    "name": "Angelica Ramos",
    "position": "1",
    "office": "London",
    "extension": "5797",
    "startDate": "2009/10/09",
    "salary": "Angelica Ramos",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 26,
    "name": "Gavin Joyce",
    "position": "1",
    "office": "Edinburgh",
    "extension": "8822",
    "startDate": "2010/12/22",
    "salary": "Gavin Joyce",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 27,
    "name": "Jennifer Chang",
    "position": "1",
    "office": "Singapore",
    "extension": "9239",
    "startDate": "2010/11/14",
    "salary": "Jennifer Chang",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 28,
    "name": "Brenden Wagner",
    "position": "1",
    "office": "San Francisco",
    "extension": "1314",
    "startDate": "2011/06/07",
    "salary": "Brenden Wagner",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 29,
    "name": "Fiona Green",
    "position": "1",
    "office": "San Francisco",
    "extension": "2947",
    "startDate": "2010/03/11",
    "salary": "Fiona Green",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 30,
    "name": "Shou Itou",
    "position": "1",
    "office": "Tokyo",
    "extension": "8899",
    "startDate": "2011/08/14",
    "salary": "Shou Itou",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 30,
    "name": "Michelle House",
    "position": "1",
    "office": "Sidney",
    "extension": "2769",
    "startDate": "2011/06/02",
    "salary": "Michelle House",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 32,
    "name": "Suki Burks",
    "position": "2",
    "office": "London",
    "extension": "6832",
    "startDate": "2009/10/22",
    "salary": "Suki Burks",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 33,
    "name": "Prescott Bartlett",
    "position": "1",
    "office": "London",
    "extension": "3606",
    "startDate": "2011/05/07",
    "salary": "Prescott Bartlett",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 34,
    "name": "Gavin Cortez",
    "position": "1",
    "office": "San Francisco",
    "extension": "2860",
    "startDate": "2008/10/26",
    "salary": "Gavin Cortez",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 35,
    "name": "Martena Mccray",
    "position": "1",
    "office": "Edinburgh",
    "extension": "8240",
    "startDate": "2011/03/09",
    "salary": "Martena Mccray",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "High school"
    }
  },
  {
    "id": 36,
    "name": "Unity Butler",
    "position": "1",
    "office": "San Francisco",
    "extension": "5384",
    "startDate": "2009/12/09",
    "salary": "Unity Butler",
    "creationTimestamp": "2000-01-01 13:50:43",
    "friends": [],
    "degree": {
      "id": 2,
      "caption": "high school"
    }
  }
]

```

C:\xampp\htdocs\belongstomany\example\06\_select\_datepicker\mock\_svc\_ok.json

```json
{
  "id": 1,
  "name": "Name modified by server",
  "position": "1",
  "office": "",
  "extension": "",
  "startDate": "",
  "salary": "",
  "creationTimestamp": "",
  "friends": [],
  "degree": {
    "id": 0,
    "caption": "None"
  }
}

```

1. [Dependent items](https://belongstomany.com/example/07_dependent_select/example7.html)
2. C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\example7.html
3. ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #3</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
     <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/css/select2.css" />
   </head>
   <body>
     <div class="container">
       <div class="row">
         <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
           <h1>DataTable-AltEditor - Example #7</h1>
           <h2>with object-based datatable rows loaded via Ajax</h2>
           <p>Populate SELECT options according to values from another field.
             Hide/show fields according to values from another field.
           </p>
         </div>
       </div>
     </div>
     <div class="container">
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.7/js/select2.js"></script>>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example7.js"></script>
   </body>
   </html>

   ```

C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\example7.js

```javascript
var url_ws_mock_prefix = './';
if (location.href.startsWith("file://")) {
  // local URL's are not allowed
  url_ws_mock_prefix = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/07_dependent_select/';
}
var countryOptions = ['Italy', 'France', 'Germany'];
var allTownsOptions = ["Torino", "Roma", "Milano", "Napoli", "Paris", "Lyon", "Toulose"];
$(document).ready(function () {
  var columnDefs = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "country",
    title: "Country",
    type: "select",
    options: countryOptions,
    select2: { width: "100%" },
    editorOnChange: function (event, altEditor) {
      console.log(event, altEditor);
      var country = $(event.currentTarget).val();
      /*
      In a real world application, this should just call a single webservice,
      passing rowdatata.country as argument
      */
      if (country == "Italy") {
        $(altEditor.modal_selector).find("#alteditor-row-town").show();
        $.ajax({
          url: url_ws_mock_prefix + 'mock_svc_italy.json',
          type: 'GET',
          success: function (options) {
            console.log(options);
            var town = $(altEditor.modal_selector).find('#town');
            altEditor.reloadOptions(town, options);
          }
        });
      } else if (country == "France") {
        $(altEditor.modal_selector).find("#alteditor-row-town").show();
        $.ajax({
          url: url_ws_mock_prefix + 'mock_svc_france.json',
          type: 'GET',
          success: function (options) {
            console.log(options);
            var town = $(altEditor.modal_selector).find('#town');
            altEditor.reloadOptions(town, options);
          }
        });
      } else {
        $(altEditor.modal_selector).find("#alteditor-row-town").hide();
      }
    }
  },
  {
    data: "town",
    title: "Town",
    type: "select",
    options: allTownsOptions,
    select2: { width: "100%" }
  }];
  var myTable;
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_prefix + 'mock_svc_load.json',
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [{
      text: 'Add',
      name: 'add'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Edit',
      name: 'edit'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Delete',
      name: 'delete'      // do not change name
    },
    {
      text: 'Refresh',
      name: 'refresh'      // do not change name
    }],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_prefix + 'mock_svc_ok.json',
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_prefix + 'mock_svc_ok.json',
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_prefix + 'mock_svc_ok.json',
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
});

```

C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\mock\_svc\_france.json

```json
[
  "Paris",
  "Lyon",
  "Toulose"
]

```

C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\mock\_svc\_italy.json

```json
[
  "Torino",
  "Roma",
  "Milano",
  "Napoli"
]

```

C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\mock\_svc\_load.json

```json
[
  {
    "id": 1,
    "name": "Tiger Nixon",
    "position": "System Architect",
    "country": "Italy",
    "town": "Torino"
  },
  {
    "id": 2,
    "name": "Garrett Winters",
    "position": "Accountant",
    "country": "Italy",
    "town": "Roma"
  },
  {
    "id": 3,
    "name": "Ashton Cox",
    "position": "Junior Technical Author",
    "country": "France",
    "town": "Lyon"
  },
  {
    "id": 4,
    "name": "Cedric Kelly",
    "position": "Senior Javascript Developer",
    "country": "Germany",
    "town": "Munich"
  },
  {
    "id": 5,
    "name": "Airi Satou",
    "position": "Accountant",
    "country": "Italy",
    "town": "Torino"
  },
  {
    "id": 6,
    "name": "Brielle Williamson",
    "position": "Integration Specialist",
    "country": "France",
    "town": "Paris"
  },
  {
    "id": 7,
    "name": "Herrod Chandler",
    "position": "Sales Assistant",
    "country": "France",
    "town": "Paris"
  },
  {
    "id": 8,
    "name": "Rhona Davidson",
    "position": "Integration Specialist",
    "country": "Germany",
    "town": "Berlin"
  },
  {
    "id": 9,
    "name": "Colleen Hurst",
    "position": "Javascript Developer",
    "country": "Germany",
    "town": "Berlin"
  },
  {
    "id": 10,
    "name": "Sonya Frost",
    "position": "Software Engineer",
    "country": "France",
    "town": "Lyon"
  },
  {
    "id": 11,
    "name": "Jena Gaines",
    "position": "Office Manager",
    "country": "Italy",
    "town": "Roma"
  },
  {
    "id": 12,
    "name": "Quinn Flynn",
    "position": "Support Lead",
    "country": "Italy",
    "town": "Roma"
  },
  {
    "id": 13,
    "name": "Charde Marshall",
    "position": "Regional Director",
    "country": "Italy",
    "town": "Roma"
  }
]

```

C:\xampp\htdocs\belongstomany\example\07\_dependent\_select\mock\_svc\_ok.json

```json
{
  "id": 1,
  "name": "Name modified by server",
  "position": "Modified position",
  "country": "Italy",
  "town": "Roma"
}

```

1. [Validation](https://belongstomany.com/example/08_validation/example8.html)
2. C:\xampp\htdocs\belongstomany\example\08\_validation\example8.html
3. ![](https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FIqfrZ8Xfgb5i8ZoCzwo7%2Fimage.png?alt=media\&token=7bff3795-f326-45ee-ae54-a8c3ccc50f24)

   ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #8</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
   </head>
   <body>
     <div class="container">
       <div class="row">
         <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
           <h1>DataTable-AltEditor - Example #8</h1>
           <h2>Form validation</h2>
         </div>
       </div>
     </div>
     <div class="container">
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
     </div>
     <style>
       input:invalid {
         border-color: red
       }
     </style>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example8.js"></script>
   </body>
   </html>

   ```

   C:\xampp\htdocs\belongstomany\example\08\_validation\example8.js
4. ```javascript
   $(document).ready(function () {
     var dataSet = [
       [1, "Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011-04-25", "$320,800"],
       [2, "Garrett Winters", "Accountant", "Tokyo", "8422", "2011-07-25", "$170,750"],
       [3, "Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009-01-12", "$86,000"],
       [4, "Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012-03-29", "$433,060"],
       [5, "Airi Satou", "Accountant", "Tokyo", "5407", "2008-11-28", "$162,700"],
       [6, "Brielle Williamson", "Integration Specialist", "New York", "4804", "2012-12-02", "$372,000"],
       [7, "Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012-08-06", "$137,500"],
       [8, "Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010-10-14", "$327,900"],
       [9, "Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009-09-15", "$205,500"],
       [10, "Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008-12-13", "$103,600"],
       [11, "Jena Gaines", "Office Manager", "London", "3814", "2008-12-19", "$90,560"],
       [12, "Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013-03-03", "$342,000"],
       [13, "Charde Marshall", "Regional Director", "San Francisco", "6741", "2008-10-16", "$470,600"],
       [14, "Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012-12-18", "$313,500"],
       [15, "Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010-03-17", "$385,750"],
       [16, "Michael Silva", "Marketing Designer", "London", "1581", "2012-11-27", "$198,500"],
       [17, "Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010-06-09", "$725,000"],
       [18, "Gloria Little", "Systems Administrator", "New York", "1721", "2009-04-10", "$237,500"],
       [19, "Bradley Greer", "Software Engineer", "London", "2558", "2012-10-13", "$132,000"],
       [20, "Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012-09-26", "$217,500"],
       [21, "Jenette Caldwell", "Development Lead", "New York", "1937", "2011-09-03", "$345,000"],
       [22, "Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009-06-25", "$675,000"],
       [23, "Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011-12-12", "$106,450"],
       [24, "Doris Wilder", "Sales Assistant", "Sidney", "3023", "2010-09-20", "$85,600"],
       [25, "Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009-10-09", "$1,200,000"],
       [26, "Gavin Joyce", "Developer", "Edinburgh", "8822", "2010-12-22", "$92,575"],
       [27, "Jennifer Chang", "Regional Director", "Singapore", "9239", "2010-11-14", "$357,650"],
       [28, "Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011-06-07", "$206,850"],
       [29, "Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010-03-11", "$850,000"],
       [30, "Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011-08-14", "$163,000"],
       [31, "Michelle House", "Integration Specialist", "Sidney", "2769", "2011-06-02", "$95,400"],
       [32, "Suki Burks", "Developer", "London", "6832", "2009-10-22", "$114,500"],
       [33, "Prescott Bartlett", "Technical Author", "London", "3606", "2011-05-07", "$145,000"],
       [34, "Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008-10-26", "$235,500"],
       [35, "Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011-03-09", "$324,050"],
       [36, "Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009-12-09", "$85,675"]
     ];
     var columnDefs = [{
       title: "Id",
       type: "readonly"
     }, {
       title: "Name",
       type: "text",
       required: true,
       unique: true
     }, {
       title: "Position",
       required: true,
       type: "text"
     }, {
       title: "Office"
       //no type = text
     }, {
       title: "Extn.",
       type: "number"
     }, {
       title: "Start date",
       type: "date"
     }, {
       title: "Salary",
       type: "text",
       pattern: "\\$[0-9]*,[0-9]{3}",
       hoverMsg: "At least $1,000"
     }];
     var myTable;
     myTable = $('#example').DataTable({
       "sPaginationType": "full_numbers",
       data: dataSet,
       columns: columnDefs,
       dom: 'Bfrtip',        // Needs button container
       select: 'single',
       responsive: true,
       altEditor: true,     // Enable altEditor
       buttons: [{
         text: 'Add',
         name: 'add'        // do not change name
       },
       {
         extend: 'selected', // Bind to Selected row
         text: 'Edit',
         name: 'edit'        // do not change name
       },
       {
         extend: 'selected', // Bind to Selected row
         text: 'Delete',
         name: 'delete'      // do not change name
       }]
     });
   });

   ```
5. [Translations](https://belongstomany.com/example/09_translations/example9.html)
6.

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FmxaZZEygpilW6qI9nVyM%2Fimage.png?alt=media&#x26;token=715c6367-dc70-4ffb-b98a-b5b4f133ce52" alt=""><figcaption></figcaption></figure>
```

```
C:\xampp\htdocs\belongstomany\example\09\_translations\example9.js
```

7\.
8. \`\`\`javascript
$(document).ready(function () {
var dataSet = \[
\[1, "Tiger Nixon", "System Architect", "Edinburgh", "5421", "2011/04/25", "$320,800"],
\[2, "Garrett Winters", "Accountant", "Tokyo", "8422", "2011/07/25", "$170,750"],
\[3, "Ashton Cox", "Junior Technical Author", "San Francisco", "1562", "2009/01/12", "$86,000"],
\[4, "Cedric Kelly", "Senior Javascript Developer", "Edinburgh", "6224", "2012/03/29", "$433,060"],
\[5, "Airi Satou", "Accountant", "Tokyo", "5407", "2008/11/28", "$162,700"],
\[6, "Brielle Williamson", "Integration Specialist", "New York", "4804", "2012/12/02", "$372,000"],
\[7, "Herrod Chandler", "Sales Assistant", "San Francisco", "9608", "2012/08/06", "$137,500"],
\[8, "Rhona Davidson", "Integration Specialist", "Tokyo", "6200", "2010/10/14", "$327,900"],
\[9, "Colleen Hurst", "Javascript Developer", "San Francisco", "2360", "2009/09/15", "$205,500"],
\[10, "Sonya Frost", "Software Engineer", "Edinburgh", "1667", "2008/12/13", "$103,600"],
\[11, "Jena Gaines", "Office Manager", "London", "3814", "2008/12/19", "$90,560"],
\[12, "Quinn Flynn", "Support Lead", "Edinburgh", "9497", "2013/03/03", "$342,000"],
\[13, "Charde Marshall", "Regional Director", "San Francisco", "6741", "2008/10/16", "$470,600"],
\[14, "Haley Kennedy", "Senior Marketing Designer", "London", "3597", "2012/12/18", "$313,500"],
\[15, "Tatyana Fitzpatrick", "Regional Director", "London", "1965", "2010/03/17", "$385,750"],
\[16, "Michael Silva", "Marketing Designer", "London", "1581", "2012/11/27", "$198,500"],
\[17, "Paul Byrd", "Chief Financial Officer (CFO)", "New York", "3059", "2010/06/09", "$725,000"],
\[18, "Gloria Little", "Systems Administrator", "New York", "1721", "2009/04/10", "$237,500"],
\[19, "Bradley Greer", "Software Engineer", "London", "2558", "2012/10/13", "$132,000"],
\[20, "Dai Rios", "Personnel Lead", "Edinburgh", "2290", "2012/09/26", "$217,500"],
\[21, "Jenette Caldwell", "Development Lead", "New York", "1937", "2011/09/03", "$345,000"],
\[22, "Yuri Berry", "Chief Marketing Officer (CMO)", "New York", "6154", "2009/06/25", "$675,000"],
\[23, "Caesar Vance", "Pre-Sales Support", "New York", "8330", "2011/12/12", "$106,450"],
\[24, "Doris Wilder", "Sales Assistant", "Sidney", "3023", "2010/09/20", "$85,600"],
\[25, "Angelica Ramos", "Chief Executive Officer (CEO)", "London", "5797", "2009/10/09", "$1,200,000"],
\[26, "Gavin Joyce", "Developer", "Edinburgh", "8822", "2010/12/22", "$92,575"],
\[27, "Jennifer Chang", "Regional Director", "Singapore", "9239", "2010/11/14", "$357,650"],
\[28, "Brenden Wagner", "Software Engineer", "San Francisco", "1314", "2011/06/07", "$206,850"],
\[29, "Fiona Green", "Chief Operating Officer (COO)", "San Francisco", "2947", "2010/03/11", "$850,000"],
\[30, "Shou Itou", "Regional Marketing", "Tokyo", "8899", "2011/08/14", "$163,000"],
\[31, "Michelle House", "Integration Specialist", "Sidney", "2769", "2011/06/02", "$95,400"],
\[32, "Suki Burks", "Developer", "London", "6832", "2009/10/22", "$114,500"],
\[33, "Prescott Bartlett", "Technical Author", "London", "3606", "2011/05/07", "$145,000"],
\[34, "Gavin Cortez", "Team Leader", "San Francisco", "2860", "2008/10/26", "$235,500"],
\[35, "Martena Mccray", "Post-Sales support", "Edinburgh", "8240", "2011/03/09", "$324,050"],
\[36, "Unity Butler", "Marketing Designer", "San Francisco", "5384", "2009/12/09", "$85,675"]
];
var columnDefs = \[{
title: "Id",
type: "readonly"
}, {
title: "Name",
type: "text"
}, {
title: "Position",
type: "text"
}, {
title: "Office"
//no type = text
}, {
title: "Extn.",
type: "text"
}, {
title: "Start date",
type: "readonly"
}, {
title: "Salary",
type: "text"
}];
var myTable;
myTable = $('#example').DataTable({
"sPaginationType": "full\_numbers",
data: dataSet,
columns: columnDefs,
dom: 'Bfrtip',        // Needs button container
select: 'single',
responsive: true,
altEditor: true,     // Enable altEditor
buttons: \[{
text: 'Thêm',
name: 'add'        // do not change name
},
{
extend: 'selected', // Bind to Selected row
text: 'Chỉnh sửa',
name: 'edit'        // do not change name
},
{
extend: 'selected', // Bind to Selected row
text: 'Xóa',
name: 'delete'      // do not change name
}],
language: {
// url: '<https://cdn.datatables.net/plug-ins/1.10.20/i18n/Vietnamese.json>',
url: '<https://belongstomany.com/example/09_translations/Vietnamese.json>',
altEditorUrl: '../../translations/vi.json'
}
});
});

````

C:\xampp\htdocs\belongstomany\example\09\_translations\Vietnamese.json

```json


{
 "sProcessing":   "Đang xử lý...",
 "sLengthMenu":   "Xem _MENU_ mục",
 "sZeroRecords":  "Không tìm thấy dòng nào phù hợp",
 "sInfo":         "Đang xem _START_ đến _END_ trong tổng số _TOTAL_ mục",
 "sInfoEmpty":    "Đang xem 0 đến 0 trong tổng số 0 mục",
 "sInfoFiltered": "(được lọc từ _MAX_ mục)",
 "sInfoPostFix":  "",
 "sSearch":       "Tìm:",
 "sUrl":          "",
 "oPaginate": {
 	"sFirst":    "Đầu",
 	"sPrevious": "Trước",
 	"sNext":     "Tiếp",
 	"sLast":     "Cuối"
 }
}

````

1. [File upload](https://belongstomany.com/example/10_file_upload/example10.html)
2. C:\xampp\htdocs\belongstomany\example\10\_file\_upload\example10.html
3. ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #10</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
   </head>
   <body>
     <div class="container">
       <h1>DataTable-AltEditor - Example #10</h1>
       <h2>Files and images</h2>
       <p>For file download, your best option is to provide a direct link for each row and download it when required.</p>
       <p>For file upload, a naive implementation is provided, the whole file is encoded in base 64 and uploaded
         togheter with the row. Not intended for huge files.</p>
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example10.js"></script>
   </body>
   </html>

   ```

C:\xampp\htdocs\belongstomany\example\10\_file\_upload\example10.js

```javascript
$(document).ready(function () {
  var columnDefs = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "position",
    title: "Position"
  },
  {
    data: "imagelink",
    title: "Avatar (direct link)",
    render: function (data, type, row, meta) {
      if (data) return `<img style='max-width:50px;max-height:50px' src='${data}'></img> or <button onclick='window.open("${data}")'>Download</button>`;
    },
    disabled: true
  },
  {
    name: "image",
    data: null,
    render: function (data, type, row, meta) {
      return "My file";
    },
    type: "file",
    title: "Avatar (base64 upload)"
  }];
  var myTable;
  // local URL's are not allowed
  var url_ws_mock_get = './mock_svc_load.json';
  var url_ws_mock_ok = './mock_svc_ok.json';
  if (location.href.startsWith("file://")) {
    // local URL's are not allowed
    url_ws_mock_get = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/10_file_upload/mock_svc_load.json';
    url_ws_mock_ok = 'https://luca-vercelli.github.io/DataTable-AltEditor/example/10_file_upload/mock_svc_ok.json';
  }
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    ajax: {
      url: url_ws_mock_get,
      // our data is an array of objects, in the root node instead of /data node, so we need 'dataSrc' parameter
      dataSrc: ''
    },
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [{
      text: 'Add',
      name: 'add'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Edit',
      name: 'edit'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Delete',
      name: 'delete'      // do not change name
    },
    {
      text: 'Refresh',
      name: 'refresh'      // do not change name
    }],
    onAddRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be / with type='PUT'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onDeleteRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='DELETE'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    },
    onEditRow: function (datatable, rowdata, success, error) {
      $.ajax({
        // a tipycal url would be /{id} with type='POST'
        url: url_ws_mock_ok,
        type: 'GET',
        data: rowdata,
        success: success,
        error: error
      });
    }
  });
});

```

C:\xampp\htdocs\belongstomany\example\10\_file\_upload\mock\_svc\_load.json

```json
[
  {
    "id": 1,
    "name": "Tiger Nixon",
    "position": "System Architect",
    "office": "Edinburgh",
    "extension": "5421",
    "startDate": "2011/04/25",
    "salary": "Tiger Nixon",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 2,
    "name": "Garrett Winters",
    "position": "Accountant",
    "office": "Tokyo",
    "extension": "8422",
    "startDate": "2011/07/25",
    "salary": "Garrett Winters",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 3,
    "name": "Ashton Cox",
    "position": "Junior Technical Author",
    "office": "San Francisco",
    "extension": "1562",
    "startDate": "2009/01/12",
    "salary": "Ashton Cox",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 4,
    "name": "Cedric Kelly",
    "position": "Senior Javascript Developer",
    "office": "Edinburgh",
    "extension": "6224",
    "startDate": "2012/03/29",
    "salary": "Cedric Kelly",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 5,
    "name": "Airi Satou",
    "position": "Accountant",
    "office": "Tokyo",
    "extension": "5407",
    "startDate": "2008/11/28",
    "salary": "Airi Satou",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 6,
    "name": "Brielle Williamson",
    "position": "Integration Specialist",
    "office": "New York",
    "extension": "4804",
    "startDate": "2012/12/02",
    "salary": "Brielle Williamson",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 7,
    "name": "Herrod Chandler",
    "position": "Sales Assistant",
    "office": "San Francisco",
    "extension": "9608",
    "startDate": "2012/08/06",
    "salary": "Herrod Chandler",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 8,
    "name": "Rhona Davidson",
    "position": "Integration Specialist",
    "office": "Tokyo",
    "extension": "6200",
    "startDate": "2010/10/14",
    "salary": "Rhona Davidson",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 9,
    "name": "Colleen Hurst",
    "position": "Javascript Developer",
    "office": "San Francisco",
    "extension": "2360",
    "startDate": "2009/09/15",
    "salary": "Colleen Hurst",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 10,
    "name": "Sonya Frost",
    "position": "Software Engineer",
    "office": "Edinburgh",
    "extension": "1667",
    "startDate": "2008/12/13",
    "salary": "Sonya Frost",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 11,
    "name": "Jena Gaines",
    "position": "Office Manager",
    "office": "London",
    "extension": "3814",
    "startDate": "2008/12/19",
    "salary": "Jena Gaines",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 12,
    "name": "Quinn Flynn",
    "position": "Support Lead",
    "office": "Edinburgh",
    "extension": "9497",
    "startDate": "2013/03/03",
    "salary": "Quinn Flynn",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 13,
    "name": "Charde Marshall",
    "position": "Regional Director",
    "office": "San Francisco",
    "extension": "6741",
    "startDate": "2008/10/16",
    "salary": "Charde Marshall",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 14,
    "name": "Haley Kennedy",
    "position": "Senior Marketing Designer",
    "office": "London",
    "extension": "3597",
    "startDate": "2012/12/18",
    "salary": "Haley Kennedy",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 15,
    "name": "Tatyana Fitzpatrick",
    "position": "Regional Director",
    "office": "London",
    "extension": "1965",
    "startDate": "2010/03/17",
    "salary": "Tatyana Fitzpatrick",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 16,
    "name": "Michael Silva",
    "position": "Marketing Designer",
    "office": "London",
    "extension": "1581",
    "startDate": "2012/11/27",
    "salary": "Michael Silva",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 17,
    "name": "Paul Byrd",
    "position": "Chief Financial Officer (CFO)",
    "office": "New York",
    "extension": "3059",
    "startDate": "2010/06/09",
    "salary": "Paul Byrd",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 18,
    "name": "Gloria Little",
    "position": "Systems Administrator",
    "office": "New York",
    "extension": "1721",
    "startDate": "2009/04/10",
    "salary": "Gloria Little",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 19,
    "name": "Bradley Greer",
    "position": "Software Engineer",
    "office": "London",
    "extension": "2558",
    "startDate": "2012/10/13",
    "salary": "Bradley Greer",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 20,
    "name": "Dai Rios",
    "position": "Personnel Lead",
    "office": "Edinburgh",
    "extension": "2290",
    "startDate": "2012/09/26",
    "salary": "Dai Rios",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 21,
    "name": "Jenette Caldwell",
    "position": "Development Lead",
    "office": "New York",
    "extension": "1937",
    "startDate": "2011/09/03",
    "salary": "Jenette Caldwell",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 22,
    "name": "Yuri Berry",
    "position": "Chief Marketing Officer (CMO)",
    "office": "New York",
    "extension": "6154",
    "startDate": "2009/06/25",
    "salary": "Yuri Berry",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 23,
    "name": "Caesar Vance",
    "position": "Pre-Sales Support",
    "office": "New York",
    "extension": "8330",
    "startDate": "2011/12/12",
    "salary": "Caesar Vance",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 24,
    "name": "Doris Wilder",
    "position": "Sales Assistant",
    "office": "Sidney",
    "extension": "3023",
    "startDate": "2010/09/20",
    "salary": "Doris Wilder",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 25,
    "name": "Angelica Ramos",
    "position": "Chief Executive Officer (CEO)",
    "office": "London",
    "extension": "5797",
    "startDate": "2009/10/09",
    "salary": "Angelica Ramos",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 26,
    "name": "Gavin Joyce",
    "position": "Developer",
    "office": "Edinburgh",
    "extension": "8822",
    "startDate": "2010/12/22",
    "salary": "Gavin Joyce",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 27,
    "name": "Jennifer Chang",
    "position": "Regional Director",
    "office": "Singapore",
    "extension": "9239",
    "startDate": "2010/11/14",
    "salary": "Jennifer Chang",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 28,
    "name": "Brenden Wagner",
    "position": "Software Engineer",
    "office": "San Francisco",
    "extension": "1314",
    "startDate": "2011/06/07",
    "salary": "Brenden Wagner",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 29,
    "name": "Fiona Green",
    "position": "Chief Operating Officer (COO)",
    "office": "San Francisco",
    "extension": "2947",
    "startDate": "2010/03/11",
    "salary": "Fiona Green",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 30,
    "name": "Shou Itou",
    "position": "Regional Marketing",
    "office": "Tokyo",
    "extension": "8899",
    "startDate": "2011/08/14",
    "salary": "Shou Itou",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 30,
    "name": "Michelle House",
    "position": "Integration Specialist",
    "office": "Sidney",
    "extension": "2769",
    "startDate": "2011/06/02",
    "salary": "Michelle House",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 32,
    "name": "Suki Burks",
    "position": "Developer",
    "office": "London",
    "extension": "6832",
    "startDate": "2009/10/22",
    "salary": "Suki Burks",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 33,
    "name": "Prescott Bartlett",
    "position": "Technical Author",
    "office": "London",
    "extension": "3606",
    "startDate": "2011/05/07",
    "salary": "Prescott Bartlett",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 34,
    "name": "Gavin Cortez",
    "position": "Team Leader",
    "office": "San Francisco",
    "extension": "2860",
    "startDate": "2008/10/26",
    "salary": "Gavin Cortez",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 35,
    "name": "Martena Mccray",
    "position": "Post-Sales support",
    "office": "Edinburgh",
    "extension": "8240",
    "startDate": "2011/03/09",
    "salary": "Martena Mccray",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  },
  {
    "id": 36,
    "name": "Unity Butler",
    "position": "Marketing Designer",
    "office": "San Francisco",
    "extension": "5384",
    "startDate": "2009/12/09",
    "salary": "Unity Butler",
    "imagelink": "http://img.timeinc.net/time/daily/2008/0811/360_mickey_mouse_1117.jpg"
  }
]

```

C:\xampp\htdocs\belongstomany\example\10\_file\_upload\mock\_svc\_ok.json

```json
{
  "id": 1,
  "name": "Tiger Nixon",
  "position": "System Architect",
  "office": "Edinburgh",
  "extension": "5421",
  "startDate": "2011/04/25",
  "salary": "Tiger Nixon",
  "imagelink": "#"
}

```

1. [Foundation support](https://belongstomany.com/example/11_foundation/example11.html)
2. ![](https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2FWIN1JPG6wgT8dq6N4tqf%2Fimage.png?alt=media\&token=efa24e6d-8ed9-4445-b3d3-b51942fc898a)
3. C:\xampp\htdocs\belongstomany\example\11\_foundation\example11.html
4. ```html
   <!DOCTYPE html>
   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #11</title>
     <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/foundation-sites@6.6.3/dist/css/foundation.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
   </head>
   <body>
     <p><br></p>
     <h1>DataTable-AltEditor - Example #11</h1>
     <h2>Foundation instead of Bootstrap</h2>
     <div class="container">
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://cdn.jsdelivr.net/npm/foundation-sites@6.6.3/dist/js/foundation.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example11.js"></script>
   </body>
   </html>

   ```

C:\xampp\htdocs\belongstomany\example\11\_foundation\example11.js

```javascript
$(document).ready(function () {
  // Enable Foundation
  $(document).foundation();
  var dataSet = [
    { id: 1, name: "Tiger Nixon", position: "System Architect", office: "Edinburgh", extension: "5421", startDate: "2011/04/25", salary: "Tiger Nixon" },
    { id: 2, name: "Garrett Winters", position: "Accountant", office: "Tokyo", extension: "8422", startDate: "2011/07/25", salary: "Garrett Winters" },
    { id: 3, name: "Ashton Cox", position: "Junior Technical Author", office: "San Francisco", extension: "1562", startDate: "2009/01/12", salary: "Ashton Cox" },
    { id: 4, name: "Cedric Kelly", position: "Senior Javascript Developer", office: "Edinburgh", extension: "6224", startDate: "2012/03/29", salary: "Cedric Kelly" },
    { id: 5, name: "Airi Satou", position: "Accountant", office: "Tokyo", extension: "5407", startDate: "2008/11/28", salary: "Airi Satou" },
    { id: 6, name: "Brielle Williamson", position: "Integration Specialist", office: "New York", extension: "4804", startDate: "2012/12/02", salary: "Brielle Williamson" },
    { id: 7, name: "Herrod Chandler", position: "Sales Assistant", office: "San Francisco", extension: "9608", startDate: "2012/08/06", salary: "Herrod Chandler" },
    { id: 8, name: "Rhona Davidson", position: "Integration Specialist", office: "Tokyo", extension: "6200", startDate: "2010/10/14", salary: "Rhona Davidson" },
    { id: 9, name: "Colleen Hurst", position: "Javascript Developer", office: "San Francisco", extension: "2360", startDate: "2009/09/15", salary: "Colleen Hurst" },
    { id: 10, name: "Sonya Frost", position: "Software Engineer", office: "Edinburgh", extension: "1667", startDate: "2008/12/13", salary: "Sonya Frost" },
    { id: 11, name: "Jena Gaines", position: "Office Manager", office: "London", extension: "3814", startDate: "2008/12/19", salary: "Jena Gaines" },
    { id: 12, name: "Quinn Flynn", position: "Support Lead", office: "Edinburgh", extension: "9497", startDate: "2013/03/03", salary: "Quinn Flynn" },
    { id: 13, name: "Charde Marshall", position: "Regional Director", office: "San Francisco", extension: "6741", startDate: "2008/10/16", salary: "Charde Marshall" },
    { id: 14, name: "Haley Kennedy", position: "Senior Marketing Designer", office: "London", extension: "3597", startDate: "2012/12/18", salary: "Haley Kennedy" },
    { id: 15, name: "Tatyana Fitzpatrick", position: "Regional Director", office: "London", extension: "1965", startDate: "2010/03/17", salary: "Tatyana Fitzpatrick" },
    { id: 16, name: "Michael Silva", position: "Marketing Designer", office: "London", extension: "1581", startDate: "2012/11/27", salary: "Michael Silva" },
    { id: 17, name: "Paul Byrd", position: "Chief Financial Officer (CFO)", office: "New York", extension: "3059", startDate: "2010/06/09", salary: "Paul Byrd" },
    { id: 18, name: "Gloria Little", position: "Systems Administrator", office: "New York", extension: "1721", startDate: "2009/04/10", salary: "Gloria Little" },
    { id: 19, name: "Bradley Greer", position: "Software Engineer", office: "London", extension: "2558", startDate: "2012/10/13", salary: "Bradley Greer" },
    { id: 20, name: "Dai Rios", position: "Personnel Lead", office: "Edinburgh", extension: "2290", startDate: "2012/09/26", salary: "Dai Rios" },
    { id: 21, name: "Jenette Caldwell", position: "Development Lead", office: "New York", extension: "1937", startDate: "2011/09/03", salary: "Jenette Caldwell" },
    { id: 22, name: "Yuri Berry", position: "Chief Marketing Officer (CMO)", office: "New York", extension: "6154", startDate: "2009/06/25", salary: "Yuri Berry" },
    { id: 23, name: "Caesar Vance", position: "Pre-Sales Support", office: "New York", extension: "8330", startDate: "2011/12/12", salary: "Caesar Vance" },
    { id: 24, name: "Doris Wilder", position: "Sales Assistant", office: "Sidney", extension: "3023", startDate: "2010/09/20", salary: "Doris Wilder" },
    { id: 25, name: "Angelica Ramos", position: "Chief Executive Officer (CEO)", office: "London", extension: "5797", startDate: "2009/10/09", salary: "Angelica Ramos" },
    { id: 26, name: "Gavin Joyce", position: "Developer", office: "Edinburgh", extension: "8822", startDate: "2010/12/22", salary: "Gavin Joyce" },
    { id: 27, name: "Jennifer Chang", position: "Regional Director", office: "Singapore", extension: "9239", startDate: "2010/11/14", salary: "Jennifer Chang" },
    { id: 28, name: "Brenden Wagner", position: "Software Engineer", office: "San Francisco", extension: "1314", startDate: "2011/06/07", salary: "Brenden Wagner" },
    { id: 29, name: "Fiona Green", position: "Chief Operating Officer (COO)", office: "San Francisco", extension: "2947", startDate: "2010/03/11", salary: "Fiona Green" },
    { id: 30, name: "Shou Itou", position: "Regional Marketing", office: "Tokyo", extension: "8899", startDate: "2011/08/14", salary: "Shou Itou" },
    { id: 30, name: "Michelle House", position: "Integration Specialist", office: "Sidney", extension: "2769", startDate: "2011/06/02", salary: "Michelle House" },
    { id: 32, name: "Suki Burks", position: "Developer", office: "London", extension: "6832", startDate: "2009/10/22", salary: "Suki Burks" },
    { id: 33, name: "Prescott Bartlett", position: "Technical Author", office: "London", extension: "3606", startDate: "2011/05/07", salary: "Prescott Bartlett" },
    { id: 34, name: "Gavin Cortez", position: "Team Leader", office: "San Francisco", extension: "2860", startDate: "2008/10/26", salary: "Gavin Cortez" },
    { id: 35, name: "Martena Mccray", position: "Post-Sales support", office: "Edinburgh", extension: "8240", startDate: "2011/03/09", salary: "Martena Mccray" },
    { id: 36, name: "Unity Butler", position: "Marketing Designer", office: "San Francisco", extension: "5384", startDate: "2009/12/09", salary: "Unity Butler" },
  ];
  var columnDefs = [{
    data: "id",
    title: "Id",
    type: "readonly"
  },
  {
    data: "name",
    title: "Name"
  },
  {
    data: "position",
    title: "Position"
  },
  {
    data: "office",
    title: "Office"
  },
  {
    data: "extension",
    title: "Extn."
  },
  {
    data: "startDate",
    title: "Start date"
  },
  {
    data: "salary",
    title: "Salary"
  }];
  var myTable;
  myTable = $('#example').DataTable({
    "sPaginationType": "full_numbers",
    data: dataSet,
    columns: columnDefs,
    dom: 'Bfrtip',        // Needs button container
    select: 'single',
    responsive: true,
    altEditor: true,     // Enable altEditor
    buttons: [{
      text: 'Add',
      name: 'add'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Edit',
      name: 'edit'        // do not change name
    },
    {
      extend: 'selected', // Bind to Selected row
      text: 'Delete',
      name: 'delete'      // do not change name
    }]
  });
});

```

1. [Edit on click,delete inline](https://belongstomany.com/example/12_inline_buttons/example12.html)
2.

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2Fnjkoz4hcg9UzRRTWRniR%2Fimage.png?alt=media&#x26;token=97807cc1-000f-4f06-a028-9906989b2904" alt=""><figcaption></figcaption></figure>
```

```
<figure><img src="https://2726517656-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-M1E4Gk2ppVKb4olmnun%2Fuploads%2Fz7tB3RylQ19X1quiknxT%2Fimage.png?alt=media&#x26;token=1c809c79-61f8-4599-a774-4be87c337108" alt=""><figcaption></figcaption></figure>
```

3\. C:\xampp\htdocs\belongstomany\example\12\_inline\_buttons\example12.html
4\.
5. \`\`\`html

   <!DOCTYPE html>

   <html lang="en">
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge">
     <meta name="viewport" content="width=device-width, initial-scale=1">
     <title>DataTable-AltEditor - Example #12</title>
     <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/buttons/1.6.2/css/buttons.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/select/1.3.1/css/select.dataTables.css" />
     <link rel="stylesheet" href="https://cdn.datatables.net/responsive/2.2.5/css/responsive.dataTables.css" />
     <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.css" />
   </head>
   <body>
     <div class="container">
       <h1>DataTable-AltEditor - Example #12</h1>
       <h2>Edit on click, delete inline</h2>
     </div>
     <div class="container">
       <button class="btn btn-primary" id="addbutton" title="Add"><span class="fa fa-plus-square"></span></button>
       <table cellpadding="0" cellspacing="0" border="0" class="dataTable table table-striped" id="example">
       </table>
     </div>
     <script src="https://code.jquery.com/jquery-3.0.0.js"></script>
     <script src="https://code.jquery.com/jquery-migrate-3.3.0.js"></script>
     <script src="https://cdn.datatables.net/1.10.21/js/jquery.dataTables.js"></script>
     <script src="https://cdn.datatables.net/buttons/1.6.2/js/dataTables.buttons.js"></script>
     <script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.js"></script>
     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.js"></script>
     <script src="https://cdn.datatables.net/responsive/2.2.5/js/dataTables.responsive.js"></script>
     <script src="../../src/dataTables.altEditor.free.js"></script>
     <script src="./example12.js"></script>
   </body>
   </html>

````

C:\xampp\htdocs\belongstomany\example\12\_inline\_buttons\example12.js

```javascript
$(document).ready(function () {
var dataSet = [
 { id: 1, name: "Tiger Nixon", position: "System Architect", office: "Edinburgh", extension: "5421", startDate: "2011/04/25", salary: "Tiger Nixon" },
 { id: 2, name: "Garrett Winters", position: "Accountant", office: "Tokyo", extension: "8422", startDate: "2011/07/25", salary: "Garrett Winters" },
 { id: 3, name: "Ashton Cox", position: "Junior Technical Author", office: "San Francisco", extension: "1562", startDate: "2009/01/12", salary: "Ashton Cox" },
 { id: 4, name: "Cedric Kelly", position: "Senior Javascript Developer", office: "Edinburgh", extension: "6224", startDate: "2012/03/29", salary: "Cedric Kelly" },
 { id: 5, name: "Airi Satou", position: "Accountant", office: "Tokyo", extension: "5407", startDate: "2008/11/28", salary: "Airi Satou" },
 { id: 6, name: "Brielle Williamson", position: "Integration Specialist", office: "New York", extension: "4804", startDate: "2012/12/02", salary: "Brielle Williamson" },
 { id: 7, name: "Herrod Chandler", position: "Sales Assistant", office: "San Francisco", extension: "9608", startDate: "2012/08/06", salary: "Herrod Chandler" },
 { id: 8, name: "Rhona Davidson", position: "Integration Specialist", office: "Tokyo", extension: "6200", startDate: "2010/10/14", salary: "Rhona Davidson" },
 { id: 9, name: "Colleen Hurst", position: "Javascript Developer", office: "San Francisco", extension: "2360", startDate: "2009/09/15", salary: "Colleen Hurst" },
 { id: 10, name: "Sonya Frost", position: "Software Engineer", office: "Edinburgh", extension: "1667", startDate: "2008/12/13", salary: "Sonya Frost" },
 { id: 11, name: "Jena Gaines", position: "Office Manager", office: "London", extension: "3814", startDate: "2008/12/19", salary: "Jena Gaines" },
 { id: 12, name: "Quinn Flynn", position: "Support Lead", office: "Edinburgh", extension: "9497", startDate: "2013/03/03", salary: "Quinn Flynn" },
 { id: 13, name: "Charde Marshall", position: "Regional Director", office: "San Francisco", extension: "6741", startDate: "2008/10/16", salary: "Charde Marshall" },
 { id: 14, name: "Haley Kennedy", position: "Senior Marketing Designer", office: "London", extension: "3597", startDate: "2012/12/18", salary: "Haley Kennedy" },
 { id: 15, name: "Tatyana Fitzpatrick", position: "Regional Director", office: "London", extension: "1965", startDate: "2010/03/17", salary: "Tatyana Fitzpatrick" },
 { id: 16, name: "Michael Silva", position: "Marketing Designer", office: "London", extension: "1581", startDate: "2012/11/27", salary: "Michael Silva" },
 { id: 17, name: "Paul Byrd", position: "Chief Financial Officer (CFO)", office: "New York", extension: "3059", startDate: "2010/06/09", salary: "Paul Byrd" },
 { id: 18, name: "Gloria Little", position: "Systems Administrator", office: "New York", extension: "1721", startDate: "2009/04/10", salary: "Gloria Little" },
 { id: 19, name: "Bradley Greer", position: "Software Engineer", office: "London", extension: "2558", startDate: "2012/10/13", salary: "Bradley Greer" },
 { id: 20, name: "Dai Rios", position: "Personnel Lead", office: "Edinburgh", extension: "2290", startDate: "2012/09/26", salary: "Dai Rios" },
 { id: 21, name: "Jenette Caldwell", position: "Development Lead", office: "New York", extension: "1937", startDate: "2011/09/03", salary: "Jenette Caldwell" },
 { id: 22, name: "Yuri Berry", position: "Chief Marketing Officer (CMO)", office: "New York", extension: "6154", startDate: "2009/06/25", salary: "Yuri Berry" },
 { id: 23, name: "Caesar Vance", position: "Pre-Sales Support", office: "New York", extension: "8330", startDate: "2011/12/12", salary: "Caesar Vance" },
 { id: 24, name: "Doris Wilder", position: "Sales Assistant", office: "Sidney", extension: "3023", startDate: "2010/09/20", salary: "Doris Wilder" },
 { id: 25, name: "Angelica Ramos", position: "Chief Executive Officer (CEO)", office: "London", extension: "5797", startDate: "2009/10/09", salary: "Angelica Ramos" },
 { id: 26, name: "Gavin Joyce", position: "Developer", office: "Edinburgh", extension: "8822", startDate: "2010/12/22", salary: "Gavin Joyce" },
 { id: 27, name: "Jennifer Chang", position: "Regional Director", office: "Singapore", extension: "9239", startDate: "2010/11/14", salary: "Jennifer Chang" },
 { id: 28, name: "Brenden Wagner", position: "Software Engineer", office: "San Francisco", extension: "1314", startDate: "2011/06/07", salary: "Brenden Wagner" },
 { id: 29, name: "Fiona Green", position: "Chief Operating Officer (COO)", office: "San Francisco", extension: "2947", startDate: "2010/03/11", salary: "Fiona Green" },
 { id: 30, name: "Shou Itou", position: "Regional Marketing", office: "Tokyo", extension: "8899", startDate: "2011/08/14", salary: "Shou Itou" },
 { id: 30, name: "Michelle House", position: "Integration Specialist", office: "Sidney", extension: "2769", startDate: "2011/06/02", salary: "Michelle House" },
 { id: 32, name: "Suki Burks", position: "Developer", office: "London", extension: "6832", startDate: "2009/10/22", salary: "Suki Burks" },
 { id: 33, name: "Prescott Bartlett", position: "Technical Author", office: "London", extension: "3606", startDate: "2011/05/07", salary: "Prescott Bartlett" },
 { id: 34, name: "Gavin Cortez", position: "Team Leader", office: "San Francisco", extension: "2860", startDate: "2008/10/26", salary: "Gavin Cortez" },
 { id: 35, name: "Martena Mccray", position: "Post-Sales support", office: "Edinburgh", extension: "8240", startDate: "2011/03/09", salary: "Martena Mccray" },
 { id: 36, name: "Unity Butler", position: "Marketing Designer", office: "San Francisco", extension: "5384", startDate: "2009/12/09", salary: "Unity Butler" },
];
var columnDefs = [{
 data: "id",
 title: "Id",
 type: "readonly"
},
{
 data: "name",
 title: "Name"
},
{
 data: "position",
 title: "Position"
},
{
 data: "office",
 title: "Office"
},
{
 data: "extension",
 title: "Extn."
},
{
 data: "startDate",
 title: "Start date"
},
{
 data: "salary",
 title: "Salary"
},
{
 data: null,
 title: "Actions",
 name: "Actions",
 render: function (data, type, row, meta) {
   return '<a class="delbutton fa fa-minus-square btn btn-danger" href="#"></a>';
 },
 disabled: true
}
];
var myTable;
myTable = $('#example').DataTable({
 "sPaginationType": "full_numbers",
 data: dataSet,
 columns: columnDefs,
 dom: 'Bfrtip',        // Needs button container
 select: {
   style: 'single',
   toggleable: false
 },
 responsive: true,
 altEditor: true,     // Enable altEditor
 buttons: []          // no buttons, however this seems compulsory
});
// Edit
$(document).on('click', "[id^='example'] tbody ", 'tr', function () {
 var tableID = $(this).closest('table').attr('id');    // id of the table
 var that = $('#' + tableID)[0].altEditor;
 that._openEditModal();
 $('#altEditor-edit-form-' + that.random_id)
   .off('submit')
   .on('submit', function (e) {
     e.preventDefault();
     e.stopPropagation();
     that._editRowData();
   });
});
// Delete
$(document).on('click', "[id^='example'] .delbutton", 'tr', function (x) {
 var tableID = $(this).closest('table').attr('id');    // id of the table
 var that = $('#' + tableID)[0].altEditor;
 that._openDeleteModal();
 $('#altEditor-delete-form-' + that.random_id)
   .off('submit')
   .on('submit', function (e) {
     e.preventDefault();
     e.stopPropagation();
     that._deleteRow();
   });
 x.stopPropagation(); //avoid open "Edit" dialog
});
// Add row
$('#addbutton').on('click', function () {
 var that = $('#example')[0].altEditor;
 that._openAddModal();
 $('#altEditor-add-form-' + that.random_id)
   .off('submit')
   .on('submit', function (e) {
     e.preventDefault();
     e.stopPropagation();
     that._addRowData();
   });
});
});

````

C:\xampp\htdocs\belongstomany\src\dataTables.altEditor.free.js

```javascript
/**
 * @summary altEditor
 * @description Lightweight editor for DataTables
 * @version 2.0
 * @file dataTables.editor.free.js
 * @author kingkode (www.kingkode.com)
 *  Modified by: Kasper Olesen (https://github.com/KasperOlesen), Luca Vercelli (https://github.com/luca-vercelli), Zack Hable (www.cobaltdevteam.com)
 * @contact www.kingkode.com/contact
 * @contact zack@cobaltdevteam.com
 * @copyright Copyright 2016 Kingkode
 *
 * This source file is free software, available under the following license: MIT
 * license
 *
 * This source file is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
 *
 *
 */
(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD
    define(['jquery', 'datatables.net'], function ($) {
      return factory($, window, document);
    });
  }
  else if (typeof exports === 'object') {
    // CommonJS
    module.exports = function (root, $) {
      if (!root) {
        root = window;
      }
      if (!$ || !$.fn.dataTable) {
        $ = require('datatables.net')(root, $).$;
      }
      return factory($, root, root.document);
    };
  }
  else {
    // Browser
    factory(jQuery, window, document);
  }
})
  (function ($, window, document, undefined) {
    'use strict';
    var DataTable = $.fn.dataTable;
    var _instance = 0;
    /**
     * altEditor provides modal editing of records for Datatables
     *
     * @class altEditor
     * @constructor
     * @param {object}
     *            oTD DataTables settings object
     * @param {object}
     *            oConfig Configuration object for altEditor
     */
    var altEditor = function (dt, opts) {
      if (!DataTable.versionCheck || !DataTable.versionCheck('1.10.8')) {
        throw ("Warning: altEditor requires DataTables 1.10.8 or greater");
      }
      // User and defaults configuration object
      this.c = $.extend(true, {}, DataTable.defaults.altEditor,
        altEditor.defaults, opts);
      /**
       * @namespace Settings object which contains customisable information
       *            for altEditor instance
       */
      this.s = {
        /** @type {DataTable.Api} DataTables' API instance */
        dt: new DataTable.Api(dt),
        /** @type {String} Unique namespace for events attached to the document */
        namespace: '.altEditor' + (_instance++)
      };
      /**
       * @namespace Common and useful DOM elements for the class instance
       */
      this.dom = {
        /** @type {jQuery} altEditor handle */
        modal: $('<div class="dt-altEditor-handle"/>'),
      };
      /* Constructor logic */
      this._constructor();
    }
    $.extend(
      altEditor.prototype,
      {
        /***************************************************************
         * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Constructor * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         */
        /**
         * Initialise the RowReorder instance
         *
         * @private
         */
        _constructor: function () {
          var that = this;
          var dt = this.s.dt;
          if (dt.settings()[0].oInit.onAddRow)
            that.onAddRow = dt.settings()[0].oInit.onAddRow;
          if (dt.settings()[0].oInit.onDeleteRow)
            that.onDeleteRow = dt.settings()[0].oInit.onDeleteRow;
          if (dt.settings()[0].oInit.onEditRow)
            that.onEditRow = dt.settings()[0].oInit.onEditRow;
          that.closeModalOnSuccess = dt.settings()[0].oInit.closeModalOnSuccess;
          if (that.closeModalOnSuccess === undefined) {
            that.closeModalOnSuccess = true;
          }
          that.encodeFiles = dt.settings()[0].oInit.encodeFiles;
          if (that.encodeFiles === undefined) {
            that.encodeFiles = true;
          }
          // Register datatable selection listener
          this.selectionListener()
          var lang = this.s.dt.settings()[0].oLanguage;
          if (lang.altEditor) {
            this.language = lang.altEditor;
            this._setup();
          }
          // Load from URL
          else if (typeof lang.altEditorUrl === 'string' && lang.altEditorUrl != '') {
            $.ajax({
              dataType: 'json',
              url: lang.altEditorUrl,
              success: function (json) {
                that.language = json;
                that._setup();
              },
              error: function () {
                // Error occurred loading language file, continue on as best we can
                that.language = {};
                that._setup();
              }
            });
          }
          // Default
          else {
            this.language = {};
            this._setup();
          }
          dt.on('destroy.altEditor', function () {
            dt.off('.altEditor');
            $(dt.table().body()).off(that.s.namespace);
            $(document.body).off(that.s.namespace);
          });
        },
        /***************************************************************
         * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         * Private methods * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
         */
        /**
         * Setup dom and bind button actions
         *
         * @private
         */
        _setup: function () {
          var that = this;
          var dt = this.s.dt;
          this.random_id = ("" + Math.random()).replace(".", "");
          var modal_id = 'altEditor-modal-' + this.random_id;
          this.modal_selector = '#' + modal_id;
          this._initLanguage();
          var modal = '<div class="modal fade altEditor-modal reveal" id="' + modal_id + '" tabindex="-1" role="dialog" data-reveal>' +
            '<div class="modal-dialog">' +
            '<div class="modal-content">' +
            '<div class="modal-header">' +
            '<h4 style="padding-top: 1rem;padding-left: 1rem;" class="modal-title"></h4>' +
            '<button style="margin: initial;" type="button" class="close close-button" data-dismiss="modal" data-close aria-label="' + this.language.modalClose + '">' +
            '<span aria-hidden="true">&times;</span></button>' +
            '</div>' +
            '<div class="modal-body">' +
            '<p></p>' +
            '</div>' +
            '<div class="modal-footer">' +
            '</div>' +
            '</div>' +
            '</div>' +
            '</div>';
          // Add modal
          $('body').append(modal);
          // Add Edit Button
          if (dt.button('edit:name')) {
            dt.button('edit:name').action(function (e, dt, node, config) {
              that._openEditModal();
              $('#altEditor-edit-form-' + that.random_id)
                .off('submit')
                .on('submit', function (e) {
                  e.preventDefault();
                  e.stopPropagation();
                  that._editRowData();
                });
            });
          }
          // Add Delete Button
          if (dt.button('delete:name')) {
            dt.button('delete:name').action(function (e, dt, node, config) {
              that._openDeleteModal();
              $('#altEditor-delete-form-' + that.random_id)
                .off('submit')
                .on('submit', function (e) {
                  e.preventDefault();
                  e.stopPropagation();
                  that._deleteRow();
                });
            });
          }
          // Add Add Button
          if (dt.button('add:name')) {
            dt.button('add:name').action(function (e, dt, node, config) {
              that._openAddModal();
              $('#altEditor-add-form-' + that.random_id)
                .off('submit')
                .on('submit', function (e) {
                  e.preventDefault();
                  e.stopPropagation();
                  that._addRowData();
                });
            });
          }
          // Bind 'unique' error messages
          $(this.modal_selector).on('input', '[data-unique]', function (elm) {
            if ($(elm.target).attr('data-unique') == null || $(elm.target).attr('data-unique') === 'false') {
              return;
            }
            var target = $(elm.target);
            var colData = dt.column("th:contains('" + target.attr("name") + "')").data();
            // go through each item in this column
            var selectedCellData = null;
            if (dt.row({ selected: true }).index() != null)
              selectedCellData = dt.cell(dt.row({ selected: true }).index(), dt.column("th:contains('" + target.attr("name") + "')").index()).data();
            elm.target.setCustomValidity('');
            for (var j in colData) {
              // if the element is in the column and its not the selected one then its not unique
              if (target.val() == colData[j] && colData[j] != selectedCellData) {
                elm.target.setCustomValidity(that.language.error.unique);
              }
            }
          });
          // Add Refresh button
          if (this.s.dt.button('refresh:name')) {
            this.s.dt.button('refresh:name').action(function (e, dt, node, config) {
              if (dt.ajax && dt.ajax.url()) {
                dt.ajax.reload();
              }
            });
          }
        },
        /**
         * Init translate
         *
         * @private
         */
        _initLanguage: function () {
          this.language.modalClose = this.language.modalClose || 'Close';
          this.language.edit = this.language.edit || {};
          this.language.edit = {
            title: this.language.edit.title || 'Edit record',
            button: this.language.edit.button || 'Edit'
          };
          this.language.delete = this.language.delete || {};
          this.language.delete = {
            title: this.language.delete.title || 'Delete record',
            button: this.language.delete.button || 'Delete'
          };
          this.language.add = this.language.add || {};
          this.language.add = {
            title: this.language.add.title || 'Add record',
            button: this.language.add.button || 'Add'
          };
          this.language.success = this.language.success || 'Success!';
          this.language.error = this.language.error || {};
          this.language.error = {
            message: this.language.error.message || 'There was an unknown error!',
            label: this.language.error.label || 'Error!',
            responseCode: this.language.error.responseCode || 'Response code: ',
            required: this.language.error.required || 'Field is required',
            unique: this.language.error.unique || 'Duplicated field'
          };
        },
        /**
         * Emit an event on the DataTable for listeners
         *
         * @param {string}
         *            name Event name
         * @param {array}
         *            args Event arguments
         * @private
         */
        _emitEvent: function (name, args) {
          this.s.dt.iterator('table', function (ctx, i) {
            $(ctx.nTable).triggerHandler(name + '.dt', args);
          });
        },
        /**
         * Open Edit Modal for selected row
         *
         * @private
         */
        _openEditModal: function () {
          var dt = this.s.dt;
          var adata = dt.rows({
            selected: true
          });
          var columnDefs = this.completeColumnDefs();
          var data = this.createDialog(columnDefs, this.language.edit.title, this.language.edit.button,
            this.language.modalClose, 'editRowBtn', 'altEditor-edit-form');
          var selector = this.modal_selector;
          for (var j in columnDefs) {
            if (columnDefs[j].name != null) {
              var jquerySelector = "#" + columnDefs[j].name.toString().replace(/\./g, "\\.");
              var arrIndex = columnDefs[j].name.toString().split(".");
              var selectedValue = adata.data()[0];
              for (var index = 0; index < arrIndex.length; index++) {
                if (selectedValue) {
                  selectedValue = selectedValue[arrIndex[index]];
                }
              }
              if (typeof selectedValue !== 'object' && selectedValue !== null) {
                selectedValue = selectedValue.toString().trim();
              }
              // Added Select2
              if (columnDefs[j].type.indexOf("select") >= 0 && columnDefs[j].select2) {
                var jsonValue = undefined;
                try { jsonValue = JSON.parse(selectedValue); } catch (e) { }
                if (typeof jsonValue === 'object') { selectedValue = jsonValue; }
              }
              // Added checkbox
              else if (columnDefs[j].type.indexOf("checkbox") >= 0) {
                if (this._quoteattr(selectedValue) === "true" || this._quoteattr(selectedValue) == "1") { // MS SQL Databases use bits for booleans. 1 is equivlent to true, 0 is false
                  $(selector).find(jquerySelector).prop("checked", this._quoteattr(selectedValue)); // required by checkbox
                }
              }
              // Added date
              else if (columnDefs[j].type.indexOf("date") >= 0) {
                if (columnDefs[j].dateFormat !== "") {
                  var mDate = moment(this._quoteattr(selectedValue));
                  if (mDate && mDate.isValid()) {
                    $(selector).find(jquerySelector).val(mDate.format(columnDefs[j].dateFormat));
                  }
                }
              }
              $(selector).find(jquerySelector)
                .filter(':input[type!="file"]').val(selectedValue) // this._quoteattr or not? see #121
                .trigger("change"); // required by select2
            }
          }
          $(selector + ' input[0]').trigger('focus');
          $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:edit_dialog_opened");
        },
        /**
         * Callback for "Edit" button
         */
        _editRowData: function () {
          var that = this;
          var dt = this.s.dt;
          var adata = dt.rows({
            selected: true
          });
          var rowDataArray = {}; // Complete new row data
          var originalRowDataArray = adata.data()[0]; // Original row data
          var $inputs = $('form[name="altEditor-edit-form-' + this.random_id + '"]').find('select, textarea, input');
          // Getting the inputs from the edit-modal
          $inputs.filter(':input[type!="file"], :input[type="checkbox"]').each(function (i) {
            rowDataArray[$(this).attr('id')] = $(this).val();
          });
          //Getting Files from the modal
          var numFilesQueued = 0;
          $inputs.filter(':input[type="file"]').each(function (i) {
            if ($(this).prop('files')[0]) {
              var context = this;
              if (that.encodeFiles) {
                ++numFilesQueued;
                that.getBase64($(this).prop('files')[0], function (filecontent) {
                  rowDataArray[$(context).attr('id')] = filecontent;
                  --numFilesQueued;
                });
              } else {
                rowDataArray[$(this).attr('id')] = $(this).prop('files')[0];
              }
            }
          });
          // Getting the checkbox from the modal
          $inputs.filter(':input[type="checkbox"]').each(function (i) {
            rowDataArray[$(this).attr('id')] = this.checked;
          });
          var checkFilesQueued = function () {
            if (numFilesQueued == 0) {
              that.onEditRow(that,
                rowDataArray,
                function (data, b, c, d, e) { that._editRowCallback(data, b, c, d, e); },
                function (data) { that._errorCallback(data); },
                originalRowDataArray);
            } else {
              console.log("Waiting for file base64-decoding...");
              setTimeout(checkFilesQueued, 1000);
            }
          };
          checkFilesQueued();
        },
        /**
         * Open Delete Modal for selected row
         *
         * @private
         */
        _openDeleteModal: function () {
          var that = this;
          var dt = this.s.dt;
          var adata = dt.rows({
            selected: true
          });
          var formName = 'altEditor-delete-form-' + this.random_id;
          var selector = this.modal_selector;
          var fill = function () {
            var btns = '<button type="button" data-content="remove" class="btn btn-default button secondary" data-close data-dismiss="modal">' + that.language.modalClose + '</button>' +
              '<button type="submit"  data-content="remove" class="btn btn-danger button" id="deleteRowBtn">' + that.language.delete.button + '</button>';
            $(selector).find('.modal-title').html(that.language.delete.title);
            $(selector).find('.modal-body').html(that.language.deleteMessage || `<h5>Are you sure you wish to delete ${adata.count()} rows?</h5>`);
            $(selector).find('.modal-footer').html(btns);
            var modalContent = $(selector).find('.modal-content');
            if (modalContent.parent().is('form')) {
              modalContent.parent().attr('name', formName);
              modalContent.parent().attr('id', formName);
            }
            else {
              modalContent.wrap("<form name='" + formName + "' id='" + formName + "' role='form'></form>");
            }
          };
          this.internalOpenDialog(selector, fill);
          $(selector + ' input[0]').trigger('focus');
          $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:delete_dialog_opened");
        },
        /**
         * Callback for "Delete" button
         */
        _deleteRow: function () {
          var that = this;
          var dt = this.s.dt;
          var adata = dt.rows({
            selected: true
          }).data().toArray();
          that.onDeleteRow(that,
            adata,
            function (data) { that._deleteRowCallback(data); },
            function (data) { that._errorCallback(data); }
          );
        },
        /**
         * Open Add Modal for selected row
         *
         * @private
         */
        _openAddModal: function () {
          var dt = this.s.dt;
          var columnDefs = this.completeColumnDefs();
          var data = this.createDialog(columnDefs, this.language.add.title, this.language.add.button,
            this.language.modalClose, 'addRowBtn', 'altEditor-add-form');
          var selector = this.modal_selector;
          $(selector + ' input[0]').trigger('focus');
          $(selector).trigger("alteditor:some_dialog_opened").trigger("alteditor:add_dialog_opened");
        },
        selectionListener: function () {
          var _dt = this.s.dt
          _dt.on('select', function (e, dt, type, indexes) {
            // when multiple rows selected then disable edit button
            if (_dt.rows({ selected: true }).count() > 1) {
              _dt.buttons('edit:name').disable()
            }
          })
          _dt.on('deselect', function (e, dt, type, indexes) {
            // when multiple rows selected then disable edit button
            if (_dt.rows({ selected: true }).count() > 1) {
              _dt.buttons('edit:name').disable()
            }
          })
        },
        /**
        * Complete DataTable.context[0].aoColumns with default values
        */
        completeColumnDefs: function () {
          var columnDefs = [];
          var dt = this.s.dt;
          for (var i in dt.context[0].aoColumns) {
            var obj = dt.context[0].aoColumns[i];
            columnDefs[i] = {
              title: obj.sTitle,
              placeholder: (obj.placeholder ? obj.placeholder : obj.title), //added placeholder
              name: (obj.data ? obj.data : obj.mData),
              type: (obj.type ? obj.type : 'text'),
              rows: (obj.rows ? obj.rows : '5'),
              cols: (obj.cols ? obj.cols : '30'),
              options: (obj.options ? obj.options : []),
              readonly: (obj.readonly ? obj.readonly : false),
              disabled: (obj.disabled ? obj.disabled : false),
              required: (obj.required ? obj.required : false),
              hoverMsg: (obj.hoverMsg ? obj.hoverMsg : ''),
              pattern: (obj.pattern ? obj.pattern : '.*'),
              accept: (obj.accept ? obj.accept : ''),
              special: (obj.special ? obj.special : ''),
              unique: (obj.unique ? obj.unique : false),
              maxLength: (obj.maxLength ? obj.maxLength : false),
              multiple: (obj.multiple ? obj.multiple : false),
              select2: (obj.select2 ? obj.select2 : false),
              datepicker: (obj.datepicker ? obj.datepicker : false),
              datetimepicker: (obj.datetimepicker ? obj.datetimepicker : false),
              editorOnChange: (obj.editorOnChange ? obj.editorOnChange : null),
              style: (obj.style ? obj.style : ''),
              dateFormat: (obj.dateFormat ? obj.dateFormat : ''),
              optionsSortByLabel: (obj.optionsSortByLabel ? obj.optionsSortByLabel : false),
              inline: (obj.inline ? obj.inline : false), // Added for inline columns
              step: (obj.step ? obj.step : null), // Number fields
              min: (obj.min ? obj.min : null), // Number fields
              max: (obj.max ? obj.max : null), // Number fields
              value: (obj.value ? obj.value : '') // Allow a default value
            }
          }
          return columnDefs;
        },
        /**
        * Create both Edit and Add dialogs
        * @param columnDefs as returned by completeColumnDefs()
        */
        createDialog: function (columnDefs, modalTitle, buttonCaption, closeCaption, buttonClass, formName) {
          formName = [formName, this.random_id].join('-');
          var that = this,
            data = "",
            count = 0;
          var fillAttrs = function (obj, attrs) {
            var attrsStr = '';
            for (var i in attrs) {
              var attr = attrs[i];
              if (!obj[attr]) continue;
              attrsStr += " " + attr + "='" + that._quoteattr(obj[attr]) + "'";
            }
            return attrsStr + " ";
          };
          for (var j in columnDefs) {
            var title = columnDefs[j].title.replace(/(<([^>]+)>)/gi, "").trim();
            //handle hidden fields
            if (columnDefs[j].type.indexOf("hidden") >= 0) {
              data += "<input type='hidden' "
                + "id='" + this._quoteattr(columnDefs[j].name) + "' "
                + fillAttrs(columnDefs[j], ['name', 'value'])
                + "></input>";
            }
            else {
              // handle fields that are visible to the user
              if (columnDefs[j].inline) { //to add upto 4 inline columns
                if (count == 0) {
                  count++;
                  data += "<div style='margin-left: initial;margin-right: initial;' class='form-group row' id='alteditor-row-" + this._quoteattr(columnDefs[j].name) + "'>";
                  data += "<div class='col-sm-3 col-md-3 col-lg-3 text-right' style='padding-top:4px;'>";
                  data += "<label for='" + this._quoteattr(columnDefs[j].name) + "'>" + title + ":</label></div>";
                  data += "<div class='col-sm-2 col-md-2 col-lg-2'>";
                }
                else {
                  data += "<div class='col-sm-2 col-md-2 col-lg-2'>";
                }
              }
              else {
                data += "<div style='margin-left: initial;margin-right: initial;' class='form-group row' id='alteditor-row-" + this._quoteattr(columnDefs[j].name) + "'>";
                data += "<div class='col-sm-3 col-md-3 col-lg-3 text-right' style='padding-top:4px;'>";
                data += "<label for='" + this._quoteattr(columnDefs[j].name) + "'>" + title + ":</label></div>";
                data += "<div class='col-sm-8 col-md-8 col-lg-8'>";
              }
              // Adding select-fields
              if (columnDefs[j].type.indexOf("select") >= 0) {
                var options = "",
                  optionsArray = columnDefs[j].options;
                if (optionsArray.length > 0) {
                  // array-style select or select2
                  for (var i = 0; i < optionsArray.length; i++) {
                    options += "<option value='" + this._quoteattr(optionsArray[i])
                      + "'>" + optionsArray[i] + "</option>";
                  }
                } else {
                  // object-style select or select2
                  for (var x in optionsArray) {
                    options += "<option value='" + this._quoteattr(x) + "' >"
                      + optionsArray[x] + "</option>";
                  }
                }
                data += "<select class='form-control" + (columnDefs[j].select2 ? ' select2' : '') + "' "
                  + fillAttrs(columnDefs[j], ['name', 'style', 'readonly', 'disabled', 'required', 'multiple'])
                  + "id='" + this._quoteattr(columnDefs[j].name) + "' "
                  + "placeholder='" + this._quoteattr(columnDefs[j].placeholder ? columnDefs[j].placeholder : title) + "' "
                  + "data-special='" + this._quoteattr(columnDefs[j].special) + "' "
                  + "data-unique='" + columnDefs[j].unique + "' "
                  + ">" + options
                  + "</select>";
              }
              // Adding Text Area
              else if (columnDefs[j].type.indexOf("textarea") >= 0) {
                data += "<textarea class='form-control' "
                  + "id='" + this._quoteattr(columnDefs[j].name) + "' "
                  + fillAttrs(columnDefs[j], ['name', 'style', 'rows', 'cols', 'maxLength', 'readonly', 'disabled', 'required'])
                  + "placeholder='" + this._quoteattr(columnDefs[j].placeholder ? columnDefs[j].placeholder : title) + "' "
                  + "data-special='" + this._quoteattr(columnDefs[j].special) + "' "
                  + "data-unique='" + columnDefs[j].unique + "'>"
                  + (columnDefs[j].value ? columnDefs[j].value : '')
                  + "</textarea>";
              }
              // Adding text-inputs and error labels, but also new HTML5 types (email, color, ...)
              else {
                data += "<input class='form-control' "
                  + fillAttrs(columnDefs[j], ['type', 'pattern', 'accept', 'name', 'step', 'min', 'max', 'maxLength', 'value', 'readonly', 'disabled', 'required'])
                  + /* ???? */ (columnDefs[j].type.indexOf("readonly") >= 0 ? "readonly " : "")
                  + "id='" + this._quoteattr(columnDefs[j].name) + "' "
                  + "title='" + this._quoteattr(columnDefs[j].hoverMsg) + "' "
                  + "placeholder='" + this._quoteattr(columnDefs[j].placeholder ? columnDefs[j].placeholder : title) + "' "
                  + "data-special='" + this._quoteattr(columnDefs[j].special) + "' "
                  + "data-unique='" + columnDefs[j].unique + "' "
                  + "style='overflow: hidden; " + this._quoteattr(columnDefs[j].style) + "' "
                  + "class='form-control form-control-sm'>";
              }
              data += "<label id='" + this._quoteattr(columnDefs[j].name) + "-label"
                + "' class='errorLabel'></label>";
              if (!columnDefs[j].inline || (+j + 1 < columnDefs.length && !columnDefs[+j + 1].inline)) {
                data += "</div><div style='clear:both;'></div></div>";
              }
              else {
                data += "</div>";
              }
            }
          }
          // data += "</form>";
          var selector = this.modal_selector;
          var fill = function () {
            var btns = '<button type="button" data-content="remove" class="btn btn-default button secondary" data-dismiss="modal" data-close>' + closeCaption + '</button>'
              + '<button type="submit" form="' + formName + '" data-content="remove" class="btn btn-primary button" id="' + buttonClass + '">' + buttonCaption + '</button>';
            $(selector).find('.modal-title').html(modalTitle);
            $(selector).find('.modal-body').html(data);
            $(selector).find('.modal-footer').html(btns);
            var modalContent = $(selector).find('.modal-content');
            if (modalContent.parent().is('form')) {
              modalContent.parent().attr('name', formName);
              modalContent.parent().attr('id', formName);
            }
            else {
              modalContent.wrap("<form name='" + formName + "' id='" + formName + "' role='form'></form>");
            }
          };
          this.internalOpenDialog(selector, fill);
          $(selector + ' input[0]').trigger('focus');
          var that = this;
          // enable select 2 items, datepicker, datetimepickerm
          for (var j in columnDefs) {
            if (columnDefs[j].select2) {
              // Require select2 plugin
              $(selector).find("select#" + columnDefs[j].name).select2(columnDefs[j].select2);
            }
            else if (columnDefs[j].datepicker) {
              // Require jquery-ui
              $(selector).find("#" + columnDefs[j].name).datepicker(columnDefs[j].datepicker);
            }
            else if (columnDefs[j].datetimepicker) {
              // Require datetimepicker plugin
              $(selector).find("#" + columnDefs[j].name).datetimepicker(columnDefs[j].datetimepicker);
            }
            // custom onchange triggers
            if (columnDefs[j].editorOnChange) {
              // $.escapeSelector requires jQuery 3.x
              $(selector).find("#" + $.escapeSelector(columnDefs[j].name)).attr('alt-editor-id', this._quoteattr(j));
              $(selector).find("#" + $.escapeSelector(columnDefs[j].name)).on('change', function (elm) {
                var f = columnDefs[$(this).attr('alt-editor-id')].editorOnChange;
                f(elm, that);
              });
            }
            //added select sort
            if (columnDefs[j].type.indexOf("select") >= 0) {
              if (columnDefs[j].optionsSortByLabel) {
                var jquerySelector = "#" + columnDefs[j].name.toString().replace(/\./g, "\\.");
                var opts_list = $(selector).find(jquerySelector).find('option');
                opts_list.sort(function (a, b) { return $(a).text() > $(b).text() ? 1 : -1; });
                $(selector).find(jquerySelector).html('').append(opts_list);
                $(selector).find(jquerySelector).val($(jquerySelector + " option:first").val());
              }
            }
          }
        },
        /**
         * Callback for "Add" button
         */
        _addRowData: function () {
          var that = this;
          var rowDataArray = {};
          var $inputs = $('form[name="altEditor-add-form-' + this.random_id + '"]').find('select, textarea, input');
          // Getting the inputs from the edit-modal
          $inputs.filter(':input[type!="file"], :input[type="checkbox"]').each(function (i) {
            rowDataArray[$(this).attr('id')] = $(this).val();
          });
          //Getting Files from the modal
          var numFilesQueued = 0;
          $inputs.filter(':input[type="file"]').each(function (i) {
            var context = this;
            if ($(this).prop('files')[0]) {
              if (that.encodeFiles) {
                ++numFilesQueued;
                that.getBase64($(this).prop('files')[0], function (filecontent) {
                  rowDataArray[$(context).attr('id')] = filecontent;
                  --numFilesQueued;
                });
              } else {
                rowDataArray[$(this).attr('id')] = $(this).prop('files')[0];
              }
            }
          });
          // Getting the checkbox from the modal
          $inputs.filter(':input[type="checkbox"]').each(function (i) {
            rowDataArray[$(this).attr('id')] = this.checked;
          });
          var checkFilesQueued = function () {
            if (numFilesQueued == 0) {
              that.onAddRow(that,
                rowDataArray,
                function (data) { that._addRowCallback(data); },
                function (data) {
                  that._errorCallback(data);
                });
            } else {
              console.log("Waiting for file base64-decoding...");
              setTimeout(checkFilesQueued, 1000);
            }
          };
          checkFilesQueued();
        },
        /**
         * Called after a row has been deleted on server
         */
        _deleteRowCallback: function (response, status, more) {
          var selector = this.modal_selector;
          $(selector + ' .modal-body .alert').remove();
          if (this.closeModalOnSuccess) {
            this.internalCloseDialog(selector);
          } else {
            var message = '<div class="alert alert-success" role="alert">' +
              '<strong>' + this.language.success + '</strong>' +
              '</div>';
            $(selector + ' .modal-body').append(message);
          }
          this.s.dt.rows({
            selected: true
          }).remove();
          this.s.dt.draw('page');
          // Disabling submit button
          $("div" + selector).find("button#addRowBtn").prop('disabled', true);
          $("div" + selector).find("button#editRowBtn").prop('disabled', true);
          $("div" + selector).find("button#deleteRowBtn").prop('disabled', true);
        },
        /**
         * Called after a row has been inserted on server
         */
        _addRowCallback: function (response, status, more) {
          //TODO should honor dt.ajax().dataSrc
          var data = (typeof response === "string") ? JSON.parse(response) : response;
          var selector = this.modal_selector;
          $(selector + ' .modal-body .alert').remove();
          if (this.closeModalOnSuccess) {
            this.internalCloseDialog(selector);
          }
          else {
            var message = '<div class="alert alert-success" role="alert">' +
              '<strong>' + this.language.success + '</strong>' +
              '</div>';
            $(selector + ' .modal-body').append(message);
          }
          this.s.dt.row.add(data).draw(false);
          // Disabling submit button
          $("div" + selector).find("button#addRowBtn").prop('disabled', true);
          $("div" + selector).find("button#editRowBtn").prop('disabled', true);
          $("div" + selector).find("button#deleteRowBtn").prop('disabled', true);
        },
        /**
         * Called after a row has been updated on server
         */
        _editRowCallback: function (response, status, more) {
          //TODO should honor dt.ajax().dataSrc
          var data = (typeof response === "string") ? JSON.parse(response) : response;
          var selector = this.modal_selector;
          $(selector + ' .modal-body .alert').remove();
          if (this.closeModalOnSuccess) {
            this.internalCloseDialog(selector);
          }
          else {
            var message = '<div class="alert alert-success" role="alert">' +
              '<strong>' + this.language.success + '</strong>' +
              '</div>';
            $(selector + ' .modal-body').append(message);
          }
          this.s.dt.row({ selected: true }).data(data);
          this.s.dt.draw('page');
          // Disabling submit button
          $("div" + selector).find("button#addRowBtn").prop('disabled', true);
          $("div" + selector).find("button#editRowBtn").prop('disabled', true);
          $("div" + selector).find("button#deleteRowBtn").prop('disabled', true);
        },
        /**
         * Called after AJAX server returned an error
         */
        _errorCallback: function (response, status, more) {
          var error = response;
          var selector = this.modal_selector;
          $(selector + ' .modal-body .alert').remove();
          var errstr = this.language.error.message;
          if (error.responseJSON) {
            if (error.responseJSON.errors) {
              errstr = "";
              for (var key in error.responseJSON.errors) {
                errstr += error.responseJSON.errors[key][0];
              }
            }
          }
          else if (error.responseText) {
            errstr = error.responseText;
          }
          else {
            errstr = (error.status == null) ? "" : this.language.error.responseCode + error.status;
          }
          var message = '<div class="alert alert-danger" role="alert">' +
            '<strong>' + this.language.error.label + '</strong>'
            + (errstr ? '<br />' + errstr : '') +
            '</div>';
          $(selector + ' .modal-body').append(message);
        },
        /**
         * Default callback for insertion: mock webservice, always success.
         */
        onAddRow: function (dt, rowdata, success, error) {
          console.log("Missing AJAX configuration for INSERT");
          success(rowdata);
        },
        /**
         * Default callback for editing: mock webservice, always success.
         */
        onEditRow: function (dt, rowdata, success, error) {
          console.log("Missing AJAX configuration for UPDATE");
          success(rowdata);
        },
        /**
         * Default callback for deletion: mock webservice, always success.
         */
        onDeleteRow: function (dt, rowdata, success, error) {
          console.log("Missing AJAX configuration for DELETE");
          rowdata.every(function (rowIdx, tableLoop, rowLoop) {
            success(rowdata[rowIdx])
          })
        },
        /**
         * Open a dialog using available framework
         */
        internalOpenDialog(selector, onopen) {
          var $sel = $(selector);
          if ($sel.modal) {
            // Bootstrap
            $sel.on('show.bs.modal', onopen);
            $sel.modal('show');
          }
          else if ($sel.foundation) {
            // Foundation
            $sel.on('open.zf.reveal', onopen);
            $sel.on('closed.zf.reveal', function () { $('.reveal-overlay').hide(); });
            var popup = new Foundation.Reveal($sel);
            popup.open();
          }
          else {
            console.error('You must load Bootstrap or Foundation in order to open modal dialogs');
            return;
          }
        },
        /**
         * Close a dialog using available framework
         */
        internalCloseDialog(selector) {
          var $sel = $(selector);
          if ($sel.modal) {
            // Bootstrap
            $sel.modal('hide');
          } else if ($sel.foundation) {
            // Foundation
            var popup = new Foundation.Reveal($sel);
            popup.close();
            $('.reveal-overlay').hide();
          } else {
            console.error('You must load Bootstrap or Foundation in order to open modal dialogs');
            return;
          }
        },
        /**
         * Dinamically reload options in SELECT menu
        */
        reloadOptions: function ($select, options) {
          var oldValue = $select.val();
          $select.empty(); // remove old options
          if (options.length > 0) {
            // array-style select or select2
            $.each(options, function (key, value) {
              $select.append($("<option></option>")
                .attr("value", value).text(value));
            });
          }
          else {
            // object-style select or select2
            $.each(options, function (key, value) {
              $select.append($("<option></option>")
                .attr("value", value).text(key));
            });
          }
          $select.val(oldValue); // if still present, of course
          $select.trigger('change');
        },
        /**
         * Convert file to Base 64 form
         * @see https://stackoverflow.com/questions/36280818
         */
        getBase64: function (file, onSuccess, onError) {
          var reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = function () {
            if (onSuccess) onSuccess(reader.result);
          };
          reader.onerror = function (error) {
            console.log('Error: ', error);
            if (onError) onError(error);
          };
        },
        /**
         * Sanitizes input for use in HTML
         * @param s
         * @param preserveCR
         * @returns {string}
         * @private
         */
        _quoteattr: function (s, preserveCR) {
          if (s == null) {
            return "";
          }
          preserveCR = preserveCR ? '&#13;' : '\n';
          if (Array.isArray(s)) {
            // for MULTIPLE SELECT
            var newArray = [];
            var x;
            for (x in s) newArray.push(s[x]);
            return newArray;
          }
          return ('' + s) /* Forces the conversion to string. */
            .replace(/&/g, '&amp;') /* This MUST be the 1st replacement. */
            .replace(/'/g, '&apos;') /* The 4 other predefined entities, required. */
            .replace(/"/g, '&quot;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/\r\n/g, preserveCR) /* Must be before the next replacement. */
            .replace(/[\r\n]/g, preserveCR);
        },
      });
    /**
     * altEditor version
     *
     * @static
     * @type String
     */
    altEditor.version = '2.0';
    /**
     * altEditor defaults
     *
     * @namespace
     */
    altEditor.defaults = {
      /**
       * @type {Boolean} Ask user what they want to do, even for a single
       *       option
       */
      alwaysAsk: false,
      /** @type {string|null} What will trigger a focus */
      focus: null, // focus, click, hover
      /** @type {column-selector} Columns to provide auto fill for */
      columns: '', // all
      /** @type {boolean|null} Update the cells after a drag */
      update: null, // false is editor given, true otherwise
      /** @type {DataTable.Editor} Editor instance for automatic submission */
      editor: null
    };
    /**
     * Classes used by altEditor that are configurable
     *
     * @namespace
     */
    altEditor.classes = {
      /** @type {String} Class used by the selection button */
      btn: 'btn'
    };
    // Attach a listener to the document which listens for DataTables
    // initialisation
    // events so we can automatically initialise
    $(document).on('preInit.dt.altEditor', function (e, settings, json) {
      if (e.namespace !== 'dt') {
        return;
      }
      var init = settings.oInit.altEditor;
      var defaults = DataTable.defaults.altEditor;
      if (init || defaults) {
        var opts = $.extend({}, init, defaults);
        if (init !== false) {
          var editor = new altEditor(settings, opts);
          // e is a jQuery event object
          // e.target is the underlying jQuery object, e.g. $('#mytable')
          // so that you can retrieve the altEditor object later
          e.target.altEditor = editor;
        }
      }
    });
    // Alias for access
    DataTable.altEditor = altEditor;
    return altEditor;
  });

```
