Meteor-Community-Packages / meteor-autocomplete

Client/server autocompletion designed for Meteor's collections and reactivity.
https://atmospherejs.com/mizzao/autocomplete
MIT License
350 stars 109 forks source link

Autocomplete (server-side configuration) not working #138

Closed andrew-filippov closed 7 years ago

andrew-filippov commented 7 years ago

Hi guys, I've created in template:

{{> inputAutocomplete name="postcode" settings=settings }}

... and settings in template's helpers :

settings(){
        return {
            position:"bottom",
            limit:5,
            rules:[{
                collection:"PostcodeLocations",
                field:"postcode",
                subscription:"app.postcodelocations.autocomplete",
                matchAll: true,
                template:Template.testTmpl
                }]
        };
    }

... also I have added some staff into template's code for debug purposes :

var autoPostcodeLocations = new Mongo.Collection("autoCompleteLocations");
...
Template.createLocationModal.onRendered(function () {
...
// print received data
this.autorun(()=>console.log(autoPostcodeLocations.find({}).fetch())); 
...
});

my publishing:

Meteor.publish('app.postcodelocations.autocomplete', function (selector, options) {
    check(selector, Object);
    check(options, Object);
    var sub = this;

    options.limit = Math.min(10, Math.abs(options.limit));

    var handle = PostcodeLocations.find(selector, options).observeChanges({
        added:function(id, fields) {console.log('added - %s', id);
            sub.added("autoCompleteLocations", id, fields);
        }
    });

    sub.ready();
    sub.onStop(function(){ handle.stop(); });
});

when I try to type into textbox, publishing works (I see console output on server side). Also client has that data received (output in browser's console - print received data section), but widget is always claims 'No matches'. In other case - when I have configured autocomplete control to use a local collection (see samples below), it works fine:

// this is template's behind code
// import collection definition
import { PostcodeLocations } from '/imports/api/postcodeLocations/collection'; 
...
Template.createLocationModal.onRendered(function () {
...
// simple subscribe
    Meteor.subscribe('app.postcodelocations.autocomplete');
...
});
...
//helpers
Template.createLocationModal.helpers({
    schema: () => locationSchema,
    settings(){
        return {
            position:"bottom",
            limit:5,
            rules:[{
                collection:PostcodeLocations,
                field:"postcode",
                template:Template.testTmpl
                }]
        };
    }
});
// my simple publication
Meteor.publish('app.postcodelocations.autocomplete', function () {
    return PostcodeLocations.find({ postcode: { '$regex': '^a', '$options': 'i' } }, {limit:10});
});

What I have missed here? any idea?

andrew-filippov commented 7 years ago

In fact, when I slightly change my Publishing and use AutoComplete class, my code became working.

aessig commented 7 years ago

@andrew-filippov can you please publish you working code. I'm struggling with the same issue. Thanks

andrew-filippov commented 7 years ago

Sory dude, I'm not working on those project anymore. But I have found this piece of code: So, Template side is looks as followed:

{{> afQuickField name="postcode" type="autocomplete-input" settings=settings template="bootstrap3-horizontal" label-class="col-sm-3" input-col-class="col-sm-9"}}

.. viewModel:

Template.createLocationModal.helpers({ schema: () => locationSchema, settings(){ return { position:"bottom", limit:5, rules:[{ collection:"PostcodeLocations", field:"postcode", subscription:"app.postcodelocations.autocomplete", template:Template.autoCompleteItem }] }; } });

... and server's side publishing:

Meteor.publish('app.postcodelocations.autocomplete', function (selector, options) { Autocomplete.publishCursor(PostcodeLocations.find(selector, options), this); this.ready(); });

... and My implementation of Autocomplete class (based on some sample from google 8-)):

var Autocomplete; Autocomplete = (function() { function Autocomplete() {}

Autocomplete.publishCursor = function(cursor, sub) { return Mongo.Collection._publishCursor(cursor, sub, "autocompleteRecords"); };

return Autocomplete;

})();

Meteor.publish('autocomplete-recordset', function(selector, options, collName) { var collection; collection = global[collName]; if (!collection) { throw new Error(collName + ' is not defined on the global namespace of the server.'); } if (!collection._isInsecure()) { Meteor._debug(collName + ' is a secure collection, therefore no data was returned because the client could compromise security by subscribing to arbitrary server collections via the browser console. Please write your own publish function.'); return []; } if (options.limit) { options.limit = Math.min(50, Math.abs(options.limit)); } Autocomplete.publishCursor(collection.find(selector, options), this); return this.ready(); });

export {Autocomplete};

I hope, this sample will help you