Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Reply
Developer
Posts: 111
Registered: ‎07-05-2012
My Device: none
My Carrier: MOvistar

BB10: How To Implement a List Filter Search

Hi everyone,

 

I need to create a top bar with a text field used for searching. Below that bar has to be a list of items.

 

I need that when the user starts typing letters in the search text field, the items in the list immediately get filtered according to what the user has entered. The point is that the items left in the list has to have, in their name attibutes, the word the user has entered so far.

 

Any idea about how to do this?

 

Thanks!

Developer
Posts: 71
Registered: ‎09-19-2012
My Device: Z10 very soon
My Carrier: Play

Re: BB10: How To Implement a List Filter Search

Did you consider DataSource class ?

 

DataSource {
      id: dataSource
      source: "sql/contacts1k.db"
      query: "select * from contact order by firstname, lastname"
      onDataLoaded: {
        dataModel.insertList(data);
      }
}
Developer
Posts: 111
Registered: ‎07-05-2012
My Device: none
My Carrier: MOvistar

Re: BB10: How To Implement a List Filter Search

Thanks igosoft,

 

looks like it could work. But I don't have a database. Maybe I could create a XML and use it as a the source of the DataSource. But what I have is a QListDataModel full of items.

 

As I can see, you cannot do this type if query (select * from BLAH ...) to a XML source, but just to a database (.db).

 

Any idea?

Developer
Posts: 103
Registered: ‎12-31-2012
My Device: Blackberry 9810
My Carrier: Verizon

Re: BB10: How To Implement a List Filter Search

This can be achieved by using a duplicate data model for sorting the listview.  The primary data model(primaryDtMdl) is iterated and each value that matches the criteria is added to a duplicate datatmodel(dupDtMdl), which is then set as the new datamodel for the listView.

 

See the code below:

CPP file

// Default empty project template
#include "MyQLstDataMdlWithSearch.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/ListView>
#include <bb/cascades/TextField>
#include <bb/cascades/QListDataModel>
#include <qstring.h>
using namespace bb::cascades;

MyQLstDataMdlWithSearch::MyQLstDataMdlWithSearch(bb::cascades::Application *app)
: QObject(app)
{
    // create scene document from main.qml asset
    // set parent to created document to ensure it exists for the whole application lifetime
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // create root object for the UI
    AbstractPane *root = qml->createRootObject<AbstractPane>();
    // set created root object as a scene
    app->setScene(root);

    dupDtMdl = new QListDataModel<QString>();

    primaryDtMdl = new QListDataModel<QString>();

    primaryDtMdl->append("Alpha");
    primaryDtMdl->append("Anthem");
    primaryDtMdl->append("Antonio");
    primaryDtMdl->append("Beta");

   TextField* txtFld = root->findChild<TextField*>("txtSrch");
   lv = root->findChild<ListView*>("lstVw");
   lv->setDataModel(primaryDtMdl);

    connect(txtFld,SIGNAL(textChanging(QString)),this,SLOT(filterDataModel(QString)));
}

void MyQLstDataMdlWithSearch::filterDataModel(QString txt)
{
	dupDtMdl->clear();

    for(int i =0; i<primaryDtMdl->size(); i++)
	   {
	      QString var = primaryDtMdl->value(i);
		  qDebug()<<var;
		  if(var.contains(txt, Qt::CaseInsensitive))
			  dupDtMdl->append(var);
	   }

	   lv->setDataModel(dupDtMdl);
}

 

My Qml file

// Default empty project template
import bb.cascades 1.0

// creates one page with a label
Page {
    Container {
     layout: StackLayout {}
      TextField {
          id: txtSrch
          objectName: "txtSrch";
      }
      ListView {
          id: lstVw
          objectName: "lstVw"
      }
      
    }
}

 

 

- Dishooom

 

Hope this helps

Developer
Posts: 71
Registered: ‎09-19-2012
My Device: Z10 very soon
My Carrier: Play

Re: BB10: How To Implement a List Filter Search

@

dupDtMdl->clear();

Developer
Posts: 103
Registered: ‎12-31-2012
My Device: Blackberry 9810
My Carrier: Verizon

Re: BB10: How To Implement a List Filter Search

[ Edited ]

 

Thanks igosoft. Smiley Happy

 

The reason why i stuck with

dupDtMdl->clear();

is because:

 

Its not always a case of

Developer
Posts: 71
Registered: ‎09-19-2012
My Device: Z10 very soon
My Carrier: Play

Re: BB10: How To Implement a List Filter Search

you are right in some areas but please keep remember that for most of the people UX is more important then how easy it was to develop a feature. Smiley Happy

 

Developer
Posts: 111
Registered: ‎07-05-2012
My Device: none
My Carrier: MOvistar

Re: BB10: How To Implement a List Filter Search

[ Edited ]

Thanks a lot igosoft and dishoom!

 

dishoom, I think I'll try your solution and then I'll let you know how it went.

 

Mixing:

I think we could easly mix what igosoft proposed with dishoom solution. You could save the last text changed. When the user change the text again you can check if the last text is contained in the new one. If so, do not clear the 2nd list and just remove from it the items that don't satisfy. Otherwise, clear the 2nd list and do the checking again by using the whole 1st list.

 

Thanks again dishoom. It's good to know a solution that works and somebody else already tried.

Developer
Posts: 71
Registered: ‎09-19-2012
My Device: Z10 very soon
My Carrier: Play

Re: BB10: How To Implement a List Filter Search

I agree. It's easy to combine to points of view Smiley Happy into excelent funcionality. Good luck!

Developer
Posts: 103
Registered: ‎12-31-2012
My Device: Blackberry 9810
My Carrier: Verizon

Re: BB10: How To Implement a List Filter Search

Buy your point igosoft, there were issues when i was using delete Datamodel....  

 

@joukel : i hav a new solution... posted below , using just one data model and appending and removing  new values to the already existing datamodel .... Since we had started with a QListDataModel, i had to carry out an additional bubblesort as well as towards the end to get the values in place....

 

 

// Default empty project template
#include "MyQLstDataMdlWithSearch.hpp"

#include <bb/cascades/Application>
#include <bb/cascades/QmlDocument>
#include <bb/cascades/AbstractPane>
#include <bb/cascades/ListView>
#include <bb/cascades/TextField>
#include <bb/cascades/QListDataModel>

using namespace bb::cascades;

MyQLstDataMdlWithSearch::MyQLstDataMdlWithSearch(bb::cascades::Application *app)
: QObject(app)
{
    // create scene document from main.qml asset
    // set parent to created document to ensure it exists for the whole application lifetime
    QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);

    // create root object for the UI
    AbstractPane *root = qml->createRootObject<AbstractPane>();
    // set created root object as a scene
    app->setScene(root);


    primaryDtMdl = new QListDataModel<QString>();

    primaryDtMdl->append("Alpha");
    primaryDtMdl->append("Anthem");
    primaryDtMdl->append("Antonio");
    primaryDtMdl->append("Beta");
    primaryDtMdl->append("Camel");
    primaryDtMdl->append("Cat");
    primaryDtMdl->append("Catherine");
    primaryDtMdl->append("Cathy");


   TextField* txtFld = root->findChild<TextField*>("txtSrch");
   lv = root->findChild<ListView*>("lstVw");

   lv->setDataModel(primaryDtMdl);

   entireList = new QStringList();

   for(int i=0; i<primaryDtMdl->size();i++)
   {
	   entireList->append(primaryDtMdl->value(i));
   }

    connect(txtFld,SIGNAL(textChanging(QString)),this,SLOT(filterDataModel(QString)));
}

void MyQLstDataMdlWithSearch::filterDataModel(QString txt)
{
	QStringList* tempList = new QStringList();
	QList<int> toBeDeletedNodes;
	for(int i = 0; i<entireList->size();i++)
	{
		QString var = entireList->at(i);
		if(var.contains(txt, Qt::CaseInsensitive))
			{tempList->append(var);
			}
	}

	//Deletion

	for(int i = 0; i<primaryDtMdl->size();i++)
	{
		QString var = primaryDtMdl->value(i);
		bool flagTobeDeleted = true;
		 for(int j = 0; j<tempList->length(); j++)
		 {
			 if(tempList->at(j).compare(var)==0)
			 {
				 flagTobeDeleted = false;
				 break;
			 }
		 }

		 if(flagTobeDeleted)
			 {
			   toBeDeletedNodes.append(i);
			 }
	}

	for(int i = 0; i < toBeDeletedNodes.size(); i++)
		{   primaryDtMdl->removeAt(toBeDeletedNodes.value(i) - i);
		}

	//Append.
	for(int i = 0; i<tempList->length();i++)
		{
		QString var = tempList->at(i);
		 bool flagTobeAppended = true;
		for(int j = 0; j<primaryDtMdl->size(); j++)
				 {
					 if(primaryDtMdl->value(j).compare(var)==0)
					 {
						 flagTobeAppended = false;
						 break;
					 }
				 }
		if(flagTobeAppended)
		  primaryDtMdl->append(var);
		}

//Sort
	int n = primaryDtMdl->size();
	for(int i=0;i<n-1;i++)
	{
		for(int j=0;j<n-i;j++)
			{
				if(!(primaryDtMdl->value(j).compare(primaryDtMdl->value(j+1))<0))
					{
						primaryDtMdl->swap(j,j+1);
					}
			}
	}

	delete tempList;
}

 

 

Let me know if u hav any issues.. Smiley Happy

 

-Dishooom

 

Hope this helps