-
-
Notifications
You must be signed in to change notification settings - Fork 484
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
uncap additional expenses and allow delete #5908
uncap additional expenses and allow delete #5908
Conversation
reindexFields () { | ||
// Reindex fields so that nested parameters come in with consecutive | ||
// indexes starting at 0 | ||
const containers = this.element.querySelectorAll('.expense-container') | ||
containers.forEach((container, index) => { | ||
container.querySelectorAll('input, select, textarea').forEach(field => { | ||
const newName = field.name.replace(/\[additional_expenses_attributes\]\[\d+\]/, `[additional_expenses_attributes][${index}]`) | ||
field.name = newName | ||
field.id = newName.replace(/\[/g, '_').replace(/\]/g, '') | ||
}) | ||
|
||
container.querySelectorAll('label').forEach(label => { | ||
const forAttr = label.getAttribute('for') | ||
if (forAttr) { | ||
const newForAttr = forAttr.replace(/additional_expenses_attributes_\d+/, `additional_expenses_attributes_${index}`) | ||
label.setAttribute('for', newForAttr) | ||
} | ||
}) | ||
}) | ||
} |
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.
What happens if we don't reindex the fields?
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.
You shouldn't need a new controller at all for this. This should be doable 100% in the template and controller. Look at the documentation here.
We already have the component installed, so you can skip the installation step.
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.
Essentially, persisted associations get their ID as their index and new records get the timestamp they were created (line 19). This ensures unique identifiers for every association in the form without needing a reindex.
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.
@schoork @elasticspoon thanks! I'll make these changes and push something up by the end of this week
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.
Overall this looks great, but we don't need the added controller.
reindexFields () { | ||
// Reindex fields so that nested parameters come in with consecutive | ||
// indexes starting at 0 | ||
const containers = this.element.querySelectorAll('.expense-container') | ||
containers.forEach((container, index) => { | ||
container.querySelectorAll('input, select, textarea').forEach(field => { | ||
const newName = field.name.replace(/\[additional_expenses_attributes\]\[\d+\]/, `[additional_expenses_attributes][${index}]`) | ||
field.name = newName | ||
field.id = newName.replace(/\[/g, '_').replace(/\]/g, '') | ||
}) | ||
|
||
container.querySelectorAll('label').forEach(label => { | ||
const forAttr = label.getAttribute('for') | ||
if (forAttr) { | ||
const newForAttr = forAttr.replace(/additional_expenses_attributes_\d+/, `additional_expenses_attributes_${index}`) | ||
label.setAttribute('for', newForAttr) | ||
} | ||
}) | ||
}) | ||
} |
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.
You shouldn't need a new controller at all for this. This should be doable 100% in the template and controller. Look at the documentation here.
We already have the component installed, so you can skip the installation step.
@@ -113,6 +113,10 @@ legend { | |||
cursor: pointer; | |||
} | |||
|
|||
.remove-expense-button { |
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.
Is this doable through Bootstrap code?
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.
@schoork I can look into that, haven't worked with bootstrap in a long time but I'll check it out
reindexFields () { | ||
// Reindex fields so that nested parameters come in with consecutive | ||
// indexes starting at 0 | ||
const containers = this.element.querySelectorAll('.expense-container') | ||
containers.forEach((container, index) => { | ||
container.querySelectorAll('input, select, textarea').forEach(field => { | ||
const newName = field.name.replace(/\[additional_expenses_attributes\]\[\d+\]/, `[additional_expenses_attributes][${index}]`) | ||
field.name = newName | ||
field.id = newName.replace(/\[/g, '_').replace(/\]/g, '') | ||
}) | ||
|
||
container.querySelectorAll('label').forEach(label => { | ||
const forAttr = label.getAttribute('for') | ||
if (forAttr) { | ||
const newForAttr = forAttr.replace(/additional_expenses_attributes_\d+/, `additional_expenses_attributes_${index}`) | ||
label.setAttribute('for', newForAttr) | ||
} | ||
}) | ||
}) | ||
} |
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.
Essentially, persisted associations get their ID as their index and new records get the timestamp they were created (line 19). This ensures unique identifiers for every association in the form without needing a reindex.
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.
You will be able to remove this file.
app/javascript/controllers/index.js
Outdated
@@ -14,6 +14,8 @@ import DismissController from './dismiss_controller' | |||
|
|||
import CourtOrderFormController from './court_order_form_controller' | |||
|
|||
import AdditionalExpensesFormController from './additional_expenses_form_controller' |
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.
This you can remove.
app/javascript/controllers/index.js
Outdated
@@ -34,6 +36,7 @@ application.register('autosave', AutosaveController) | |||
application.register('disable-form', DisableFormController) | |||
application.register('dismiss', DismissController) | |||
application.register('court-order-form', CourtOrderFormController) | |||
application.register('additional-expenses-form', AdditionalExpensesFormController) |
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.
Remove as well.
@@ -42,3 +45,4 @@ application.register('select-all', SelectAllController) | |||
application.register('sidebar', SidebarController) | |||
application.register('sidebar-group', SidebarGroupController) | |||
application.register('truncated-text', TruncatedTextController) | |||
application.register('nested-form', NestedForm) |
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.
I wasn't able to access the nested form controller until I added this - not sure if there is a more standard way to do this. I realize the rest of the imports in here are all local
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.
The court_order_form_controller.js
uses it, too. But it loads it directly. This is the right thing to do for your use case.
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.
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.
ah, just saw this, will take those out
<%= form.number_field :other_expense_amount, | ||
placeholder: "0", | ||
class: "form-control other-expense-amount", | ||
min: "0", max: 1000, step: 0.01 %> |
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.
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.
@schoork added number_with_precision to the field, let me know if this display is ok:
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.
This looks great @shacon. One tweak to the way the cost is displayed when editing and good to go!
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.
Looks great @shacon! Thanks for the reminder.
What github issue is this PR for, if any?
Resolves #5773
What changed, and why?
Allows for adding more than 10 additional expenses and allows for deleting additional expenses from the form
Used this stimulus controller for nested form fields as suggested in the ticket: https://www.stimulus-components.com/docs/stimulus-rails-nested-form/
How is this tested? (please write tests!) 💖💪
Edited the capybara tests that existed with the changes to allow for more than 10 additional expenses.
Also added capybara test for the delete functionality.
This pr does add a javascript controller that resets the indexes on the nested fields generated by the stimulus controller. The capybara tests so end up testing this functionality but if it seems like we want specific javascript tests I can take a stab at those.
Screenshots please :)
A note on testing locally - this requires a feature flag to be set and for a config to be set on the related Casa Org. Here's what I ran in the rails console to do this:
Feelings gif (optional)