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

Form serialization does not include values set in web components #5245

Open
Tam opened this issue Apr 27, 2023 · 6 comments
Open

Form serialization does not include values set in web components #5245

Tam opened this issue Apr 27, 2023 · 6 comments
Milestone

Comments

@Tam
Copy link

Tam commented Apr 27, 2023

Description

Web components can set data on a form using setFormValues, but this isn't picked up by jQuery's form serialization.

Link to test case

https://codepen.io/_Tam_/pen/yLRXYxe

@mgol
Copy link
Member

mgol commented Apr 27, 2023

Thanks for the report. jQuery traverses form.elements, reading values from each entry. Unfortunately, for a Web Component, reading the value property won't help.

Is there a way to read submitted form values from a Web Component? I guess no?

We may consider using FormData directly when available in serializeArray but we'll need to make sure all the current tests pass in the Web Component context as well.

If you'd like to take a stab at this, the code is here:

jquery/src/serialize.js

Lines 94 to 127 in 89ef81f

jQuery.fn.extend( {
serialize: function() {
return jQuery.param( this.serializeArray() );
},
serializeArray: function() {
return this.map( function() {
// Can add propHook for "elements" to filter or add form elements
var elements = jQuery.prop( this, "elements" );
return elements ? jQuery.makeArray( elements ) : this;
} ).filter( function() {
var type = this.type;
// Use .is( ":disabled" ) so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !rcheckableType.test( type ) );
} ).map( function( _i, elem ) {
var val = jQuery( this ).val();
if ( val == null ) {
return null;
}
if ( Array.isArray( val ) ) {
return jQuery.map( val, function( val ) {
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
} );
}
return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
} ).get();
}
} );

@mgol mgol added Serialize Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. labels Apr 27, 2023
@dmethvin
Copy link
Member

I think the web component used in the example isn't fully implemented. If there were a value property getter/setter defined it should work. It's the job of the WC implementation to take whatever internal values there are and expose them to make it look like a native element.

@dmethvin
Copy link
Member

More info:

Just tracing the code paths, it seems like .val() will get the value once the getter is defined.

@Tam
Copy link
Author

Tam commented Apr 28, 2023

I've updated the pen to include the additional getters / setters, but it hasn't had any effect on the output: https://codepen.io/_Tam_/pen/jOewRVq

I think the issue comes down to this part of the code filtering out any non-native form elements:

jquery/src/serialize.js

Lines 104 to 111 in 89ef81f

} ).filter( function() {
var type = this.type;
// Use .is( ":disabled" ) so that fieldset[disabled] works
return this.name && !jQuery( this ).is( ":disabled" ) &&
rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
( this.checked || !rcheckableType.test( type ) );
} ).map( function( _i, elem ) {

@dmethvin
Copy link
Member

Yeah I agree, I didn't look far enough down the serialization to see the other roadblocks. I can't find tickets but I'm pretty sure that serializeArray got those guards because people would select a group of elements, some of which weren't form elements, and be upset when they ended up in the serialization just because they had a name or checked property.

In this situation, though, we know for certain that the elements prop has the list we need, including the custom elements. The problem is that we do the filtering further down. I think a solution might involve skipping the extra filtering checks for a collection that came directly from elements.

@timmywil
Copy link
Member

Dave to the rescue! We can look into avoiding filtering for .elements.

@timmywil timmywil removed the Discuss in Meeting Reserved for Issues and PRs that anyone would like to discuss in the weekly meeting. label May 15, 2023
@timmywil timmywil added this to the 4.1.0 milestone May 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

4 participants