Textbox Autocomplete with unicode char

20 views
Skip to first unread message

Sebastien Saint-Sevin

unread,
Jun 13, 2015, 3:15:36 PM6/13/15
to nitro...@googlegroups.com
Hi,
I'm upgrading my app with the last nitrogen version (was using an old 2.0.4 previously)
I'm having troubles with textbox autocomplete when using unicode chars (ascii chars only are ok).
The  {id, value} expected tuple seems to be undefined as shown by the following error :

{error,function_clause,
        [{w_panel,autocomplete_select_event,
             [undefined,zoom_commune],
             [{file,"/usr/local/lib/la-taxe-habitation/site/src/w_panel.erl"},
              {line,248}]},
         {wf_core,run_catched,0,[{file,"src/wf_core.erl"},{line,90}]},
         {wf_core,run,0,[{file,"src/wf_core.erl"},{line,23}]},
         {mochiweb_simple_bridge_anchor,loop,1,
             [{file,
                  "src/mochiweb_bridge_modules/mochiweb_simple_bridge_anchor.erl"},
              {line,27}]},
         {mochiweb_http,headers,5,[{file,"src/mochiweb_http.erl"},{line,96}]},
         {proc_lib,init_p_do_apply,3,[{file,"proc_lib.erl"},{line,237}]}]}}


My function is expecting something like 

autocomplete_select_event([{<<"id">>, Id },{<<"value">>, _Value}], zoom_commune)

What I am doing wrong ?

Cheers,

Sébastien.

Jesse Gumm

unread,
Jun 13, 2015, 4:22:06 PM6/13/15
to nitrogenweb
Hi Sebastian,

Would you be willing to share some of the code you used? The
textbox_autocomplete was reworked pretty heavily for 2.3 to be a bit
cleaner, at the expense of some backwards compatibility.

In this case, there might be some wonkiness for not properly handling
unicode, in which case, I'd love to see some code to play with.

If you're not comfortable sharing it on-list, you could send it to me
off-list (gu...@sigma-star.com) and I can have a gander at it!

-Jesse

-Jesse
> --
> You received this message because you are subscribed to the Google Groups
> "Nitrogen Project / The Nitrogen Web Framework for Erlang" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to nitrogenweb...@googlegroups.com.
> To post to this group, send email to nitro...@googlegroups.com.
> Visit this group at http://groups.google.com/group/nitrogenweb.
> For more options, visit https://groups.google.com/d/optout.



--
Jesse Gumm
Owner, Sigma Star Systems
414.940.4866 || sigma-star.com || @jessegumm

Sebastien Saint-Sevin

unread,
Jun 13, 2015, 5:03:13 PM6/13/15
to nitro...@googlegroups.com
Hi Jesse,

My code involves RDBMS connection and is a bit complicated to clean up right now. 
But I think I was able to reproduce the problem I'm facing by lightly modifiying the nitrogen example demo.
Below, I just modifed the {value, <<"Elixir é"/utf8>> } entry to add an european letter.

When selecting this entry in the list I get the error with undefined.

Hope this helps,
Cheers,

Sébastien.


%% -*- coding: utf-8 -*-
-module (autocomplete).
-include_lib ("nitrogen_core/include/wf.hrl").
-compile(export_all).


main() -> #template{file="./site/templates/carte.html"}.

description() -> "description".
title() -> "Autocompletion".
body() -> w_panel:get_body_panel(?MODULE).


main_div_body() ->
    [
    "<p>
    The <code>#textbox_autocomplete{}</code> element gives you a simple way
    to add autocompletion with options to a textbox element. It relies on
    JSON encoding, and expects your application to have two functions
    exported: <code>autocomplete_enter_event(SearchTerm, Tag)</code>, which
    is called as the user types and
    <code>autocomplete_select_event(SelectedElement, Tag)</code>, which is
    called when the user selects and element from the list.
        ",
        #p{},
        #label { text="What's your favorite programming language?" },
        #textbox_autocomplete { tag=auto1, minLength=1 },
        #flash {}
    ].

does_search_match(LangRec, SearchTerm0) ->
  %% We extract the label from the passed Lang "Rec" (which is just a proplist)
  Label0 = proplists:get_value(label, LangRec),
  %% And convert it ot lower case
  Label = string:to_lower(wf:to_list(Label0)),
  %% and also convert the SearchTerm to lowercase
  SearchTerm = string:to_lower(SearchTerm0),
  %% Then see if SearchTerm is contained anywhere in the Label
    string:str(Label, SearchTerm) > 0.

autocomplete_enter_event(SearchTerm, _Tag) ->
  Data0 = base_data(),
  
  %% Let's filter the list based on the SearchTerm
    Data = [LangRec || LangRec <- Data0, does_search_match(LangRec, SearchTerm)],

  %% Encode the Data into json for the autocomplete event. As you can see
  %% from the base_data function below, it expects each record to have an
  %% "id", a "label", and a "value". "id" is a short-hand identifier. "label"
  %% is what will be displayed in the dropdown, and "value" will be passed
  %% along with the "id", then decoded from json and sent to the
  %% autocomplete_select_event function as a proplist.
    wf:json_encode(Data).

autocomplete_select_event(SelectedElement, _Tag) ->
  %% SelectedElement is a proplist
  %% Let's tell the user what we selected!
    wf:flash(proplists:get_value(<<"value">>, SelectedElement)),
    ok.

base_data() ->
  [
    [{id, <<"c">>}, {label, <<"C">>}, {value, <<"C">>}],
    [{id, <<"cpp">>}, {label, <<"C++">>}, {value, <<"C++">>}],
    [{id, <<"clojure">>}, {label, <<"Clojure">>}, {value, <<"Clojure">>}],
    [{id, <<"coffeescript">>}, {label, <<"Coffeescript">>} , {value, <<"Coffeescript">> }],
    [{id, <<"elixir">>}, {label, <<"Elixir">>} , {value, <<"Elixir é"/utf8>> }],
    [{id, <<"erlang">>}, {label, <<"Erlang">>} , {value, <<"Erlang">> }],
    [{id, <<"go">>}, {label, <<"Golang">>} , {value, <<"Golang">> }],
    [{id, <<"haskell">>}, {label, <<"Haskell">>} , {value, <<"Haskell">> }],
    [{id, <<"lua">>}, {label, <<"Lua">>} , {value, <<"Lua">> }],
    [{id, <<"java">>}, {label, <<"Java">>} , {value, <<"Java">> }],
    [{id, <<"js">>}, {label, <<"Javascript">>} , {value, <<"Javascript">> }],
    [{id, <<"perl">>}, {label, <<"Perl">>} , {value, <<"Perl">> }],
    [{id, <<"php">>}, {label, <<"PHP">>} , {value, <<"PHP">> }],
    [{id, <<"python">>}, {label, <<"Python">>}, {value, <<"Python">>}],
    [{id, <<"objc">>}, {label, <<"Objective-C">>} , {value, <<"Objective-C">> }],
    [{id, <<"ocaml">>}, {label, <<"OCaml">>} , {value, <<"OCaml">> }],
    [{id, <<"ruby">>}, {label, <<"Ruby">>} , {value, <<"Ruby">> }],
    [{id, <<"scala">>}, {label, <<"Scala">>} , {value, <<"Scala">> }],
    [{id, <<"swift">>}, {label, <<"Swift">>} , {value, <<"Swift">> }]
  ].
 

Jesse Gumm

unread,
Jun 13, 2015, 5:33:31 PM6/13/15
to nitrogenweb

Thanks Sebastien,

I'm away from the house right now, but I'll try to check it out this weekend.

Not sure yet what the problem is. L

-Jesse

--

Jesse Gumm

unread,
Jun 16, 2015, 2:21:44 PM6/16/15
to nitrogenweb
Hi Sebastien,

Thanks for your patience. I've made a change to master which seems to
fix the problem. Please check it out at your earliest convenience.

Please updated your nitrogen_core lib to master and give it another shot.

Thanks,

-Jesse

Sebastien Saint-Sevin

unread,
Jun 16, 2015, 4:23:32 PM6/16/15
to nitro...@googlegroups.com
Hi Jesse,

It fixes it partially only I think.

Use the following test cases for example :

    [{id, <<"elixir">>}, {label, <<"Elixir">>} , {value, <<"Elixir">> }],
    [{id, <<"élixir"/utf8>>}, {label, <<"élixir"/utf8>>} , {value, <<"élixir"/utf8>> }],

When I enter "lixir" both values are shown and It's ok to select one or the other, no more errors, that's good.
But if I enter "élix" to select the second case, nothing is shown...

Thanks for your time,
Cheers,
Sébastien.

Jesse Gumm

unread,
Jun 16, 2015, 4:43:35 PM6/16/15
to nitrogenweb
Thanks for pointing that out. That's actually a bug in the demo page
code itself. SearchTerm will be passed as a string list so it need to
compare, and with it naively converting unicode binaries to lists
using wf:to_list rather than wf:to_unicode_list, the comparison
failed, returning an empty list of valid matches. The commit fixing
this is here:

https://github.com/nitrogen/NitrogenProject.com/commit/84f3f4b41a719b89b329584380f95d5900e052ad

-Jesse

Sebastien Saint-Sevin

unread,
Jun 16, 2015, 5:10:50 PM6/16/15
to nitro...@googlegroups.com
Thanks a lot Jesse,
I'm able to make my app work with your fix !
Cheers,

Sébastien.

Jesse Gumm

unread,
Jun 16, 2015, 5:15:24 PM6/16/15
to nitrogenweb
Fabulous! Thanks for bringing this bug to light.

Have a good one,

-Jesse
Reply all
Reply to author
Forward
0 new messages