-
-
Notifications
You must be signed in to change notification settings - Fork 7
fix: formdata is not updating when options populated dynamically #419
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
base: main
Are you sure you want to change the base?
Conversation
|
|
|
So you're having problem with the form data when using lazy loading? The code looks fine except that you're not actually lazy loading anything in that demo. Did you see the new Lazy Loading - Example that I added recently? I never use form data myself (I typically use |
|
Oh, sorry for bad explanation. I've found the issue I when tried to lazy-load data, but later found a simple scenario that represents it. This scenario is in my test example. By 'dynamically' I mean just passing In my thoughts, there is solution that will fix my scenario, lazy-loaded options update and, possibly, refreshOptions({ data: newData} ). But I'm afraid of some architectural tricks in lib that prevent it. I'm in progress with codebase investigations 🙃 Of course it's not a problem to check inputs right before auto-submission, detect multiple-select-vanilla'd inputs and use custom js for them. But I think it would be better to keep consistency with web platform and native browser js features. |
|
hi, @ghiscoding |
| // when multiple values could be set, we need to loop through each | ||
| Array.from(this.elm.options).forEach(option => { | ||
| option.selected = selectedValues.some(val => val === option.value); | ||
| option.selected = selectedValues.some(val => val.toString() === option.value); |
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 don't think this is correct, why are you doing this? It's probably causing some of the test failures.
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.
as I understand, when I try to get value from option tag it's always a string
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.
yes you're right, but I wonder what are the test failures? I didn't try it locally so it's hard to know, but if you roll back this change, does that remove any of the test failures?
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.
yes, it was all green before I started.I expect some of them might be fixed in spec files, but have to check carefully
|
I don't understand why you're adding a new function when there should already be code to do this, for example this code to add all rows multiple-select-vanilla/packages/multiple-select-vanilla/src/MultipleSelectInstance.ts Lines 580 to 583 in 85027e2
So why are you adding a new function? We should be able to reuse the code that already exists and creating a list from an HTML Select is nothing new, the first few examples are using that technique. So I don't understand why you're adding a new function and I would rather use and modify what already exists in the library, that is mainly to avoid making the library larger. |
|
I've added new function because I didn't see these. Thanks for sharing, I will update my changes. |
Yeah I even don't remember all of the code myself haha, just let me know if you need more assistance in trying to understand some part. The main reason for this function |
|
@caulfield did you need further help on this PR? I still don't fully understand the problem and the example that you modified doesn't seem to use any lazy loading which is why I don't quite understand the problem |
|
Hi. Yes. Sorry, there was a lot of other work to do. I will provide more examples to explain the issue |
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.
Pull Request Overview
This PR fixes a bug where FormData values were not updating when select options were populated dynamically via the data property or lazy loading. The fix ensures that when options are created programmatically (not from HTML), the underlying select element's DOM structure is properly initialized, allowing FormData to correctly capture selected values.
Key Changes:
- Added DOM structure initialization for dynamically populated select elements
- Fixed value comparison logic to handle numeric values correctly
- Added comprehensive test coverage for FormData with both single and multiple selects
Reviewed Changes
Copilot reviewed 8 out of 9 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/multiple-select-vanilla/src/utils/domUtils.ts | Added createDomStructureFromData function to build DOM elements from data objects |
| packages/multiple-select-vanilla/src/MultipleSelectInstance.ts | Added initHtmlRows method and logic to initialize DOM when options are from data, plus fixed value comparison |
| playwright/e2e/example08.spec.ts | Added tests verifying FormData updates for single and multiple selects |
| playwright/e2e/example07.spec.ts | Added test for lazy-loaded select FormData submission |
| packages/demo/src/examples/example08.ts | Added demo instances for FormData testing |
| packages/demo/src/examples/example08.html | Added HTML forms for FormData testing |
| packages/demo/src/examples/example07.ts | Added lazy-loaded select instance |
| packages/demo/src/examples/example07.html | Added HTML for lazy-loaded select and updated selectors |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
|
Hi, @ghiscoding , sorry for the big delay |
|
ok cool thanks, I will review it further this evening after work. It's nice to see that all E2E tests Will that change fix all your issues? |
|
note that I committed 1 copilot suggestion, but it might be worst, so it might be a good idea to rollback this commit 57aabc2 |
|
thanks
about copilot commit - I would try to rollback it at first. It felt strange for me too. |
the copilot is because we don't typically add wait timeout in Playwright (I often do that in Cypress but never with Playwright). I saw you have a |
playwright/e2e/example07.spec.ts
Outdated
| }); | ||
|
|
||
| await page.goto('#/example07'); | ||
| await page.waitForSelector('[data-test=select3] .ms-options .ms-option span:text("First")'); |
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 can remove this line, it's totally not needed, you previously had await page.waitForTimeout(1); but again that's not needed at all when using Playwright because we should always use async/wait in Playwright tests. It passes fine for me locally without this line
| // when multiple values could be set, we need to loop through each | ||
| Array.from(this.elm.options).forEach(option => { | ||
| option.selected = selectedValues.some(val => val === option.value); | ||
| option.selected = selectedValues.some(val => val.toString() === option.value); |
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.
please rollback this .toString() change, that is what make some tests fail.
|
can you do a git force push to rebase the PR, because as it is now it's really hard to see what changed when the PR includes all my own recent changes. git rebase origin/main
# fix any conflict if any
# add all git changes
git add .
git push origin HEAD --forceAlso by trying it out locally, I see that you are calling your new function that you created via if (!this.fromHtml) {
this.initHtmlRows();
}but I don't really like this, if I add a console log to see when it executes and then I open Example 10 (Large Select - Virtual Scroll) in the browser, it does print to the console which mean that it renders the select drop twice (1x by the previoud code So I'd like to know again, what are you trying to fix? Could you describe a bit more the problem you are trying to fix? |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
6ad7fb5 to
6254d76
Compare
This reverts commit 6254d76.
sure, if you comment out my rendering from
|
So if I understand correctly, you added some lazy loaded data to Example07-08 and some test that are expected to work but fail without changes? So you're trying to fix an issue with the lazy load feature, however your change is affecting nearly all examples (i.e. Example10) and with your change it's loading the data twice (which is what I mentioned in my previous comment). With that in mind, let me take a look at after my working hours and there's probably an easier fix for that. I don't think that the new Util function you added is necessary but I can't be sure until I spend a bit more time on it. At least now you provided some tests that are failing without any changes, and the goal is to make these tests pass. So at least now I have a way to reproduce the bug (your new tests), and I can work with that
thanks for referencing previous comment, I kind of forgot since it's been a while, however I still don't want to accept this change since it does make at least 1 test fail and I think this change is probably unrelated to your issue, so let's not mix too many things and rollback this change please |
|
ok after trying it locally, I'm starting to understand what the issue is, so the reason that the first 2 selects from Example07 work as form data is simply because that example has multiple-select-vanilla/packages/demo/src/examples/example07.html Lines 32 to 37 in 7b8e914
If however you're providing the options through the |
| optionProps.className = row.classes; | ||
| } | ||
| const option = createDomElement('option', optionProps, parent); | ||
| option.textContent = (row as OptionRowData).text; |
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 entire else section could be simplified and replaced with
createDomElement(
'option',
{
value: row.value?.toString() || '',
disabled: row.disabled || false,
selected: !!(row.selected || false),
className: row.classes || '',
textContent: (row as OptionRowData).text,
},
parent,
);|
@caulfield did you need more help to finish this PR? I would be accepting the PR if you make the changes I mentioned in my last 2 comments. Let me know if you need more help. Cheers |
|
@ghiscoding thanks for it. I will push updates soon. I'm going to create new section in documentation for new option and restructure old sections I've updated here. |
Hi, thank you for your package, we use it in our work routine 👍
I found a bug when tried to lazy-load data to my control. We use automated way of submitting our forms and selected values were ignored. I reproduce an issue without lazy-load, even only using
dataoption from javascript.This is a draft pr with tests only (failed ofc). I continue my work on it tomorrow. Are you okay with that code? Maybe you have some suggestions where I can find the reason..
Thanks in advance