Skip to content
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

Phase and funding forms on one page #156

Closed
smcalilly opened this issue Mar 29, 2022 · 14 comments · Fixed by #244
Closed

Phase and funding forms on one page #156

smcalilly opened this issue Mar 29, 2022 · 14 comments · Fixed by #244
Assignees
Labels
enhancement New feature or request

Comments

@smcalilly
Copy link
Contributor

No description provided.

@smcalilly
Copy link
Contributor Author

@xmedr is going to wireframe this so we can share with clients and get feedback, then we'll implement this.

@smcalilly
Copy link
Contributor Author

@xmedr when wireframing, be sure to allow one or more funding sources to be added.

@xmedr
Copy link
Collaborator

xmedr commented May 9, 2023

@smcalilly Ah heard, so the potential to add more than one funding source at a time, gotcha.

@xmedr
Copy link
Collaborator

xmedr commented May 9, 2023

@smcalilly Here's a first draft

The note next to "Add another source" just says that clicking that could add another row to allow for multiple funding sources to be added at once.

image

@smcalilly
Copy link
Contributor Author

smcalilly commented May 9, 2023

@xmedr that looks nice. i added a comment on the moqup.

one thing to think about: how would the form submission work from a code point of view, specifically the backend view? the html form is setup to submit a post request to the phase view. adding another "save funding" button would require a new endpoint. submitting two separate forms on one html page is kind of a confusing pattern.

with that in mind, would it be possible to combine the two forms so they're submitted to the same endpoint? this would let us simply the UI and only have one "save" button. django inline forms kind of solve this. here's an example (with a rough ui): https://medium.com/@adandan01/django-inline-formsets-example-mybook-420cc4b6225d they simplify the form submission with one button.

@smcalilly
Copy link
Contributor Author

smcalilly commented May 9, 2023

submitting two separate forms on one html page is kind of a confusing pattern.

in other words:

clicking "save phase" sends a post request to the projects/phases/edit/<int:pk>/ url. clicking "save funding" sends a post request to the projects/phases/<int:pk>/funding/update/. it would be nice to consolidate those to a single url since they're on the same page.

just something to keep in mind. this could get complicated but maybe i'm overthinking it?

also, we might need some javascript to render the the phase funding forms as a user clicks "add another source". which adds to the complexity.

@xmedr
Copy link
Collaborator

xmedr commented May 10, 2023

@smcalilly Got a version 2 up. Notable changes are that the button at the top right changed to "Save All Changes" from "Save Phase", and the add funding box got merged with the funding list box. Also responded to your comment about the edit button

image

So with one "save all" button, I'm hoping that this starts to get us towards having just one url for the update. And it looks like the article you sent has an example of them using some javascript to add a new row, so maybe we can borrow from that when the time comes.

@xmedr
Copy link
Collaborator

xmedr commented May 11, 2023

@smcalilly I've got a couple ideas I wanted to get some feedback on about how we can get those multiple FundingStreamForms to submit.

1) Using Javascript to submit separate forms

Reading through this SO answer, maybe we could render each FundingStreamForm as a separate <form> element, and add a JS onlick() to the Save All Changes button that takes every form on the page and submits them as individual forms. The answer even talks about using that JS to allow the user to make as many forms as they want.

This feels like an okay approach so far, but I haven't tried this out yet.

2) Grouping form sets through unique names

This was my initial thought, but it's more convoluted and I'm not sure it would work. Like we talked about, within the PhaseForm, we can have a funding_stream field containing the FundingStreamForm, and use a loop in the template to make a few funding forms. (This example doesn't consider dynamically setting the number of forms, so for simplicity's sake we'll say 3 instances.)

If it's possible, we might be able to make these forms in such a way that each input's name can have a suffix with a number. Something like name="{{field.name}}_{{i}}" equating to year_0, year_1, and year_2

 {% for i in range %}  # let's say range goes from 0 to 2 for three instances
   <div class="row">
   {% for field in form.funding_streams %}
     <div class="col-md-2">
       <input name="{{field.name}}_{{i}}" type=(field-type-accessor) value=(field-value-accessor) .... />
     </div>
   {% endfor %}
   </div>
 {% endfor %}

Then in the view, we might be able to use the suffix numbers for each field to both group submitted fields into FundingStreamForms and instantiate as many of those forms as needed.

An issue with this are that I haven't yet been able to successfully recreate the input with all it's necessary attributes.

@smcalilly
Copy link
Contributor Author

@xmedr these are some good ideas - thanks for sharing.

Yeah we can definitely do all of this in javascript. I was trying to keep things in django form-land but you're right that we could get away with submitting them via an api.

With number two, you might could render those inputs with javascript rather than the Django templating language. And then you can capture the entire form input in the PhaseUpdateView, including the inputs you rendered in javascript. So you'd basically use the FundingStreamForm in the view only to capture/validate the data.

One thing you'll need to consider either way — if the update view has any existing funding streams, you'll need to serve those up as inputs in the django template. So with either approach, you'll have to render in the template any instances of the FundingStreamForm (which are hydrated with the funding stream's data so you'll need the instance's id/pk), plus be able to add new inputs with javascript.

So I guess either way you'll need to generate the form inputs in javascript, and the question is whether to submit them via api (option 1) or with the phase form (option 2).

@smcalilly
Copy link
Contributor Author

@xmedr thinking more about your javascript proposal, if you went that route, it would probably be best to submit the form after each funding stream is "added" (after a click event that submits the payload to the api), rather than submitting them all at once whenever the user clicks the main "save phase" button.

have you had more time to think about either of the options? i'm wondering what you're leaning towards.

@xmedr
Copy link
Collaborator

xmedr commented May 12, 2023

@smcalilly hm, i was leaning towards exploring the javascript focused option. and i might absolutely be misunderstanding, but would this essentially bring us back to filling out the form and clicking something other than the "save phase" button (so a button that's just for funding submission) to submit funding streams one by one, as opposed to making a few at a time and saving everything together?

because if that's the case, then i imagine we don't need to worry about the forms being sent to the PhaseForm's funding_streams list, and we can instead just instantiate FundingStreamForms in the PhaseUpdateView each time those single forms get submitted, right? let me know if that made sense haha, but that would be a lot easier than what we're trying.

also i was thinking, as long as we're allowing for preexisting funding streams to always appear as editable fields, how would we update/delete them? is there something about a hydrated django form that allows you to reference the primary key for the object that it comes from?
Edit: i was able to just add the form's fundingstream id to the context and added that to the delete button, so now those can be deleted individually at least

@xmedr
Copy link
Collaborator

xmedr commented May 12, 2023

@smcalilly and on an simpler note, thankfully getting existing funding streams into editable fields and also getting js to add more rows to the dom for new sources wasn't difficult at all!

add_sources

@xmedr
Copy link
Collaborator

xmedr commented Jun 27, 2023

I'll be picking this back up!

@jim-z Just some questions in regards to you mentioning alerting users when they haven't filled out some fields on the phase edit page. Were you thinking:

  • Informing users navigating away from the edit page that they haven't added funding sources?
  • Or making that mandatory upon creating a phase? (I'm not sure if in your process you folks can have a phase without funding, but as of right now in this app that can exist)
  • Or something else entirely?

@jim-z
Copy link

jim-z commented Jun 27, 2023

If it's an easy add, I think just a note informing users that they haven't added funding sources when navigating away would suffice. There are instances when phases are added without funding secured/known so wouldn't want to make it mandatory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants