YII2 Street City Lookup by Postcode

In the Yii2 advanced app in the Signup form,

I would like the street and city to show up, when a postcode is typed and the postcode field looses focus.

To the user table was added: postcode(Varchar(6)) (In the Netherlands the postcode fomat is like 3743DA or 3743 DA)

3 tables are added:

street: id, street

city: id, city

postcode: id, postcode, street_id, city_id

In my common/models/Postcode model




    public function getCity()

    {

        return $this->hasOne(City::className(), ['id' => 'city_id']);

    }


    public function getStreet()

    {

        return $this->hasOne(Street::className(), ['id' => 'street_id']);

    }



in common/models/RecordHelpers.php

Uses were added




use common\models\Postcode;

use common\models\Street;

use common\models\City;



and a function for retreiving street and city was added.




    public function getStreetCity($postcode="3741DA") {

        

        $postcode = str_replace(' ', '', strtoupper($postcode));

        

        $sql =    'SELECT `street`, `city` '

                . 'FROM postcode, street, city '

                . 'WHERE postcode="'.$postcode.'" '

                . 'AND postcode.street_id = street.id '

                . 'AND postcode.city_id=city.id ';

        

        $address = Postcode::findBySql($sql)->one();

    }



in frontend/views/site/signup.php

Javascript code was added: (when the focus of the postcode field is lost replace div id Address with street and city.)




$this->registerJs('$("#signupform-postcode").blur(function() {

  if ($(this).val().length==6 || $(this).val().length==7){  

  $("#address").text("Street and City here");}

});');



underneath the postcode field I’ve placed the address div.




<?= $form->field($model, 'postcode') ?>

<div id="address"></div>

Now the question is how to lookup street and city and place them in address div…

Look at http://www.yiiframework.com/doc-2.0/yii-jui-autocomplete.html

That is an Ajax autocomplete class that I used in Yii 1.1 and it should do what you want without too much extra code.

I do not know how to use that widged, can you give me an example regarding my code?

I have not used it in Yii2 yet but I have two blog posts about Yii 1.1 widget which might help (I don’t know how much it has changed).

Otherwise, you’ll have to read the docs for it. I think what you have is basically correct in code, you just need to wire it up to the auto complete widget.

Hi Luke thanks for the reply, I’ll look into that…

Still waiting for your 10th tutorial :) perhaps yii2 and ajax ;)

Allmost there…

In frontend\views\site\signup.php

Beneath code shows the street now in the php part,

But my javascript isn’t right it will throw me an error on

$address=RecordHelpers::streetCity on the first colon.

SyntaxError: missing ; before statement

$address=RecordHelpers::streetCity($("#signupform-email").val());


use common\models\RecordHelpers;

use common\models\Postcode;


$address=RecordHelpers::streetCity("3741DA");

var_dump($address);

echo $address['street'];

$this->title = Yii::t('frontend', 'Signup');

$this->params['breadcrumbs'][] = $this->title;


$this->registerJs('$("#signupform-postcode").blur(function() {

  if ($(this).val().length==6 || $(this).val().length==7){ 

    $address=RecordHelpers::streetCity($("#signupform-email").val());

    $("#address").text($address["street"]);}

});');

I’ve done it!

First created an action in the SiteController


    public function actionAddress($postcode) {

        

        $address=RecordHelpers::streetCity($postcode);

        echo $address['street'].' - '.$address['city'];

    }



Which uses following recordhelper


    public static function streetCity($postcode="3741DA") {

        

        $postcode = str_replace(' ', '', strtoupper($postcode));

        

        $sql =    'SELECT `street`, `city` '

                . 'FROM postcode, street, city '

                . 'WHERE postcode="'.$postcode.'" '

                . 'AND postcode.street_id = street.id '

                . 'AND postcode.city_id=city.id ';

        

        $address = Postcode::findBySql($sql)->asArray()->one();

        return $address;

    }



In the SignUp view I added following Javascript


$this->registerJs('$("#signupform-postcode").blur(function() {

  if ($(this).val().length==6 || $(this).val().length==7){ 

    var $postcode=$(this).val();

    

    $.ajax({

        url: "/site/address",

        data: {"postcode":$postcode},

        context: document.body

        }).done(function(data) {

            $("#address").text(data);

        });

   }

});');



And the div id under postcode




      <?= $form->field($model, 'postcode') ?>

      <div id="address"></div>

Don’t forget the use statements for moddels and helpers

[size="4"]The above code works,

but in the real world I had to use Postcode-ID’s.

Because depending on the number in combination with a postcode,

Postcode can come up with another streetname…

So a Postcode is not uniquely addressed to 1 streetname[/size]