i needed to use a dropdown list that could do that functionality:
- dynamically fetches and loads values from the database
- has an embeded search box
- has 2 custom buttons on each Li, one for delete and one for edit.
- the search field, if the searched text does not exist, add it on 'enter' press, either on the same select
<option>
and also on the database with Ajax.
I chose the custom select for @twitter bootstrap 'bootstrap-select' from silviomoreto git repository and because I did not find the functionality that I want i tried to make it on my own.
So, for those that need or would like to add that functionality on their web-apps , I wrote down my solution, which is not the best solution but it works, and I am open to any suggestions to make it work better.
1. step: create a selectpicker with parameters : data-size="5" (show 5 values and the add scrollbar), data-live-search="true" (add the search box on the top) and load the values that I get from db (preferably with ajax):
<select class="selectpicker typedropdown" data-size="5" data-live-search="true">
<?php
$counter=0;
foreach($eventTypeList as $evType){
$counter++;
if(is_array($evType)){
echo "<option>".$evType['type_name']."</option>";
}else{
echo "<option>".$evType."</option>";
}
} ?>
</select>
2. step: add the custom buttons (edit, delete) (override the prototype function 'createLi')
override the prototype function 'createLi' on your main js file like this:
$.fn.selectpicker.Constructor.prototype.createLi = function (){..}
Inside :
var generateLI = function (content, index, classes, optgroup) {
return '<li' + ........
just before the 'return' add the line with tha two button classes :
content += "<div class='removeTypebtn'></div><div class='editTypebtn'></div>";
so that , when you create the li items you also create the two custom buttons on each row.
3. step: catch 'click' events for edit & delete value (also makes an ajax request on the database to update the dbtable)
$(document.body).on('click','.btn-group.typedropdown .dropdown-menu ul li .removeTypebtn',function(event){
var index = $(event.target).closest( "li" ).data('original-index');//get the item index
var type_name = $(event.target).closest( "li" ).text();
deleteType(index,type_name);
});
in a similar way we catch the 'click' event for the 'edit item', so I omitted it.
now we need to do the interesting part , to delete the selected item from the selectpicker and also make an ajax request to delete it from dbtable. the database is beyond the tutorial scope so , I left it out. pay attention inside the success function how I remove.
function deleteType(index,type_name){
var url = "<?php echo $domain.$deleteType; ?>";
data = {'index':index,'type_name':type_name};
$.ajax({
cache: false,
url : url,
type: "POST",
data : data,
success : function(data, textStatus, jqXHR){
$('.typedropdown').find('[data-original-index=$index]').remove();//remove selected item from selectpicker
$('.typedropdown').find('option:contains($type_name)').remove();";// remove value also from the hidden select
$('.selectpicker.typedropdown').selectpicker('val', []);//clear selected
},
error : function(xhr, ajaxOptions, thrownError){
alert(thrownError);
}
});
}
4. step: create the 'add new value' functionality on Enter (as you know the search field only permit searches inside the li's)
so, when we init the selectpicker component , we change the 'noneResultsText' message , by altering the parameter : noneResultsText :
//init selectpicker
selectPickerType = $('.selectpicker.typedropdown').selectpicker({
noneResultsText:'Add new {0}',
selectOnTab: true
});
so, now whenever we write down a new word that does not exist , we get the message Add new 'myword'
Now we need to catch the click event.
$('.selectpicker.typedropdown').data('selectpicker').$searchbox.on('keydown',function(e){
if(e.keyCode == 13){
addNewDropdownValue(e.target.value,'type');
return false;
}
});
and the addNewDropdownValue function : (with an ajax request to dbtable to add the new value) (pay attention into the success function)
function addNewDropdownValue(newValue,tble){
var url = "<?php echo $domain.$addDropdownValueURL; ?>";
data = {'newValue':newValue,'tble':tble};
var loading = $('.loading');
$.ajax({
cache: false,
url : url,
type: "POST",
data : data,
beforeSend: function( xhr ) {
loading.css('top',screen.height/2);
loading.css('left',screen.width/2);
loading.html('<div><img alt="loading..." src="<?php echo $domain; ?>/assets/images/loader/ajax_loader_blue_48.gif" /></div>').show();
},
success : function(data, textStatus, jqXHR){
loading.fadeOut(500);
$('.selectpicker.".$tble."dropdown').append('<option selected>$newValue</option>');//append new item on the selectpicker
$('.selectpicker.".$tble."dropdown').val('$newValue');//select the new value
$('.selectpicker.".$tble."dropdown').selectpicker('refresh');//refresh the selectpicker
$('.".$tble."dropdown').removeClass('open');//close the selectpicker
},
error : function(xhr, ajaxOptions, thrownError){
alert(thrownError);
}
});
}
that's it , now we have a custom bootstrap select-picker with delete and edit buttons on each row and add new text functionality on enter.
please by any means, tell me your opinion on how we can make it work better or if you have any questions.