{"pageProps":{"locale":{"code":"fr","domain":"frenchstack.fr","lang":"fr-FR","json":{"TRANSLATE":"Traduire en","EN":"Anglais","FR":"Français","NO_TRANSLATION_AVAILABLE":"Aucune traduction disponible","PROFILE_OF":"Profil de","FILTER_BY_TAG":"Filtrer par tag","REMOVE_FILTER":"Supprimer le filtre","RESULT":"Résulat","RESULTS":"Résulats","FORM_CONTACT_SUPPORT":"Support","FORM_CONTACT_SALES":"Devis","FORM_CONTACT_BUGS":"Rapport de bug","FORM_LOADING":"Chargement","FORM_SEND":"Envoyer","FORM_VERIFY":"Vérifier","FORM_NAME":"Nom","FORM_TOPIC":"Sujet","FORM_PHONE":"Téléphone","FORM_EMAIL":"Email","FORM_MESSAGE":"Message","FORM_DOMAIN_PLACEHOLDER":"exemple.fr","FORM_DOMAIN_AVAILABLE":"Félicitations, le domaine <span data-selector='domain'></span> est disponible !","FORM_DOMAIN_TAKEN":"Désolé, le domaine <span data-selector='domain'></span> est pris.","SUBSCRIBE":"S'abonner","SUCCESS_CONTACT":"Votre message a bien été envoyé ! Nous vous répondrons dans les plus brefs délais.","SOMETING_WENT_WRONG":"Oops, une erreur s'est produite. Veuillez réessayer ultérieurement.","PERFORMANCE":"Performance","ACCESSIBILITY":"Accessibilité","BEST_PRACTICES":"Bonnes pratiques","SEO":"Référencement","MOBILE":"Mobile","TABLET":"Tablette","DESKTOP":"Ordinateur","VISITORS":"Visiteurs","ENGAGEMENT":"Engagement","CONVERSIONS":"Conversions","JAN":"Janv","FEB":"Févr","MAR":"Mars","APR":"Avr","MAY":"Mai","JUN":"Juin","JUL":"Juil","AUG":"Août","SEP":"Sept","OCT":"Oct","NOV":"Nov","DEC":"Déc","METHOD_PHONE":"Téléphone","METHOD_EMAIL":"Email"},"subdomains":{"blog":"blog","clients":"references","videos":"videos","services":"services"},"ogSection":"Technologie"},"slugs":["fr","blog","angular"],"component":"paging","articles":[{"id":"content/articles/fr/angular-validation-formulaire-comparer-plusieurs-champs.mdx","heroSection":{"heroTitle":"Comparer plusieurs champs","heroSubtitle":"","heroBadge":"Validation de formulaire Angular","heroColoredWords":"1","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Comment valider deux champs d'un formulaire en faisant une comparaison ?"}]},{"type":"p","children":[{"type":"text","text":"Vérifions plusieurs champs avec un validateur de haut niveau !"}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/angular-form-validation.png","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(180deg, transparent 0%, #0e256ddb 17%, #ff4444db 120%)","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"angular form validation","imageWidth":1344,"imageHeight":768},"seoSection":{"metaTitle":"Validation de formulaire Angular : Comparer plusieurs champs","metaDescription":"Comment valider deux champs d'un formulaire en faisant une comparaison ? Vérifions plusieurs champs avec un validateur de haut niveau !","metaTags":"formulaire, angular, validation, angular-validation","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-07T00:09:54.046Z","localeCode":"fr","slug":"angular-validation-formulaire-comparer-plusieurs-champs","url":"/fr/blog/angular-validation-formulaire-comparer-plusieurs-champs","ogId":"angular-validation-formulaire-comparer-plusieurs-champs-blog-fr","ogImagePath":"/og/angular-validation-formulaire-comparer-plusieurs-champs-blog-fr.png","type":"Article","title":"Comparer plusieurs champs avec Angular","subtitle":"","browserUrl":"","textPreview":{"type":"root","children":[]},"subdomainKey":"blog","subdomain":"blog","logoAlt":"","logoWidth":0,"logoHeight":0,"body":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Supposons que notre formulaire ait des champs de date "},{"type":"text","text":"startDate","code":true},{"type":"text","text":" et "},{"type":"text","text":"endDate","code":true},{"type":"text","text":" et nous voulons nous assurer que "},{"type":"text","text":"startDate","code":true},{"type":"text","text":" doit être avant "},{"type":"text","text":"endDate","code":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Pour implémenter des validations contenant un ou plusieurs contrôles frères, nous devons définir la fonction de validation à un niveau supérieur à celui des contrôles frères."}]},{"type":"mdxJsxFlowElement","name":"codeHeader","children":[{"type":"text","text":""}],"props":{"filePath":"app / src / pages / form-example / form-example.component.ts","fileName":"form-example.component.ts","svgFile":"typescript"}},{"type":"code_block","lang":"typescript","value":"ngOnInit() : void\n{\n  this.formGroup = this.formBuilder.group(\n  {\n    startDate : new FormControl({\n      value    : null,\n      disabled : false\n    }, [ Validators.required ]),\n    endDate : new FormControl({\n      value    : null,\n      disabled : false\n    }, [ Validators.required ]),\n  },\n  // NOTE Validateur de haut niveau\n  { validator : DateValidator.dateRangeValidator });\n}","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"Ensuite, nous définissons un validateur personnalisé dans un fichier séparé, par exemple "},{"type":"text","text":"date.validator.ts","code":true},{"type":"text","text":"."}]},{"type":"mdxJsxFlowElement","name":"codeHeader","children":[{"type":"text","text":""}],"props":{"fileName":"date.validator.ts","filePath":"app / src / shared / validators / date.validator.ts","svgFile":"typescript"}},{"type":"code_block","lang":"typescript","value":"// Angular modules\nimport { Injectable }       from '@angular/core';\nimport { AbstractControl }  from '@angular/forms';\nimport { ValidationErrors } from '@angular/forms';\n\n@Injectable({\n  providedIn : 'root'\n})\nexport class DateValidator\n{\n  constructor() {}\n\n  public static dateRangeValidator(control : AbstractControl) : ValidationErrors | null\n  {\n    // NOTE Contrôle de sécurité\n    if (!control.get('startDate').value || !control.get('endDate').value)\n      return null;\n\n    // NOTE Comparaison de champs\n    // const mStart  = moment(control.get('startDate').value);\n    // const mEnd    = moment(control.get('endDate').value);\n    // const isValid = mStart.isBefore(mEnd);\n\n    // NOTE Invalide\n    if (!isValid)\n      return { invalidDateRange : true };\n\n    // NOTE Valide\n    return null;\n  }\n}","children":[{"type":"text","text":""}]},{"type":"p","children":[{"type":"text","text":"Si invalide, retourne un objet d'erreur (n'importe quel nom arbitraire), comme, "},{"type":"text","text":"return { invalidEndDate: true }","code":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Assurez-vous qu'il renvoie toujours un "},{"type":"text","text":"null","code":true},{"type":"text","text":" pour les cas valides ou non pertinents, et un objet \"non-null\" dans les cas où une erreur doit être déclenchée sur le "},{"type":"text","text":"formGroup","code":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Pour afficher l'erreur au niveau de notre vue, nous utilisons la clé "},{"type":"text","text":"invalidDateRange","code":true},{"type":"text","text":" retournée par notre validateur."}]},{"type":"mdxJsxFlowElement","name":"codeHeader","children":[{"type":"text","text":""}],"props":{"fileName":"form-example.component.html","filePath":"app / src / pages / form-example / form-example.component.html","svgFile":"html"}},{"type":"code_block","lang":"html","value":"<div *ngIf=\"formGroup.hasError('invalidDateRange')\">\n  La date de début n'est pas antérieure à la date de fin\n</div>","children":[{"type":"text","text":""}]}]},"dateCreate":"2021-03-17T10:46:42.000Z","dateUpdate":"2021-09-15T10:57:26.000Z","author":{"id":"content/authors/fr/nicolas-roehm-bettcher.mdx","heroSection":{"heroTitle":"Nicolas Roehm","heroSubtitle":"Ingénieur logiciel","heroBadge":"","heroColoredWords":"","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Fondateur de French Stack, je conçois des solutions informatiques complètes."}]},{"type":"p","children":[{"type":"text","text":"Développeur full-stack, j'interviens principalement sur des projets frontend avec Angular, React ou Vue."}]},{"type":"p","children":[{"type":"text","text":"Passionné de design, voici quelques-unes de mes "},{"type":"a","url":"https://www.artstation.com/nicolas-roehm","title":"ArtStation - Nicolas Roehm","children":[{"type":"text","text":"conceptions graphiques"}]},{"type":"text","text":"."}]},{"type":"mdxJsxFlowElement","name":"socialLinks","children":[{"type":"text","text":""}],"props":{"links":[{"icon":"gitHub","link":"https://github.com/NicolasRoehm"},{"icon":"stackOverflow","link":"https://stackoverflow.com/users/7462178/nicolas-roehm?tab=profile"},{"icon":"linkedIn","link":"https://fr.linkedin.com/in/nicolas-roehm-bettcher"}]}}]},"heroSubtitleIsInline":true,"heroHasBackground":false,"heroImage":"/images/nicolas-roehm-bettcher.png","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(312deg, #0800ff 0%, #4300ff00 70%)","heroMaxWidth":"","heroMs":"25%","heroTitleMb":"0.5rem","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"#fff0","navbarBorderColor":"","navbarLinkActive":"#6785be","navbarLinkHover":"#6785be"},"imageAlt":"nicolas roehm bettcher","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Nicolas Roehm, Ingénieur logiciel","metaDescription":"Passionné d'informatique, je conçois des sites web dans leur intégralité : design, developpement, référencement, e-reputation, e-mailling, hébergement","metaTags":"Nicolas Roehm, Ingénieur logiciel, web, mobile, site internet","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-09T00:38:50.025Z","localeCode":"fr","slug":"nicolas-roehm-bettcher","url":"/fr/nicolas-roehm-bettcher","ogId":"nicolas-roehm-bettcher-fr","ogImagePath":"/og/nicolas-roehm-bettcher-fr.png","type":"Author","title":"Nicolas Roehm-Bettcher","avatar":"/images/nicolas-roehm-avatar.png","lname":"Roehm","fname":"Nicolas","name":"Nicolas Roehm","translations":[{"localeCode":"en","title":"Nicolas Roehm-Bettcher","slug":"nicolas-roehm-bettcher","url":"/en/nicolas-roehm-bettcher"}]},"translations":[{"localeCode":"en","title":"Comparing Multiple Fields with Angular","slug":"angular-form-validation-compare-multiple-fields","url":"/en/blog/angular-form-validation-compare-multiple-fields"}],"tags":[{"id":"content/tags/fr/angular.mdx","localeCode":"fr","title":"Angular","slug":"angular","url":"/fr/blog/angular"}]}],"tag":{"id":"content/tags/fr/angular.mdx","heroSection":{"heroTitle":"Angular","heroSubtitle":"","heroBadge":"","heroColoredWords":"","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Framework d'application Web open source basé sur TypeScript,"}]},{"type":"p","children":[{"type":"text","text":"dirigé par Google et assisté par la communauté."}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/angular.svg","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(140deg, rgba(0,69,145,0.83) 31%, rgb(221,7,49) 100%)","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"angular","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Angular","metaDescription":"Framework d'application web open-source basé sur TypeScript, dirigé par Google et assisté par la communauté","metaTags":"Angular, Typescript, Material, Bootstrap, framework, frontend","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-08T21:25:00.079Z","localeCode":"fr","slug":"angular","url":"/fr/blog/angular","ogId":"angular-blog-fr","ogImagePath":"/og/angular-blog-fr.png","type":"Tag","title":"Angular","subdomainKey":"blog","subdomain":"blog","translations":[{"localeCode":"en","title":"Angular","slug":"angular","url":"/en/blog/angular"}]},"tags":[{"id":"content/tags/fr/angular.mdx","heroSection":{"heroTitle":"Angular","heroSubtitle":"","heroBadge":"","heroColoredWords":"","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Framework d'application Web open source basé sur TypeScript,"}]},{"type":"p","children":[{"type":"text","text":"dirigé par Google et assisté par la communauté."}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/angular.svg","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(140deg, rgba(0,69,145,0.83) 31%, rgb(221,7,49) 100%)","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"angular","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Angular","metaDescription":"Framework d'application web open-source basé sur TypeScript, dirigé par Google et assisté par la communauté","metaTags":"Angular, Typescript, Material, Bootstrap, framework, frontend","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-08T21:25:00.079Z","localeCode":"fr","slug":"angular","url":"/fr/blog/angular","ogId":"angular-blog-fr","ogImagePath":"/og/angular-blog-fr.png","type":"Tag","title":"Angular","subdomainKey":"blog","subdomain":"blog","translations":[{"localeCode":"en","title":"Angular","slug":"angular","url":"/en/blog/angular"}]},{"id":"content/tags/fr/jquery.mdx","heroSection":{"heroTitle":"jQuery","heroSubtitle":"","heroBadge":"","heroColoredWords":"","heroBreakTitle":"","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"jQuery est une librairie Javascript open-source conçue pour simplifier la traversée et la manipulation du DOM HTML mais aussi la gestion d'évenements, les animations CSS ainsi que les requêtes Ajax"}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/jquery-logo.svg","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(140deg, rgba(0,69,145,0) 31%, rgba(0,174,255,100) 100%)","heroMaxWidth":"860px","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"jquery logo","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"jQuery","metaDescription":"jQuery est une librairie Javascript open-source conçue pour simplifier la traversée et la manipulation du DOM HTML, la gestion d'évenements, les animations CSS et les requêtes Ajax","metaTags":"jQuery, Javascript, librairie, DOM HTML","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-08T19:29:58.745Z","localeCode":"fr","slug":"jquery","url":"/fr/blog/jquery","ogId":"jquery-blog-fr","ogImagePath":"/og/jquery-blog-fr.png","type":"Tag","title":"jQuery","subdomainKey":"blog","subdomain":"blog","translations":[{"localeCode":"en","title":"jQuery","slug":"jquery","url":"/en/blog/jquery"}]}],"pages":[0],"curPage":1,"page":{"id":"content/subdomains/fr/blog.mdx","heroSection":{"heroTitle":"Actualités digitales","heroSubtitle":"","heroBadge":"","heroColoredWords":"2","heroBreakTitle":"","heroShape":"shiny","heroGradient":"business-gradient","heroDescription":{"type":"root","children":[{"type":"p","children":[{"type":"text","text":"Explorez les dernières avancées en "},{"type":"text","text":"design web","bold":true},{"type":"text","text":", "},{"type":"text","text":"SEO","bold":true},{"type":"text","text":", "},{"type":"text","text":"marketing digital","bold":true},{"type":"text","text":", "},{"type":"text","text":"développement web","bold":true},{"type":"text","text":" et bien plus."}]},{"type":"p","children":[{"type":"text","text":"Nos articles décryptent les "},{"type":"text","text":"technologies innovantes","bold":true},{"type":"text","text":" et les "},{"type":"text","text":"standards du web","bold":true},{"type":"text","text":" qui façonnent l'"},{"type":"text","text":"avenir du numérique","bold":true},{"type":"text","text":"."}]},{"type":"p","children":[{"type":"text","text":"Restez connecté, suivez-nous sur les "},{"type":"text","text":"réseaux sociaux","bold":true},{"type":"text","text":"."}]}]},"heroSubtitleIsInline":false,"heroHasBackground":false,"heroImage":"/images/blog-news-web.jpg","heroVideoBackground":"","heroStyle":{"heroBg":"linear-gradient(353deg, rgba(255,129,0,0.64) 0%, #0018ffe0 120%)","heroMaxWidth":"","heroMs":"","heroTitleMb":"","heroTitleColor":"","heroContentBg":"","heroContentAlign":"","heroContentBlur":"","heroBlurImage":"","navbarBg":"","navbarBorderColor":"","navbarLinkActive":"","navbarLinkHover":""},"imageAlt":"blog news web","imageWidth":0,"imageHeight":0},"seoSection":{"metaTitle":"Actualité numérique","metaDescription":"Magazine en ligne pour apprendre le Web, trouver des ressources, parcourir les tendances et déguster un café chaud","metaTags":"inspiration web, tutoriels développement web, tendances web","socialImageWidth":0,"socialImageHeight":0},"heroUpdatedAt":"2024-12-12T18:23:51.381Z","localeCode":"fr","slug":"blog","url":"/fr/blog","ogId":"blog-fr","ogImagePath":"/og/blog-fr.png","type":"Subdomain","title":"Blog","subdomainKey":"blog","subdomain":"blog","translations":[{"localeCode":"en","title":"Blog","slug":"blog","url":"/en/blog"}],"canShare":true,"canComment":true,"hasAuthor":true,"tagsInPanel":true,"cardContainer":"col-md-6","cardTemplate":"default"},"global":{"id":"content/global/fr/settings.json","localeCode":"fr","header":{"nav":[{"href":"index","label":"Accueil"},{"href":"blog","label":"Blog"},{"href":"videos","label":"Vidéos"},{"href":"services","label":"Prestations"},{"href":"references","label":"Références"},{"href":"a-propos","label":"À propos"},{"href":"contact","label":"Contact"}]},"footer":{"social":[{"website":"youtube","account":"@french-stack"}],"hasSocial":true,"nav":[{"title":"L'agence","links":[{"href":"references","label":"Références"},{"href":"a-propos","label":"À propos"},{"href":"contact","label":"Contact"}]},{"title":"Prestations","links":[{"href":"services/creation-graphique","label":"Graphisme"},{"href":"services/developpement-web-mobile","label":"Développement"},{"href":"services/marketing-web","label":"Marketing"},{"href":"services/formation-informatique","label":"Formation"}]},{"title":"Blog","links":[{"href":"blog/angular","label":"Angular"},{"href":"blog/jquery","label":"jQuery"}]},{"title":"Vidéos","links":[{"href":"videos/marketing-audiovisuel","label":"Marketing audiovisuel"}]}]},"bottom":{"dateCreate":"2015-12-27T05:55:00.000Z","nav":[{"href":"mentions-legales","label":"Mentions légales"},{"href":"politique-de-confidentialite","label":"Politique de confidentialité"}],"hasLinks":true},"contactInfo":{"contactMethods":[{"id":"email","icon":"envelope","value":"frenchstack@gmail.com"},{"id":"phone","icon":"phone","value":"0651570751"}]}}},"__N_SSG":true}