This forum has moved to a new location and is in read-only mode. Please visit talk.octobercms.com to access the new location.

dleee59417
dleee59417

Hello, need help I created 2 models in the builder:

  • MerchantPoints
  • Brands

MerchantPoints data structure like this:

  • id
  • name
  • displayname
  • logo
  • brand_id

MerchantPoints fields.yaml:


fields:

name:

    label: Name

    span: auto

    placeholder: 'Terminal name'

    type: text

    comment: 'Terminal name'

brand:

    label: Brand

    nameFrom: name

    descriptionFrom: disgusting

    emptyOption: '-- Select brand --'

    span: full

    type: relation

logo:

    label: Logo

    span: auto

    placeholder: ' .png'

    type: text

    comment: ' .png'

    dependsOn: brand

displayname:

    label: Displayname

    span: auto

    placeholder: '-- Name brand --'

    type: text

    dependsOn: brand

RELATIONS:


public $belongsTo = [

 'brand' => Brands::class,

 ];

Brands data structure like this:

  • id
  • name
  • logo

In model MerchantPoints i get list atribute brands like this:


//** Brands lists**//   
public function getBrandsOptions()
{    
    return Brands::all()->lists('name', 'id', 'logo');
}

I need logic like this:

  1. User selects brend from the drop-down list brand.
  2. Based on the selected brand, fill in the displayname and logo fields

But I don’t know how to do it

Last updated

mjauvin
mjauvin

Just add a depends on field definition in your MerchantPoints model fields config and use brand[name] and brand[logo] as the field names.

dleee59417
dleee59417

https://ibb.co/xHSzfQq

  1. Choosing a brand
  2. Completed fields

Last updated

dleee59417
dleee59417

mjauvin said:

Just add a depends on field definition in your MerchantPoints model fields config and use brand[name] and brand[logo] as the field names.

"Call to a member function hasRelation() on null" on line 70 of /logo/public_html/modules/backend/traits/FormModelSaver.php

 public $belongsTo = [
 'brand' => Brands::class,
 'displayname' => [Brands::class, 'key' => 'name'],
 'logo' => [Brands::class, 'key' => 'logo'],
 ];

Last updated

mjauvin
mjauvin

Show your field definition file(s)

mjauvin
mjauvin

And this is all you need for your getBrandOptions() [brand singular, like the relation/field name] :

public function getBrandOptions()
{    
    return Brands::all()->lists('name', 'id');
}

Note: this is needed if you use type=dropdown for your brand field (instead of type=relation)

Last updated

mjauvin
mjauvin
fields:
    name:
        label: Name
        span: auto
        placeholder: 'Terminal name'
        type: text
        comment: 'Terminal name'

    brand:
        label: Brand
        nameFrom: name
        descriptionFrom: disgusting
        emptyOption: '-- Select brand --'
        span: full
        type: relation

    brand[logo]:
        label: Logo
        span: auto
        placeholder: ' .png'
        type: text
        comment: ' .png'
        dependsOn: brand

    brand[name]:
        label: Displayname
        span: auto
        placeholder: '-- Name brand --'
        type: text
        dependsOn: brand
mjauvin
mjauvin

In fact, you don't need the getBrandOptions() method since you're using type=relation for this field.

Last updated

mjauvin
mjauvin

And the convention is to use singular names for models, and plural names for controllers... no big deal, but it's better to follow this as it is less confusing...

mjauvin
mjauvin

Ok, I looked into this further and you need the following:

For your fields, use the following:

    _logo:
        label: Logo
        span: auto
        placeholder: ' .png'
        type: text
        comment: ' .png'
        dependsOn: brand

    _name:
        label: Displayname
        span: auto
        placeholder: '-- Name brand --'
        type: text
        dependsOn: brand

the "_" before the field names is to prevent the model from saving these since they are part of the related model.

In your model, add these methods:


function getLogoAttribute()
{
   if ($this->brand) {
      return $this->brand->logo;
   }
}
function getNameAttribute()
{
   if ($this->brand) {
      return $this->brand->name;
   }
}
dleee59417
dleee59417

Wow it works! but if save the form, the data is not added to the base.

I have a data structure like this

    Schema::create('logo_merchantpoints', function($table)
    {
        $table->engine = 'InnoDB';
        $table->bigIncrements('id')->unsigned();
        $table->string('mcc', 5);
        $table->string('name', 100);
        $table->string('displayname', 100);
        $table->string('logo', 50);
    });

If I use _name and _logo then no data is added.

If I use displayname and logo. Then the list does not display values

maybe getAttribute is not the method I want?

Last updated

mjauvin
mjauvin

But why would you save this information if it's already available in the brand relation?

dleee59417
dleee59417

Importantly, brand and merchant are not related.

$belongsTo i only use to get id brand value in columns.yaml merchant

dleee59417
dleee59417

mjauvin said:

But why would you save this information if it's already available in the brand relation?

This is the evolution of data, before there were no brands, there was displayname, now they decided to change the data model.

But people work with the current model and have to maintain it.

dleee59417
dleee59417

For understanding, this is interface for data enrichment.

There is a set of data on the input, the user looks at it and fills in the empty fields displayname and logo.

But since users make mistakes in filling. I decided automate the process. Since the data that the user fills in is the same, I made a table with brands from where I want to get the canonical data. If they are there. If not, the user fills in them himself.

Did I blow your mind? :)

Last updated

mjauvin
mjauvin

Ok, then try this one:

function getLogoAttribute($val)
{  
   if ($this->brand && empty($val)) {
      return $this->brand->logo;
   }
   return $val;
}   
function getDisplaynameAttribute($val)
{  
   if ($this->brand && empty($val)) {
      return $this->brand->name;
   }
   return $val;
}

And, of course:

    logo:
        label: Logo
        span: auto
        placeholder: ' .png'
        type: text
        comment: ' .png'
        dependsOn: brand

    displayname:
        label: Displayname
        span: auto
        placeholder: '-- Name brand --'
        type: text
        dependsOn: brand

1-16 of 16

You cannot edit posts or make replies: the forum has moved to talk.octobercms.com.