Cool RapidSearch Technique

Contrary to my typical approach towards making things as perfect as I can, I wanted to share one of my recent techniques that makes searching a dream come true. The video file size is a bit big because I forgot to reduce my monitor resolution (even though I shot at 800X600)

About a 12 minute video on a technique I am using for searching. Enjoy

http://www.mattstemplates.com/videos/RapidSearch.mov

QuickTime required

P.S. Yes, I know I mixed up the “begins with” and “ends with” SQL search criteria.

mattman:
The video file size is a bit big because…

Way to go, Matt :!:
The size can’t be bigg enough :wink:

Thanks,
Bert

Matt,

WHOA!! :D

AWESOME job! Thanks for sharing your cool technique!

Bob Cusick

Bravo, Matt!

That video finally gave me a functional understanding of text searches that I’ve been fighting with for #%awhile now%

Super stuff!

dave

VERY cool indeed! 8)

Thank you matt. Very nice looking and a good idea to share!

Aren’t the Academy Awards coming. My vote is on you.

Thanks for contributing

Hello Matt,
I did some research in my own solution, and saw that I already used this kind of technique too!

you can even do it in one (total) method, without jumping from one form to another form, to call all kinds of methods.

You can put before
controller.find() and
controller.search()

the form name, like this:
forms.formname.controller.search()

So you can do a quick search in one method!

HJK:
…you can even do it in one (total) method, without jumping from one form to another form, to call all kinds of methods.

You can put before
controller.find() and
controller.search()

the form name, like this:
forms.formname.controller.search()

So you can do a quick search in one method!

That’s for the next lesson. :D Explaining the object model is important in knowing how to reference objects when you haven’t worked with them before. I’m counting on yourself and Maarten and others to teach me so I can teach others.

I didn’t want to scare off newer developers by telling them they can program their whole solution using global methods. .

Of course those of us who know, know that a local method using my.controller.search() will be more flexible than a hardcoded forms.formname.controller.search() because it’s not an absolute reference. But we can talk about coding styles and functional relevance in another thread. :wink:

If you guys have cool techniques you come up with that explain how things work then send me the ideas!

Anonymous:

HJK:
…you can even do it in one (total) method, without jumping from one form to another form, to call all kinds of methods.

You can put before
controller.find() and
controller.search()

the form name, like this:
forms.formname.controller.search()

So you can do a quick search in one method!

That’s for the next lesson. :D Explaining the object model is important in knowing how to reference objects when you haven’t worked with them before. I’m counting on yourself and Maarten and others to teach me so I can teach others.

I didn’t want to scare off newer developers by telling them they can program their whole solution using global methods. .

Of course those of us who know, know that a local method using my.controller.search() will be more flexible than a hardcoded forms.formname.controller.search() because it’s not an absolute reference. But we can talk about coding styles and functional relevance in another thread. :wink:

If you guys have cool techniques you come up with that explain how things work then send me the ideas!

Oops, forgot to log in… that was me replying. :D

Finally sat down to watch this – very good stuff, thx.

  • david

First of all, this is awsome. Implemented it myself in a matter of minutes and love it. Added two more search fields and made it a global method; now works for all my forms :D

Now, I’ve ran into a little trouble. I added some more fields to the list and wamm!!! it doesn’t like number or date fields.

Is there a way we could find out the field’s data type during the method?

Was really excited to see this video because I want a Google-like search on most pages of my solution, however the video URL no longer works.

Any help much appreciated.

Here’s some sample code from some early training materials we have laying around. Can run something like this:

[attachment=0]Picture 50.png[/attachment]

Pretty standard stuff these days that you see many developers doing. It doesn’t conform to Servoy 5’s best practices for passing parameters around but should be enough ideas to get you started.

/*
 *	Global method to run a search
 *	Input: 	object with properties: columnName, columnType, findName, relation, valuelist 
 *	
 *	Requires several other global methods to function correctly
**/

	/****
		1. setup
	****/
	
	//control variables
	var baseForm = ''	//name of the top-level form
	var formName = ''	//name of the form we are searching on
	var keyPressed = (arguments[1] != undefined) ? arguments[1] : globals.CODE_key_pressed()
	
	//search variables
	var colName = arguments[0].columnName
	var colType = arguments[0].columnType
	var findName = arguments[0].findName
	var relation = arguments[0].relation
	var valuelist = arguments[0].valuelist
	var searchValue = globals.FRAMEWORKS_find
	
	//current foundset
	var initialFS = forms[formName].foundset.duplicateFoundSet()
	
	var serverName = forms[formName].controller.getServerName()
	var tableName = forms[formName].controller.getTableName()
	
	//if an omit request, get the table object to find array of PKs
	if (keyPressed && keyPressed == 8) {
		var jsTable = databaseManager.getTable(forms[formName].foundset)
		var pkCols = jsTable.getRowIdentifierColumnNames()
		
		//MEMO: does not account for multiple primary keys on a table
		var primaryKey = pkCols[0]
		if (primaryKey) {
			var originalIDs = databaseManager.getFoundSetDataProviderAsArray(forms[formName].foundset,primaryKey)
		}
	}
	
	
	/****
		2. find
	****/
	
	//show date picker
	if (colType == "DATETIME" && searchValue == null) {
		forms.DATE_P_solution.FrameworksFastFind = true
		application.showFormInDialog(forms.DATE_P_solution,-1,-1,-1,-1,"Search",false)
	}
	
	//if no value to search for, quit
	if (searchValue == null) {
		return
	}
	
	//begin find
	forms[formName].controller.find()

	
	//add find request
		//Fx method returns break if this method should stop
	if (globals.FIND_search_request(formName,relation,colName,colType,searchValue) == 'break') {
		return
	}
	
	//perform search
	if (keyPressed == 1) { //shift for extend
		var count = forms[formName].controller.search(false, true)

		//LOG find
		globals.CALLBACK_create_log('Fast finds',
							serverName,
							tableName,
							'Extend',
							relation,
							colName,
							searchValue,
							count
							)
	}
	else if (keyPressed == 2) { //control for reduce
		var count = forms[formName].controller.search(false, false)
		
		//LOG find
		globals.CALLBACK_create_log('Fast finds',
							serverName,
							tableName,
							'Reduce',
							relation,
							colName,
							searchValue,
							count
							)
	}
	else if (keyPressed == 8) { //option/alt for omit
		var count = forms[formName].controller.search()
		var omitIDs = databaseManager.getFoundSetDataProviderAsArray(forms[formName].foundset,primaryKey)
		
		var flag = 0
		var tempPKs = new Array()
		
		//loop through originalIDs
		for ( var z = 0 ; z < originalIDs.length ; z++ ) {		
			//loop through omitIDs and remove from originalIDs
			var j = 0
			while (omitIDs[j] <= originalIDs[z] ) {
				if (omitIDs[j] == originalIDs[z]) {
					flag = 1
					omitIDs.shift()
				}
				j ++	
			}
			if (!flag) {
				tempPKs.push(originalIDs[z])
			}
			
			//reset values for next loop
			flag = 0					
		}
		
		//load tempPKs
		var loadSet = databaseManager.convertToDataSet(tempPKs)
		forms[formName].controller.loadRecords(loadSet)

		//LOG find
		globals.CALLBACK_create_log('Fast finds',
							serverName,
							tableName,
							'Omit',
							relation,
							colName,
							searchValue,
							count
							)
	}
	else {
		var count = forms[formName].controller.search()

		//LOG find
		globals.CALLBACK_create_log('Fast finds',
							serverName,
							tableName,
							'Normal',
							relation,
							colName,
							searchValue,
							count
							)
	}
	
	if (count == 0) {
		if (!dlgTitle) {
			var dlgTitle = 'Error searching'
		}
		
		//if a valuelist, get real value for passed display value
		if (valuelist) {
			var valuelist = application.getValueListDisplayValue(valuelist,searchValue)
		}
		
		plugins.dialogs.showWarningDialog(dlgTitle, '<html><body>No records found for <strong>"'+searchValue+'"</strong>'+' while searching in <strong>'+findName+'</strong> field</body></html>','OK')
		forms[formName].controller.loadRecords(initialFS)
	}
	
}
/*
 *	TITLE    :	FIND_search_request
 *			  	
 *	MODULE   :	fw_NAV_engine
 *			  	
 *	ABOUT    :	adds a find request to the stack
 *			  	
 *	INPUT    :	1) name of form in workflow area
 *			  	2) relation name
 *			  	3) name of column
 *			  	4) type of column
 *			  	5) value to search
 *			  	6) create a new find request (optional)
 *			  	
 *	OUTPUT   :	'break' if column searched on is media or showall
 *			  	
 *	REQUIRES :	
 *			  	
 *	MODIFIED :	Apr 16, 2008 -- Troy Elliott, Data Mosaic
 *			  	
 */

var formName = arguments[0]
var relation = (arguments[1] == 'NONE') ? false : arguments[1]
var colName = arguments[2]
var colType = arguments[3]
var searchValue = arguments[4]
var newRecord = arguments[5]

//add new request
if (newRecord && colType != 'SHOWALL' && colType != 'MEDIA') {
	forms[formName].controller.newRecord()
}

//add request to search by
switch (colType) {
		case "TEXT":
					var prefix = ''
					var suffix = ''
					var dlgTitle
					var wildChar = '#'
					var start = false
					var end = false
					
					//only look for characters if a text field
					if (typeof searchValue == 'string') {
						//is first character the control one?
						if (searchValue.charAt(0) == wildChar) {
							start = true
							searchValue = searchValue.slice(1)
						}
						//is last character the control one?
						if (searchValue.charAt(searchValue.length-1) == wildChar) {
							end = true
							searchValue = searchValue.slice(0,searchValue.length-1)
						}
					}
					
					//exact match
					if (start && end) {
						dlgTitle = 'Searching for exact value'
					}
					//starts with
					else if (start) {
						suffix += '%'
						dlgTitle = 'Searching at beginning of field'
					}
					//ends with
					else if (end) {
						prefix += '%'
						dlgTitle = 'Searching at end of field'
					}
					//contains
					else {
						prefix += '#%'
						suffix += '%'
						dlgTitle = 'Searching anywhere in field'
					}
					
					if (relation) {
						forms[formName][relation][colName] = prefix + searchValue + suffix
					}
					else {
						forms[formName][colName] = prefix + searchValue + suffix
					}
					break
					
		case "INTEGER":
					if (relation) {
						forms[formName][relation][colName] = searchValue
					}
					else {
						forms[formName][colName] = searchValue
					}
					break
					
		case "NUMBER":
					if (relation) {
						forms[formName][relation][colName] = searchValue
					}
					else {
						forms[formName][colName] = searchValue
					}
					break
					
		case "DATETIME":
					//get default format for dates
					var defaultFormat = 'M-d-yyyy'
					
					//if no mask, apply default one
					if (utils.stringPosition(searchValue,'|',1,1) != -1) {
						if (relation) {
							forms[formName][relation][colName] = searchValue
						}
						else {
							forms[formName][colName] = searchValue
						}
					}
					else {
						if (relation) {
							forms[formName][relation][colName] = searchValue + '|' + defaultFormat
						}
						else {
							forms[formName][colName] = searchValue + '|' + defaultFormat
						}
					}
					break
					
		case "MEDIA":
					return 'break'
					break

		case "SHOWALL":
					forms[formName].controller.loadAllRecords()
					return 'break'
					break
}

Picture 50.png

BulldogBen:
Was really excited to see this video because I want a Google-like search on most pages of my solution, however the video URL no longer works.

Vintage 2003, but still great stuff. Big file (24.4MB) - still worth the download. QuickTime required. Hope Matt is okay with this replacement link. He did a great job putting together this little movie that has withstood the test of time.
Try this: http://72.74.82.2/RapidSearch.mov

Ah, that URL worked, thanks so much.

It’s actually pretty simple to follow, I feel like I’m just starting to get some traction with Servoy. I’m really excited about what it will able to do for my company(s).