自动完成先前值的字段

时间:2012-06-28 11:30:17

标签: php mysql yii yii-events

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

 === 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 model中渲染了Invoice model,以便我可以在single Invoice form中输入两个模型的所有值。但是有一个问题,让我们假设我有一个我有xyz的客户名称saved 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框架中实现这一点。任何帮助和建议都将非常值得关注。如果需要,可以分享我所做的代码的更多说明。 请帮帮我。我完全被困在这里。

3 个答案:

答案 0 :(得分:1)

要做到这一点,因为每个人都已经提到过你需要ajax和一些javascript。逻辑是这样的:

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

    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's ajax documentation中看到。

  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的success函数回调中完成,在上面的代码中是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
        }
    ');
    
  4. 注意: 您的客户可以有很多发票,因此问题将是根据客户名称选择哪个发票。这是你必须要处理的事情,我认为我的答案有足够的代码可以帮助你。

    要知道输入字段ID,您只需检查生成的html。

答案 1 :(得分:0)

您检查过Yii Autocomplete小部件吗?而且你不必担心AJAX的实现。它适合你。

Yii Framework: CJui AutoComplete

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

Yii Framework: custom-autocomplete-display-and-value-submission

答案 2 :(得分:0)

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

  1. 最初显示视图时,系统会要求客户提供email addresscustomer_name

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

  3. 这个概念可以按如下方式实施:

    <?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 -->