soilAnalysisForm.php 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. <?php
  2. /**
  3. * components/soilAnalysisForm.php
  4. *
  5. * Soil analysis data entry form component.
  6. * Replaces modX [[$soilAnalysisForm]] chunk.
  7. */
  8. // Form field definitions with validation rules
  9. $formSections = [
  10. 'Client Information' => [
  11. 'name' => ['type' => 'text', 'label' => 'Client Name', 'required' => true, 'placeholder' => 'Enter client name'],
  12. 'company' => ['type' => 'text', 'label' => 'Company Name', 'required' => false, 'placeholder' => 'Enter company name'],
  13. 'email' => ['type' => 'email', 'label' => 'Email Address', 'required' => true, 'placeholder' => 'client@example.com'],
  14. 'site_address' => ['type' => 'text', 'label' => 'Site Address', 'required' => true, 'placeholder' => 'Enter site address'],
  15. 'state_postcode' => ['type' => 'text', 'label' => 'State & Postcode', 'required' => true, 'placeholder' => 'State, Postcode'],
  16. ],
  17. 'Sample Information' => [
  18. 'lab_no' => ['type' => 'text', 'label' => 'Lab Number', 'required' => true, 'placeholder' => 'Lab reference number'],
  19. 'batch_no' => ['type' => 'text', 'label' => 'Batch Number', 'required' => false, 'placeholder' => 'Batch reference'],
  20. 'sample_id' => ['type' => 'text', 'label' => 'Sample ID', 'required' => true, 'placeholder' => 'Sample identifier'],
  21. 'site_id' => ['type' => 'text', 'label' => 'Site ID', 'required' => true, 'placeholder' => 'Site identifier'],
  22. 'crop_type' => ['type' => 'text', 'label' => 'Crop Type', 'required' => true, 'placeholder' => 'Type of crop'],
  23. 'soil_type' => ['type' => 'select', 'label' => 'Soil Type', 'required' => true, 'options' => ['Sandy', 'Loamy', 'Clay', 'Silt', 'Peat', 'Chalk']],
  24. 'date_sampled' => ['type' => 'date', 'label' => 'Date Sampled', 'required' => true],
  25. ],
  26. 'Physical Properties' => [
  27. 'texture' => ['type' => 'text', 'label' => 'Texture', 'required' => false, 'placeholder' => 'Soil texture description'],
  28. 'gravel' => ['type' => 'number', 'label' => 'Gravel (%)', 'required' => false, 'step' => '0.1', 'min' => '0', 'max' => '100'],
  29. 'colour' => ['type' => 'text', 'label' => 'Colour', 'required' => false, 'placeholder' => 'Soil colour'],
  30. 'ocarbon' => ['type' => 'number', 'label' => 'Organic Carbon (%)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  31. 'omatter' => ['type' => 'number', 'label' => 'Organic Matter (%)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  32. ],
  33. 'Chemical Properties' => [
  34. 'ph_cacl2' => ['type' => 'number', 'label' => 'pH (CaCl₂)', 'required' => false, 'step' => '0.1', 'min' => '0', 'max' => '14'],
  35. 'ph_h2o' => ['type' => 'number', 'label' => 'pH (H₂O)', 'required' => false, 'step' => '0.1', 'min' => '0', 'max' => '14'],
  36. 'paramag' => ['type' => 'number', 'label' => 'Paramagnetic', 'required' => false, 'step' => '0.01'],
  37. 'ec' => ['type' => 'number', 'label' => 'EC (dS/m)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  38. ],
  39. 'Nutrient Analysis' => [
  40. 'NO3_N' => ['type' => 'number', 'label' => 'NO₃-N (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  41. 'NH3_N' => ['type' => 'number', 'label' => 'NH₃-N (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  42. 'p_mehlick' => ['type' => 'number', 'label' => 'P Mehlich (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  43. 'p_bray2' => ['type' => 'number', 'label' => 'P Bray-2 (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  44. 'p_morgan' => ['type' => 'number', 'label' => 'P Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  45. 'k_morgan' => ['type' => 'number', 'label' => 'K Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  46. 'ca_morgan' => ['type' => 'number', 'label' => 'Ca Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  47. 'mg_morgan' => ['type' => 'number', 'label' => 'Mg Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  48. 'na_morgan' => ['type' => 'number', 'label' => 'Na Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  49. 's_morgan' => ['type' => 'number', 'label' => 'S Morgan (mg/kg)', 'required' => false, 'step' => '0.1', 'min' => '0'],
  50. ],
  51. 'Micronutrients' => [
  52. 'b_cacl2' => ['type' => 'number', 'label' => 'B (CaCl₂) (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  53. 'mn_dtpa' => ['type' => 'number', 'label' => 'Mn (DTPA) (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  54. 'zn_dtpa' => ['type' => 'number', 'label' => 'Zn (DTPA) (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  55. 'fe_dtpa' => ['type' => 'number', 'label' => 'Fe (DTPA) (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  56. 'cu_dtpa' => ['type' => 'number', 'label' => 'Cu (DTPA) (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  57. 'al' => ['type' => 'number', 'label' => 'Al (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  58. 'se' => ['type' => 'number', 'label' => 'Se (mg/kg)', 'required' => false, 'step' => '0.01', 'min' => '0'],
  59. ],
  60. 'Base Saturation' => [
  61. 'tec' => ['type' => 'number', 'label' => 'TEC', 'required' => false, 'step' => '0.01'],
  62. 'cec' => ['type' => 'number', 'label' => 'CEC', 'required' => false, 'step' => '0.01'],
  63. 'ca_mehlick3' => ['type' => 'number', 'label' => 'Ca Mehlich-3', 'required' => false, 'step' => '0.01'],
  64. 'mg_mehlick3' => ['type' => 'number', 'label' => 'Mg Mehlich-3', 'required' => false, 'step' => '0.01'],
  65. 'k_mehlick3' => ['type' => 'number', 'label' => 'K Mehlich-3', 'required' => false, 'step' => '0.01'],
  66. 'na_mehlick3' => ['type' => 'number', 'label' => 'Na Mehlich-3', 'required' => false, 'step' => '0.01'],
  67. 'al_mehlick3' => ['type' => 'number', 'label' => 'Al Mehlich-3', 'required' => false, 'step' => '0.01'],
  68. ],
  69. ];
  70. ?>
  71. <?php foreach ($formSections as $sectionName => $fields): ?>
  72. <div class="card mb-3">
  73. <div class="card-header">
  74. <h5 class="mb-0"><?= htmlspecialchars($sectionName, ENT_QUOTES, 'UTF-8') ?></h5>
  75. </div>
  76. <div class="card-body">
  77. <div class="row">
  78. <?php foreach ($fields as $fieldName => $fieldConfig): ?>
  79. <div class="col-md-6">
  80. <label for="<?= htmlspecialchars($fieldName, ENT_QUOTES, 'UTF-8') ?>" class="form-label">
  81. <?= htmlspecialchars($fieldConfig['label'], ENT_QUOTES, 'UTF-8') ?>
  82. <?php if ($fieldConfig['required']): ?><span class="text-danger">*</span><?php endif; ?>
  83. </label>
  84. <?php if ($fieldConfig['type'] === 'select'): ?>
  85. <select class="form-control form-control-sm" id="<?= htmlspecialchars($fieldName, ENT_QUOTES, 'UTF-8') ?>"
  86. name="<?= htmlspecialchars($fieldName, ENT_QUOTES, 'UTF-8') ?>"
  87. <?= $fieldConfig['required'] ? 'required' : '' ?>>
  88. <option value="">Select...</option>
  89. <?php foreach ($fieldConfig['options'] as $option): ?>
  90. <option value="<?= htmlspecialchars($option, ENT_QUOTES, 'UTF-8') ?>">
  91. <?= htmlspecialchars($option, ENT_QUOTES, 'UTF-8') ?>
  92. </option>
  93. <?php endforeach; ?>
  94. </select>
  95. <?php else: ?>
  96. <input type="<?= htmlspecialchars($fieldConfig['type'], ENT_QUOTES, 'UTF-8') ?>"
  97. class="form-control form-control-sm"
  98. id="<?= htmlspecialchars($fieldName, ENT_QUOTES, 'UTF-8') ?>"
  99. name="<?= htmlspecialchars($fieldName, ENT_QUOTES, 'UTF-8') ?>"
  100. placeholder="<?= htmlspecialchars($fieldConfig['placeholder'] ?? '', ENT_QUOTES, 'UTF-8') ?>"
  101. <?= $fieldConfig['required'] ? 'required' : '' ?>
  102. <?php if (isset($fieldConfig['step'])): ?>step="<?= htmlspecialchars($fieldConfig['step'], ENT_QUOTES, 'UTF-8') ?>"<?php endif; ?>
  103. <?php if (isset($fieldConfig['min'])): ?>min="<?= htmlspecialchars($fieldConfig['min'], ENT_QUOTES, 'UTF-8') ?>"<?php endif; ?>
  104. <?php if (isset($fieldConfig['max'])): ?>max="<?= htmlspecialchars($fieldConfig['max'], ENT_QUOTES, 'UTF-8') ?>"<?php endif; ?>>
  105. <?php endif; ?>
  106. </div>
  107. <?php endforeach; ?>
  108. </div>
  109. </div>
  110. </div>
  111. <?php endforeach; ?>
  112. <!-- Hidden fields for form processing -->
  113. <input type="hidden" name="m_user" value="<?= htmlspecialchars($_SESSION['user_id'] ?? '1', ENT_QUOTES, 'UTF-8') ?>">