Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support custom sort functions #26

Open
m-mujica opened this issue Nov 20, 2018 · 4 comments
Open

Support custom sort functions #26

m-mujica opened this issue Nov 20, 2018 · 4 comments

Comments

@m-mujica
Copy link

Sometimes you have to use a custom sort function on Lists, being unable to use this function in can-query-logic means that unexpected insertion/removals will happen when using real-time.

// sorter
function sortByName(item1, item2) {
  var val1 = item1.name.toLowerCase();
  var val2 = item2.name.toLowerCase()
 ...
}

// adding the symbol to the list
...
list.sort(sortByName);
list[canSymbol.for('can.listQuery')] = { sort: 'name' };

When real-time tries to figure where a new (or existing) item should be placed on the lists it calls getIndex which will sometimes not match the position where the instance "should be placed" based on the sortByName comparator logic.

Ideally we should be able to pass sortByName so can-query-logic can determine the position correctly.

@justinbmeyer
Copy link
Contributor

A work around would be to add additional properties like nameLowerCase on your data returned by the server and then sort by that property.

@justinbmeyer
Copy link
Contributor

justinbmeyer commented Nov 29, 2018

@m-mujica when querying, is case also ignored? Should {filter: {name: "manuel"}} match {name: "ManuEL"}? If yes, then something like this should work: https://codepen.io/justinbmeyer/pen/aQReVq?editors=0011 .... but it's not ... I'm fixing this.

@justinbmeyer
Copy link
Contributor

This works, does that solve it for you @m-mujica ?

	function StringIgnoreCaseSet(value){
		this.value = value;
	}
	StringIgnoreCaseSet.prototype.valueOf = function(){
		return this.value.toLowerCase();
	};
	canReflect.assignSymbols(StringIgnoreCaseSet.prototype,{
		"can.serialize": function(){
			return this.value;
		}
	});
	var StringIgnoreCase = canReflect.assignSymbols({},{
		"can.SetType": StringIgnoreCaseSet,
		"can.new": function(value){
			return value;
		}
	});

	var queryLogic = new QueryLogic({
		keys: {
			name: StringIgnoreCase
		},
		identity: ["id"]
	});

	var filter = queryLogic.filterMembers(
		{sort: "name"},
		[{id: 1, name: "grab coffee"},
		{id: 2, name: "finish these docs"},
		{id: 3, name: "Learn CanJS"}]
	);
	QUnit.deepEqual([
		{id: 2, name: "finish these docs"},
		{id: 1, name: "grab coffee"},
		{id: 3, name: "Learn CanJS"}
	], filter);

@m-mujica
Copy link
Author

@justinbmeyer I haven't tried this out... About the querying, yes, the casing is totally ignored.

I'lll let you know once I test your workaround. Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants