I am using Semantic UI 2.0 and trying to use data returned from its API to build the options inside my dropdown.
For the dropdown itself, I am using a code that is pratically the same as this code shown in Semantic UI's documentation:
<div class="ui search selection dropdown select-city">
<input type="hidden" name="city">
<i class="dropdown icon"></i>
<div class="default text">Select City</div>
</div>
I have a service that returns json-formatted cities, then Semantic UI shows in the console that the result was successful with all 261 cities:
"Using specified url" ["/cities/"] 1648
"Querying URL" ["/cities/"] 0
"Sending request" [undefined, "get"] 0
"Successful API Response" [Object { success=true, results=[261]}]
The /cities endpoint return a json formatted as:
{"success":true,"results":[{"description":"Opole","data-value":1},{"description":"Wrocław","data-value":2},{"description":"Warszawa","data-value":3},{"description":"Budapest","data-value":4},{"description":"Köln","data-value":5}, ...]}
It looks like that Semantic UI does not directly understand the format of the json.
I've tried many formats of json attributes, even tried to change a bit the html. For instance, tried to add an empty <div class="menu"> in the bottom of the select, hoping that Semantic UI would fill it in, e.g.,:
<div class="ui search selection dropdown select-city">
<input type="hidden" name="city">
<i class="dropdown icon"></i>
<div class="default text">Select City</div>
<div class="menu"></div>
</div>
I am trying to match the format of the attributes with the ones from the example, e.g., using "data-value" attribute.
But it did not work either, I've seen Semantic UI checks for that in the source code, so it does not make any difference. At the end, my problem persists and no items are inserted into the dropdown selection.
Without you posting the code that you're using I'm taking a bit of a stab here, but the dropdown expects data results to be keyed as { name: "Item 1", value: "value1" } as is explained in the relevant part of the documentation.
If you have a different field names then you can provide a fields structure in the settings to override these:
$('.ui.dropdown').dropdown({
fields: { name: "description", value: "data-value" },
apiSettings: {
mockResponse: {
success: true,
results: [
{"description":"Opole","data-value":1},
{"description":"Wrocław","data-value":2},
{"description":"Warszawa","data-value":3},
{"description":"Budapest","data-value":4},
{"description":"Köln","data-value":5}
]
}
}
});
The minimum HTML required is:
<div class="ui search selection dropdown">
<div class="text">Search</div>
</div>
or:
<div class="ui search selection dropdown">
<input class="search"></input>
</div>
The empty <div class="menu"></div> is automatically inserted, but an <input class="search"></input> is required and is only automatically inserted if you already have a <div class="text"></div> element.
Note however that, in what I believe to be a fault with the dropdown behaviour, it will not load the data until you start typing into the search field and so just clicking on the dropdown icon is not sufficient.
Related
I'm stuck in a form, I am wondering how can I display an image inside a select option.
Inputs will load text.
What I'm trying to do...
What is the best way to make this work inside the form?
This is what I've done.
So my code is this because <select><option><img href=""></option></select> wont work.
<div class="input-group mb-3">
<input type="text" class="form-control" aria-label="Text input with dropdown button">
<div class="btn-group">
<button type="button" class="no-border btn btn-secondary dropdown-toggle dropdown-toggle-split" id="dropdownMenuReference" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" data-reference="parent">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu " aria-labelledby="dropdownMenuReference" style="position: absolute;transform: translate3d(-352px, 35px, 0px);min-width: 380px;overflow-x: hidden;" x-placement="bottom-start">
#foreach($categories as $category)
<a class="dropdown-item" href="#"><img class="rounded" src="/storage/category-icon/{{$category->business_icon}}">{{$category->business_name}}</a>
#endforeach
</div>
</div>
</div>
What is the best practice for this?
(using bootstrap 4 and laravel btw)
Since it is not possible to do that with native HTML elements, you cannot make it work without Javascript. Therefore you at least need a hidden input field (<input name="foo-bar-baz" type="hidden value="…" />) to transfer the data between the server and the client. The data could be a simple serialized JSON Object like so:
[
{
"label": "Click ME",
"icon": "/img/icon.png",
"value": "item-xxx"
},
…
]
Going from there you need to write some Javascript code that generates something that looks like a <select> but isn't. Each change on that »virtual field« needs to modify the respective hidden one's value, such that at submission, the correct value is transferred to the server.
Here I could find an example based on bootstrap, maybe that is helpful. It renders a <ul><li></li>…</ul> list to display the »virtual field«.
One possible solution maybe found here.
To sum up, you need to find a proper Javascript library that helps you doing it, or write some code by yourself to make it. Which one to choose strongly depends on your needs and requirements.
Another thing to keep in mind here is accessibility — what should happen if the user has Javascript disabled, or uses a browser that has problems to execute the code provided. Then it might be a good starting point to render a regular <select> and use data attributes to inject images like so:
<select name="foo-bar-baz">
<option value="value" data-icon="/path/to/icon">Label</option>
</select>
which yields a working form element, which then can be enriched with icons, in case Javascript works properly.
So to answer the question: IMHO best practice is the solution which always works and doesn't exclude users without Javascript, a screen reader or a text-based browser. So the solution provided above, starting with a regular <select>, which should be progressively enhanced, is what I would call best practice here.
I started to use Semantic UI recently and I got into this very frustrating situation, where in the search bar, when I change the php file that sends the same syntax, the result is not loading anymore under the search bar. Any ideas what could be the problem? It looks so simple and elementary, but it just doesn't work.
These are the two twin files and their result:
keyword_suggest.php?term=sauerkraut
returns:
{"results":[{"name":"Sauerkraut, canned, solids and
liquids","url":"product.php?id=11439"}]}
and also this file
sci_name_suggest.php?term=sinapis
returns:
{"results":[{"name":"Sinapis alba and Brassica juncea","url":"produs.php?id=2024"}]}
Considering that they both return the same syntax, how is it possible that when I change from first file to the second, there are no results in the Semantic UI search bar?
This is the javascript that I use:
function page_home() {
$('.ui.search')
.search({
apiSettings: {
url: '//www.website.com/keyword_suggest.php?term={query}'
},
fields: {
results: 'results',
title: 'name'
},
minCharacters : 2
})
;
}
if($('.page_home').length) {
page_home();
}
In the second example I changed the url to:
//www.website.com/sci_name_suggest.php?term={query}
But it doesn't load the result, even though there is one result for "sinapis".
How is it possible? They both send back the same syntax.
At the end of both php files there is this json:
echo '{"results":' . json_encode($values) . '}';
This is the Semantic UI search bar:
<div class="ui attached stackable">
<div class="ui container page_home">
<div class="ui center aligned grid">
<div class="">
<h2>Search in database:</h2>
<div class="ui right aligned search">
<div class="ui left icon input">
<input class="prompt" type="text" placeholder="Search...">
<i class="search icon"></i>
</div>
</div>
</div>
</div>
</div>
</div>
Any ideas and suggestions are appreciated, thank you !
I suggest you check the console for warning, errors, semantic ui will act this way if the request is not successful. Also make sure you handle the Cross-Origin Policy properly.
I use Vue.js in most of my (amateur) frontend development and I am stuck with a simple case I cannot understand.
In the code below, the content of the search box (an <input>) is transformed into an Array, which is then iterated against to create some links (<a>):
var vm = new Vue({
el: "#search",
data: {
search: '',
results: []
},
watch: {
search: function() {
this.results = this.search.split('')
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.min.js"></script>
<h2>a dropdown</h2>
<div class="dropdown" id="search">
<input type="text" v-model="search">
<div id="myDropdown" class="dropdown-content">
<a :href="#e" v-for="e in results">{{e}}</a>
</div>
</div>
Why isn't the <input> displayed?
Note 1: When inspecting the code in Chrome, I see
<h2>a dropdown</h2>
<!---->
and such a comment is usually a sign that Vue.js has explicitly not rendered something.
Note 2: When refreshing the page, I see a very brief glimpse of the input field, so it is rendered, then hidden by (I assume) Vue.js.
If you properly bind the href attribute like :href="'#' + e" it works. Vue.js somehow seems to get confused by that otherwise.
This is an AngularJS application (1.2.16). I browse to a dialog to edit some item. One of the controls is a multi-SELECT with the following visible values:
incident
work order
These visible values correspond to the following data values:
INCIDENT
WORK_ORDER
This is done through using the ng-options=" ... as ... for ... in ... " pattern, using an enumeration:
var FlexFieldSubjectTypeEnum = {
INCIDENT:{name:"INCIDENT", description:"incident"},
WORK_ORDER:{name:"WORK_ORDER", description:"work order"}
}
If have a form pretty much as follows:
<form ng-submit="save(formName)" name="formName" class="form-horizontal">
...
<div class="control-group">
<label class="control-label">Subject type:</label>
<div class="controls">
<select name="subjectType"
ng-options="type.name as type.description for type in getEnumAsArray('FlexFieldSubjectTypeEnum') | orderBy:'name'"
ng-model="entity.subjectType"
required></select>
</div>
</div>
Now, if the dialog loads the item ($scope.entity) from the backend and entity.subjectType is set to the first item in the list, the form validation marks it as unset. I have many other dialogs with similar constructs and have not seen this problem anywhere else.
If the item returned from the backend points to the second item (WORK_ORDER), this is nicely represented in the SELECT ("work order") and there is no validation error.
The problem does exist equally when using required or ng-required="true".
The problem does not exist if I remove the required attribute, but then the field also suddenly becomes optional, which is not what I wanted.
Your help much appreciated!
Almost a month later, with meanwhile an upgrade from Bootstrap v2.2.2 to v3.1.1 the problem disappeared.
I am using bootstrap-select plugin (http://silviomoreto.github.io/bootstrap-select/) to provide an option to select multiple values. I have a hash table with letters as key and words starting with corresponding letter as values. I have a drop down with list of letters and once a letter is selected the multi select box should be populated with the words for that letter.
.cshtml
<div class="row word-letter">
<div class="col-md-3">
<div class="input-group">
<input type="text" class="form-control dropdown-text letterVal" placeholder="Select Letter" autocomplete="off" />
<div class="input-group-btn">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right letterList"></ul>
</div>
</div>
</div>
<div class="col-md-5">
<select class="selectpicker" multiple title="No words available"></select>
</div>
</div>
Once the letter from letterList is selected, the selectpicker should be populated with options corresponding to that letter in wordMap. And also the default title should change from "No words available" to "Select from following words". Below is the code snippet, theObject here is jquery handle to the dropdown-menu.
.js
var wordMap = {
"A": ["Aware", "Analog"],
"D": ["Dare", "Digital"],
"F": ["Flare", "Fist", "Frame"]
};
var selectedLetter = theObject.text();
var wordSelectElem = theObject.parents('.word-letter').find('.selectpicker')
if (wordSelectElem.length > 0) {
$.each(wordMap[selectedLetter], function (key, value) {
wordSelectElem.append($('<option>' + value + '</option>'));
});
if (wordSelectElem.size() > 0) {
wordSelectElem.prop('title', "Select from following words");
}
wordSelectElem.selectpicker('refresh');
}
When I run this in IE, I am seeing that the selectpicker adds the words in a weird way as below (eg: when D selected):
How can I fix this?
My best guess, from what I see above, is that you have a bit of errant CSS that is causing the problem. This would be very easy to locate using FireBug or any other browser based developer tools that will allow you to see what CSS is being applied to that element (or perhaps the surrounding elements).
If you can even post a link to the page in question (send it privately if there is concern about a public link) and I (or anyone else) can look at the elements in question.
If you try to reproduce this in JSFiddle and can't then all the more reason suspect the problem is local your CSS or code. Try removing all CSS files on the page except the Bootstrap.css and whatever CSS file comes with this control.