Yii2-Working with multiple check boxes in gridview

2020-03-31 04:27发布

问题:

I have a gridview in which there also a checkbox.

    <?= Html::a('Disconnect', ['dco'], ['class' => 'btn btn-success', 'id'=>'dco']) ?>
    <?= Html::a('Connect', ['rco'], ['class' => 'btn btn-info','id'=>'rco']) ?>

<?php Pjax::begin(); ?>
        <div class="pre-scrollable">
        <?= GridView::widget([
    'dataProvider' => $dataProvider,
    'filterModel' => $searchModel,
    'columns' => [


        ['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d) {
            return ['value' => $d['msn']];
        }],


        'customer_id',       
        'dept_name:ntext',
        'sub_div_name',
        'division_name',

        'allowed_units',
        'msn',

        'units_consumed',
        [
            'label' => 'Disconnected',
            'attribute' => 'disconnected',
            'format'=>'raw',
            'contentOptions' => ['style'=>'text-align:center'],
            'value' => function($model){
                return $model->disconnected == 1 ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger"></span>';
            },
            'filter' => Html::activeDropDownList($searchModel, 'disconnected', [''=>'All','1'=>'Yes','0'=>'No'], ['class' => 'form-control']),
        ],


        'active_energy_total_m',


        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>
        </div>

I am using ajax for sending checked data to the controller.

There is two buttons Disconnect and Connect. On the checkbox checked and after clicking any of the two buttons, the corresponding selected item will be connected or disconnected.

$DCOurl = Url::toRoute(['/hescolog/dco']);
$RCOurl = Url::toRoute(['/hescolog/rco']);
$(document).ready(function () {      
//DCO 
 $('#dco').on('click',function(e) {


       e.preventDefault();    
 var strValue = "";        
    $('input[name="selection[]"]:checked').each(function() {

    if(strValue!=="")
        {
        strValue = strValue + " , " + this.value;

        }
    else 
       strValue = this.value;     

});

   // alert(strValue);
$.ajax({
     url: '$DCOurl',
     type: 'POST',
     dataType: 'json',
     data: {data:strValue},         
     success: function(data) {
        alert(data);
     }
  });

 });

 $('#rco').on('click',function(e) {
e.preventDefault();    
 var strValue = "";        
    $('input[name="selection[]"]:checked').each(function() {

    if(strValue!=="")
        {
        strValue = strValue + " , " + this.value;

        }
    else 
       strValue = this.value;     

});
    // alert(strValue);
$.ajax({
     url: '$RCOurl',
     type: 'POST',
     dataType: 'json',
     data: {data:strValue},         
     success: function(data) {
        alert(data);
     }
  });
  });

  });

Controller

if(Yii::$app->request->isAjax && Yii::$app->request->post())
{
   $data = explode(',',$_POST['data']);
   foreach($data as $value)
   {
      //...... other code
   }
}

Now the problem I am facing is when I check all the checkboxes and click on any of the buttons, only the 1st checkbox checked an item is connect or disconnect.

Although while checking the controller `` I can see both the items against checkbox checked.

array(2) { [0]=> string(13) "002995000100 " [1]=> string(13) " 002992002018" }

Update 1

Against these two buttons, I have a SOAP service

 if(Yii::$app->request->isAjax && Yii::$app->request->isPost)
    {
        $data = explode(',',$_POST['data']);


        foreach($data as $value)
        {
            $ic++;
            $msn = $value;

            $xml_post_string = /** @lang text */
                '<soapenv:Envelope 
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
            xmlns:soap="http://soap.inf.hexing.cn">
            <soapenv:Header/>
            <soapenv:Body>
            <soap:doCommand>
            <!--Optional:-->
            <arg0><![CDATA[<?xml version="1.0" encoding="utf-8"?>
            <RequestMessage
            xmlns="http://iec.ch/TC57/2011/schema/message"
            xmlns:m="http://iec.ch/TC57/2011/EndDeviceControls#"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://iec.ch/TC57/2011/schema/message 
            Message.xsd">
            <Header>
            <Verb>create</Verb>
            <Noun>EndDeviceControls</Noun>
            <Revision>2.0</Revision>
            <Timestamp>2016-01-01T00:00:00+04:30</Timestamp>
            <Source>MDM</Source>
            <AsyncReplyFlag>true</AsyncReplyFlag>
      <ReplyAddress>http://ip:port/AmiWeb/services/Metering</ReplyAddress>
            <AckRequired>true</AckRequired>
            <User>
            <UserID>'.$userName.'</UserID>
            </User>
            <MessageID>83c643e6-85c5-43c0-9e0a-fa1deb469b72</MessageID>
            <CorrelationID>1001</CorrelationID>
            <Property>
            <Name>password</Name>
            <Value>'.$password.'</Value>
            </Property>
            <Property>
            <Name>timeout(m)</Name>
            <Value>30</Value>
            </Property>
            </Header>
            <Payload>
            <m:EndDeviceControls>
            <m:EndDeviceControl>
            <m:reason>Disconnect/Reconnect</m:reason>
            <m:EndDeviceControlType ref="3.0.211.23"/>
            <m:EndDevices>
            <m:mRID>'.$msn.'</m:mRID>
            <m:Names>
            <m:name>Disconnect</m:name>
            <m:NameType>
            <m:name>ControlType</m:name>
            </m:NameType>
            </m:Names>
            </m:EndDevices>
            </m:EndDeviceControl>
            </m:EndDeviceControls>
            </Payload>
            </RequestMessage>
            ]]></arg0>
            </soap:doCommand>
            </soapenv:Body>
            </soapenv:Envelope>';

            $headers = array(
                "Content-type: text/xml;charset=\"utf-8\"",
                "Accept: text/xml",
                "Cache-Control: no-cache",
                "Pragma: no-cache",
                "Content-length: ".strlen($xml_post_string),
            ); //SOAPAction: your op URL

            $url = $soapUrl;

            // PHP cURL  for https connection

            $ch = curl_init();
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            //curl_setopt($ch, CURLOPT_USERPWD, $soapUser.":".$soapPassword); // username and password - declared at the top of the doc
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
            curl_setopt($ch, CURLOPT_TIMEOUT, 10);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $xml_post_string); // the SOAP request
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

            // converting
            $response = curl_exec($ch);
            curl_close($ch);
            $domd=new DOMDocument();


            if(!$domd->loadXML($response)){
                throw new \RuntimeException("failed to parse XML!");
            }
            $inner_xml=$domd->getElementsByTagName("return")->item(0)->textContent;
            if(!($domd2=@DOMDocument::loadXML($inner_xml))){
                throw new \RuntimeException("failed to parse inner_xml!");
            }
            $AsyncReplyFlag=$domd2->getElementsByTagName("AsyncReplyFlag")->item(0)->textContent;


            if ($AsyncReplyFlag =='true')
            {
                $ds = 1;

                $disconnected_at = date('Y-m-d H:i:s');

                try {
                    Yii::$app->db->createCommand(/** @lang text */
                        "update 
                     `accurate_mam`.`daily_log` 
                     set
                     `disconnected` = '$ds',
                     `diconnected_at` = '$disconnected_at', 
                     `reconnected_at` = NULL
                      where `msn` = '$msn' ;

                       ")->execute(); //update master table

                    Yii::$app->db->createCommand(/** @lang text */
                        "update 
                    `accurate_mam`.`log_disconnected` 
                    set

                    `disconnected_at` = '$disconnected_at' 
                     where `msn` = '$msn'")->execute();// update log disconnected table
                } catch (Exception $e) {
                } // updating the master table
            }


        }

    }

I don't know what is the issue and why I am not able to process both the records.

Any help would be highly appreciated.

回答1:

Because you left a comment here, I used the beginForm method:

in View

<div class="pre-scrollable">
  <?php Pjax::begin() ?>
  <?=Html::beginForm(['test'],'post');?>

    <?= Html::submitButton('Disconnect', ['class' => 'btn btn-success', 'name'=>'dco', 'value'=>'dco', 'id'=>'dco','style'=>'margin:0 10px;']) ?>
    <?= Html::submitButton('Connect', ['class' => 'btn btn-primary', 'name'=>'rco', 'value'=>'rco','id'=>'rco']) ?>

    <?= GridView::widget([
      'dataProvider' => $dataProvider,
      'filterModel' => $searchModel,
    'columns' => [

        ['class' => 'yii\grid\CheckboxColumn', 'checkboxOptions' => function($d) {
            return ['value' => $d['msn']];
        }],

        'customer_id',       
        'dept_name:ntext',
        'sub_div_name',
        'division_name',

        'allowed_units',
        'msn',

        'units_consumed',
        [
            'label' => 'Disconnected',
            'attribute' => 'disconnected',
            'format'=>'raw',
            'contentOptions' => ['style'=>'text-align:center'],
            'value' => function($model){
                return $model->disconnected == 1 ? '<span class="glyphicon glyphicon-ok text-success"></span>' : '<span class="glyphicon glyphicon-remove text-danger"></span>';
            },
            'filter' => Html::activeDropDownList($searchModel, 'disconnected', [''=>'All','1'=>'Yes','0'=>'No'], ['class' => 'form-control']),
        ],

        'active_energy_total_m',

        ['class' => 'yii\grid\ActionColumn'],
    ],
]); ?>

  <?= Html::endForm();?> 
  <?php Pjax::end() ?>
</div>

in controllers

public function actionTest()
{
    $searchModel  = \Yii::createObject(\app\models\TestSearch::className());
    $dataProvider = $searchModel->search(Yii::$app->request->queryParams);

  if ( Yii::$app->request->post() ) {

      $arr_select=(array)Yii::$app->request->post('selection');  //An array of selected items (checkbox)
      $dco=Yii::$app->request->post('dco');  // submitButton Disconnect
      $rco=Yii::$app->request->post('rco');  // submitButton Connect

      if ($dco === 'dco') {
           //code for Disconnect here ($query)
           // example:  $modelTest::updateAll(['disconnected' => 1], ['msn' => $arr_select]);
      } elseif ($rco == 'rco') {
           //code for Connect here ($query)
      }

    }

    return $this->render('test', [
        'dataProvider' => $dataProvider,
        'searchModel'  => $searchModel,
    ]);
}

You can optimize your code in the controller.
Of course, I think if you use the following method, it is better (a button and ...).
You can easily decide on the controller.

<?= Html::dropDownList('action','',[ 'Connect' =>'Connect','Disconnect' =>'Disconnect'],['prompt' => 'Please select','class'=> 'field-black input-sm']) ?>
<?= Html::submitButton('Apply', ['class' => 'btn btn-success','style'=>'margin:0 10px;']) ?>

You can place the above code instead of the two submitButton. Then decide on the controller according to the dropDownList value. Like below:
also add:, 'data-pjax'=>''

$_action=Yii::$app->request->post('action'); // dropDown
$arr_select=(array)Yii::$app->request->post('selection'); //selected items