matteodem / meteor-easy-search

Easy-to-use search for Meteor with Blaze Components
MIT License
435 stars 68 forks source link

How to search on composite fields #493

Closed matteodem closed 7 years ago

matteodem commented 8 years ago

For example with a full name, see #490

jasonnmark commented 8 years ago

This is great. I've been trying to build a composite field, but choking so an example would be super helpful. I tried AutoValue (Components/Simple Schema) but can only get that to work if all fields that are being composited are part of every form submit, so I tried using collection hooks, but after.update won't update and before.update composites the wrong info: https://github.com/matb33/meteor-collection-hooks/issues/186#issuecomment-215975214

I see that this issues is tagged "docs" but I don't see any associated docs. Please let me know if I missed anything, and thanks again for your help!

matteodem commented 8 years ago

The tag docs just specifies that this is a topic that could be put into the docs. I'm not sure where the problem would be with autoValue and collection2, but I'll try to write something up and see if that helps.

jasonnmark commented 8 years ago

I'm not sure where the problem would be with autoValue and collection2

Probably with my ignorance... but here's my code:

    searchOnMe: {
        type: String,
        optional: true,
        autoValue: function() {
            var searchTerm = this.siblingField("firstName").value + ' ' + this.siblingField("lastName").value;
            return searchTerm;
        }
    },  

This works great on insert, or if I update the entire record BUT when I use editable-text to update just the first name or just the last name the other becomes "undefined".

So on first write I get:

Max Mark

Then when I edit first name I get:

Max undefined

or when I edit last name I get:

undefined Mark

I tried this some variants, but none of them worked:

return this.firstName.value + ' ' + this.lastName.value;
return firstName.value + ' ' + lastName.value;
matteodem commented 8 years ago

I'm sorry but I can't help you with project specific code that's not related to EasySearch, I added docs though that explain how one might go about implementing this http://matteodem.github.io/meteor-easy-search/docs/recipes/.

jasonnmark commented 8 years ago

Thanks. The example code you wrote only works for "insert" and not for "update"... BUT I think I'm close to figuring it out... I have to put a test to make sure that I use the "modifier" if that field has been updated and the doc if it hasn't.

So close....

matteodem commented 8 years ago

You're right! just updated the docs example, hopefully this works as expected.

jasonnmark commented 8 years ago

That example you created gave me the old data (from the doc) when I ran it, instead of the updated data that the user just submitted (from the modifier).

This worked for me and covers cases where one field is updated as well as cases where both fields are updated.

Contacts.before.update(function (userId, doc, fieldNames, modifier) {
    if (fieldNames.indexOf("firstName") > -1){
                // If it's been changed, set var firstName to the new value
        var firstName = modifier.$set && modifier.$set.firstName + ' ';
    } else {
        if (doc.firstName){
                        // if it hasn't been changed and is stored in the database set it to whatever is in database
            var firstName = doc.firstName + ' ';    
        } else {
                        // otherwise set it to blank (so it's not undefined)
            var firstName = '';
        }
    }

    if (fieldNames.indexOf("lastName") > -1){
        var lastName = modifier.$set && modifier.$set.lastName + ' ';
    } else {
        if (doc.lastName){
            var lastName = doc.lastName + ' ';  
        } else {
            var lastName = '';
        }
    }

    var fullName = firstName + lastName;
    modifier.$set = modifier.$set || {};
    modifier.$set.searchOnMe = fullName;
});

Thanks for all your help!