Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
168 changes: 107 additions & 61 deletions assets/js/odw-admin-fields.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
* 1. Auto-suggest datalist for license_custom (inside distributions)
* 2. Auto-suggest datalist for CESSDA topic classification
* 3. Composite file-size widget (Zahl + Einheit → Bytes in backing field)
* Widget HTML is built via JS so no CF html-field is needed inside
* the complex field (CF5 React renderer crashes on html fields there).
*/
( function () {
'use strict';

var data = ( typeof odwAdminFields !== 'undefined' ) ? odwAdminFields : {};
var i18n = data.fileSizeWidget || {};

// -------------------------------------------------------------------------
// Utility: set a value on a React-controlled or plain input
Expand Down Expand Up @@ -77,75 +80,118 @@

// -------------------------------------------------------------------------
// 3. File-size composite widget
// Finds every .odw-filesize-widget and wires up its number+unit inputs
// to write computed bytes into the backing CF field.
// Built dynamically from JS so no CF html-field is needed inside the
// complex field. Finds every hidden [data-odw-backing] input and inserts
// a visible composite widget before its CF field wrapper.
// -------------------------------------------------------------------------
function initFileSizeWidgets() {
document.querySelectorAll( '.odw-filesize-widget' ).forEach( function ( widget ) {
var numberInput = widget.querySelector( '.odw-filesize-number' );
var unitSelect = widget.querySelector( '.odw-filesize-unit' );
var hint = widget.querySelector( '.odw-filesize-hint' );

// Find the backing CF input (data-odw-backing="byte_size" in same group).
var group = widget.closest( '.carbon-fields-group, .carbon-complex-group, .cf-group, [data-group]' );
var backing = group
? group.querySelector( 'input[data-odw-backing="byte_size"]' )
: null;

if ( ! numberInput || ! unitSelect ) {
return;
}

var factors = { KB: 1024, MB: 1048576, GB: 1073741824 };
function buildWidgetHtml() {
var label = i18n.label || 'Dateigröße';
var optional = i18n.optional || '(optional)';
var placeholder = i18n.placeholder || 'z. B. 2.5';
var ariaNumber = i18n.ariaNumber || 'Dateigröße Zahlenwert';
var ariaUnit = i18n.ariaUnit || 'Einheit';
var helpText = i18n.helpText || '1 MB = 1.024 KB';

return '<div class="odw-filesize-widget">' +
'<label class="odw-filesize-label">' + label +
' <span class="odw-filesize-optional">' + optional + '</span>' +
'</label>' +
'<div class="odw-filesize-row">' +
'<input type="number" class="odw-filesize-number" min="0" step="0.1"' +
' placeholder="' + placeholder + '" aria-label="' + ariaNumber + '">' +
'<select class="odw-filesize-unit" aria-label="' + ariaUnit + '">' +
'<option value="KB">KB</option>' +
'<option value="MB" selected>MB</option>' +
'<option value="GB">GB</option>' +
'</select>' +
'<span class="odw-filesize-hint description"></span>' +
'</div>' +
'<p class="odw-filesize-helptext description">' + helpText + '</p>' +
'</div>';
}

function updateBacking() {
var num = parseFloat( numberInput.value );
var unit = unitSelect.value;
if ( isNaN( num ) || num < 0 ) {
numberInput.setCustomValidity( 'Bitte einen positiven Wert eingeben.' );
if ( hint ) {
hint.textContent = '';
}
return;
function wireWidget( widget, backing ) {
var numberInput = widget.querySelector( '.odw-filesize-number' );
var unitSelect = widget.querySelector( '.odw-filesize-unit' );
var hint = widget.querySelector( '.odw-filesize-hint' );
var factors = { KB: 1024, MB: 1048576, GB: 1073741824 };

function updateBacking() {
var num = parseFloat( numberInput.value );
var unit = unitSelect.value;
if ( isNaN( num ) || num < 0 ) {
numberInput.setCustomValidity( 'Bitte einen positiven Wert eingeben.' );
if ( hint ) {
hint.textContent = '';
}
numberInput.setCustomValidity( '' );
return;
}
numberInput.setCustomValidity( '' );

var bytes = Math.round( num * ( factors[ unit ] || 1048576 ) );
var bytes = Math.round( num * ( factors[ unit ] || 1048576 ) );

if ( hint ) {
hint.textContent = '= ' + bytes.toLocaleString( 'de-DE' ) + ' Bytes';
}
if ( hint ) {
hint.textContent = '= ' + bytes.toLocaleString( 'de-DE' ) + ' Bytes';
}

if ( backing ) {
setInputValue( backing, String( bytes ) );
}
if ( backing ) {
setInputValue( backing, String( bytes ) );
}
}

numberInput.addEventListener( 'input', updateBacking );
numberInput.addEventListener( 'change', updateBacking );
unitSelect.addEventListener( 'change', updateBacking );

// Restore display value from stored bytes on page load.
if ( backing && backing.value && backing.value !== '0' && backing.value !== '' ) {
var stored = parseInt( backing.value, 10 );
if ( ! isNaN( stored ) && stored > 0 ) {
var displayUnit = 'MB';
var displayVal;
if ( stored >= 1073741824 ) {
displayUnit = 'GB';
displayVal = stored / 1073741824;
} else if ( stored >= 1048576 ) {
displayUnit = 'MB';
displayVal = stored / 1048576;
} else {
displayUnit = 'KB';
displayVal = stored / 1024;
}
numberInput.value = parseFloat( displayVal.toFixed( 2 ) );
unitSelect.value = displayUnit;
updateBacking();
numberInput.addEventListener( 'input', updateBacking );
numberInput.addEventListener( 'change', updateBacking );
unitSelect.addEventListener( 'change', updateBacking );

// Restore display value from stored bytes on page load.
if ( backing && backing.value && backing.value !== '0' && backing.value !== '' ) {
var stored = parseInt( backing.value, 10 );
if ( ! isNaN( stored ) && stored > 0 ) {
var displayUnit, displayVal;
if ( stored >= 1073741824 ) {
displayUnit = 'GB';
displayVal = stored / 1073741824;
} else if ( stored >= 1048576 ) {
displayUnit = 'MB';
displayVal = stored / 1048576;
} else {
displayUnit = 'KB';
displayVal = stored / 1024;
}
numberInput.value = parseFloat( displayVal.toFixed( 2 ) );
unitSelect.value = displayUnit;
updateBacking();
}
}
}

function initFileSizeWidget( backing ) {
if ( ! backing || backing.dataset.odwWidgetInit ) {
return;
}
backing.dataset.odwWidgetInit = '1';

// Find the CF field wrapper that contains the backing input.
// CF5 uses .cf-field as the wrapper; fall back to closest div.
var fieldWrapper = backing.closest( '.cf-field' ) ||
backing.closest( 'div[class]' ) ||
backing.parentElement;

if ( ! fieldWrapper || ! fieldWrapper.parentNode ) {
return;
}

var widget = document.createElement( 'div' );
widget.innerHTML = buildWidgetHtml();
var widgetEl = widget.firstElementChild;

fieldWrapper.parentNode.insertBefore( widgetEl, fieldWrapper );
wireWidget( widgetEl, backing );
}

function initFileSizeWidgets() {
document.querySelectorAll( 'input[data-odw-backing="byte_size"]' ).forEach( function ( backing ) {
initFileSizeWidget( backing );
} );
}

Expand All @@ -163,8 +209,8 @@
node.querySelectorAll( 'input[data-odw-autosuggest="license_custom"]' ).forEach( function ( input ) {
attachDatalist( input, 'odw-license-datalist', data.licenseOptions || [] );
} );
node.querySelectorAll( '.odw-filesize-widget' ).forEach( function () {
initFileSizeWidgets();
node.querySelectorAll( 'input[data-odw-backing="byte_size"]' ).forEach( function ( backing ) {
initFileSizeWidget( backing );
} );
} );
} );
Expand Down
8 changes: 8 additions & 0 deletions includes/class-admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,14 @@ public static function enqueue_assets( string $hook ): void {
array(
'licenseOptions' => $license_file_options,
'cessdaOptions' => $cessda_options,
'fileSizeWidget' => array(
'label' => __( 'Dateigröße', 'open-data-wizard' ),
'optional' => __( '(optional)', 'open-data-wizard' ),
'placeholder' => __( 'z. B. 2.5', 'open-data-wizard' ),
'ariaNumber' => __( 'Dateigröße Zahlenwert', 'open-data-wizard' ),
'ariaUnit' => __( 'Einheit', 'open-data-wizard' ),
'helpText' => __( 'Bitte geben Sie die ungefähre Größe der Datei an und wählen Sie die passende Einheit. 1 MB = 1.024 KB', 'open-data-wizard' ),
),
)
);

Expand Down
35 changes: 0 additions & 35 deletions includes/class-fields.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,6 @@ private static function register_required_fields(): void {
->add_options( self::get_format_options() )
->set_help_text( __( 'FORMAT (dct:format)', 'open-data-wizard' ) . "\n\n" . __( 'Beispiel: CSV, JSON, PDF', 'open-data-wizard' ) ),

Field::make( 'html', 'byte_size_ui' )
->set_html( self::get_filesize_widget_html() ),

Field::make( 'text', 'byte_size', __( 'Dateigröße (Bytes)', 'open-data-wizard' ) )
->set_attribute( 'type', 'number' )
->set_attribute( 'min', '0' )
Expand Down Expand Up @@ -630,38 +627,6 @@ public static function get_political_geocoding_level_options(): array {
*
* @return string HTML markup.
*/
private static function get_filesize_widget_html(): string {
ob_start();
?>
<div class="odw-filesize-widget">
<label class="odw-filesize-label">
<?php esc_html_e( 'Dateigröße', 'open-data-wizard' ); ?>
<span class="odw-filesize-optional"><?php esc_html_e( '(optional)', 'open-data-wizard' ); ?></span>
</label>
<div class="odw-filesize-row">
<input
type="number"
class="odw-filesize-number"
min="0"
step="0.1"
placeholder="<?php esc_attr_e( 'z. B. 2.5', 'open-data-wizard' ); ?>"
aria-label="<?php esc_attr_e( 'Dateigröße Zahlenwert', 'open-data-wizard' ); ?>"
>
<select class="odw-filesize-unit" aria-label="<?php esc_attr_e( 'Einheit', 'open-data-wizard' ); ?>">
<option value="KB">KB</option>
<option value="MB" selected="selected">MB</option>
<option value="GB">GB</option>
</select>
<span class="odw-filesize-hint description"></span>
</div>
<p class="odw-filesize-helptext description">
<?php esc_html_e( 'Bitte geben Sie die ungefähre Größe der Datei an und wählen Sie die passende Einheit. 1 MB = 1.024 KB', 'open-data-wizard' ); ?>
</p>
</div>
<?php
return ob_get_clean();
}

/**
* Generates the HTML for the JSON-LD preview tab.
*
Expand Down
Loading