Search code examples
octobercmsoctobercms-pluginsoctobercms-backend

How to implement the Location function of User Plus+ Plugin from Rainlab?


I've implemented the Country Select Form and State Select Form in my frontend from the Location Plugin. The values get populated according to the backend settings of Location. But if I click on register, the country and state are not saved.

first i thougth it's a fillable problem because no errors are thrown. Then I looked into the code an realized that the documentation of the Location Plugin states that the Behavior Controller adds two new relation to the implemented model (state and country). Looking at the code example for the location plugin i noticed that the select form fields are named 'country_id' and 'state_id'. I have changed them to country and state so the usermodel picks up the relation created by the Location Behavior but still no luck. The fields aren't saved. What am I doing wrong?

partial site/country-state-horizontal.htm

 {% set countryId = countryId|default(form_value('country')) %}
 {% set stateId = stateId|default(form_value('state')) %}
 <div class="uk-margin">
     <div class="uk-margin">
         <label class="uk-form-label" for="accountCountry">{{ 'Land'|_      }}</label>
         <div class="uk-form-controls">
             {{ form_select_country('country', countryId, {
             id: 'accountCountry',
             class: 'uk-select',
             emptyOption: '',
             'data-request': 'onInit',
             'data-request-update': {
             'site/country-state-horizontal': '#partialCountryState'
             }
             }) }}
         </div>
     </div>
 </div>

 <div class="uk-margin">
     <label class="uk-form-label" for="accountState">{{ 'Bundesland'|_      }}</label>
     <div class="uk-form-controls">
         {{ form_select_state('state', countryId, stateId, {
         id: 'accountState',
         class: 'uk-select',
         emptyOption: ''
         }) }}
     </div>
 </div>

EDIT:

partial snippets/intro.htm

    <form 
     data-request="onRegister"
     class="uk-form-horizontal uk-margin-large">
          <div class="uk-margin">
               <label class="uk-form-label" for="registerName">Vorname</label>
               <div class="uk-form-controls">
                    <input
                            name="name"
                            type="text"
                            class="uk-input"
                            id="registerName"
                            placeholder="Bitte deinen Vornamen eingeben" />
               </div>
          </div>

           <div class="uk-margin">
                <label class="uk-form-label" for="registerSurname">Nachname</label>
                <div class="uk-form-controls">
                   <input name="surname" type="text" class="uk-input" id="registerSurame" placeholder="Bitte deinen Nachnamen eingeben" />
                </div>
           </div>

 .....

           <div id="partialCountryState">
                {% partial 'site/country-state-horizontal' countryId=user.country_id stateId=user.state_id %}
           </div>

 .....

           <div class="uk-margin">
                <button type="submit" class="uk-button uk-button-primary">Registrieren</button>
           </div>

Expected: Form saves the Ids for the User upon registration for country and state Actual: Fields stay empty


Solution

  • I read plugin and find out that its general plugin so to make it compatible to users plugin we need to add some extra code there.

    1. Add needed fields in table ( manually )

    we need to manually add country_id and state_id in to table users

    you can add them by creating new version file from builder plugin and apply that. make sure it stayscountry_id and state_id[ in your case you tried to change them if that so just revert back and add postfix_id`]

    <?php namespace HardikSatasiya\SoTest\Updates;
    
    use Schema;
    use October\Rain\Database\Updates\Migration;
    
    class Migration1013 extends Migration
    {
        public function up()
        {
            Schema::table('users', function($table)
            {
                $table->integer('country_id')->unsigned()->nullable()->index();
                $table->integer('state_id')->unsigned()->nullable()->index();
            });
        }
    
        public function down()
        {
            // Remove fields
        }
    }
    
    1. Now in your plugin's boot method add this code
    <?php namespace HardikSatasiya\SoTest;
    
    // ... 
    use RainLab\User\Models\User as UserModel;
    
    class Plugin extends PluginBase
    {
    
        public function boot() {
    
          UserModel::extend(function ($model) {
            $model->implement[] = 'RainLab.Location.Behaviors.LocationModel';
            $model->addFillable([
                'country_id',
                'state_id',
            ]);
          });
    
        // ...
    

    Now just try to save your data it should save country and state and to retrieve them you can use

    echo $userModel->country_code; // US
    echo $userModel->state_code; // FL
    
    echo $userModel->country_id; // 10 respective id
    echo $userModel->state_id; // 22 respective id
    

    With User Plus(+) plugin installed

    Not sure with User Plus(+) plugin but I debugged and find some issue, because of this commit https://github.com/rainlab/location-plugin/commit/6360a319f1e1e3eff8b6a43e85bdfdf3f84fbb58 fillable is not working properly.

    So, We can try to add it manually again once more.

    <?php namespace HardikSatasiya\SoTest;
    
    // ... 
    use RainLab\User\Models\User as UserModel;
    
    class Plugin extends PluginBase
    {
    
        public function boot() {    
          UserModel::extend(function ($model) {            
            $model->addFillable([
                'country_id',
                'state_id',
            ]);
          });
    

    if any doubt please comment.