I am using the lastest version of Select2. Want to add an Insert New button at the end of the dropdown list. I tried these two solutions I found online
Solution 1:
$(".select2-drop").append('<table width="100%"><tr><td class="row"><button class="btn btn-block btn-default btn-xs" onClick="modal()">Add new Item</button></div></td></tr></table>');
Solution 2
$("#itemId0").select2("container").find("div.select2-drop").append('<table width="100%"><tr><td class="row"><button class="btn btn-block btn-default btn-xs" onClick="modal()">Add new Item</button></div></td></tr></table>');
With Solution 1 nothing happens. With solution 2 I get the error message in the select 2 js file
0x800a138f - JavaScript runtime error: Unable to get property 'apply' of undefined or null reference
Can anyone please help?
Here is my HTML
<select id='itemId0' name='product[0][name]' class='form-control col-lg-5 itemSearch' >
<option></option>
</select>
AND the full select2 javascritp
function productFormatResult(product) {
if (product.loading) product.text;
var html = "<table><tr>";
html += "<td>";
html += product.text;
html += "</td></tr></table>";
return html;
}
// alert(html);
function productFormatSelection(product) {
var selected = "<input type='hidden' name='itemId' value='" + product.id + "'/>";
return selected + product.text;
}
//$("#itemId0").select2();
$("#itemId0").select2({
ajax: {
url: "@Url.Action("GetProducts", "Inventories")",
dataType: 'json',
data: function (params) {
return {
q: params.term
};
},
processResults: function (data, params) {
return { results: data };
},
cache: true
},
escapeMarkup: function (markup) { return markup; },
minimumInputLength: 1,
templateResult: productFormatResult,
templateSelection: productFormatSelection,
dropdownClass: 'bigdrop'
});
// $(".select2-drop").append('<table width="100%"><tr><td class="row"><button class="btn btn-block btn-default btn-xs" onClick="modal()">Add new Item</button></div></td></tr></table>');
$("#itemId0").select2("container").find("div.select2-drop").append('<table width="100%"><tr><td class="row"><button class="btn btn-block btn-default btn-xs" onClick="modal()">Add new Item</button></div></td></tr></table>');
check it
$('#select2').select2({
placeholder: 'This is my placeholder',
language: {
noResults: function() {
return `<button style="width: 100%" type="button"
class="btn btn-primary"
onClick='task()'>+ Add New Item</button>
</li>`;
}
},
escapeMarkup: function (markup) {
return markup;
}
});
Update: (Explanation)
If you need to add button in select2 if no result found you just need to returnHTML Button code from noResults function and Add escapeMarkup function to render custom templates.
language: {
noResults: function() {
return `<button style="width: 100%" type="button"
class="btn btn-primary"
onClick='task()'>+ Add New Item</button>
</li>`;
}
},
escapeMarkup: function (markup) {
return markup;
}
Try below example to see how it looks.
I think this can be done with Select2's Adapters and Decorators (https://select2.org/advanced/default-adapters). However, personally I find this approach really heavy and to be honest I don't understand the documentation regarding this area.
What I personally do, is binding on the select2:open
-event and appending a add-new-button container.
Here is an example:
// create new container
$('#select2').select2CreateNew("Create new");
// generic function
$.fn.select2CreateNew = function( text ) {
// bind to "open"-event
this.on( 'select2:open', function( e ) {
let name = $( this ).attr( 'name' );
let html = '<div class="s-add-new-container">' + text + '</div>';
let $resultContainer = $( '[aria-controls="select2-' + name + '-results"]' )
.closest( '.select2-dropdown' ).find( '.select2-results' );
// avoid duplicates ~ append "create new" to result bottom
if ( $resultContainer.find( '.s-add-new-container' ).length === 0 ) $resultContainer.append( html );
} );
}
Customize the code or add some click-event handler for whenever the user clicks on the container.
For styling I'm using this CSS:
.s-add-new-container {
padding: 7px;
background: #f1f1f1;
border-top: 1px solid #c7c7c7;
}
.select2-dropdown.select2-dropdown--below {
border-radius: 0px;
box-shadow: 0px 5px 10px #6b6b6b59;
}
.s-add-new-container:hover {
background: #3db470;
color: white;
cursor: pointer;
}
Here is an example in codepen
html
is below
<select id="CustomSelect" multiple="multiple">
<option value="volvo">BMW</option>
<option value="saab">Jaquar</option>
<option value="mercedes">RR</option>
<option value="audi">Audi</option>
</select>
CSS
is below
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#banner-message {
background: #fff;
border-radius: 4px;
padding: 20px;
font-size: 25px;
text-align: center;
transition: all 0.2s;
margin: 0 auto;
width: 300px;
}
button {
background: #0084ff;
border: none;
border-radius: 5px;
padding: 8px 14px;
font-size: 15px;
color: #fff;
}
#banner-message.alt {
background: #0084ff;
color: #fff;
margin-top: 40px;
width: 200px;
}
#banner-message.alt button {
background: #fff;
color: #000;
}
Script
is below
$("#CustomSelect").select2({
width: '100%',
allowClear: true,
closeOnSelect: false
}).on('select2:open', function () {
let a = $(this).data('select2');
if (!$('.select2-link').length) {
a.$results.parents('.select2-results')
.append('<div class="select2-link2 select2-close"><button>Close</button></div>')
.on('click', function (b) {
});
}
});
User contributions licensed under CC BY-SA 3.0