Reputation: 544
I am currently attempting to make a dropdown menu where selecting one of the links from the menu will change the hidden value as well as the text of the hyperlink. This is based upon Twitter's Bootstrap dropdown, and uses jQuery:
<div id="periodChooser" class="btn-group">
<input type="hidden" value="1" name="dtype" id="dtype1"></input>
<a data-toggle="dropdown" href="javascript:;">Weekend</a>
<ul class="dropdown-menu">
<li><a href="javascript:;" data-value="1">Weekend</a></li>
<li><a href="javascript:;" data-value="2">Week</a></li>
<li><a href="javascript:;" data-value="3">Midweek</a></li>
</ul>
</div>
The script that I have attempted to write is as follows:
<script>
jQuery(function($){
$('#periodChooser').each(function() {
$('.dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
});
});
</script>
Unfortunately, whilst it doesn't return any specific error, the code does not work. Any suggestions?
Upvotes: 0
Views: 156
Reputation: 2760
I think that this can be optimized and made more re-usable.
First of all, you are using jQuery selectors like $('.btn-group')
very ineffectively.
Secondly it will break, if you will use more than one "widget", because the context is whole document and it will find all elements with that class .btn-group
.
Thirdly it would be more effective to use single event handler that is being binded to the parent <ul>
element instead of each <a>
element. It's called "event delegation". http://api.jquery.com/delegate/
<script>
$('#periodChooser').each(function() {
var $input = $('input', this),
$select = $('>a', this);
$('ul', this).on('click', 'a', function() {
var $this = $(this);
$input.val($this.data('value')).change();
$select.html($this.html());
});
});
</script>
I made this code available in JSBin: http://jsbin.com/welcome/38724/edit
What I did here?
<script>
$('#periodChooser').each(function() {
// Find and store input and "select" element only once.
var $input = $('input', this),
$select = $('>a', this); // This finds only direct child element <a>
// Find the <ul> element inside the #periodChooser
// Bind a click event that will "bubble up" from <a> elements that are children of it
$('ul', this).on('click', 'a', function() {
// Wrap a jQuery around the <a> element
var $this = $(this);
// Set the input value and execute "change" event(s)
$input.val($this.data('value')).change();
// Change the "select" title. Doesn't matter if you use html() or text() - choose yourself!
$select.html($this.html());
});
});
</script>
Now, you can use this to make multiple widgets inside single page! :)
<script>
$('.btn-group').each( /* Well, you know, the function goes here... */ );
</script>
Of course, threre are many other things that has to be done here, like opening and closing the "option list", scrolling and probably many other things...
Upvotes: 0
Reputation: 148110
Bind event out side each
<script>
$('#periodChooser .dropdown-menu a').click(function() {
$('.btn-group').find('input[type=hidden]').val($(this)
.data('value')).change();
$('.btn-group').find('.btn:eq(0)').text($(this).text());
});
</script>
Upvotes: 1