I'm struggling with coding an ajax refresh of options in a select list based on what's already selected in the previous field.
Scenario is I get a list of positions and each position one or many nominations for that position. So I display the position name and then a list of each nomination name which has a selection listbox "1st preference", "2nd preference", etc and the preferences are dictated by the number of nominations for that position.
So when someone selects for example "3rd preference" for the first nomination, I want to remove that "3rd preference" option from the select box of the next nomination's listbox. Any clues and guidance on this much appreciated. The following code is what I'm using in the tmpl/default.php.
<form id="form-voter"
action="<?php echo Route::_('index.php?option=com_mycomponent&task=voterform.save'); ?>"
method="post" class="form-validate form-horizontal" enctype="multipart/form-data">
<?php echo $nominations->form->renderFieldset('sysinfo'); ?>
<?php echo $nominations->form->renderField('user_id'); ?>
<?php echo $nominations->form->renderField('cat_id'); ?>
<?php echo LayoutHelper::render('default_proxy', array('data' => $nominations), dirname(__FILE__)); ?>
<?php /* ------------ Cycle through the positions records and show the nomination ------ */ ?>
<?php /* the nominations are in an array of position arrays and then each position array is */ ?>
<?php /* an array of nominations objects. so Key is the posID */ ?>
<?php foreach ($nominations->nominations AS $posID => $nomins) : $NomCntr = 0; ?>
<?php if (is_array($nomins) && !empty($nomins)) : ?>
<div class="control-group">
<div class="control-label">
<label id="jform_nom_ids_lbl" for="jform_nom_ids_<?php echo $posID; ?>">
<?php echo $nomins[0]->position_id_name; ?>
</label>
</div>
<div class="controls extrawide">
<?php $qtyNoms = \count($nomins); ?>
<?php foreach ($nomins AS $nom) : $NomCntr++; ?>
<?php if ($NomCntr == 1) : ?>
<?php echo '<p> <p /><p>'.Text::sprintf('COM_MYCOMPONENT_MULTIPLE_POSITIONS_PREF', $nom->pos_qty).'<p />'; ?>
<?php endif; ?>
<?php echo $selectList = MyajaxHelper::displayPrefVoteOptions($nom, $qtyNoms, $posID); ?>
<?php endforeach; ?>
</div>
</div>
<?php endif; ?>
<?php endforeach; ?>
<div class="control-group">
<div class="controls">
<?php if ($nominations->canSave): ?>
<button type="submit" class="validate btn btn-primary">
<?php echo Text::_('JSUBMIT'); ?>
</button>
<?php endif; ?>
<a class="btn btn-secondary"
href="<?php echo Route::_('index.php?option=com_mycomponent&task=voterform.cancel'); ?>"
title="<?php echo Text::_('JCANCEL'); ?>">
<?php echo Text::_('JCANCEL'); ?>
</a>
</div>
</div>
<input type="hidden" name="option" value="com_mycomponent"/>
<input type="hidden" name="task" value="voterform.save"/>
<?php echo HTMLHelper::_('form.token'); ?>
EDITED: since reviewing the original code I've updated the above and with a hope I may get an ajax answer, I've moved the selection list to a helper called MyajaxHelper and the code is:
/**
* Create a selection list for preferential voting
* @param object $nom nomination object
* @param integer $qtyNoms number of nominations for this position
* @param integer $posID id reference of the position
* @return selection list box
*/
public static function displayPrefVoteOptions($nom, $qtyNoms, $posID)
{
// Load admin language file
$lang = Factory::getApplication()->getLanguage();
$lang->load('com_mycomponent', JPATH_ADMINISTRATOR);
// setup array of the votes per option
$nomVotes = \range(1,$qtyNoms,1);
\arsort($nomVotes);
$i=1;
$selectList = '<div class="selectlist">';
$selectList .= '<label id="jform_nom_ids_lbl" for="jform_nom_ids_'.$posID.'" class="selectlist">';
$selectList .= '<div style="width:230px;float:left;">'.$nom->nomination_name.'</div>';
$selectList .= '<div style="with:100px;float:right;">';
$selectList .= '<select id="jform_nom_ids_'.$posID.'" name="jform[nom_ids][nom_id_'.$posID.'_'.$nom->id.']">';
foreach ($nomVotes as $vote) {
$nf = new \NumberFormatter('en_GB', \NumberFormatter::ORDINAL);
$sel = $nf->format($i);
if ($i == 1) {
$selectList .= '<option value="0" >'.Text::_('MYCOMPONENT_NO_VOTE').'</option>';
}
$selectList .= '<option value="'.$vote.'" >'.Text::sprintf('COM_MYCOMPONENT_PREF_SELECTION', $sel).'</option>';
}
$selectList .= '</select></div></label></div>';
return $selectList;
}
posID
infor
orid
attributes outside of the loop is okay, but inside of the loop looks like trouble because you will be producing invalid HTML via duplicatedid
values. That must change. I see where$NomCntr
is incremented, but not where it is firat declared. I generally do not support building form field keys via concatenation of incremented values. Might you change:jform[nom_ids][nom_id_<?php echo $posID.'_'.$NomCntr; ?>]
tojform[nom_ids][<?php echo $posID; ?>][]
? Thatfalse;"
after your option value looks like a typo.range()
is1
so that 3rd argument can be safely omitted. Since there are no answers, it is safe to remove the initial coding attempt if you wish (to reduce the question size). Why do youarsort()
if you don't use the preserved keys? Maybe you wantforeach (range($qtyNoms, 1) as $vote) {
. Why use$i
? Can you not simply unconditionally concatenate that option after the loop?