I used the Scriptaculous autocompleter with a set of custom extend
functions to filter table rows, <tr> tags, by a class name with some
custom attributes. There is quite a bit of code below, so contact me
if you need a more detailed walk-through. I can be reached in
evenings, by usually calling your mother, who i may or may not have
been banging. I love her stories.. or, probably more often by Gchat!!
Javascript looks like this:
Searcher = {
selector : function ( instance ) {
try {
var ret = [];
var partial = [];
var entry = instance.getToken ();
var count = 0;
for (var i = 0; i < instance.options.array.length &&
ret.length
< instance.options.choices; i++) {
var itemLabel = instance.options.array [ i ].label;
var itemValue = instance.options.array [ i ].val;
var itemId = instance.options.array [ i ].itemId;
var foundPos = instance.options.ignoreCase ?
itemLabel.toLowerCase().indexOf(entry.toLowerCase()) :
itemLabel.indexOf(entry);
while (foundPos != -1) {
if (foundPos == 0 && itemLabel.length !=
entry.length) {
var li = '<li item-id="' + itemId +
'" item-value="' +
itemValue + '">';
li += '<strong>' +
itemLabel.substr(0, entry.length) + '</
strong>';
li +=
itemLabel.substr(entry.length);
li += '</li>';
ret.push(li);
break;
} else if (entry.length >=
instance.options.partialChars &&
instance.options.partialSearch && foundPos != -1) {
if (instance.options.fullSearch || /
\s/.test(itemLabel.substr(foundPos-1,1))) {
var li = '<li item-id="' +
itemId + '" item-value="' +
itemValue + '">';
li += itemLabel.substr(0,
foundPos) + '<strong>' +
itemLabel.substr(foundPos, entry.length) + '</strong>' +
itemLabel.substr( foundPos + entry.length);
li += '</li>';
partial.push(li);
break;
}
}
foundPos = instance.options.ignoreCase ?
itemLabel.toLowerCase().indexOf(entry.toLowerCase(), foundPos
+ 1) :
itemLabel.indexOf(entry, foundPos + 1);
}
}
if ( partial.length ) {
ret = ret.concat ( partial.slice ( 0,
instance.options.choices
- ret.length ) );
} else {
Searcher.hideItems ( '' );
}
if ( ret.length == 0 ) {
Searcher.hideItems ( '' );
}
return "<ul>" + ret.join ( '' ) + "</ul>";
} catch ( e ) { alert ( e ); }
},
render: function () {
try {
if ( this.entryCount > 0 ) {
for ( var i = 0; i < this.entryCount; i++ ) {
this.index == i ? Element.addClassName (
this.getEntry ( i ),
'selected' ) : Element.removeClassName ( this.getEntry ( i ),
'selected' );
}
if( this.hasFocus ) {
this.show ();
this.active = true;
Searcher.showList ( this );
}
} else {
this.active = false;
this.hide ( '' );
Searcher.hideItems ( '' );
}
} catch ( e ) { alert ( 'Error in render: ' + e ); }
},
showList : function ( instance ) {
try {
Searcher.hideItems ( '.open' );
var listItems = $$ ( '#item-searcher-list li' );
listItems.each ( function ( listItem ) {
var variationId = listItem.readAttribute (
'item-value' );
listItem.addClassName('open');
listItem.show ();
$ ( 'list-item-' + variationId ).show ();
});
} catch ( e ) { alert ( 'Error in showList: ' + e ); }
},
hideItems : function ( slctr ) {
var listItems = $$ ( '.searcher-list-item' );
listItems.each(function(listItem) {
listItem.removeClassName('open');
listItem.hide ();
});
},
afterUpdate : function ( inputEl, selectedEl ) {
try {
Searcher.hideItems ( '' );
var variationId = selectedEl.readAttribute ( 'item-value' );
var listItem = $ ( 'list-item-' + variationId );
listItem.addClassName ( 'open' );
listItem.show ();
} catch ( e ) { alert ( 'Error in afterUpdate: ' + e ); }
},
selectCustomer : function ( inputEl, selectedEl ) {
var itemId = selectedEl.readAttribute ( 'item-value' );
window.location.href = 'my-shizzle.aspx?customer-id=' + itemId;
}
};
Sample HTML looks like this:
<label for="item-searcher">Find a Customer by Name or Email</label>
<input id="item-searcher" name="item-searcher" class="searcher-input"
type="text" />
<div id="item-searcher-list" class="item-searcher-list"
style="display:none;"></div>
<table class="table" width="100%" cellspacing="0">
<table>
<tr class="head">
<td>Customer Name</td>
<td>Email</td>
<td>Signup Date</td>
<td>Actions</td>
</tr>
<tr id="list-item-ee25e25d-761e-4a63-9ce5-3446d988b93f"
class="searcher-list-item open even">
<td><a href="customer.aspx?id=123xxx">Sasha Gray</a></td>
<td>[email protected]</td>
<td>Wednesday, April 7, 10:22 AM</td>
<td><a href="edit.aspx?id=123xxx">Edit</a></td>
</tr>
</table>
I didn't set it up to read the table rows per say, instead i looped
through my customer database and created a javascript array when
instantiating the autocompleter:
<script type="text/javascript">
var itemList = [
{ itemId : '', val : '<xsl:value-of select="Id" />', label :
'Sasha
Gray - [email protected]' },
{ itemId : '', val : '<xsl:value-of select="Id" />', label :
'Pill
Popper 2 - i<[email protected]' }
];
var searcher = new Autocompleter.Local ( 'item-searcher', 'item-
searcher-list', itemList, {
partialSearch : true,
fullSearch : true,
selector : Searcher.selector,
afterUpdateElement : Searcher.selectCustomer
});
searcher.render = Searcher.render;
</script>
On Apr 6, 7:44 am, Shinkan <[email protected]> wrote:
> Hi everyone,
>
> I'm brand new to Prototype JS.
> I just made use of it to create a basic function which can filter
> table lines (show/hide) according to a column text search.
>
> My first impression is that IE is dozens times slower than FF for this
> thing.
> As I'm new to Prototype, and that my code doesn't seem beautiful at
> all (pretty basic thinking), I wonder if there would be a way to
> "prototipize" it more, so that is would be more efficient and less
> ugly.
> Thanks for any advice that will make me learn Prototype and make my
> code faster.
>
> Here is the excerpt :
>
> field_filter = function(nam, val) {
> var lines = $$("#annuaire_table > div > table > tbody > tr");
> // Gather cells that have our target column name as class :
> they are cells of our current filtering column.
> // IS THERE ANY WAY TO GET THAT FROM "lines" DIRECTLY ?
> instead of traversing DOM once again ?
> var ourcells = $$("#annuaire_table > div > table > tbody > tr> ."+nam)
>
> // Removing previous search results : search results are made
> of class changes.
> ourcells.each( function(i) {
> i.removeClassName("highlight");
> i.removeClassName("hide");
> } );
> // If our filter value is not empty...
> if( val.length > 0 )
> {
> // We partition our column's cells in 2 parts.
> var rtab = ourcells.partition( function(i) {
> i.cleanWhitespace();
> // Those which have a text content matching our search.
> if( i.empty() != true )
> {
> return ((i.textContent || i.innerText ||
> "").toLowerCase().indexOf(val.toLowerCase()) >= 0);
> }
> // Those which don't.
> return false;
> } );
> var containstext = rtab[0];
> var notcontainstext = rtab[1];
> // We add "highlight" class to cells we care about (matching
> search cells).
> containstext.each( function(j)
> { j.addClassName("highlight"); } );
> // We add "hide" class to others.
> notcontainstext.each( function(j)
> { j.addClassName("hide"); } );
> }
> // We hide every table line which has a cell with "hide"
> class.
> lines.each( function(i) {
> var childcells = i.childElements();
> if( childcells.detect( function(j) { return
> j.hasClassName("hide"); } ) )
> {
> i.hide();
> }
> else
> {
> i.show();
> }
> } );
> // THEN, IS THERE ANY WAY TO FIND TABLES WHERE ALL LINES ARE
> HIDDEN ?
> };
>
> Many thanks in advance.
--
You received this message because you are subscribed to the Google Groups
"Prototype & script.aculo.us" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/prototype-scriptaculous?hl=en.