Semantic-ui: [Dropdown] - Error behavior "setup menu"

Created on 16 May 2016  Â·  15Comments  Â·  Source: Semantic-Org/Semantic-UI

Steps to Reproduce
$('#selectID').dropdown('setup menu');

Expected
Recreates dropdown menu from select option values.

Result
In Console:
Uncaught TypeError: Cannot read property 'values' of undefined

Testcase
http://jsfiddle.net/agvg0L3j/1/

Confirmed Bug Docs Issue

Most helpful comment

Having massive issues with the dropdown module and API as a whole, seems very inconsistent in the current build.

setup menu while undocumented, actually requires an argument with a structure such as this:

$el.dropdown('setup menu', {
            values: [
                {
                    value: '2016',
                    text: '2016',
                    name: '2016'
                },
                {
                    value: '2015',
                    text: '2015',
                    name: '2015'
                }
            ]
        });

Alternatively, replacing the entire html of <select> should cause the dropdown observer to re-render the dropdown module, updating selected value from the new <select> html. It does not update the text tho, for whatever reason. Also it looks like when calling setup menu it actually re-renders twice, not once.

All 15 comments

I'm having the same issue in here with version 2.1.7 and 2.2.0 so the error remains. This is bad, because that's the only function to rebuild the dropdown.

Same here

Having massive issues with the dropdown module and API as a whole, seems very inconsistent in the current build.

setup menu while undocumented, actually requires an argument with a structure such as this:

$el.dropdown('setup menu', {
            values: [
                {
                    value: '2016',
                    text: '2016',
                    name: '2016'
                },
                {
                    value: '2015',
                    text: '2015',
                    name: '2015'
                }
            ]
        });

Alternatively, replacing the entire html of <select> should cause the dropdown observer to re-render the dropdown module, updating selected value from the new <select> html. It does not update the text tho, for whatever reason. Also it looks like when calling setup menu it actually re-renders twice, not once.

@wubzz I appreciate your answer here. If anyone else comes here looking to also set those values as selected you need to combine 'setup menu', like the answer above, followed with
$el.dropdown('set selected', ['2016','2015']);
Basically pass an array with your values that you want selected.

I'm also finding that when using a dropdown that has had setup menu used on it any subsequent calls of .dropdown('get text') work as expected but .dropdown('get value') returns null - anyone else had this... got a fix?

bit more investigation... If I replace the entire select element and then call setup menu with the associated options then .dropdown('get value') works as expected. I would expect the setup menu method to replace the select stuff for me... maybe I'm misunderstanding it's purpose?

I'm experiencing the same thing as timdiacon. After running setup menu, subsequent calls of .dropdown('get value') do not return the correct values.

Same issue here.
Version 2.2.6

Why should one put those values again?

How can one re-initialise the dropdown on a select after complete overwriting the dropdown with Ajax?

Not sure if the documentation should be changed, or the behavior of setup menu should be changed—the documentation states that the method “recreates dropdown menu from select option values”; I’m assuming any changes to a hidden select should be reflected in an actual dropdown after setup menu is called, does that sound right?

I reinitialized dropdown strange way (maybe you know better one way - I hope :) )
What I did I reconstructed menu HTML based on AJAX result. The fragment this.dropdownItems.next(results); sends received data to Angular (using RxJS) for menu part rendering. In OnCompletion part I just fire set selected behavior after short period (to be sure Angular/zone.js processed events and rendered menu html). When I was using get item * behavior without setTimeout it gave me proper HTML element, but setting selection of it through *set selected had no effect (although get item succeeded).

       .subscribe(
            // On successs
            (results: any[]) => {
                this.loading.next(false);
                this.dropdownItems.next(results);
                lastResult = results;

                //fireInitializationSync.next(true);
            },
            // On error
            (err: any) => {
                console.log(err);
                this.loading.next(false);
            },
            // On completion
            () => {
                this.loading.next(false);
                console.log("Completed");

                setTimeout(() => {
                    for (var resElem of lastResult) {
                        let elemId = resElem.value;
                        let callResult = $(dropDownElem).dropdown('set selected', elemId);
                        console.log(callResult);
                    }
                },100);

            });

This is my dropdown definition:

    <div class="ui multiple dropdown" #dropdownEditor>
        <input type="hidden" name="filters">
        <i class="filter icon"></i>
        <span class="text">{{filterMessage}}</span>
        <span class="menu">
            <!--<span class="header">Search Dictionary Values</span>-->
            <span class="ui icon input" [class.loading]="loading|async">
                <i class="search icon"></i>
                <input type="text" 
                       placeholder="{{filterMessage}}" 
                       #dropdownSearchBox>
            </span> <!--[attr.disabled]="(loading|async)?'':null" -->
            <span class="spanider"></span>
            <span class="header">
                <i class="tags icon"></i>
                <span>{{dictionaryCode}}</span>
            </span>
            <span class="scrolling menu">

                <span *ngFor="let elem of dropdownItems|async; let i = index; let isFirstElem=first; let isLast=last;" 
                      class="item" 
                      [attr.data-value]="elem.value">
                    <span class="ui red empty circular label"></span>
                    <span *ngIf="elem.code!=null">{{elem.code}}: </span>
                    <span>{{elem.text}}</span>
                </span>

            </span>

            <div class="divider"></div>
            <span class="header">
                <i class="calendar icon"></i>
                <span>Special values</span>
            </span>

            <span class="item"
                  data-value="null">
                <span class="ui red empty circular label"></span>
                <span>Empty</span>
            </span>

        </span>
    </div>

I'm trying to reload a dropdown linked to the change event of another dropdown. In doing this I've run into the same problems everyone else has. I applied the answer provided by wubzz, and it works, but not the first time.

You can see here that you have to refresh twice in order to get the dropdown to reload. I tried hacking it to run twice, but that only works with the 2nd execution using an async timeout.
https://jsfiddle.net/h9opjj3a/5/

I love semantic, but your dropdown is not up to par. The honest truth is that it's overly complex and confusing. I'd love it for the entire thing to be redesigned and redone.

Leaving traces and looking for better solutions.

I'm adding a new setting in next version for setting up dropdowns in JS and re-initializing dropdowns in js

Code looks like this

$('.ui.dropdown')
  .dropdown({
    values: [
      {
        name: 'Male',
        value: 'male'
      },
      {
        name     : 'Female',
        value    : 'female',
        selected : true
      }
    ]
  })
;

I've created a few examples to showcase all the different ways dropdowns can be initialized with new settings object.
https://jsfiddle.net/Lb7c5dkz/

I've also fixed a related issue where replacing the entire <select> inside a dropdown would not update the dropdown automatically (you can see an example where I remove whole <select> in fiddle)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

guilhermeblanco picture guilhermeblanco  Â·  3Comments

zhaoyao91 picture zhaoyao91  Â·  3Comments

ghost picture ghost  Â·  3Comments

Morrolan picture Morrolan  Â·  3Comments

larsbo picture larsbo  Â·  3Comments