Laravel Backpack Select2 Attribute - To show foreign key attribute - laravel

I have 3 tables below with relationship applied accordingly.
Order Table - (order_id, stock_id) - Need to have stock id, in order to assign available stock to the order.
Stock Table - (stock_id, product_id, order_id) - have product id in order to know the product name.
Product Table - (product_id, name)
When I want to create order, I want to show the available stock to assign for my order.
Below code is able to show me the available stock with its product_id, however, how can I link it to show product name in this case? Is there any specific relationship method or attribute I can use to achieve my objective?
$this->crud->addField([
'name' => 'stock_id',
'type' => 'select2',
'label' => 'Stock',
'entity' => 'stock',
'attribute' => 'product_id',
'model' => 'App\Models\Stock',
'options' => (function ($query) {
return $query->orderBy('created_at', 'DESC')->where('order_id', null)->get();
}),
]);

Related

Having multiple columns (foreign keys) of the same n-n relation in Backpackforlaravel

I'm struggling with the following situation:
My entities Session & Registration are related with a many-to-many (n-n) relationship. In Registration, I have two foreign keys, player_id and hotel_id.
In the Session CrudController, I want to display the related name(s) of the Player(s) and Hotel(s).
For Player, it worked like this:
CRUD::addColumn([
// any type of relationship
'name' => 'registrations', // name of relationship method in the model
'type' => 'relationship',
'label' => 'Spieler', // Table column heading
// OPTIONAL
'entity' => 'registrations', // the method that defines the relationship in your Model
'attribute' => 'player.full_name', // foreign key attribute that is shown to user
'model' => App\Models\Registration::class, // foreign key model
]);
So I've continued to add the Hotel like this:
CRUD::addColumn([
// any type of relationship
'name' => 'registrations', // name of relationship method in the model
'type' => 'relationship',
'label' => 'Hotel', // Table column heading
// OPTIONAL
'entity' => 'registrations', // the method that defines the relationship in your Model
'attribute' => 'hotel.name', // foreign key attribute that is shown to user
'model' => App\Models\Registration::class, // foreign key model
]);
But unfortunately it doesn't work - I don't get an error message, it just keeps showing only the Player column. I think the reason for this is the same value in 'name' - because after commenting the 'name' value in Player, the Hotel information was visible. But I have no idea how to avoid it.
Currently I'm not sure if it's a bug or if I'm doing anything wrong. Would appreciate any kind of support - thanks in advance!
thank you #tabacitu, that works!
I've added
'key' => 'hotel'
and it showed up in the table.

save both field same name relationship one to one backpack laravel

I have two tables with relationship one to one hasOne and have column same name
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'new_title', // the db column for the foreign key
]);
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'achive.new_title', // the db column for the foreign key
'entity' => 'achive',
]);
I just want show once but save both to two table
You need something that's call the callbacks method, the simplicity of that method is you can control what you want after create, edit, delete and etc.
So, in your controller just need one field name,
CRUD::addField([
'label' => "Title",
'type' => 'text',
'name' => 'new_title',
]);
After that, you can create a new trait in your controller for creating/updating your relationship,
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
And then, declare the store function,
public function store() {
// Get the value from the request
$request = $this->crud->getRequest();
// And then you can insert/update data into your relationship table
\DB::table('achives') // Your relation table
->updateOrInsert(
['new_title' => $request->new_title],
['other_column_name' => 'Value of your other column']
);
$response = $this->traitStore();
// do something after save
return $response;
}
The updateOrInsert method accepts two arguments: an array of conditions by which to find the record, and an array of column and value pairs indicating the columns to be updated. more info here

Show/hide fields based on value of another field

I have a scenario where a field should be shown as dropdown or text field based on the value of another field.
Example:
User to select State as dropdown (California, North Carolina, etc) if the selected country is USA.
If any other country is selected (other than USA), user should be shown only a editable text field (instead of dropdown).
Please let me know if there is a way to achieve this using backpack's out-of-the box features. If not, is there any workaround possible?
My code snippet:
COUNTRY FIELD FROM DB:
CRUD::addField([
// 1-n relationship
'name' => 'countryid', // the column that contains the ID of that connected entity;
'label' => 'Country', // Table column heading
'type' => 'select2',
'entity' => 'getcountryid', // the method that defines the relationship in your Model
// optional
//'attribute' => 'name', // foreign key attribute that is shown to user
'model' => "App\Models\Country", // foreign key model
]);
STATE FIELD WHICH DEPENDS ON COUNTRY FIELD
(THIS SHOULD BE MADE AS A TEXT FILED OR DROPDOWN BASED ON THE COUNTRY SELECTED):
CRUD::addField([ // select2_from_ajax: 1-n relationship
'label' => "State", // Table column heading
'type' => 'select2_from_ajax',
'name' => 'countrystateid', // the column that contains the ID of that connected entity;
'entity' => 'countrystate', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'data_source' => url('/api/countrystate'), // url to controller search function (with /{id} should return model)
'placeholder' => 'Select an Indian state', // placeholder for the select
'minimum_input_length' => 0, // minimum characters to type before querying results
'dependencies' => ['countryid'], // when a dependency changes, this select2 is reset to null
//'method' => 'GET', // optional - HTTP method to use for the AJAX call ]); (GET, POST)
]);

How to add a default ordering of ListEntries table in Backpack for Laravel?

When a user first visits the page, the ListEntries table is ordered ascending by id and none of the ordering icons in the table header are active.
I would like to have the ListEntries table ordered by a column of my choosing, including having the icon next to this column active (either ascending or descending).
Is there a way to have the ListEntries table ordered by a column of my choosing when a user visits the page?
In your Controller's setup() method you can use:
$this->crud->orderBy('name', 'DESC');
Anything you pass to the orderBy() statement will be used on the Eloquent query.
By default, columns for real attributes (that have a correspondent column in the database) should be orderable. But you can also manually specify 'orderable' => true for columns, or define your own order logic. Note that relationship columns (1-n, n-n), model_function or model_function columns are NOT orderable by default, but you can make them orderable with orderLogic.
Hope it helps.
This can be done by manipulating the request object, which may be frowned upon in some circles.
This solution will also update the order icon on the appropriate column.
There are a number of ways to accomplish this, but one way would be to add the following to the setupListOperation() method of your Controller.
/** #var \Illuminate\Http\Request $request */
$request = $this->crud->getRequest();
if (!$request->has('order')) {
$request->merge(['order' => [
[
'column' => 'column-index-here',
'dir' => 'asc'
]
]]);
}
Use this key orderable it is a boolean
this->crud->addColumn([
'label' => 'Category',
'type' => 'select',
'name' => 'category_id', // the db column for the foreign key
'entity' => 'category', // the method that defines the relationship in your Model
'attribute' => 'name', // foreign key attribute that is shown to user
'orderable' => true,
'orderLogic' => function ($query, $column, $columnDirection) {
return $query->leftJoin('categories', 'categories.id', '=', 'articles.select')
->orderBy('categories.name', $columnDirection)->select('articles.*');
}
]);
Reference

Magento Admin formfield multiselect selected

I´m currently developing a custom module for magento thats going to list employees.
I have figured out almost everything. The only thing I got left is how the selected values is going to be highlighted.
The problem I´m having is for the backend.
I got 2 tabs per employee, one for employee data and one tab for magento categories.
1 employee can have 1 or more categories.
The database table that the categories are stored in are a non-eav table.
So my question is
What in a multiselect determines which values are selected? As it is now, only one value is selected.
I think you can do this by simply passing in an array of the id's to be selected into the 'value' attribute of the field being added for the multiselect in the _prepareForm() method. Something like the following.
$fieldset->addField('category_id', 'multiselect', array(
'name' => 'categories[]',
'label' => Mage::helper('cms')->__('Store View'),
'title' => Mage::helper('cms')->__('Store View'),
'required' => true,
'values' => Mage::getSingleton('mymodule/mymodel')->getMymodelValuesForForm(),
'value' => array(1,7,10),
));
The id of the form element (e.g. category_id) must not be an attribute in your model, otherwise when the form values get set with $form->setValues() later on, the attribute value will be overwritten.
I normally store multiple selections as a text column separated by commas much like most magento modules handles stores which requires a slightly different approach as shown below.
In the form block for the tab with the multiselect, you firstly define the element to be displayed like so in the _prepareForm() method. You then get the values from the model and set put them into the form data.
protected function _prepareForm()
{
...
$fieldset->addField('store_id', 'multiselect', array(
'name' => 'stores[]',
'label' => Mage::helper('cms')->__('Store View'),
'title' => Mage::helper('cms')->__('Store View'),
'required' => true,
'values' => Mage::getSingleton('adminhtml/system_store')->getStoreValuesForForm(false, true),
));
...
if ( Mage::getSingleton('adminhtml/session')->getMymodelData() )
{
$data = Mage::getSingleton('adminhtml/session')->getMymodelData();
} elseif ( Mage::registry('mymodel_data') ) {
$data = Mage::registry('mymodel_data')->getData();
}
$data['store_id'] = isset($data['stores']) ? explode(',', $data['stores']) : array();
$form->setValues($data);
}
I normally store the selected stores (categories as in your case) in the main model as a text column and comma separated values of ids, hence the explode.
In the controller for for the edit action, I put the model being edited into the mage registry so we can load it and it's values in the step above.
Mage::register('mymodel_data', $model);
Thanks for answering.
This is how my field looks like:
$fieldset->addField('npn_CatID', 'multiselect', array(
'label' => Mage::helper('employeelist')->__('Kategori'),
'class' => 'required-entry',
'required' => true,
'name' => 'npn_CatID',
'values' => $data,
'value' => array(3,5)
));
npn_CatID is the value in my db where the category id is saved.
I have tried to change the name and field ID but cant get it working.
When its the field id is like above ONE value is selected and its the last one inserted for the chosen employee
My data array looks likes
array(array('value' => '1', 'label' => 'USB'), array('value' => '2', 'label' => 'Memories'))

Resources