Autocomplete / tags and AJAX

Autocomplete / tags and AJAX

Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

Just a quick question / request -- any chance that the new (and wonderful) autocomplete and tags fields will eventually have the same AJAX capabilities as a regular AJAX request?

For example, the US state of Texas is divided into 254 counties.

Something like this would help get all the relevant counties from a table with all counties for every state in the US:

new DataTable.Editor({
    ajax: '/api/data',
    fields: [{
        label: 'Counties:',
        name: 'county',
        type: 'tags',
        ajax: {
            url: '/api/counties',
            data: {
                state: 'Texas'
            }
    }],
    // ...
})

This question has accepted answers - jump to:

«1

Answers

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Do you mean the ability to add extra information to the Ajax request, or provide the other options for it as an object (like ajax.data)?

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Yeah -- exactly like that. I think it would make a world of difference in terms of the flexibility on the backend.

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Oh sorry -- I don't think I read your question correctly -- I meant like ajax.data.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin
    Answer ✓

    Good idea, thank you. I've got it on the list :).

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Hey @allan -- is this something that will be included in Editor 2.4.1?

    I have my own custom field plugin that I am tinkering with but I could probably replace it in total if autocomplete and tags had the ajax.data capability.

    No rush, but just trying to determine if I should focus on my custom plugin or wait for the next iteration of the autocomplete and tags field types!

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Your post has prompted me to look at this properly - there is already a concept of this in the Dropdown control I wrote for these fields in Editor, however, it isn't yet exposed. Is it just static key/values that you want to attach to the data object sent to the server? That shouldn't be a problem to add.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Would be great if it allowed something like this:

    new DataTable.Editor({
        ajax: '/api/data',
        fields: [{
            label: 'Counties:',
            name: 'county',
            type: 'tags',
            ajax: {
                url: '/api/counties',
                data: {
                    state: 'Texas',
                    yet_another_param: function () {
                        let foo = 42
                        return foo
                    }
                }
        }],
        // ...
    })
    
  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin
    Answer ✓

    Committed :). That functionality will be in 2.4.1 which I'll release shortly (hopefully later today).

    It will be under ajaxData rather than a nested object - e.g. the above would be:

    new DataTable.Editor({
      ajax: "/api/data",
      fields: [
        {
          label: "Counties:",
          name: "county",
          type: "tags",
          ajax: "/api/counties",
          ajaxData: {
            state: "Texas",
            yet_another_param: function () {
              let foo = 42;
              return foo;
            },
          },
        },
      ],
      // ...
    });
    

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Thanks, @allan!

    This will (at least for me) greatly enhance autocomplete and tags!

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    @allan -- after some incorporation into my current forms and testing, I have two more requests for the dropdown control :smile:

    1) The Bootstrap floating labels is not taking effect on that input
    2) Provide a way to change the AJAX request from 'Post' to 'Get'

    On that last note, not to second guess but to understand -- I'm curious about the choice to implement sending additional data through the ajaxData rather than recycle the current -inst ajax used for tables and have the ability to set those options in a similar way..

    I'm sure there's much more to consider than what I'm thinking of, but I was just surprised to see the ajaxData option added rather then the -inst ajax.


    On a slightly separate but related note, my favorite upgrade from Editor 1.x to 2.0 was the DataTable-as-an-input, but the one thing I disliked is the amount of space it takes up on a form, especially when a form has several of those.

    The custom control I had started (which is not completely functional and looks like it was programmed by an amateur, because it was :smile: ) places a DataTable-as-an-input into a Bootstrap dropdown to get something close to what I'm looking for, but I was thrilled to see the autocomplete and tags essentially doing the same thing.

    Anyway, I'm glad to see these field types incorporated as out-of-the-box options for Editor and I'm hopeful the ultimate vision for them is to have them as a fully functioning DataTable-as-an-input but in a dropdown!

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Hi Loren,

    I did consider allowing ajax to be specified as an object, and decided that I will offer that as an option in future, but there are a lot of moving pieces there that need to be accounted for and to expedite the release I though I'd just extend the already existing internal ajaxData option. At the moment to change to GET you'd need to modify the Editor code to tweak that option.

    1) The Bootstrap floating labels is not taking effect on that input

    Not something I tested - didn't think of it! I'll take a look when I'm back in the office next week.

    2) Provide a way to change the AJAX request from 'Post' to 'Get'

    Will be part of the support for ajax as an object.

    I'm hopeful the ultimate vision for them is to have them as a fully functioning DataTable-as-an-input but in a dropdown!

    It is a DataTable in the dropdown as it happens :). Additional table functionality could be exposed in future field types or versions. If there is something specific about the table UI that you'd like to see in the dropdown, I'd be interested to know. I've gone to some lengths to hide the table aspect of it thus far.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited February 7

    Thanks, @allan -- and please know I greatly appreciate you adding the ajaxData option to expedite the release just to appease a particular fussy person in the forums! :smile:

    I did see that it's a DataTable in the DropDown -- that's why I was surprised the DataTable itself is not exposed for the ajax options, however . . .

    I've gone to some lengths to hide the table aspect of it thus far.

    This is interesting -- there is a natural tension between flexibility and simplicity, but I think to fully expose the DataTable like is done for the DataTabes-as-an-input would be better.

    Or at least have the option to do so.

    Aside from the ajax options I've mentioned, I could be interested in ordering the table in the Dropdown or seeing the info for the number of records, or performign a rowGroup on those options, etc., not to mention the ability to open another Editor window to add a record to the joined table, etc.

    Please remember I am an amateur programmer, so I have very little idea how difficult any of this is to do, so perhaps it's more complicated than what I think.

    But to have a strong default configuration for the DataTable in the DropDown, like you do, and also making it possible access the DataTable itself through a config option and .dt() like the DataTable-as-an-input would make it a much more powerful field.

    At least for my purposes!

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin
    Answer ✓

    I wanted the dropdown list to be a basic list, but also be sorted and searchable, which is why I hid a lot of the DataTables aspects (e.g. the table header) while utalising them underneath. I haven't considering row groups before - that would be a good way of doing something like an optgroup, thanks for the suggestion. Multiple columns for more complex data I did consider, but thought I'd come back to at a later date!

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Thanks, @allan -- it's an excellent addition and I look forward to seeing the increased functionality!

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited February 20

    @allan -- using this thread to annotate areas I think the autocomplete and tags might have additional functionality.

    Sorting
    I mentioned previously the ability to sort and I have a concrete example for your consideration.

    The default sorting on the label is asc and it doesn't appear that can be overwritten.

    I have a sports research site where users enter games and the first field on the form (a tag) is the season in which the game was played.

    During the current season users are mostly concerned with entering a game from the current, but if they type '2' then '2025' is the last on the list, so they have to continue to type.

    Typed '2'
    
    List
    2000
    2001
    2002
    ...
    2025
    
    Typed '202'
    
    List
    2020
    2021
    2022
    ...
    2025
    

    If I had the ability to sort desc then they could type '2' and down arrow to select the current season and be done.

    Typed '2'
    
    List
    2025
    2024
    2023
    ...
    

    Wrap around navigation
    Similarly, I’d suggest pressing the up arrow from the input should move focus to the last item in the dropdown. Additionally, the up/down arrows should allow navigation to wrap around, moving from the last item to the first and vice versa.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Excellent ideas - thank you for both. I've put them into my tracker for addition to Editor :).

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Just a quick amendment based on some more experimenting:

    Wrap around navigation
    * The up/down arrows should allow navigation to wrap around, to include the input
    ** Arrow down from the input moves to the first record
    ** Arrow up from the first record moves to the input
    ** Arrow up from the input moves to the last record
    ** Arrow down from the last record moves to the input

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    CSS
    When the text of a tag is a little long, the delete x can get bumped below it.

    Suggestion:

    div.DTE div.DTE_Field_Type_tags div.dte-tag {
        ...
        white-space: nowrap;
    }
    
  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited February 23

    Tags with null values not showing add button
    In many places I use tags, the corresponding field in the database allows null, but the null value shows up as a tag itself rather than the "+ Add" button.

    I think that would be resolved with this small change to add the null case under the set method:

        set: function (conf, val) {
            ...
            if (val === '' || val === null) {
                val = [];
            }
            ...
    

    Allow deleteButton text
    addButton can be changed under the i18n option but the delete button only has the default ×

    I can make a fancy add button from somewhere like Font Awesome but it would be nice to have the ability to show a red trash can (rubbish bins :smile: ) or something similar for the delete.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    This is great feedback - thank you! Issued filed and will be looked at when I'm working on Editor next :).

    Regarding the null - I'm thinking I might have an exclude option in the server-side Options class. That would allow null to be removed. At the moment you could add a where() condition to remove it as an option. I think I prefer to have the client-side display whatever the server sends.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited February 24

    Thanks, @allan, and I appreciate your willingness to take the feedback!

    On the null, I'm doing an ajax call for the options so I don't think I can catch it the way you're describing.


    Here's the return from one of my ajax requests for a DataTable (the time property is just added so I can more easily monitor query performance):

    {
        "data": [
            {
                "id": 121,
                "school_code": "GA.CK-008",
                "school_name": "Clarke Central",
                "start_season": "1970",
                "end_season": null
            }
        ],
        "time": 0.006724119186401367
    }
    

    This is for the name of school "GA.CK-008". In this case, the start_season is 1970 but the end_season is null because the school still has the name "Clarke Central".

    When I open the edit form, only the start_season tag triggers an ajax call for the options.

    The end_season does not trigger an ajax call and so the tag renders the null as per the screenshot in the previous post.


    If the set function accounted for the null case then I think it'd take care of that.

    Alternatively if opening the form triggered an ajax call for options even on null, then I could return something that would end up rendering as the add button.

    But currently I don't see a way to get the add button to render for null values except to modify the initial DataTable query to return '' instead of null for all the relevant fields.

    That doesn't seem like a reasonable solution though.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Ah - I misunderstood a bit. Thanks for the clarification. That does indeed sound like something that needs to be handled. I'll look into that as well!

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Ordering
    A quick thought on ordering -- if you're still planning on not exposing the underlying DataTable, then a sort function similar to the display function would easily allow sorting on items other than the label and the value.

    For example, to sort a list of countries by population:

    {
        label: 'Country:',
        name: 'country.name',
        type: 'autocomplete',
        ajax: '../php/autoCompleteRender.php',
        escapeLabelHtml: false,
        display: function (data, val) {
            return DataTable.util.escapeHtml(data.name) + '<span class="pull-right">' + data.flag + '</span>';
        },
        sort: function (data, val) {
            return data.population;
        }
    }
    

    This would also be helpful with the rowGroup option (or optgroup as you mentioned), where sorting on the label would probably disrupt the rowGroup.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    I'm not sure yet how to do it. I need to have a bit of a think about it. It could be that I have an order option which can be asc, desc or null (i.e. no sorting, use the load order).

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    The null sounds like it would work for me because I can return the ajax results ordered the way I prefer from the server.

    Anyway, thanks for being open to the feedback!

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10

    Just a couple of more suggestions for tags and autocomplete:

    Option to have an initial AJAX load
    The DataTable in the dropdown is already populated with options if those are provided with the table, but it would be nice to have a config setting to get an initial set of options from an ajax call.

    {
        label: 'Country:',
        name: 'country.name',
        type: 'tags',
        ajax: '../php/autoCompleteRender.php',
        ajaxInit: true
    }
    

    This would trigger an ajax call for the initial set of options when the dropdown is shown.

    Throttle for AJAX search
    I haven't double checked but it seems like there's something similar for tables using serverSide.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    Throttle - yes! That one will be added.

    The initial Ajax I'm less sure about. You can populate the options using the options property of the JSON DataTables loads, or use field().update() which could be called in a custom Ajax result function, so the end effect is already possible, and I'm not sure that it would be used often enough to warrant being in the API. Certainly open to other requests for that though, at which point I can bump it up the scale.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited March 7

    Just a quick amendment to the CSS I mentioned above:

    CSS
    When the text of a tag is a little long, the delete x can get bumped below it.

    Suggestion (ignore suggestion from my post above):

    div.DTE div.DTE_Field_Type_tags div.dte-tag {
        display: flex;
        margin-right: var(--dte-tag-margin);
        margin-bottom: var(--dte-tag-margin);
        border: var(--dte-tag-border);
        background: var(--dte-tag-background);
        border-radius: var(--dte-tag-border-radius);
        cursor: pointer;
        font-size: var(--dte-tag-font-size);
        color: var(--dte-tag-color);
    }
    

    The change is from

        display: inline-block;
    

    to

        display: inline-flex;
    

    This allows the text in the tag itself to wrap but keep the x to delete the tag to the left.

  • allanallan Posts: 64,223Questions: 1Answers: 10,598 Site admin

    I do like flex box :). It took a while to get use to it, but it is very useful. Thanks for the update. I hope to look into implementing some of this stuff soon.

    Allan

  • Loren MaxwellLoren Maxwell Posts: 432Questions: 102Answers: 10
    edited March 10

    Thanks, @allan -- no rush. I'm just using this thread to consolidate my suggestions on the new field types.

    Also, I'll make another push for having the ability to load options through initial AJAX call when the current value is null.

    You've pointed out it's achievable through other means, although I don't necessarily agree with this:

    I'm not sure [having options initially loaded through AJAX] would be used often enough to warrant being in the API

    A visitor to my site could be either a viewer or an editor.

    If they're a viewer, then I'd prefer to not load the options with the DataTable since they won't be editing.

    But if they're an editor, then I could:
    1) load the initial options with the DataTable or
    2) load the initial options when the editor is opened.

    Loading with the DataTables requires me to either:
    1) always load them (which is excessive for users who I know are not doing any editing) or
    2) conditionally load them with the DataTable based on if the visitor is a viewer or an editor

    But if the initial options are loaded with AJAX when the form is opened then I don't have to fiddle with the DataTable at all, I just write my query on the backend to handle the initial options for a null value.

    For me, it allows a better separation of concerns for viewing and editing.

    Anyway, there's my pitch for the option to load some initial options through AJAX!

Sign In or Register to comment.