The form is working fine. All the selects and other form elements are works fine when I submit. The only problem is the community_id which is dependent on the district. Its always given The input was not found in the haystack
. In the browser console the form sends the community_id but I don't why I keep getting the haystack problem:
district_id: 9c72f59e-f733-11ef-89e9-00155d016f00
community_id: 4acc72cb-fc61-11ef-8c90-00155d016f00
Form:
Elements
// Add district selection
$this->add([
'name' => 'district_id',
'type' => Element\Select::class,
'options' => [
'label' => 'District',
'empty_option' => 'Select District',
'value_options' => $this->getDistrictOptions(),
'label_attributes' => [
'class' => 'required-field'
],
],
'attributes' => [
'id' => 'district_id',
'class' => 'form-control form-select',
'required' => true,
'data-dependent-url' => '/community/list'
],
]);
// Add community selection
$this->add([
'name' => 'community_id',
'type' => Element\Select::class,
'options' => [
'label' => 'Community',
'empty_option' => 'Select Community',
'value_options' => $this->getCommunityOptions(),
'label_attributes' => [
'class' => 'required-field'
],
],
'attributes' => [
'id' => 'community_id',
'class' => 'form-control form-select',
'required' => true,
'disabled' => true,
'data-dependent' => 'district_id',
'value' => ''
],
]);
*Inputfilters*
'district_id' => [
'required' => true,
'filters' => [
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => 'NotEmpty',
'options' => [
'messages' => [
'isEmpty' => 'Please select a district'
],
],
],
[
'name' => 'Callback',
'options' => [
'callback' => [$this, 'validateDistrict'],
'messages' => [
'callbackValue' => 'Invalid district selected'
],
],
],
],
],
'community_id' => [
'required' => true,
'filters' => [
['name' => 'StringTrim'],
],
'validators' => [
[
'name' => 'NotEmpty',
'options' => [
'messages' => [
'isEmpty' => 'Please select a community or choose Other and specify a new community name'
],
],
],
[
'name' => 'Callback',
'options' => [
'callback' => [$this, 'validateCommunity'],
'messages' => [
'callbackValue' => 'Please select a valid community from the list or choose Other and specify a new community name'
],
],
],
],
],
*Validators*
public function validateDistrict($value)
{
$district = $this->entityManager->getRepository(\Grm\Entity\District::class)
->find($value);
return $district !== null;
}
public function validateCommunity($value)
{
// Log the submitted value
error_log("Submitted community_id: " . $value);
// Get the district ID
$districtId = $this->get('district_id')->getValue();
error_log("Selected district_id: " . $districtId);
if (empty($districtId)) {
error_log("District ID is empty.");
return false;
}
// Handle 'other' option
if ($value === 'other') {
$otherCommunity = $this->get('other_community')->getValue();
if (empty($otherCommunity)) {
error_log("Other community name is empty.");
return false;
}
return true;
}
// For numeric IDs, verify the community exists in the selected district
if (is_numeric($value)) {
try {
$community = $this->entityManager->getRepository(\Grm\Entity\Community::class)
->findOneBy([
'id' => $value,
'district' => $districtId
]);
if ($community === null) {
error_log("Community not found in the selected district.");
} else {
error_log("Community found: " . $community->getName());
}
return $community !== null;
} catch (\Exception $e) {
error_log("Error validating community: " . $e->getMessage());
return false;
}
}
error_log("Invalid community_id value: " . $value);
return false;
}
Index.phtml:
<!-- District and Community -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="flex items-center space-x-2">
<?= $this->formLabel($form->get('district_id')) ?>
<div class="flex-1">
<?= $this->formElement($form->get('district_id')) ?>
<?= $this->formElementErrors($form->get('district_id')) ?>
</div>
</div>
<div class="flex items-center space-x-2">
<?= $this->formLabel($form->get('community_id')) ?>
<div class="flex-1">
<?= $this->formElement($form->get('community_id')) ?>
<?= $this->formElementErrors($form->get('community_id')) ?>
</div>
</div>
</div>
*Scripts*
`// Handle dependent dropdowns and form fields
$(document).ready(function() {
// District -> Community dependency
$('#district_id').change(function() {
const districtId = $(this).val();
const communitySelect = $('#community_id');
const otherCommunityContainer = $('.other-community-container');
const otherCommunityField = $('#other_community');
// Reset and hide other community field
otherCommunityContainer.addClass('hidden');
otherCommunityField.val('').prop('required', false);
if (districtId) {
// Show loading indicator
communitySelect.prop('disabled', true).empty()
.append('<option value="">Select Community</option>');
$.ajax({
url: '/community/list/' + districtId,
method: 'GET',
dataType: 'json',
success: function(response) {
communitySelect.empty();
// Add empty option
communitySelect.append('<option value="">Select Community</option>');
if (response && response.length > 0) {
response.forEach(function(community) {
communitySelect.append(
$('<option></option>')
.val(community.id)
.text(community.name)
);
});
}
// Add "Other" option
communitySelect.append('<option value="other">Other (Specify)</option>');
communitySelect.prop('disabled', false);
},
error: function() {
communitySelect.empty()
.append('<option value="">Error loading communities</option>')
.append('<option value="other">Other (Specify)</option>')
.prop('disabled', false);
}
});
} else {
communitySelect.empty()
.append('<option value="">Select Community</option>')
.append('<option value="other">Other (Specify)</option>')
.prop('disabled', true);
// Reset other community field
otherCommunityContainer.addClass('hidden');
otherCommunityField.val('').prop('required', false);
}
});
// Handle Other Community selection
$('#community_id').on('change', function() {
const selectedValue = $(this).val();
const otherCommunityContainer = $('.other-community-container');
const otherCommunityField = $('#other_community');
if (selectedValue === 'other') {
otherCommunityContainer.removeClass('hidden');
otherCommunityField.prop('required', true).val('');
} else {
otherCommunityContainer.addClass('hidden');
otherCommunityField.prop('required', false).val('');
}
});
});`