I can't seem to figure out how to make this thing work, wherever i put this binding it won't work
Here's my script
<a class="dropdown-toggle expanded" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" data-bind="hasFocus:notificationService.aaaa">
this.aaaa = ko.observable(false);
And my html
<span data-bind="text:notificationService.aaaa"></span>
Where notificationService is an Object passed with Require. Everything else works, but not this hasFocus
Any clues?
If notificationService is an observable, your binding needs to be
data-bind="hasFocus:notificationService().aaaa"
(with the invocation parentheses after notificationService). Also, you need to add tabindex to the <a> tag, as your anchor is not a link (it has no href) and so it would not normally be able to be focused.
const vm = {
notificationService: ko.observable({
aaaa: ko.observable(false)
})
};
ko.applyBindings(vm);
setTimeout(() => {
vm.notificationService().aaaa(true);
}, 800);
a:focus {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<a class="dropdown-toggle expanded" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" data-bind="hasFocus:notificationService().aaaa" tabindex="0">Anchor</a>
<span data-bind="text:ko.toJSON(notificationService)"></span>
Related
I've just started using Vue, (which seems really nice) and I've run into an issue.
I have a bootstrap4 dropdown that I'm using to populate a hidden form (clicking on a dropdown-item saves the data value to the form below).
This is only done as I can't style the normal select/option dropdown as I would like.
This was all working fine, until I tried implementing vue, as I'm not using a select component directly the solutions offered in the vue select documentation don't seem to work.
Any help would be much appreciated.
Thanks in advance
html
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle device-dropdown" type="button" data-toggle="dropdown" aria-haspopup="true"
aria-expanded="false">
All Devices
</button>
<div class="dropdown-menu" aria-labelledby="device-dropdown">
<a class="dropdown-item" href="#" data-value="all">All Devices</a>
<a class="dropdown-item" href="#" data-value="imac">iMac</a>
<a class="dropdown-item" href="#" data-value="macbook">MacBook</a>
<a class="dropdown-item" href="#" data-value="ipad">iPad</a>
<a class="dropdown-item" href="#" data-value="iphone">iPhone</a>
</div>
<select name="device" class="hidden-device-dropdown">
<option></option>
</select>
</div>
js
// copies the selected dropdown element into a hidden select in the form
$('.dropdown-menu').click(function (e) {
e.preventDefault();
// change button text to selected item
var selected = $(e.target);
$(".device-dropdown").text($(selected).text());
// change option value (inside select) to selected dropdown
var form = $("select.hidden-device-dropdown").children("option");
$(form).val(selected.data("value"));
});
Edit: looks like v-on:click="device = '...'" might get me the functionality I'm after, is this a good way of doing it? seems to be duplicating a lot of code
I would suggest a component.
Vue.component("bs-dropdown",{
props:["options", "value"],
template:`
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle"
:class="id"
ref="dropdown"
type="button"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false">
{{selected.text}}
</button>
<div class="dropdown-menu" :aria-labelledby="id">
<a class="dropdown-item"
href="#"
v-for="option in options"
#click="selected = option">
{{option.text}}
</a>
</div>
</div>
`,
computed:{
selected:{
get() {return this.value},
set(v){this.$emit("input", v)}
},
id(){
return `dropdown-${this._uid}`
}
},
mounted(){
$(this.$refs.dropdown).dropdown()
}
})
This component wraps the bootstrap functionality, which is what you typically want to do when integrating with external libraries.
Use it like so:
<bs-dropdown :options="devices" v-model="selected"></bs-dropdown>
Here is a codepen demonstrating it in action.
If/when you need the value, instead of copying it to a hidden select, the value is a data property bound with v-model. You can use that however you like.
I have an HTML page with a dropdown list, which represent specific time as follow:
<div class="dropdown form-group col-xs-5" style="padding-right: 20px;">
<label for="time">Temps</label>
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
5 sec<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1" id="timeChoice">
<li>5 sec</li>
<li>10 sec</li>
<li> 15 sec</li>
<li>30 sec</li>
</ul>
</div>
I want to create a function which identify the time and return a value assigned with this time. For instance when user click sec5 the function put in the variable timeOption = 5000;
I use javascript and jQuery for that:
$('#act1').click(function(e) {
var timeOption = 5000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
});
$('#act2').click(function(e) {
var timeOption = 10000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
});
$('#act3').click(function(e) {
var timeOption = 15000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
});
$('#act4').click(function(e) {
var timeOption = 30000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
});
How to add a return statement with specific value ?
Change your code little bit. Add data attribute to every anchor tag and then write click handler
$('#timeChoice').on("click", "a", function(e) {
var timeOption = e.target.getAttribute('data-time')*1000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dropdown form-group col-xs-5" style="padding-right: 20px;">
<label for="time">Temps</label>
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
5 sec<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu1" id="timeChoice">
<li>5 sec</li>
<li>10 sec</li>
<li> 15 sec</li>
<li>30 sec</li>
</ul>
</div>
You are asking for a return statement, but that is not the right approach, because an event callback isn't called from a context where you can handle the function's return value (the return value ends up in a jQuery function and gets handled there). You want to make your timeOption value visible to some other function, which you can do in various ways. In this case, I would suggest passing the value to a function:
$('#act1').click(function(e) {
var timeOption = 5000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
handleTimeOption(timeOption);
});
$('#act2').click(function(e) {
var timeOption = 10000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
handleTimeOption(timeOption);
});
$('#act3').click(function(e) {
var timeOption = 15000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
handleTimeOption(timeOption);
});
$('#act4').click(function(e) {
var timeOption = 30000;
alert(timeOption);
e.preventDefault();// prevent the default anchor functionality
handleTimeOption(timeOption);
});
function handleTimeOption(timeOption) {
// Here goes whatever code you want to run when a time option has been selectedl
}
I have a bootstrap dropdown menu that is populated with time zone information. The dropdown is correctly populated but when i click on the dropdown and press a key on the keyboard (for example "P") it does not select an appropriate item on the list. The code for the dropdown is bellow.
HTML
<select class="form-control" name="timeZone" ng-model="engagement.timeZone" ng-init="engagement.timeZone=timezones[37].code" ng-options="timeZone.code as timeZone.name for timeZone in timezones" required></select>
The output is something like this.
What i want is if i press A on the keyboard first item matching the letter should be selected. (not to be confused with a filtering like behaviour)
UPDATE
This does not seem to relate to bootstrap at all. I removed all the bootstrap classes and it still is the same. May be something to do with Angular?
As you know using Boostrap drop-down components you are not able to select an element by pressing the Keyboard Letter. So you can utilize the following code which uses a directive;
myApp.directive('keypressEvents',
function ($document, $rootScope) {
return {
restrict: 'A',
link: function (scope, element, attr) {
console.log('linked');
$document.bind('keypress', function (e) {
$rootScope.$broadcast('keypress', e, String.fromCharCode(e.which));
var letter = String.fromCharCode(e.which);
var target = e.target;
var charat = element[0].textContent.charAt(0);
if(charat === letter){
element.addClass("red");
}
});
}
}
});
Up there, you get to see the directive used, it simply is bounding on the keypressed and in the end set the class for the element found with the very same first letter. Nevertheless, you just need to set the focus on this;
<div class="dropup">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropup
<span class="caret"></span>
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenu2">
<li keypress-events>action</li>
<li keypress-events>something else here</li>
</ul>
</div>
As you can see, the directive has been bounded on the li elements.
I have a razor syntax enumdropdownlist for displaying either active/inactive status.
#Html.EnumDropDownListFor(model => model.Status, new { #class = "btn btn-default btn-lg dropdown-toggle" })
I want to use a button group drop down with glyphs like I have below but don't know how to get my model value 'model.Status' to set the value of the button group drop down.
$(document).ready(function() {
$('#item1').on('click', function() {
$('#item0').text('Active');
});
$('#item2').on('click', function() {
$('#item0').text('Not Listed');
});
});
<div class="btn-group">
<button id="item0" type="button" class="btn btn-default">Action</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li id="item1">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>Active
</li>
<li id="item2">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>Not Listed
</li>
</ul>
</div>
I don't care if I use html or razor, I just want to use the boostrap button drop down with glyphs and I want to be able to set the enumerated view model value active/inactive (Status) when the page loads.
Although the Bootstrap dropdown buttons look similar to a select list, their functionality is vastly different. I wouldn't recommend trying to use a Bootstrap dropdown button as a replacement for a select list if you need to actually post the "selected" item.
If you're just looking for a more stylistic and visually appealing alternative to a traditional select control, take a look at something like Select2, and while the look is pleasant enough out of the box, there's also a project that styles it to fit even better with the rest of Bootstrap.
If you're dead set on using Bootstrap dropdown buttons, you've got a lot of work ahead of you. You'll need to set up some JavaScript that will read the information from the select element and dynamically create the Boostrap dropdown button based on that, while hiding the original select. Then, you'll need to map over all the events such as a click on one of the items in the dropdown so that it selects the same item in the actual select element. You'll also have to account for highlighting the item in the dropdown that corresponds with the selected option in the select list, etc. If you run into specific problems while writing all that code, you can ask additional questions here as necessary, but providing you with all the code you'll need here is far beyond the scope of StackOverflow.
You can try to enumerate through enum values and put them in page, please notice the Html.HiddenFor from the end, we will use it to store the selected Status.
<div class="btn-group">
<button id="item0" type="button" class="btn btn-default">Action</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
#{
var values = Enum.GetValues(typeof(Status));
for(int i=0; i < values.Count; i++)
{
var status = (Status)values[i];
<li id="item#(i+1)" class="select-status" data-status="#values[i]">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>#status.ToString()
</li>
}
}
</ul>
</div>
#Html.HiddenFor(model => model.Status)
After we create the html we have to update the selected Status in Html.HiddenFor to persist when a POST is performed.
$(document).ready(function() {
$('.select-status').click(function(){
$('#Status').val($(this).data('status')); // update the status in hidden input
});
#for(int i=0; i < values.Count; i++)
{
<text>
$('#item#(i+1)').on('click', function() {
$('#item0').text('#status.ToString()');
});
</text>
}
});
HTML snippet example:
$(document).ready(function() {
$('.select-status').click(function(){
$('#Status').val($(this).data('status')); // update the status in hidden input
});
$('#item1').on('click', function() {
$('#item0').text('Active');
});
$('#item2').on('click', function() {
$('#item0').text('Not Listed');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<!-- Optional theme -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<!-- Latest compiled and minified JavaScript -->
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div class="btn-group">
<button id="item0" type="button" class="btn btn-default">Action</button>
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu" role="menu">
<li id="item1" class="select-status" data-status="1">
<span class="glyphicon glyphicon-ok" aria-hidden="true"></span>Active
</li>
<li id="item2" class="select-status" data-status="2">
<span class="glyphicon glyphicon-remove" aria-hidden="true"></span>Not Listed
</li>
</ul>
</div>
<br />
Visible Status just for test
<input type="text" id="Status" value="1" />
Note: The code may have some errors but the logic/flow is the same.
In .cshtml file
<script>
myModelStatus = '#Model.Status';
</script>
#Html.EnumDropDownListFor(model => model.Status, new { #class = "btn btn-default btn-lg dropdown-toggle" })
more html here...
In your js file
$(document).ready(function() {
var status = myModelStatus;
$('#item1').on('click', function() {
$('#item0').text('Active');
});
$('#item2').on('click', function() {
$('#item0').text('Not Listed');
});
});
You are listening for click events on the li element rather than on the anchor tag
You should stop event propagation by using event.preventDefault() method.
When I click on the input my dropdownmenu is expanded, what I need is to expand it automatically Onkeyup event.
I'm trying the following but not working.
HTML
<div class="btn-group DropDownMenu">
<input id="input1" class="btn btn-default dropdown-toggle btn-select" data-toggle="dropdown" type="text" onkeyup = "Filter()">
<ul class="dropdown-menu">
<li></li>
</ul>
</div>
JavaScript
function Filter() {
//some other code
$("#input1").click();
}
Any thoughts ? I'm using bootstrap btw
remove class="dropdown-toggle" and data-toogle="dropdown" from input and this to JS
$(".dropdown").keyup(function (event) {
//preventing default behaviour of bootstrap
event.stopPropagation();
$('.dropdown-menu').dropdown().toggle();
});
I don't know where have you written the javascript.
I have created a fiddle and changed the javascript a little:
window.Filter = function() {
$("#input1").click();
}
it is working in the fiddle. http://jsfiddle.net/dyo8fowt/