-->

How to add spinner/loader in yii2 php

2020-07-27 03:48发布

问题:

I want to add a spinner/loader in one of my forms. The scenario is simple: When I hit the create button then it will show a spinner/loader. On hitting the create button a call to a web-service is made so the spinner/loader will show from call start to call end.

Below is my controller:

$m = MetersInventoryStore::findOne($_REQUEST['selected_meters']);
$msn = $m->meter_serial; // current selected meter serial number is saved

$date_time = str_replace(' ', 'T', date('Y-m-d H:i:s')); // current date time

$api_url = 'http://xx.xxx.xxx.xxx:7000/api/meters/GetByMsn/' . $msn . '/' .$date_time; // my base URL

$curl = curl_init($api_url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_TIMEOUT, 1000);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization:key'));

$curl_response = curl_exec($curl);
$json = json_decode($curl_response);
$meter_alive = $json->data->Response;
.
.
.
.
// my other code that is saving data
.
.
.
.
return $this->render('create', ['model' => $model,]);

The submit button is below:

<div class="form-group">
   <?= Html::submitButton($model->isNewRecord ? 'Verify Communication' : 'Update', ['id'=> 'spin','name'=>'create','class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-success']) ?>

</div>

As told above when I press the Verify Communication button a call is made to the web-service and during this time I want to show a spinner/loader.

For creating/showing a spinner/loader I have searched many articles.

  1. Show Loading
  2. Kartik Spinner
  3. Submit Spinner
  4. Yii2 Model Loader
  5. Yii2 Jquery Loading

But none of the above articles have mentioned the full implementation details. Although I have tried each and every step mentioned in the articles.

Any help would be highly appreciated.

回答1:

Instead of on the submit button why not put the loader on each page load. This can be done by making changes in main layout.

<style>
        /*loader css*/

#loader {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 1;
  width: 150px;
  height: 150px;
  margin: -75px 0 0 -75px;
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  width: 120px;
  height: 120px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* Add animation to "page content" */
.animate-bottom {
  position: relative;
  -webkit-animation-name: animatebottom;
  -webkit-animation-duration: 1s;
  animation-name: animatebottom;
  animation-duration: 1s
}

@-webkit-keyframes animatebottom {
  from { bottom:-100px; opacity:0 } 
  to { bottom:0px; opacity:1 }
}

@keyframes animatebottom { 
  from{ bottom:-100px; opacity:0 } 
  to{ bottom:0; opacity:1 }
}



</style>

Add script for function.

<script>
var myVar;

function myFunction() {
  myVar = setTimeout(showPage, 0000);
}

function showPage() {
  document.getElementById("loader").style.display = "none";
  document.getElementById("container").style.display = "block";
}
</script>

Finally, call the function by binding onload function with body.

    <body onload="myFunction()">
        <div id="loader"></div>
<section id="container" style="display:none;" class="animate-bottom">
</section>
    </body>


回答2:

No validation on user request

$m = MetersInventoryStore::findOne($_REQUEST['selected_meters']);

it's too much

$msn = $m->meter_serial;

do this

$api_url = 'http://xx.xxx.xxx.xxx:7000/api/meters/GetByMsn/' . $m->meter_serial . '/' .$date_time;

Curl request need to be moved to separated method

function curlRequest(msn) {
  $api_url = 'http://xx.xxx.xxx.xxx:7000/api/meters/GetByMsn/' . $msn . '/' .$date_time; // my base URL
  $curl = curl_init($api_url);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($curl, CURLOPT_TIMEOUT, 1000);
  curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization:key'));
  $curl_response = curl_exec($curl);
  $json = json_decode($curl_response); // WTF snake case only in Python

  return $json->data->Response;
}

And now answer to your question You need add click event to your button. You using Yii2 his have jQuery for more powerful DOM-tools. Use $.hide() and $.show() for you button class and draw preloader. You can use Promise if you need feedback from server of his save data.