Keine Bearbeitungszusammenfassung
Keine Bearbeitungszusammenfassung
Zeile 2: Zeile 2:
  * Eventform-Gadget: Komfortables Anlegen von Veranstaltungsseiten
  * Eventform-Gadget: Komfortables Anlegen von Veranstaltungsseiten
  * Aktiv auf der Seite "Veranstaltung_anlegen"
  * Aktiv auf der Seite "Veranstaltung_anlegen"
* DEBUG-VERSION mit console.log
  */
  */
( function () {
( function () {
'use strict';
'use strict';
console.log( 'EVENTFORM 1: Gadget-Code wird ausgeführt' );
console.log( 'EVENTFORM 1: wgPageName =', mw.config.get( 'wgPageName' ) );
console.log( 'EVENTFORM 1: wgUserName =', mw.config.get( 'wgUserName' ) );


// Konfiguration
// Konfiguration
Zeile 11: Zeile 16:
// Nur auf der Trigger-Seite aktiv werden
// Nur auf der Trigger-Seite aktiv werden
if ( mw.config.get( 'wgPageName' ) !== TRIGGER_PAGE ) {
if ( mw.config.get( 'wgPageName' ) !== TRIGGER_PAGE ) {
console.log( 'EVENTFORM: falsche Seite, beende' );
return;
return;
}
}
Zeile 16: Zeile 22:
// Nur für eingeloggte User
// Nur für eingeloggte User
if ( !mw.config.get( 'wgUserName' ) ) {
if ( !mw.config.get( 'wgUserName' ) ) {
console.log( 'EVENTFORM: nicht eingeloggt, beende' );
return;
return;
}
}
console.log( 'EVENTFORM 2: Checks bestanden, lade Module' );


var WOCHENTAGE = [ 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
var WOCHENTAGE = [ 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
Zeile 25: Zeile 34:


function formatGermanDate( isoDate ) {
function formatGermanDate( isoDate ) {
// isoDate im Format YYYY-MM-DD
var d = new Date( isoDate + 'T12:00:00' );
var d = new Date( isoDate + 'T12:00:00' );
return WOCHENTAGE[ d.getDay() ] + ' ' + d.getDate() + '. ' +
return WOCHENTAGE[ d.getDay() ] + ' ' + d.getDate() + '. ' +
Zeile 88: Zeile 96:
'mediawiki.util'
'mediawiki.util'
] ).then( function () {
] ).then( function () {
console.log( 'EVENTFORM 3: Module geladen, baue UI' );
try {


function EventDialog( config ) {
function EventDialog( config ) {
EventDialog.super.call( this, config );
EventDialog.super.call( this, config );
}
}
OO.inheritClass( EventDialog, OO.ui.ProcessDialog );
OO.inheritClass( EventDialog, OO.ui.ProcessDialog );


EventDialog.static.name = 'eventDialog';
EventDialog.static.name = 'eventDialog';
EventDialog.static.title = 'Neue Veranstaltung anlegen';
EventDialog.static.title = 'Neue Veranstaltung anlegen';
EventDialog.static.actions = [
EventDialog.static.actions = [
{ action: 'save', label: 'Seite anlegen', flags: [ 'primary', 'progressive' ] },
{ action: 'save', label: 'Seite anlegen', flags: [ 'primary', 'progressive' ] },
{ label: 'Abbrechen', flags: 'safe' }
{ label: 'Abbrechen', flags: 'safe' }
];
];


EventDialog.prototype.initialize = function () {
EventDialog.prototype.initialize = function () {
EventDialog.super.prototype.initialize.apply( this, arguments );
EventDialog.super.prototype.initialize.apply( this, arguments );


this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );
this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );


this.titelInput = new OO.ui.TextInputWidget( {
this.titelInput = new OO.ui.TextInputWidget( {
placeholder: 'z.B. Sommerfest 2026', required: true
placeholder: 'z.B. Sommerfest 2026', required: true
} );
} );
this.datumInput = new OO.ui.TextInputWidget( { type: 'date', required: true } );
this.datumInput = new OO.ui.TextInputWidget( { type: 'date', required: true } );
this.uhrzeitInput = new OO.ui.TextInputWidget( { type: 'time', value: '17:00', required: true } );
this.uhrzeitInput = new OO.ui.TextInputWidget( { type: 'time', value: '17:00', required: true } );


this.bildInput = new OO.ui.TextInputWidget( { placeholder: 'sommerfest.jpg' } );
this.bildInput = new OO.ui.TextInputWidget( { placeholder: 'sommerfest.jpg' } );
this.websiteUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://...' } );
this.websiteUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://...' } );
this.websiteTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.websiteTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );


this.omapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://omaps.app/...' } );
this.omapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://omaps.app/...' } );
this.omapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Adresse als Anzeigetext' } );
this.omapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Adresse als Anzeigetext' } );
this.osmUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://www.openstreetmap.org/way/...' } );
this.osmUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://www.openstreetmap.org/way/...' } );
this.osmTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.osmTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.koordinatenInput = new OO.ui.TextInputWidget( { placeholder: '47.7500000,15.6800000' } );
this.koordinatenInput = new OO.ui.TextInputWidget( { placeholder: '47.7500000,15.6800000' } );
this.comapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://comaps.at/...' } );
this.comapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://comaps.at/...' } );
this.comapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.comapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.gmapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://maps.app.goo.gl/...' } );
this.gmapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://maps.app.goo.gl/...' } );
this.gmapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
this.gmapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );


var fsBasis = new OO.ui.FieldsetLayout( { label: 'Pflichtfelder' } );
var fsBasis = new OO.ui.FieldsetLayout( { label: 'Pflichtfelder' } );
fsBasis.addItems( [
fsBasis.addItems( [
new OO.ui.FieldLayout( this.titelInput, {
new OO.ui.FieldLayout( this.titelInput, {
label: 'Seitentitel', align: 'left',
label: 'Seitentitel', align: 'left',
help: 'Wird der Name der neuen Wiki-Seite. Muss eindeutig sein.'
help: 'Wird der Name der neuen Wiki-Seite. Muss eindeutig sein.'
} ),
} ),
new OO.ui.FieldLayout( this.datumInput, { label: 'Datum', align: 'left' } ),
new OO.ui.FieldLayout( this.datumInput, { label: 'Datum', align: 'left' } ),
new OO.ui.FieldLayout( this.uhrzeitInput, { label: 'Uhrzeit', align: 'left' } )
new OO.ui.FieldLayout( this.uhrzeitInput, { label: 'Uhrzeit', align: 'left' } )
] );
] );


var fsEvent = new OO.ui.FieldsetLayout( { label: 'Event' } );
var fsEvent = new OO.ui.FieldsetLayout( { label: 'Event' } );
fsEvent.addItems( [
fsEvent.addItems( [
new OO.ui.FieldLayout( this.bildInput, {
new OO.ui.FieldLayout( this.bildInput, {
label: 'Bild (Dateiname)', align: 'left',
label: 'Bild (Dateiname)', align: 'left',
help: 'Muss vorher hochgeladen sein. Leer lassen, wenn kein Bild.'
help: 'Muss vorher hochgeladen sein. Leer lassen, wenn kein Bild.'
} ),
} ),
new OO.ui.FieldLayout( this.websiteUrlInput, { label: 'Website URL', align: 'left' } ),
new OO.ui.FieldLayout( this.websiteUrlInput, { label: 'Website URL', align: 'left' } ),
new OO.ui.FieldLayout( this.websiteTextInput, { label: 'Website Anzeigetext', align: 'left' } )
new OO.ui.FieldLayout( this.websiteTextInput, { label: 'Website Anzeigetext', align: 'left' } )
] );
] );


var fsLoc = new OO.ui.FieldsetLayout( { label: 'Location (alles optional)' } );
var fsLoc = new OO.ui.FieldsetLayout( { label: 'Location (alles optional)' } );
fsLoc.addItems( [
fsLoc.addItems( [
new OO.ui.FieldLayout( this.omapsUrlInput, { label: 'Organic Maps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.omapsUrlInput, { label: 'Organic Maps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.omapsTextInput, { label: 'Organic Maps Adresse', align: 'left' } ),
new OO.ui.FieldLayout( this.omapsTextInput, { label: 'Organic Maps Adresse', align: 'left' } ),
new OO.ui.FieldLayout( this.osmUrlInput, { label: 'OpenStreetMap URL', align: 'left' } ),
new OO.ui.FieldLayout( this.osmUrlInput, { label: 'OpenStreetMap URL', align: 'left' } ),
new OO.ui.FieldLayout( this.osmTextInput, { label: 'OpenStreetMap Anzeigetext', align: 'left' } ),
new OO.ui.FieldLayout( this.osmTextInput, { label: 'OpenStreetMap Anzeigetext', align: 'left' } ),
new OO.ui.FieldLayout( this.koordinatenInput, { label: 'GPS-Koordinaten', align: 'left' } ),
new OO.ui.FieldLayout( this.koordinatenInput, { label: 'GPS-Koordinaten', align: 'left' } ),
new OO.ui.FieldLayout( this.comapsUrlInput, { label: 'CoMaps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.comapsUrlInput, { label: 'CoMaps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.comapsTextInput, { label: 'CoMaps Anzeigetext', align: 'left' } ),
new OO.ui.FieldLayout( this.comapsTextInput, { label: 'CoMaps Anzeigetext', align: 'left' } ),
new OO.ui.FieldLayout( this.gmapsUrlInput, { label: 'Google Maps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.gmapsUrlInput, { label: 'Google Maps URL', align: 'left' } ),
new OO.ui.FieldLayout( this.gmapsTextInput, { label: 'Google Maps Anzeigetext', align: 'left' } )
new OO.ui.FieldLayout( this.gmapsTextInput, { label: 'Google Maps Anzeigetext', align: 'left' } )
] );
] );


this.panel.$element.append( fsBasis.$element, fsEvent.$element, fsLoc.$element );
this.panel.$element.append( fsBasis.$element, fsEvent.$element, fsLoc.$element );
this.$body.append( this.panel.$element );
this.$body.append( this.panel.$element );
};
};


EventDialog.prototype.getActionProcess = function ( action ) {
EventDialog.prototype.getActionProcess = function ( action ) {
var dialog = this;
var dialog = this;
if ( action === 'save' ) {
if ( action === 'save' ) {
return new OO.ui.Process( function () {
return new OO.ui.Process( function () {
var titel = v( dialog.titelInput.getValue() );
var titel = v( dialog.titelInput.getValue() );
var datum = v( dialog.datumInput.getValue() );
var datum = v( dialog.datumInput.getValue() );
var uhrzeit = v( dialog.uhrzeitInput.getValue() );
var uhrzeit = v( dialog.uhrzeitInput.getValue() );


if ( !titel || !datum || !uhrzeit ) {
if ( !titel || !datum || !uhrzeit ) {
return $.Deferred().reject( new OO.ui.Error(
return $.Deferred().reject( new OO.ui.Error(
'Bitte alle Pflichtfelder ausfüllen.',
'Bitte alle Pflichtfelder ausfüllen.',
{ recoverable: true }
{ recoverable: true }
) ).promise();
) ).promise();
}
}


var fields = {
var fields = {
datum: datum,
datum: datum,
uhrzeit: uhrzeit,
uhrzeit: uhrzeit,
bild: v( dialog.bildInput.getValue() ),
bild: v( dialog.bildInput.getValue() ),
websiteUrl: v( dialog.websiteUrlInput.getValue() ),
websiteUrl: v( dialog.websiteUrlInput.getValue() ),
websiteText: v( dialog.websiteTextInput.getValue() ),
websiteText: v( dialog.websiteTextInput.getValue() ),
omapsUrl: v( dialog.omapsUrlInput.getValue() ),
omapsUrl: v( dialog.omapsUrlInput.getValue() ),
omapsText: v( dialog.omapsTextInput.getValue() ),
omapsText: v( dialog.omapsTextInput.getValue() ),
osmUrl: v( dialog.osmUrlInput.getValue() ),
osmUrl: v( dialog.osmUrlInput.getValue() ),
osmText: v( dialog.osmTextInput.getValue() ),
osmText: v( dialog.osmTextInput.getValue() ),
koordinaten: v( dialog.koordinatenInput.getValue() ),
koordinaten: v( dialog.koordinatenInput.getValue() ),
comapsUrl: v( dialog.comapsUrlInput.getValue() ),
comapsUrl: v( dialog.comapsUrlInput.getValue() ),
comapsText: v( dialog.comapsTextInput.getValue() ),
comapsText: v( dialog.comapsTextInput.getValue() ),
gmapsUrl: v( dialog.gmapsUrlInput.getValue() ),
gmapsUrl: v( dialog.gmapsUrlInput.getValue() ),
gmapsText: v( dialog.gmapsTextInput.getValue() )
gmapsText: v( dialog.gmapsTextInput.getValue() )
};
};


var wikitext = buildWikitext( fields );
var wikitext = buildWikitext( fields );
var api = new mw.Api();
var api = new mw.Api();


// Erst prüfen ob Seite schon existiert
return api.get( {
return api.get( {
action: 'query',
action: 'query',
titles: titel,
titles: titel,
formatversion: 2
formatversion: 2
} ).then( function ( data ) {
} ).then( function ( data ) {
var page = data.query.pages[ 0 ];
var page = data.query.pages[ 0 ];
if ( !page.missing ) {
if ( !page.missing ) {
return $.Deferred().reject( new OO.ui.Error(
'Eine Seite mit dem Titel „' + titel + '" existiert bereits.',
{ recoverable: true }
) ).promise();
}
return api.postWithToken( 'csrf', {
action: 'edit',
title: titel,
text: wikitext,
createonly: true,
summary: 'Veranstaltung über Eventform-Gadget angelegt'
} );
} ).then( function () {
window.location.href = mw.util.getUrl( titel );
}, function ( err ) {
if ( err instanceof OO.ui.Error ) {
return $.Deferred().reject( err ).promise();
}
return $.Deferred().reject( new OO.ui.Error(
return $.Deferred().reject( new OO.ui.Error(
'Eine Seite mit dem Titel „' + titel + '" existiert bereits.',
'Fehler beim Anlegen: ' + ( err && err.toString ? err.toString() : 'unbekannt' ),
{ recoverable: true }
{ recoverable: true }
) ).promise();
) ).promise();
}
return api.postWithToken( 'csrf', {
action: 'edit',
title: titel,
text: wikitext,
createonly: true,
summary: 'Veranstaltung über Eventform-Gadget angelegt'
} );
} );
} ).then( function () {
window.location.href = mw.util.getUrl( titel );
}, function ( err ) {
if ( err instanceof OO.ui.Error ) {
return $.Deferred().reject( err ).promise();
}
return $.Deferred().reject( new OO.ui.Error(
'Fehler beim Anlegen: ' + ( err && err.toString ? err.toString() : 'unbekannt' ),
{ recoverable: true }
) ).promise();
} );
} );
} );
}
}
return EventDialog.super.prototype.getActionProcess.call( this, action );
return EventDialog.super.prototype.getActionProcess.call( this, action );
};
};
 
EventDialog.prototype.getBodyHeight = function () {
return 600;
};
 
console.log( 'EVENTFORM 4: Dialog-Klasse definiert, hole Container' );


EventDialog.prototype.getBodyHeight = function () {
var $container = $( '#event-form-container' );
return 600;
console.log( 'EVENTFORM 4: Container gefunden:', $container.length, $container[0] );
};


// UI einbauen - kein DOM-Ready-Wrapper, da die Module asynchron geladen werden
if ( !$container.length ) {
// und das DOM zu dem Zeitpunkt garantiert fertig ist
$container = $( '<div id="event-form-container"></div>' )
var $container = $( '#event-form-container' );
.appendTo( '#mw-content-text .mw-parser-output' );
if ( !$container.length ) {
console.log( 'EVENTFORM 4: Container neu erstellt' );
$container = $( '<div id="event-form-container"></div>' )
}
.appendTo( '#mw-content-text .mw-parser-output' );
}


var button = new OO.ui.ButtonWidget( {
var button = new OO.ui.ButtonWidget( {
label: 'Neue Veranstaltung anlegen',
label: 'Neue Veranstaltung anlegen',
flags: [ 'primary', 'progressive' ],
flags: [ 'primary', 'progressive' ],
icon: 'add'
icon: 'add'
} );
} );
console.log( 'EVENTFORM 5: Button erstellt' );


var windowManager = new OO.ui.WindowManager();
var windowManager = new OO.ui.WindowManager();
$( document.body ).append( windowManager.$element );
$( document.body ).append( windowManager.$element );
var dialog = new EventDialog( { size: 'large' } );
var dialog = new EventDialog( { size: 'large' } );
windowManager.addWindows( [ dialog ] );
windowManager.addWindows( [ dialog ] );


button.on( 'click', function () {
button.on( 'click', function () {
windowManager.openWindow( dialog );
windowManager.openWindow( dialog );
} );
} );


$container.empty().append( button.$element );
$container.empty().append( button.$element );
console.log( 'EVENTFORM 6: FERTIG - Button im DOM. Container-HTML:', $container.html() );


} catch ( e ) {
console.error( 'EVENTFORM EXCEPTION:', e );
}
}, function ( err ) {
console.error( 'EVENTFORM: Module konnten nicht geladen werden:', err );
} );
} );
}() );
}() );

Version vom 30. Mai 2026, 01:27 Uhr

/**
 * Eventform-Gadget: Komfortables Anlegen von Veranstaltungsseiten
 * Aktiv auf der Seite "Veranstaltung_anlegen"
 * DEBUG-VERSION mit console.log
 */
( function () {
	'use strict';

	console.log( 'EVENTFORM 1: Gadget-Code wird ausgeführt' );
	console.log( 'EVENTFORM 1: wgPageName =', mw.config.get( 'wgPageName' ) );
	console.log( 'EVENTFORM 1: wgUserName =', mw.config.get( 'wgUserName' ) );

	// Konfiguration
	var TRIGGER_PAGE = 'Veranstaltung_anlegen';

	// Nur auf der Trigger-Seite aktiv werden
	if ( mw.config.get( 'wgPageName' ) !== TRIGGER_PAGE ) {
		console.log( 'EVENTFORM: falsche Seite, beende' );
		return;
	}

	// Nur für eingeloggte User
	if ( !mw.config.get( 'wgUserName' ) ) {
		console.log( 'EVENTFORM: nicht eingeloggt, beende' );
		return;
	}

	console.log( 'EVENTFORM 2: Checks bestanden, lade Module' );

	var WOCHENTAGE = [ 'Sonntag', 'Montag', 'Dienstag', 'Mittwoch',
		'Donnerstag', 'Freitag', 'Samstag' ];
	var MONATE = [ 'Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
		'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember' ];

	function formatGermanDate( isoDate ) {
		var d = new Date( isoDate + 'T12:00:00' );
		return WOCHENTAGE[ d.getDay() ] + ' ' + d.getDate() + '. ' +
			MONATE[ d.getMonth() ] + ' ' + d.getFullYear();
	}

	function v( val ) {
		return ( val || '' ).trim();
	}

	function buildWikitext( f ) {
		var lines = [];
		lines.push( '[[Hauptseite]] > [[Hauptseite#Kultur & Events|Kultur & Events]] > [[Veranstaltungen]]' );
		lines.push( '==Zeit==' );
		lines.push( '🗓️ ' + formatGermanDate( f.datum ) + ', ' );
		lines.push( '⏰ ' + f.uhrzeit );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '==Event==' );
		if ( f.bild ) {
			lines.push( '[[file:' + f.bild + '|frameless|upright=3.0]]' );
		}
		if ( f.websiteUrl ) {
			lines.push( '🌐 [https://](' + f.websiteUrl + ')' + f.websiteText );
		}
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '==Location==' );
		if ( f.omapsUrl ) {
			lines.push( '📍 [[https://omaps.app/](' + f.omapsUrl + ')' + f.omapsText + ']' );
		}
		if ( f.osmUrl ) {
			lines.push( '[[file:osm.png|24px|link=]] [https://www.openstreetmap.org/way/](' + f.osmUrl + ')' + f.osmText );
		}
		if ( f.koordinaten ) {
			lines.push( '🧭 ' + f.koordinaten );
		}
		if ( f.comapsUrl ) {
			lines.push( '[[file:CoMaps.png|24px|link=]] [https://comaps.at/](' + f.comapsUrl + ')' + f.comapsText );
		}
		if ( f.gmapsUrl ) {
			lines.push( '[[file:GoogleMaps.png|24px|link=]] [https://maps.app.goo.gl/](' + f.gmapsUrl + ')' + f.gmapsText );
		}
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '<br>' );
		lines.push( '==Photos & Videos==' );
		lines.push( 'Bitte hier verlinken.' );
		return lines.join( '\n' );
	}

	mw.loader.using( [
		'oojs-ui-core',
		'oojs-ui-windows',
		'oojs-ui.styles.icons-interactions',
		'mediawiki.api',
		'mediawiki.util'
	] ).then( function () {
		console.log( 'EVENTFORM 3: Module geladen, baue UI' );
		try {

			function EventDialog( config ) {
				EventDialog.super.call( this, config );
			}
			OO.inheritClass( EventDialog, OO.ui.ProcessDialog );

			EventDialog.static.name = 'eventDialog';
			EventDialog.static.title = 'Neue Veranstaltung anlegen';
			EventDialog.static.actions = [
				{ action: 'save', label: 'Seite anlegen', flags: [ 'primary', 'progressive' ] },
				{ label: 'Abbrechen', flags: 'safe' }
			];

			EventDialog.prototype.initialize = function () {
				EventDialog.super.prototype.initialize.apply( this, arguments );

				this.panel = new OO.ui.PanelLayout( { padded: true, expanded: false } );

				this.titelInput = new OO.ui.TextInputWidget( {
					placeholder: 'z.B. Sommerfest 2026', required: true
				} );
				this.datumInput = new OO.ui.TextInputWidget( { type: 'date', required: true } );
				this.uhrzeitInput = new OO.ui.TextInputWidget( { type: 'time', value: '17:00', required: true } );

				this.bildInput = new OO.ui.TextInputWidget( { placeholder: 'sommerfest.jpg' } );
				this.websiteUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://...' } );
				this.websiteTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );

				this.omapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://omaps.app/...' } );
				this.omapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Adresse als Anzeigetext' } );
				this.osmUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://www.openstreetmap.org/way/...' } );
				this.osmTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
				this.koordinatenInput = new OO.ui.TextInputWidget( { placeholder: '47.7500000,15.6800000' } );
				this.comapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://comaps.at/...' } );
				this.comapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );
				this.gmapsUrlInput = new OO.ui.TextInputWidget( { placeholder: 'https://maps.app.goo.gl/...' } );
				this.gmapsTextInput = new OO.ui.TextInputWidget( { placeholder: 'Anzeigetext' } );

				var fsBasis = new OO.ui.FieldsetLayout( { label: 'Pflichtfelder' } );
				fsBasis.addItems( [
					new OO.ui.FieldLayout( this.titelInput, {
						label: 'Seitentitel', align: 'left',
						help: 'Wird der Name der neuen Wiki-Seite. Muss eindeutig sein.'
					} ),
					new OO.ui.FieldLayout( this.datumInput, { label: 'Datum', align: 'left' } ),
					new OO.ui.FieldLayout( this.uhrzeitInput, { label: 'Uhrzeit', align: 'left' } )
				] );

				var fsEvent = new OO.ui.FieldsetLayout( { label: 'Event' } );
				fsEvent.addItems( [
					new OO.ui.FieldLayout( this.bildInput, {
						label: 'Bild (Dateiname)', align: 'left',
						help: 'Muss vorher hochgeladen sein. Leer lassen, wenn kein Bild.'
					} ),
					new OO.ui.FieldLayout( this.websiteUrlInput, { label: 'Website URL', align: 'left' } ),
					new OO.ui.FieldLayout( this.websiteTextInput, { label: 'Website Anzeigetext', align: 'left' } )
				] );

				var fsLoc = new OO.ui.FieldsetLayout( { label: 'Location (alles optional)' } );
				fsLoc.addItems( [
					new OO.ui.FieldLayout( this.omapsUrlInput, { label: 'Organic Maps URL', align: 'left' } ),
					new OO.ui.FieldLayout( this.omapsTextInput, { label: 'Organic Maps Adresse', align: 'left' } ),
					new OO.ui.FieldLayout( this.osmUrlInput, { label: 'OpenStreetMap URL', align: 'left' } ),
					new OO.ui.FieldLayout( this.osmTextInput, { label: 'OpenStreetMap Anzeigetext', align: 'left' } ),
					new OO.ui.FieldLayout( this.koordinatenInput, { label: 'GPS-Koordinaten', align: 'left' } ),
					new OO.ui.FieldLayout( this.comapsUrlInput, { label: 'CoMaps URL', align: 'left' } ),
					new OO.ui.FieldLayout( this.comapsTextInput, { label: 'CoMaps Anzeigetext', align: 'left' } ),
					new OO.ui.FieldLayout( this.gmapsUrlInput, { label: 'Google Maps URL', align: 'left' } ),
					new OO.ui.FieldLayout( this.gmapsTextInput, { label: 'Google Maps Anzeigetext', align: 'left' } )
				] );

				this.panel.$element.append( fsBasis.$element, fsEvent.$element, fsLoc.$element );
				this.$body.append( this.panel.$element );
			};

			EventDialog.prototype.getActionProcess = function ( action ) {
				var dialog = this;
				if ( action === 'save' ) {
					return new OO.ui.Process( function () {
						var titel = v( dialog.titelInput.getValue() );
						var datum = v( dialog.datumInput.getValue() );
						var uhrzeit = v( dialog.uhrzeitInput.getValue() );

						if ( !titel || !datum || !uhrzeit ) {
							return $.Deferred().reject( new OO.ui.Error(
								'Bitte alle Pflichtfelder ausfüllen.',
								{ recoverable: true }
							) ).promise();
						}

						var fields = {
							datum: datum,
							uhrzeit: uhrzeit,
							bild: v( dialog.bildInput.getValue() ),
							websiteUrl: v( dialog.websiteUrlInput.getValue() ),
							websiteText: v( dialog.websiteTextInput.getValue() ),
							omapsUrl: v( dialog.omapsUrlInput.getValue() ),
							omapsText: v( dialog.omapsTextInput.getValue() ),
							osmUrl: v( dialog.osmUrlInput.getValue() ),
							osmText: v( dialog.osmTextInput.getValue() ),
							koordinaten: v( dialog.koordinatenInput.getValue() ),
							comapsUrl: v( dialog.comapsUrlInput.getValue() ),
							comapsText: v( dialog.comapsTextInput.getValue() ),
							gmapsUrl: v( dialog.gmapsUrlInput.getValue() ),
							gmapsText: v( dialog.gmapsTextInput.getValue() )
						};

						var wikitext = buildWikitext( fields );
						var api = new mw.Api();

						return api.get( {
							action: 'query',
							titles: titel,
							formatversion: 2
						} ).then( function ( data ) {
							var page = data.query.pages[ 0 ];
							if ( !page.missing ) {
								return $.Deferred().reject( new OO.ui.Error(
									'Eine Seite mit dem Titel „' + titel + '" existiert bereits.',
									{ recoverable: true }
								) ).promise();
							}
							return api.postWithToken( 'csrf', {
								action: 'edit',
								title: titel,
								text: wikitext,
								createonly: true,
								summary: 'Veranstaltung über Eventform-Gadget angelegt'
							} );
						} ).then( function () {
							window.location.href = mw.util.getUrl( titel );
						}, function ( err ) {
							if ( err instanceof OO.ui.Error ) {
								return $.Deferred().reject( err ).promise();
							}
							return $.Deferred().reject( new OO.ui.Error(
								'Fehler beim Anlegen: ' + ( err && err.toString ? err.toString() : 'unbekannt' ),
								{ recoverable: true }
							) ).promise();
						} );
					} );
				}
				return EventDialog.super.prototype.getActionProcess.call( this, action );
			};

			EventDialog.prototype.getBodyHeight = function () {
				return 600;
			};

			console.log( 'EVENTFORM 4: Dialog-Klasse definiert, hole Container' );

			var $container = $( '#event-form-container' );
			console.log( 'EVENTFORM 4: Container gefunden:', $container.length, $container[0] );

			if ( !$container.length ) {
				$container = $( '<div id="event-form-container"></div>' )
					.appendTo( '#mw-content-text .mw-parser-output' );
				console.log( 'EVENTFORM 4: Container neu erstellt' );
			}

			var button = new OO.ui.ButtonWidget( {
				label: 'Neue Veranstaltung anlegen',
				flags: [ 'primary', 'progressive' ],
				icon: 'add'
			} );
			console.log( 'EVENTFORM 5: Button erstellt' );

			var windowManager = new OO.ui.WindowManager();
			$( document.body ).append( windowManager.$element );
			var dialog = new EventDialog( { size: 'large' } );
			windowManager.addWindows( [ dialog ] );

			button.on( 'click', function () {
				windowManager.openWindow( dialog );
			} );

			$container.empty().append( button.$element );
			console.log( 'EVENTFORM 6: FERTIG - Button im DOM. Container-HTML:', $container.html() );

		} catch ( e ) {
			console.error( 'EVENTFORM EXCEPTION:', e );
		}
	}, function ( err ) {
		console.error( 'EVENTFORM: Module konnten nicht geladen werden:', err );
	} );
}() );