Use jquery ui autocomplete by using ReactiveHTML

Dear all,

I think ReactiveHTML is really awesome and I am trying to learn to use it.
I am trying to use jquery ui but I could not assign the options from my list.
My code is given below.

from panel.reactive import ReactiveHTML
import panel as pn
import param

wordlist = [
    "abcdefg",
    "hijklmnop",
    "qrstuv",
    "wxyz",
    "abc",
    "def",
    "ghi",
    "jkl",
    "mno",
    "pqr",
    "stu",
    "vwx",
    "yz",
  ]

class JQuery(ReactiveHTML):
    
    value = param.String(default='')
    options = param.List(default=[])
    
    _template = """
    <label for="tags">Tags: </label>
    <input id="tags" value="${value}"> </input>
    """
    
    _dom_events = {'tags': ['change']}
    
    _scripts = {
        'render':   """
        tags.autocomplete({source: data.options})
        """
    }
    
    __javascript__ = [
        "https://code.jquery.com/ui/1.12.1/jquery-ui.js"
    ]
    
    
jquery = JQuery(options=wordlist)
pn.extension()
jquery

Any comments to solve the problem or suggestions for improvement are greatly appreciated.

Thanks in advance.
Arifin

I am using this as reference.
https://jqueryui.com/autocomplete/

you have a missing jquery script (https://code.jquery.com/jquery-1.12.4.js) script and you have to wrap your input into a jquery object ($(tags)):

class JQuery(ReactiveHTML):
    
    value = param.String(default='')
    options = param.List(default=[])
    
    _template = """
    <div>
        <label for="tags">Tags: </label>
        <input id="tags" value="${value}"> </input>
    </div>
    """
    
    _dom_events = {'tags': ['change']}
    
    _scripts = {
        'render':   """
            $(tags).autocomplete({source: data.options})
        """
    }
    
    __javascript__ = [
        "https://code.jquery.com/jquery-1.12.4.js",
        "https://code.jquery.com/ui/1.12.1/jquery-ui.js"
    ]
   
2 Likes

@xavArtley Thank you for your quick response! It is really excited to see it is working. Thanks!

I have another questions here. I had included name parameter to specify the title of the widget.
It works if I specified it like name="ID: as below. However, if it is not specified, the name becomes JQuery**** where **** are the random number. I wonder why it do not take the default value for name there.

class JQuery(ReactiveHTML):
    
    value = param.String(default='')
    options = param.List(default=[])
    name = param.String(default='')
    
    _template = """
    <div>
        <label for="tags"> ${name} </label>
        <input id="tags" value="${value}"> </input>
    </div>
    """
    
    _dom_events = {'tags': ['change']}
    
    _scripts = {
        'render':   """
            $(tags).autocomplete({source: data.options})
        """
    }
    
    __javascript__ = [
        "https://code.jquery.com/jquery-1.12.4.js",
        "https://code.jquery.com/ui/1.12.1/jquery-ui.js"
    ]
    
    
jquery = JQuery(options=wordlist, name="ID:")
pn.extension()
jquery

Another question is I found that this funny behavior that the suggestion box could be separated from the input box. Any suggestion to solve it?

Thanks all in advance.

1 Like

Hi @Arifin

You can add

def __init__(self, **params):
        if not "name" in params:
            params["name"]=''
        super().__init__(**params)

Then it will behave as you want.

image

What you see is that name is special to all Parameterized classes. It acts a bit as an autogenerated, unique key if no name is provided.

Here is the full code

import panel as pn
import param

class JQuery(pn.reactive.ReactiveHTML):

    value = param.String(default='')
    options = param.List(default=[])
    name = param.String(default='')

    def __init__(self, **params):
        if not "name" in params:
            params["name"]=''
        super().__init__(**params)

    _template = """
    <div>
        <label for="tags"> ${name} </label>
        <input id="tags" value="${value}"> </input>
    </div>
    """

    _dom_events = {'tags': ['change']}

    _scripts = {
        'render':   """
            $(tags).autocomplete({source: data.options})
        """
    }

    __javascript__ = [
        "https://code.jquery.com/jquery-1.12.4.js",
        "https://code.jquery.com/ui/1.12.1/jquery-ui.js"
    ]


pn.extension()
wordlist=["apples", "pears", "bananas"]
jquery = JQuery(options=wordlist)
jquery.servable()

Regarding using jquery components and widgets. As I understand the world has/ is moving away from jquery. I also have a feeling (but don’t know) that it can be problematic in a notebook context ??

So my advice is to choose a non-jquery based library if it exists.

Thanks Marc for your solutions and the comments regarding jquery. I will look for other library. Anyway, ReactiveHTML is really interesting programming tool!

1 Like