О скока сразу мнений. Вот только я с аяксом ни разу даже не сталкивался.
Модуль выводит список записей, для каждой записи кнопка вызова формы и передача форме параметров из записи. Форма post, в форме action="index.php" (модуль предполагается на главной), и поля
      <input type="hidden" name="option" value="com_mfo" />
      <input type="hidden" name="task" value="smail.work" />
т.е., если я понял правильно, будет стандартным механизмом вызван контроллер smail компонента com_mfo.
Т.к. модель smail не возвращает данные, а просто отсылает почтовое сообщение с данными из формы в модуле, может, вообще обойтись без модели и все сделать в контроллере? Как правильно? AJAX - это хорошо, но но пока слабо без конкретного примера.
Возможно, можно вообще обойтись без компонента и все обрабатывать в модуле, но я не знаю, как в модуле отловить сабмит формы и вызвать функцию в хелпере.
[spoiler title=Плагин]
<?php defined('_JEXEC') or die;
require_once __DIR__ . '/helper.php';
$moduleclass_sfx = htmlspecialchars($params->get('moduleclass_sfx'));
$items = ModMfoCreditOffersHelper::getItems((bool)JFactory::getUser()->guest);
require JModuleHelper::getLayoutPath('mod_mfo_creditoffers', $params->get('layout', 'default'));
require_once JPATH_SITE.'/components/com_content/helpers/route.php';
JModelLegacy::addIncludePath(JPATH_SITE.'/components/com_content/models', 'ContentModel');
[/spoiler]
[spoiler title=Хелпер модуля]
<?php defined('_JEXEC') or die;
require_once JPATH_SITE.'/components/com_content/helpers/route.php';
class ModMfoCreditOffersHelper
{
  public static function getItems($is_guest)
  {
    $status = (bool)$is_guest ? '3' : '2';
    $db = JFactory::getDbo();
    $query = $db->getQuery(true);
    $query->select('id, offername, status, sm_from, sm_to, prc_from, prc_to, term_from, term_to')
          ->from('#__mfo_credit_offers')
          ->where('status != '.$status);
    try
    {
      $items = $db->setQuery($query)->loadObjectList('id');
      $query = $db->getQuery(true)->select('co_id, `condition`')->from('#__mfo_credit_offers_conditions');
      $conditions = $db->setQuery($query)->loadObjectList();
      foreach ($conditions as $condition) {
        if (isset($items[$condition->co_id])) 
          $items[$condition->co_id]->conditions[] = $condition;
      }
      return $items;
    }
    catch (RuntimeException $e)
    {
      $this->setError($e->getMessage());
      return false;
    }
  }
}
[/spoiler]
[spoiler title=Вьюха модуля]
<?php defined('_JEXEC') or die;
if (!empty($items) && count($items)) {
  JHtml::_('jquery.framework');
  $document = JFactory::getDocument();
  $document->addStyleSheet('/media/com_mfo/css/jquery-ui.min.css');
  $document->addStyleSheet('/media/mod_mfo_co/css/mod_mfo_co.css');
  
  $document->addScript('/media/com_mfo/js/jquery-ui.min.js');
  $document->addScript('/media/mod_mfo_co/js/jquery.maskedinput.js');
  $document->addScript('/media/mod_mfo_co/js/accounting.min.js');
  $document->addScript('/media/mod_mfo_co/js/mod_mfo_co.js');
  $params = JComponentHelper::getParams('com_mfo');
  $dcs = $params->get('mfo_decimal_separator', '.');
  $ths = $params->get('mfo_thousands_separator', ' ');
  if ($ths == '=') $ths = '';
  $document->addScriptDeclaration('var dcs = "'.$dcs.'";');
  $document->addScriptDeclaration('var ths = "'.$ths.'";');
  echo '<div class="mfo-co">';
  foreach ($items as $i => $item) {
    $id = $item->id;
    echo '<div class="mfo-co-item">';
    if (isset($item->conditions) && count($item->conditions)) $list = $item->conditions;
    echo '<h4>'.$item->offername.'</h4>';
    if (isset($list) && count($list)) {
      echo '<div class="conditions">';
      $list_cnt = count($list);
      $list_ii = 1;
      foreach ($list as $listitem) {
        if ($list_ii == $list_cnt)
          {echo $listitem->condition;} else
          {echo $listitem->condition.'<br />';}
        $list_ii++;
      }
      echo '</div>';
    }
    echo '<div>'.JText::sprintf('MOD_MFO_CO_SM', number_format($item->sm_from,0,$dcs,$ths), number_format($item->sm_to,0,$dcs,$ths)).'</div>';
    echo '<div>'.JText::sprintf('MOD_MFO_CO_PRC', number_format($item->prc_from,1,$dcs,$ths), number_format($item->prc_to,1,$dcs,$ths)).'</div>';
    echo '<div>'.JText::sprintf('MOD_MFO_CO_TERM', number_format($item->term_from,0), number_format($item->term_to,0)).'</div>';
    echo '<input type="hidden" name="smf'.$id.'" value="'.(int)$item->sm_from.'">';
    echo '<input type="hidden" name="smf'.$id.'" value="'.(int)$item->sm_from.'">';
    echo '<input type="hidden" name="smt'.$id.'" value="'.(int)$item->sm_to.'">';
    echo '<input type="hidden" name="prct'.$id.'" value="'.(int)$item->prc_to.'">';
    echo '<input type="hidden" name="termf'.$id.'" value="'.(int)$item->term_from.'">';
    echo '<input type="hidden" name="termt'.$id.'" value="'.(int)$item->term_to.'">';
    echo '<div><a class="btn btn-primary" href="javascript:ShowForm('.$id.')">'.JText::_('MOD_MFO_CO_DEMAND').'</a></div>';
    echo '</div>';
  }
  echo '</div>';
  
}?>
<form action="<?php echo JRoute::_('index.php'); ?>" method="post" id="co-form" class="form-inline">
  <a href="javascript:HideForm(false)" class="overlay" id="co_form"></a>
  <div class="popup">
    <a class="close" href="javascript:HideForm(false)"></a>
    <div class="mfo_co_controls">
      <div class="pretext">
        <h2><?php echo JText::_('MOD_MFO_CO_FORM_CAPTION'); ?></h2>
        <label><?php echo JText::sprintf('MOD_MFO_CO_FORM_PRETEXT', $item->offername); ?></label>
      </div>
      <div class="controls">
        <?php if ((int)$item->sm_from == (int)$item->sm_to) {?>
          <label for="amount-sm"><span><?php echo JText::_('MOD_MFO_CO_FORM_SM'); ?></span></label>
          <input class="no-brd" type="text" id="amount-sm" readonly disabled="true" value="<?php echo (int)$item->sm_to; ?>">
        <?php } else { ?>
          <label for="amount-sm"><span><?php echo JText::_('MOD_MFO_CO_FORM_SM'); ?></span></label>
          <input class="no-brd" type="text" id="amount-sm" readonly disabled="true">
          <div id="slider-sm"></div>
        <? } ?>
      </div>
      <div class="controls">
        <?php if ((int)$item->term_from == (int)$item->term_to) {?>
          <label for="amount-term"><span><?php echo JText::_('MOD_MFO_CO_FORM_TERM'); ?></span></label>
          <input class="no-brd" type="text" id="amount-term" readonly disabled="true" value="<?php echo (int)$item->term_to; ?>">
        <?php } else { ?>
          <label for="amount-term"><span><?php echo JText::_('MOD_MFO_CO_FORM_TERM'); ?></span></label>
          <input class="no-brd" type="text" id="amount-term" readonly disabled="true">
          <div id="slider-term"></div>
        <? } ?>
      </div>
      <div class="controls">
        <label for="amount-mpay"><span><?php echo JText::_('MOD_MFO_CO_FORM_MPAY'); ?></span><span class="star"> *</span></label>
        <input class="no-brd" type="text" id="amount-mpay" readonly disabled="true">
      </div>
      <div class="controls">
        <p><span class="star">* </span><?php echo JText::_('MOD_MFO_CO_FORM_PS'); ?></p>
      </div>
    </div>
    <div class="mfo_co_controls">
      <?php if ((bool)JFactory::getUser()->guest) { ?>
        <div class="controls"> 
          <hr />
          <label for="mod_mfo_co_name"><span><?php echo JText::_('MOD_MFO_CO_FORM_NAME'); ?></span><?php echo JText::_('MOD_MFO_CO_FORM_NAME_PH'); ?></label>
          <input id="mod_mfo_co_name" type="text" class="inputbox"/>
        </div>
        <div class="controls"> 
          <label for="mod_mfo_co_phone"><span><?php echo JText::_('MOD_MFO_CO_FORM_PHONE'); ?></span><?php echo JText::_('MOD_MFO_CO_FORM_PHONE_PH'); ?></label>
          <input id="mod_mfo_co_phone" type="text" class="inputbox" placeholder="+7(___)___-__-__"/>
        </div>
      <?php } else { ?>
        <div class="controls">
          <hr />
          <label><span><?php echo JText::_('MOD_MFO_CO_FORM_POSPTEXT'); ?></span></label>
        </div>
      <?php } ?>
    </div>
    <div class="mfo_co_controls">
      <div class="controls">
        <hr />
        <a class="btn btn-primary" href="javascript:HideForm(true)"><?php echo JText::_('MOD_MFO_CO_DEMAND')?></a>
      </div>
      <input type="hidden" name="option" value="com_mfo" />
      <input type="hidden" name="task" value="smail.work" />
      <input type="hidden" name="return" value="<?php echo $return; ?>" />
    </div>
  </div>
</form>
[/spoiler]