# easy-invoice/2.3.3/includes/Forms/ItemFieldRenderer.php

Easy Invoice – Invoice Generator, PDF Quotes &amp; Payments, version 2.3.3. 315 lines.

- Page: https://pluginprobe.com/plugins/easy-invoice/2.3.3/code/includes/Forms/ItemFieldRenderer.php
- Raw: https://pluginprobe.com/plugins/easy-invoice/2.3.3/raw/includes/Forms/ItemFieldRenderer.php
- Modified: 2025-08-19T12:00:36+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/easy-invoice/2.3.3/code/includes/Forms/ItemFieldRenderer.php#L10-L20`.

```php
<?php
/**
 * Item Field Renderer Class
 *
 * @package     EasyInvoice
 * @author      Your Name
 * @copyright   Copyright (c) 2023, Your Company
 * @license     http://opensource.org/licenses/gpl-2.0.php GNU Public License
 * @since       1.0.0
 */

namespace EasyInvoice\Forms;

use EasyInvoice\Forms\BaseFieldRegistration;

/**
 * Item Field Renderer
 *
 * Handles rendering of all invoice item field types.
 *
 * @since 1.0.0
 */
class ItemFieldRenderer {
    
    /**
     * Render an item field
     *
     * @since 1.0.0
     * @param array $field Field configuration
     * @param int $item_index Item index
     * @param string|null $item_value Current item value
     * @return string Rendered HTML
     */
    public function renderItemField(array $field, int $item_index, ?string $item_value = ''): string {
        $type = $field['type'] ?? 'text';
        $method = 'renderItem' . ucfirst($type) . 'Field';
        
        if (method_exists($this, $method)) {
            return $this->$method($field, $item_index, $item_value);
        }
        
        // Fallback to text field
        return $this->renderItemTextField($field, $item_index, $item_value);
    }
    
    /**
     * Render an item text field
     *
     * @since 1.0.0
     * @param array $field Field configuration
     * @param int $item_index Item index
     * @param string|null $item_value Current item value
     * @return string Rendered HTML
     */
    private function renderItemTextField(array $field, int $item_index, ?string $item_value = ''): string {
        $id = $field['id'] ?? '';
        $name = $field['name'] ?? '';
        $label = $field['label'] ?? '';
        $placeholder = $field['placeholder'] ?? '';
        $required = $field['required'] ?? false;
        $readonly = $field['readonly'] ?? false;
        $container_class = $field['container_class'] ?? 'sm:col-span-6';
        
        $value = $item_value ?: ($field['default_value'] ?? '');
        $description = $field['description'] ?? '';
        
        $required_attr = $required ? 'required' : '';
        $readonly_attr = $readonly ? 'readonly' : '';
        $required_class = $required ? 'required' : '';
        $description_html = $description ? '<p class="text-gray-500 mt-1 text-xs">' . esc_html($description) . '</p>' : '';
        
        return sprintf(
            '<div class="%s">
                <label for="%s_%d" class="block text-sm font-bold text-gray-700 %s">%s</label>
                <div class="mt-1">
                    <input type="text" 
                           id="%s_%d" 
                           name="items[%d][%s]" 
                           value="%s" 
                           placeholder="%s" 
                           class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm %s" 
                           %s %s>
                    %s
                </div>
            </div>',
            esc_attr($container_class),
            esc_attr($id),
            $item_index,
            esc_attr($required_class),
            esc_html($label),
            esc_attr($id),
            $item_index,
            $item_index,
            esc_attr($name),
            esc_attr($value),
            esc_attr($placeholder),
            esc_attr($required_class),
            $required_attr,
            $readonly_attr,
            $description_html
        );
    }
    
    /**
     * Render an item textarea field
     *
     * @since 1.0.0
     * @param array $field Field configuration
     * @param int $item_index Item index
     * @param string|null $item_value Current item value
     * @return string Rendered HTML
     */
    private function renderItemTextareaField(array $field, int $item_index, ?string $item_value = ''): string {
        $id = $field['id'] ?? '';
        $name = $field['name'] ?? '';
        $label = $field['label'] ?? '';
        $placeholder = $field['placeholder'] ?? '';
        $required = $field['required'] ?? false;
        $readonly = $field['readonly'] ?? false;
        $container_class = $field['container_class'] ?? 'sm:col-span-6';
        $value = $item_value ?: ($field['default_value'] ?? '');
        $rows = $field['rows'] ?? 3;
        $description = $field['description'] ?? '';
        
        $required_attr = $required ? 'required' : '';
        $readonly_attr = $readonly ? 'readonly' : '';
        $required_class = $required ? 'required' : '';
        $description_html = $description ? '<p class="text-gray-500 mt-1 text-xs">' . esc_html($description) . '</p>' : '';
        
        return sprintf(
            '<div class="%s">
                <label for="%s_%d" class="block text-sm font-bold text-gray-700 %s">%s</label>
                <div class="mt-1">
                    <textarea id="%s_%d" 
                              name="items[%d][%s]" 
                              rows="%s" 
                              placeholder="%s" 
                              class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm %s" 
                              %s %s>%s</textarea>
                    %s
                </div>
            </div>',
            esc_attr($container_class),
            esc_attr($id),
            $item_index,
            esc_attr($required_class),
            esc_html($label),
            esc_attr($id),
            $item_index,
            $item_index,
            esc_attr($name),
            esc_attr($rows),
            esc_attr($placeholder),
            esc_attr($required_class),
            $required_attr,
            $readonly_attr,
            wp_kses_post($value),
            $description_html
        );
    }
    
    /**
     * Render an item number field
     *
     * @since 1.0.0
     * @param array $field Field configuration
     * @param int $item_index Item index
     * @param string $item_value Current item value
     * @return string Rendered HTML
     */
    private function renderItemNumberField(array $field, int $item_index, ?string $item_value = ''): string {
        $id = $field['id'] ?? '';
        $name = $field['name'] ?? '';
        $label = $field['label'] ?? '';
        $placeholder = $field['placeholder'] ?? '';
        $required = $field['required'] ?? false;
        $readonly = $field['readonly'] ?? false;
        $container_class = $field['container_class'] ?? 'sm:col-span-6';
        $value = $item_value ?: ($field['default_value'] ?? '');
        $min = $field['min'] ?? '';
        $max = $field['max'] ?? '';
        $step = $field['step'] ?? '';
        $description = $field['description'] ?? '';
        
        $required_attr = $required ? 'required' : '';
        $readonly_attr = $readonly ? 'readonly' : '';
        $required_class = $required ? 'required' : '';
        $min_attr = $min !== '' ? 'min="' . esc_attr($min) . '"' : '';
        $max_attr = $max !== '' ? 'max="' . esc_attr($max) . '"' : '';
        $step_attr = $step !== '' ? 'step="' . esc_attr($step) . '"' : '';
        $description_html = $description ? '<p class="text-gray-500 mt-1 text-xs">' . esc_html($description) . '</p>' : '';
        
        return sprintf(
            '<div class="%s">
                <label for="%s_%d" class="block text-sm font-bold text-gray-700 %s">%s</label>
                <div class="mt-1">
                    <input type="number" 
                           id="%s_%d" 
                           name="items[%d][%s]" 
                           value="%s" 
                           placeholder="%s" 
                           class="mt-1 block w-full border border-gray-300 rounded-md shadow-sm py-2 px-3 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm %s" 
                           %s %s %s %s %s>
                    %s
                </div>
            </div>',
            esc_attr($container_class),
            esc_attr($id),
            $item_index,
            esc_attr($required_class),
            esc_html($label),
            esc_attr($id),
            $item_index,
            $item_index,
            esc_attr($name),
            esc_attr($value),
            esc_attr($placeholder),
            esc_attr($required_class),
            $required_attr,
            $readonly_attr,
            $min_attr,
            $max_attr,
            $step_attr,
            $description_html
        );
    }
    
    /**
     * Render an item checkbox field
     *
     * @since 1.0.0
     * @param array $field Field configuration
     * @param int $item_index Item index
     * @param string $item_value Current item value
     * @return string Rendered HTML
     */
    private function renderItemCheckboxField(array $field, int $item_index, ?string $item_value = ''): string {
        $id = $field['id'] ?? '';
        $name = $field['name'] ?? '';
        $label = $field['label'] ?? '';
        $required = $field['required'] ?? false;
        $container_class = $field['container_class'] ?? 'sm:col-span-6';
        $value = (boolean)$item_value ;
        $description = $field['description'] ?? '';
        $required_attr = $required ? 'required' : '';
        $required_class = $required ? 'required' : '';
        $checked = ($value == '1' || $value === true) ? 'checked' : '';
               
        $description_html = $description ? '<p class="text-gray-500 mt-1 text-xs">' . esc_html($description) . '</p>' : '';
        
        return sprintf(
            '<div class="%s">
                <div class="flex items-start">
                    <div class="flex items-center h-5">
                        <input type="checkbox" 
                               id="%s_%d" 
                               name="items[%d][%s]" 
                               value="1" 
                               class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded %s" 
                               %s %s>
                    </div>
                    <div class="ml-3 text-sm">
                        <label for="%s_%d" class="font-bold text-gray-700 %s">%s</label>
                        %s
                    </div>
                </div>
            </div>',
            esc_attr($container_class),
            esc_attr($id),
            $item_index,
            $item_index,
            esc_attr($name),
            esc_attr($required_class),
            $checked,
            $required_attr,
            esc_attr($id),
            $item_index,
            esc_attr($required_class),
            esc_html($label),
            $description_html
        );
    }

    /**
     * Generate HTML for a blank (template) item
     *
     * @since 1.0.0
     * @param BaseFieldRegistration|null $field_registration Optional field registration to use
     * @return string
     */
    public function generateItemTemplateHtml($field_registration = null): string {
        $html = '';
        
        // If no field registration provided, use a default one
        if (!$field_registration) {
            // Try to determine the correct field registration based on context
            // This is a fallback for backward compatibility
            $field_registration = new \EasyInvoice\Forms\Invoice\InvoiceFieldRegistration();
        }
        
        $fields = $field_registration->getItemFields();
        
        // Wrap fields in a grid container
        $html .= '<div class="grid grid-cols-1 gap-y-6 gap-x-4 sm:grid-cols-4">';
        
        // Use index -1 for template fields
        foreach ($fields as $field) {
            $html .= $this->renderItemField($field, -1, '');
        }
        
        $html .= '</div>';
        
        return $html;
    }
} 
```
