{"id":19658137,"url":"https://github.com/cdaringe/ampersand-collection-jquery-datatable","last_synced_at":"2026-02-12T23:31:25.541Z","repository":{"id":26580263,"uuid":"30034682","full_name":"cdaringe/ampersand-collection-jquery-datatable","owner":"cdaringe","description":"Renders a ampersand-collections via jQuery DataTables","archived":false,"fork":false,"pushed_at":"2023-12-15T14:55:44.000Z","size":340,"stargazers_count":1,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-10T21:12:44.026Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://cdaringe.net","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cdaringe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-01-29T18:28:44.000Z","updated_at":"2017-07-07T19:16:57.000Z","dependencies_parsed_at":"2024-11-11T15:38:46.432Z","dependency_job_id":"cafd395e-589c-47a6-8228-62b41d79d757","html_url":"https://github.com/cdaringe/ampersand-collection-jquery-datatable","commit_stats":{"total_commits":32,"total_committers":2,"mean_commits":16.0,"dds":0.0625,"last_synced_commit":"7ffc69a6a4f40605fb03d9862ecd414a4f5daa02"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/cdaringe/ampersand-collection-jquery-datatable","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdaringe%2Fampersand-collection-jquery-datatable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdaringe%2Fampersand-collection-jquery-datatable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdaringe%2Fampersand-collection-jquery-datatable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdaringe%2Fampersand-collection-jquery-datatable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cdaringe","download_url":"https://codeload.github.com/cdaringe/ampersand-collection-jquery-datatable/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cdaringe%2Fampersand-collection-jquery-datatable/sbom","scorecard":{"id":269543,"data":{"date":"2025-08-11","repo":{"name":"github.com/cdaringe/ampersand-collection-jquery-datatable","commit":"7ffc69a6a4f40605fb03d9862ecd414a4f5daa02"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":2.6,"checks":[{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Code-Review","score":0,"reason":"Found 0/28 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":0,"reason":"license file not detected","details":["Warn: project does not have a license file"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 3 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T12:59:23.660Z","repository_id":26580263,"created_at":"2025-08-17T12:59:23.660Z","updated_at":"2025-08-17T12:59:23.660Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29386217,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-12T22:07:52.078Z","status":"ssl_error","status_checked_at":"2026-02-12T22:07:49.026Z","response_time":55,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-11T15:36:13.527Z","updated_at":"2026-02-12T23:31:25.522Z","avatar_url":"https://github.com/cdaringe.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ampersand-collection-jquery-datatable\n[ ![Codeship Status for cdaringe/ampersand-collection-jquery-datatable](https://codeship.com/projects/21ed5d70-9f55-0132-8711-02db7f3f2d41/status?branch=master)](https://codeship.com/projects/65128)\n[![browser support](https://ci.testling.com/cdaringe/ampersand-collection-jquery-datatable.png)\n](https://ci.testling.com/cdaringe/ampersand-collection-jquery-datatable.png)\n\n# What\n\n* You use [ampersand.js](https://ampersandjs.com/) (or [backbone.js](http://backbonejs.org/)).\n* You use [jQuery DataTables](https://datatables.net/).\n* You have an [collection](https://github.com/AmpersandJS/ampersand-collection) that you want to render in a DataTable.\n* You want your dataTable to respond to collection events (i.e. `add`, `remove`, `update`), and be displayed immediately, without having to get into the dataTable API on your own.  This library updates DataTable rows and columns as their corresponding collections change.  However, you are technically not required to use collections for either (rows/columns), and instead may use arrays.\n\nHow refreshing.\n\n## Usage\n\n```js\nvar CollectionTable = require('ampersand-collection-jquery-datatable'); // long name :)\n// Generate a config of the following form:\nvar config = {\n    el: raw_DOM_node_for_table, // e.g. this.queryByHook('my-table')\n    collection: myCollection, // OR ...\n    dtOptions: {\n        // datatable constructor options\n    },\n    dtClasses: 'display compact' // sugar for adding some styles\n};\n\n...\n    // inside a view\n    render: function() {\n        var myCollDataTable = new CollectionTable(config)\n    }\n...\n```\n\nTo see other options, **check the contructor DocBlock**.  The latest should always be maintained here, too:\n\n```js\n/**\n * Constructor\n * @param  {options} object {\n *     collection: {AmpersandCollection}, // assumes `rows`, OR use...\n *     collections: {\n *         rows: {AmpersandCollection|Array},\n *         cols: {AmpersandCollection|Array}  // overrides dtOptions.columns. Contained\n *                                            // states should have .title, .data, \u0026 .id attr\n *     }\n *     el: {Element},           // dataTable target\n *     dtOptions: {Object},     // dataTable config.  Set the `data` (rows) and `columns` props as reqd\n *     dtClasses: {String=},    // class(es) to be applied to the target element/table\n *     noToolbar: {Boolean=},   // hide the datatable toolbar\n *     renderer:  {Function=}   // delegate a custom function to init the dataTable.\n *                              // renderer receives `($el, modified-dtOptions)`,\n *                              // and should return the result of `$el.DataTables(...)\n * }\n * @return {CollectionDataTable}\n */\n```\n\n## api\n\n##### attrs\n- `stateNodes` - Access the row DOM node for you state/model by peeking at `yourCollectionTable.stateNodes[yourModel.cid]`\n\n\n# Full Example\n\n```js\nvar jQuery = window.jQuery = require('jquery'),\n    Collection = require('ampersand-collection'),\n    Model = require('ampersand-model'),\n    TestModel = Model.extend({ props: {a: 'string', b: 'string'} }),\n    CollectionTable = require('../../ampersand-collection-jquery-datatable'),\n    datatables= require('datatables'),\n    domready = require('domready');\n\nvar colDefs = [{title: 'a', data: 'a'}, {title: 'b', data: 'b'}];\nvar dummyData = [\n    new TestModel({a: 'a1', b: 'b1'}),\n    new TestModel({a: 'a2', b: 'b2'})\n];\n\ndomready(function() {\n    var $myDt = jQuery('#myTable');\n    var TestCollection = Collection.extend({\n        indexes: ['a', 'b'],\n        model: TestModel\n    });\n    var dummyCollection = new TestCollection();\n    var acjd = new CollectionTable({\n        collection: dummyCollection,\n        el: $myDt[0],\n        dtOptions: {\n            data: dummyData,\n            columns: colDefs\n        }\n    });\n\n    // Test add/remove/update\n    var newObj = new TestModel({a: 'new', b: 'new'});\n    dummyCollection.add(newObj);  // dataTable responds, adds row!\n\n    // remove obj\n    var removeObj = new TestModel({a: 'REMOVE', b: 'REMOVE'});\n    dummyCollection.add(removeObj);\n    dummyCollection.remove(removeObj); // dataTable responds, removes row!\n\n    // change\n    dummyCollection\n        .add({a: 'needs-to-be-updated', b: 'needs-to-be-updated'});\n    var toChange = dummyCollection.get('nees-to-be-updated', 'a');\n    toChange.a = 'updated-successfully';\n    toChange.b = 'updated-successfully';\n    // dataTable responds, deletes old row, adds row with new data back in\n    // as your model changes.  Note: if your model changes a lot, this is expensive\n    // re-drawing.  A debounce may worth implementing, or simply refreshing the row\n    // from an updated data source\n\n});\n```\n# Edge Cases and Warnings\n\n1. **Adding and deleting columns completely destroys the dataTable and rebuilds it**.  Dynamic columns is not officially supported by DataTables, so I scrap and rebuild it as there is no other way at the time of writing.  Be careful adding/deleting many cols with large datasets.  PRs are in work @DataTables for this.\n1. Using the `init.dt` event and `initComplete` options may yield unexpected behavior.  Post-initialization of a ACJD, an *empty table is drawn*.  CollectionTable then immediately adds row data, and re-draws.  Your defined `initComplete` is executed then.  The `init.dt` (or similair) event is not rethrown.  PRs are welcome in this regard.\n1. Using `deferRender` in `dtOptions` prevents `CollectionTable.stateNodes` from storing valid DOM nodes, as DOM nodes aren't built immediately!\n1. To run the tests, if initial run results in an error that complains about phantom/*, see [this](https://github.com/AmpersandJS/ampersand-collection-view/issues/13#issuecomment-51083095)\n\n# Changelog\n* 2.1.0 - Module now listens to `reset` event from collection as well and re-draws datatable with new data.\n* 2.0.2 - patch README\n* 2.0.1 - reduce payload by including micro-lodash deps\n* 2.0.0 - moved datatables and jquery to package.json dependencies. support DT 1.10.7.\n* 1.3.5 - bugfix: do standing draw on update (change), not reset draw\n* 1.3.4 - if DT `deferRender` is activated, still be able to locate data to update, regardless if a DOM node is built or not. (handle no node in `cid` store)\n* 1.3.1-3 - README updates and remove self-assign from `options.dtOptions` (all pass in of read-only `.dtOptions`)\n* 1.3.0 - add dynamic columns, tests, and sandbox\n* 1.2.3 - add missing repo field\n* 1.2.2 - Carry applied `classes` from old `tr` to new `tr` onchange.  Additional attrs may need consideration as well\n* 1.2.1 - Drastically improve `change` on the collection--rows are no longer deleted and re-added.  Instead, the `.data()` setter is used, even if the data pointer is the same as the original, which triggers a view update on that row.\n* 1.2.0 - `initComplete` handling update.  initComplete must be called after the table is instantiated due to the way that the table data is populated in CollectionTable.  Additionally, `.$dt` now points to the actual DT instance, and `.$api` points to a `.$dt.api()`.\n* 1.1.2 - doc updates only\n* 1.1.1 - bugfix \u0026 feature.  removing a state would sometimes scrap the full table. improved the indexing by looking up models in table by DOM node via `.stateNodes`\n* 1.1.0 - added `.renderer` option.  some users have pre-defined utilities to pipe table options thru prior to initialization\n\n# ToDo\n\n1. Debounce for bulk changes\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdaringe%2Fampersand-collection-jquery-datatable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcdaringe%2Fampersand-collection-jquery-datatable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcdaringe%2Fampersand-collection-jquery-datatable/lists"}