Many thanks for sharing your code Richard, yes, my solution is, in fact, similar, but using the callback like the original widget to get the json data. I was thinking how move all the javascript code from the server side, and I think that putting the needed info as data attributes in the input for use them from jquery will be the solution.

About httrack, I was downloading it some days ago (the semantic doc) for about 6 hours and I give up, maybe I need to give him a try again.

Greetings.

El 12/02/16 a las 10:02, Richard Vézina escribió:
This is mostly it :

# Code in controller
@cache('json_feed', time_expire=60)
def json_feed():
    rows = db().select(db.table_name_all.ALL)
    options = []
    for i, row in enumerate(rows):
options.append({'option': row.field_name, 'id': row.id <http://row.id>})
    from gluon.contrib import simplejson
    return simplejson.dumps({'options': options})


def typeahead_widget(field, value, json_feed=json_feed(), **kwargs):
    input_args = {'_data-provide': 'typeahead', '_autocomplete': 'off'}
    input_args.update(**kwargs)
    return CAT(
        INPUT(
            _type='text',
            _class='string input-xlarge',
_id='txt_%s_%s' % (field._tablename, field.name <http://field.name>),
            _value=value,
            **input_args
        ),
        SELECT(
_id='%s_%s' % (field._tablename, field.name <http://field.name>),
            _name='%s' % (field.name <http://field.name>),
            _style='display: none;',
            _multiple='multiple',
            requires=field.requires
        ),
        DIV(
            OL(
_id='ol_%s_%s' % (field._tablename, field.name <http://field.name>),
                _class='typeahead_multiselect'
            ),
            _class='typeahead_multiselect'
        ),
        SCRIPT("""
        $(document).ready(function(){
        var json_feed = $.parseJSON('%(json_feed)s');
        var mapped = {};
        var searchFieldNames = _.debounce(function(query, process) {
                        var labels = []

                        $.each(json_feed.options, function (i, item) {
                            mapped[item.option] = item.id <http://item.id>
                            labels.push(item.option)
                            });
                            process(labels);
                        }, 100);
                        // _.debounce() depend on underscore.js
//make_ol_sortable(); // jquery-sortable seems to be bugged and leave option with value undefined
        $('#%(txtSearch)s').typeahead({
                minLength: 0,
                items: 30,
                source: function(query, process) {
                    searchFieldNames (query, process);
                    },
                updater: function(item) {
$('#%(olSearch)s li span:contains("' + item + '")').parent().remove(); $('#%(olSearch)s').append('<li id="' + mapped[item] + '" class="typeahead_multiselect_option"><span class="typeahead_multiselect_option_label">' + item + '</span><a href="#" class="typeahead_multiselect_close" onclick="$(this).parent().remove(); checkOlEmpty(); redo_select();">x</a></li>');
//$('#%(olSearch)s').sortable().bind('sortupdate',function(){
                    //    redo_select();
                    //});
                    redo_select();
                    checkOlEmpty();
                }
            });

            checkOlEmpty();

        });
        function redo_select() {
            $('select[id="%(selSearch)s"]').empty();
            $('#%(olSearch)s li').each(function(){
$('#%(selSearch)s').append('<option value="' + $(this).attr('id') + '" selected="selected">' + $('li[id="' + $(this).attr('id') + '"] span.typeahead_multiselect_option_label').text() + '</option>');
            });
        }

        function checkOlEmpty() {
            $('ol.typeahead_multiselect').hide();
$('ol.typeahead_multiselect').has('li').show();
        };

        function make_ol_sortable(){
            var adjustment;
            $('#%(olSearch)s').sortable({
                  group: 'simple_with_animation',
                  pullPlaceholder: false,
                  // animation on drop
                  onDrop: function  (item, targetContainer, _super) {
                    var clonedItem = $('<li/>').css({height: 0})
                    item.before(clonedItem)
                    clonedItem.animate({'height': item.height()})

                    item.animate(clonedItem.position(), function  () {
                      clonedItem.detach()
                      _super(item)
                    })
//redo_select(); // This not working for now there is option with undefined value that remain once the dragged option is released that seems a bug
                  },

                  // set item relative to cursor position
                  onDragStart: function ($item, container, _super) {
                    var offset = $item.offset(),
                    pointer = container.rootGroup.pointer

                    adjustment = {
                      left: pointer.left - offset.left,
                      top: pointer.top - offset.top
                    }

                    _super($item, container)
                  },
                  onDrag: function ($item, position) {
                    $item.css({
                      left: position.left - adjustment.left,
                      top: position.top - adjustment.top
                    })
                  }
            });
        }

""" % {'txtSearch': 'txt_%s_%s' % (field._tablename, field.name <http://field.name>), 'selSearch': '%s_%s' % (field._tablename, field.name <http://field.name>), 'olSearch': 'ol_%s_%s' % (field._tablename, field.name <http://field.name>),
               'json_feed': XML(json_feed),
               })
    )

I am not a JS kingpin, so it may contain dumb things... Basically I create a feed function... And use it in callback in javascript...

I didn't have time to review your code, but I guess it similar...

Hope it helps create a good plugin for web2py community... I really thing this one is missing, but since it sometime really specific what you need as an autocomplete I doudt it can address every needs... But on this side semantic ui seems to have more feature... If we can have plugin for which you can switch from bs to semantic it could be so nice...

You may grab the whole semantic ui and work offline with it : https://www.httrack.com/

Richard

On Fri, Feb 12, 2016 at 7:25 AM, <tim.nyb...@conted.ox.ac.uk <mailto:tim.nyb...@conted.ox.ac.uk>> wrote:

    I've been thinking about doing this exact thing for a while, so
    I'll be eagerly watching your plugin

    On Thursday, 11 February 2016 16:18:28 UTC, Carlos Cesar Caballero
    wrote:

        Hi, right now I am working in a plugin with an autocomplete
        widget using
        typeahead.js:

        https://github.com/daxslab/web2py-typeahead

        Any clues, suggestions, recomendations etc... will be very
        welcomed.

        Greetings.

-- Este mensaje le ha llegado mediante el servicio de correo
        electronico que ofrece Infomed para respaldar el cumplimiento
        de las misiones del Sistema Nacional de Salud. La persona que
        envia este correo asume el compromiso de usar el servicio a
        tales fines y cumplir con las regulaciones establecidas

        Infomed: http://www.sld.cu/

-- Resources:
    - http://web2py.com
    - http://web2py.com/book (Documentation)
    - http://github.com/web2py/web2py (Source code)
    - https://code.google.com/p/web2py/issues/list (Report Issues)
    ---
    You received this message because you are subscribed to the Google
    Groups "web2py-users" group.
    To unsubscribe from this group and stop receiving emails from it,
    send an email to web2py+unsubscr...@googlegroups.com
    <mailto:web2py+unsubscr...@googlegroups.com>.
    For more options, visit https://groups.google.com/d/optout.


--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
---
You received this message because you are subscribed to the Google Groups "web2py-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to web2py+unsubscr...@googlegroups.com <mailto:web2py+unsubscr...@googlegroups.com>.
For more options, visit https://groups.google.com/d/optout.



--
Este mensaje le ha llegado mediante el servicio de correo electronico que 
ofrece Infomed para respaldar el cumplimiento de las misiones del Sistema 
Nacional de Salud. La persona que envia este correo asume el compromiso de usar 
el servicio a tales fines y cumplir con las regulaciones establecidas

Infomed: http://www.sld.cu/

--
Resources:
- http://web2py.com
- http://web2py.com/book (Documentation)
- http://github.com/web2py/web2py (Source code)
- https://code.google.com/p/web2py/issues/list (Report Issues)
--- You received this message because you are subscribed to the Google Groups "web2py-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to web2py+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to