{"id":15046335,"url":"https://github.com/peterstaev/nativescript-folding-list-view","last_synced_at":"2025-04-10T00:44:10.552Z","repository":{"id":57308527,"uuid":"148635776","full_name":"PeterStaev/nativescript-folding-list-view","owner":"PeterStaev","description":"Folding Cells for NativeScript","archived":false,"fork":false,"pushed_at":"2019-07-29T20:59:46.000Z","size":12758,"stargazers_count":13,"open_issues_count":2,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-10T00:44:04.714Z","etag":null,"topics":["android","folding","foldingcell","ios","nativescript","plugin","tangra"],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PeterStaev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-09-13T12:40:49.000Z","updated_at":"2024-05-30T16:12:10.000Z","dependencies_parsed_at":"2022-09-13T04:54:33.050Z","dependency_job_id":null,"html_url":"https://github.com/PeterStaev/nativescript-folding-list-view","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterStaev%2Fnativescript-folding-list-view","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterStaev%2Fnativescript-folding-list-view/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterStaev%2Fnativescript-folding-list-view/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PeterStaev%2Fnativescript-folding-list-view/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PeterStaev","download_url":"https://codeload.github.com/PeterStaev/nativescript-folding-list-view/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248137998,"owners_count":21053775,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["android","folding","foldingcell","ios","nativescript","plugin","tangra"],"created_at":"2024-09-24T20:53:00.070Z","updated_at":"2025-04-10T00:44:10.536Z","avatar_url":"https://github.com/PeterStaev.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"**This repo only supports NativeScript pre-6.0. The latest version of the plugin supporting NS 6+ is availble as part of [ProPlugins](https://proplugins.org).**\n # NativeScript Folding List View widget\n[![Build Status](https://travis-ci.com/PeterStaev/nativescript-folding-list-view.svg?branch=master)](https://travis-ci.com/PeterStaev/nativescript-folding-list-view)\n[![npm downloads](https://img.shields.io/npm/dm/nativescript-folding-list-view.svg)](https://www.npmjs.com/package/nativescript-folding-list-view)\n[![npm downloads](https://img.shields.io/npm/dt/nativescript-folding-list-view.svg)](https://www.npmjs.com/package/nativescript-folding-list-view)\n[![npm](https://img.shields.io/npm/v/nativescript-folding-list-view.svg)](https://www.npmjs.com/package/nativescript-folding-list-view)\n\n![NativeScript+Ramotion=❤️](https://raw.githubusercontent.com/PeterStaev/nativescript-folding-list-view/master/media/header.gif)\n\nA NativeScript ListView with foldable cells. Utilizes the wonderfull FoldingCell created by [Ramotion](https://github.com/Ramotion)!\n\n## Screenshot\n![ios](https://raw.githubusercontent.com/PeterStaev/nativescript-folding-list-view/master/media/folding_ios.gif)\n![android](https://raw.githubusercontent.com/PeterStaev/nativescript-folding-list-view/master/media/folding_android.gif)\n\n## Installation\nRun the following command from the root of your project:\n\n`tns plugin add nativescript-folding-list-view`\n\nThis command automatically installs the necessary files, as well as stores nativescript-folding-list-view as a dependency in your project's package.json file.\n\n## Configuration\nThere is no additional configuration needed!\n\n## API\n\n### Events\n* **itemLoading**  \nTriggered when generating an item in the FoldingListView. \n\n* **loadMoreItems**  \nTriggered when the generated items reached the end of the items property.\n\n### Static Properties\n* **itemLoadingEvent** - *String*  \nString value used when hooking to itemLoadingEvent event.\n\n* **loadMoreItemsEvent** - *String*  \nString value used when hooking to itemTapEvent event.\n\n### Instance Properties\n* **ios** - *[UITableView](https://developer.apple.com/documentation/uikit/uitableview?language=objc)*  \nGets the native iOS view that represents the user interface for this component. Valid only when running on iOS.\n\n* **android** - *[android.widget.ListView](https://developer.android.com/reference/android/widget/ListView)*  \nGets the native android widget that represents the user interface for this component. Valid only when running on Android OS.\n\n* **items** - *Array | ItemsSource*  \nGets or sets the items collection of the FoldingListView. The items property can be set to an array or an object defining length and getItem(index) method.\n\n* **foregroundItemTemplate** - *String*  \nGets or sets the item template of that is displayed for **folded** cell.\n\n* **containerItemTemplate** - *String*  \nGets or sets the item template of that is displayed for **unfolded** cell.\n\n* **foldedRowHeight** - *Length*  \nGets or sets the height for folded cells in the list.\n\n* **foldsCount** - *number*  \nGets or sets the number of unfolds each cell will have. Minimum is 3.\n\n* **foldAnimationDuration** - *number*  \nGets or sets the miliseconds each fold/unfold should take. Default value is 330ms. \n\n* **backViewColor** - *Color*  \nGets or sets the color that will be displayed during the unfolding animation of the cell. \n\n* **toggleMode** - *boolean*  \nGets or sets whether the control will work in toggle mode. If set to true only a single cell can be expanded and if the user tries to expand another cell the first one will get folded. \n\n* **itemTemplateSelector** - *Function | string*  \nThis can be either a function that should return a string representing the template key to use, or it can be a string of a property which value will be pulled from the binding context for the current item. Note that the same template key will be used to pull the template for **both** the foreground and container views. \n\n* **detailDataLoader** - *Function*  \nGets or sets the a function that will be used for loading the data for the unfolded cell. By default, when this is not specified the widget binds both the folded and unfolded cells the current item. This means that the data for both views should be available in the item. If you set this function it will be called whenever the user taps on an item to unfold it. The function the current `item` and `index` and must return a `Promise` with the data item that should be bound to the unfolded cell. \n\n### Instance Methods\n* **refresh()**  \nForces the FoldingListView to reload all its items.\n\n* **scrollToIndex(index: number, animated: boolean = true)**  \nScrolls the FoldingListView to the item with the given index. This can be either animated or not. Defaults to animated.\n\n* **invalidateChachedDetailData(index: number)**  \nInvalidates the cahced detail data for the given index. This will cause the `detailDataLoader` to be called when the cell at the given indexed is shown or the list is refreshed. \n\n* **isItemAtIndexVisible(index: number): boolean**  \nChecks if the given index is curently visible in the list. \n\n* **resetExpandedStates()**  \nResets expanded states for all cells in the list view. Useful when you are reloading the list with completely different data so all cells can start in folded state. \n\n## Usage\nYou need to add `xmlns:flv=\"nativescript-folding-list-view\"` to your page tag, and then simply use `\u003cflv:FoldingListView/\u003e` in order to add the widget to your page. Use `\u003cflv:FoldingListView.foregroundItemTemplate/\u003e` to specify the template for folded cells and `\u003cflv:FoldingListView.containerItemTemplate/\u003e` to specify the template for unfolded cells:\n\n```xml\n\u003c!-- test-page.xml --\u003e\n\u003cPage xmlns=\"http://schemas.nativescript.org/tns.xsd\" \n      xmlns:flv=\"nativescript-folding-list-view\"\n      navigatingTo=\"navigatingTo\" class=\"page\"\u003e\n\n    \u003cPage.actionBar\u003e\n        \u003cActionBar title=\"Folding LV\" icon=\"\" class=\"action-bar\"\u003e\n        \u003c/ActionBar\u003e\n    \u003c/Page.actionBar\u003e\n\n    \u003cGridLayout\u003e\n        \u003cflv:FoldingListView items=\"{{ items }}\" foldsCount=\"5\" foldedRowHeight=\"95\" \n            detailDataLoader=\"detailDataLoader\"\u003e\n            \u003cflv:FoldingListView.foregroundItemTemplate\u003e\n                \u003cGridLayout columns=\"75, *\" class=\"folded-cell\"\u003e\n                    \u003cGridLayout row=\"0\" col=\"0\" rows=\"*, auto, auto, *\" class=\"item-nbr\"\u003e\n                        \u003cLabel row=\"1\" text=\"Item\"/\u003e\n                        \u003cLabel row=\"2\" text=\"{{ '#' + item }}\"/\u003e\n                        \u003cActivityIndicator row=\"3\" busy=\"{{ isBusyIn }}\" /\u003e\n                    \u003c/GridLayout\u003e\n                    \u003cStackLayout col=\"1\" padding=\"10\"\u003e\n                        \u003cLabel class=\"h2\" text=\"My Header\"/\u003e\n                        \u003cLabel class=\"label\" textWrap=\"true\" text=\"Short description. Tap to see more!\"/\u003e\n                    \u003c/StackLayout\u003e\n                \u003c/GridLayout\u003e\n            \u003c/flv:FoldingListView.foregroundItemTemplate\u003e\n            \n            \u003cflv:FoldingListView.containerItemTemplate\u003e\n                \u003cStackLayout rows=\"auto, *, auto\" class=\"expanded-cell\"\u003e\n                    \u003cLabel class=\"item-nbr\" text=\"{{ 'Item #' + item }}\" /\u003e\n                    \u003cLabel class=\"label\" textWrap=\"true\" text=\"{{ details }}\" /\u003e\n                    \u003cButton id=\"btn\" class=\"btn btn-primary\" text=\"Click Me!\" /\u003e\n                \u003c/StackLayout\u003e\n            \u003c/flv:FoldingListView.containerItemTemplate\u003e\n        \u003c/flv:FoldingListView\u003e\n    \u003c/GridLayout\u003e\n\u003c/Page\u003e\n```\n### Multiple templates\nUsing mutiple templates is dones the same way as you would in the buil-tin `ListView` control - the wdiget provides an `itemTemplateSelector` property that can be either set to a function that returns the correct template key for an item or to a string from which property the value of the key will be pulled. Note that same template key will be used for both the container and foreground views. If you want to have different template only for one type of view, then you can leave the single template for the other one\n```xml\n\u003cflv:FoldingListView id=\"lv\" items=\"{{ items }}\" foldsCount=\"5\" foldedRowHeight=\"95\" \n    loadMoreItems=\"loadMoreItems\" itemLoading=\"itemLoading\" detailDataLoader=\"detailDataLoader\"\n    itemTemplateSelector=\"itemTemplateSelector\"\u003e\n    \u003cflv:FoldingListView.foregroundItemTemplates\u003e\n        \u003ctemplate key=\"odd\"\u003e\n            \u003cGridLayout columns=\"75, *\" class=\"folded-cell\"\u003e\n                \u003c!-- ... --\u003e\n            \u003c/GridLayout\u003e\n        \u003c/template\u003e\n        \u003ctemplate key=\"even\"\u003e\n            \u003cGridLayout columns=\"75, *\" class=\"folded-cell even\"\u003e\n                \u003c!-- ... --\u003e\n            \u003c/GridLayout\u003e\n        \u003c/template\u003e\n    \u003c/flv:FoldingListView.foregroundItemTemplates\u003e\n\n    \u003cflv:FoldingListView.containerItemTemplates\u003e\n        \u003ctemplate key=\"odd\"\u003e\n            \u003cStackLayout class=\"expanded-cell\"\u003e\n                \u003c!-- ... --\u003e\n            \u003c/StackLayout\u003e\n        \u003c/template\u003e\n        \u003ctemplate key=\"even\"\u003e\n            \u003cStackLayout class=\"expanded-cell even\"\u003e\n                \u003c!-- ... --\u003e\n            \u003c/StackLayout\u003e\n        \u003c/template\u003e\n    \u003c/flv:FoldingListView.containerItemTemplates\u003e\n\u003c/flv:FoldingListView\u003e\n```\n```ts\nexport function itemTemplateSelector(item: any, index: number, items: any) {\n    return (index % 2 === 0 ? \"even\" : \"odd\");\n}\n```\n\n### Unfolded view height requirements\nNote that in order for the widget to function properly the unfolded view height must be more than two times the height of the folded view. In order to ensure this (especially in cases where you load the detail data on demand and do not know exactly the height of the item) it is a good idea to set `min-height` on the wrapping layout for the unfolded cells. \n\n### Using `detailDataLoader` to load the bound item for the unfolded cells\nIn many cases when you have complex layout or you want to display many details in the unfolded cells, it is a good practice to not load all that data with your folded cells items. The widget provides a function which you can use to load that data on demand when the user taps to unfold a given cell. \n```ts\nexport function detailDataLoader(item: any, index: number) {\n    item.set(\"isBusyIn\", true);\n    return new Promise((resolve, reject) =\u003e {\n        setTimeout(() =\u003e {\n            item.details = \"\u003c ... some very long text ... \u003e\";\n            resolve(item);\n\n            item.set(\"isBusyIn\", false);\n        }, 3000);\n    });\n}\n```\nNote that this simply a bound function, it is not an event! The function should **return** a `Promise` that resolves the loaded data from you backend for the given cell. \n\n### Having buttons inside the cells (Android)\nUnder Android there are problems for the `ListView` android widget to intercept tap evens in cases when you have a `Button` inside the cells. In order to overcome this you need to subscribe to the `itemLoading` event and then set the button to **not** be focusable:\n```ts\nexport function itemLoading({ index, view }: ItemEventData) {\n    if (isAndroid) {\n        // HACK: Button inside the ListView prevents item click\n        view.container.getViewById(\"btn\").android.setFocusable(false);\n    }\n}\n```\n\n## Usage in Angular\nCurrently the Folding List View does **not** support Angular projects out of the box!\n\n## Demos\nThis repository includes plain NativeScript demo. In order to run it execute the following in your shell:\n```shell\n$ git clone https://github.com/peterstaev/nativescript-folding-list-view\n$ cd nativescript-folding-list-view\n$ npm install\n$ npm run demo-ios\n```\nThis will run the  NativeScript demo project on iOS. If you want to run it on Android simply use the `-android` instead of the `-ios` sufix. \n\n## Donate\n[![Donate](https://img.shields.io/badge/paypal-donate-brightgreen.svg)](https://bit.ly/2AS9QKB)\n\n`bitcoin:14fjysmpwLvSsAskvLASw6ek5XfhTzskHC`\n\n![Donate](https://www.tangrainc.com/qr.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterstaev%2Fnativescript-folding-list-view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpeterstaev%2Fnativescript-folding-list-view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpeterstaev%2Fnativescript-folding-list-view/lists"}