Datetimepicker en un nuevo componente
La mayor parte de la lógica que haces en 'handleDateInputsOptions' debería estar dentro de tu 'script' de componentes. Tu prop 'dateInputsSelect' contiene el tipo de entrada, así que usa la interpolación en tu 'script' y luego aplica la lógica de 'handleDateInputsOptions'. Otro truco que necesitarías es activar la act...
Lee la respuesta completa abajo ↓Pregunta
¡Disculpa la extensión de esta pregunta! Es un componente completamente nuevo y ya casi lo he terminado, solo necesito un poco de ayuda y creo que esto podría ser útil para otros.
Estoy creando una entrada de selección de fecha que utiliza la lib de daterangepicker. '''gatherDateOptions()''' recopila todos los campos de tipo de fecha a través de las opciones. Tengo los campos de '''fecha''', 'hora de cita''', ''intervalo' y ''intervalo'''. Luego uso su nombre y divido en "-" para obtener el tipo de campo.
Cargo los scripts uno a uno para evitar problemas de dependencias (como "$ no está definido"). Si crees que hay una forma más eficiente de hacerlo, por favor aconsejadme. Una vez cargado ''daterangepicker', puedo ejecutar la función '''initDateRange''' y, de hecho, ejecutará '''daterangepicker' en el campo y generará el desplegable de selección de fecha en el lugar correcto (bajo el campo de entrada), pero explicaré más adelante por qué esto parece un desperdicio.
Como tengo un select que permite cambiar entre campos y su tipo, necesito una función para escuchar ese cambio y actualizar el campo de entrada. Así que debajo de '''defaults''' he añadido la función '''init()' y estoy escuchando el evento de cambio y ejecutando ''handleDateInputsOptions''.
Problema nº 1: Al ejecutar la inicialización de 'daterangepicker''' en ''default: script:'''' aparece la ventana emergente de selección '''daterangepicker' en el lugar correcto, debajo del campo de entrada. Sin embargo, al inicializar '''daterangepicker''' dentro de ''handleDateInputsOptions''', añade '''daterangepicker''' al cuerpo exterior y no debajo de la entrada dentro de nuestro iframe grapesjs.
Al mirar https://www.daterangepicker.com/#options verás que podemos añadir un '''parentEl''', pero al ponerlo en '''iframe''' se añade '''daterangepicker' dentro del iframe, pero no puedo colocarlo dentro del cuerpo del iframe. Tengo la sensación de que la razón por la que añade el '''daterangepicker'' al cuerpo principal y no al iframe es porque inicializo '''daterangepicker''' fuera del modelo. Tengo la sensación de que mi función ''init()''' debería ocurrir dentro de '''default: script:'''? Si es así, ¿cómo lo hago?
Problema nº 2: Para inicializar correctamente ''daterangepicker' en la entrada al cargar, puedo usar '''default: script:'''', pero como escribí en mi script abajo, si quiero inicializar el daterangepicker allí, tendré que escribir la mayor parte de la función 'handleDateInputsOptions''' dos veces para comprobar qué tipo de campo de fecha es la entrada. Esto parece un desperdicio.
¡Cualquier ayuda será muy apreciada!
function gatherDateOptions() {
var customDateFieldInputs = c.customDateFields.split(',');
var customDateRangeInputs = c.customDateRangeFields.split(',');
var customDatetimeInputs = c.customDatetimeFields.split(',');
var customDatetimeRangeInputs = c.customDatetimeRangeFields.split(',');
const dateInputsOptions = []
Añadir campos de fecha
si (c.customDateFields.length){
$.each(customDateFieldInputs, function( index, field ) {
dateInputsOptions.push({
valor: campo + " - Fecha", nombre: campo + " - Fecha"
})
});
}
Añadir campos de dataRange
if (c.customDateRangeFields.length){
$.each(customDateRangeInputs, function( index, field ) {
dateInputsOptions.push({
valor: campo + " - Rango de fechas", nombre: campo + " - Rango de fechas"
})
});
}
Añadir campos de fecha y hora
if (c.customDatetimeFields.length){
$.each(customDatetimeInputs, function( index, field ) {
dateInputsOptions.push({
valor: campo + " - Fechahora", nombre: campo + " - Fecha-hora"
})
});
}
Añadir campos datetimeRange
if (c.customDateTimeRangeFields.length){
$.each(customDatetimeRangeInputs, function( index, field ) {
dateInputsOptions.push({
valor: campo + " - Rango de Fechas", nombre: campo + " - Intervalo de Fechas"
})
});
}
fecha de retornoEntradasOpciones;
}
let dateInputsOptions = gatherDateOptions();
domc.addType('date', {
model: defaultModel.extend({
Predeterminados: {
... defaultModel.prototype.defaults,
'nombre personalizado': c.labelNombreFecha,
etiquetaNombre: 'entrada',
Tipo: "fecha",
arrastrable: 'forma, forma *', // Solo puede caerse dentro de los elementos de 'forma'
Droppable: falso, // No se pueden colocar otros elementos dentro
copiable: false, // No permitir duplicar el componente
Rasgos: [
'marcador de posición',
{
tipo: 'select',
etiqueta: 'Seleccionar campo de fecha',
nombre: 'fechaInputsSelect',
cambioProp: 1,
opciones: fechaEntradasOpciones
},
{ tipo: 'casilla de verificación', nombre: 'requerido' },
],
script: función () {
var input = this;
console.log(«Entrada de trabajo», entrada);
var initDateRange = function() {
Si quiero inicializar el selector de datarangerangepicker aquí, tendré que escribir la mayor parte de la función handleDateInputsOptions dos veces para comprobar qué tipo de campo de fecha es la entrada. Esto parece un desperdicio.
$(input).daterangepicker({
singleDatePicker: cierto,
showDropdowns: cierto,
// });
}
if (typeof daterangepicker == 'undefined' || typeof jQuery == 'undefined' || typeof moment == 'undefined') {
if (typeof jQuery == 'undefined'){
var jquery = document.createElement('script');
jquery.src = '//cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js';
document.body.appendChild(jquery);
jquery.onload = function(){
loadMoment();
}
} else {
loadMoment();
}
function loadMoment(){
si (tipode de momento == 'indefinido'){
var moment = document.createElement('script');
moment.src = '//cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js';
document.body.appendChild(momento);
moment.onload = function(){
loadDatePicker();
}
} else {
loadDatePicker();
}
}
function loadDatePicker(){
if (typeof $ == 'indefinido'){window.$ = jQuery};
var link = document.createElement('link');
link.rel = "hoja de estilo";
link.href = "//cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.css";
document.body.appendChild(enlace);
var daterangepicker = document.createElement('script');
daterangepicker.src = '//cdnjs.cloudflare.com/ajax/libs/bootstrap-daterangepicker/3.0.5/daterangepicker.min.js';
document.body.appendChild(daterangepicker);
dataranquepicker.onload = initIntervaloFecha;
}
} else {
console.log("todos los liberales presentes");
initDateRange();
}
},
},
init() {
this.handleFechaOpcionesEntradas(); <<<< Esto fracasará porque no sabe cuál es la vista en esta etapa. ¿Quizá se supone que aún debe cargar algo?, lo que me lleva a la siguiente línea:
this.listenTo(this, 'this.view.el está cargado?????', this.handleDateInputsOptions); <<<< ¿Cuál es ese evento para escuchar en cuanto se carga this.view.el?
this.listenTo(this, 'change:dateInputsSelect', this.handleDateInputsOptions);
},
handleDateInputsOptions() {
si (typeof $(this.view.el).data('daterangepicker') != 'indefinido'){
$(this.view.el).data('daterangepicker').remove();
}
function initDateRange(input, options) {
$(entrada).datarangepicker(opciones);
}
let dateOption = this.get('dateInputsSelect');
var val = dateOption.split(' - ');
var fieldName = "Custom." + val[0];
var type = val[1].trim().toLowerCase();
var fieldOptions = {};
this.set('attributes', {
nombre: fieldNombre,
id: val[0],
Tipo: "texto",
});
if (escribe == "fecha"){
fieldOptions = {
singleDatePicker: cierto,
showDropdowns: cierto,
}
} si no (escribe == "datetime"){
fieldOptions = {
singleDatePicker: cierto,
showDropdowns: cierto,
TimePicker: cierto,
localidad: {
formato: 'MM/DD/YYYY hh:mm A'
}
}
} si no (escribe == "datetimerange"){
fieldOptions = {
TimePicker: cierto,
localidad: {
formato: 'MM/DD/YYYY hh:mm A'
}
}
}
initDateRange(this.view.el, fieldOptions);
},
}, {
isComponent(el) {
var dateType;
if (tipode el.dataset != "indefinido" && el.dataset.type == "fecha") {
Typetipo de fecha = verdadero;
} else {
DateType = false;
}
if(el.tagName == 'INPUT' && dateType){
return {type: 'date'};
}
},
}),
view: defaultView
});Respuestas (1)
La mayor parte de la lógica que haces en 'handleDateInputsOptions' debería estar dentro de tu 'script' de componentes. Tu prop 'dateInputsSelect' contiene el tipo de entrada, así que usa la interpolación en tu 'script' y luego aplica la lógica de 'handleDateInputsOptions'. Otro truco que necesitarías es activar la actualización de 'script' en el lienzo, así que hazlo en tu 'model.init' '''js init() { this.on('change:dateInputsSelect', () => this.trigger('change:script')); }
PD. Hazte un favor a ti mismo... usar la nueva [API de componentes](https://grapesjs.com/docs/modules/Components.html#define-custom-component-type) para definir tipos personalizados, con la antigua es bastante fácil romper cosas
Preguntas y respuestas relacionadas
Continúa investigando con debates sobre temas similares.
Issue #1150
[Pregunta] Obtén subidas como Base64
Hola a todos, Necesito ayuda para integrar esto en una aplicación web que tengo. Todo se renderiza y funciona como se espera, pero estoy in...
Issue #1084
[Bug] Vincula handleAdd para que los implementadores puedan obtener una referencia
He marcado como un error solo porque creo que esto refleja una pequeña inconsistencia; Pero también podría entenderse como una solicitud de...
Issue #2808
[PREGUNTA] Componente de tipo personalizado en entorno de producción
Hola, tengo una pregunta: cuando creo un componente de tipo personalizado desde el editor, ¿cuál sería el siguiente paso para mostrar ese c...
Issue #2284
[Pregunta] ¿Debería una clase deseleccionada en un componente ser deseleccionada en otros componentes?
No estoy seguro de si esto es un bug o si simplemente estoy malinterpretando el uso. Haz clic en componente 1 > añadir clase1 > haz clic en...
Plugins de pago que cumplen con este problema
Seleccionado por temas clave y relevancia de etiquetas para ayudarte a enviar más rápido.
Cargando recomendaciones de plugins de pago...
Consulta los plugins de código abierto de GrapesJS en GitHub O haz una búsqueda rápida en nuestro catálogo gratuito.
Explora plugins gratuitos →Los plugins premium incluyen soporte, actualizaciones regulares y funciones listas para producción — ahorrando días de trabajo de integración.
Explora plugins premium →Explorar categorías de plugins
Ve directamente a las páginas de categorías de plugins en el marketplace.