1

我正在Yii 框架中做一个小应用程序,因为我的数据库是这样的

 === Invoices ===
  id (PK)
  customer_id
  invoice_title
  order_no
  invoice_issue_date
  due_date
  description

  === Customers ===
  id (PK)
  email_address
  customer_name
  address
  city
  state
  postal_code
  description

我已经渲染了Customer modelinInvoice model以便我可以在一个中输入两个模型的所有值single Invoice form。但是有一个问题,让我们假设我有一个客户名称xyzsaved before现在当我要去的时候again fill the Customer name with xyz,它应该显示all the fields of both models like invoice_title,order_no,invoice_issue_date,due_date,description,email_address,customer_name,address etc. in that input fields of the form出来我不必re-enter all the fields again。所以如何在 Yii 框架中实现这一点。任何帮助和建议都将是非常可观的。如果需要,可以分享我所做的代码的更多说明。请帮帮我。我完全被困在这里。

4

3 回答 3

1

正如大家已经提到的那样,要做到这一点,您需要 ajax 和一些 javascript。逻辑是这样的:

  1. 在客户名称的下拉列表中选择一个值时,触发 ajax 调用以检索有关该用户的信息。这可以通过 ajax 选项轻松完成,该选项可用作 CHtml 中某些 html 元素助手的附加 htmlOption,作为clientChange的一部分。

    echo $form->dropDownList($model,'customer_name',CHtml::listData(Customers::model()->findAll(),'id','customer_name'),
       array(// htmlOptions
         'ajax'=>array(// special htmlOption through clientChange, for ajax
               'type'=>'GET', 
               'url'=>$this->createUrl('controllername/customerdetails'),// action that will generate the data
               'data'=>'js:"id="+$(this).val()',// this is the data that we are sending to the action in the controller
               'dataType'=>'json',// type of data we expect back from the server
               'success'=>'js:updateFields'// a javascript function that will execute when the request completes successfully
         )
       )
     );
    

    上述 ajax 选项的文档可以在jquery 的 ajax 文档中看到。

  2. 然后在服务器端找到特定的客户,并向浏览器发送响应。例子:

    // in the controllername code an action that will return the values as json
    public function actionCustomerdetails($id){
        $var=Customers::model()->findByPk($id);
        echo CJSON::encode($var);
    }
    
  3. 当您收到服务器响应时,填充相应的字段。这可以在 ajax 的成功函数回调中完成,在上面的代码中是 updateFields:

    Yii::app()->clientScript->registerScript('update','
        function updateFields(data, textStatus, jqXHR){
            // select each input field by id, and update its value
            $("#Customers_postal_code").val(data.postal_code);
            $("#Customers_city").val(data.city);
            $("#Customers_address").val(data.address);
            // similarly update the fields for the other inputs
        }
    ');
    

注意:您的客户可以有许多发票,因此问题将是在给定客户名称的情况下选择哪张发票。这是你必须处理的事情,我认为我的答案有足够的代码让你继续前进。

要知道输入字段 id,您可以简单地检查生成的 html。

于 2012-07-06T16:35:30.827 回答
0

您可以分两个阶段执行此操作,以便:

  1. 最初显示视图时,会要求客户提供他们的email addresscustomer_name

  2. 表单提交到的控制器操作然后从客户模型中检索提交的数据email addresscustomer_name(我将email_address在下面的示例中使用)。检索后,您可以显示您的单一发票表单视图,其中包含为客户预先填充的数据(如果有)。

然后可以按如下方式实现此概念:

<?php
// file: controllers/InvoiceController.php
class InvoiceController extends CController
{
  // ... other controller functions

  public function actionCreate($step = null)
  {
    $invoice  = new Invoice;
    $customer = new Customer;

    # Form has been submitted:
    if ( isset($_POST['Customer']) )
    {
      # The submitted form was Step 1:
      if ( $step == 1 )
      {
        # make sure the submitted email address is valid
        $customer->setAttributes($_POST['Customer']);
        if ( $customer->validate(array('email_address')) )
        {
          # retrieve the customer by email_address
          $customer = Customer::model()->findByAttributes(array('email_address' => $_POST['Customer']['email_address']));
        }

        $this->render('createstep2', array('invoice' => $invoice, 'customer' => $customer));
      }

      # The submitted form was Step 2:
      elseif ( $step == 2 )
      {
        $income->setAttributes($_POST['Invoice']);
        $customer->setAttributes($_POST['Customer']);

        # save the data
        if ( $customer->save() )
        {
          $invoice->customer_id = $customer->id;
          if ( $invoice->save() )
          {
            $this->redirect(array('view', 'id' => $invoice->id));
          }
        }

        # display any errors
        $this->render('createstep2', array('invoice' => $invoice, 'customer' => $customer));
      }
    } 

    $this->render('createstep1', array('invoice' => $invoice, 'customer' => $customer));
  }

  // ... other controller functions
}
?>

如果您愿意,可以将其拆分为两个单独的控制器操作。

对于第 1 步视图,您可以拥有以下内容:

<!-- file: views/invoice/createstep1.php -->
<h1>Create Invoice: Step 1</h1>

<div class="form">

<?php
$form = $this->beginWidget('CActiveForm', array(
  'id'=>'invoice-form',
  'enableAjaxValidation'=>false,
  'action'=>array('invoice/create','step' => 1)
)); 
?>

  <?php echo $form->errorSummary($customer); ?>

  <div class="row">
    <?php echo $form->labelEx($customer,'email_address'); ?>
    <?php echo $form->textField($customer,'email_address', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'email_address'); ?>
  </div>

  <div class="row buttons">
    <?php echo CHtml::submitButton('Next'); ?>
  </div>

<?php $this->endWidget(); ?>

</div><!-- form -->

第 2 步查看,然后您可能看起来就像您已经拥有的一样。也许是这样的:

<!-- file: views/invoice/createstep2.php -->
<h1>Create Invoice: Step 2</h1>

<div class="form">

<?php
$form = $this->beginWidget('CActiveForm', array(
  'id'=>'invoice-form',
  'enableAjaxValidation'=>false,
  'action'=>array('invoice/create','step' => 2)
)); 
?>

  <?php echo $form->errorSummary($invoce); ?>
  <?php echo $form->errorSummary($customer); ?>

  <h2>Customer Details</h2>
  <div class="row">
    <?php echo $form->labelEx($customer,'email_address'); ?>
    <?php echo $form->textField($customer,'email_address', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'email_address'); ?>
  </div>

  <!-- If the customer already exists, these field should be pre-populated: -->

  <div class="row">
    <?php echo $form->labelEx($customer,'customer_name'); ?>
    <?php echo $form->textField($customer,'customer_name', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'customer_name'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($customer,'address'); ?>
    <?php echo $form->textField($customer,'address', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'address'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($customer,'city'); ?>
    <?php echo $form->textField($customer,'city', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'city'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($customer,'state'); ?>
    <?php echo $form->textField($customer,'state', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'state'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($customer,'postal_code'); ?>
    <?php echo $form->textField($customer,'postal_code', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'postal_code'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($customer,'description'); ?>
    <?php echo $form->textField($customer,'description', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($customer,'description'); ?>
  </div>


  <h2>Order Details</h2>

  <div class="row">
    <?php echo $form->labelEx($invoice,'invoice_title'); ?>
    <?php echo $form->textField($invoice,'invoice_title', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($invoice,'invoice_title'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($invoice,'order_no'); ?>
    <?php echo $form->textField($invoice,'order_no', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($invoice,'order_no'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($invoice,'invoice_issue_date'); ?>
    <?php $form->widget('zii.widgets.jui.CJuiDatePicker', array(
        'model'     => $invoice,
        'attribute' => 'invoice_issue_date',
        'value'     => $invoice->invoice_issue_date,
        'options'   => array(
          'showButtonPanel' => false,
          'changeYear'      => true,
          'dateFormat'      => 'yy-mm-dd',
        ),
      )); ?>
    <?php echo $form->error($invoice,'invoice_issue_date'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($invoice,'due_date'); ?>
    <?php $form->widget('zii.widgets.jui.CJuiDatePicker', array(
        'model'     => $invoice,
        'attribute' => 'due_date',
        'value'     => $invoice->due_date,
        'options'   => array(
          'showButtonPanel' => false,
          'changeYear'      => true,
          'dateFormat'      => 'yy-mm-dd',
        ),
      )); ?>
    <?php echo $form->error($invoice,'due_date'); ?>
  </div>

  <div class="row">
    <?php echo $form->labelEx($invoice,'description'); ?>
    <?php echo $form->textField($invoice,'description', array('size'=>60,'maxlength'=>255)); ?>
    <?php echo $form->error($invoice,'description'); ?>
  </div>


  <div class="row buttons">
    <?php echo CHtml::submitButton('Create'); ?>
  </div>

<?php $this->endWidget(); ?>

</div><!-- form -->
于 2012-07-01T07:18:12.853 回答
0

你检查过 Yii 自动完成小部件吗?而且您不必担心 AJAX 的实现。它为你做。

Yii 框架:CJui 自动完成

此链接中更定制的自动完成解决方案。

Yii 框架:自定义自动完成显示和值提交

于 2012-06-30T12:39:49.067 回答