{ "id": "113433", "key": "TIMOB-13684", "fields": { "issuetype": { "id": "5", "description": "The sub-task of the issue", "name": "Sub-task", "subtask": true }, "parent": { "id": "111847", "key": "TIMOB-13245", "fields": { "summary": "Android: Implement ListView Phase 2", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "priority": { "name": "Critical", "id": "1" }, "issuetype": { "id": "2", "description": "A new feature of the product, which has yet to be developed.", "name": "New Feature", "subtask": false } } }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [ { "id": "15699", "description": "2013 Sprint 21", "name": "2013 Sprint 21", "archived": true, "released": true, "releaseDate": "2013-10-18" }, { "id": "15700", "description": "2013 Sprint 21 API", "name": "2013 Sprint 21 API", "archived": true, "released": true, "releaseDate": "2013-10-18" }, { "id": "14982", "description": "Release 3.2.0", "name": "Release 3.2.0", "archived": false, "released": true, "releaseDate": "2013-12-19" } ], "resolution": { "id": "1", "description": "A fix for this issue is checked into the tree and tested.", "name": "Fixed" }, "resolutiondate": "2013-10-18T22:17:11.000+0000", "created": "2013-04-26T17:13:29.000+0000", "priority": { "name": "Medium", "id": "3" }, "labels": [], "versions": [], "issuelinks": [], "assignee": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-22T00:13:04.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10202", "name": "Android", "description": "Android Platform" } ], "description": "Integrating search functionalities into ListView:\r\n1. ListView properties: searchView, searchText, caseInsensitiveSearch\r\n2. ListItem properties: searchableText\r\n\r\n\r\nTest case for searchView, searchableText:\r\n{code}\r\n\r\nvar sections = [];\r\n\t \r\n\tvar fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'});\r\n\tvar fruitDataSet = [\r\n\t {properties: { title: 'Apple', searchableText:' Fruits Apple', itemId:'0 0'}},\r\n\t {properties: { title: 'Banana', searchableText:'Fruits Banana', itemId:'0 1'}},\r\n\t {properties: { title: 'Cantaloupe', searchableText:'Fruits Cantaloupe', itemId:'0 2'}},\r\n\t {properties: { title: 'Fig', searchableText:'Fruits Fig', itemId:'0 3'}},\r\n\t {properties: { title: 'Guava', searchableText:'Fruits Guava', itemId:'0 4'}},\r\n\t {properties: { title: 'Kiwi', searchableText:'Fruits Kiwi', itemId:'0 5'}},\r\n\t];\r\n\tfruitSection.setItems(fruitDataSet);\r\n\tsections.push(fruitSection);\r\n\t \r\n\tvar vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'});\r\n\tvar vegDataSet = [\r\n\t {properties: { title: 'Carrots', searchableText:'Vegetables Carrots', itemId:'1 0'}},\r\n\t {properties: { title: 'Potatoes', searchableText:'Vegetables Potatoes', itemId:'1 1'}},\r\n\t {properties: { title: 'Corn', searchableText:'Vegetables Corn', itemId:'1 2'}},\r\n\t {properties: { title: 'Beans', searchableText:'Vegetables Beans', itemId:'1 3'}},\r\n\t {properties: { title: 'Tomato', searchableText:'Vegetables Tomato', itemId:'1 4'}},\r\n\t];\r\n\tvegSection.setItems(vegDataSet);\r\n\tsections.push(vegSection);\r\n\t \r\n\t \r\n\tvar fishSection = Ti.UI.createListSection({ headerTitle: 'Fish'});\r\n\tvar fishDataSet = [\r\n\t {properties: { title: 'Cod', searchableText:'Fish Cod', itemId:'2 0'}},\r\n\t {properties: { title: 'Haddock', searchableText:'Fish Haddock', itemId:'2 1'}},\r\n\t {properties: { title: 'Salmon', searchableText:'Fish Salmon', itemId:'2 2'}},\r\n\t {properties: { title: 'Tuna', searchableText:'Fish Tuna', itemId:'2 3'}},\r\n\t];\r\n\tfishSection.setItems(fishDataSet);\r\n\tsections.push(fishSection);\r\n\t\r\n\tvar animalsSection = Ti.UI.createListSection({ headerTitle: 'Animals'});\r\n\tvar animalsDataSet = [\r\n\t {properties: { title: 'Deer', searchableText:'Animals Deer', itemId:'3 0'}},\r\n\t {properties: { title: 'Dog', searchableText:'Animals Dog', itemId:'3 1'}},\r\n\t {properties: { title: 'Cat', searchableText:'Animals Cat', itemId:'3 2'}},\r\n\t {properties: { title: 'Elephant', searchableText:'Animals Elephant', itemId:'3 3'}},\r\n\t];\r\n\tanimalsSection.setItems(animalsDataSet);\r\n\tsections.push(animalsSection);\r\n\r\n\tvar sv = Titanium.UI.createSearchBar({\r\n\t showCancel:true,\r\n\t height: 100,\r\n\t top: 10,\r\n\t hintText:'search'\r\n\t});\r\n\t\r\n\tvar sv2 = Titanium.UI.createSearchBar({\r\n\t showCancel:true,\r\n\t height: 150,\r\n\t top: 10,\r\n\t hintText:'search two'\r\n\t});\r\n\t\r\n\tvar button = Ti.UI.createButton({top: 100, title: \"toggle searchView\"});\r\n\t\r\n\tbutton.addEventListener('click', function(e) {\r\n\t listView.searchView = sv2;\r\n\t});\r\n\t\r\n\t//The textfield must be a subview of the tableView to \r\n\t//calculate correct contentInsets when keyboard is visible. \r\n\tvar listView = Ti.UI.createListView({searchView: sv, top: 250});\r\n\tlistView.sections = sections;\r\n\t\r\n\tvar win = Ti.UI.createWindow();\r\n\twin.add(listView);\r\n\twin.add(button);\r\n\twin.open();\r\n{code}\r\n\r\n1. Run code, type something in the search and to make sure its working properly. Note that each product can be search by both type and name. For instance, Apple can be lookup with either \"Fruits\" or \"Apple\" or any substrings of the two.\r\n2. Click on button to change searchView.\r\n\r\nTest case for searchText, searchableText, caseInsensitiveSearch\r\n{code}\r\n\r\nvar sections = [];\r\n\t \r\n\tvar fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'});\r\n\tvar fruitDataSet = [\r\n\t {properties: { title: 'Apple', searchableText:' Fruits Apple', itemId:'0 0'}},\r\n\t {properties: { title: 'Banana', searchableText:'Fruits Banana', itemId:'0 1'}},\r\n\t {properties: { title: 'Cantaloupe', searchableText:'Fruits Cantaloupe', itemId:'0 2'}},\r\n\t {properties: { title: 'Fig', searchableText:'Fruits Fig', itemId:'0 3'}},\r\n\t {properties: { title: 'Guava', searchableText:'Fruits Guava', itemId:'0 4'}},\r\n\t {properties: { title: 'Kiwi', searchableText:'Fruits Kiwi', itemId:'0 5'}},\r\n\t];\r\n\tfruitSection.setItems(fruitDataSet);\r\n\tsections.push(fruitSection);\r\n\t \r\n\tvar vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'});\r\n\tvar vegDataSet = [\r\n\t {properties: { title: 'Carrots', searchableText:'Vegetables Carrots', itemId:'1 0'}},\r\n\t {properties: { title: 'Potatoes', searchableText:'Vegetables Potatoes', itemId:'1 1'}},\r\n\t {properties: { title: 'Corn', searchableText:'Vegetables Corn', itemId:'1 2'}},\r\n\t {properties: { title: 'Beans', searchableText:'Vegetables Beans', itemId:'1 3'}},\r\n\t {properties: { title: 'Tomato', searchableText:'Vegetables Tomato', itemId:'1 4'}},\r\n\t];\r\n\tvegSection.setItems(vegDataSet);\r\n\tsections.push(vegSection);\r\n\t \r\n\t \r\n\tvar fishSection = Ti.UI.createListSection({ headerTitle: 'Fish'});\r\n\tvar fishDataSet = [\r\n\t {properties: { title: 'Cod', searchableText:'Fish Cod', itemId:'2 0'}},\r\n\t {properties: { title: 'Haddock', searchableText:'Fish Haddock', itemId:'2 1'}},\r\n\t {properties: { title: 'Salmon', searchableText:'Fish Salmon', itemId:'2 2'}},\r\n\t {properties: { title: 'Tuna', searchableText:'Fish Tuna', itemId:'2 3'}},\r\n\t];\r\n\tfishSection.setItems(fishDataSet);\r\n\tsections.push(fishSection);\r\n\t\r\n\tvar animalsSection = Ti.UI.createListSection({ headerTitle: 'Animals'});\r\n\tvar animalsDataSet = [\r\n\t {properties: { title: 'Deer', searchableText:'Animals Deer', itemId:'3 0'}},\r\n\t {properties: { title: 'Dog', searchableText:'Animals Dog', itemId:'3 1'}},\r\n\t {properties: { title: 'Cat', searchableText:'Animals Cat', itemId:'3 2'}},\r\n\t {properties: { title: 'Elephant', searchableText:'Animals Elephant', itemId:'3 3'}},\r\n\t];\r\n\tanimalsSection.setItems(animalsDataSet);\r\n\tsections.push(animalsSection);\r\n\r\n\tvar tf = Ti.UI.createTextField({\r\n\t color: '#336699',\r\n\t height: '50dp',\r\n\t top:10,\r\n\t bottom:10,\r\n\t left:10,\r\n\t right:10,\r\n\t font:{fontSize:20,fontWeight:'bold'},\r\n\t hintText: 'Search'\r\n\t});\r\n\t\r\n\ttf.addEventListener('change',function(e){\r\n\t listView.searchText = e.value;\r\n\t})\r\n\t\r\n\tvar button = Ti.UI.createButton({top: '70dp', title: \"toggle caseInsensitive\"});\r\n\t\r\n\tbutton.addEventListener('click', function(e) {\r\n\t if (listView.caseInsensitiveSearch) {\r\n\t \tlistView.caseInsensitiveSearch = false;\r\n\t } else {\r\n\t listView.caseInsensitiveSearch = true;\r\n\t }\r\n\t});\r\n\t\r\n\t//The textfield must be a subview of the tableView to \r\n\t//calculate correct contentInsets when keyboard is visible. \r\n\tvar listView = Ti.UI.createListView({top: '150dp'});\r\n\tlistView.sections = sections;\r\n\t\r\n\tvar win = Ti.UI.createWindow();\r\n\twin.add(listView);\r\n\twin.add(button);\r\n\twin.add(tf);\r\n\twin.open();\r\n{code}\r\n\r\n1. Run code, type something in the textfield and to make sure its working properly. Note that each product can be search by both type and name. For instance, Apple can be lookup with either \"Fruits\" or \"Apple\" or any substrings of the two.\r\n2. Click on button to toggle case sensitivity.\r\n\r\nTest case for Ti.UI.Android.SearchView: \r\n{code}var sections = [];\r\n \r\n var fruitSection = Ti.UI.createListSection({ headerTitle: 'Fruits'});\r\n var fruitDataSet = [\r\n {properties: { title: 'Apple', searchableText:' Fruits Apple', itemId:'0 0'}},\r\n {properties: { title: 'Banana', searchableText:'Fruits Banana', itemId:'0 1'}},\r\n {properties: { title: 'Cantaloupe', searchableText:'Fruits Cantaloupe', itemId:'0 2'}},\r\n {properties: { title: 'Fig', searchableText:'Fruits Fig', itemId:'0 3'}},\r\n {properties: { title: 'Guava', searchableText:'Fruits Guava', itemId:'0 4'}},\r\n {properties: { title: 'Kiwi', searchableText:'Fruits Kiwi', itemId:'0 5'}},\r\n ];\r\n fruitSection.setItems(fruitDataSet);\r\n sections.push(fruitSection);\r\n \r\n var vegSection = Ti.UI.createListSection({ headerTitle: 'Vegetables'});\r\n var vegDataSet = [\r\n {properties: { title: 'Carrots', searchableText:'Vegetables Carrots', itemId:'1 0'}},\r\n {properties: { title: 'Potatoes', searchableText:'Vegetables Potatoes', itemId:'1 1'}},\r\n {properties: { title: 'Corn', searchableText:'Vegetables Corn', itemId:'1 2'}},\r\n {properties: { title: 'Beans', searchableText:'Vegetables Beans', itemId:'1 3'}},\r\n {properties: { title: 'Tomato', searchableText:'Vegetables Tomato', itemId:'1 4'}},\r\n ];\r\n vegSection.setItems(vegDataSet);\r\n sections.push(vegSection);\r\n \r\n \r\n var fishSection = Ti.UI.createListSection({ headerTitle: 'Fish'});\r\n var fishDataSet = [\r\n {properties: { title: 'Cod', searchableText:'Fish Cod', itemId:'2 0'}},\r\n {properties: { title: 'Haddock', searchableText:'Fish Haddock', itemId:'2 1'}},\r\n {properties: { title: 'Salmon', searchableText:'Fish Salmon', itemId:'2 2'}},\r\n {properties: { title: 'Tuna', searchableText:'Fish Tuna', itemId:'2 3'}},\r\n ];\r\n fishSection.setItems(fishDataSet);\r\n sections.push(fishSection);\r\n \r\n var animalsSection = Ti.UI.createListSection({ headerTitle: 'Animals'});\r\n var animalsDataSet = [\r\n {properties: { title: 'Deer', searchableText:'Animals Deer', itemId:'3 0'}},\r\n {properties: { title: 'Dog', searchableText:'Animals Dog', itemId:'3 1'}},\r\n {properties: { title: 'Cat', searchableText:'Animals Cat', itemId:'3 2'}},\r\n {properties: { title: 'Elephant', searchableText:'Animals Elephant', itemId:'3 3'}},\r\n ];\r\n animalsSection.setItems(animalsDataSet);\r\n sections.push(animalsSection);\r\n \r\n var sv = Titanium.UI.createSearchBar({\r\n showCancel:true,\r\n height: 100,\r\n top: 10,\r\n hintText:'search'\r\n });\r\n \r\n var sv2 = Titanium.UI.createSearchBar({\r\n showCancel:true,\r\n height: 150,\r\n top: 10,\r\n hintText:'search two'\r\n });\r\n \r\n var sv3 = Ti.UI.Android.createSearchView({\r\n hintText: \"Search View\",\r\n height: 150,\r\n top: 10\r\n });\r\n \r\n var button = Ti.UI.createButton({top: 100, title: \"toggle searchView\"});\r\n \r\n var num = 1;\r\n button.addEventListener('click', function(e) {\r\n if (num%3 == 1) {\r\n listView.searchView = sv2;\r\n } else if (num%3 == 2) {\r\n listView.searchView = sv3;\r\n } else {\r\n listView.searchView = sv;\r\n }\r\n num ++;\r\n });\r\n \r\n //The textfield must be a subview of the tableView to \r\n //calculate correct contentInsets when keyboard is visible. \r\n var listView = Ti.UI.createListView({searchView: sv, top: 250});\r\n listView.sections = sections;\r\n \r\n listView.addEventListener('itemclick', function(e){\r\n alert(\r\n \"ItemId: \" + e.itemId + \"\\n\" +\r\n \"BindId: \" + e.bindId + \"\\n\" +\r\n \"Section Index: \" + e.sectionIndex + \", Item Index: \" + e.itemIndex\r\n ); \r\n });\r\n \r\n var win = Ti.UI.createWindow();\r\n win.add(listView);\r\n win.add(button);\r\n win.open();\r\n{code}\r\n1. Click on 'toggle searchView' to toggle between different searchViews. Make sure the search functionality works for all searchView types.\r\n\r\n", "attachment": [], "flagged": false, "summary": "Android: Integrate ListView Search", "creator": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "environment": null, "comment": { "comments": [ { "id": "275241", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Master PR: https://github.com/appcelerator/titanium_mobile/pull/4774", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-16T00:23:06.000+0000", "updated": "2013-10-16T00:23:06.000+0000" }, { "id": "275528", "author": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "body": "keepSectionsInSearch PR: https://github.com/appcelerator/titanium_mobile/pull/4798\r\n\r\nRemove 'keepSectionsInSearch' PR: https://github.com/appcelerator/titanium_mobile/pull/4809.\r\nKS 'keepSectionsInSearch' remove PR: https://github.com/appcelerator-developer-relations/KitchenSink/pull/136\r\n\r\nHowever, section's headers and footers will hide automatically during search if there are no elements being displayed in the section.", "updateAuthor": { "name": "hpham", "key": "hpham", "displayName": "Hieu Pham", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-17T21:40:54.000+0000", "updated": "2013-10-18T21:50:34.000+0000" }, { "id": "275719", "author": { "name": "pwang", "key": "pwang", "displayName": "Ping Wang", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Reopen the ticket because for the property \"keepSectionsInSearch\", Android has a different behavior with iOS.", "updateAuthor": { "name": "pwang", "key": "pwang", "displayName": "Ping Wang", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2013-10-18T20:24:37.000+0000", "updated": "2013-10-18T20:24:37.000+0000" }, { "id": "414695", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket as fixed.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-22T00:13:04.000+0000", "updated": "2017-03-22T00:13:04.000+0000" } ], "maxResults": 4, "total": 4, "startAt": 0 } } }