creazione datapicker drupal bootrap
Salve ragazzi,
vorrei integrare in drupal 7 un datepicker bootstrap con testo per filtrare per data eventi e news. Qualcosa così (link).
Qualcuno di voi ha qualche idea su come procedere?
Salve ragazzi,
vorrei integrare in drupal 7 un datepicker bootstrap con testo per filtrare per data eventi e news. Qualcosa così (link).
Qualcuno di voi ha qualche idea su come procedere?
Risposte
Prova
Prova https://www.drupal.org/project/bdtpicker
Anche il modulo date (https://www.drupal.org/project/) ha un sottomodulo date_popup che permette di agganciare un date picker (widget di visualizzazione) ai campi data sui form delle entità oppure sui filtri delle viste. Non usa però una libreria bootstrap.
ciao Maurizio, il plugin
ciao Maurizio, il plugin sembra funzionare, e solo la versione dev (2017). Occorre un ulteriore file js (moment).
Al momento sto cercando di capire come farlo funzionare, consigli? O deve leggermi tutta la documentazione? :)
Devi installare tutte le
Devi installare tutte le dipendenze per librerie esterne (moment, moment-timezone, bootstrap-timepicker) e il modulo moment. In questo post ci sono i comandi per clonare le giuste versioni da github https://www.drupal.org/node/2361275#comment-12203615: ad ogni modo la master di moment e moment-timezone e la versione 3.1.4 di bootstrap-datetimepicker.
Il modulo funziona come "opzione" per i tipi di campo data (modulo date) con widget campo di testo: troverai l'impostazione in modifica/creazione del campo.
Per averlo funzionante nelle viste è più ostico perchè non ha integrazione.
L'unica via è creare un modulo implementando un hook_form_alter del genere:
function [nome-modulo]_form_alter(&$form, &$form_state, $form_id){
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-[nome-vista]-[tipo-display]') {
$form['btcalendar']['value']['#bdtpicker'] = TRUE;
$form['btcalendar']['value']['#process'][] = 'bdtpicker_element_date_text_process';
}
}
calcola che il nome btcalendar dell'elemento $form['btcalendar'] può essere impostato dalle opzioni "Altro >> Identificatore filtro" del filtro esposto sulla vista. Il [tipo-display] dovrebbe essere "page" in generale e [nome-vista] il machine name della vista. Se tutto va per il verso giusto il popup dovrebbe apparirti sul filtro esposto:
Sicuramente più integrato in un tema bootstrap ma più scomodo da gestire.
Spero ti sia utile.
Ciao Maurizio, allora la
Ciao Maurizio, allora la versione del plugin è la bdtpicker-7.x-3.x-dev. Mentre la versione di bootstrap-datetimepicker è la 3.1.3 del master, la 3.1.4 non è nel master (forse lo era?).
Cmq installate tutte le dipendenze e librerie necessarie (Moment Timezone library version 0.5.13;
Moment.js library version 2.19.1; Bootstrap Date & Time picker library version 4.17.47) ho richiamato la relativa funzione (function datepicker_form_alter...) su template.php.
Tuttavia non mi visualizza il popop del calendiario in pagina, e non riesco a capire se è dovuto ad un incompatibilità con le librerie installate oppure ad un problema di impostazione di settaggi in viste. L'obiettivo è quello di avere un filtro calendario in pagina (modello bootstrap) per eventi e notizie.
Ps. Occorrerebbe anche forkare la relativa documentazione del plugin.
Ti posto le versioni
Ti posto le versioni utilizzate:
https://github.com/Eonasdan/bootstrap-datetimepicker/archive/3.1.4.zip
https://github.com/moment/moment-timezone/archive/master.zip
https://github.com/moment/moment/archive/master.zip
bdtpicker-7.x-3.x-dev
bootstrap-7.x-3.15
versione jquery (jquery_update) 1.10
nella vista il filtro esposto sul campo di tipo data ha come "elemento del form per la selezione della data" il valore testo e su "Altro > Identificatore filtro" il valore "btcalendar".
Lo snippet sopra è inserito in un modulo custom ma puoi anche inserirlo come hai fatto nel template. Devi solo assicurarti che il nome funzione sia giusto: se il nome macchina del tema è "bootstrap_agency" il nome della funzione dovrà essere bootstrap_agency_form_alter. Pulisci sempre le cache quando aggiungi un nuovo hook per farlo riconoscere dal sistema.
Aggiungo: se ti interessa
Aggiungo: se ti interessa solo usare la libreria sui filtri delle viste e non ti interessa poter disporre di interfaccia di configurazione per il campo, potresti anche solo iniettare le librerie sul form dei filtri esposti. Così eviti di installare moment e bdtpicker.
In pratica in codice sul form alter diventa:
<?php
function [nome-modulo]_form_alter(&$form, &$form_state, $form_id){
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-[nome-vista]-[tipo-display]') {
// aggiungo la class per facilitare il ritrovamento con jQuery dell'elemento
$form['btcalendar']['value']['#attributes']['class'] = array('btcalendar');
// in questo caso i file li ho scaricati dentro la cartella del tema bootstrap
// ma qualsiasi posizione va bene
$theme_path = drupal_get_path('theme', 'bootstrap');
$form['#attached']['js'][] = $theme_path . '/js/moment.min.js';
$form['#attached']['js'][] = $theme_path . '/js/bootstrap-datetimepicker.min.js';
$form['#attached']['css'][] = $theme_path . '/js/bootstrap-datetimepicker.min.css';
$form['#attached']['js'][] = $theme_path . '/js/btdatetimepicker.js';
}
}
?>
in questo caso nella directory sites/all/bootstrap/js ho messo (tutte le ultime versioni):
bootstrap-datetimepicker.min.css
bootstrap-datetimepicker.min.js
moment.min.js
btdatetimepicker.js
il contenuto di quest'ultimo file è
(function($){
Drupal.behaviors.btdatetimepicker = {
attach: function (context, settings) {
$('.btcalendar').datetimepicker({
locale: moment.locale('IT'),
format: 'DD/MM/YYYY'
});
}
};
})(jQuery);
Riassuanto errore, passi: 1)
Riassuanto errore, passi:
1) installato moment.js e Bootstrap Date & Time picker (bdtpicker) ed abilitati.
2) installate dipendenze e librerie: https://www.drupal.org/node/2361275#comment-12203615
3) creato modulo custom personalizzato: datapicker (/sites/default/modules/custom/datapicker) con all'interno datepicker.info e datepicker.module, codice php:
<?php
/**
* @file
* A block module that show a datepicker plugin for view!
*/
/**
* Implements hook_form_alter().
*/
function datepicker_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-[pagina_notizie]-[page]') {
$form['btcalendar']['value']['#bdtpicker'] = TRUE;
$form['btcalendar']['value']['#process'][] = 'bdtpicker_element_date_text_process';
}
}
3) nel back-end ho configurato come in foto
4) per NON ottenere un risultato desiderato come questo, partendo da link foto
Prova a correggere il form
Prova a correggere il form #id in views-exposed-form-pagina-notizie-page.
mi riporta sempre errore ajax
mi riporta sempre errore ajax (sia selezionando ''testo'' come 'elemento del form per la selezione della data' sia con l'opzione ''scegliere'', mentre con ''popop'' non crea errore ma ritorna il calendario di default).
L'impostazione passata nel modulo custom è:
if ($form_id == 'views_exposed_form' && $form['#id'] == 'views-exposed-form-pagina-notizie-page') {
...
O è un problema di errata indicazione del [tipo-display] o del [nome-vista]?
A questo punto sto pensando, se non se ne esce, di provare a passare div file css e js nel modulo custom e costruire così un indipendente blocco calendario bootstrap datapicker (:
Prova a
Prova a vedere:
https://bitbucket.org/mganovelli/ultime_notizie
creato con Features, contiene un tipo di contenuto notizia con un campo data, la vista ultime notizie e il codice del form_alter funzionante.
Nota: da usare solo in test non in produzione.
va, dopo aver
va, dopo aver installato Strongarm!
Adesso provo a fixare il mio modulo, anche perché devo usarlo in produzione implementandalo ulteriolmente (voglio arrivare all'esempio sopra, vedi foto).
Sì le dipendenze non
Sì le dipendenze non soddisfatte vanno installate come ogni altro modulo, la cosa più comoda è usare drush (sempre se possibile e disponibile).
Per ottenere un insieme di filtri (date o intervalli) predefiniti (ieri, oggi, settimana scorsa ...) c'è la funzione built-in di views "Filtri raggruppati". Utilizzando le date relative dovresti poter definire i filtri che ti servono (today-1day, today, Monday previous week - Friday previous week, e così via).
hai verificato se funziona? a
hai verificato se funziona? a me ritorna errore ajax raggrupando i filtri
Applica questa patch al
Applica questa patch al modulo date:
https://www.drupal.org/files/issues/1876168-132--exposed_grouped_filters...
Lancio la patch dentro il
Lancio la patch dentro il modulo date (/sites/all/modules/date) con patch -p1 < 1876168-132--exposed_grouped_filters.patch e ritorna:
patching file date_views/includes/date_views_filter_handler_simple.inc
Hunk #1 succeeded at 9 with fuzz 2.
Hunk #2 FAILED at 62.
Hunk #3 succeeded at 80 with fuzz 2.
Hunk #5 FAILED at 118.
Hunk #6 FAILED at 134.
Hunk #7 succeeded at 157 with fuzz 1.
Hunk #8 FAILED at 328.
Hunk #9 FAILED at 371.
Hunk #10 FAILED at 395.
Hunk #11 FAILED at 425.
Hunk #12 FAILED at 469.
Hunk #13 FAILED at 480.
Hunk #14 succeeded at 506 with fuzz 2.
Hunk #15 succeeded at 549 with fuzz 1.
patch unexpectedly ends in middle of line
9 out of 15 hunks FAILED -- saving rejects to file date_views/includes/date_views_filter_handler_simple.inc.rej
patch unexpectedly ends in middle of line
drush dl date (Date
drush dl date (Date 7.x-2.10)
cd date
wget https://www.drupal.org/files/issues/1876168-132--exposed_grouped_filters...
patch -p1 < 1876168-132--exposed_grouped_filters.patch
> patching file date_views/includes/date_views_filter_handler_simple.inc
non rilevo errori .. non saprei
ho risolto aggiornando il
ho risolto aggiornando il modulo date all'ultima versione.
Ma se dovessi applicare lo stesso filtro datapicker ad un altro blocco contenuti come ''eventi'' o ''archivio notizie'' è possibile?
Credo basti adattare il form
Credo basti adattare il form id e se la vista contiene un filtro data impostato esattamente come l'altro, non dovrebbero esserci problemi.
Potresti generalizzare sennò il codice per applicare la classe ad ogni filtro esposto di tipo data con widget di testo. Qualcosa del tipo (testato solo al volo usando il modulo su bitbucket):
<?php
function ultime_notizie_form_alter(&$form, &$form_state, $form_id){
if ($form_id == 'views_exposed_form') {
$found = 0;
foreach(element_children($form) as $element_key) {
if (isset($form[$element_key]['value']['#type']) && $form[$element_key]['value']['#type'] == 'date_text') {
$form[$element_key]['value']['#attributes']['class'] = array('btcalendar');
$found++;
}
}
if ($found) {
$lib_path = drupal_get_path('module', 'ultime_notizie') . '/lib';
$form['#attached']['js'][] = $lib_path . '/moment.min.js';
$form['#attached']['js'][] = $lib_path . '/bootstrap-datetimepicker.min.js';
$form['#attached']['css'][] = $lib_path . '/bootstrap-datetimepicker.min.css';
$form['#attached']['js'][] = $lib_path . '/btdatetimepicker.js';
}
}
}
?>
via codice mi ritorna errore
via codice mi ritorna errore ajax http.
Impostando campi data - testo -Data notizia (field_news_date)- e impostando poi filto esposto per ogni blocco pagina contenuto (:
Dopo vari test posso
Dopo vari test posso affermare che il modulo non fa quello che deve:
1) se si inserisce un doppio calendario (calendario bootstrap data inizio e data fine) nella stessa view ritorna errore
2) se si cerca di adattarlo ad altri blocchi (''eventi' o blocco ''x'', ad esempio) ritorna errore ajax.
Allo stato attuale sconsiglio il tuo utilizzo.
Ciao, se ti riferisci al
Ciao, se ti riferisci al modulo che ho postato su bitbucket o ai codici scritti sopra, come già accennato sono solo a scopo dimostrativo e non pronti per la produzione, in quanto non sufficientemente testati.
Ho provato a creare un filtro data con operatore "Tra" e adattando il codice sopra http://www.drupal.it/supporto/creazione-datapicker-drupal-bootrap#comment-11846 (le chiavi dell'array sono max e min e non value) ottengo questo:
Se provo ad utilizzare
Se provo ad utilizzare un'altra vista con campo data:
Comunque alla fine anche usare semplicemente la lib tramite jQuery scegliendo le classi, dovrebbe produrre lo stesso risultato.
Il punto è che (a me)
Il punto è che (a me) continua a ritornare errore ajax http. Non metto in dubbio che a te funzioni correttamente. Puoi certo passare tutto in jquery per ottenere lo stesso risultato in termini di filtro esposto calendario, ma non è quello che volevo fare originariamente integrando un datepicker bootstrap.
Non so che consigliarti ..
Non so che consigliarti .. che errore ti ritorna esattamente? Nel caso il messaggio sia poco esplicativo (tipo "Service unavailable" o similari) controlla anche il log di Drupal e il log del webserver alla ricerca di qualche errore significativo.
ho piallato tutto e fatto
ho piallato tutto e fatto un'installazione pulita e ora (per lo meno) mi compare il calendario su viste diverse. Ma, ma, non riesce a filtrarli i contenuti correttamente.
Che impostazioni hai utilizzato sui filtri?
Dalle immagini su imgur mi
Dalle immagini su imgur mi pare che l'unica differenza sia nella scelta dell'operatore, che nel caso di data singola ho impostato a "È maggiore o uguale a" per l'intervallo "È tra".
https://screenshots.firefox.com/d69cOYjpAlR4DcHi/d7.local
ecco, appunto, quindi qualche
ecco, appunto, quindi qualche idea perché non filtra (non funziona neppure il filtro con data con calendario di default)!
Ps. A questo punto mi chiedo: puo' essere un'incompatibilità del tema di bootrastrap 3, o un conflitto? E' un'ipotesi, perché al momento non ho risposte certe!
che valori hai settato di
che valori hai settato di array con min o max rispetto a questo:
$found = 0;
foreach(element_children($form) as $element_key) {
if (isset($form[$element_key]['value']['#type']) && $form[$element_key]['value']['#type'] == 'date_text') {
$form[$element_key]['value']['#attributes']['class'] = array('btcalendar');
$found++;
}
}
La query generata da views o
La query generata da views o i risultati di quest'ultima possono essere modificati da altri moduli attivi. Il filtro sulla data non ha alcun effetto o non ritorna la lista di risultati attesi (cioè filtra più o meno risultati del dovuto)?
Ho sostiuito la chiave 'value' con 'min' / 'max'
<?php
...
else if (isset($form[$element_key]['min']['#type']) && $form[$element_key]['min']['#type'] == 'date_text') {
$form[$element_key]['min']['#attributes']['class'] = array('btcalendar');
$found++;
}
else if (isset($form[$element_key]['max']['#type']) ...
?>
c'era un'incopatibilità con
c'era un'incopatibilità con il relativo modulo precedente (Bootstrap Date & Time picker) che non so per quale ragione (mi installava il form calendario nella pagina di amministrazione, sotto 'salva'', parte relativa ai blocchi).
Inoltre le impostazioni per le viste errano errate, ho filtrato con un nodo di questo tipo (a qualcuno forse tornerà utile).
Ora volevo mettere tutto dentro un bottone a comparsa, per ridurre l'invasività. Qualche suggerimento?
Questo perché ci sono problemi di allienamento css tra i vari form, e ti ritrovi qualcosa di per nulla responsive.
Ci sono alcuni moduli che
Ci sono alcuni moduli che creano un wrap attorno al form esposto e lo possono rendere espandibile (es: Better Exposed Filters, Views Toggle Filter).
Personalmente la risolverei con jQuery, visto che si tratta di un riarrangiamento grafico.
modificato il
modificato il file views-exposed-form.tpl.php e richimata la libreria jquery necessaria dando:
<?php
drupal_add_library('system', 'drupal.collapse');
?
Creo il wrapper con:
<fieldset class="collapsible collapsed">
<legend><span class="fieldset-legend">CERCA CON FILTRI E BLA BLA</span></legend>
<div class="fieldset-wrapper">
CODICE QUI --- FILTRI ESPOSTI
</div>
</fieldset>
Ps. Non funziona, qualcuno ha qualche suggerimento?
Potresti agire sul template
Potresti agire sul template di output della vista views-view.php e inserire il form esposto in un fieldset:
<div class="<?php print $classes; ?>">
<?php print render($title_prefix); ?>
<?php if ($title): ?>
<?php print $title; ?>
<?php endif; ?>
<?php print render($title_suffix); ?>
<?php if ($header): ?>
<div class="view-header">
<?php print $header; ?>
</div>
<?php endif; ?>
// --> inizio parte modificata
<?php if ($exposed): ?>
<div class="view-filters">
<?php
$fieldset_vars = array(
'element' => array(
'#title' => 'Filtri',
'#collapsible' => TRUE,
'#collapsed' => count($_GET) == 1,
'#children' => $exposed,
),
);
print theme('fieldset', $fieldset_vars);
?>
</div>
<?php endif; ?>
// <-- fine parte modificata
<?php if ($attachment_before): ?>
<div class="attachment attachment-before">
<?php print $attachment_before; ?>
</div>
<?php endif; ?>
<?php if ($rows): ?>
<div class="view-content">
<?php print $rows; ?>
</div>
<?php elseif ($empty): ?>
<div class="view-empty">
<?php print $empty; ?>
</div>
<?php endif; ?>
<?php if ($pager): ?>
<?php print $pager; ?>
<?php endif; ?>
<?php if ($attachment_after): ?>
<div class="attachment attachment-after">
<?php print $attachment_after; ?>
</div>
<?php endif; ?>
<?php if ($more): ?>
<?php print $more; ?>
<?php endif; ?>
<?php if ($footer): ?>
<div class="view-footer">
<?php print $footer; ?>
</div>
<?php endif; ?>
<?php if ($feed_icon): ?>
<div class="feed-icon">
<?php print $feed_icon; ?>
</div>
<?php endif; ?>
</div>
Il fatto che si creino
Il fatto che si creino problemi responsive (disallineamento crossbrowser) è del tutto normale?
Di solito in un qualsiasi
Di solito in un qualsiasi progetto è difficile non dover fare alcun aggiustamento anche partendo da temi base responsive. Credo, a vedere dall'immagine postata, che tu possa risolvere anche lavorando esclusivamente sui fogli di stile.
Naturalmente. Qui basterebbe
Naturalmente. Qui basterebbe togliere il float (none) .views-exposed-form .views-exposed-widget ma le modifiche vengono estese al tema admin (che è quello di default)
Views aggiunge classi
Views aggiunge classi specifiche al wrapper di ogni vista costruite usando il nome macchina della vista, l'id del display etc.. puoi quindi applicare ad una sola vista le modifiche necessarie, ad esempio
.view-ultime-notizie .views-exposed-widget { ... }
può essere anche utile creare una classe generica dalla pagina di modifica di una vista >> avanzate >> altro >> classe css >> "nome-classe" in modo da poterla riutilizzare su più viste
.nome-classe .views-exposed-widget { ... }
Il wrapper crea conflitto con
Il wrapper crea conflitto con la paginazione, al momento. Se infatti provo a selezionare le pagine desiderate o il numero di pagina desiderato (ad esempio cliccando su successive notizie o precedenti notizie, o un numero di pagina) vengo rimandato dentro il box dei contenuti di ricerca, che viene aperto.
La paginazione dovrebbe essere indipendente dai filtri inseriti nel wrapper, e il wrapper una volta richiamato dovrebbe chiudersi in automatico al click su ‘’applica’’ (effettuando così la selezione dei filtri e dando l’input).
Probabilmente (se ho capito
Probabilmente (se ho capito bene quello che vorresti ottenere) è sufficiente cambiare la linea
<?php
'#collapsed' => count($_GET) == 1,
?>
in
<?php
'#collapsed' => TRUE,
?>
in questo modo il fieldset non dovrebbe tener conto se i filtri sono valorizzati o meno e ad ogni richiesta dovrebbe tornare allo stato collassato. Non ho avuto tempo di testare.
si, ma con un selettore (di
si, ma con un selettore (di apertura e chiusura) ad icona, via php è possibile integrarlo?
Utilizzando Bootstrap
Utilizzando Bootstrap qualcosa del genere potrebbe funzionare
// --> inizio parte modificata
<?php if ($exposed): ?>
<div class="view-filters">
<button data-target="#collapse-me .collapse" data-toggle="collapse"><span class="glyphicon glyphicon-cog"></span></button>
<?php
$fieldset_vars = array(
'element' => array(
'#id' => 'collapse-me',
'#title' => 'Filtri',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#children' => $exposed,
),
);
print theme('fieldset', $fieldset_vars);
?>
</div>
<?php endif; ?>
// <-- fine parte modificata
ritorna qualcosa così. Le
ritorna qualcosa così.
Le classi rispettive in boostrap sono queste:
glyphicon glyphicon-menu-down
glyphicon glyphicon-menu-up
Non so, dovresti vedere una
Non so, dovresti vedere una rotellina all'interno del bottone, controlla che il font glyphicon venga caricato correttamente.
Verifico e ti dico! Ma non
Verifico e ti dico! Ma non c'è un modo per richiamare più velocemente una funzione passandola con jquery?
Certo puoi anche creare un
...
$('#views-exposed-form-ultime-notizie-page').wrap('<div id="views-exposed-form-ultime-notizie-page-collapse" class="collapse"></div>');
$('#views-exposed-form-ultime-notizie-page-collapse').before('<button data-toggle="collapse" data-target="#views-exposed-form-ultime-notizie-page-collapse" class="btn"><span class="glyphicon glyphicon-cog"></span></button>');
...
In termini di procedura tra
In termini di procedura tra le due qual è preferibile a tuo parere? considerando anche una migliore resa del sito in termini di efficienza?
Come accennato al
Come accennato al commento
http://www.drupal.it/supporto/creazione-datapicker-drupal-bootrap#commen...
io la risolverei con jQuery.
In termini di efficienza è difficile dare un giudizio netto, perchè entrambi i metodi non generano una complessità tale da generare differenze sensibili nè sul rendering della pagina (lato client) nè sulla costruzione della stessa (lato server).
Lato server con la soluzione php si effettuano un numero maggiore di operazioni (diciamo che si effettua il rendering di un elemento in più e l'override di un template). Quindi a livello computazionale credo sia (relativamente) più "costosa" da gestire la versione php (che implica comunque anche il caricamento di una libreria jQuery del core, se non già richiesta su altri punti della pagina) rispetto quella puramente jQuery.
chiaro, il tuo punto di
chiaro, il tuo punto di vista. E lo condivido.
Venendo a quanto sopra al momento non mi carica (ancora) l'icona desiderata. Procedo quindi con icon api all'installazione dei relativi pacchetti di font.
Ciao il font Glyphicon
Ciao il font Glyphicon Halflings dovrebbe essere disponibile utilizzando l'opzione cdn altrimenti trovi il font dentro il pacchetto che puoi prelevare da http://getbootstrap.com
ho risolto con font awesome,
ho risolto con font awesome, giusto per le icone. Teniamo cmq il thread aperto per ulteriori implementazioni, che possono essere utili anche ad altri utenti.