@@ -577,3 +577,323 @@ test('errors are available to the newly inserted items', async () => {
577577 await flushPromises ( ) ;
578578 expect ( spanAt ( 1 ) . textContent ) . toBeTruthy ( ) ;
579579} ) ;
580+
581+ // #5113
582+ test ( 'push should set the form as touched' , async ( ) => {
583+ let form ! : FormContext ;
584+ let arr ! : FieldArrayContext ;
585+ const InputText = defineComponent ( {
586+ props : { name : { type : String , required : true } } ,
587+ setup ( props ) {
588+ const { value } = useField ( ( ) => props . name ) ;
589+ return { value } ;
590+ } ,
591+ template : '<input v-model="value" />' ,
592+ } ) ;
593+
594+ mountWithHoc ( {
595+ components : { InputText } ,
596+ setup ( ) {
597+ form = useForm < any > ( {
598+ initialValues : {
599+ users : [ 'one' ] ,
600+ } ,
601+ } ) ;
602+
603+ arr = useFieldArray ( 'users' ) ;
604+
605+ return { fields : arr . fields } ;
606+ } ,
607+ template : `
608+ <div>
609+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
610+ </div>
611+ ` ,
612+ } ) ;
613+
614+ await flushPromises ( ) ;
615+ expect ( form . meta . value . touched ) . toBe ( false ) ;
616+ arr . push ( 'two' ) ;
617+ await flushPromises ( ) ;
618+ expect ( form . meta . value . touched ) . toBe ( true ) ;
619+ } ) ;
620+
621+ // #5113
622+ test ( 'remove should set the form as touched' , async ( ) => {
623+ let form ! : FormContext ;
624+ let arr ! : FieldArrayContext ;
625+ const InputText = defineComponent ( {
626+ props : { name : { type : String , required : true } } ,
627+ setup ( props ) {
628+ const { value } = useField ( ( ) => props . name ) ;
629+ return { value } ;
630+ } ,
631+ template : '<input v-model="value" />' ,
632+ } ) ;
633+
634+ mountWithHoc ( {
635+ components : { InputText } ,
636+ setup ( ) {
637+ form = useForm < any > ( {
638+ initialValues : {
639+ users : [ 'one' , 'two' ] ,
640+ } ,
641+ } ) ;
642+
643+ arr = useFieldArray ( 'users' ) ;
644+
645+ return { fields : arr . fields } ;
646+ } ,
647+ template : `
648+ <div>
649+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
650+ </div>
651+ ` ,
652+ } ) ;
653+
654+ await flushPromises ( ) ;
655+ expect ( form . meta . value . touched ) . toBe ( false ) ;
656+ arr . remove ( 0 ) ;
657+ await flushPromises ( ) ;
658+ expect ( form . meta . value . touched ) . toBe ( true ) ;
659+ } ) ;
660+
661+ // #5113
662+ test ( 'insert should set the form as touched' , async ( ) => {
663+ let form ! : FormContext ;
664+ let arr ! : FieldArrayContext ;
665+ const InputText = defineComponent ( {
666+ props : { name : { type : String , required : true } } ,
667+ setup ( props ) {
668+ const { value } = useField ( ( ) => props . name ) ;
669+ return { value } ;
670+ } ,
671+ template : '<input v-model="value" />' ,
672+ } ) ;
673+
674+ mountWithHoc ( {
675+ components : { InputText } ,
676+ setup ( ) {
677+ form = useForm < any > ( {
678+ initialValues : {
679+ users : [ 'one' , 'two' ] ,
680+ } ,
681+ } ) ;
682+
683+ arr = useFieldArray ( 'users' ) ;
684+
685+ return { fields : arr . fields } ;
686+ } ,
687+ template : `
688+ <div>
689+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
690+ </div>
691+ ` ,
692+ } ) ;
693+
694+ await flushPromises ( ) ;
695+ expect ( form . meta . value . touched ) . toBe ( false ) ;
696+ arr . insert ( 1 , 'inserted' ) ;
697+ await flushPromises ( ) ;
698+ expect ( form . meta . value . touched ) . toBe ( true ) ;
699+ } ) ;
700+
701+ // #5113
702+ test ( 'prepend should set the form as touched' , async ( ) => {
703+ let form ! : FormContext ;
704+ let arr ! : FieldArrayContext ;
705+ const InputText = defineComponent ( {
706+ props : { name : { type : String , required : true } } ,
707+ setup ( props ) {
708+ const { value } = useField ( ( ) => props . name ) ;
709+ return { value } ;
710+ } ,
711+ template : '<input v-model="value" />' ,
712+ } ) ;
713+
714+ mountWithHoc ( {
715+ components : { InputText } ,
716+ setup ( ) {
717+ form = useForm < any > ( {
718+ initialValues : {
719+ users : [ 'one' ] ,
720+ } ,
721+ } ) ;
722+
723+ arr = useFieldArray ( 'users' ) ;
724+
725+ return { fields : arr . fields } ;
726+ } ,
727+ template : `
728+ <div>
729+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
730+ </div>
731+ ` ,
732+ } ) ;
733+
734+ await flushPromises ( ) ;
735+ expect ( form . meta . value . touched ) . toBe ( false ) ;
736+ arr . prepend ( 'zero' ) ;
737+ await flushPromises ( ) ;
738+ expect ( form . meta . value . touched ) . toBe ( true ) ;
739+ } ) ;
740+
741+ // #5113
742+ test ( 'swap should set the form as touched' , async ( ) => {
743+ let form ! : FormContext ;
744+ let arr ! : FieldArrayContext ;
745+ const InputText = defineComponent ( {
746+ props : { name : { type : String , required : true } } ,
747+ setup ( props ) {
748+ const { value } = useField ( ( ) => props . name ) ;
749+ return { value } ;
750+ } ,
751+ template : '<input v-model="value" />' ,
752+ } ) ;
753+
754+ mountWithHoc ( {
755+ components : { InputText } ,
756+ setup ( ) {
757+ form = useForm < any > ( {
758+ initialValues : {
759+ users : [ 'one' , 'two' ] ,
760+ } ,
761+ } ) ;
762+
763+ arr = useFieldArray ( 'users' ) ;
764+
765+ return { fields : arr . fields } ;
766+ } ,
767+ template : `
768+ <div>
769+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
770+ </div>
771+ ` ,
772+ } ) ;
773+
774+ await flushPromises ( ) ;
775+ expect ( form . meta . value . touched ) . toBe ( false ) ;
776+ arr . swap ( 0 , 1 ) ;
777+ await flushPromises ( ) ;
778+ expect ( form . meta . value . touched ) . toBe ( true ) ;
779+ } ) ;
780+
781+ // #5113
782+ test ( 'move should set the form as touched' , async ( ) => {
783+ let form ! : FormContext ;
784+ let arr ! : FieldArrayContext ;
785+ const InputText = defineComponent ( {
786+ props : { name : { type : String , required : true } } ,
787+ setup ( props ) {
788+ const { value } = useField ( ( ) => props . name ) ;
789+ return { value } ;
790+ } ,
791+ template : '<input v-model="value" />' ,
792+ } ) ;
793+
794+ mountWithHoc ( {
795+ components : { InputText } ,
796+ setup ( ) {
797+ form = useForm < any > ( {
798+ initialValues : {
799+ users : [ 'one' , 'two' , 'three' ] ,
800+ } ,
801+ } ) ;
802+
803+ arr = useFieldArray ( 'users' ) ;
804+
805+ return { fields : arr . fields } ;
806+ } ,
807+ template : `
808+ <div>
809+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
810+ </div>
811+ ` ,
812+ } ) ;
813+
814+ await flushPromises ( ) ;
815+ expect ( form . meta . value . touched ) . toBe ( false ) ;
816+ arr . move ( 0 , 2 ) ;
817+ await flushPromises ( ) ;
818+ expect ( form . meta . value . touched ) . toBe ( true ) ;
819+ } ) ;
820+
821+ // #5113
822+ test ( 'replace should set the form as touched' , async ( ) => {
823+ let form ! : FormContext ;
824+ let arr ! : FieldArrayContext ;
825+ const InputText = defineComponent ( {
826+ props : { name : { type : String , required : true } } ,
827+ setup ( props ) {
828+ const { value } = useField ( ( ) => props . name ) ;
829+ return { value } ;
830+ } ,
831+ template : '<input v-model="value" />' ,
832+ } ) ;
833+
834+ mountWithHoc ( {
835+ components : { InputText } ,
836+ setup ( ) {
837+ form = useForm < any > ( {
838+ initialValues : {
839+ users : [ 'one' ] ,
840+ } ,
841+ } ) ;
842+
843+ arr = useFieldArray ( 'users' ) ;
844+
845+ return { fields : arr . fields } ;
846+ } ,
847+ template : `
848+ <div>
849+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
850+ </div>
851+ ` ,
852+ } ) ;
853+
854+ await flushPromises ( ) ;
855+ expect ( form . meta . value . touched ) . toBe ( false ) ;
856+ arr . replace ( [ 'a' , 'b' ] ) ;
857+ await flushPromises ( ) ;
858+ expect ( form . meta . value . touched ) . toBe ( true ) ;
859+ } ) ;
860+
861+ // #5113
862+ test ( 'update should set the form as touched' , async ( ) => {
863+ let form ! : FormContext ;
864+ let arr ! : FieldArrayContext ;
865+ const InputText = defineComponent ( {
866+ props : { name : { type : String , required : true } } ,
867+ setup ( props ) {
868+ const { value } = useField ( ( ) => props . name ) ;
869+ return { value } ;
870+ } ,
871+ template : '<input v-model="value" />' ,
872+ } ) ;
873+
874+ mountWithHoc ( {
875+ components : { InputText } ,
876+ setup ( ) {
877+ form = useForm < any > ( {
878+ initialValues : {
879+ users : [ 'one' ] ,
880+ } ,
881+ } ) ;
882+
883+ arr = useFieldArray ( 'users' ) ;
884+
885+ return { fields : arr . fields } ;
886+ } ,
887+ template : `
888+ <div>
889+ <InputText v-for="(field, idx) in fields" :key="field.key" :name="'users[' + idx + ']'" />
890+ </div>
891+ ` ,
892+ } ) ;
893+
894+ await flushPromises ( ) ;
895+ expect ( form . meta . value . touched ) . toBe ( false ) ;
896+ arr . update ( 0 , 'updated' ) ;
897+ await flushPromises ( ) ;
898+ expect ( form . meta . value . touched ) . toBe ( true ) ;
899+ } ) ;
0 commit comments