Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Semantic UI doesn't replace the {value} in a GET route when loading dropdown options remotely

Here's my API setup:

//-------------------------------------------------------------------------
// Define API endpoints once globally.
//-------------------------------------------------------------------------
$.fn.api.settings.api = {
  'find cool cats' : '/search/coolcats?query={value}'
};

The route returns a proper JSON response as per the documentation:

// For example, "http://localhost:3000/search/coolcats?query=cool" returns this limited array of results:

{
    "success": true,
    "results": [
        {
            "name": "Cool Cat Cooper",
            "value": "Cool Cat Cooper"
        },
        {
            "name": "Cool Cat Charlie",
            "value": "Cool Cat Charlie"
        },
        {
            "name": "Cool Cat Mittens",
            "value": "Cool Cat Mittens"
        }
    ]
}

I append this HTML inside a form at some point (it's the same "Favorite Animal" code from the documentation reference above):

var coolCatsField = '<div class="field">';
        coolCatsField += '<label>Find a cool cat:</label>';
        coolCatsField += '<div class="ui fluid search selection dropdown cool_cat_search">';
            coolCatsField += '<input type="hidden">';
            coolCatsField += '<i class="dropdown icon"></i>';
            coolCatsField += '<input type="text" class="search" tabindex="0">';
            coolCatsField += '<div class="default text">';
                coolCatsField += 'Start typing to search or add';
            coolCatsField += '</div>';
            coolCatsField += '<div class="menu" tabindex="-1"></div>';
        coolCatsField += '</div>';
    coolCatsField += '</div>';

$('#someFormField') // Is a <div class="field">...</div> as well.
    .after(coolCatsField);

And initialize a .dropdown() with API settings on it:

$('.cool_cat_search').dropdown({
    apiSettings : {
        action   : 'find cool cats',
        throttle : 500
    }
});

Semantic UI should append route value automatically, but it doesn't work for dropdowns apparently, and I get an error:

API: Missing a required URL parameter: value /search/coolcats?query={value}


What I tried

Adding a urlData property; it replaces {value} to an empty string as a result, because jQuery's .val() can't catch anything even if there're a lot of characters inside a .search input (and I made sure it was connecting to the server after each character). Firing .val() afterwards in a console returned whatever I entered in a field, though.

$('.cool_cat_search')
    .dropdown() // I think it should be initialized first for .val() to work.
    .dropdown({
        apiSettings : {
            action   : 'find cool cats',
            throttle : 500,
            urlData  : {
                value : $('.cool_cat_search .search').val()
            }
        }
    });

Of course, I also tried to see if it all worked in general, and it did as should with all front-end bells and whistles:

$('.cool_cat_search')
    .dropdown({
        apiSettings : {
            action   : 'find cool cats',
            throttle : 500,
            urlData  : {
                value : 'cool'
            }
        }
    });

I also tried using Semantic UI's means of getting a value instead of jQuery's .val() inside a urlData property, no luck. I don't understand how it works at all, in fact, maybe I should initialize it on the .search input, but either way, it returns an empty string or an object.

$('.cool_cat_search')
    .dropdown('get value');

Before I copied that HTML from the documentation I tried initializing a dropdown on a select tag, which produced a slightly different HTML than the one above. Again, it worked as a dropdown, but had similar problems with retrieving remote content.

var coolCatsField = '<div class="field">';
        coolCatsField += '<label for="cool_cat_search">Find a cool cat:</label>';
        coolCatsField += '<select id="cool_cat_search" class="ui fluid search selection dropdown" name="query"><option value="">Start typing to search or add</option></select>';
    coolCatsField += '</div>';

I also tried using Semantic UI's .api() method directly on .search input, it successfully and automatically replaced the {value} from the route and retrieved a server response, but failed to append those results to a dropdown, even though I specified the stateContext property:

$('.cool_cat_search .search')
    .api({
        action       : 'find cool cats',
        stateContext : '.cool_cat_search' // UI state will be applied to the dropdown element, defaults to triggering element.
    });

So, I can't replace the route {value} automatically, and I can't set it manually with urlData property. The documentation is vague, but it works there, so I guess I did something wrong; thank you very much for your time, and I'm sorry I couldn't provide a JSFiddle to work with, but maybe you'll notice a mistake somewhere anyway.

like image 485
awgv Avatar asked Feb 09 '23 20:02

awgv


2 Answers

I have had exactly the same problem recently, but did not have time to submit a bug report because of time constraints. I managed to replicate your issue on a jsfiddle and the only way I got it to work was to override the settings object just before sending the request:

$('.ui.dropdown')
  .dropdown({
    apiSettings: {
        action   : 'find cool cats',
        throttle: 500,
        beforeSend: function(settings) {
            settings.urlData = {
                value: $('.ui.dropdown .search').val()
            };

            return settings;
        }
    }
  });

http://jsfiddle.net/Lwwonzte/

like image 101
J3Y Avatar answered Feb 11 '23 08:02

J3Y


The associated GitHub issue was closed, and apparently we found the solution to the problem that never existed: '/search/coolcats?query={value}' doesn’t work, because the value is always being passed as {query} instead of {value}; change that, and it should work.

The original example should look like so:

//-------------------------------------------------------------------------
// Define API endpoints once globally.
//-------------------------------------------------------------------------
$.fn.api.settings.api = {
  'find cool cats' : '/search/coolcats?query={query}'
};

Here’s a JSFiddle.

like image 24
awgv Avatar answered Feb 11 '23 10:02

awgv