question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Debounce multiple keyups?

See original GitHub issue

Hi there,

Perhaps I’m missing something but I am finding that attempting to implement a typeahead search feature (fairly similar to the example in the documentation) results in a lot of AJAX requests, i.e. one per keyup event which is a lot if the user types in a long search term fairly quickly (or backspaces repeatedly).

In my own (admittedly kinda janky) implementations of typeahead in the past I’ve set it up so that there is no call until no key has been pressed in X milliseconds (see below in case I am doing a poor job of explaining). I’ve tried a few combinations of django-unicorn’s lazy, debounce, and defer modifiers but haven’t had any luck implementing something similar that way.

Code example of what I mean:

    var liveSearchTimeout;
    var keyupDelay = 150;

    $("#live-search").on('keyup', function(e) {
        let search_term = $(this).val();
        if (liveSearchTimeout) clearTimeout(liveSearchTimeout);
        liveSearchTimeout = setTimeout(function() {
            performSearch(quiz_search_url, search_term, "#live-table-body");
        }, keyupDelay);
    });

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
adamghillcommented, Nov 29, 2020

Ah, I think what is happening is that the model updates for search_term are firing along with the search keyup action and they are colliding.

If I’m understanding what you are attempting to do I think you can remove unicorn:keyup="search" from the input and I would re-name the search method to something like result_list to make it more clear what is happening. With this setup the method isn’t used for an action in the component, but is more like a normal Django template variable in the context.

<input type="text" id="quizSearchInput" unicorn:model.debounce-500="search_term" unicorn:key="smoothKey" class="form-control" placeholder="Search for a quiz...">

{% for result in result_list %}
{{ result }}
{% endfor %}
class QuizSearchView(UnicornView):
    template_name="unicorn/quiz-search.html"
    search_term = ""
    quiz_list = Quiz.objects.none()

    class Meta:
        exclude = ("quiz_list",)        

    def mount(self):
        user = self.request.user
        # code to generate self.quiz_list, a filtered QuerySet

    def result_list(self):
        if not self.search_term:
            return self.quiz_list
        else:
            title_search = [quiz for quiz in self.quiz_list if self.search_term.lower() in quiz.title.lower()]
            course_title_search = [quiz for quiz in self.quiz_list if self.search_term.lower() in quiz.course.title.lower()]
            course_shortname_search = [quiz for quiz in self.quiz_list if self.search_term.lower() in quiz.course.short_name.lower()]
            results = list(set(title_search + course_shortname_search + course_title_search))
            return results

To be more explicit, def result_list(self) could be marked as a property so it’s super clear that it’s not a method that would ever get called in the component.

@property
def result_list(self):
    ...

Hopefully that all makes sense, but let me know if that doesn’t work for what you are trying to do!

0reactions
adamghillcommented, Nov 30, 2020

events like unicorn:keyup to be used for calling “helper” methods

Yep! For example, here is one way that I have mixed a model and an action on the same input:

<input type="text" unicorn:model="task" unicorn:keyup.escape="task=''"></input>

So, the model updates the task field in the input, but hitting the escape key would clear the field.

Actions listen for any browser event, so keyup in an input works, but another big purpose is to listen for a click on a button or submit on a form like:

<form unicorn:submit.prevent="add">
...
</form>

or

<button unicorn:click="reset">Clear all tasks</button>

Glad it seems to be working as you expect now, feel free to make a new issue if you run into any other roadblocks. 👍

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to debounce for multiple buttons | Arduino FAQs
How to debounce for multiple buttons using millis() in Arduino. How to debounce for two buttons, three button, four button without using delay....
Read more >
How to add debounce on more than one button?
I am making a keypad using the pro micro as an HID device for the game "osu!" I am adding up to 6...
Read more >
Caching on multiple keys combined with debouncing ignores ...
I am trying to combine caching of plots alongside debouncing the input data. I have an app that tests this, with the first...
Read more >
What is debouncing? – TechTarget Definition
Debouncing is removing unwanted input noise from buttons, switches or other user input. Debouncing prevents extra activations or slow functions from triggering ...
Read more >
The simplest button debounce solution - E-Tinkers
The idea of button debouncing is simple, when a button is pressed, you will wait for it to reach a stable state and...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found