-
Notifications
You must be signed in to change notification settings - Fork 915
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change repeatable names on display #4032
Conversation
Pedro... I think we're onto something here. Please:
|
We can still have both, but notice that
Nop, we still need the JS version that takes care of naming when new item is added or items are moved. |
I pulled this PR and made few tests. CRUD::addField([
'name' => 'characters',
'label' => 'Assosciate Characters with this origins.',
'tab' => 'Relationships',
'wrapper' => [
'class' => 'form-group col-md-6',
],
'pivot_selector' => [
'wrapper' => [
'class' => 'form-group col-md-6',
]
],
'pivotFields' => [
[
'name' => 'as',
'type' => 'text',
'wrapper' => [
'class' => 'form-group col-md-6',
],
],
],
'new_item_label' => 'Associate Character',
'init_rows' => 0,
'min_rows' => 0,
'max_rows' => 10,
]); When updating (creating works fine)resource, it throws an exception.
/// Traits/Create.php:119
if (isset($field['pivotFields'])) {
foreach ($values as $pivot_row) {
Log::channel('daily')->debug($pivot_row);
$relation_data[$pivot_row[$field['name']]] = Arr::except($pivot_row, $field['name']);
}
} This doesn't seem to be correct.
|
Hey @PitchRE , I can't stress enough how important it was for me that you stick with this issue and provided all the help needed to reproduce it! I really appreciate your efforts here. 🙏 I was finally able to reproduce it and I think it's now fixed for good. I don't wanna ask, but .. wanna try ? 😄 Thanks again, and Merry Christmas! Pedro |
@pxpm You too! :) So the problem right now is that updating "kinda works" but removing/attaching relationship doesn't. change-repeatable-names-on-display.mp4Logs HereLogs of `$input` inside `CrudPanel/Traits/Create@syncPivot`When only updating (not removing, adding relationships [2021-12-23 18:32:00] local.DEBUG: array (
'name' => 'aaaaa',
'characters' =>
array (
0 =>
array (
'characters' => '2',
'as' => 'THIS ROW WAS ALREADY THERE 1',
),
1 =>
array (
'characters' => '1',
'as' => 'THIS ROW WAS ALREADY THERE 2',
),
),
)
When I added a relationship. [2021-12-23 18:31:23] local.DEBUG: array (
'name' => 'aaaaa',
'characters' =>
array (
0 =>
array (
'characters[0' =>
array (
'characters' => '2',
'as' => 'THIS ROW WAS ALREADY THERE 1',
),
),
1 =>
array (
'characters[1' =>
array (
'characters' => '1',
'as' => 'THIS ROW WAS ALREADY THERE 2',
),
),
2 =>
array (
'characters' => '3',
'as' => '!!!! THIS IS NEW RELATIONSHIP !!!!',
),
),
) Very dirty fix to Create@syncPivot $relation_data = [];
if (isset($field['pivotFields'])) {
foreach ($values as $pivot_row) {
if (!isset($pivot_row[$field['name']])) {
$relation_data[reset($pivot_row)[$field['name']]] = Arr::except(reset($pivot_row), $field['name']);
} else {
$relation_data[$pivot_row[$field['name']]] = Arr::except($pivot_row, $field['name']);
}
}
} So with this patch, it works for me. But that's not the point. |
@@ -27,6 +27,7 @@ | |||
if(isset($row[$subfield['name']]) || isset($row[$subfield['name'].'[]'])) { | |||
$subfield['value'] = $row[$subfield['name']] ?? $row[$subfield['name'].'[]']; | |||
} | |||
$subfield['name'] = $field['name'].'['.$repeatable_row_key.']['.$subfield['name'].']'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Two questions here, both might be absurd or stupid:
- What if
subfield['name']
is already a bracket-using-field-name? Can there ever be? - What if
$subfield
is another repeatable?
I guess question no 2 also implies question no 1, since repeatable will have subfields. And I know we said we don't support repeatable
inside repeatable
(I still think it's too complicated to support right now). But... now that relationship
loads repeatable
for some relationships... we have to at least know what will happen... If not all relationships can be used inside repeatable... we have to know that...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Third question. Can't we check if it's an array here?
if (is_string($subfield['name']) {
$subfield['name'] = $field['name'].'['.$repeatable_row_key.']['.$subfield['name'].']';
} elseif (is_array($subfield['name'])) {
// probably a date_range but hey, who knows, might be somthing else too
foreach ($subfield['name'] as $k => $item) {
$subfield['name'][$k] = $field['name'].'['.$repeatable_row_key.']['.$item['name'].']';
}
// and if (for some reason) we can't do that... we can even do something hacky like
$subfield['some_flag_for_the_field_to_know_its_repeatable'] = true;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey @tabacitu
1 - Can never be.
2 - If subfield is another repeatable it will have the repeatable name there.
3 - Not even considering that for now, after the "first repeatable" it's initialized the "repeatable" field name is changed to accomodate "first repeatable row", so imagine the following scenario:
$this->crud->addFields([
[
'name' => 'extras',
'type' => 'repeatable',
'fields' => [
[
'name' => 'testing',
'type' => 'repeatable',
'fields' => [
[
'name' => 'rep sub 1',
]
]
],
[
'name' => 'testing2'
]
]
],
When extras
initialize, the testing
repeatable name would become: extras[row][testing]
breaking the nested repeatable.
Like you said, I didn't focused on making repeatable work inside repeatable. It would probably be doable since we now use array names, but need a big refactor on how repeatable initializes itself and nested fields.
I've fixed the issue with names in JS (where was the problem for regular/relationship repeatables) and added your suggestion to parse the field names when array.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I understand why it wouldn't work. As I said... I still think it's NOT important to support repeatable inside repeatable.
But now that some of the relationship
fields use repeatable
... we have to know. What combinations will NOT work? From what I understand... the new relationships that 4.2 brings will not work inside repeatable
right? Which begs the question... does it make sense to use any relationship field inside repeatable
??! Not really... right? You only want to use relationship
to update the relationship on the Model... when you want a relationship inside the repeatable... you're better off using select_from_array
or select_from_ajax
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If anything, we should at least add them to the "relationship edge cases" issue - #4012
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tabacitu exactly.
I don't think there is any sense in using relationships inside repeatable.
One thing is using repeatable to edit a relation (like we do), other thing is using repeatable field on your own and add relationship fields there. The CrudField
will be the repeatable, not any of the repeatable fields.
The only reason people use relationships inside repeatable is because the setup of the fields is easier since relationships support adding only the field name as a relation and backpack does a great job guessing the stuff needed.
It will show the "relationship" field, but technically it will never be a relationship, it's just a select.
Like I told you earlier, it's way easier to support repeatable inside repeatable now. I am sure that if I parsed the names a little bit more I would endup making it work ... Maybe without BC, so we can have a look at it in 4.2.xx !
@pxpm , what's the status on this? How can I test the before&after? Thanks! |
@tabacitu this is ready to merge. This was pointing to Before repeatable names would only be setup with JS in repeatable initialization. This change makes all fields get the repeatable names before they reach the page otherwise To test this before and after you can add a repeatable field and purposely fail the validation of some field inside repeatable. Let me know, |
Hmm... still cannot confirm the bug is there on the 4.2 branch. Here's what I did:
Why is this needed again? |
@tabacitu sorry if I wasn't 100% clear. The problem here is the fact that if we don't change the names before parsing the field blade file, the Follow me, $this->crud->addFields([
[
'name' => 'dummyproducts',
'pivotFields' => [
[
'name' => 'notes',
'type' => 'textarea'
],
],
],
]); This will add a If we don't change the field name before displaying the field, Let me know if I made myself clear now. Thanks, |
or any other fields with multiple names
Oh ok, I get it now, thanks for the explanation and video @pxpm . So we're basically fixing a bug in
Otherwise, I cannot find a fault with this PR and I'm inclined to merge it. Cheers! |
@tabacitu I've just checked your fix for date_range and it seems to work just fine. My only concern is that we are adding that conditional fixing into the "core" only to solve this field problem, that we would probably be better fixing in the field itself but conventionally removing the support for arrayed field names. This should become field configurations instead of field name defining what other fields that field is going to setup. But I get if you don't wanna mess with that rn. But maybe leave a comment in the code about it so we don't forget ? About the @PitchRE problem I was able to reproduce it, and fix it. If you look close at the reported results the problem was repeatable setting up the names wrong leaving "[" where it shouldn't. You cannot replicate it because @PitchRE tested this branch in the middle, so it's already fixed on top of it. Let me know, |
Awesome. Let's merge this bad boy!
Yeah.... I'm a bit unconfortable with that rn. Let's leave it for future-us. 😅👀 |
WHY
This will make old() wrapper work for repeatable by using
[]
arrayed names.BEFORE - What was wrong? What was happening before this PR?
Fields didn't overwritte the name in PHP only in JS. This way
old()
would get thereal name
eg:category
instead of the repeatable correct namerepeatable[row][category]
AFTER - What is happening after this PR?
Names are changed before displaying them.
HOW
How did you achieve that, in technical terms?
Setup the name before repeatable initializes.
@tabacitu this seems to fix the problem.
This points to
create-old-input-helper
branch,This does not take into account fields with arrayed names.