I've created a field called "international" in my TYPO3 project. This field is a checkbox and is displayed on my backend with an associated label.
'international' => [
'exclude' => FALSE,
'label' => 'LLL:EXT:projects/Resources/Private/Language/locallang_db.xlf:tx_projects_domain_model_requestprojects.international',
'config' => [
'type' => 'check',
'items' => [
// label, value
['LLL:EXT:projects/Resources/Private/Language/locallang_db.xlf:tx_projects_domain_model_requestprojects.international.items.1', 1],
],
]
],
If I go to my frontend, the faceting is indeed showing the field as link to filter my content thanks to this :
fieldRenderingInstructions {
international =< plugin.tx_solr.search.faceting.facets.international.renderingInstruction
international.field = international_intS
}
faceting {
facets.international {
label.data = LLL:EXT:skin/Resources/Private/Language/locallang.xlf:tx_projects_domain_model_requestprojects.international
field = international_intS
renderingInstruction = TEXT
renderingInstruction {
field = optionValue
wrap = {LLL:EXT:projects/Resources/Private/Language/locallang_db.xlf:tx_projects_domain_model_requestprojects.international.items.|}
insertData = 1
}
}
}
Starting with this, I have 2 questions:
Why does my content which have the field "international" not selected are triggering an "extra faceting" this the name of my root page?
If I have 2 "international" and 3 "international" not checked, my facets returns "international (2)" and "root page (3)" ? (the 3 have an empty value)
How can I hide this facet, but keep getting the value that was set to my content ?
I need to hide this facet on front (but probably I will have to fix the "bug" from 1), but keep the given value.
That was quite simple, actually.
Just added this in my facet
includeInAvailableFacets = 0
Related
I have doctor and specialization table, and have doctor_specialization_pivot table. In my pivot table I have the following columns:
| doctor_id | additional_data | specialization_id |
additional_data is from the doctor model along with the doctor_id.
In my doctor model file, I have this relationship:
public $belongsToMany = [
'specialization' => [
'path\to\specialization\model',
'table' => 'doctor_specialization_pivot',
'parentKey' => 'doctor_id',
'otherKey' => 'specialization_id',
]
];
Now during submit of form, I'm getting this error:
SQLSTATE[HY000]: General error: 1364 Field 'additional_data' doesn't have a default value (SQL: insert into doctor_specialization_pivot (doctor_id, specializations_id) values (1, 3))"
I tried adding to my relationship 'pivot' => ['additional_data']. But still getting the same error.
I checked the submitted data and additional_data is not empty. I checked from OctoberCMS forums but not getting straight forward answers such as this and this.
Okay. I found the answer to my own question.
I'll answer in detail to help everyone. After digging and blind shooting. According to this documentation here, we can use the method attach() to attach a role to a user by inserting a record in the intermediate table that joins the models.
What confuse me in the documentation is that it uses a $roleId variable and I didn't understand where the $roleId came from. If it's the id of the parent table or the id of other table.
Sample from the link:
$user = User::find(1);
$user->roles()->attach($roleId);
So what I did in my doctor model, I hook to the event beforeSave, use the relationship ($this->specialization) as the first parameter instead of the id in the docs. The $this->specialization() is the relationship too defined in belongsToMany.
Answer:
public function beforeSave()
{
$this->specialization()->attach($this->specialization,['additional_data' => 'additional data from doctor table']);
}
The implementation is pretty much like this video from Watch Learn (Ivan). You can learn a lot about OctoberCMS just by watching his guide on it. Here is the documentation on it as well. This is the example info that I have done.
WARNING Another known flaw is you can't apply this to a model record that isn't created yet. Unlike the standard relation widget which waits until it is saved before attaching records this attaches records in a separate overlay form.
Here is my model.php relationship:
public $belongsToMany = [
'equipments' => [
'Brandon\Pixelrpg\Models\Equipments',
'table' => 'brandon_pixelrpg_equipment_inventory',
'key' => 'inventory',
'otherKey' => 'equipment',
'pivot' => ['quantity']
]
];
Here is my controller.php:
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController',
'Backend\Behaviors\ReorderController',
'Backend\Behaviors\RelationController'
];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $reorderConfig = 'config_reorder.yaml';
public $relationConfig = 'config_relation.yaml';
Here is my config_relation.yaml:
equipments:
label: Equipments
view:
list:
columns:
id:
label: ID
type: number
searchable: true
sortable: true
name:
label: Name
type: text
searchable: true
sortable: true
value:
label: Value
type: number
searchable: true
sortable: true
updated_at:
label: Updated
type: datetime
searchable: true
sortable: true
pivot[quantity]:
label: Quantity
type: number
pivot:
form:
fields:
pivot[quantity]:
label: Quantity
type: number
default: 0
I am just going to make a new answer and assume is what you need because you have yet to show any code on how your form works. This is how I would update the pivot information from a frontend form.
Relationship in model.php:
public $belongsToMany = [
'specialization' => [
'path\to\specialization\model',
'table' => 'doctor_specialization_pivot',
'parentKey' => 'doctor_id',
'otherKey' => 'specialization_id',
'pivot' => ['additional_data'] //This is required
]
];
Then in some php code lets call it onAddSpecialization():
public function onAddSpecialization() {
//Calling a function to get the doctor id maybe from the signed in user
$doctor = Doctors::find($this->$doctorId());
//We get our Specialization from an input
$specialization = Specialization::find(Input::get('specialization_id'));
//We get our additional data from an input
$additional_data = Input::get('additional_data');
//Now we are going to attach the information
$doctor->specialization()->attach($specialization, ['additional_data' => $additional_data]);
}
Now an example of updating our additional data:
public function onUpdateAdditionalData() {
//Calling a function to get the doctor id maybe from the signed in user
$doctor = Doctors::find($this->$doctorId());
//If you get specialization by id from an input. I believe you need to go through the relationship in order to access the correct pivot information.
$specialization = $doctor->specialization->where('id', Input::get('specialization_id'))->first();
//Insert the new pivot information
$specialization->pivot->additional_data = $new_additional_data;
//Save
$specialization->pivot->save();
}
I want to search in a datatable field that not used as columns in serverSide mode.
$scope.dtColumns = [
DTColumnBuilder.newColumn('title').withTitle('title')
.renderWith((data, type, full) => {
return `${data} <br> ${full.title_en}`;
}
)
]
I Have used title filed as a column, But don't have used title_en.
Now When I search title_en, the result is empty!
What's your idea?
So I've got a weird problem that I'm having a hard time figuring out. I've got a simple form with a few elements that are not being submitted, all of these elements have only one thing in common, they're select elements:
echo $this->Form->control("spirit_type_id", [
"label" => false,
"type" => "select",
"options" => $spirit_types,
"empty" => "Spirit Type"
]);
echo $this->Form->control("country_id", [
"label" => false,
"type" => "select",
"options" => $countries,
"empty" => "Country"
]);
echo $this->Form->control("region_id", [
"label" => false,
"type" => "select",
"options" => $regions,
"empty" => "Region"
]);
And in my controller I have:
public function add() {
$spirit = $this->Spirits->newEntity();
$spirit_types = $this->Spirits->SpiritTypes->find("list");
$countries = $this->Spirits->Countries->find("list");
$regions = $this->Spirits->Regions->find("list");
if ($this->request->is("post")) {
debug($this->request->getData());
die();
$spirit = $this->Spirits->patchEntity($spirit, $this->request->getData());
$spirit->user_id = $this->Auth->user("id");
if ($this->Spirits->save($spirit)) {
$this->Flash->success("Your spirit was successfully saved.");
$this->redirect(["action" => "index"]);
} else {
$this->Flash->error("Your spirit could not be saved.");
}
}
$this->set(compact("spirit", "spirit_types", "countries", "regions"));
}
The important part is that debug statement. It shows this when I insert data using the form.
[
'name' => 'Longrow Peated',
'image' => 'imageLocation',
'brand' => 'Springbank',
'age' => '',
'cost' => '55'
]
Those are all text and/or number elements in my form, and they all come out just fine. It gets a little weirder though. I have validation in my table to require those id fields:
public function validationDefault(Validator $validator) {
$validator->requirePresence(
"name", "brand", "spirit_type_id", "country_id", "region_id", "age", "cost", "image"
)
->notEmpty("name", "We require a name")
->notEmpty("brand", "We require a brand or distillery")
->notEmpty("spirit_type_id", "We require a type of alchohol")
->notEmpty("country_id", "We require a country of origin")
But this doesn't ever seem to get triggered when I insert the data using patchEntity, it's only caught when I actually call the save function and I try inserting into the database.
If $this->request->getData() is not showing all of your fields, the most likely cause would be some sort of problem with your form; there are not a lot of ways for CakePHP to discard your data from here. You can narrow it down by using browser tools (built into most of them now) to inspect the data actually being sent from your browser in the page request.
If it turns out that the fields really aren't being sent across at all, the problem is almost certainly in your form. For example, you might be closing it early, or there might be HTML errors that confuse the browser. Make sure that all of your input tags are between the <form> and </form>, and if they are then try an HTML validator to check your code. There are lots of options online, and even the inspectors built into browsers can often help you spot these sorts of issues.
This is the most common problem:
If you check debug($this->request->getData()); before $spirit = $this->Spirits->newEntity(); you then see all submitted data!
Next go to Spirit Entity and double check if your fields "spirit_type_id,.." accessible!
/**
* Fields that can be mass assigned using newEntity() or patchEntity().
*
* Note that when '*' is set to true, this allows all unspecified fields to
* be mass assigned. For security purposes, it is advised to set '*' to false
* (or remove it), and explicitly make individual fields accessible as needed.
*
* #var array
*/
protected $_accessible = [
'*' => true, // quick fix
'id' => false,
];
or better way:
protected $_accessible = [
'spirit_type_id' => true,
'country_id' => true,
// etc ...
];
Edit
debug
$spirit = $this->Spirits->patchEntity($spirit, $this->request->getData());
debug($spirit); exit();
see if any errors.
I want to create a dropdown with custom field but my list query append id field into the query. How to show only selected fields in my query.
$this->loadModel('CardTypes');
$cardTypes = $this->CardTypes->find('list')->select(['code', 'name']);
In my view
$this->Form->select('card_type_id', $cardTypes, [ 'default' => 'DELTA']);
see the manual
$cardTypes = $this->CardTypes->->find('list', [
'keyField' => 'code',
'valueField' => 'name'
]);
I have an array of objects in an ng-repeat that I am looking to filter.
%input{type: 'text', 'ng-show' => "content == 'include'", 'ng-model' => "search.author"}
%input{type: 'text', 'ng-show' => "content == 'exclude'", 'ng-model' => "search.author"}
%tr{'ng-repeat' => 'book in books| filter:search'}
The first input filters correctly (filters the authors that match the input string) but for the second input I want to filter the model differently (for example: a filter that excludes authors that match the string input).
How would I pass the correct filter from the input to the ng-repeat so that it will know how to correctly filter my collection based on what input I am typing from?
I would create a custom filter on the scope that returns what you want
$scope.myFilter = function(item) {
if(content == 'include')
//filter one way
else
//filter another way
};
%tr{'ng-repeat' => 'book in books| filter:myFilter '}