MediaWiki:Events-calendar-navigation.js
From DFM Wiki
Note: After saving, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/* * EventsCalendar * * Change a static [[Template:Events calendar]] into a dynamic one. * Allow the user to toggle between the different views (grid, list, map), * to navigate between different months and to dynamicaly manage filters. * * Author: [[User:0x010C]] * Creation: 14 April 2017 * Last edit: 4 May 2017 */ //<nowiki> ( function ( mw ) { const baseTemplate = '{{Events calendar|display=$(display)|lang=$(lang)|month=$(month)|year=$(year)|locations=$(locations)|tags=$(tags)}}'; window.eventsCalendars = []; var messages = ( function () { var translations = { en: { displayOptions: 'Display options', filteringOptions: 'Filtering options', language: 'Language:', location: 'Location:', tags: 'Tags:', settings: 'Settings', filter: 'Filter!', cancel: 'Cancel', }, fr: { displayOptions: 'Options d\'affichage', filteringOptions: 'Options de filtrage', language: 'Langue :', location: 'Lieux :', tags: 'Tags :', settings: 'Paramètres', filter: 'Filtrer !', cancel: 'Annuler', }, ru: { displayOptions: 'Настройки отображения', filteringOptions: 'Настройки фильтрации', language: 'Язык:', location: 'Место:', tags: 'Тэги:', settings: 'Настройки', filter: 'Фильтровать!', cancel: 'Отменить', } }, chain = mw.language.getFallbackLanguageChain(), len = chain.length, ret = {}, i = len - 1; while ( i >= 0 ) { if ( translations.hasOwnProperty( chain[i] ) ) { $.extend( ret, translations[chain[i]] ); } i--; } return ret; }() ); var EventsCalendar = function( $element ) { this.$element = $element; this.display = $element.attr( 'data-display' ); this.lang = $element.attr( 'data-lang' ); this.year = parseInt( $element.attr( 'data-year' ) ); this.month = parseInt( $element.attr( 'data-month' ) ); this.locations = $element.attr( 'data-locations' ); this.tags = $element.attr( 'data-tags' ); this.preparePopup(); this.addListeners(); }; EventsCalendar.prototype.addListeners = function() { var self = this; $( '.events-calendar-noscript' ).hide(); this.$element.find( '.events-calendar-grid' ).css( 'cursor', 'pointer' ).click( function() { self.display = 'grid'; self.reloadView(); } ); this.$element.find( '.events-calendar-list' ).css( 'cursor', 'pointer' ).click( function() { self.display = 'list'; self.reloadView(); } ); this.$element.find( '.events-calendar-map' ).css( 'cursor', 'pointer' ).click( function() { self.display = 'map'; self.reloadView(); } ); this.$element.find( '.events-calendar-prev' ).css( 'cursor', 'pointer' ).click( function() { self.month--; if ( self.month === 0 ) { self.month = 12; self.year--; } self.reloadView(); } ); this.$element.find( '.events-calendar-next' ).css( 'cursor', 'pointer' ).click( function() { self.month = ( self.month % 12 ) + 1; if ( self.month === 1 ) { self.year++; } self.reloadView(); } ); this.$element.find( '.events-calendar-settings' ).css( 'cursor', 'pointer' ).click( function() { self.popup.openWindow( self.popupContent ); } ); $( '.ec-advanced-icons' ).show(); }; EventsCalendar.prototype.removeListeners = function() { this.$element.find( '.events-calendar-grid' ).off( 'click' ); this.$element.find( '.events-calendar-list' ).off( 'click' ); this.$element.find( '.events-calendar-map' ).off( 'click' ); this.$element.find( '.events-calendar-prev' ).off( 'click' ); this.$element.find( '.events-calendar-next' ).off( 'click' ); }; EventsCalendar.prototype.reloadView = function() { var template = baseTemplate.replace( '$(display)', this.display ) .replace( '$(lang)', this.lang ) .replace( '$(year)', this.year ) .replace( '$(month)', this.month ) .replace( '$(locations)', this.locations ) .replace( '$(tags)', this.tags ); this.removeListeners(); mw.hook( 'eventscalendar.deleting' ).fire( this.$element ); var self = this; mw.loader.using( [ 'mediawiki.api' ], function() { var api = new mw.Api(); api.parse( template ).then( function( html ) { self.$element.fadeOut(30, function() { $(this).html( $( html ).html() ) .fadeIn(200) .queue(function(){ self.addListeners(); mw.hook( 'wikipage.content' ).fire( $( 'body' ) ); mw.hook( 'eventscalendar.ready' ).fire( self.$element ); }) .dequeue(); }); } ); } ); }; EventsCalendar.prototype.preparePopup = function() { var self = this; mw.loader.using( 'oojs-ui', function() { function SettingsProcessDialog( config ) { SettingsProcessDialog.parent.call( this, config ); } OO.inheritClass( SettingsProcessDialog, OO.ui.ProcessDialog ); SettingsProcessDialog.static.name = 'settingsProcessDialog'; SettingsProcessDialog.static.title = messages.settings; SettingsProcessDialog.static.size = 'large'; SettingsProcessDialog.static.actions = [ { action: 'save', label: messages.filter, flags: [ 'primary', 'progressive' ] }, { label: messages.cancel, flags: 'safe' } ]; SettingsProcessDialog.prototype.initialize = function () { SettingsProcessDialog.parent.prototype.initialize.apply( this, arguments ); var displayFieldset = new OO.ui.FieldsetLayout( { label: messages.displayOptions, } ); var filterFieldset = new OO.ui.FieldsetLayout( { label: messages.filteringOptions, } ); self.langInput = new OO.ui.TextInputWidget( { value: self.lang } ); self.locationsInput = new OO.ui.MenuTagMultiselectWidget( { menu: { items: [] }, allowArbitrary: true, allowDuplicates: false, $overlay: this.$overlay } ); self.tagsInput = new OO.ui.MenuTagMultiselectWidget( { label: 'TagMultiselectWidget', menu: { items: [] }, allowArbitrary: true, allowDuplicates: false, $overlay: this.$overlay } ); displayFieldset.addItems( [ new OO.ui.FieldLayout( self.langInput, {label: messages.language, align: 'left', help: '' } ), ] ); filterFieldset.addItems( [ new OO.ui.FieldLayout( self.locationsInput, { label: messages.location, align: 'left', help: '' } ), new OO.ui.FieldLayout( self.tagsInput, { label: messages.tags, align: 'left', help: '', } ), ] ); this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } ); this.content.$element.append( displayFieldset.$element ).append( filterFieldset.$element ); this.$body.append( this.content.$element ); var api = new mw.Api(); var _self = this; api.get( { action: 'query', prop: 'revisions', rvprop: [ 'content' ], titles: 'Events calendar/parameters.json', formatversion: '2', } ).then( function( data ) { var content = JSON.parse( data.query.pages[ 0 ].revisions[ 0 ].content ); _self.populateMenu( self.locationsInput, content.locations ); _self.populateMenu( self.tagsInput, content.tags ); if ( self.locations.length > 0 ) { self.locationsInput.setValue( self.locations.split( ',' ) ); } if ( self.tags.length > 0 ) { self.tagsInput.setValue( self.tags.split( ',' ) ); } } ); }; SettingsProcessDialog.prototype.populateMenu = function( selectWidget, data, level ) { level = level || 0; var _self = this; $.each( data, function( key, value ) { var data = '', text = '', offset = ''; for(var i=0; i<level; i++) { offset = offset + ' '; } if ( typeof value.text === 'string' ) { data = value.text; text = value.text; } else { if ( value.text.en !== undefined ) { data = value.text.en; text = value.text.en; } if ( value.text[ self.lang ] !== undefined ) { text = value.text[ self.lang ]; } } selectWidget.addOptions( [ { data: data, label: offset + text, } ] ); if ( value.sub !== undefined ) { _self.populateMenu( selectWidget, value.sub, level + 1 ); } } ); }; SettingsProcessDialog.prototype.getActionProcess = function ( action ) { var dialog = this; if ( action ) { if ( action === 'save' ) { self.locations = self.locationsInput.getValue().join( ',' ); self.tags = self.tagsInput.getValue().join( ',' ); self.lang = self.langInput.getValue(); self.reloadView(); } return new OO.ui.Process( function () { dialog.close( { action: action } ); } ); } return SettingsProcessDialog.parent.prototype.getActionProcess.call( this, action ); }; self.popup = new OO.ui.WindowManager(); $( 'body' ).append( self.popup.$element ); self.popupContent = new SettingsProcessDialog(); self.popup.addWindows( [ self.popupContent ] ); } ); }; $( '.events-calendar' ).each( function() { eventsCalendars.push( new EventsCalendar( $( this ) ) ); mw.hook( 'eventscalendar.ready' ).fire( $( this ) ); } ) } )( mediaWiki ); //</nowiki>