• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

knowledgepixels / nanodash / 26622127697

29 May 2026 06:33AM UTC coverage: 20.725% (-0.007%) from 20.732%
26622127697

push

github

tkuhn
feat: apply view filters live as the user types

Filter text fields used AjaxFormComponentUpdatingBehavior("change"),
which only fires on blur/Enter, so the filter required pressing Enter.

Add a reusable FilterUpdatingBehavior that listens on the "input" event
(fires per keystroke) with a 300ms debounce so rapid typing coalesces
into a single request. Swap it into all filter fields.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

1003 of 6148 branches covered (16.31%)

Branch coverage included in aggregate %.

2584 of 11160 relevant lines covered (23.15%)

3.31 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
src/main/java/com/knowledgepixels/nanodash/component/QueryResultPlainParagraph.java
1
package com.knowledgepixels.nanodash.component;
2

3
import com.knowledgepixels.nanodash.FilteredQueryResultDataProvider;
4
import com.knowledgepixels.nanodash.QueryResult;
5
import com.knowledgepixels.nanodash.QueryResultDataProvider;
6
import com.knowledgepixels.nanodash.ViewDisplay;
7
import com.knowledgepixels.nanodash.page.ExplorePage;
8
import org.apache.wicket.ajax.AjaxRequestTarget;
9
import org.apache.wicket.markup.html.WebMarkupContainer;
10
import org.apache.wicket.markup.html.basic.Label;
11
import org.apache.wicket.markup.html.form.TextField;
12
import org.apache.wicket.markup.html.link.BookmarkablePageLink;
13
import org.apache.wicket.markup.html.list.ListItem;
14
import org.apache.wicket.markup.html.list.ListView;
15
import org.apache.wicket.model.Model;
16
import org.apache.wicket.request.mapper.parameter.PageParameters;
17
import org.nanopub.extra.services.ApiResponse;
18
import org.nanopub.extra.services.ApiResponseEntry;
19
import org.nanopub.extra.services.QueryRef;
20

21
/**
22
 * Component for displaying query results in a list format.
23
 */
24
public class QueryResultPlainParagraph extends QueryResult {
25

26
    private FilteredQueryResultDataProvider filteredDataProvider;
27
    private Model<String> filterModel = Model.of("");
×
28
    private WebMarkupContainer paragraphsContainer;
29

30
    /**
31
     * Constructor for QueryResultList.
32
     *
33
     * @param markupId    the markup ID
34
     * @param queryRef    the query reference
35
     * @param response    the API response
36
     * @param viewDisplay the view display
37
     */
38
    QueryResultPlainParagraph(String markupId, QueryRef queryRef, ApiResponse response, ViewDisplay viewDisplay) {
39
        super(markupId, queryRef, response, viewDisplay);
×
40

41
        String label = grlcQuery.getLabel();
×
42
        if (viewDisplay.getTitle() != null) {
×
43
            label = viewDisplay.getTitle();
×
44
        }
45
        add(new Label("label", label));
×
46
        setOutputMarkupId(true);
×
47

48
        TextField<String> filterField = new TextField<>("filter", filterModel);
×
49
        filterField.setOutputMarkupId(true);
×
50
        filterField.add(new FilterUpdatingBehavior() {
×
51
            @Override
52
            protected void onUpdate(AjaxRequestTarget target) {
53
                if (filteredDataProvider != null && paragraphsContainer != null) {
×
54
                    filteredDataProvider.setFilterText(filterModel.getObject());
×
55
                    paragraphsContainer.addOrReplace(buildParagraphsView());
×
56
                    target.add(paragraphsContainer);
×
57
                }
58
            }
×
59
        });
60
        add(filterField);
×
61

62
        populateComponent();
×
63
    }
×
64

65
    @Override
66
    protected void populateComponent() {
67
        filteredDataProvider = new FilteredQueryResultDataProvider(new QueryResultDataProvider(response.getData()), response);
×
68

69
        paragraphsContainer = new WebMarkupContainer("paragraphs-container");
×
70
        paragraphsContainer.setOutputMarkupId(true);
×
71
        paragraphsContainer.add(buildParagraphsView());
×
72
        add(paragraphsContainer);
×
73
    }
×
74

75
    private ListView<ApiResponseEntry> buildParagraphsView() {
76
        return new ListView<>("paragraphs", filteredDataProvider.getFilteredData()) {
×
77
            @Override
78
            protected void populateItem(ListItem<ApiResponseEntry> item) {
79
                item.add(new Label("title", item.getModelObject().get("title")));
×
80
                String npId = item.getModelObject().get("np");
×
81
                if (npId != null && !npId.isBlank()) {
×
82
                    item.add(new BookmarkablePageLink<Void>("pnp", ExplorePage.class, new PageParameters().set("id", npId)));
×
83
                } else {
84
                    item.add(new Label("pnp").setVisible(false));
×
85
                }
86
                item.add(new Label("content", item.getModelObject().get("content")).setEscapeModelStrings(false));
×
87
            }
×
88
        };
89
    }
90

91
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc