i needed to use a dropdown list that could do that functionality:
<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.
How this could be done better is to remove PHP from the equation. In fact, remove any server side code from generating html or DOM elements. This will leave you with two pieces, the javascript to render the UI and the database methods via an API (node.js or the like).
The implementation would look something like the following -
$.ajax({
url: "/api/databaseCall/",
success: function(data){
/*
Build DropDown
the data variable will be a hash or array of returned db results
iterate over them and build UI
*/
for(var i=0; i < data.results.length; i++){
var row = '<option id=' + data.results[i].id + '>' + data.results[i].value + '</option>';
$(".dropdown").append(row);
}
}
});
Angular, react, backbone all are built with this approach in mind. The only one I endorse at this time is backbone.js. Backbone is very easy to learn.
Once you build the UI programmatically with javascript any functionality will be bound automatically using a framework like backbone.