Combat skill/item filter

Schik

New member
I like the combat bar but using skills and items that you haven't dragged to their own buttons is slower to use - with the old style, I just start typing it and go to the right element in the listbox.

So I made this simple relay script to add a filter to the drop-down combat bar skills & items. At the top of the list, a textbox is added. When you type in it, the list gets filtered to only show things that match your text.
Without a filter:
no-filter.jpg
With a filter:
divine-filter.jpg

You can grab it via:
Code:
svn checkout https://svn.code.sf.net/p/kolcombatfilter/code/trunk/combatfilter/

It's pretty small but I guess I should document how to use it:
- When you click on either the skill or item button, focus will automatically go to the filter textbox.
- Type stuff in the filter textbox, and the skill/items list will filter as you type.
- Press ESC to quickly clear the textbox (this didn't work in Opera, but does work in IE, Chrome, & FF)
 
Last edited:

Winterbay

Active member
Oh...You've made my new favourite script I think. I need to test it when I get back to my computer in a week but otherwise :)
 

roippi

Developer
Pretty cool. I didn't even know KoL imports jquery.

This is the sort of thing that we can talk about absorbing into mafia itself, with author permission. It's clear that you are more talented than I at JS/jquery, so a couple of suggestions from looking at the source briefly:

Code:
			var skills = $(this).parent().parent().children('a');
			$.each(skills, function(i, skill) {
				var el = $(skill).children('span')[0];
			...stuff...

This could probably be simplified/beautified with $(this).parentsUntil('div').filter(function(...))

Or .parent().siblings('a') or somesuch. I'd have to look at the DOM.

<snip>

Heh, I had more stuff here but then I realized that I misread your indentation and thought you were running things on an event loop. Or maybe I mistook setTimeout for setInterval. Not sure.

I do think it is a bit strange that you are attaching your event listener to keyup instead of change(), but maybe that is for some weird browser compatibility issue? Or maybe because you're already messing with key event propagation with the keydown() stuff so that interferes with change()... I dunno, javascript makes me itchy sometimes.

I think this is a fantastic idea for a widget, one that even native kol should probably have.
 
Last edited:

Bale

Minion
That might be a new high water mark for someone's first post on this forum.


This is the sort of thing that we can talk about absorbing into mafia itself, with author permission.

Wow. His first post and you're talking about adapting it for KoLmafia. I have wanted this for ages, so I cannot disagree with your enthusiasm. Honestly this should be part of KoL! A legend is born.
 
Last edited:

Schik

New member
Wow. Thanks for all the feedback, guys!

By all means, feel free to take whatever you like and change whatever you don't and add it to mafia, I would be honored. :)

You're right about the changes, I did this over a couple hours and was a bit impatient and wanted to get a first version out there.

Edit: @roippi - Didn't see those edits. change only fires when an input loses focus. Modern browsers can use the 'input' event, and it would be better than keyup as it would catch pastes and things like that. I'm not sure offhand what versions of various browsers started supporting input.

The setTimeouts are a little sloppy, but they were a quick fix for a couple annoying problems.
 
Last edited:

roippi

Developer
You're right about the changes, I did this over a couple hours and was a bit impatient and wanted to get a first version out there.

Hey, that's agile software. Ship product as soon as it works, then iterate.

One other optimization:

Code:
				var el = $(skill).children('span')[0];
				el = el.textContent||el.innerText;

jquery's .text() standardizes the cross-compatibility thing between IE/mozilla so you can just use that, I think.
 

zarqon

Well-known member
This looks great. Is this compatible with BatMan RE? If not, I can do an svn_exists check and import the important bits. I'll look into it.
 

zarqon

Well-known member
I have an idea. Will PM you.

ETA: My idea was an "idea had on the bus". I've gotta learn to stop treating bus ideas as equally valid as home ideas. I may PM you at some point, but not about that idea.
 
Last edited:

Schik

New member
I committed a small update. The only thing that users will notice is the filter text is selected when the menu pops up, so you can just start typing to start a new filter.

Other than that, I did a little code cleanup and commenting and changed the events a bit - I now only grab keydown and keyup to avoid global handlers when you press numbers or backspace, and to handle clearing the filter by ESC.

There's a second regex in there that is not used by default, a loose one that inserts ".*" between every pair of characters in your filter, so for instance "divpop" would find "divine champagne popper". If you want to try it, look for looseRegex in combatfilter.js and change it to true. I'm not sure what I think of it so I didn't turn it on by default.

The setTimeouts are still there. On initialization, the menu items haven't been created yet, so applying the default filter can't work. The other setTimeouts are for setting focus when the menu is opened, same deal - I can't set the focus there until the menu shows up. The non-setTimeout way to do it would be to set event handlers to watch the DOM for these elements changing, or for CDMoyer to add some of this logic to actionbar.<version>.js. Bleh.
 

roippi

Developer
I had a go at adding an 'x' clickybutton to visually indicate that the field can be cleared. I like having visual cues that people are familiar with.

My css-fu is weak; it looks okay in firefox but I'm sure it's off in chrome/opera. Damn you position:absolute. Basically I ran out of time to mess around with this today, not sure when I'll have more. Busy traveling.

Code:
Index: combatfilter.js
===================================================================
--- combatfilter.js	(revision 4)
+++ combatfilter.js	(working copy)
@@ -12,11 +12,29 @@
 		}
 	}
 	function AddFilter($div) {
-		var $filter = $("<div>").addClass('filter');
-		var $input = $("<input>").attr({type: 'text'}).css({width: '100%', 'margin-bottom': '0px'});
-		$div.prepend($filter);
-		$filter.append($input);
+		var $in1 = $('<input>')
+			.addClass('buttoned')
+			.attr({type: 'text'})
+			.css({'width': '100%', 'margin-bottom': '0px','padding-right':'16px'});
+		$div.prepend($in1);
 
+		$in1.wrap('<div class="filter" />')
+			.after($('<span class="xbutton" />'));
+
+		$('.xbutton').css({
+			'position':'absolute',
+			'display': 'block',
+                	'top': '4px',
+                	'right': '0px',
+                	'width': '16px',
+                	'height': '16px',
+                	'background': 'url("http://cdn.sstatic.net/stackoverflow/img/sprites.png?v=4") 0 -690px',
+                	'cursor': 'pointer'
+		}).click(function() {	
+		    	$(this).prev('input').val('').triggerHandler('input');
+		});
+
+		var $input = $('input.buttoned');
 		$input.keydown(function(ev) {
 			// Make global keyhandlers (like #s for combat actions) not fire if you're focused
 			// on the filter textbox
@@ -52,6 +70,7 @@
 				var el = $(skill).children('span').text();
 				$(skill).css('display', regex.test(el) ? 'block' : 'none');
 			});
+			$('.xbutton').css('display', text === '' ? 'none' : 'block');
 		}));
 		$input.val(GetStorage($div.attr('id')));
 
@@ -80,3 +99,4 @@
 	});
 
 });
+
 

Bale

Minion
This is my new favorite script.

I committed a small update. The only thing that users will notice is the filter text is selected when the menu pops up, so you can just start typing to start a new filter.

You also fixed escape clearing the text field for Opera. Yay!
 

Schik

New member
I had a go at adding an 'x' clickybutton to visually indicate that the field can be cleared. I like having visual cues that people are familiar with.

My css-fu is weak; it looks okay in firefox but I'm sure it's off in chrome/opera. Damn you position:absolute. Basically I ran out of time to mess around with this today, not sure when I'll have more. Busy traveling.
Hot damn, nice! I made a minor change, the <input> padding is now 0 everywhere, and your button lines up great on 4 browsers. Sourceforge is having issues right now, as soon as I can I'll commit the change. Thanks for the patch!

You also fixed escape clearing the text field for Opera. Yay!
Oh yeah, switching around the events seemed to help with that. I thought it was still flaky though, but if it's working for you, then great!
 

roippi

Developer
Hot damn, nice! I made a minor change, the <input> padding is now 0 everywhere, and your button lines up great on 4 browsers. Sourceforge is having issues right now, as soon as I can I'll commit the change. Thanks for the patch!

Nice.

Embarrasingly, I forgot that there were two filter fields and that my jquery selections would be a little too greedy. I see that you fixed one of them but there's a couple other ones.

Code:
Index: combatfilter.js
===================================================================
--- combatfilter.js	(revision 5)
+++ combatfilter.js	(working copy)
@@ -34,7 +34,7 @@
 			$(this).prev('input').val('').triggerHandler('input');
 		});
 
-		var $input = $('input.buttoned');
+		var $input = $div.find('input');
 		$input.keydown(function(ev) {
 			// Make global keyhandlers (like #s for combat actions) not fire if you're focused
 			// on the filter textbox
@@ -69,7 +69,7 @@
 				var el = $(skill).children('span').text();
 				$(skill).css('display', regex.test(el) ? 'block' : 'none');
 			});
-			$('.xbutton').css('display', text === '' ? 'none' : 'block');
+			$input.next('.xbutton').css('display', text === '' ? 'none' : 'block');
 		}));
 		$input.val(GetStorage($div.attr('id')));
 

Schik

New member
Oops. Nice catch, fix applied & checked in. I think I only tested one of the dropdowns so I didn't notice anything weird.
 

slyz

Developer
Really great override. I don't know how flexible TPTB are about feature requests, but this would probably be a nice addition to vanilla KoL.
 
Top