我有一个数据表,每行包含两个 select2 用于自动完成产品和计量单位。此功能可以正常工作,但如果未找到结果,每个 select2 必须显示“添加”按钮以启动模式对话框以插入新产品或新计量单位。问题是第二个 select2 (度量单位列)按预期工作,但没有结果,但第一个不显示按钮。我的策略是在 Select2 语言定义中,利用
noResults
函数创建按钮并绑定单击事件。也许存在另一种方法来在 Select2 结果列表末尾创建按钮,但我不知道。
我已经尝试过在
init.dt
事件中、在createdCell
和createdRow
上初始化select2;结果总是一样的。
总结列定义:
"columnDefs": [
{
name: "productoFactura", "targets": 1, "searchable": false, "orderable": false, width: '300px',
render: function (data, type, full) {
return `<input type="hidden" class="input-csrf-token" name="detalle_factura__token" value="${full['detalle_factura__token']}"/><select name="detalle_factura_producto_producto" class="selector-producto form-control-sm d-none" ><option value="${data.id}" selected>${data.descripcion}</option></select>`;
}
},
{
name: "unidadDeMedida", "targets": 2, "searchable": false, "orderable": false, width: '150px',
render: function (data, type, full) {
return '<select name="detalle_factura_producto_unidad_de_medida" class="selector-unidadmedida form-control-sm d-none" ><option value="' + data.id + '" selected>' + data.descripcion + '</option></select>';
}
},
// rest of columns definition
],
创建行定义(注意:与createdCell结果相同,也在init.dt事件上):
createdRow: function (row, data, dataIndex, cells) {
let tdProducto = $(row).find('td:eq(1)');
let tdUM = $(row).find('td:eq(2)');
$(row).find('select.selector-producto').select2({
theme: 'bootstrap4',
width: '299px',
dropdownParent: tdProducto,
minimumInputLength: 1,
delay: 400,
ajax: {
url: Routing.generate('producto_autocompletar'),
processResults: function (data) {
return data;
}
},
language: {
noResults: function (term) {
let g = $('#modalReader_contenedorForm').find('#prov').data('r');
if (g === '0') {
return "No hay resultados";
}
tdProducto.find('span.select2-results > ul.select2-results__options').append(`<li class="select2-results__options"><a class="btnProductoNuevo btn btn-block btn-default btn-xs text-secondary" data-src="${Routing.generate('producto_nuevo')}" data-mainform-name="producto" data-cerrar-dialogo="0" data-original-title="Registrar producto" data-modal-dialog-fullscreen="modal-fullscreen" data-modal-dialog-scrollable="modal-dialog-scrollable" data-modal-dialog-textsize="text-sm"><span class="fa fa-plus-circle"></span> Registrar producto</a></li>`).on('click', 'a.btnProductoNuevo', function (e) {
e.preventDefault();
e.stopPropagation();
var target = $(this);
const onCreateProductoFromFactura = function (data) {
let newOption = new Option(data.producto.nombre, data.producto.id, true, true);
tdProducto.find('select.selector-producto').append(newOption).trigger('change');
};//select2-search__field
secondModalFormV2(target, false, null, onCreateProductoFromFactura);
});
},
escapeMarkup: function (markup) {
return markup;
}
}
}).on('select2:select', function (e) {
let precio = e.params.data.precio;
let filaActual = $(tdProducto).parents('tr');
filaActual.find('input.input-precio:first').val(numberParser.parse(precio).toFixed(precisionPrecio));
recalcularImporteFila(filaActual);
recalcularSubtotalProductos(importeFormat);
});
$(row).find('select.selector-unidadmedida').select2({
theme: 'bootstrap4',
dropdownParent: tdUM,
placeholder: 'Unidad de Medidas',
width: '149px',
minimumInputLength: 1,
delay: 400,
ajax: {
url: Routing.generate('unidadDeMedida_autocompletar'),
processResults: function (data) {
return data;
}
},
language: {
noResults: function () {
let g = $('#modalReader_contenedorForm').find('#prov').data('r');
if (g === '0') {
return "No hay resultados";
}
tdUM.find('span.select2-results > ul.select2-results__options').append('<li class="select2-results__options"><a class="btnUnidadMedidaNuevo btn btn-block btn-default btn-xs' + (g === '0' ? 'disabled' : '') + ' text-secondary" data-src="' + Routing.generate('unidadDeMedida_nueva') + '" data-mainform-name="unidad_de_medida" data-cerrar-dialogo="1" data-original-title="Registrar Unidad de Medida"><span class="fa fa-plus-circle"></span> Agregar nueva</a></li>').on('click', 'a.btnUnidadMedidaNuevo', function (e) {
e.preventDefault();
e.stopPropagation();
var target = $(this);
const onUnidadDeMedidaCreated = function (data) {
let newOption = new Option(data.unidadDeMedida.texto, data.unidadDeMedida.id, true, true);
$(tdUM).find('select.selector-unidadmedida').append(newOption).trigger('change');
}
secondModalFormV2(target, false, null, onUnidadDeMedidaCreated);
});
}
}
});
}
请注意,第一个 Select2 的代码实际上与第二个 Select2 相同,只是在个别方面有一些细微的变化。
确实,正如我在问题中提到的,使用 Select2 语言的定义并不理想,因为动态建立 select2 语言的选项丢失了,这在我的情况下也是必要的。因此,我使用
select2:open
和 select2:close
事件来添加和删除 select2 中的按钮。在这种情况下,我当前的解决方案略有不同:该按钮始终显示。 这个帖子对我有帮助。
所以,解决方案:
createdRow: function (row, data, dataIndex, cells) {
let tdProducto = $(row).find('td:eq(1)');
let tdUM = $(row).find('td:eq(2)');
$(row).find('select.selector-producto').select2({
theme: 'bootstrap4',
width: '299px',
dropdownParent: tdProducto,
minimumInputLength: 1,
delay: 400,
ajax: {
url: Routing.generate('producto_autocompletar'),
processResults: function (data) {
return data;
}
},
language: locale
}).on('select2:select', function (e) {
let precio = e.params.data.precio;
let filaActual = $(tdProducto).parents('tr');
filaActual.find('input.input-precio:first').val(numberParser.parse(precio).toFixed(precisionPrecio));
recalcularImporteFila(filaActual);
recalcularSubtotalProductos(importeFormat);
}).on('select2:open', function () {
var a = $(this).data('select2');
var tdUM = $(this).parents('td');
if (!$('.select2-link').length) {
a.$results.parents('.select2-results')
.append(`<li class="btnProductoNuevoLI select2-results__options"><a class="btnProductoNuevo btn btn-block btn-default btn-xs text-secondary" data-src="${Routing.generate('producto_nuevo_v2')}" data-mainform-name="producto" data-cerrar-dialogo="0" data-original-title="Registrar producto" data-modal-dialog-fullscreen="modal-fullscreen" data-modal-dialog-scrollable="modal-dialog-scrollable" data-modal-dialog-textsize="text-sm"><span class="fa fa-plus-circle"></span> Registrar producto</a></li>`).on('click', 'a.btnProductoNuevo', function (e) {
e.preventDefault();
e.stopPropagation();
var target = $(this);
const onCreateProductoFromFactura = function (data) {
let newOption = new Option(data.producto.nombre, data.producto.id, true, true);
tdProducto.find('select.selector-producto').append(newOption).trigger('change');
};
secondModalFormV2(target, false, null, onCreateProductoFromFactura);
a.trigger('close');
});
}
}).on('select2:close', function () {
var a = $(this).data('select2');
a.$results.parents('.select2-results').find('li.btnProductoNuevoLI').remove();
});
$(row).find('select.selector-unidadmedida').select2({
theme: 'bootstrap4',
dropdownParent: tdUM,
placeholder: 'Unidad de Medidas',
width: '149px',
minimumInputLength: 1,
delay: 400,
ajax: {
url: Routing.generate('unidadDeMedida_autocompletar'),
processResults: function (data) {
return data;
}
},
language: locale
}).on('select2:open', function () {
var a = $(this).data('select2');
var tdUM = $(this).parents('td');
if (!$('.select2-link').length) {
a.$results.parents('.select2-results')
.append('<li class="btnUnidadMedidaNuevoLI select2-results__options"><a class="btnUnidadMedidaNuevo btn btn-block btn-default btn-xs text-secondary" data-src="' + Routing.generate('unidadDeMedida_nueva') + '" data-mainform-name="unidad_de_medida" data-cerrar-dialogo="1" data-original-title="Registrar Unidad de Medida"><span class="fa fa-plus-circle"></span> Agregar nueva</a></li>').on('click', 'a.btnUnidadMedidaNuevo', function (e) {
e.preventDefault();
e.stopPropagation();
var target = $(this);
const onUnidadDeMedidaCreated = function (data) {
let newOption = new Option(data.unidadDeMedida.texto, data.unidadDeMedida.id, true, true);
$(tdUM).find('select.selector-unidadmedida').append(newOption).trigger('change');
}
secondModalFormV2(target, false, null, onUnidadDeMedidaCreated);
a.trigger('close');
});
}
}).on('select2:close', function () {
var a = $(this).data('select2');
a.$results.parents('.select2-results').find('li.btnUnidadMedidaNuevoLI').remove();
});
}