forms.js 243 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780
  1. /**
  2. * @license Angular v8.1.0
  3. * (c) 2010-2019 Google LLC. https://angular.io/
  4. * License: MIT
  5. */
  6. import { InjectionToken, forwardRef, Directive, Renderer2, ElementRef, Optional, Inject, Self, ɵisPromise, ɵisObservable, Injectable, Injector, Input, ɵlooseIdentical, Host, isDevMode, EventEmitter, SkipSelf, Output, NgModule, Version } from '@angular/core';
  7. import { ɵgetDOM } from '@angular/platform-browser';
  8. import { forkJoin, from } from 'rxjs';
  9. import { map } from 'rxjs/operators';
  10. /**
  11. * @fileoverview added by tsickle
  12. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  13. */
  14. /**
  15. * Used to provide a `ControlValueAccessor` for form controls.
  16. *
  17. * See `DefaultValueAccessor` for how to implement one.
  18. *
  19. * \@publicApi
  20. * @type {?}
  21. */
  22. const NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor');
  23. /**
  24. * @fileoverview added by tsickle
  25. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  26. */
  27. /** @type {?} */
  28. const CHECKBOX_VALUE_ACCESSOR = {
  29. provide: NG_VALUE_ACCESSOR,
  30. useExisting: forwardRef((/**
  31. * @return {?}
  32. */
  33. () => CheckboxControlValueAccessor)),
  34. multi: true,
  35. };
  36. /**
  37. * \@description
  38. * A `ControlValueAccessor` for writing a value and listening to changes on a checkbox input
  39. * element.
  40. *
  41. * \@usageNotes
  42. *
  43. * ### Using a checkbox with a reactive form.
  44. *
  45. * The following example shows how to use a checkbox with a reactive form.
  46. *
  47. * ```ts
  48. * const rememberLoginControl = new FormControl();
  49. * ```
  50. *
  51. * ```
  52. * <input type="checkbox" [formControl]="rememberLoginControl">
  53. * ```
  54. *
  55. * \@ngModule ReactiveFormsModule
  56. * \@ngModule FormsModule
  57. * \@publicApi
  58. */
  59. class CheckboxControlValueAccessor {
  60. /**
  61. * @param {?} _renderer
  62. * @param {?} _elementRef
  63. */
  64. constructor(_renderer, _elementRef) {
  65. this._renderer = _renderer;
  66. this._elementRef = _elementRef;
  67. /**
  68. * \@description
  69. * The registered callback function called when a change event occurs on the input element.
  70. */
  71. this.onChange = (/**
  72. * @param {?} _
  73. * @return {?}
  74. */
  75. (_) => { });
  76. /**
  77. * \@description
  78. * The registered callback function called when a blur event occurs on the input element.
  79. */
  80. this.onTouched = (/**
  81. * @return {?}
  82. */
  83. () => { });
  84. }
  85. /**
  86. * Sets the "checked" property on the input element.
  87. *
  88. * @param {?} value The checked value
  89. * @return {?}
  90. */
  91. writeValue(value) {
  92. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value);
  93. }
  94. /**
  95. * \@description
  96. * Registers a function called when the control value changes.
  97. *
  98. * @param {?} fn The callback function
  99. * @return {?}
  100. */
  101. registerOnChange(fn) { this.onChange = fn; }
  102. /**
  103. * \@description
  104. * Registers a function called when the control is touched.
  105. *
  106. * @param {?} fn The callback function
  107. * @return {?}
  108. */
  109. registerOnTouched(fn) { this.onTouched = fn; }
  110. /**
  111. * Sets the "disabled" property on the input element.
  112. *
  113. * @param {?} isDisabled The disabled value
  114. * @return {?}
  115. */
  116. setDisabledState(isDisabled) {
  117. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  118. }
  119. }
  120. CheckboxControlValueAccessor.decorators = [
  121. { type: Directive, args: [{
  122. selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
  123. host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' },
  124. providers: [CHECKBOX_VALUE_ACCESSOR]
  125. },] }
  126. ];
  127. /** @nocollapse */
  128. CheckboxControlValueAccessor.ctorParameters = () => [
  129. { type: Renderer2 },
  130. { type: ElementRef }
  131. ];
  132. /**
  133. * @fileoverview added by tsickle
  134. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  135. */
  136. /** @type {?} */
  137. const DEFAULT_VALUE_ACCESSOR = {
  138. provide: NG_VALUE_ACCESSOR,
  139. useExisting: forwardRef((/**
  140. * @return {?}
  141. */
  142. () => DefaultValueAccessor)),
  143. multi: true
  144. };
  145. /**
  146. * We must check whether the agent is Android because composition events
  147. * behave differently between iOS and Android.
  148. * @return {?}
  149. */
  150. function _isAndroid() {
  151. /** @type {?} */
  152. const userAgent = ɵgetDOM() ? ɵgetDOM().getUserAgent() : '';
  153. return /android (\d+)/.test(userAgent.toLowerCase());
  154. }
  155. /**
  156. * \@description
  157. * Provide this token to control if form directives buffer IME input until
  158. * the "compositionend" event occurs.
  159. * \@publicApi
  160. * @type {?}
  161. */
  162. const COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode');
  163. /**
  164. * \@description
  165. * The default `ControlValueAccessor` for writing a value and listening to changes on input
  166. * elements. The accessor is used by the `FormControlDirective`, `FormControlName`, and
  167. * `NgModel` directives.
  168. *
  169. * \@usageNotes
  170. *
  171. * ### Using the default value accessor
  172. *
  173. * The following example shows how to use an input element that activates the default value accessor
  174. * (in this case, a text field).
  175. *
  176. * ```ts
  177. * const firstNameControl = new FormControl();
  178. * ```
  179. *
  180. * ```
  181. * <input type="text" [formControl]="firstNameControl">
  182. * ```
  183. *
  184. * \@ngModule ReactiveFormsModule
  185. * \@ngModule FormsModule
  186. * \@publicApi
  187. */
  188. class DefaultValueAccessor {
  189. /**
  190. * @param {?} _renderer
  191. * @param {?} _elementRef
  192. * @param {?} _compositionMode
  193. */
  194. constructor(_renderer, _elementRef, _compositionMode) {
  195. this._renderer = _renderer;
  196. this._elementRef = _elementRef;
  197. this._compositionMode = _compositionMode;
  198. /**
  199. * \@description
  200. * The registered callback function called when an input event occurs on the input element.
  201. */
  202. this.onChange = (/**
  203. * @param {?} _
  204. * @return {?}
  205. */
  206. (_) => { });
  207. /**
  208. * \@description
  209. * The registered callback function called when a blur event occurs on the input element.
  210. */
  211. this.onTouched = (/**
  212. * @return {?}
  213. */
  214. () => { });
  215. /**
  216. * Whether the user is creating a composition string (IME events).
  217. */
  218. this._composing = false;
  219. if (this._compositionMode == null) {
  220. this._compositionMode = !_isAndroid();
  221. }
  222. }
  223. /**
  224. * Sets the "value" property on the input element.
  225. *
  226. * @param {?} value The checked value
  227. * @return {?}
  228. */
  229. writeValue(value) {
  230. /** @type {?} */
  231. const normalizedValue = value == null ? '' : value;
  232. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  233. }
  234. /**
  235. * \@description
  236. * Registers a function called when the control value changes.
  237. *
  238. * @param {?} fn The callback function
  239. * @return {?}
  240. */
  241. registerOnChange(fn) { this.onChange = fn; }
  242. /**
  243. * \@description
  244. * Registers a function called when the control is touched.
  245. *
  246. * @param {?} fn The callback function
  247. * @return {?}
  248. */
  249. registerOnTouched(fn) { this.onTouched = fn; }
  250. /**
  251. * Sets the "disabled" property on the input element.
  252. *
  253. * @param {?} isDisabled The disabled value
  254. * @return {?}
  255. */
  256. setDisabledState(isDisabled) {
  257. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  258. }
  259. /**
  260. * \@internal
  261. * @param {?} value
  262. * @return {?}
  263. */
  264. _handleInput(value) {
  265. if (!this._compositionMode || (this._compositionMode && !this._composing)) {
  266. this.onChange(value);
  267. }
  268. }
  269. /**
  270. * \@internal
  271. * @return {?}
  272. */
  273. _compositionStart() { this._composing = true; }
  274. /**
  275. * \@internal
  276. * @param {?} value
  277. * @return {?}
  278. */
  279. _compositionEnd(value) {
  280. this._composing = false;
  281. this._compositionMode && this.onChange(value);
  282. }
  283. }
  284. DefaultValueAccessor.decorators = [
  285. { type: Directive, args: [{
  286. selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
  287. // TODO: vsavkin replace the above selector with the one below it once
  288. // https://github.com/angular/angular/issues/3011 is implemented
  289. // selector: '[ngModel],[formControl],[formControlName]',
  290. host: {
  291. '(input)': '$any(this)._handleInput($event.target.value)',
  292. '(blur)': 'onTouched()',
  293. '(compositionstart)': '$any(this)._compositionStart()',
  294. '(compositionend)': '$any(this)._compositionEnd($event.target.value)'
  295. },
  296. providers: [DEFAULT_VALUE_ACCESSOR]
  297. },] }
  298. ];
  299. /** @nocollapse */
  300. DefaultValueAccessor.ctorParameters = () => [
  301. { type: Renderer2 },
  302. { type: ElementRef },
  303. { type: Boolean, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] }] }
  304. ];
  305. /**
  306. * @fileoverview added by tsickle
  307. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  308. */
  309. /**
  310. * @license
  311. * Copyright Google Inc. All Rights Reserved.
  312. *
  313. * Use of this source code is governed by an MIT-style license that can be
  314. * found in the LICENSE file at https://angular.io/license
  315. */
  316. /**
  317. * \@description
  318. * Base class for control directives.
  319. *
  320. * This class is only used internally in the `ReactiveFormsModule` and the `FormsModule`.
  321. *
  322. * \@publicApi
  323. * @abstract
  324. */
  325. class AbstractControlDirective {
  326. /**
  327. * \@description
  328. * Reports the value of the control if it is present, otherwise null.
  329. * @return {?}
  330. */
  331. get value() { return this.control ? this.control.value : null; }
  332. /**
  333. * \@description
  334. * Reports whether the control is valid. A control is considered valid if no
  335. * validation errors exist with the current value.
  336. * If the control is not present, null is returned.
  337. * @return {?}
  338. */
  339. get valid() { return this.control ? this.control.valid : null; }
  340. /**
  341. * \@description
  342. * Reports whether the control is invalid, meaning that an error exists in the input value.
  343. * If the control is not present, null is returned.
  344. * @return {?}
  345. */
  346. get invalid() { return this.control ? this.control.invalid : null; }
  347. /**
  348. * \@description
  349. * Reports whether a control is pending, meaning that that async validation is occurring and
  350. * errors are not yet available for the input value. If the control is not present, null is
  351. * returned.
  352. * @return {?}
  353. */
  354. get pending() { return this.control ? this.control.pending : null; }
  355. /**
  356. * \@description
  357. * Reports whether the control is disabled, meaning that the control is disabled
  358. * in the UI and is exempt from validation checks and excluded from aggregate
  359. * values of ancestor controls. If the control is not present, null is returned.
  360. * @return {?}
  361. */
  362. get disabled() { return this.control ? this.control.disabled : null; }
  363. /**
  364. * \@description
  365. * Reports whether the control is enabled, meaning that the control is included in ancestor
  366. * calculations of validity or value. If the control is not present, null is returned.
  367. * @return {?}
  368. */
  369. get enabled() { return this.control ? this.control.enabled : null; }
  370. /**
  371. * \@description
  372. * Reports the control's validation errors. If the control is not present, null is returned.
  373. * @return {?}
  374. */
  375. get errors() { return this.control ? this.control.errors : null; }
  376. /**
  377. * \@description
  378. * Reports whether the control is pristine, meaning that the user has not yet changed
  379. * the value in the UI. If the control is not present, null is returned.
  380. * @return {?}
  381. */
  382. get pristine() { return this.control ? this.control.pristine : null; }
  383. /**
  384. * \@description
  385. * Reports whether the control is dirty, meaning that the user has changed
  386. * the value in the UI. If the control is not present, null is returned.
  387. * @return {?}
  388. */
  389. get dirty() { return this.control ? this.control.dirty : null; }
  390. /**
  391. * \@description
  392. * Reports whether the control is touched, meaning that the user has triggered
  393. * a `blur` event on it. If the control is not present, null is returned.
  394. * @return {?}
  395. */
  396. get touched() { return this.control ? this.control.touched : null; }
  397. /**
  398. * \@description
  399. * Reports the validation status of the control. Possible values include:
  400. * 'VALID', 'INVALID', 'DISABLED', and 'PENDING'.
  401. * If the control is not present, null is returned.
  402. * @return {?}
  403. */
  404. get status() { return this.control ? this.control.status : null; }
  405. /**
  406. * \@description
  407. * Reports whether the control is untouched, meaning that the user has not yet triggered
  408. * a `blur` event on it. If the control is not present, null is returned.
  409. * @return {?}
  410. */
  411. get untouched() { return this.control ? this.control.untouched : null; }
  412. /**
  413. * \@description
  414. * Returns a multicasting observable that emits a validation status whenever it is
  415. * calculated for the control. If the control is not present, null is returned.
  416. * @return {?}
  417. */
  418. get statusChanges() {
  419. return this.control ? this.control.statusChanges : null;
  420. }
  421. /**
  422. * \@description
  423. * Returns a multicasting observable of value changes for the control that emits every time the
  424. * value of the control changes in the UI or programmatically.
  425. * If the control is not present, null is returned.
  426. * @return {?}
  427. */
  428. get valueChanges() {
  429. return this.control ? this.control.valueChanges : null;
  430. }
  431. /**
  432. * \@description
  433. * Returns an array that represents the path from the top-level form to this control.
  434. * Each index is the string name of the control on that level.
  435. * @return {?}
  436. */
  437. get path() { return null; }
  438. /**
  439. * \@description
  440. * Resets the control with the provided value if the control is present.
  441. * @param {?=} value
  442. * @return {?}
  443. */
  444. reset(value = undefined) {
  445. if (this.control)
  446. this.control.reset(value);
  447. }
  448. /**
  449. * \@description
  450. * Reports whether the control with the given path has the error specified.
  451. *
  452. * \@usageNotes
  453. * For example, for the following `FormGroup`:
  454. *
  455. * ```
  456. * form = new FormGroup({
  457. * address: new FormGroup({ street: new FormControl() })
  458. * });
  459. * ```
  460. *
  461. * The path to the 'street' control from the root form would be 'address' -> 'street'.
  462. *
  463. * It can be provided to this method in one of two formats:
  464. *
  465. * 1. An array of string control names, e.g. `['address', 'street']`
  466. * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
  467. *
  468. * If no path is given, this method checks for the error on the current control.
  469. *
  470. * @param {?} errorCode The code of the error to check
  471. * @param {?=} path A list of control names that designates how to move from the current control
  472. * to the control that should be queried for errors.
  473. *
  474. * @return {?} whether the given error is present in the control at the given path.
  475. *
  476. * If the control is not present, false is returned.
  477. */
  478. hasError(errorCode, path) {
  479. return this.control ? this.control.hasError(errorCode, path) : false;
  480. }
  481. /**
  482. * \@description
  483. * Reports error data for the control with the given path.
  484. *
  485. * \@usageNotes
  486. * For example, for the following `FormGroup`:
  487. *
  488. * ```
  489. * form = new FormGroup({
  490. * address: new FormGroup({ street: new FormControl() })
  491. * });
  492. * ```
  493. *
  494. * The path to the 'street' control from the root form would be 'address' -> 'street'.
  495. *
  496. * It can be provided to this method in one of two formats:
  497. *
  498. * 1. An array of string control names, e.g. `['address', 'street']`
  499. * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
  500. *
  501. * @param {?} errorCode The code of the error to check
  502. * @param {?=} path A list of control names that designates how to move from the current control
  503. * to the control that should be queried for errors.
  504. *
  505. * @return {?} error data for that particular error. If the control or error is not present,
  506. * null is returned.
  507. */
  508. getError(errorCode, path) {
  509. return this.control ? this.control.getError(errorCode, path) : null;
  510. }
  511. }
  512. /**
  513. * @fileoverview added by tsickle
  514. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  515. */
  516. /**
  517. * \@description
  518. * A base class for directives that contain multiple registered instances of `NgControl`.
  519. * Only used by the forms module.
  520. *
  521. * \@publicApi
  522. * @abstract
  523. */
  524. class ControlContainer extends AbstractControlDirective {
  525. /**
  526. * \@description
  527. * The top-level form directive for the control.
  528. * @return {?}
  529. */
  530. get formDirective() { return null; }
  531. /**
  532. * \@description
  533. * The path to this group.
  534. * @return {?}
  535. */
  536. get path() { return null; }
  537. }
  538. /**
  539. * @fileoverview added by tsickle
  540. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  541. */
  542. /**
  543. * @return {?}
  544. */
  545. function unimplemented() {
  546. throw new Error('unimplemented');
  547. }
  548. /**
  549. * \@description
  550. * A base class that all control `FormControl`-based directives extend. It binds a `FormControl`
  551. * object to a DOM element.
  552. *
  553. * \@publicApi
  554. * @abstract
  555. */
  556. class NgControl extends AbstractControlDirective {
  557. constructor() {
  558. super(...arguments);
  559. /**
  560. * \@description
  561. * The parent form for the control.
  562. *
  563. * \@internal
  564. */
  565. this._parent = null;
  566. /**
  567. * \@description
  568. * The name for the control
  569. */
  570. this.name = null;
  571. /**
  572. * \@description
  573. * The value accessor for the control
  574. */
  575. this.valueAccessor = null;
  576. /**
  577. * \@description
  578. * The uncomposed array of synchronous validators for the control
  579. *
  580. * \@internal
  581. */
  582. this._rawValidators = [];
  583. /**
  584. * \@description
  585. * The uncomposed array of async validators for the control
  586. *
  587. * \@internal
  588. */
  589. this._rawAsyncValidators = [];
  590. }
  591. /**
  592. * \@description
  593. * The registered synchronous validator function for the control
  594. *
  595. * @throws An exception that this method is not implemented
  596. * @return {?}
  597. */
  598. get validator() { return (/** @type {?} */ (unimplemented())); }
  599. /**
  600. * \@description
  601. * The registered async validator function for the control
  602. *
  603. * @throws An exception that this method is not implemented
  604. * @return {?}
  605. */
  606. get asyncValidator() { return (/** @type {?} */ (unimplemented())); }
  607. }
  608. /**
  609. * @fileoverview added by tsickle
  610. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  611. */
  612. class AbstractControlStatus {
  613. /**
  614. * @param {?} cd
  615. */
  616. constructor(cd) { this._cd = cd; }
  617. /**
  618. * @return {?}
  619. */
  620. get ngClassUntouched() { return this._cd.control ? this._cd.control.untouched : false; }
  621. /**
  622. * @return {?}
  623. */
  624. get ngClassTouched() { return this._cd.control ? this._cd.control.touched : false; }
  625. /**
  626. * @return {?}
  627. */
  628. get ngClassPristine() { return this._cd.control ? this._cd.control.pristine : false; }
  629. /**
  630. * @return {?}
  631. */
  632. get ngClassDirty() { return this._cd.control ? this._cd.control.dirty : false; }
  633. /**
  634. * @return {?}
  635. */
  636. get ngClassValid() { return this._cd.control ? this._cd.control.valid : false; }
  637. /**
  638. * @return {?}
  639. */
  640. get ngClassInvalid() { return this._cd.control ? this._cd.control.invalid : false; }
  641. /**
  642. * @return {?}
  643. */
  644. get ngClassPending() { return this._cd.control ? this._cd.control.pending : false; }
  645. }
  646. /** @type {?} */
  647. const ngControlStatusHost = {
  648. '[class.ng-untouched]': 'ngClassUntouched',
  649. '[class.ng-touched]': 'ngClassTouched',
  650. '[class.ng-pristine]': 'ngClassPristine',
  651. '[class.ng-dirty]': 'ngClassDirty',
  652. '[class.ng-valid]': 'ngClassValid',
  653. '[class.ng-invalid]': 'ngClassInvalid',
  654. '[class.ng-pending]': 'ngClassPending',
  655. };
  656. /**
  657. * \@description
  658. * Directive automatically applied to Angular form controls that sets CSS classes
  659. * based on control status.
  660. *
  661. * \@usageNotes
  662. *
  663. * ### CSS classes applied
  664. *
  665. * The following classes are applied as the properties become true:
  666. *
  667. * * ng-valid
  668. * * ng-invalid
  669. * * ng-pending
  670. * * ng-pristine
  671. * * ng-dirty
  672. * * ng-untouched
  673. * * ng-touched
  674. *
  675. * \@ngModule ReactiveFormsModule
  676. * \@ngModule FormsModule
  677. * \@publicApi
  678. */
  679. class NgControlStatus extends AbstractControlStatus {
  680. /**
  681. * @param {?} cd
  682. */
  683. constructor(cd) { super(cd); }
  684. }
  685. NgControlStatus.decorators = [
  686. { type: Directive, args: [{ selector: '[formControlName],[ngModel],[formControl]', host: ngControlStatusHost },] }
  687. ];
  688. /** @nocollapse */
  689. NgControlStatus.ctorParameters = () => [
  690. { type: NgControl, decorators: [{ type: Self }] }
  691. ];
  692. /**
  693. * \@description
  694. * Directive automatically applied to Angular form groups that sets CSS classes
  695. * based on control status (valid/invalid/dirty/etc).
  696. *
  697. * @see `NgControlStatus`
  698. *
  699. * \@ngModule ReactiveFormsModule
  700. * \@ngModule FormsModule
  701. * \@publicApi
  702. */
  703. class NgControlStatusGroup extends AbstractControlStatus {
  704. /**
  705. * @param {?} cd
  706. */
  707. constructor(cd) { super(cd); }
  708. }
  709. NgControlStatusGroup.decorators = [
  710. { type: Directive, args: [{
  711. selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
  712. host: ngControlStatusHost
  713. },] }
  714. ];
  715. /** @nocollapse */
  716. NgControlStatusGroup.ctorParameters = () => [
  717. { type: ControlContainer, decorators: [{ type: Self }] }
  718. ];
  719. /**
  720. * @fileoverview added by tsickle
  721. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  722. */
  723. /**
  724. * @param {?} value
  725. * @return {?}
  726. */
  727. function isEmptyInputValue(value) {
  728. // we don't check for string here so it also works with arrays
  729. return value == null || value.length === 0;
  730. }
  731. /**
  732. * \@description
  733. * An `InjectionToken` for registering additional synchronous validators used with `AbstractControl`s.
  734. *
  735. * @see `NG_ASYNC_VALIDATORS`
  736. *
  737. * \@usageNotes
  738. *
  739. * ### Providing a custom validator
  740. *
  741. * The following example registers a custom validator directive. Adding the validator to the
  742. * existing collection of validators requires the `multi: true` option.
  743. *
  744. * ```typescript
  745. * \@Directive({
  746. * selector: '[customValidator]',
  747. * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
  748. * })
  749. * class CustomValidatorDirective implements Validator {
  750. * validate(control: AbstractControl): ValidationErrors | null {
  751. * return { 'custom': true };
  752. * }
  753. * }
  754. * ```
  755. *
  756. * \@publicApi
  757. * @type {?}
  758. */
  759. const NG_VALIDATORS = new InjectionToken('NgValidators');
  760. /**
  761. * \@description
  762. * An `InjectionToken` for registering additional asynchronous validators used with `AbstractControl`s.
  763. *
  764. * @see `NG_VALIDATORS`
  765. *
  766. * \@publicApi
  767. * @type {?}
  768. */
  769. const NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators');
  770. /** @type {?} */
  771. const EMAIL_REGEXP = /^(?=.{1,254}$)(?=.{1,64}@)[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+(\.[-!#$%&'*+/0-9=?A-Z^_`a-z{|}~]+)*@[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?(\.[A-Za-z0-9]([A-Za-z0-9-]{0,61}[A-Za-z0-9])?)*$/;
  772. /**
  773. * \@description
  774. * Provides a set of built-in validators that can be used by form controls.
  775. *
  776. * A validator is a function that processes a `FormControl` or collection of
  777. * controls and returns an error map or null. A null map means that validation has passed.
  778. *
  779. * @see [Form Validation](/guide/form-validation)
  780. *
  781. * \@publicApi
  782. */
  783. class Validators {
  784. /**
  785. * \@description
  786. * Validator that requires the control's value to be greater than or equal to the provided number.
  787. * The validator exists only as a function and not as a directive.
  788. *
  789. * \@usageNotes
  790. *
  791. * ### Validate against a minimum of 3
  792. *
  793. * ```typescript
  794. * const control = new FormControl(2, Validators.min(3));
  795. *
  796. * console.log(control.errors); // {min: {min: 3, actual: 2}}
  797. * ```
  798. *
  799. * @param {?} min
  800. * @return {?} A validator function that returns an error map with the
  801. * `min` property if the validation check fails, otherwise `null`.
  802. *
  803. */
  804. static min(min) {
  805. return (/**
  806. * @param {?} control
  807. * @return {?}
  808. */
  809. (control) => {
  810. if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
  811. return null; // don't validate empty values to allow optional controls
  812. }
  813. /** @type {?} */
  814. const value = parseFloat(control.value);
  815. // Controls with NaN values after parsing should be treated as not having a
  816. // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
  817. return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null;
  818. });
  819. }
  820. /**
  821. * \@description
  822. * Validator that requires the control's value to be less than or equal to the provided number.
  823. * The validator exists only as a function and not as a directive.
  824. *
  825. * \@usageNotes
  826. *
  827. * ### Validate against a maximum of 15
  828. *
  829. * ```typescript
  830. * const control = new FormControl(16, Validators.max(15));
  831. *
  832. * console.log(control.errors); // {max: {max: 15, actual: 16}}
  833. * ```
  834. *
  835. * @param {?} max
  836. * @return {?} A validator function that returns an error map with the
  837. * `max` property if the validation check fails, otherwise `null`.
  838. *
  839. */
  840. static max(max) {
  841. return (/**
  842. * @param {?} control
  843. * @return {?}
  844. */
  845. (control) => {
  846. if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
  847. return null; // don't validate empty values to allow optional controls
  848. }
  849. /** @type {?} */
  850. const value = parseFloat(control.value);
  851. // Controls with NaN values after parsing should be treated as not having a
  852. // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
  853. return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null;
  854. });
  855. }
  856. /**
  857. * \@description
  858. * Validator that requires the control have a non-empty value.
  859. *
  860. * \@usageNotes
  861. *
  862. * ### Validate that the field is non-empty
  863. *
  864. * ```typescript
  865. * const control = new FormControl('', Validators.required);
  866. *
  867. * console.log(control.errors); // {required: true}
  868. * ```
  869. *
  870. * @param {?} control
  871. * @return {?} An error map with the `required` property
  872. * if the validation check fails, otherwise `null`.
  873. *
  874. */
  875. static required(control) {
  876. return isEmptyInputValue(control.value) ? { 'required': true } : null;
  877. }
  878. /**
  879. * \@description
  880. * Validator that requires the control's value be true. This validator is commonly
  881. * used for required checkboxes.
  882. *
  883. * \@usageNotes
  884. *
  885. * ### Validate that the field value is true
  886. *
  887. * ```typescript
  888. * const control = new FormControl('', Validators.requiredTrue);
  889. *
  890. * console.log(control.errors); // {required: true}
  891. * ```
  892. *
  893. * @param {?} control
  894. * @return {?} An error map that contains the `required` property
  895. * set to `true` if the validation check fails, otherwise `null`.
  896. */
  897. static requiredTrue(control) {
  898. return control.value === true ? null : { 'required': true };
  899. }
  900. /**
  901. * \@description
  902. * Validator that requires the control's value pass an email validation test.
  903. *
  904. * \@usageNotes
  905. *
  906. * ### Validate that the field matches a valid email pattern
  907. *
  908. * ```typescript
  909. * const control = new FormControl('bad\@', Validators.email);
  910. *
  911. * console.log(control.errors); // {email: true}
  912. * ```
  913. *
  914. * @param {?} control
  915. * @return {?} An error map with the `email` property
  916. * if the validation check fails, otherwise `null`.
  917. *
  918. */
  919. static email(control) {
  920. if (isEmptyInputValue(control.value)) {
  921. return null; // don't validate empty values to allow optional controls
  922. }
  923. return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };
  924. }
  925. /**
  926. * \@description
  927. * Validator that requires the length of the control's value to be greater than or equal
  928. * to the provided minimum length. This validator is also provided by default if you use the
  929. * the HTML5 `minlength` attribute.
  930. *
  931. * \@usageNotes
  932. *
  933. * ### Validate that the field has a minimum of 3 characters
  934. *
  935. * ```typescript
  936. * const control = new FormControl('ng', Validators.minLength(3));
  937. *
  938. * console.log(control.errors); // {minlength: {requiredLength: 3, actualLength: 2}}
  939. * ```
  940. *
  941. * ```html
  942. * <input minlength="5">
  943. * ```
  944. *
  945. * @param {?} minLength
  946. * @return {?} A validator function that returns an error map with the
  947. * `minlength` if the validation check fails, otherwise `null`.
  948. */
  949. static minLength(minLength) {
  950. return (/**
  951. * @param {?} control
  952. * @return {?}
  953. */
  954. (control) => {
  955. if (isEmptyInputValue(control.value)) {
  956. return null; // don't validate empty values to allow optional controls
  957. }
  958. /** @type {?} */
  959. const length = control.value ? control.value.length : 0;
  960. return length < minLength ?
  961. { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } :
  962. null;
  963. });
  964. }
  965. /**
  966. * \@description
  967. * Validator that requires the length of the control's value to be less than or equal
  968. * to the provided maximum length. This validator is also provided by default if you use the
  969. * the HTML5 `maxlength` attribute.
  970. *
  971. * \@usageNotes
  972. *
  973. * ### Validate that the field has maximum of 5 characters
  974. *
  975. * ```typescript
  976. * const control = new FormControl('Angular', Validators.maxLength(5));
  977. *
  978. * console.log(control.errors); // {maxlength: {requiredLength: 5, actualLength: 7}}
  979. * ```
  980. *
  981. * ```html
  982. * <input maxlength="5">
  983. * ```
  984. *
  985. * @param {?} maxLength
  986. * @return {?} A validator function that returns an error map with the
  987. * `maxlength` property if the validation check fails, otherwise `null`.
  988. */
  989. static maxLength(maxLength) {
  990. return (/**
  991. * @param {?} control
  992. * @return {?}
  993. */
  994. (control) => {
  995. /** @type {?} */
  996. const length = control.value ? control.value.length : 0;
  997. return length > maxLength ?
  998. { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } :
  999. null;
  1000. });
  1001. }
  1002. /**
  1003. * \@description
  1004. * Validator that requires the control's value to match a regex pattern. This validator is also
  1005. * provided by default if you use the HTML5 `pattern` attribute.
  1006. *
  1007. * Note that if a Regexp is provided, the Regexp is used as is to test the values. On the other
  1008. * hand, if a string is passed, the `^` character is prepended and the `$` character is
  1009. * appended to the provided string (if not already present), and the resulting regular
  1010. * expression is used to test the values.
  1011. *
  1012. * \@usageNotes
  1013. *
  1014. * ### Validate that the field only contains letters or spaces
  1015. *
  1016. * ```typescript
  1017. * const control = new FormControl('1', Validators.pattern('[a-zA-Z ]*'));
  1018. *
  1019. * console.log(control.errors); // {pattern: {requiredPattern: '^[a-zA-Z ]*$', actualValue: '1'}}
  1020. * ```
  1021. *
  1022. * ```html
  1023. * <input pattern="[a-zA-Z ]*">
  1024. * ```
  1025. *
  1026. * @param {?} pattern
  1027. * @return {?} A validator function that returns an error map with the
  1028. * `pattern` property if the validation check fails, otherwise `null`.
  1029. */
  1030. static pattern(pattern) {
  1031. if (!pattern)
  1032. return Validators.nullValidator;
  1033. /** @type {?} */
  1034. let regex;
  1035. /** @type {?} */
  1036. let regexStr;
  1037. if (typeof pattern === 'string') {
  1038. regexStr = '';
  1039. if (pattern.charAt(0) !== '^')
  1040. regexStr += '^';
  1041. regexStr += pattern;
  1042. if (pattern.charAt(pattern.length - 1) !== '$')
  1043. regexStr += '$';
  1044. regex = new RegExp(regexStr);
  1045. }
  1046. else {
  1047. regexStr = pattern.toString();
  1048. regex = pattern;
  1049. }
  1050. return (/**
  1051. * @param {?} control
  1052. * @return {?}
  1053. */
  1054. (control) => {
  1055. if (isEmptyInputValue(control.value)) {
  1056. return null; // don't validate empty values to allow optional controls
  1057. }
  1058. /** @type {?} */
  1059. const value = control.value;
  1060. return regex.test(value) ? null :
  1061. { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } };
  1062. });
  1063. }
  1064. /**
  1065. * \@description
  1066. * Validator that performs no operation.
  1067. * @param {?} control
  1068. * @return {?}
  1069. */
  1070. static nullValidator(control) { return null; }
  1071. /**
  1072. * @param {?} validators
  1073. * @return {?}
  1074. */
  1075. static compose(validators) {
  1076. if (!validators)
  1077. return null;
  1078. /** @type {?} */
  1079. const presentValidators = (/** @type {?} */ (validators.filter(isPresent)));
  1080. if (presentValidators.length == 0)
  1081. return null;
  1082. return (/**
  1083. * @param {?} control
  1084. * @return {?}
  1085. */
  1086. function (control) {
  1087. return _mergeErrors(_executeValidators(control, presentValidators));
  1088. });
  1089. }
  1090. /**
  1091. * \@description
  1092. * Compose multiple async validators into a single function that returns the union
  1093. * of the individual error objects for the provided control.
  1094. *
  1095. * @param {?} validators
  1096. * @return {?} A validator function that returns an error map with the
  1097. * merged error objects of the async validators if the validation check fails, otherwise `null`.
  1098. */
  1099. static composeAsync(validators) {
  1100. if (!validators)
  1101. return null;
  1102. /** @type {?} */
  1103. const presentValidators = (/** @type {?} */ (validators.filter(isPresent)));
  1104. if (presentValidators.length == 0)
  1105. return null;
  1106. return (/**
  1107. * @param {?} control
  1108. * @return {?}
  1109. */
  1110. function (control) {
  1111. /** @type {?} */
  1112. const observables = _executeAsyncValidators(control, presentValidators).map(toObservable);
  1113. return forkJoin(observables).pipe(map(_mergeErrors));
  1114. });
  1115. }
  1116. }
  1117. /**
  1118. * @param {?} o
  1119. * @return {?}
  1120. */
  1121. function isPresent(o) {
  1122. return o != null;
  1123. }
  1124. /**
  1125. * @param {?} r
  1126. * @return {?}
  1127. */
  1128. function toObservable(r) {
  1129. /** @type {?} */
  1130. const obs = ɵisPromise(r) ? from(r) : r;
  1131. if (!(ɵisObservable(obs))) {
  1132. throw new Error(`Expected validator to return Promise or Observable.`);
  1133. }
  1134. return obs;
  1135. }
  1136. /**
  1137. * @param {?} control
  1138. * @param {?} validators
  1139. * @return {?}
  1140. */
  1141. function _executeValidators(control, validators) {
  1142. return validators.map((/**
  1143. * @param {?} v
  1144. * @return {?}
  1145. */
  1146. v => v(control)));
  1147. }
  1148. /**
  1149. * @param {?} control
  1150. * @param {?} validators
  1151. * @return {?}
  1152. */
  1153. function _executeAsyncValidators(control, validators) {
  1154. return validators.map((/**
  1155. * @param {?} v
  1156. * @return {?}
  1157. */
  1158. v => v(control)));
  1159. }
  1160. /**
  1161. * @param {?} arrayOfErrors
  1162. * @return {?}
  1163. */
  1164. function _mergeErrors(arrayOfErrors) {
  1165. /** @type {?} */
  1166. const res = arrayOfErrors.reduce((/**
  1167. * @param {?} res
  1168. * @param {?} errors
  1169. * @return {?}
  1170. */
  1171. (res, errors) => {
  1172. return errors != null ? Object.assign({}, (/** @type {?} */ (res)), errors) : (/** @type {?} */ (res));
  1173. }), {});
  1174. return Object.keys(res).length === 0 ? null : res;
  1175. }
  1176. /**
  1177. * @fileoverview added by tsickle
  1178. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1179. */
  1180. /**
  1181. * @license
  1182. * Copyright Google Inc. All Rights Reserved.
  1183. *
  1184. * Use of this source code is governed by an MIT-style license that can be
  1185. * found in the LICENSE file at https://angular.io/license
  1186. */
  1187. /**
  1188. * @param {?} validator
  1189. * @return {?}
  1190. */
  1191. function normalizeValidator(validator) {
  1192. if (((/** @type {?} */ (validator))).validate) {
  1193. return (/**
  1194. * @param {?} c
  1195. * @return {?}
  1196. */
  1197. (c) => ((/** @type {?} */ (validator))).validate(c));
  1198. }
  1199. else {
  1200. return (/** @type {?} */ (validator));
  1201. }
  1202. }
  1203. /**
  1204. * @param {?} validator
  1205. * @return {?}
  1206. */
  1207. function normalizeAsyncValidator(validator) {
  1208. if (((/** @type {?} */ (validator))).validate) {
  1209. return (/**
  1210. * @param {?} c
  1211. * @return {?}
  1212. */
  1213. (c) => ((/** @type {?} */ (validator))).validate(c));
  1214. }
  1215. else {
  1216. return (/** @type {?} */ (validator));
  1217. }
  1218. }
  1219. /**
  1220. * @fileoverview added by tsickle
  1221. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1222. */
  1223. /** @type {?} */
  1224. const NUMBER_VALUE_ACCESSOR = {
  1225. provide: NG_VALUE_ACCESSOR,
  1226. useExisting: forwardRef((/**
  1227. * @return {?}
  1228. */
  1229. () => NumberValueAccessor)),
  1230. multi: true
  1231. };
  1232. /**
  1233. * \@description
  1234. * The `ControlValueAccessor` for writing a number value and listening to number input changes.
  1235. * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel`
  1236. * directives.
  1237. *
  1238. * \@usageNotes
  1239. *
  1240. * ### Using a number input with a reactive form.
  1241. *
  1242. * The following example shows how to use a number input with a reactive form.
  1243. *
  1244. * ```ts
  1245. * const totalCountControl = new FormControl();
  1246. * ```
  1247. *
  1248. * ```
  1249. * <input type="number" [formControl]="totalCountControl">
  1250. * ```
  1251. *
  1252. * \@ngModule ReactiveFormsModule
  1253. * \@ngModule FormsModule
  1254. * \@publicApi
  1255. */
  1256. class NumberValueAccessor {
  1257. /**
  1258. * @param {?} _renderer
  1259. * @param {?} _elementRef
  1260. */
  1261. constructor(_renderer, _elementRef) {
  1262. this._renderer = _renderer;
  1263. this._elementRef = _elementRef;
  1264. /**
  1265. * \@description
  1266. * The registered callback function called when a change or input event occurs on the input
  1267. * element.
  1268. */
  1269. this.onChange = (/**
  1270. * @param {?} _
  1271. * @return {?}
  1272. */
  1273. (_) => { });
  1274. /**
  1275. * \@description
  1276. * The registered callback function called when a blur event occurs on the input element.
  1277. */
  1278. this.onTouched = (/**
  1279. * @return {?}
  1280. */
  1281. () => { });
  1282. }
  1283. /**
  1284. * Sets the "value" property on the input element.
  1285. *
  1286. * @param {?} value The checked value
  1287. * @return {?}
  1288. */
  1289. writeValue(value) {
  1290. // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
  1291. /** @type {?} */
  1292. const normalizedValue = value == null ? '' : value;
  1293. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  1294. }
  1295. /**
  1296. * \@description
  1297. * Registers a function called when the control value changes.
  1298. *
  1299. * @param {?} fn The callback function
  1300. * @return {?}
  1301. */
  1302. registerOnChange(fn) {
  1303. this.onChange = (/**
  1304. * @param {?} value
  1305. * @return {?}
  1306. */
  1307. (value) => { fn(value == '' ? null : parseFloat(value)); });
  1308. }
  1309. /**
  1310. * \@description
  1311. * Registers a function called when the control is touched.
  1312. *
  1313. * @param {?} fn The callback function
  1314. * @return {?}
  1315. */
  1316. registerOnTouched(fn) { this.onTouched = fn; }
  1317. /**
  1318. * Sets the "disabled" property on the input element.
  1319. *
  1320. * @param {?} isDisabled The disabled value
  1321. * @return {?}
  1322. */
  1323. setDisabledState(isDisabled) {
  1324. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1325. }
  1326. }
  1327. NumberValueAccessor.decorators = [
  1328. { type: Directive, args: [{
  1329. selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
  1330. host: {
  1331. '(change)': 'onChange($event.target.value)',
  1332. '(input)': 'onChange($event.target.value)',
  1333. '(blur)': 'onTouched()'
  1334. },
  1335. providers: [NUMBER_VALUE_ACCESSOR]
  1336. },] }
  1337. ];
  1338. /** @nocollapse */
  1339. NumberValueAccessor.ctorParameters = () => [
  1340. { type: Renderer2 },
  1341. { type: ElementRef }
  1342. ];
  1343. /**
  1344. * @fileoverview added by tsickle
  1345. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1346. */
  1347. /** @type {?} */
  1348. const RADIO_VALUE_ACCESSOR = {
  1349. provide: NG_VALUE_ACCESSOR,
  1350. useExisting: forwardRef((/**
  1351. * @return {?}
  1352. */
  1353. () => RadioControlValueAccessor)),
  1354. multi: true
  1355. };
  1356. /**
  1357. * \@description
  1358. * Class used by Angular to track radio buttons. For internal use only.
  1359. */
  1360. class RadioControlRegistry {
  1361. constructor() {
  1362. this._accessors = [];
  1363. }
  1364. /**
  1365. * \@description
  1366. * Adds a control to the internal registry. For internal use only.
  1367. * @param {?} control
  1368. * @param {?} accessor
  1369. * @return {?}
  1370. */
  1371. add(control, accessor) {
  1372. this._accessors.push([control, accessor]);
  1373. }
  1374. /**
  1375. * \@description
  1376. * Removes a control from the internal registry. For internal use only.
  1377. * @param {?} accessor
  1378. * @return {?}
  1379. */
  1380. remove(accessor) {
  1381. for (let i = this._accessors.length - 1; i >= 0; --i) {
  1382. if (this._accessors[i][1] === accessor) {
  1383. this._accessors.splice(i, 1);
  1384. return;
  1385. }
  1386. }
  1387. }
  1388. /**
  1389. * \@description
  1390. * Selects a radio button. For internal use only.
  1391. * @param {?} accessor
  1392. * @return {?}
  1393. */
  1394. select(accessor) {
  1395. this._accessors.forEach((/**
  1396. * @param {?} c
  1397. * @return {?}
  1398. */
  1399. (c) => {
  1400. if (this._isSameGroup(c, accessor) && c[1] !== accessor) {
  1401. c[1].fireUncheck(accessor.value);
  1402. }
  1403. }));
  1404. }
  1405. /**
  1406. * @private
  1407. * @param {?} controlPair
  1408. * @param {?} accessor
  1409. * @return {?}
  1410. */
  1411. _isSameGroup(controlPair, accessor) {
  1412. if (!controlPair[0].control)
  1413. return false;
  1414. return controlPair[0]._parent === accessor._control._parent &&
  1415. controlPair[1].name === accessor.name;
  1416. }
  1417. }
  1418. RadioControlRegistry.decorators = [
  1419. { type: Injectable }
  1420. ];
  1421. /**
  1422. * \@description
  1423. * The `ControlValueAccessor` for writing radio control values and listening to radio control
  1424. * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
  1425. * `NgModel` directives.
  1426. *
  1427. * \@usageNotes
  1428. *
  1429. * ### Using radio buttons with reactive form directives
  1430. *
  1431. * The follow example shows how to use radio buttons in a reactive form. When using radio buttons in
  1432. * a reactive form, radio buttons in the same group should have the same `formControlName`.
  1433. * Providing a `name` attribute is optional.
  1434. *
  1435. * {\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
  1436. *
  1437. * \@ngModule ReactiveFormsModule
  1438. * \@ngModule FormsModule
  1439. * \@publicApi
  1440. */
  1441. class RadioControlValueAccessor {
  1442. /**
  1443. * @param {?} _renderer
  1444. * @param {?} _elementRef
  1445. * @param {?} _registry
  1446. * @param {?} _injector
  1447. */
  1448. constructor(_renderer, _elementRef, _registry, _injector) {
  1449. this._renderer = _renderer;
  1450. this._elementRef = _elementRef;
  1451. this._registry = _registry;
  1452. this._injector = _injector;
  1453. /**
  1454. * \@description
  1455. * The registered callback function called when a change event occurs on the input element.
  1456. */
  1457. this.onChange = (/**
  1458. * @return {?}
  1459. */
  1460. () => { });
  1461. /**
  1462. * \@description
  1463. * The registered callback function called when a blur event occurs on the input element.
  1464. */
  1465. this.onTouched = (/**
  1466. * @return {?}
  1467. */
  1468. () => { });
  1469. }
  1470. /**
  1471. * \@description
  1472. * A lifecycle method called when the directive is initialized. For internal use only.
  1473. *
  1474. * @return {?}
  1475. */
  1476. ngOnInit() {
  1477. this._control = this._injector.get(NgControl);
  1478. this._checkName();
  1479. this._registry.add(this._control, this);
  1480. }
  1481. /**
  1482. * \@description
  1483. * Lifecycle method called before the directive's instance is destroyed. For internal use only.
  1484. *
  1485. * @return {?}
  1486. */
  1487. ngOnDestroy() { this._registry.remove(this); }
  1488. /**
  1489. * \@description
  1490. * Sets the "checked" property value on the radio input element.
  1491. *
  1492. * @param {?} value The checked value
  1493. * @return {?}
  1494. */
  1495. writeValue(value) {
  1496. this._state = value === this.value;
  1497. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state);
  1498. }
  1499. /**
  1500. * \@description
  1501. * Registers a function called when the control value changes.
  1502. *
  1503. * @param {?} fn The callback function
  1504. * @return {?}
  1505. */
  1506. registerOnChange(fn) {
  1507. this._fn = fn;
  1508. this.onChange = (/**
  1509. * @return {?}
  1510. */
  1511. () => {
  1512. fn(this.value);
  1513. this._registry.select(this);
  1514. });
  1515. }
  1516. /**
  1517. * Sets the "value" on the radio input element and unchecks it.
  1518. *
  1519. * @param {?} value
  1520. * @return {?}
  1521. */
  1522. fireUncheck(value) { this.writeValue(value); }
  1523. /**
  1524. * \@description
  1525. * Registers a function called when the control is touched.
  1526. *
  1527. * @param {?} fn The callback function
  1528. * @return {?}
  1529. */
  1530. registerOnTouched(fn) { this.onTouched = fn; }
  1531. /**
  1532. * Sets the "disabled" property on the input element.
  1533. *
  1534. * @param {?} isDisabled The disabled value
  1535. * @return {?}
  1536. */
  1537. setDisabledState(isDisabled) {
  1538. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1539. }
  1540. /**
  1541. * @private
  1542. * @return {?}
  1543. */
  1544. _checkName() {
  1545. if (this.name && this.formControlName && this.name !== this.formControlName) {
  1546. this._throwNameError();
  1547. }
  1548. if (!this.name && this.formControlName)
  1549. this.name = this.formControlName;
  1550. }
  1551. /**
  1552. * @private
  1553. * @return {?}
  1554. */
  1555. _throwNameError() {
  1556. throw new Error(`
  1557. If you define both a name and a formControlName attribute on your radio button, their values
  1558. must match. Ex: <input type="radio" formControlName="food" name="food">
  1559. `);
  1560. }
  1561. }
  1562. RadioControlValueAccessor.decorators = [
  1563. { type: Directive, args: [{
  1564. selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
  1565. host: { '(change)': 'onChange()', '(blur)': 'onTouched()' },
  1566. providers: [RADIO_VALUE_ACCESSOR]
  1567. },] }
  1568. ];
  1569. /** @nocollapse */
  1570. RadioControlValueAccessor.ctorParameters = () => [
  1571. { type: Renderer2 },
  1572. { type: ElementRef },
  1573. { type: RadioControlRegistry },
  1574. { type: Injector }
  1575. ];
  1576. RadioControlValueAccessor.propDecorators = {
  1577. name: [{ type: Input }],
  1578. formControlName: [{ type: Input }],
  1579. value: [{ type: Input }]
  1580. };
  1581. /**
  1582. * @fileoverview added by tsickle
  1583. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1584. */
  1585. /** @type {?} */
  1586. const RANGE_VALUE_ACCESSOR = {
  1587. provide: NG_VALUE_ACCESSOR,
  1588. useExisting: forwardRef((/**
  1589. * @return {?}
  1590. */
  1591. () => RangeValueAccessor)),
  1592. multi: true
  1593. };
  1594. /**
  1595. * \@description
  1596. * The `ControlValueAccessor` for writing a range value and listening to range input changes.
  1597. * The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel`
  1598. * directives.
  1599. *
  1600. * \@usageNotes
  1601. *
  1602. * ### Using a range input with a reactive form
  1603. *
  1604. * The following example shows how to use a range input with a reactive form.
  1605. *
  1606. * ```ts
  1607. * const ageControl = new FormControl();
  1608. * ```
  1609. *
  1610. * ```
  1611. * <input type="range" [formControl]="ageControl">
  1612. * ```
  1613. *
  1614. * \@ngModule ReactiveFormsModule
  1615. * \@ngModule FormsModule
  1616. * \@publicApi
  1617. */
  1618. class RangeValueAccessor {
  1619. /**
  1620. * @param {?} _renderer
  1621. * @param {?} _elementRef
  1622. */
  1623. constructor(_renderer, _elementRef) {
  1624. this._renderer = _renderer;
  1625. this._elementRef = _elementRef;
  1626. /**
  1627. * \@description
  1628. * The registered callback function called when a change or input event occurs on the input
  1629. * element.
  1630. */
  1631. this.onChange = (/**
  1632. * @param {?} _
  1633. * @return {?}
  1634. */
  1635. (_) => { });
  1636. /**
  1637. * \@description
  1638. * The registered callback function called when a blur event occurs on the input element.
  1639. */
  1640. this.onTouched = (/**
  1641. * @return {?}
  1642. */
  1643. () => { });
  1644. }
  1645. /**
  1646. * Sets the "value" property on the input element.
  1647. *
  1648. * @param {?} value The checked value
  1649. * @return {?}
  1650. */
  1651. writeValue(value) {
  1652. this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value));
  1653. }
  1654. /**
  1655. * \@description
  1656. * Registers a function called when the control value changes.
  1657. *
  1658. * @param {?} fn The callback function
  1659. * @return {?}
  1660. */
  1661. registerOnChange(fn) {
  1662. this.onChange = (/**
  1663. * @param {?} value
  1664. * @return {?}
  1665. */
  1666. (value) => { fn(value == '' ? null : parseFloat(value)); });
  1667. }
  1668. /**
  1669. * \@description
  1670. * Registers a function called when the control is touched.
  1671. *
  1672. * @param {?} fn The callback function
  1673. * @return {?}
  1674. */
  1675. registerOnTouched(fn) { this.onTouched = fn; }
  1676. /**
  1677. * Sets the "disabled" property on the range input element.
  1678. *
  1679. * @param {?} isDisabled The disabled value
  1680. * @return {?}
  1681. */
  1682. setDisabledState(isDisabled) {
  1683. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1684. }
  1685. }
  1686. RangeValueAccessor.decorators = [
  1687. { type: Directive, args: [{
  1688. selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
  1689. host: {
  1690. '(change)': 'onChange($event.target.value)',
  1691. '(input)': 'onChange($event.target.value)',
  1692. '(blur)': 'onTouched()'
  1693. },
  1694. providers: [RANGE_VALUE_ACCESSOR]
  1695. },] }
  1696. ];
  1697. /** @nocollapse */
  1698. RangeValueAccessor.ctorParameters = () => [
  1699. { type: Renderer2 },
  1700. { type: ElementRef }
  1701. ];
  1702. /**
  1703. * @fileoverview added by tsickle
  1704. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1705. */
  1706. /**
  1707. * @license
  1708. * Copyright Google Inc. All Rights Reserved.
  1709. *
  1710. * Use of this source code is governed by an MIT-style license that can be
  1711. * found in the LICENSE file at https://angular.io/license
  1712. */
  1713. /** @type {?} */
  1714. const FormErrorExamples = {
  1715. formControlName: `
  1716. <div [formGroup]="myGroup">
  1717. <input formControlName="firstName">
  1718. </div>
  1719. In your class:
  1720. this.myGroup = new FormGroup({
  1721. firstName: new FormControl()
  1722. });`,
  1723. formGroupName: `
  1724. <div [formGroup]="myGroup">
  1725. <div formGroupName="person">
  1726. <input formControlName="firstName">
  1727. </div>
  1728. </div>
  1729. In your class:
  1730. this.myGroup = new FormGroup({
  1731. person: new FormGroup({ firstName: new FormControl() })
  1732. });`,
  1733. formArrayName: `
  1734. <div [formGroup]="myGroup">
  1735. <div formArrayName="cities">
  1736. <div *ngFor="let city of cityArray.controls; index as i">
  1737. <input [formControlName]="i">
  1738. </div>
  1739. </div>
  1740. </div>
  1741. In your class:
  1742. this.cityArray = new FormArray([new FormControl('SF')]);
  1743. this.myGroup = new FormGroup({
  1744. cities: this.cityArray
  1745. });`,
  1746. ngModelGroup: `
  1747. <form>
  1748. <div ngModelGroup="person">
  1749. <input [(ngModel)]="person.name" name="firstName">
  1750. </div>
  1751. </form>`,
  1752. ngModelWithFormGroup: `
  1753. <div [formGroup]="myGroup">
  1754. <input formControlName="firstName">
  1755. <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}">
  1756. </div>
  1757. `
  1758. };
  1759. /**
  1760. * @fileoverview added by tsickle
  1761. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1762. */
  1763. class ReactiveErrors {
  1764. /**
  1765. * @return {?}
  1766. */
  1767. static controlParentException() {
  1768. throw new Error(`formControlName must be used with a parent formGroup directive. You'll want to add a formGroup
  1769. directive and pass it an existing FormGroup instance (you can create one in your class).
  1770. Example:
  1771. ${FormErrorExamples.formControlName}`);
  1772. }
  1773. /**
  1774. * @return {?}
  1775. */
  1776. static ngModelGroupException() {
  1777. throw new Error(`formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents
  1778. that also have a "form" prefix: formGroupName, formArrayName, or formGroup.
  1779. Option 1: Update the parent to be formGroupName (reactive form strategy)
  1780. ${FormErrorExamples.formGroupName}
  1781. Option 2: Use ngModel instead of formControlName (template-driven strategy)
  1782. ${FormErrorExamples.ngModelGroup}`);
  1783. }
  1784. /**
  1785. * @return {?}
  1786. */
  1787. static missingFormException() {
  1788. throw new Error(`formGroup expects a FormGroup instance. Please pass one in.
  1789. Example:
  1790. ${FormErrorExamples.formControlName}`);
  1791. }
  1792. /**
  1793. * @return {?}
  1794. */
  1795. static groupParentException() {
  1796. throw new Error(`formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup
  1797. directive and pass it an existing FormGroup instance (you can create one in your class).
  1798. Example:
  1799. ${FormErrorExamples.formGroupName}`);
  1800. }
  1801. /**
  1802. * @return {?}
  1803. */
  1804. static arrayParentException() {
  1805. throw new Error(`formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup
  1806. directive and pass it an existing FormGroup instance (you can create one in your class).
  1807. Example:
  1808. ${FormErrorExamples.formArrayName}`);
  1809. }
  1810. /**
  1811. * @return {?}
  1812. */
  1813. static disabledAttrWarning() {
  1814. console.warn(`
  1815. It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
  1816. when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
  1817. you. We recommend using this approach to avoid 'changed after checked' errors.
  1818. Example:
  1819. form = new FormGroup({
  1820. first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
  1821. last: new FormControl('Drew', Validators.required)
  1822. });
  1823. `);
  1824. }
  1825. /**
  1826. * @param {?} directiveName
  1827. * @return {?}
  1828. */
  1829. static ngModelWarning(directiveName) {
  1830. console.warn(`
  1831. It looks like you're using ngModel on the same form field as ${directiveName}.
  1832. Support for using the ngModel input property and ngModelChange event with
  1833. reactive form directives has been deprecated in Angular v6 and will be removed
  1834. in Angular v7.
  1835. For more information on this, see our API docs here:
  1836. https://angular.io/api/forms/${directiveName === 'formControl' ? 'FormControlDirective'
  1837. : 'FormControlName'}#use-with-ngmodel
  1838. `);
  1839. }
  1840. }
  1841. /**
  1842. * @fileoverview added by tsickle
  1843. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  1844. */
  1845. /** @type {?} */
  1846. const SELECT_VALUE_ACCESSOR = {
  1847. provide: NG_VALUE_ACCESSOR,
  1848. useExisting: forwardRef((/**
  1849. * @return {?}
  1850. */
  1851. () => SelectControlValueAccessor)),
  1852. multi: true
  1853. };
  1854. /**
  1855. * @param {?} id
  1856. * @param {?} value
  1857. * @return {?}
  1858. */
  1859. function _buildValueString(id, value) {
  1860. if (id == null)
  1861. return `${value}`;
  1862. if (value && typeof value === 'object')
  1863. value = 'Object';
  1864. return `${id}: ${value}`.slice(0, 50);
  1865. }
  1866. /**
  1867. * @param {?} valueString
  1868. * @return {?}
  1869. */
  1870. function _extractId(valueString) {
  1871. return valueString.split(':')[0];
  1872. }
  1873. /**
  1874. * \@description
  1875. * The `ControlValueAccessor` for writing select control values and listening to select control
  1876. * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and
  1877. * `NgModel` directives.
  1878. *
  1879. * \@usageNotes
  1880. *
  1881. * ### Using select controls in a reactive form
  1882. *
  1883. * The following examples show how to use a select control in a reactive form.
  1884. *
  1885. * {\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
  1886. *
  1887. * ### Using select controls in a template-driven form
  1888. *
  1889. * To use a select in a template-driven form, simply add an `ngModel` and a `name`
  1890. * attribute to the main `<select>` tag.
  1891. *
  1892. * {\@example forms/ts/selectControl/select_control_example.ts region='Component'}
  1893. *
  1894. * ### Customizing option selection
  1895. *
  1896. * Angular uses object identity to select option. It's possible for the identities of items
  1897. * to change while the data does not. This can happen, for example, if the items are produced
  1898. * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
  1899. * second response will produce objects with different identities.
  1900. *
  1901. * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
  1902. * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
  1903. * If `compareWith` is given, Angular selects option by the return value of the function.
  1904. *
  1905. * ```ts
  1906. * const selectedCountriesControl = new FormControl();
  1907. * ```
  1908. *
  1909. * ```
  1910. * <select [compareWith]="compareFn" [formControl]="selectedCountriesControl">
  1911. * <option *ngFor="let country of countries" [ngValue]="country">
  1912. * {{country.name}}
  1913. * </option>
  1914. * </select>
  1915. *
  1916. * compareFn(c1: Country, c2: Country): boolean {
  1917. * return c1 && c2 ? c1.id === c2.id : c1 === c2;
  1918. * }
  1919. * ```
  1920. *
  1921. * **Note:** We listen to the 'change' event because 'input' events aren't fired
  1922. * for selects in Firefox and IE:
  1923. * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350
  1924. * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/
  1925. *
  1926. * \@ngModule ReactiveFormsModule
  1927. * \@ngModule FormsModule
  1928. * \@publicApi
  1929. */
  1930. class SelectControlValueAccessor {
  1931. /**
  1932. * @param {?} _renderer
  1933. * @param {?} _elementRef
  1934. */
  1935. constructor(_renderer, _elementRef) {
  1936. this._renderer = _renderer;
  1937. this._elementRef = _elementRef;
  1938. /**
  1939. * \@internal
  1940. */
  1941. this._optionMap = new Map();
  1942. /**
  1943. * \@internal
  1944. */
  1945. this._idCounter = 0;
  1946. /**
  1947. * \@description
  1948. * The registered callback function called when a change event occurs on the input element.
  1949. */
  1950. this.onChange = (/**
  1951. * @param {?} _
  1952. * @return {?}
  1953. */
  1954. (_) => { });
  1955. /**
  1956. * \@description
  1957. * The registered callback function called when a blur event occurs on the input element.
  1958. */
  1959. this.onTouched = (/**
  1960. * @return {?}
  1961. */
  1962. () => { });
  1963. this._compareWith = ɵlooseIdentical;
  1964. }
  1965. /**
  1966. * \@description
  1967. * Tracks the option comparison algorithm for tracking identities when
  1968. * checking for changes.
  1969. * @param {?} fn
  1970. * @return {?}
  1971. */
  1972. set compareWith(fn) {
  1973. if (typeof fn !== 'function') {
  1974. throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
  1975. }
  1976. this._compareWith = fn;
  1977. }
  1978. /**
  1979. * Sets the "value" property on the input element. The "selectedIndex"
  1980. * property is also set if an ID is provided on the option element.
  1981. *
  1982. * @param {?} value The checked value
  1983. * @return {?}
  1984. */
  1985. writeValue(value) {
  1986. this.value = value;
  1987. /** @type {?} */
  1988. const id = this._getOptionId(value);
  1989. if (id == null) {
  1990. this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);
  1991. }
  1992. /** @type {?} */
  1993. const valueString = _buildValueString(id, value);
  1994. this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString);
  1995. }
  1996. /**
  1997. * \@description
  1998. * Registers a function called when the control value changes.
  1999. *
  2000. * @param {?} fn The callback function
  2001. * @return {?}
  2002. */
  2003. registerOnChange(fn) {
  2004. this.onChange = (/**
  2005. * @param {?} valueString
  2006. * @return {?}
  2007. */
  2008. (valueString) => {
  2009. this.value = this._getOptionValue(valueString);
  2010. fn(this.value);
  2011. });
  2012. }
  2013. /**
  2014. * \@description
  2015. * Registers a function called when the control is touched.
  2016. *
  2017. * @param {?} fn The callback function
  2018. * @return {?}
  2019. */
  2020. registerOnTouched(fn) { this.onTouched = fn; }
  2021. /**
  2022. * Sets the "disabled" property on the select input element.
  2023. *
  2024. * @param {?} isDisabled The disabled value
  2025. * @return {?}
  2026. */
  2027. setDisabledState(isDisabled) {
  2028. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  2029. }
  2030. /**
  2031. * \@internal
  2032. * @return {?}
  2033. */
  2034. _registerOption() { return (this._idCounter++).toString(); }
  2035. /**
  2036. * \@internal
  2037. * @param {?} value
  2038. * @return {?}
  2039. */
  2040. _getOptionId(value) {
  2041. for (const id of Array.from(this._optionMap.keys())) {
  2042. if (this._compareWith(this._optionMap.get(id), value))
  2043. return id;
  2044. }
  2045. return null;
  2046. }
  2047. /**
  2048. * \@internal
  2049. * @param {?} valueString
  2050. * @return {?}
  2051. */
  2052. _getOptionValue(valueString) {
  2053. /** @type {?} */
  2054. const id = _extractId(valueString);
  2055. return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
  2056. }
  2057. }
  2058. SelectControlValueAccessor.decorators = [
  2059. { type: Directive, args: [{
  2060. selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
  2061. host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' },
  2062. providers: [SELECT_VALUE_ACCESSOR]
  2063. },] }
  2064. ];
  2065. /** @nocollapse */
  2066. SelectControlValueAccessor.ctorParameters = () => [
  2067. { type: Renderer2 },
  2068. { type: ElementRef }
  2069. ];
  2070. SelectControlValueAccessor.propDecorators = {
  2071. compareWith: [{ type: Input }]
  2072. };
  2073. /**
  2074. * \@description
  2075. * Marks `<option>` as dynamic, so Angular can be notified when options change.
  2076. *
  2077. * @see `SelectControlValueAccessor`
  2078. *
  2079. * \@ngModule ReactiveFormsModule
  2080. * \@ngModule FormsModule
  2081. * \@publicApi
  2082. */
  2083. class NgSelectOption {
  2084. /**
  2085. * @param {?} _element
  2086. * @param {?} _renderer
  2087. * @param {?} _select
  2088. */
  2089. constructor(_element, _renderer, _select) {
  2090. this._element = _element;
  2091. this._renderer = _renderer;
  2092. this._select = _select;
  2093. if (this._select)
  2094. this.id = this._select._registerOption();
  2095. }
  2096. /**
  2097. * \@description
  2098. * Tracks the value bound to the option element. Unlike the value binding,
  2099. * ngValue supports binding to objects.
  2100. * @param {?} value
  2101. * @return {?}
  2102. */
  2103. set ngValue(value) {
  2104. if (this._select == null)
  2105. return;
  2106. this._select._optionMap.set(this.id, value);
  2107. this._setElementValue(_buildValueString(this.id, value));
  2108. this._select.writeValue(this._select.value);
  2109. }
  2110. /**
  2111. * \@description
  2112. * Tracks simple string values bound to the option element.
  2113. * For objects, use the `ngValue` input binding.
  2114. * @param {?} value
  2115. * @return {?}
  2116. */
  2117. set value(value) {
  2118. this._setElementValue(value);
  2119. if (this._select)
  2120. this._select.writeValue(this._select.value);
  2121. }
  2122. /**
  2123. * \@internal
  2124. * @param {?} value
  2125. * @return {?}
  2126. */
  2127. _setElementValue(value) {
  2128. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  2129. }
  2130. /**
  2131. * \@description
  2132. * Lifecycle method called before the directive's instance is destroyed. For internal use only.
  2133. * @return {?}
  2134. */
  2135. ngOnDestroy() {
  2136. if (this._select) {
  2137. this._select._optionMap.delete(this.id);
  2138. this._select.writeValue(this._select.value);
  2139. }
  2140. }
  2141. }
  2142. NgSelectOption.decorators = [
  2143. { type: Directive, args: [{ selector: 'option' },] }
  2144. ];
  2145. /** @nocollapse */
  2146. NgSelectOption.ctorParameters = () => [
  2147. { type: ElementRef },
  2148. { type: Renderer2 },
  2149. { type: SelectControlValueAccessor, decorators: [{ type: Optional }, { type: Host }] }
  2150. ];
  2151. NgSelectOption.propDecorators = {
  2152. ngValue: [{ type: Input, args: ['ngValue',] }],
  2153. value: [{ type: Input, args: ['value',] }]
  2154. };
  2155. /**
  2156. * @fileoverview added by tsickle
  2157. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2158. */
  2159. /** @type {?} */
  2160. const SELECT_MULTIPLE_VALUE_ACCESSOR = {
  2161. provide: NG_VALUE_ACCESSOR,
  2162. useExisting: forwardRef((/**
  2163. * @return {?}
  2164. */
  2165. () => SelectMultipleControlValueAccessor)),
  2166. multi: true
  2167. };
  2168. /**
  2169. * @param {?} id
  2170. * @param {?} value
  2171. * @return {?}
  2172. */
  2173. function _buildValueString$1(id, value) {
  2174. if (id == null)
  2175. return `${value}`;
  2176. if (typeof value === 'string')
  2177. value = `'${value}'`;
  2178. if (value && typeof value === 'object')
  2179. value = 'Object';
  2180. return `${id}: ${value}`.slice(0, 50);
  2181. }
  2182. /**
  2183. * @param {?} valueString
  2184. * @return {?}
  2185. */
  2186. function _extractId$1(valueString) {
  2187. return valueString.split(':')[0];
  2188. }
  2189. /**
  2190. * \@description
  2191. * The `ControlValueAccessor` for writing multi-select control values and listening to multi-select control
  2192. * changes. The value accessor is used by the `FormControlDirective`, `FormControlName`, and `NgModel`
  2193. * directives.
  2194. *
  2195. * @see `SelectControlValueAccessor`
  2196. *
  2197. * \@usageNotes
  2198. *
  2199. * ### Using a multi-select control
  2200. *
  2201. * The follow example shows you how to use a multi-select control with a reactive form.
  2202. *
  2203. * ```ts
  2204. * const countryControl = new FormControl();
  2205. * ```
  2206. *
  2207. * ```
  2208. * <select multiple name="countries" [formControl]="countryControl">
  2209. * <option *ngFor="let country of countries" [ngValue]="country">
  2210. * {{ country.name }}
  2211. * </option>
  2212. * </select>
  2213. * ```
  2214. *
  2215. * ### Customizing option selection
  2216. *
  2217. * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
  2218. * See the `SelectControlValueAccessor` for usage.
  2219. *
  2220. * \@ngModule ReactiveFormsModule
  2221. * \@ngModule FormsModule
  2222. * \@publicApi
  2223. */
  2224. class SelectMultipleControlValueAccessor {
  2225. /**
  2226. * @param {?} _renderer
  2227. * @param {?} _elementRef
  2228. */
  2229. constructor(_renderer, _elementRef) {
  2230. this._renderer = _renderer;
  2231. this._elementRef = _elementRef;
  2232. /**
  2233. * \@internal
  2234. */
  2235. this._optionMap = new Map();
  2236. /**
  2237. * \@internal
  2238. */
  2239. this._idCounter = 0;
  2240. /**
  2241. * \@description
  2242. * The registered callback function called when a change event occurs on the input element.
  2243. */
  2244. this.onChange = (/**
  2245. * @param {?} _
  2246. * @return {?}
  2247. */
  2248. (_) => { });
  2249. /**
  2250. * \@description
  2251. * The registered callback function called when a blur event occurs on the input element.
  2252. */
  2253. this.onTouched = (/**
  2254. * @return {?}
  2255. */
  2256. () => { });
  2257. this._compareWith = ɵlooseIdentical;
  2258. }
  2259. /**
  2260. * \@description
  2261. * Tracks the option comparison algorithm for tracking identities when
  2262. * checking for changes.
  2263. * @param {?} fn
  2264. * @return {?}
  2265. */
  2266. set compareWith(fn) {
  2267. if (typeof fn !== 'function') {
  2268. throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
  2269. }
  2270. this._compareWith = fn;
  2271. }
  2272. /**
  2273. * \@description
  2274. * Sets the "value" property on one or of more
  2275. * of the select's options.
  2276. *
  2277. * @param {?} value The value
  2278. * @return {?}
  2279. */
  2280. writeValue(value) {
  2281. this.value = value;
  2282. /** @type {?} */
  2283. let optionSelectedStateSetter;
  2284. if (Array.isArray(value)) {
  2285. // convert values to ids
  2286. /** @type {?} */
  2287. const ids = value.map((/**
  2288. * @param {?} v
  2289. * @return {?}
  2290. */
  2291. (v) => this._getOptionId(v)));
  2292. optionSelectedStateSetter = (/**
  2293. * @param {?} opt
  2294. * @param {?} o
  2295. * @return {?}
  2296. */
  2297. (opt, o) => { opt._setSelected(ids.indexOf(o.toString()) > -1); });
  2298. }
  2299. else {
  2300. optionSelectedStateSetter = (/**
  2301. * @param {?} opt
  2302. * @param {?} o
  2303. * @return {?}
  2304. */
  2305. (opt, o) => { opt._setSelected(false); });
  2306. }
  2307. this._optionMap.forEach(optionSelectedStateSetter);
  2308. }
  2309. /**
  2310. * \@description
  2311. * Registers a function called when the control value changes
  2312. * and writes an array of the selected options.
  2313. *
  2314. * @param {?} fn The callback function
  2315. * @return {?}
  2316. */
  2317. registerOnChange(fn) {
  2318. this.onChange = (/**
  2319. * @param {?} _
  2320. * @return {?}
  2321. */
  2322. (_) => {
  2323. /** @type {?} */
  2324. const selected = [];
  2325. if (_.hasOwnProperty('selectedOptions')) {
  2326. /** @type {?} */
  2327. const options = _.selectedOptions;
  2328. for (let i = 0; i < options.length; i++) {
  2329. /** @type {?} */
  2330. const opt = options.item(i);
  2331. /** @type {?} */
  2332. const val = this._getOptionValue(opt.value);
  2333. selected.push(val);
  2334. }
  2335. }
  2336. // Degrade on IE
  2337. else {
  2338. /** @type {?} */
  2339. const options = (/** @type {?} */ (_.options));
  2340. for (let i = 0; i < options.length; i++) {
  2341. /** @type {?} */
  2342. const opt = options.item(i);
  2343. if (opt.selected) {
  2344. /** @type {?} */
  2345. const val = this._getOptionValue(opt.value);
  2346. selected.push(val);
  2347. }
  2348. }
  2349. }
  2350. this.value = selected;
  2351. fn(selected);
  2352. });
  2353. }
  2354. /**
  2355. * \@description
  2356. * Registers a function called when the control is touched.
  2357. *
  2358. * @param {?} fn The callback function
  2359. * @return {?}
  2360. */
  2361. registerOnTouched(fn) { this.onTouched = fn; }
  2362. /**
  2363. * Sets the "disabled" property on the select input element.
  2364. *
  2365. * @param {?} isDisabled The disabled value
  2366. * @return {?}
  2367. */
  2368. setDisabledState(isDisabled) {
  2369. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  2370. }
  2371. /**
  2372. * \@internal
  2373. * @param {?} value
  2374. * @return {?}
  2375. */
  2376. _registerOption(value) {
  2377. /** @type {?} */
  2378. const id = (this._idCounter++).toString();
  2379. this._optionMap.set(id, value);
  2380. return id;
  2381. }
  2382. /**
  2383. * \@internal
  2384. * @param {?} value
  2385. * @return {?}
  2386. */
  2387. _getOptionId(value) {
  2388. for (const id of Array.from(this._optionMap.keys())) {
  2389. if (this._compareWith((/** @type {?} */ (this._optionMap.get(id)))._value, value))
  2390. return id;
  2391. }
  2392. return null;
  2393. }
  2394. /**
  2395. * \@internal
  2396. * @param {?} valueString
  2397. * @return {?}
  2398. */
  2399. _getOptionValue(valueString) {
  2400. /** @type {?} */
  2401. const id = _extractId$1(valueString);
  2402. return this._optionMap.has(id) ? (/** @type {?} */ (this._optionMap.get(id)))._value : valueString;
  2403. }
  2404. }
  2405. SelectMultipleControlValueAccessor.decorators = [
  2406. { type: Directive, args: [{
  2407. selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
  2408. host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' },
  2409. providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
  2410. },] }
  2411. ];
  2412. /** @nocollapse */
  2413. SelectMultipleControlValueAccessor.ctorParameters = () => [
  2414. { type: Renderer2 },
  2415. { type: ElementRef }
  2416. ];
  2417. SelectMultipleControlValueAccessor.propDecorators = {
  2418. compareWith: [{ type: Input }]
  2419. };
  2420. /**
  2421. * \@description
  2422. * Marks `<option>` as dynamic, so Angular can be notified when options change.
  2423. *
  2424. * @see `SelectMultipleControlValueAccessor`
  2425. *
  2426. * \@ngModule ReactiveFormsModule
  2427. * \@ngModule FormsModule
  2428. * \@publicApi
  2429. */
  2430. class ɵNgSelectMultipleOption {
  2431. /**
  2432. * @param {?} _element
  2433. * @param {?} _renderer
  2434. * @param {?} _select
  2435. */
  2436. constructor(_element, _renderer, _select) {
  2437. this._element = _element;
  2438. this._renderer = _renderer;
  2439. this._select = _select;
  2440. if (this._select) {
  2441. this.id = this._select._registerOption(this);
  2442. }
  2443. }
  2444. /**
  2445. * \@description
  2446. * Tracks the value bound to the option element. Unlike the value binding,
  2447. * ngValue supports binding to objects.
  2448. * @param {?} value
  2449. * @return {?}
  2450. */
  2451. set ngValue(value) {
  2452. if (this._select == null)
  2453. return;
  2454. this._value = value;
  2455. this._setElementValue(_buildValueString$1(this.id, value));
  2456. this._select.writeValue(this._select.value);
  2457. }
  2458. /**
  2459. * \@description
  2460. * Tracks simple string values bound to the option element.
  2461. * For objects, use the `ngValue` input binding.
  2462. * @param {?} value
  2463. * @return {?}
  2464. */
  2465. set value(value) {
  2466. if (this._select) {
  2467. this._value = value;
  2468. this._setElementValue(_buildValueString$1(this.id, value));
  2469. this._select.writeValue(this._select.value);
  2470. }
  2471. else {
  2472. this._setElementValue(value);
  2473. }
  2474. }
  2475. /**
  2476. * \@internal
  2477. * @param {?} value
  2478. * @return {?}
  2479. */
  2480. _setElementValue(value) {
  2481. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  2482. }
  2483. /**
  2484. * \@internal
  2485. * @param {?} selected
  2486. * @return {?}
  2487. */
  2488. _setSelected(selected) {
  2489. this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
  2490. }
  2491. /**
  2492. * \@description
  2493. * Lifecycle method called before the directive's instance is destroyed. For internal use only.
  2494. * @return {?}
  2495. */
  2496. ngOnDestroy() {
  2497. if (this._select) {
  2498. this._select._optionMap.delete(this.id);
  2499. this._select.writeValue(this._select.value);
  2500. }
  2501. }
  2502. }
  2503. ɵNgSelectMultipleOption.decorators = [
  2504. { type: Directive, args: [{ selector: 'option' },] }
  2505. ];
  2506. /** @nocollapse */
  2507. ɵNgSelectMultipleOption.ctorParameters = () => [
  2508. { type: ElementRef },
  2509. { type: Renderer2 },
  2510. { type: SelectMultipleControlValueAccessor, decorators: [{ type: Optional }, { type: Host }] }
  2511. ];
  2512. ɵNgSelectMultipleOption.propDecorators = {
  2513. ngValue: [{ type: Input, args: ['ngValue',] }],
  2514. value: [{ type: Input, args: ['value',] }]
  2515. };
  2516. /**
  2517. * @fileoverview added by tsickle
  2518. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2519. */
  2520. /**
  2521. * @param {?} name
  2522. * @param {?} parent
  2523. * @return {?}
  2524. */
  2525. function controlPath(name, parent) {
  2526. return [...(/** @type {?} */ (parent.path)), name];
  2527. }
  2528. /**
  2529. * @param {?} control
  2530. * @param {?} dir
  2531. * @return {?}
  2532. */
  2533. function setUpControl(control, dir) {
  2534. if (!control)
  2535. _throwError(dir, 'Cannot find control with');
  2536. if (!dir.valueAccessor)
  2537. _throwError(dir, 'No value accessor for form control with');
  2538. control.validator = Validators.compose([(/** @type {?} */ (control.validator)), dir.validator]);
  2539. control.asyncValidator = Validators.composeAsync([(/** @type {?} */ (control.asyncValidator)), dir.asyncValidator]);
  2540. (/** @type {?} */ (dir.valueAccessor)).writeValue(control.value);
  2541. setUpViewChangePipeline(control, dir);
  2542. setUpModelChangePipeline(control, dir);
  2543. setUpBlurPipeline(control, dir);
  2544. if ((/** @type {?} */ (dir.valueAccessor)).setDisabledState) {
  2545. control.registerOnDisabledChange((/**
  2546. * @param {?} isDisabled
  2547. * @return {?}
  2548. */
  2549. (isDisabled) => { (/** @type {?} */ ((/** @type {?} */ (dir.valueAccessor)).setDisabledState))(isDisabled); }));
  2550. }
  2551. // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
  2552. dir._rawValidators.forEach((/**
  2553. * @param {?} validator
  2554. * @return {?}
  2555. */
  2556. (validator) => {
  2557. if (((/** @type {?} */ (validator))).registerOnValidatorChange)
  2558. (/** @type {?} */ (((/** @type {?} */ (validator))).registerOnValidatorChange))((/**
  2559. * @return {?}
  2560. */
  2561. () => control.updateValueAndValidity()));
  2562. }));
  2563. dir._rawAsyncValidators.forEach((/**
  2564. * @param {?} validator
  2565. * @return {?}
  2566. */
  2567. (validator) => {
  2568. if (((/** @type {?} */ (validator))).registerOnValidatorChange)
  2569. (/** @type {?} */ (((/** @type {?} */ (validator))).registerOnValidatorChange))((/**
  2570. * @return {?}
  2571. */
  2572. () => control.updateValueAndValidity()));
  2573. }));
  2574. }
  2575. /**
  2576. * @param {?} control
  2577. * @param {?} dir
  2578. * @return {?}
  2579. */
  2580. function cleanUpControl(control, dir) {
  2581. (/** @type {?} */ (dir.valueAccessor)).registerOnChange((/**
  2582. * @return {?}
  2583. */
  2584. () => _noControlError(dir)));
  2585. (/** @type {?} */ (dir.valueAccessor)).registerOnTouched((/**
  2586. * @return {?}
  2587. */
  2588. () => _noControlError(dir)));
  2589. dir._rawValidators.forEach((/**
  2590. * @param {?} validator
  2591. * @return {?}
  2592. */
  2593. (validator) => {
  2594. if (validator.registerOnValidatorChange) {
  2595. validator.registerOnValidatorChange(null);
  2596. }
  2597. }));
  2598. dir._rawAsyncValidators.forEach((/**
  2599. * @param {?} validator
  2600. * @return {?}
  2601. */
  2602. (validator) => {
  2603. if (validator.registerOnValidatorChange) {
  2604. validator.registerOnValidatorChange(null);
  2605. }
  2606. }));
  2607. if (control)
  2608. control._clearChangeFns();
  2609. }
  2610. /**
  2611. * @param {?} control
  2612. * @param {?} dir
  2613. * @return {?}
  2614. */
  2615. function setUpViewChangePipeline(control, dir) {
  2616. (/** @type {?} */ (dir.valueAccessor)).registerOnChange((/**
  2617. * @param {?} newValue
  2618. * @return {?}
  2619. */
  2620. (newValue) => {
  2621. control._pendingValue = newValue;
  2622. control._pendingChange = true;
  2623. control._pendingDirty = true;
  2624. if (control.updateOn === 'change')
  2625. updateControl(control, dir);
  2626. }));
  2627. }
  2628. /**
  2629. * @param {?} control
  2630. * @param {?} dir
  2631. * @return {?}
  2632. */
  2633. function setUpBlurPipeline(control, dir) {
  2634. (/** @type {?} */ (dir.valueAccessor)).registerOnTouched((/**
  2635. * @return {?}
  2636. */
  2637. () => {
  2638. control._pendingTouched = true;
  2639. if (control.updateOn === 'blur' && control._pendingChange)
  2640. updateControl(control, dir);
  2641. if (control.updateOn !== 'submit')
  2642. control.markAsTouched();
  2643. }));
  2644. }
  2645. /**
  2646. * @param {?} control
  2647. * @param {?} dir
  2648. * @return {?}
  2649. */
  2650. function updateControl(control, dir) {
  2651. if (control._pendingDirty)
  2652. control.markAsDirty();
  2653. control.setValue(control._pendingValue, { emitModelToViewChange: false });
  2654. dir.viewToModelUpdate(control._pendingValue);
  2655. control._pendingChange = false;
  2656. }
  2657. /**
  2658. * @param {?} control
  2659. * @param {?} dir
  2660. * @return {?}
  2661. */
  2662. function setUpModelChangePipeline(control, dir) {
  2663. control.registerOnChange((/**
  2664. * @param {?} newValue
  2665. * @param {?} emitModelEvent
  2666. * @return {?}
  2667. */
  2668. (newValue, emitModelEvent) => {
  2669. // control -> view
  2670. (/** @type {?} */ (dir.valueAccessor)).writeValue(newValue);
  2671. // control -> ngModel
  2672. if (emitModelEvent)
  2673. dir.viewToModelUpdate(newValue);
  2674. }));
  2675. }
  2676. /**
  2677. * @param {?} control
  2678. * @param {?} dir
  2679. * @return {?}
  2680. */
  2681. function setUpFormContainer(control, dir) {
  2682. if (control == null)
  2683. _throwError(dir, 'Cannot find control with');
  2684. control.validator = Validators.compose([control.validator, dir.validator]);
  2685. control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
  2686. }
  2687. /**
  2688. * @param {?} dir
  2689. * @return {?}
  2690. */
  2691. function _noControlError(dir) {
  2692. return _throwError(dir, 'There is no FormControl instance attached to form control element with');
  2693. }
  2694. /**
  2695. * @param {?} dir
  2696. * @param {?} message
  2697. * @return {?}
  2698. */
  2699. function _throwError(dir, message) {
  2700. /** @type {?} */
  2701. let messageEnd;
  2702. if ((/** @type {?} */ (dir.path)).length > 1) {
  2703. messageEnd = `path: '${(/** @type {?} */ (dir.path)).join(' -> ')}'`;
  2704. }
  2705. else if ((/** @type {?} */ (dir.path))[0]) {
  2706. messageEnd = `name: '${dir.path}'`;
  2707. }
  2708. else {
  2709. messageEnd = 'unspecified name attribute';
  2710. }
  2711. throw new Error(`${message} ${messageEnd}`);
  2712. }
  2713. /**
  2714. * @param {?} validators
  2715. * @return {?}
  2716. */
  2717. function composeValidators(validators) {
  2718. return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
  2719. }
  2720. /**
  2721. * @param {?} validators
  2722. * @return {?}
  2723. */
  2724. function composeAsyncValidators(validators) {
  2725. return validators != null ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
  2726. null;
  2727. }
  2728. /**
  2729. * @param {?} changes
  2730. * @param {?} viewModel
  2731. * @return {?}
  2732. */
  2733. function isPropertyUpdated(changes, viewModel) {
  2734. if (!changes.hasOwnProperty('model'))
  2735. return false;
  2736. /** @type {?} */
  2737. const change = changes['model'];
  2738. if (change.isFirstChange())
  2739. return true;
  2740. return !ɵlooseIdentical(viewModel, change.currentValue);
  2741. }
  2742. /** @type {?} */
  2743. const BUILTIN_ACCESSORS = [
  2744. CheckboxControlValueAccessor,
  2745. RangeValueAccessor,
  2746. NumberValueAccessor,
  2747. SelectControlValueAccessor,
  2748. SelectMultipleControlValueAccessor,
  2749. RadioControlValueAccessor,
  2750. ];
  2751. /**
  2752. * @param {?} valueAccessor
  2753. * @return {?}
  2754. */
  2755. function isBuiltInAccessor(valueAccessor) {
  2756. return BUILTIN_ACCESSORS.some((/**
  2757. * @param {?} a
  2758. * @return {?}
  2759. */
  2760. a => valueAccessor.constructor === a));
  2761. }
  2762. /**
  2763. * @param {?} form
  2764. * @param {?} directives
  2765. * @return {?}
  2766. */
  2767. function syncPendingControls(form, directives) {
  2768. form._syncPendingControls();
  2769. directives.forEach((/**
  2770. * @param {?} dir
  2771. * @return {?}
  2772. */
  2773. dir => {
  2774. /** @type {?} */
  2775. const control = (/** @type {?} */ (dir.control));
  2776. if (control.updateOn === 'submit' && control._pendingChange) {
  2777. dir.viewToModelUpdate(control._pendingValue);
  2778. control._pendingChange = false;
  2779. }
  2780. }));
  2781. }
  2782. // TODO: vsavkin remove it once https://github.com/angular/angular/issues/3011 is implemented
  2783. /**
  2784. * @param {?} dir
  2785. * @param {?} valueAccessors
  2786. * @return {?}
  2787. */
  2788. function selectValueAccessor(dir, valueAccessors) {
  2789. if (!valueAccessors)
  2790. return null;
  2791. if (!Array.isArray(valueAccessors))
  2792. _throwError(dir, 'Value accessor was not provided as an array for form control with');
  2793. /** @type {?} */
  2794. let defaultAccessor = undefined;
  2795. /** @type {?} */
  2796. let builtinAccessor = undefined;
  2797. /** @type {?} */
  2798. let customAccessor = undefined;
  2799. valueAccessors.forEach((/**
  2800. * @param {?} v
  2801. * @return {?}
  2802. */
  2803. (v) => {
  2804. if (v.constructor === DefaultValueAccessor) {
  2805. defaultAccessor = v;
  2806. }
  2807. else if (isBuiltInAccessor(v)) {
  2808. if (builtinAccessor)
  2809. _throwError(dir, 'More than one built-in value accessor matches form control with');
  2810. builtinAccessor = v;
  2811. }
  2812. else {
  2813. if (customAccessor)
  2814. _throwError(dir, 'More than one custom value accessor matches form control with');
  2815. customAccessor = v;
  2816. }
  2817. }));
  2818. if (customAccessor)
  2819. return customAccessor;
  2820. if (builtinAccessor)
  2821. return builtinAccessor;
  2822. if (defaultAccessor)
  2823. return defaultAccessor;
  2824. _throwError(dir, 'No valid value accessor for form control with');
  2825. return null;
  2826. }
  2827. /**
  2828. * @template T
  2829. * @param {?} list
  2830. * @param {?} el
  2831. * @return {?}
  2832. */
  2833. function removeDir(list, el) {
  2834. /** @type {?} */
  2835. const index = list.indexOf(el);
  2836. if (index > -1)
  2837. list.splice(index, 1);
  2838. }
  2839. // TODO(kara): remove after deprecation period
  2840. /**
  2841. * @param {?} name
  2842. * @param {?} type
  2843. * @param {?} instance
  2844. * @param {?} warningConfig
  2845. * @return {?}
  2846. */
  2847. function _ngModelWarning(name, type, instance, warningConfig) {
  2848. if (!isDevMode() || warningConfig === 'never')
  2849. return;
  2850. if (((warningConfig === null || warningConfig === 'once') && !type._ngModelWarningSentOnce) ||
  2851. (warningConfig === 'always' && !instance._ngModelWarningSent)) {
  2852. ReactiveErrors.ngModelWarning(name);
  2853. type._ngModelWarningSentOnce = true;
  2854. instance._ngModelWarningSent = true;
  2855. }
  2856. }
  2857. /**
  2858. * @fileoverview added by tsickle
  2859. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  2860. */
  2861. /**
  2862. * Reports that a FormControl is valid, meaning that no errors exist in the input value.
  2863. *
  2864. * @see `status`
  2865. * @type {?}
  2866. */
  2867. const VALID = 'VALID';
  2868. /**
  2869. * Reports that a FormControl is invalid, meaning that an error exists in the input value.
  2870. *
  2871. * @see `status`
  2872. * @type {?}
  2873. */
  2874. const INVALID = 'INVALID';
  2875. /**
  2876. * Reports that a FormControl is pending, meaning that that async validation is occurring and
  2877. * errors are not yet available for the input value.
  2878. *
  2879. * @see `markAsPending`
  2880. * @see `status`
  2881. * @type {?}
  2882. */
  2883. const PENDING = 'PENDING';
  2884. /**
  2885. * Reports that a FormControl is disabled, meaning that the control is exempt from ancestor
  2886. * calculations of validity or value.
  2887. *
  2888. * @see `markAsDisabled`
  2889. * @see `status`
  2890. * @type {?}
  2891. */
  2892. const DISABLED = 'DISABLED';
  2893. /**
  2894. * @param {?} control
  2895. * @param {?} path
  2896. * @param {?} delimiter
  2897. * @return {?}
  2898. */
  2899. function _find(control, path, delimiter) {
  2900. if (path == null)
  2901. return null;
  2902. if (!(path instanceof Array)) {
  2903. path = ((/** @type {?} */ (path))).split(delimiter);
  2904. }
  2905. if (path instanceof Array && (path.length === 0))
  2906. return null;
  2907. return ((/** @type {?} */ (path))).reduce((/**
  2908. * @param {?} v
  2909. * @param {?} name
  2910. * @return {?}
  2911. */
  2912. (v, name) => {
  2913. if (v instanceof FormGroup) {
  2914. return v.controls.hasOwnProperty((/** @type {?} */ (name))) ? v.controls[name] : null;
  2915. }
  2916. if (v instanceof FormArray) {
  2917. return v.at((/** @type {?} */ (name))) || null;
  2918. }
  2919. return null;
  2920. }), control);
  2921. }
  2922. /**
  2923. * @param {?=} validatorOrOpts
  2924. * @return {?}
  2925. */
  2926. function coerceToValidator(validatorOrOpts) {
  2927. /** @type {?} */
  2928. const validator = (/** @type {?} */ ((isOptionsObj(validatorOrOpts) ? ((/** @type {?} */ (validatorOrOpts))).validators :
  2929. validatorOrOpts)));
  2930. return Array.isArray(validator) ? composeValidators(validator) : validator || null;
  2931. }
  2932. /**
  2933. * @param {?=} asyncValidator
  2934. * @param {?=} validatorOrOpts
  2935. * @return {?}
  2936. */
  2937. function coerceToAsyncValidator(asyncValidator, validatorOrOpts) {
  2938. /** @type {?} */
  2939. const origAsyncValidator = (/** @type {?} */ ((isOptionsObj(validatorOrOpts) ? ((/** @type {?} */ (validatorOrOpts))).asyncValidators :
  2940. asyncValidator)));
  2941. return Array.isArray(origAsyncValidator) ? composeAsyncValidators(origAsyncValidator) :
  2942. origAsyncValidator || null;
  2943. }
  2944. /**
  2945. * @param {?=} validatorOrOpts
  2946. * @return {?}
  2947. */
  2948. function isOptionsObj(validatorOrOpts) {
  2949. return validatorOrOpts != null && !Array.isArray(validatorOrOpts) &&
  2950. typeof validatorOrOpts === 'object';
  2951. }
  2952. /**
  2953. * This is the base class for `FormControl`, `FormGroup`, and `FormArray`.
  2954. *
  2955. * It provides some of the shared behavior that all controls and groups of controls have, like
  2956. * running validators, calculating status, and resetting state. It also defines the properties
  2957. * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
  2958. * instantiated directly.
  2959. *
  2960. * @see [Forms Guide](/guide/forms)
  2961. * @see [Reactive Forms Guide](/guide/reactive-forms)
  2962. * @see [Dynamic Forms Guide](/guide/dynamic-form)
  2963. *
  2964. * \@publicApi
  2965. * @abstract
  2966. */
  2967. class AbstractControl {
  2968. /**
  2969. * Initialize the AbstractControl instance.
  2970. *
  2971. * @param {?} validator The function that determines the synchronous validity of this control.
  2972. * @param {?} asyncValidator The function that determines the asynchronous validity of this
  2973. * control.
  2974. */
  2975. constructor(validator, asyncValidator) {
  2976. this.validator = validator;
  2977. this.asyncValidator = asyncValidator;
  2978. /**
  2979. * \@internal
  2980. */
  2981. this._onCollectionChange = (/**
  2982. * @return {?}
  2983. */
  2984. () => { });
  2985. /**
  2986. * A control is `pristine` if the user has not yet changed
  2987. * the value in the UI.
  2988. *
  2989. * @return True if the user has not yet changed the value in the UI; compare `dirty`.
  2990. * Programmatic changes to a control's value do not mark it dirty.
  2991. */
  2992. this.pristine = true;
  2993. /**
  2994. * True if the control is marked as `touched`.
  2995. *
  2996. * A control is marked `touched` once the user has triggered
  2997. * a `blur` event on it.
  2998. */
  2999. this.touched = false;
  3000. /**
  3001. * \@internal
  3002. */
  3003. this._onDisabledChange = [];
  3004. }
  3005. /**
  3006. * The parent control.
  3007. * @return {?}
  3008. */
  3009. get parent() { return this._parent; }
  3010. /**
  3011. * A control is `valid` when its `status` is `VALID`.
  3012. *
  3013. * @see {\@link AbstractControl.status}
  3014. *
  3015. * @return {?} True if the control has passed all of its validation tests,
  3016. * false otherwise.
  3017. */
  3018. get valid() { return this.status === VALID; }
  3019. /**
  3020. * A control is `invalid` when its `status` is `INVALID`.
  3021. *
  3022. * @see {\@link AbstractControl.status}
  3023. *
  3024. * @return {?} True if this control has failed one or more of its validation checks,
  3025. * false otherwise.
  3026. */
  3027. get invalid() { return this.status === INVALID; }
  3028. /**
  3029. * A control is `pending` when its `status` is `PENDING`.
  3030. *
  3031. * @see {\@link AbstractControl.status}
  3032. *
  3033. * @return {?} True if this control is in the process of conducting a validation check,
  3034. * false otherwise.
  3035. */
  3036. get pending() { return this.status == PENDING; }
  3037. /**
  3038. * A control is `disabled` when its `status` is `DISABLED`.
  3039. *
  3040. * Disabled controls are exempt from validation checks and
  3041. * are not included in the aggregate value of their ancestor
  3042. * controls.
  3043. *
  3044. * @see {\@link AbstractControl.status}
  3045. *
  3046. * @return {?} True if the control is disabled, false otherwise.
  3047. */
  3048. get disabled() { return this.status === DISABLED; }
  3049. /**
  3050. * A control is `enabled` as long as its `status` is not `DISABLED`.
  3051. *
  3052. * @see {\@link AbstractControl.status}
  3053. *
  3054. * @return {?} True if the control has any status other than 'DISABLED',
  3055. * false if the status is 'DISABLED'.
  3056. *
  3057. */
  3058. get enabled() { return this.status !== DISABLED; }
  3059. /**
  3060. * A control is `dirty` if the user has changed the value
  3061. * in the UI.
  3062. *
  3063. * @return {?} True if the user has changed the value of this control in the UI; compare `pristine`.
  3064. * Programmatic changes to a control's value do not mark it dirty.
  3065. */
  3066. get dirty() { return !this.pristine; }
  3067. /**
  3068. * True if the control has not been marked as touched
  3069. *
  3070. * A control is `untouched` if the user has not yet triggered
  3071. * a `blur` event on it.
  3072. * @return {?}
  3073. */
  3074. get untouched() { return !this.touched; }
  3075. /**
  3076. * Reports the update strategy of the `AbstractControl` (meaning
  3077. * the event on which the control updates itself).
  3078. * Possible values: `'change'` | `'blur'` | `'submit'`
  3079. * Default value: `'change'`
  3080. * @return {?}
  3081. */
  3082. get updateOn() {
  3083. return this._updateOn ? this._updateOn : (this.parent ? this.parent.updateOn : 'change');
  3084. }
  3085. /**
  3086. * Sets the synchronous validators that are active on this control. Calling
  3087. * this overwrites any existing sync validators.
  3088. * @param {?} newValidator
  3089. * @return {?}
  3090. */
  3091. setValidators(newValidator) {
  3092. this.validator = coerceToValidator(newValidator);
  3093. }
  3094. /**
  3095. * Sets the async validators that are active on this control. Calling this
  3096. * overwrites any existing async validators.
  3097. * @param {?} newValidator
  3098. * @return {?}
  3099. */
  3100. setAsyncValidators(newValidator) {
  3101. this.asyncValidator = coerceToAsyncValidator(newValidator);
  3102. }
  3103. /**
  3104. * Empties out the sync validator list.
  3105. * @return {?}
  3106. */
  3107. clearValidators() { this.validator = null; }
  3108. /**
  3109. * Empties out the async validator list.
  3110. * @return {?}
  3111. */
  3112. clearAsyncValidators() { this.asyncValidator = null; }
  3113. /**
  3114. * Marks the control as `touched`. A control is touched by focus and
  3115. * blur events that do not change the value.
  3116. *
  3117. * @see `markAsUntouched()` / `markAsDirty()` / `markAsPristine()`
  3118. *
  3119. * @param {?=} opts Configuration options that determine how the control propagates changes
  3120. * and emits events events after marking is applied.
  3121. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3122. * marks all direct ancestors. Default is false.
  3123. * @return {?}
  3124. */
  3125. markAsTouched(opts = {}) {
  3126. ((/** @type {?} */ (this))).touched = true;
  3127. if (this._parent && !opts.onlySelf) {
  3128. this._parent.markAsTouched(opts);
  3129. }
  3130. }
  3131. /**
  3132. * Marks the control and all its descendant controls as `touched`.
  3133. * @see `markAsTouched()`
  3134. * @return {?}
  3135. */
  3136. markAllAsTouched() {
  3137. this.markAsTouched({ onlySelf: true });
  3138. this._forEachChild((/**
  3139. * @param {?} control
  3140. * @return {?}
  3141. */
  3142. (control) => control.markAllAsTouched()));
  3143. }
  3144. /**
  3145. * Marks the control as `untouched`.
  3146. *
  3147. * If the control has any children, also marks all children as `untouched`
  3148. * and recalculates the `touched` status of all parent controls.
  3149. *
  3150. * @see `markAsTouched()` / `markAsDirty()` / `markAsPristine()`
  3151. *
  3152. * @param {?=} opts Configuration options that determine how the control propagates changes
  3153. * and emits events after the marking is applied.
  3154. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3155. * marks all direct ancestors. Default is false.
  3156. * @return {?}
  3157. */
  3158. markAsUntouched(opts = {}) {
  3159. ((/** @type {?} */ (this))).touched = false;
  3160. this._pendingTouched = false;
  3161. this._forEachChild((/**
  3162. * @param {?} control
  3163. * @return {?}
  3164. */
  3165. (control) => { control.markAsUntouched({ onlySelf: true }); }));
  3166. if (this._parent && !opts.onlySelf) {
  3167. this._parent._updateTouched(opts);
  3168. }
  3169. }
  3170. /**
  3171. * Marks the control as `dirty`. A control becomes dirty when
  3172. * the control's value is changed through the UI; compare `markAsTouched`.
  3173. *
  3174. * @see `markAsTouched()` / `markAsUntouched()` / `markAsPristine()`
  3175. *
  3176. * @param {?=} opts Configuration options that determine how the control propagates changes
  3177. * and emits events after marking is applied.
  3178. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3179. * marks all direct ancestors. Default is false.
  3180. * @return {?}
  3181. */
  3182. markAsDirty(opts = {}) {
  3183. ((/** @type {?} */ (this))).pristine = false;
  3184. if (this._parent && !opts.onlySelf) {
  3185. this._parent.markAsDirty(opts);
  3186. }
  3187. }
  3188. /**
  3189. * Marks the control as `pristine`.
  3190. *
  3191. * If the control has any children, marks all children as `pristine`,
  3192. * and recalculates the `pristine` status of all parent
  3193. * controls.
  3194. *
  3195. * @see `markAsTouched()` / `markAsUntouched()` / `markAsDirty()`
  3196. *
  3197. * @param {?=} opts Configuration options that determine how the control emits events after
  3198. * marking is applied.
  3199. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3200. * marks all direct ancestors. Default is false..
  3201. * @return {?}
  3202. */
  3203. markAsPristine(opts = {}) {
  3204. ((/** @type {?} */ (this))).pristine = true;
  3205. this._pendingDirty = false;
  3206. this._forEachChild((/**
  3207. * @param {?} control
  3208. * @return {?}
  3209. */
  3210. (control) => { control.markAsPristine({ onlySelf: true }); }));
  3211. if (this._parent && !opts.onlySelf) {
  3212. this._parent._updatePristine(opts);
  3213. }
  3214. }
  3215. /**
  3216. * Marks the control as `pending`.
  3217. *
  3218. * A control is pending while the control performs async validation.
  3219. *
  3220. * @see {\@link AbstractControl.status}
  3221. *
  3222. * @param {?=} opts Configuration options that determine how the control propagates changes and
  3223. * emits events after marking is applied.
  3224. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3225. * marks all direct ancestors. Default is false..
  3226. * * `emitEvent`: When true or not supplied (the default), the `statusChanges`
  3227. * observable emits an event with the latest status the control is marked pending.
  3228. * When false, no events are emitted.
  3229. *
  3230. * @return {?}
  3231. */
  3232. markAsPending(opts = {}) {
  3233. ((/** @type {?} */ (this))).status = PENDING;
  3234. if (opts.emitEvent !== false) {
  3235. ((/** @type {?} */ (this.statusChanges))).emit(this.status);
  3236. }
  3237. if (this._parent && !opts.onlySelf) {
  3238. this._parent.markAsPending(opts);
  3239. }
  3240. }
  3241. /**
  3242. * Disables the control. This means the control is exempt from validation checks and
  3243. * excluded from the aggregate value of any parent. Its status is `DISABLED`.
  3244. *
  3245. * If the control has children, all children are also disabled.
  3246. *
  3247. * @see {\@link AbstractControl.status}
  3248. *
  3249. * @param {?=} opts Configuration options that determine how the control propagates
  3250. * changes and emits events after the control is disabled.
  3251. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3252. * marks all direct ancestors. Default is false..
  3253. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  3254. * `valueChanges`
  3255. * observables emit events with the latest status and value when the control is disabled.
  3256. * When false, no events are emitted.
  3257. * @return {?}
  3258. */
  3259. disable(opts = {}) {
  3260. // If parent has been marked artificially dirty we don't want to re-calculate the
  3261. // parent's dirtiness based on the children.
  3262. /** @type {?} */
  3263. const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
  3264. ((/** @type {?} */ (this))).status = DISABLED;
  3265. ((/** @type {?} */ (this))).errors = null;
  3266. this._forEachChild((/**
  3267. * @param {?} control
  3268. * @return {?}
  3269. */
  3270. (control) => { control.disable(Object.assign({}, opts, { onlySelf: true })); }));
  3271. this._updateValue();
  3272. if (opts.emitEvent !== false) {
  3273. ((/** @type {?} */ (this.valueChanges))).emit(this.value);
  3274. ((/** @type {?} */ (this.statusChanges))).emit(this.status);
  3275. }
  3276. this._updateAncestors(Object.assign({}, opts, { skipPristineCheck }));
  3277. this._onDisabledChange.forEach((/**
  3278. * @param {?} changeFn
  3279. * @return {?}
  3280. */
  3281. (changeFn) => changeFn(true)));
  3282. }
  3283. /**
  3284. * Enables the control. This means the control is included in validation checks and
  3285. * the aggregate value of its parent. Its status recalculates based on its value and
  3286. * its validators.
  3287. *
  3288. * By default, if the control has children, all children are enabled.
  3289. *
  3290. * @see {\@link AbstractControl.status}
  3291. *
  3292. * @param {?=} opts Configure options that control how the control propagates changes and
  3293. * emits events when marked as untouched
  3294. * * `onlySelf`: When true, mark only this control. When false or not supplied,
  3295. * marks all direct ancestors. Default is false..
  3296. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  3297. * `valueChanges`
  3298. * observables emit events with the latest status and value when the control is enabled.
  3299. * When false, no events are emitted.
  3300. * @return {?}
  3301. */
  3302. enable(opts = {}) {
  3303. // If parent has been marked artificially dirty we don't want to re-calculate the
  3304. // parent's dirtiness based on the children.
  3305. /** @type {?} */
  3306. const skipPristineCheck = this._parentMarkedDirty(opts.onlySelf);
  3307. ((/** @type {?} */ (this))).status = VALID;
  3308. this._forEachChild((/**
  3309. * @param {?} control
  3310. * @return {?}
  3311. */
  3312. (control) => { control.enable(Object.assign({}, opts, { onlySelf: true })); }));
  3313. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  3314. this._updateAncestors(Object.assign({}, opts, { skipPristineCheck }));
  3315. this._onDisabledChange.forEach((/**
  3316. * @param {?} changeFn
  3317. * @return {?}
  3318. */
  3319. (changeFn) => changeFn(false)));
  3320. }
  3321. /**
  3322. * @private
  3323. * @param {?} opts
  3324. * @return {?}
  3325. */
  3326. _updateAncestors(opts) {
  3327. if (this._parent && !opts.onlySelf) {
  3328. this._parent.updateValueAndValidity(opts);
  3329. if (!opts.skipPristineCheck) {
  3330. this._parent._updatePristine();
  3331. }
  3332. this._parent._updateTouched();
  3333. }
  3334. }
  3335. /**
  3336. * @param {?} parent Sets the parent of the control
  3337. * @return {?}
  3338. */
  3339. setParent(parent) { this._parent = parent; }
  3340. /**
  3341. * Recalculates the value and validation status of the control.
  3342. *
  3343. * By default, it also updates the value and validity of its ancestors.
  3344. *
  3345. * @param {?=} opts Configuration options determine how the control propagates changes and emits events
  3346. * after updates and validity checks are applied.
  3347. * * `onlySelf`: When true, only update this control. When false or not supplied,
  3348. * update all direct ancestors. Default is false..
  3349. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  3350. * `valueChanges`
  3351. * observables emit events with the latest status and value when the control is updated.
  3352. * When false, no events are emitted.
  3353. * @return {?}
  3354. */
  3355. updateValueAndValidity(opts = {}) {
  3356. this._setInitialStatus();
  3357. this._updateValue();
  3358. if (this.enabled) {
  3359. this._cancelExistingSubscription();
  3360. ((/** @type {?} */ (this))).errors = this._runValidator();
  3361. ((/** @type {?} */ (this))).status = this._calculateStatus();
  3362. if (this.status === VALID || this.status === PENDING) {
  3363. this._runAsyncValidator(opts.emitEvent);
  3364. }
  3365. }
  3366. if (opts.emitEvent !== false) {
  3367. ((/** @type {?} */ (this.valueChanges))).emit(this.value);
  3368. ((/** @type {?} */ (this.statusChanges))).emit(this.status);
  3369. }
  3370. if (this._parent && !opts.onlySelf) {
  3371. this._parent.updateValueAndValidity(opts);
  3372. }
  3373. }
  3374. /**
  3375. * \@internal
  3376. * @param {?=} opts
  3377. * @return {?}
  3378. */
  3379. _updateTreeValidity(opts = { emitEvent: true }) {
  3380. this._forEachChild((/**
  3381. * @param {?} ctrl
  3382. * @return {?}
  3383. */
  3384. (ctrl) => ctrl._updateTreeValidity(opts)));
  3385. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  3386. }
  3387. /**
  3388. * @private
  3389. * @return {?}
  3390. */
  3391. _setInitialStatus() {
  3392. ((/** @type {?} */ (this))).status = this._allControlsDisabled() ? DISABLED : VALID;
  3393. }
  3394. /**
  3395. * @private
  3396. * @return {?}
  3397. */
  3398. _runValidator() {
  3399. return this.validator ? this.validator(this) : null;
  3400. }
  3401. /**
  3402. * @private
  3403. * @param {?=} emitEvent
  3404. * @return {?}
  3405. */
  3406. _runAsyncValidator(emitEvent) {
  3407. if (this.asyncValidator) {
  3408. ((/** @type {?} */ (this))).status = PENDING;
  3409. /** @type {?} */
  3410. const obs = toObservable(this.asyncValidator(this));
  3411. this._asyncValidationSubscription =
  3412. obs.subscribe((/**
  3413. * @param {?} errors
  3414. * @return {?}
  3415. */
  3416. (errors) => this.setErrors(errors, { emitEvent })));
  3417. }
  3418. }
  3419. /**
  3420. * @private
  3421. * @return {?}
  3422. */
  3423. _cancelExistingSubscription() {
  3424. if (this._asyncValidationSubscription) {
  3425. this._asyncValidationSubscription.unsubscribe();
  3426. }
  3427. }
  3428. /**
  3429. * Sets errors on a form control when running validations manually, rather than automatically.
  3430. *
  3431. * Calling `setErrors` also updates the validity of the parent control.
  3432. *
  3433. * \@usageNotes
  3434. * ### Manually set the errors for a control
  3435. *
  3436. * ```
  3437. * const login = new FormControl('someLogin');
  3438. * login.setErrors({
  3439. * notUnique: true
  3440. * });
  3441. *
  3442. * expect(login.valid).toEqual(false);
  3443. * expect(login.errors).toEqual({ notUnique: true });
  3444. *
  3445. * login.setValue('someOtherLogin');
  3446. *
  3447. * expect(login.valid).toEqual(true);
  3448. * ```
  3449. * @param {?} errors
  3450. * @param {?=} opts
  3451. * @return {?}
  3452. */
  3453. setErrors(errors, opts = {}) {
  3454. ((/** @type {?} */ (this))).errors = errors;
  3455. this._updateControlsErrors(opts.emitEvent !== false);
  3456. }
  3457. /**
  3458. * Retrieves a child control given the control's name or path.
  3459. *
  3460. * \@usageNotes
  3461. * ### Retrieve a nested control
  3462. *
  3463. * For example, to get a `name` control nested within a `person` sub-group:
  3464. *
  3465. * * `this.form.get('person.name');`
  3466. *
  3467. * -OR-
  3468. *
  3469. * * `this.form.get(['person', 'name']);`
  3470. * @param {?} path A dot-delimited string or array of string/number values that define the path to the
  3471. * control.
  3472. *
  3473. * @return {?}
  3474. */
  3475. get(path) { return _find(this, path, '.'); }
  3476. /**
  3477. * \@description
  3478. * Reports error data for the control with the given path.
  3479. *
  3480. * \@usageNotes
  3481. * For example, for the following `FormGroup`:
  3482. *
  3483. * ```
  3484. * form = new FormGroup({
  3485. * address: new FormGroup({ street: new FormControl() })
  3486. * });
  3487. * ```
  3488. *
  3489. * The path to the 'street' control from the root form would be 'address' -> 'street'.
  3490. *
  3491. * It can be provided to this method in one of two formats:
  3492. *
  3493. * 1. An array of string control names, e.g. `['address', 'street']`
  3494. * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
  3495. *
  3496. * @param {?} errorCode The code of the error to check
  3497. * @param {?=} path A list of control names that designates how to move from the current control
  3498. * to the control that should be queried for errors.
  3499. *
  3500. * @return {?} error data for that particular error. If the control or error is not present,
  3501. * null is returned.
  3502. */
  3503. getError(errorCode, path) {
  3504. /** @type {?} */
  3505. const control = path ? this.get(path) : this;
  3506. return control && control.errors ? control.errors[errorCode] : null;
  3507. }
  3508. /**
  3509. * \@description
  3510. * Reports whether the control with the given path has the error specified.
  3511. *
  3512. * \@usageNotes
  3513. * For example, for the following `FormGroup`:
  3514. *
  3515. * ```
  3516. * form = new FormGroup({
  3517. * address: new FormGroup({ street: new FormControl() })
  3518. * });
  3519. * ```
  3520. *
  3521. * The path to the 'street' control from the root form would be 'address' -> 'street'.
  3522. *
  3523. * It can be provided to this method in one of two formats:
  3524. *
  3525. * 1. An array of string control names, e.g. `['address', 'street']`
  3526. * 1. A period-delimited list of control names in one string, e.g. `'address.street'`
  3527. *
  3528. * If no path is given, this method checks for the error on the current control.
  3529. *
  3530. * @param {?} errorCode The code of the error to check
  3531. * @param {?=} path A list of control names that designates how to move from the current control
  3532. * to the control that should be queried for errors.
  3533. *
  3534. * @return {?} whether the given error is present in the control at the given path.
  3535. *
  3536. * If the control is not present, false is returned.
  3537. */
  3538. hasError(errorCode, path) {
  3539. return !!this.getError(errorCode, path);
  3540. }
  3541. /**
  3542. * Retrieves the top-level ancestor of this control.
  3543. * @return {?}
  3544. */
  3545. get root() {
  3546. /** @type {?} */
  3547. let x = this;
  3548. while (x._parent) {
  3549. x = x._parent;
  3550. }
  3551. return x;
  3552. }
  3553. /**
  3554. * \@internal
  3555. * @param {?} emitEvent
  3556. * @return {?}
  3557. */
  3558. _updateControlsErrors(emitEvent) {
  3559. ((/** @type {?} */ (this))).status = this._calculateStatus();
  3560. if (emitEvent) {
  3561. ((/** @type {?} */ (this.statusChanges))).emit(this.status);
  3562. }
  3563. if (this._parent) {
  3564. this._parent._updateControlsErrors(emitEvent);
  3565. }
  3566. }
  3567. /**
  3568. * \@internal
  3569. * @return {?}
  3570. */
  3571. _initObservables() {
  3572. ((/** @type {?} */ (this))).valueChanges = new EventEmitter();
  3573. ((/** @type {?} */ (this))).statusChanges = new EventEmitter();
  3574. }
  3575. /**
  3576. * @private
  3577. * @return {?}
  3578. */
  3579. _calculateStatus() {
  3580. if (this._allControlsDisabled())
  3581. return DISABLED;
  3582. if (this.errors)
  3583. return INVALID;
  3584. if (this._anyControlsHaveStatus(PENDING))
  3585. return PENDING;
  3586. if (this._anyControlsHaveStatus(INVALID))
  3587. return INVALID;
  3588. return VALID;
  3589. }
  3590. /**
  3591. * \@internal
  3592. * @param {?} status
  3593. * @return {?}
  3594. */
  3595. _anyControlsHaveStatus(status) {
  3596. return this._anyControls((/**
  3597. * @param {?} control
  3598. * @return {?}
  3599. */
  3600. (control) => control.status === status));
  3601. }
  3602. /**
  3603. * \@internal
  3604. * @return {?}
  3605. */
  3606. _anyControlsDirty() {
  3607. return this._anyControls((/**
  3608. * @param {?} control
  3609. * @return {?}
  3610. */
  3611. (control) => control.dirty));
  3612. }
  3613. /**
  3614. * \@internal
  3615. * @return {?}
  3616. */
  3617. _anyControlsTouched() {
  3618. return this._anyControls((/**
  3619. * @param {?} control
  3620. * @return {?}
  3621. */
  3622. (control) => control.touched));
  3623. }
  3624. /**
  3625. * \@internal
  3626. * @param {?=} opts
  3627. * @return {?}
  3628. */
  3629. _updatePristine(opts = {}) {
  3630. ((/** @type {?} */ (this))).pristine = !this._anyControlsDirty();
  3631. if (this._parent && !opts.onlySelf) {
  3632. this._parent._updatePristine(opts);
  3633. }
  3634. }
  3635. /**
  3636. * \@internal
  3637. * @param {?=} opts
  3638. * @return {?}
  3639. */
  3640. _updateTouched(opts = {}) {
  3641. ((/** @type {?} */ (this))).touched = this._anyControlsTouched();
  3642. if (this._parent && !opts.onlySelf) {
  3643. this._parent._updateTouched(opts);
  3644. }
  3645. }
  3646. /**
  3647. * \@internal
  3648. * @param {?} formState
  3649. * @return {?}
  3650. */
  3651. _isBoxedValue(formState) {
  3652. return typeof formState === 'object' && formState !== null &&
  3653. Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
  3654. }
  3655. /**
  3656. * \@internal
  3657. * @param {?} fn
  3658. * @return {?}
  3659. */
  3660. _registerOnCollectionChange(fn) { this._onCollectionChange = fn; }
  3661. /**
  3662. * \@internal
  3663. * @param {?=} opts
  3664. * @return {?}
  3665. */
  3666. _setUpdateStrategy(opts) {
  3667. if (isOptionsObj(opts) && ((/** @type {?} */ (opts))).updateOn != null) {
  3668. this._updateOn = (/** @type {?} */ (((/** @type {?} */ (opts))).updateOn));
  3669. }
  3670. }
  3671. /**
  3672. * Check to see if parent has been marked artificially dirty.
  3673. *
  3674. * \@internal
  3675. * @private
  3676. * @param {?=} onlySelf
  3677. * @return {?}
  3678. */
  3679. _parentMarkedDirty(onlySelf) {
  3680. /** @type {?} */
  3681. const parentDirty = this._parent && this._parent.dirty;
  3682. return !onlySelf && parentDirty && !this._parent._anyControlsDirty();
  3683. }
  3684. }
  3685. /**
  3686. * Tracks the value and validation status of an individual form control.
  3687. *
  3688. * This is one of the three fundamental building blocks of Angular forms, along with
  3689. * `FormGroup` and `FormArray`. It extends the `AbstractControl` class that
  3690. * implements most of the base functionality for accessing the value, validation status,
  3691. * user interactions and events.
  3692. *
  3693. * @see `AbstractControl`
  3694. * @see [Reactive Forms Guide](guide/reactive-forms)
  3695. * @see [Usage Notes](#usage-notes)
  3696. *
  3697. * \@usageNotes
  3698. *
  3699. * ### Initializing Form Controls
  3700. *
  3701. * Instantiate a `FormControl`, with an initial value.
  3702. *
  3703. * ```ts
  3704. * const control = new FormControl('some value');
  3705. * console.log(control.value); // 'some value'
  3706. * ```
  3707. *
  3708. * The following example initializes the control with a form state object. The `value`
  3709. * and `disabled` keys are required in this case.
  3710. *
  3711. * ```ts
  3712. * const control = new FormControl({ value: 'n/a', disabled: true });
  3713. * console.log(control.value); // 'n/a'
  3714. * console.log(control.status); // 'DISABLED'
  3715. * ```
  3716. *
  3717. * The following example initializes the control with a sync validator.
  3718. *
  3719. * ```ts
  3720. * const control = new FormControl('', Validators.required);
  3721. * console.log(control.value); // ''
  3722. * console.log(control.status); // 'INVALID'
  3723. * ```
  3724. *
  3725. * The following example initializes the control using an options object.
  3726. *
  3727. * ```ts
  3728. * const control = new FormControl('', {
  3729. * validators: Validators.required,
  3730. * asyncValidators: myAsyncValidator
  3731. * });
  3732. * ```
  3733. *
  3734. * ### Configure the control to update on a blur event
  3735. *
  3736. * Set the `updateOn` option to `'blur'` to update on the blur `event`.
  3737. *
  3738. * ```ts
  3739. * const control = new FormControl('', { updateOn: 'blur' });
  3740. * ```
  3741. *
  3742. * ### Configure the control to update on a submit event
  3743. *
  3744. * Set the `updateOn` option to `'submit'` to update on a submit `event`.
  3745. *
  3746. * ```ts
  3747. * const control = new FormControl('', { updateOn: 'submit' });
  3748. * ```
  3749. *
  3750. * ### Reset the control back to an initial value
  3751. *
  3752. * You reset to a specific form state by passing through a standalone
  3753. * value or a form state object that contains both a value and a disabled state
  3754. * (these are the only two properties that cannot be calculated).
  3755. *
  3756. * ```ts
  3757. * const control = new FormControl('Nancy');
  3758. *
  3759. * console.log(control.value); // 'Nancy'
  3760. *
  3761. * control.reset('Drew');
  3762. *
  3763. * console.log(control.value); // 'Drew'
  3764. * ```
  3765. *
  3766. * ### Reset the control back to an initial value and disabled
  3767. *
  3768. * ```
  3769. * const control = new FormControl('Nancy');
  3770. *
  3771. * console.log(control.value); // 'Nancy'
  3772. * console.log(control.status); // 'VALID'
  3773. *
  3774. * control.reset({ value: 'Drew', disabled: true });
  3775. *
  3776. * console.log(control.value); // 'Drew'
  3777. * console.log(control.status); // 'DISABLED'
  3778. * ```
  3779. *
  3780. * \@publicApi
  3781. */
  3782. class FormControl extends AbstractControl {
  3783. /**
  3784. * Creates a new `FormControl` instance.
  3785. *
  3786. * @param {?=} formState Initializes the control with an initial value,
  3787. * or an object that defines the initial value and disabled state.
  3788. *
  3789. * @param {?=} validatorOrOpts A synchronous validator function, or an array of
  3790. * such functions, or an `AbstractControlOptions` object that contains validation functions
  3791. * and a validation trigger.
  3792. *
  3793. * @param {?=} asyncValidator A single async validator or array of async validator functions
  3794. *
  3795. */
  3796. constructor(formState = null, validatorOrOpts, asyncValidator) {
  3797. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  3798. /**
  3799. * \@internal
  3800. */
  3801. this._onChange = [];
  3802. this._applyFormState(formState);
  3803. this._setUpdateStrategy(validatorOrOpts);
  3804. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  3805. this._initObservables();
  3806. }
  3807. /**
  3808. * Sets a new value for the form control.
  3809. *
  3810. * @param {?} value The new value for the control.
  3811. * @param {?=} options Configuration options that determine how the control propagates changes
  3812. * and emits events when the value changes.
  3813. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  3814. * updateValueAndValidity} method.
  3815. *
  3816. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
  3817. * false.
  3818. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  3819. * `valueChanges`
  3820. * observables emit events with the latest status and value when the control value is updated.
  3821. * When false, no events are emitted.
  3822. * * `emitModelToViewChange`: When true or not supplied (the default), each change triggers an
  3823. * `onChange` event to
  3824. * update the view.
  3825. * * `emitViewToModelChange`: When true or not supplied (the default), each change triggers an
  3826. * `ngModelChange`
  3827. * event to update the model.
  3828. *
  3829. * @return {?}
  3830. */
  3831. setValue(value, options = {}) {
  3832. ((/** @type {?} */ (this))).value = this._pendingValue = value;
  3833. if (this._onChange.length && options.emitModelToViewChange !== false) {
  3834. this._onChange.forEach((/**
  3835. * @param {?} changeFn
  3836. * @return {?}
  3837. */
  3838. (changeFn) => changeFn(this.value, options.emitViewToModelChange !== false)));
  3839. }
  3840. this.updateValueAndValidity(options);
  3841. }
  3842. /**
  3843. * Patches the value of a control.
  3844. *
  3845. * This function is functionally the same as {\@link FormControl#setValue setValue} at this level.
  3846. * It exists for symmetry with {\@link FormGroup#patchValue patchValue} on `FormGroups` and
  3847. * `FormArrays`, where it does behave differently.
  3848. *
  3849. * @see `setValue` for options
  3850. * @param {?} value
  3851. * @param {?=} options
  3852. * @return {?}
  3853. */
  3854. patchValue(value, options = {}) {
  3855. this.setValue(value, options);
  3856. }
  3857. /**
  3858. * Resets the form control, marking it `pristine` and `untouched`, and setting
  3859. * the value to null.
  3860. *
  3861. * @param {?=} formState Resets the control with an initial value,
  3862. * or an object that defines the initial value and disabled state.
  3863. *
  3864. * @param {?=} options Configuration options that determine how the control propagates changes
  3865. * and emits events after the value changes.
  3866. *
  3867. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
  3868. * false.
  3869. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  3870. * `valueChanges`
  3871. * observables emit events with the latest status and value when the control is reset.
  3872. * When false, no events are emitted.
  3873. *
  3874. * @return {?}
  3875. */
  3876. reset(formState = null, options = {}) {
  3877. this._applyFormState(formState);
  3878. this.markAsPristine(options);
  3879. this.markAsUntouched(options);
  3880. this.setValue(this.value, options);
  3881. this._pendingChange = false;
  3882. }
  3883. /**
  3884. * \@internal
  3885. * @return {?}
  3886. */
  3887. _updateValue() { }
  3888. /**
  3889. * \@internal
  3890. * @param {?} condition
  3891. * @return {?}
  3892. */
  3893. _anyControls(condition) { return false; }
  3894. /**
  3895. * \@internal
  3896. * @return {?}
  3897. */
  3898. _allControlsDisabled() { return this.disabled; }
  3899. /**
  3900. * Register a listener for change events.
  3901. *
  3902. * @param {?} fn The method that is called when the value changes
  3903. * @return {?}
  3904. */
  3905. registerOnChange(fn) { this._onChange.push(fn); }
  3906. /**
  3907. * \@internal
  3908. * @return {?}
  3909. */
  3910. _clearChangeFns() {
  3911. this._onChange = [];
  3912. this._onDisabledChange = [];
  3913. this._onCollectionChange = (/**
  3914. * @return {?}
  3915. */
  3916. () => { });
  3917. }
  3918. /**
  3919. * Register a listener for disabled events.
  3920. *
  3921. * @param {?} fn The method that is called when the disabled status changes.
  3922. * @return {?}
  3923. */
  3924. registerOnDisabledChange(fn) {
  3925. this._onDisabledChange.push(fn);
  3926. }
  3927. /**
  3928. * \@internal
  3929. * @param {?} cb
  3930. * @return {?}
  3931. */
  3932. _forEachChild(cb) { }
  3933. /**
  3934. * \@internal
  3935. * @return {?}
  3936. */
  3937. _syncPendingControls() {
  3938. if (this.updateOn === 'submit') {
  3939. if (this._pendingDirty)
  3940. this.markAsDirty();
  3941. if (this._pendingTouched)
  3942. this.markAsTouched();
  3943. if (this._pendingChange) {
  3944. this.setValue(this._pendingValue, { onlySelf: true, emitModelToViewChange: false });
  3945. return true;
  3946. }
  3947. }
  3948. return false;
  3949. }
  3950. /**
  3951. * @private
  3952. * @param {?} formState
  3953. * @return {?}
  3954. */
  3955. _applyFormState(formState) {
  3956. if (this._isBoxedValue(formState)) {
  3957. ((/** @type {?} */ (this))).value = this._pendingValue = formState.value;
  3958. formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) :
  3959. this.enable({ onlySelf: true, emitEvent: false });
  3960. }
  3961. else {
  3962. ((/** @type {?} */ (this))).value = this._pendingValue = formState;
  3963. }
  3964. }
  3965. }
  3966. /**
  3967. * Tracks the value and validity state of a group of `FormControl` instances.
  3968. *
  3969. * A `FormGroup` aggregates the values of each child `FormControl` into one object,
  3970. * with each control name as the key. It calculates its status by reducing the status values
  3971. * of its children. For example, if one of the controls in a group is invalid, the entire
  3972. * group becomes invalid.
  3973. *
  3974. * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular,
  3975. * along with `FormControl` and `FormArray`.
  3976. *
  3977. * When instantiating a `FormGroup`, pass in a collection of child controls as the first
  3978. * argument. The key for each child registers the name for the control.
  3979. *
  3980. * \@usageNotes
  3981. *
  3982. * ### Create a form group with 2 controls
  3983. *
  3984. * ```
  3985. * const form = new FormGroup({
  3986. * first: new FormControl('Nancy', Validators.minLength(2)),
  3987. * last: new FormControl('Drew'),
  3988. * });
  3989. *
  3990. * console.log(form.value); // {first: 'Nancy', last; 'Drew'}
  3991. * console.log(form.status); // 'VALID'
  3992. * ```
  3993. *
  3994. * ### Create a form group with a group-level validator
  3995. *
  3996. * You include group-level validators as the second arg, or group-level async
  3997. * validators as the third arg. These come in handy when you want to perform validation
  3998. * that considers the value of more than one child control.
  3999. *
  4000. * ```
  4001. * const form = new FormGroup({
  4002. * password: new FormControl('', Validators.minLength(2)),
  4003. * passwordConfirm: new FormControl('', Validators.minLength(2)),
  4004. * }, passwordMatchValidator);
  4005. *
  4006. *
  4007. * function passwordMatchValidator(g: FormGroup) {
  4008. * return g.get('password').value === g.get('passwordConfirm').value
  4009. * ? null : {'mismatch': true};
  4010. * }
  4011. * ```
  4012. *
  4013. * Like `FormControl` instances, you choose to pass in
  4014. * validators and async validators as part of an options object.
  4015. *
  4016. * ```
  4017. * const form = new FormGroup({
  4018. * password: new FormControl('')
  4019. * passwordConfirm: new FormControl('')
  4020. * }, { validators: passwordMatchValidator, asyncValidators: otherValidator });
  4021. * ```
  4022. *
  4023. * ### Set the updateOn property for all controls in a form group
  4024. *
  4025. * The options object is used to set a default value for each child
  4026. * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
  4027. * group level, all child controls default to 'blur', unless the child
  4028. * has explicitly specified a different `updateOn` value.
  4029. *
  4030. * ```ts
  4031. * const c = new FormGroup({
  4032. * one: new FormControl()
  4033. * }, { updateOn: 'blur' });
  4034. * ```
  4035. *
  4036. * \@publicApi
  4037. */
  4038. class FormGroup extends AbstractControl {
  4039. /**
  4040. * Creates a new `FormGroup` instance.
  4041. *
  4042. * @param {?} controls A collection of child controls. The key for each child is the name
  4043. * under which it is registered.
  4044. *
  4045. * @param {?=} validatorOrOpts A synchronous validator function, or an array of
  4046. * such functions, or an `AbstractControlOptions` object that contains validation functions
  4047. * and a validation trigger.
  4048. *
  4049. * @param {?=} asyncValidator A single async validator or array of async validator functions
  4050. *
  4051. */
  4052. constructor(controls, validatorOrOpts, asyncValidator) {
  4053. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  4054. this.controls = controls;
  4055. this._initObservables();
  4056. this._setUpdateStrategy(validatorOrOpts);
  4057. this._setUpControls();
  4058. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  4059. }
  4060. /**
  4061. * Registers a control with the group's list of controls.
  4062. *
  4063. * This method does not update the value or validity of the control.
  4064. * Use {\@link FormGroup#addControl addControl} instead.
  4065. *
  4066. * @param {?} name The control name to register in the collection
  4067. * @param {?} control Provides the control for the given name
  4068. * @return {?}
  4069. */
  4070. registerControl(name, control) {
  4071. if (this.controls[name])
  4072. return this.controls[name];
  4073. this.controls[name] = control;
  4074. control.setParent(this);
  4075. control._registerOnCollectionChange(this._onCollectionChange);
  4076. return control;
  4077. }
  4078. /**
  4079. * Add a control to this group.
  4080. *
  4081. * This method also updates the value and validity of the control.
  4082. *
  4083. * @param {?} name The control name to add to the collection
  4084. * @param {?} control Provides the control for the given name
  4085. * @return {?}
  4086. */
  4087. addControl(name, control) {
  4088. this.registerControl(name, control);
  4089. this.updateValueAndValidity();
  4090. this._onCollectionChange();
  4091. }
  4092. /**
  4093. * Remove a control from this group.
  4094. *
  4095. * @param {?} name The control name to remove from the collection
  4096. * @return {?}
  4097. */
  4098. removeControl(name) {
  4099. if (this.controls[name])
  4100. this.controls[name]._registerOnCollectionChange((/**
  4101. * @return {?}
  4102. */
  4103. () => { }));
  4104. delete (this.controls[name]);
  4105. this.updateValueAndValidity();
  4106. this._onCollectionChange();
  4107. }
  4108. /**
  4109. * Replace an existing control.
  4110. *
  4111. * @param {?} name The control name to replace in the collection
  4112. * @param {?} control Provides the control for the given name
  4113. * @return {?}
  4114. */
  4115. setControl(name, control) {
  4116. if (this.controls[name])
  4117. this.controls[name]._registerOnCollectionChange((/**
  4118. * @return {?}
  4119. */
  4120. () => { }));
  4121. delete (this.controls[name]);
  4122. if (control)
  4123. this.registerControl(name, control);
  4124. this.updateValueAndValidity();
  4125. this._onCollectionChange();
  4126. }
  4127. /**
  4128. * Check whether there is an enabled control with the given name in the group.
  4129. *
  4130. * Reports false for disabled controls. If you'd like to check for existence in the group
  4131. * only, use {\@link AbstractControl#get get} instead.
  4132. *
  4133. * @param {?} controlName
  4134. * @return {?} false for disabled controls, true otherwise.
  4135. */
  4136. contains(controlName) {
  4137. return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
  4138. }
  4139. /**
  4140. * Sets the value of the `FormGroup`. It accepts an object that matches
  4141. * the structure of the group, with control names as keys.
  4142. *
  4143. * \@usageNotes
  4144. * ### Set the complete value for the form group
  4145. *
  4146. * ```
  4147. * const form = new FormGroup({
  4148. * first: new FormControl(),
  4149. * last: new FormControl()
  4150. * });
  4151. *
  4152. * console.log(form.value); // {first: null, last: null}
  4153. *
  4154. * form.setValue({first: 'Nancy', last: 'Drew'});
  4155. * console.log(form.value); // {first: 'Nancy', last: 'Drew'}
  4156. * ```
  4157. *
  4158. * @throws When strict checks fail, such as setting the value of a control
  4159. * that doesn't exist or if you excluding the value of a control.
  4160. *
  4161. * @param {?} value The new value for the control that matches the structure of the group.
  4162. * @param {?=} options Configuration options that determine how the control propagates changes
  4163. * and emits events after the value changes.
  4164. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4165. * updateValueAndValidity} method.
  4166. *
  4167. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
  4168. * false.
  4169. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4170. * `valueChanges`
  4171. * observables emit events with the latest status and value when the control value is updated.
  4172. * When false, no events are emitted.
  4173. * @return {?}
  4174. */
  4175. setValue(value, options = {}) {
  4176. this._checkAllValuesPresent(value);
  4177. Object.keys(value).forEach((/**
  4178. * @param {?} name
  4179. * @return {?}
  4180. */
  4181. name => {
  4182. this._throwIfControlMissing(name);
  4183. this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  4184. }));
  4185. this.updateValueAndValidity(options);
  4186. }
  4187. /**
  4188. * Patches the value of the `FormGroup`. It accepts an object with control
  4189. * names as keys, and does its best to match the values to the correct controls
  4190. * in the group.
  4191. *
  4192. * It accepts both super-sets and sub-sets of the group without throwing an error.
  4193. *
  4194. * \@usageNotes
  4195. * ### Patch the value for a form group
  4196. *
  4197. * ```
  4198. * const form = new FormGroup({
  4199. * first: new FormControl(),
  4200. * last: new FormControl()
  4201. * });
  4202. * console.log(form.value); // {first: null, last: null}
  4203. *
  4204. * form.patchValue({first: 'Nancy'});
  4205. * console.log(form.value); // {first: 'Nancy', last: null}
  4206. * ```
  4207. *
  4208. * @param {?} value The object that matches the structure of the group.
  4209. * @param {?=} options Configuration options that determine how the control propagates changes and
  4210. * emits events after the value is patched.
  4211. * * `onlySelf`: When true, each change only affects this control and not its parent. Default is
  4212. * true.
  4213. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4214. * `valueChanges`
  4215. * observables emit events with the latest status and value when the control value is updated.
  4216. * When false, no events are emitted.
  4217. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4218. * updateValueAndValidity} method.
  4219. * @return {?}
  4220. */
  4221. patchValue(value, options = {}) {
  4222. Object.keys(value).forEach((/**
  4223. * @param {?} name
  4224. * @return {?}
  4225. */
  4226. name => {
  4227. if (this.controls[name]) {
  4228. this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  4229. }
  4230. }));
  4231. this.updateValueAndValidity(options);
  4232. }
  4233. /**
  4234. * Resets the `FormGroup`, marks all descendants are marked `pristine` and `untouched`, and
  4235. * the value of all descendants to null.
  4236. *
  4237. * You reset to a specific form state by passing in a map of states
  4238. * that matches the structure of your form, with control names as keys. The state
  4239. * is a standalone value or a form state object with both a value and a disabled
  4240. * status.
  4241. *
  4242. * \@usageNotes
  4243. *
  4244. * ### Reset the form group values
  4245. *
  4246. * ```ts
  4247. * const form = new FormGroup({
  4248. * first: new FormControl('first name'),
  4249. * last: new FormControl('last name')
  4250. * });
  4251. *
  4252. * console.log(form.value); // {first: 'first name', last: 'last name'}
  4253. *
  4254. * form.reset({ first: 'name', last: 'last name' });
  4255. *
  4256. * console.log(form.value); // {first: 'name', last: 'last name'}
  4257. * ```
  4258. *
  4259. * ### Reset the form group values and disabled status
  4260. *
  4261. * ```
  4262. * const form = new FormGroup({
  4263. * first: new FormControl('first name'),
  4264. * last: new FormControl('last name')
  4265. * });
  4266. *
  4267. * form.reset({
  4268. * first: {value: 'name', disabled: true},
  4269. * last: 'last'
  4270. * });
  4271. *
  4272. * console.log(this.form.value); // {first: 'name', last: 'last name'}
  4273. * console.log(this.form.get('first').status); // 'DISABLED'
  4274. * ```
  4275. * @param {?=} value
  4276. * @param {?=} options Configuration options that determine how the control propagates changes
  4277. * and emits events when the group is reset.
  4278. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default is
  4279. * false.
  4280. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4281. * `valueChanges`
  4282. * observables emit events with the latest status and value when the control is reset.
  4283. * When false, no events are emitted.
  4284. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4285. * updateValueAndValidity} method.
  4286. *
  4287. * @return {?}
  4288. */
  4289. reset(value = {}, options = {}) {
  4290. this._forEachChild((/**
  4291. * @param {?} control
  4292. * @param {?} name
  4293. * @return {?}
  4294. */
  4295. (control, name) => {
  4296. control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  4297. }));
  4298. this._updatePristine(options);
  4299. this._updateTouched(options);
  4300. this.updateValueAndValidity(options);
  4301. }
  4302. /**
  4303. * The aggregate value of the `FormGroup`, including any disabled controls.
  4304. *
  4305. * Retrieves all values regardless of disabled status.
  4306. * The `value` property is the best way to get the value of the group, because
  4307. * it excludes disabled controls in the `FormGroup`.
  4308. * @return {?}
  4309. */
  4310. getRawValue() {
  4311. return this._reduceChildren({}, (/**
  4312. * @param {?} acc
  4313. * @param {?} control
  4314. * @param {?} name
  4315. * @return {?}
  4316. */
  4317. (acc, control, name) => {
  4318. acc[name] = control instanceof FormControl ? control.value : ((/** @type {?} */ (control))).getRawValue();
  4319. return acc;
  4320. }));
  4321. }
  4322. /**
  4323. * \@internal
  4324. * @return {?}
  4325. */
  4326. _syncPendingControls() {
  4327. /** @type {?} */
  4328. let subtreeUpdated = this._reduceChildren(false, (/**
  4329. * @param {?} updated
  4330. * @param {?} child
  4331. * @return {?}
  4332. */
  4333. (updated, child) => {
  4334. return child._syncPendingControls() ? true : updated;
  4335. }));
  4336. if (subtreeUpdated)
  4337. this.updateValueAndValidity({ onlySelf: true });
  4338. return subtreeUpdated;
  4339. }
  4340. /**
  4341. * \@internal
  4342. * @param {?} name
  4343. * @return {?}
  4344. */
  4345. _throwIfControlMissing(name) {
  4346. if (!Object.keys(this.controls).length) {
  4347. throw new Error(`
  4348. There are no form controls registered with this group yet. If you're using ngModel,
  4349. you may want to check next tick (e.g. use setTimeout).
  4350. `);
  4351. }
  4352. if (!this.controls[name]) {
  4353. throw new Error(`Cannot find form control with name: ${name}.`);
  4354. }
  4355. }
  4356. /**
  4357. * \@internal
  4358. * @param {?} cb
  4359. * @return {?}
  4360. */
  4361. _forEachChild(cb) {
  4362. Object.keys(this.controls).forEach((/**
  4363. * @param {?} k
  4364. * @return {?}
  4365. */
  4366. k => cb(this.controls[k], k)));
  4367. }
  4368. /**
  4369. * \@internal
  4370. * @return {?}
  4371. */
  4372. _setUpControls() {
  4373. this._forEachChild((/**
  4374. * @param {?} control
  4375. * @return {?}
  4376. */
  4377. (control) => {
  4378. control.setParent(this);
  4379. control._registerOnCollectionChange(this._onCollectionChange);
  4380. }));
  4381. }
  4382. /**
  4383. * \@internal
  4384. * @return {?}
  4385. */
  4386. _updateValue() { ((/** @type {?} */ (this))).value = this._reduceValue(); }
  4387. /**
  4388. * \@internal
  4389. * @param {?} condition
  4390. * @return {?}
  4391. */
  4392. _anyControls(condition) {
  4393. /** @type {?} */
  4394. let res = false;
  4395. this._forEachChild((/**
  4396. * @param {?} control
  4397. * @param {?} name
  4398. * @return {?}
  4399. */
  4400. (control, name) => {
  4401. res = res || (this.contains(name) && condition(control));
  4402. }));
  4403. return res;
  4404. }
  4405. /**
  4406. * \@internal
  4407. * @return {?}
  4408. */
  4409. _reduceValue() {
  4410. return this._reduceChildren({}, (/**
  4411. * @param {?} acc
  4412. * @param {?} control
  4413. * @param {?} name
  4414. * @return {?}
  4415. */
  4416. (acc, control, name) => {
  4417. if (control.enabled || this.disabled) {
  4418. acc[name] = control.value;
  4419. }
  4420. return acc;
  4421. }));
  4422. }
  4423. /**
  4424. * \@internal
  4425. * @param {?} initValue
  4426. * @param {?} fn
  4427. * @return {?}
  4428. */
  4429. _reduceChildren(initValue, fn) {
  4430. /** @type {?} */
  4431. let res = initValue;
  4432. this._forEachChild((/**
  4433. * @param {?} control
  4434. * @param {?} name
  4435. * @return {?}
  4436. */
  4437. (control, name) => { res = fn(res, control, name); }));
  4438. return res;
  4439. }
  4440. /**
  4441. * \@internal
  4442. * @return {?}
  4443. */
  4444. _allControlsDisabled() {
  4445. for (const controlName of Object.keys(this.controls)) {
  4446. if (this.controls[controlName].enabled) {
  4447. return false;
  4448. }
  4449. }
  4450. return Object.keys(this.controls).length > 0 || this.disabled;
  4451. }
  4452. /**
  4453. * \@internal
  4454. * @param {?} value
  4455. * @return {?}
  4456. */
  4457. _checkAllValuesPresent(value) {
  4458. this._forEachChild((/**
  4459. * @param {?} control
  4460. * @param {?} name
  4461. * @return {?}
  4462. */
  4463. (control, name) => {
  4464. if (value[name] === undefined) {
  4465. throw new Error(`Must supply a value for form control with name: '${name}'.`);
  4466. }
  4467. }));
  4468. }
  4469. }
  4470. /**
  4471. * Tracks the value and validity state of an array of `FormControl`,
  4472. * `FormGroup` or `FormArray` instances.
  4473. *
  4474. * A `FormArray` aggregates the values of each child `FormControl` into an array.
  4475. * It calculates its status by reducing the status values of its children. For example, if one of
  4476. * the controls in a `FormArray` is invalid, the entire array becomes invalid.
  4477. *
  4478. * `FormArray` is one of the three fundamental building blocks used to define forms in Angular,
  4479. * along with `FormControl` and `FormGroup`.
  4480. *
  4481. * \@usageNotes
  4482. *
  4483. * ### Create an array of form controls
  4484. *
  4485. * ```
  4486. * const arr = new FormArray([
  4487. * new FormControl('Nancy', Validators.minLength(2)),
  4488. * new FormControl('Drew'),
  4489. * ]);
  4490. *
  4491. * console.log(arr.value); // ['Nancy', 'Drew']
  4492. * console.log(arr.status); // 'VALID'
  4493. * ```
  4494. *
  4495. * ### Create a form array with array-level validators
  4496. *
  4497. * You include array-level validators and async validators. These come in handy
  4498. * when you want to perform validation that considers the value of more than one child
  4499. * control.
  4500. *
  4501. * The two types of validators are passed in separately as the second and third arg
  4502. * respectively, or together as part of an options object.
  4503. *
  4504. * ```
  4505. * const arr = new FormArray([
  4506. * new FormControl('Nancy'),
  4507. * new FormControl('Drew')
  4508. * ], {validators: myValidator, asyncValidators: myAsyncValidator});
  4509. * ```
  4510. *
  4511. * ### Set the updateOn property for all controls in a form array
  4512. *
  4513. * The options object is used to set a default value for each child
  4514. * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
  4515. * array level, all child controls default to 'blur', unless the child
  4516. * has explicitly specified a different `updateOn` value.
  4517. *
  4518. * ```ts
  4519. * const arr = new FormArray([
  4520. * new FormControl()
  4521. * ], {updateOn: 'blur'});
  4522. * ```
  4523. *
  4524. * ### Adding or removing controls from a form array
  4525. *
  4526. * To change the controls in the array, use the `push`, `insert`, `removeAt` or `clear` methods
  4527. * in `FormArray` itself. These methods ensure the controls are properly tracked in the
  4528. * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
  4529. * the `FormArray` directly, as that result in strange and unexpected behavior such
  4530. * as broken change detection.
  4531. *
  4532. * \@publicApi
  4533. */
  4534. class FormArray extends AbstractControl {
  4535. /**
  4536. * Creates a new `FormArray` instance.
  4537. *
  4538. * @param {?} controls An array of child controls. Each child control is given an index
  4539. * where it is registered.
  4540. *
  4541. * @param {?=} validatorOrOpts A synchronous validator function, or an array of
  4542. * such functions, or an `AbstractControlOptions` object that contains validation functions
  4543. * and a validation trigger.
  4544. *
  4545. * @param {?=} asyncValidator A single async validator or array of async validator functions
  4546. *
  4547. */
  4548. constructor(controls, validatorOrOpts, asyncValidator) {
  4549. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  4550. this.controls = controls;
  4551. this._initObservables();
  4552. this._setUpdateStrategy(validatorOrOpts);
  4553. this._setUpControls();
  4554. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  4555. }
  4556. /**
  4557. * Get the `AbstractControl` at the given `index` in the array.
  4558. *
  4559. * @param {?} index Index in the array to retrieve the control
  4560. * @return {?}
  4561. */
  4562. at(index) { return this.controls[index]; }
  4563. /**
  4564. * Insert a new `AbstractControl` at the end of the array.
  4565. *
  4566. * @param {?} control Form control to be inserted
  4567. * @return {?}
  4568. */
  4569. push(control) {
  4570. this.controls.push(control);
  4571. this._registerControl(control);
  4572. this.updateValueAndValidity();
  4573. this._onCollectionChange();
  4574. }
  4575. /**
  4576. * Insert a new `AbstractControl` at the given `index` in the array.
  4577. *
  4578. * @param {?} index Index in the array to insert the control
  4579. * @param {?} control Form control to be inserted
  4580. * @return {?}
  4581. */
  4582. insert(index, control) {
  4583. this.controls.splice(index, 0, control);
  4584. this._registerControl(control);
  4585. this.updateValueAndValidity();
  4586. }
  4587. /**
  4588. * Remove the control at the given `index` in the array.
  4589. *
  4590. * @param {?} index Index in the array to remove the control
  4591. * @return {?}
  4592. */
  4593. removeAt(index) {
  4594. if (this.controls[index])
  4595. this.controls[index]._registerOnCollectionChange((/**
  4596. * @return {?}
  4597. */
  4598. () => { }));
  4599. this.controls.splice(index, 1);
  4600. this.updateValueAndValidity();
  4601. }
  4602. /**
  4603. * Replace an existing control.
  4604. *
  4605. * @param {?} index Index in the array to replace the control
  4606. * @param {?} control The `AbstractControl` control to replace the existing control
  4607. * @return {?}
  4608. */
  4609. setControl(index, control) {
  4610. if (this.controls[index])
  4611. this.controls[index]._registerOnCollectionChange((/**
  4612. * @return {?}
  4613. */
  4614. () => { }));
  4615. this.controls.splice(index, 1);
  4616. if (control) {
  4617. this.controls.splice(index, 0, control);
  4618. this._registerControl(control);
  4619. }
  4620. this.updateValueAndValidity();
  4621. this._onCollectionChange();
  4622. }
  4623. /**
  4624. * Length of the control array.
  4625. * @return {?}
  4626. */
  4627. get length() { return this.controls.length; }
  4628. /**
  4629. * Sets the value of the `FormArray`. It accepts an array that matches
  4630. * the structure of the control.
  4631. *
  4632. * This method performs strict checks, and throws an error if you try
  4633. * to set the value of a control that doesn't exist or if you exclude the
  4634. * value of a control.
  4635. *
  4636. * \@usageNotes
  4637. * ### Set the values for the controls in the form array
  4638. *
  4639. * ```
  4640. * const arr = new FormArray([
  4641. * new FormControl(),
  4642. * new FormControl()
  4643. * ]);
  4644. * console.log(arr.value); // [null, null]
  4645. *
  4646. * arr.setValue(['Nancy', 'Drew']);
  4647. * console.log(arr.value); // ['Nancy', 'Drew']
  4648. * ```
  4649. *
  4650. * @param {?} value Array of values for the controls
  4651. * @param {?=} options Configure options that determine how the control propagates changes and
  4652. * emits events after the value changes
  4653. *
  4654. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
  4655. * is false.
  4656. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4657. * `valueChanges`
  4658. * observables emit events with the latest status and value when the control value is updated.
  4659. * When false, no events are emitted.
  4660. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4661. * updateValueAndValidity} method.
  4662. * @return {?}
  4663. */
  4664. setValue(value, options = {}) {
  4665. this._checkAllValuesPresent(value);
  4666. value.forEach((/**
  4667. * @param {?} newValue
  4668. * @param {?} index
  4669. * @return {?}
  4670. */
  4671. (newValue, index) => {
  4672. this._throwIfControlMissing(index);
  4673. this.at(index).setValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  4674. }));
  4675. this.updateValueAndValidity(options);
  4676. }
  4677. /**
  4678. * Patches the value of the `FormArray`. It accepts an array that matches the
  4679. * structure of the control, and does its best to match the values to the correct
  4680. * controls in the group.
  4681. *
  4682. * It accepts both super-sets and sub-sets of the array without throwing an error.
  4683. *
  4684. * \@usageNotes
  4685. * ### Patch the values for controls in a form array
  4686. *
  4687. * ```
  4688. * const arr = new FormArray([
  4689. * new FormControl(),
  4690. * new FormControl()
  4691. * ]);
  4692. * console.log(arr.value); // [null, null]
  4693. *
  4694. * arr.patchValue(['Nancy']);
  4695. * console.log(arr.value); // ['Nancy', null]
  4696. * ```
  4697. *
  4698. * @param {?} value Array of latest values for the controls
  4699. * @param {?=} options Configure options that determine how the control propagates changes and
  4700. * emits events after the value changes
  4701. *
  4702. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
  4703. * is false.
  4704. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4705. * `valueChanges`
  4706. * observables emit events with the latest status and value when the control value is updated.
  4707. * When false, no events are emitted.
  4708. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4709. * updateValueAndValidity} method.
  4710. * @return {?}
  4711. */
  4712. patchValue(value, options = {}) {
  4713. value.forEach((/**
  4714. * @param {?} newValue
  4715. * @param {?} index
  4716. * @return {?}
  4717. */
  4718. (newValue, index) => {
  4719. if (this.at(index)) {
  4720. this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  4721. }
  4722. }));
  4723. this.updateValueAndValidity(options);
  4724. }
  4725. /**
  4726. * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the
  4727. * value of all descendants to null or null maps.
  4728. *
  4729. * You reset to a specific form state by passing in an array of states
  4730. * that matches the structure of the control. The state is a standalone value
  4731. * or a form state object with both a value and a disabled status.
  4732. *
  4733. * \@usageNotes
  4734. * ### Reset the values in a form array
  4735. *
  4736. * ```ts
  4737. * const arr = new FormArray([
  4738. * new FormControl(),
  4739. * new FormControl()
  4740. * ]);
  4741. * arr.reset(['name', 'last name']);
  4742. *
  4743. * console.log(this.arr.value); // ['name', 'last name']
  4744. * ```
  4745. *
  4746. * ### Reset the values in a form array and the disabled status for the first control
  4747. *
  4748. * ```
  4749. * this.arr.reset([
  4750. * {value: 'name', disabled: true},
  4751. * 'last'
  4752. * ]);
  4753. *
  4754. * console.log(this.arr.value); // ['name', 'last name']
  4755. * console.log(this.arr.get(0).status); // 'DISABLED'
  4756. * ```
  4757. *
  4758. * @param {?=} value Array of values for the controls
  4759. * @param {?=} options Configure options that determine how the control propagates changes and
  4760. * emits events after the value changes
  4761. *
  4762. * * `onlySelf`: When true, each change only affects this control, and not its parent. Default
  4763. * is false.
  4764. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and
  4765. * `valueChanges`
  4766. * observables emit events with the latest status and value when the control is reset.
  4767. * When false, no events are emitted.
  4768. * The configuration options are passed to the {\@link AbstractControl#updateValueAndValidity
  4769. * updateValueAndValidity} method.
  4770. * @return {?}
  4771. */
  4772. reset(value = [], options = {}) {
  4773. this._forEachChild((/**
  4774. * @param {?} control
  4775. * @param {?} index
  4776. * @return {?}
  4777. */
  4778. (control, index) => {
  4779. control.reset(value[index], { onlySelf: true, emitEvent: options.emitEvent });
  4780. }));
  4781. this._updatePristine(options);
  4782. this._updateTouched(options);
  4783. this.updateValueAndValidity(options);
  4784. }
  4785. /**
  4786. * The aggregate value of the array, including any disabled controls.
  4787. *
  4788. * Reports all values regardless of disabled status.
  4789. * For enabled controls only, the `value` property is the best way to get the value of the array.
  4790. * @return {?}
  4791. */
  4792. getRawValue() {
  4793. return this.controls.map((/**
  4794. * @param {?} control
  4795. * @return {?}
  4796. */
  4797. (control) => {
  4798. return control instanceof FormControl ? control.value : ((/** @type {?} */ (control))).getRawValue();
  4799. }));
  4800. }
  4801. /**
  4802. * Remove all controls in the `FormArray`.
  4803. *
  4804. * \@usageNotes
  4805. * ### Remove all elements from a FormArray
  4806. *
  4807. * ```ts
  4808. * const arr = new FormArray([
  4809. * new FormControl(),
  4810. * new FormControl()
  4811. * ]);
  4812. * console.log(arr.length); // 2
  4813. *
  4814. * arr.clear();
  4815. * console.log(arr.length); // 0
  4816. * ```
  4817. *
  4818. * It's a simpler and more efficient alternative to removing all elements one by one:
  4819. *
  4820. * ```ts
  4821. * const arr = new FormArray([
  4822. * new FormControl(),
  4823. * new FormControl()
  4824. * ]);
  4825. *
  4826. * while (arr.length) {
  4827. * arr.removeAt(0);
  4828. * }
  4829. * ```
  4830. * @return {?}
  4831. */
  4832. clear() {
  4833. if (this.controls.length < 1)
  4834. return;
  4835. this._forEachChild((/**
  4836. * @param {?} control
  4837. * @return {?}
  4838. */
  4839. (control) => control._registerOnCollectionChange((/**
  4840. * @return {?}
  4841. */
  4842. () => { }))));
  4843. this.controls.splice(0);
  4844. this.updateValueAndValidity();
  4845. }
  4846. /**
  4847. * \@internal
  4848. * @return {?}
  4849. */
  4850. _syncPendingControls() {
  4851. /** @type {?} */
  4852. let subtreeUpdated = this.controls.reduce((/**
  4853. * @param {?} updated
  4854. * @param {?} child
  4855. * @return {?}
  4856. */
  4857. (updated, child) => {
  4858. return child._syncPendingControls() ? true : updated;
  4859. }), false);
  4860. if (subtreeUpdated)
  4861. this.updateValueAndValidity({ onlySelf: true });
  4862. return subtreeUpdated;
  4863. }
  4864. /**
  4865. * \@internal
  4866. * @param {?} index
  4867. * @return {?}
  4868. */
  4869. _throwIfControlMissing(index) {
  4870. if (!this.controls.length) {
  4871. throw new Error(`
  4872. There are no form controls registered with this array yet. If you're using ngModel,
  4873. you may want to check next tick (e.g. use setTimeout).
  4874. `);
  4875. }
  4876. if (!this.at(index)) {
  4877. throw new Error(`Cannot find form control at index ${index}`);
  4878. }
  4879. }
  4880. /**
  4881. * \@internal
  4882. * @param {?} cb
  4883. * @return {?}
  4884. */
  4885. _forEachChild(cb) {
  4886. this.controls.forEach((/**
  4887. * @param {?} control
  4888. * @param {?} index
  4889. * @return {?}
  4890. */
  4891. (control, index) => { cb(control, index); }));
  4892. }
  4893. /**
  4894. * \@internal
  4895. * @return {?}
  4896. */
  4897. _updateValue() {
  4898. ((/** @type {?} */ (this))).value =
  4899. this.controls.filter((/**
  4900. * @param {?} control
  4901. * @return {?}
  4902. */
  4903. (control) => control.enabled || this.disabled))
  4904. .map((/**
  4905. * @param {?} control
  4906. * @return {?}
  4907. */
  4908. (control) => control.value));
  4909. }
  4910. /**
  4911. * \@internal
  4912. * @param {?} condition
  4913. * @return {?}
  4914. */
  4915. _anyControls(condition) {
  4916. return this.controls.some((/**
  4917. * @param {?} control
  4918. * @return {?}
  4919. */
  4920. (control) => control.enabled && condition(control)));
  4921. }
  4922. /**
  4923. * \@internal
  4924. * @return {?}
  4925. */
  4926. _setUpControls() {
  4927. this._forEachChild((/**
  4928. * @param {?} control
  4929. * @return {?}
  4930. */
  4931. (control) => this._registerControl(control)));
  4932. }
  4933. /**
  4934. * \@internal
  4935. * @param {?} value
  4936. * @return {?}
  4937. */
  4938. _checkAllValuesPresent(value) {
  4939. this._forEachChild((/**
  4940. * @param {?} control
  4941. * @param {?} i
  4942. * @return {?}
  4943. */
  4944. (control, i) => {
  4945. if (value[i] === undefined) {
  4946. throw new Error(`Must supply a value for form control at index: ${i}.`);
  4947. }
  4948. }));
  4949. }
  4950. /**
  4951. * \@internal
  4952. * @return {?}
  4953. */
  4954. _allControlsDisabled() {
  4955. for (const control of this.controls) {
  4956. if (control.enabled)
  4957. return false;
  4958. }
  4959. return this.controls.length > 0 || this.disabled;
  4960. }
  4961. /**
  4962. * @private
  4963. * @param {?} control
  4964. * @return {?}
  4965. */
  4966. _registerControl(control) {
  4967. control.setParent(this);
  4968. control._registerOnCollectionChange(this._onCollectionChange);
  4969. }
  4970. }
  4971. /**
  4972. * @fileoverview added by tsickle
  4973. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  4974. */
  4975. /** @type {?} */
  4976. const formDirectiveProvider = {
  4977. provide: ControlContainer,
  4978. useExisting: forwardRef((/**
  4979. * @return {?}
  4980. */
  4981. () => NgForm))
  4982. };
  4983. const ɵ0 = /**
  4984. * @return {?}
  4985. */
  4986. () => Promise.resolve(null);
  4987. /** @type {?} */
  4988. const resolvedPromise = ((ɵ0))();
  4989. /**
  4990. * \@description
  4991. * Creates a top-level `FormGroup` instance and binds it to a form
  4992. * to track aggregate form value and validation status.
  4993. *
  4994. * As soon as you import the `FormsModule`, this directive becomes active by default on
  4995. * all `<form>` tags. You don't need to add a special selector.
  4996. *
  4997. * You optionally export the directive into a local template variable using `ngForm` as the key
  4998. * (ex: `#myForm="ngForm"`). This is optional, but useful. Many properties from the underlying
  4999. * `FormGroup` instance are duplicated on the directive itself, so a reference to it
  5000. * gives you access to the aggregate value and validity status of the form, as well as
  5001. * user interaction properties like `dirty` and `touched`.
  5002. *
  5003. * To register child controls with the form, use `NgModel` with a `name`
  5004. * attribute. You may use `NgModelGroup` to create sub-groups within the form.
  5005. *
  5006. * If necessary, listen to the directive's `ngSubmit` event to be notified when the user has
  5007. * triggered a form submission. The `ngSubmit` event emits the original form
  5008. * submission event.
  5009. *
  5010. * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`.
  5011. * To import the `FormsModule` but skip its usage in some forms,
  5012. * for example, to use native HTML5 validation, add the `ngNoForm` and the `<form>`
  5013. * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is
  5014. * unnecessary because the `<form>` tags are inert. In that case, you would
  5015. * refrain from using the `formGroup` directive.
  5016. *
  5017. * \@usageNotes
  5018. *
  5019. * ### Migrating from deprecated ngForm selector
  5020. *
  5021. * Support for using `ngForm` element selector has been deprecated in Angular v6 and will be removed
  5022. * in Angular v9.
  5023. *
  5024. * This has been deprecated to keep selectors consistent with other core Angular selectors,
  5025. * as element selectors are typically written in kebab-case.
  5026. *
  5027. * Now deprecated:
  5028. * ```html
  5029. * <ngForm #myForm="ngForm">
  5030. * ```
  5031. *
  5032. * After:
  5033. * ```html
  5034. * <ng-form #myForm="ngForm">
  5035. * ```
  5036. *
  5037. * ### Listening for form submission
  5038. *
  5039. * The following example shows how to capture the form values from the "ngSubmit" event.
  5040. *
  5041. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  5042. *
  5043. * ### Setting the update options
  5044. *
  5045. * The following example shows you how to change the "updateOn" option from its default using
  5046. * ngFormOptions.
  5047. *
  5048. * ```html
  5049. * <form [ngFormOptions]="{updateOn: 'blur'}">
  5050. * <input name="one" ngModel> <!-- this ngModel will update on blur -->
  5051. * </form>
  5052. * ```
  5053. *
  5054. * \@ngModule FormsModule
  5055. * \@publicApi
  5056. */
  5057. class NgForm extends ControlContainer {
  5058. /**
  5059. * @param {?} validators
  5060. * @param {?} asyncValidators
  5061. */
  5062. constructor(validators, asyncValidators) {
  5063. super();
  5064. /**
  5065. * \@description
  5066. * Returns whether the form submission has been triggered.
  5067. */
  5068. this.submitted = false;
  5069. this._directives = [];
  5070. /**
  5071. * \@description
  5072. * Event emitter for the "ngSubmit" event
  5073. */
  5074. this.ngSubmit = new EventEmitter();
  5075. this.form =
  5076. new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
  5077. }
  5078. /**
  5079. * \@description
  5080. * Lifecycle method called after the view is initialized. For internal use only.
  5081. * @return {?}
  5082. */
  5083. ngAfterViewInit() { this._setUpdateStrategy(); }
  5084. /**
  5085. * \@description
  5086. * The directive instance.
  5087. * @return {?}
  5088. */
  5089. get formDirective() { return this; }
  5090. /**
  5091. * \@description
  5092. * The internal `FormGroup` instance.
  5093. * @return {?}
  5094. */
  5095. get control() { return this.form; }
  5096. /**
  5097. * \@description
  5098. * Returns an array representing the path to this group. Because this directive
  5099. * always lives at the top level of a form, it is always an empty array.
  5100. * @return {?}
  5101. */
  5102. get path() { return []; }
  5103. /**
  5104. * \@description
  5105. * Returns a map of the controls in this group.
  5106. * @return {?}
  5107. */
  5108. get controls() { return this.form.controls; }
  5109. /**
  5110. * \@description
  5111. * Method that sets up the control directive in this group, re-calculates its value
  5112. * and validity, and adds the instance to the internal list of directives.
  5113. *
  5114. * @param {?} dir The `NgModel` directive instance.
  5115. * @return {?}
  5116. */
  5117. addControl(dir) {
  5118. resolvedPromise.then((/**
  5119. * @return {?}
  5120. */
  5121. () => {
  5122. /** @type {?} */
  5123. const container = this._findContainer(dir.path);
  5124. ((/** @type {?} */ (dir))).control =
  5125. (/** @type {?} */ (container.registerControl(dir.name, dir.control)));
  5126. setUpControl(dir.control, dir);
  5127. dir.control.updateValueAndValidity({ emitEvent: false });
  5128. this._directives.push(dir);
  5129. }));
  5130. }
  5131. /**
  5132. * \@description
  5133. * Retrieves the `FormControl` instance from the provided `NgModel` directive.
  5134. *
  5135. * @param {?} dir The `NgModel` directive instance.
  5136. * @return {?}
  5137. */
  5138. getControl(dir) { return (/** @type {?} */ (this.form.get(dir.path))); }
  5139. /**
  5140. * \@description
  5141. * Removes the `NgModel` instance from the internal list of directives
  5142. *
  5143. * @param {?} dir The `NgModel` directive instance.
  5144. * @return {?}
  5145. */
  5146. removeControl(dir) {
  5147. resolvedPromise.then((/**
  5148. * @return {?}
  5149. */
  5150. () => {
  5151. /** @type {?} */
  5152. const container = this._findContainer(dir.path);
  5153. if (container) {
  5154. container.removeControl(dir.name);
  5155. }
  5156. removeDir(this._directives, dir);
  5157. }));
  5158. }
  5159. /**
  5160. * \@description
  5161. * Adds a new `NgModelGroup` directive instance to the form.
  5162. *
  5163. * @param {?} dir The `NgModelGroup` directive instance.
  5164. * @return {?}
  5165. */
  5166. addFormGroup(dir) {
  5167. resolvedPromise.then((/**
  5168. * @return {?}
  5169. */
  5170. () => {
  5171. /** @type {?} */
  5172. const container = this._findContainer(dir.path);
  5173. /** @type {?} */
  5174. const group = new FormGroup({});
  5175. setUpFormContainer(group, dir);
  5176. container.registerControl(dir.name, group);
  5177. group.updateValueAndValidity({ emitEvent: false });
  5178. }));
  5179. }
  5180. /**
  5181. * \@description
  5182. * Removes the `NgModelGroup` directive instance from the form.
  5183. *
  5184. * @param {?} dir The `NgModelGroup` directive instance.
  5185. * @return {?}
  5186. */
  5187. removeFormGroup(dir) {
  5188. resolvedPromise.then((/**
  5189. * @return {?}
  5190. */
  5191. () => {
  5192. /** @type {?} */
  5193. const container = this._findContainer(dir.path);
  5194. if (container) {
  5195. container.removeControl(dir.name);
  5196. }
  5197. }));
  5198. }
  5199. /**
  5200. * \@description
  5201. * Retrieves the `FormGroup` for a provided `NgModelGroup` directive instance
  5202. *
  5203. * @param {?} dir The `NgModelGroup` directive instance.
  5204. * @return {?}
  5205. */
  5206. getFormGroup(dir) { return (/** @type {?} */ (this.form.get(dir.path))); }
  5207. /**
  5208. * Sets the new value for the provided `NgControl` directive.
  5209. *
  5210. * @param {?} dir The `NgControl` directive instance.
  5211. * @param {?} value The new value for the directive's control.
  5212. * @return {?}
  5213. */
  5214. updateModel(dir, value) {
  5215. resolvedPromise.then((/**
  5216. * @return {?}
  5217. */
  5218. () => {
  5219. /** @type {?} */
  5220. const ctrl = (/** @type {?} */ (this.form.get((/** @type {?} */ (dir.path)))));
  5221. ctrl.setValue(value);
  5222. }));
  5223. }
  5224. /**
  5225. * \@description
  5226. * Sets the value for this `FormGroup`.
  5227. *
  5228. * @param {?} value The new value
  5229. * @return {?}
  5230. */
  5231. setValue(value) { this.control.setValue(value); }
  5232. /**
  5233. * \@description
  5234. * Method called when the "submit" event is triggered on the form.
  5235. * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
  5236. *
  5237. * @param {?} $event The "submit" event object
  5238. * @return {?}
  5239. */
  5240. onSubmit($event) {
  5241. ((/** @type {?} */ (this))).submitted = true;
  5242. syncPendingControls(this.form, this._directives);
  5243. this.ngSubmit.emit($event);
  5244. return false;
  5245. }
  5246. /**
  5247. * \@description
  5248. * Method called when the "reset" event is triggered on the form.
  5249. * @return {?}
  5250. */
  5251. onReset() { this.resetForm(); }
  5252. /**
  5253. * \@description
  5254. * Resets the form to an initial value and resets its submitted status.
  5255. *
  5256. * @param {?=} value The new value for the form.
  5257. * @return {?}
  5258. */
  5259. resetForm(value = undefined) {
  5260. this.form.reset(value);
  5261. ((/** @type {?} */ (this))).submitted = false;
  5262. }
  5263. /**
  5264. * @private
  5265. * @return {?}
  5266. */
  5267. _setUpdateStrategy() {
  5268. if (this.options && this.options.updateOn != null) {
  5269. this.form._updateOn = this.options.updateOn;
  5270. }
  5271. }
  5272. /**
  5273. * \@internal
  5274. * @param {?} path
  5275. * @return {?}
  5276. */
  5277. _findContainer(path) {
  5278. path.pop();
  5279. return path.length ? (/** @type {?} */ (this.form.get(path))) : this.form;
  5280. }
  5281. }
  5282. NgForm.decorators = [
  5283. { type: Directive, args: [{
  5284. selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,ng-form,[ngForm]',
  5285. providers: [formDirectiveProvider],
  5286. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  5287. outputs: ['ngSubmit'],
  5288. exportAs: 'ngForm'
  5289. },] }
  5290. ];
  5291. /** @nocollapse */
  5292. NgForm.ctorParameters = () => [
  5293. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  5294. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }
  5295. ];
  5296. NgForm.propDecorators = {
  5297. options: [{ type: Input, args: ['ngFormOptions',] }]
  5298. };
  5299. /**
  5300. * @fileoverview added by tsickle
  5301. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5302. */
  5303. class TemplateDrivenErrors {
  5304. /**
  5305. * @return {?}
  5306. */
  5307. static modelParentException() {
  5308. throw new Error(`
  5309. ngModel cannot be used to register form controls with a parent formGroup directive. Try using
  5310. formGroup's partner directive "formControlName" instead. Example:
  5311. ${FormErrorExamples.formControlName}
  5312. Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:
  5313. Example:
  5314. ${FormErrorExamples.ngModelWithFormGroup}`);
  5315. }
  5316. /**
  5317. * @return {?}
  5318. */
  5319. static formGroupNameException() {
  5320. throw new Error(`
  5321. ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.
  5322. Option 1: Use formControlName instead of ngModel (reactive strategy):
  5323. ${FormErrorExamples.formGroupName}
  5324. Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy):
  5325. ${FormErrorExamples.ngModelGroup}`);
  5326. }
  5327. /**
  5328. * @return {?}
  5329. */
  5330. static missingNameException() {
  5331. throw new Error(`If ngModel is used within a form tag, either the name attribute must be set or the form
  5332. control must be defined as 'standalone' in ngModelOptions.
  5333. Example 1: <input [(ngModel)]="person.firstName" name="first">
  5334. Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">`);
  5335. }
  5336. /**
  5337. * @return {?}
  5338. */
  5339. static modelGroupParentException() {
  5340. throw new Error(`
  5341. ngModelGroup cannot be used with a parent formGroup directive.
  5342. Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):
  5343. ${FormErrorExamples.formGroupName}
  5344. Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy):
  5345. ${FormErrorExamples.ngModelGroup}`);
  5346. }
  5347. /**
  5348. * @return {?}
  5349. */
  5350. static ngFormWarning() {
  5351. console.warn(`
  5352. It looks like you're using 'ngForm'.
  5353. Support for using the 'ngForm' element selector has been deprecated in Angular v6 and will be removed
  5354. in Angular v9.
  5355. Use 'ng-form' instead.
  5356. Before:
  5357. <ngForm #myForm="ngForm">
  5358. After:
  5359. <ng-form #myForm="ngForm">
  5360. `);
  5361. }
  5362. }
  5363. /**
  5364. * @fileoverview added by tsickle
  5365. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5366. */
  5367. /**
  5368. * \@description
  5369. * `InjectionToken` to provide to turn off the warning when using 'ngForm' deprecated selector.
  5370. * @type {?}
  5371. */
  5372. const NG_FORM_SELECTOR_WARNING = new InjectionToken('NgFormSelectorWarning');
  5373. /**
  5374. * This directive is solely used to display warnings when the deprecated `ngForm` selector is used.
  5375. *
  5376. * @deprecated in Angular v6 and will be removed in Angular v9.
  5377. * \@ngModule FormsModule
  5378. * \@publicApi
  5379. */
  5380. class NgFormSelectorWarning {
  5381. /**
  5382. * @param {?} ngFormWarning
  5383. */
  5384. constructor(ngFormWarning) {
  5385. if (((!ngFormWarning || ngFormWarning === 'once') && !NgFormSelectorWarning._ngFormWarning) ||
  5386. ngFormWarning === 'always') {
  5387. TemplateDrivenErrors.ngFormWarning();
  5388. NgFormSelectorWarning._ngFormWarning = true;
  5389. }
  5390. }
  5391. }
  5392. /**
  5393. * Static property used to track whether the deprecation warning for this selector has been sent.
  5394. * Used to support warning config of "once".
  5395. *
  5396. * \@internal
  5397. */
  5398. NgFormSelectorWarning._ngFormWarning = false;
  5399. NgFormSelectorWarning.decorators = [
  5400. { type: Directive, args: [{ selector: 'ngForm' },] }
  5401. ];
  5402. /** @nocollapse */
  5403. NgFormSelectorWarning.ctorParameters = () => [
  5404. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_FORM_SELECTOR_WARNING,] }] }
  5405. ];
  5406. /**
  5407. * @fileoverview added by tsickle
  5408. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5409. */
  5410. /**
  5411. * \@description
  5412. * A base class for code shared between the `NgModelGroup` and `FormGroupName` directives.
  5413. *
  5414. * \@publicApi
  5415. */
  5416. class AbstractFormGroupDirective extends ControlContainer {
  5417. /**
  5418. * \@description
  5419. * An internal callback method triggered on the instance after the inputs are set.
  5420. * Registers the group with its parent group.
  5421. * @return {?}
  5422. */
  5423. ngOnInit() {
  5424. this._checkParentType();
  5425. (/** @type {?} */ (this.formDirective)).addFormGroup(this);
  5426. }
  5427. /**
  5428. * \@description
  5429. * An internal callback method triggered before the instance is destroyed.
  5430. * Removes the group from its parent group.
  5431. * @return {?}
  5432. */
  5433. ngOnDestroy() {
  5434. if (this.formDirective) {
  5435. this.formDirective.removeFormGroup(this);
  5436. }
  5437. }
  5438. /**
  5439. * \@description
  5440. * The `FormGroup` bound to this directive.
  5441. * @return {?}
  5442. */
  5443. get control() { return (/** @type {?} */ (this.formDirective)).getFormGroup(this); }
  5444. /**
  5445. * \@description
  5446. * The path to this group from the top-level directive.
  5447. * @return {?}
  5448. */
  5449. get path() { return controlPath(this.name, this._parent); }
  5450. /**
  5451. * \@description
  5452. * The top-level directive for this group if present, otherwise null.
  5453. * @return {?}
  5454. */
  5455. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  5456. /**
  5457. * \@description
  5458. * The synchronous validators registered with this group.
  5459. * @return {?}
  5460. */
  5461. get validator() { return composeValidators(this._validators); }
  5462. /**
  5463. * \@description
  5464. * The async validators registered with this group.
  5465. * @return {?}
  5466. */
  5467. get asyncValidator() {
  5468. return composeAsyncValidators(this._asyncValidators);
  5469. }
  5470. /**
  5471. * \@internal
  5472. * @return {?}
  5473. */
  5474. _checkParentType() { }
  5475. }
  5476. /**
  5477. * @fileoverview added by tsickle
  5478. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5479. */
  5480. /** @type {?} */
  5481. const modelGroupProvider = {
  5482. provide: ControlContainer,
  5483. useExisting: forwardRef((/**
  5484. * @return {?}
  5485. */
  5486. () => NgModelGroup))
  5487. };
  5488. /**
  5489. * \@description
  5490. * Creates and binds a `FormGroup` instance to a DOM element.
  5491. *
  5492. * This directive can only be used as a child of `NgForm` (within `<form>` tags).
  5493. *
  5494. * Use this directive to validate a sub-group of your form separately from the
  5495. * rest of your form, or if some values in your domain model make more sense
  5496. * to consume together in a nested object.
  5497. *
  5498. * Provide a name for the sub-group and it will become the key
  5499. * for the sub-group in the form's full value. If you need direct access, export the directive into
  5500. * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
  5501. *
  5502. * \@usageNotes
  5503. *
  5504. * ### Consuming controls in a grouping
  5505. *
  5506. * The following example shows you how to combine controls together in a sub-group
  5507. * of the form.
  5508. *
  5509. * {\@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
  5510. *
  5511. * \@ngModule FormsModule
  5512. * \@publicApi
  5513. */
  5514. class NgModelGroup extends AbstractFormGroupDirective {
  5515. /**
  5516. * @param {?} parent
  5517. * @param {?} validators
  5518. * @param {?} asyncValidators
  5519. */
  5520. constructor(parent, validators, asyncValidators) {
  5521. super();
  5522. this._parent = parent;
  5523. this._validators = validators;
  5524. this._asyncValidators = asyncValidators;
  5525. }
  5526. /**
  5527. * \@internal
  5528. * @return {?}
  5529. */
  5530. _checkParentType() {
  5531. if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  5532. TemplateDrivenErrors.modelGroupParentException();
  5533. }
  5534. }
  5535. }
  5536. NgModelGroup.decorators = [
  5537. { type: Directive, args: [{ selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup' },] }
  5538. ];
  5539. /** @nocollapse */
  5540. NgModelGroup.ctorParameters = () => [
  5541. { type: ControlContainer, decorators: [{ type: Host }, { type: SkipSelf }] },
  5542. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  5543. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }
  5544. ];
  5545. NgModelGroup.propDecorators = {
  5546. name: [{ type: Input, args: ['ngModelGroup',] }]
  5547. };
  5548. /**
  5549. * @fileoverview added by tsickle
  5550. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5551. */
  5552. /** @type {?} */
  5553. const formControlBinding = {
  5554. provide: NgControl,
  5555. useExisting: forwardRef((/**
  5556. * @return {?}
  5557. */
  5558. () => NgModel))
  5559. };
  5560. const ɵ0$1 = /**
  5561. * @return {?}
  5562. */
  5563. () => Promise.resolve(null);
  5564. /**
  5565. * `ngModel` forces an additional change detection run when its inputs change:
  5566. * E.g.:
  5567. * ```
  5568. * <div>{{myModel.valid}}</div>
  5569. * <input [(ngModel)]="myValue" #myModel="ngModel">
  5570. * ```
  5571. * I.e. `ngModel` can export itself on the element and then be used in the template.
  5572. * Normally, this would result in expressions before the `input` that use the exported directive
  5573. * to have and old value as they have been
  5574. * dirty checked before. As this is a very common case for `ngModel`, we added this second change
  5575. * detection run.
  5576. *
  5577. * Notes:
  5578. * - this is just one extra run no matter how many `ngModel` have been changed.
  5579. * - this is a general problem when using `exportAs` for directives!
  5580. * @type {?}
  5581. */
  5582. const resolvedPromise$1 = ((ɵ0$1))();
  5583. /**
  5584. * \@description
  5585. * Creates a `FormControl` instance from a domain model and binds it
  5586. * to a form control element.
  5587. *
  5588. * The `FormControl` instance tracks the value, user interaction, and
  5589. * validation status of the control and keeps the view synced with the model. If used
  5590. * within a parent form, the directive also registers itself with the form as a child
  5591. * control.
  5592. *
  5593. * This directive is used by itself or as part of a larger form. Use the
  5594. * `ngModel` selector to activate it.
  5595. *
  5596. * It accepts a domain model as an optional `Input`. If you have a one-way binding
  5597. * to `ngModel` with `[]` syntax, changing the value of the domain model in the component
  5598. * class sets the value in the view. If you have a two-way binding with `[()]` syntax
  5599. * (also known as 'banana-box syntax'), the value in the UI always syncs back to
  5600. * the domain model in your class.
  5601. *
  5602. * To inspect the properties of the associated `FormControl` (like validity state),
  5603. * export the directive into a local template variable using `ngModel` as the key (ex: `#myVar="ngModel"`).
  5604. * You then access the control using the directive's `control` property,
  5605. * but most properties used (like `valid` and `dirty`) fall through to the control anyway for direct access.
  5606. * See a full list of properties directly available in `AbstractControlDirective`.
  5607. *
  5608. * @see `RadioControlValueAccessor`
  5609. * @see `SelectControlValueAccessor`
  5610. *
  5611. * \@usageNotes
  5612. *
  5613. * ### Using ngModel on a standalone control
  5614. *
  5615. * The following examples show a simple standalone control using `ngModel`:
  5616. *
  5617. * {\@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
  5618. *
  5619. * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
  5620. * so that the control can be registered with the parent form under that name.
  5621. *
  5622. * In the context of a parent form, it's often unnecessary to include one-way or two-way binding,
  5623. * as the parent form syncs the value for you. You access its properties by exporting it into a
  5624. * local template variable using `ngForm` such as (`#f="ngForm"`). Use the variable where
  5625. * needed on form submission.
  5626. *
  5627. * If you do need to populate initial values into your form, using a one-way binding for
  5628. * `ngModel` tends to be sufficient as long as you use the exported form's value rather
  5629. * than the domain model's value on submit.
  5630. *
  5631. * ### Using ngModel within a form
  5632. *
  5633. * The following example shows controls using `ngModel` within a form:
  5634. *
  5635. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  5636. *
  5637. * ### Using a standalone ngModel within a group
  5638. *
  5639. * The following example shows you how to use a standalone ngModel control
  5640. * within a form. This controls the display of the form, but doesn't contain form data.
  5641. *
  5642. * ```html
  5643. * <form>
  5644. * <input name="login" ngModel placeholder="Login">
  5645. * <input type="checkbox" ngModel [ngModelOptions]="{standalone: true}"> Show more options?
  5646. * </form>
  5647. * <!-- form value: {login: ''} -->
  5648. * ```
  5649. *
  5650. * ### Setting the ngModel name attribute through options
  5651. *
  5652. * The following example shows you an alternate way to set the name attribute. The name attribute is used
  5653. * within a custom form component, and the name `\@Input` property serves a different purpose.
  5654. *
  5655. * ```html
  5656. * <form>
  5657. * <my-person-control name="Nancy" ngModel [ngModelOptions]="{name: 'user'}">
  5658. * </my-person-control>
  5659. * </form>
  5660. * <!-- form value: {user: ''} -->
  5661. * ```
  5662. *
  5663. * \@ngModule FormsModule
  5664. * \@publicApi
  5665. */
  5666. class NgModel extends NgControl {
  5667. /**
  5668. * @param {?} parent
  5669. * @param {?} validators
  5670. * @param {?} asyncValidators
  5671. * @param {?} valueAccessors
  5672. */
  5673. constructor(parent, validators, asyncValidators, valueAccessors) {
  5674. super();
  5675. this.control = new FormControl();
  5676. /**
  5677. * \@internal
  5678. */
  5679. this._registered = false;
  5680. /**
  5681. * \@description
  5682. * Event emitter for producing the `ngModelChange` event after
  5683. * the view model updates.
  5684. */
  5685. this.update = new EventEmitter();
  5686. this._parent = parent;
  5687. this._rawValidators = validators || [];
  5688. this._rawAsyncValidators = asyncValidators || [];
  5689. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  5690. }
  5691. /**
  5692. * \@description
  5693. * A lifecycle method called when the directive's inputs change. For internal use
  5694. * only.
  5695. *
  5696. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  5697. * @return {?}
  5698. */
  5699. ngOnChanges(changes) {
  5700. this._checkForErrors();
  5701. if (!this._registered)
  5702. this._setUpControl();
  5703. if ('isDisabled' in changes) {
  5704. this._updateDisabled(changes);
  5705. }
  5706. if (isPropertyUpdated(changes, this.viewModel)) {
  5707. this._updateValue(this.model);
  5708. this.viewModel = this.model;
  5709. }
  5710. }
  5711. /**
  5712. * \@description
  5713. * Lifecycle method called before the directive's instance is destroyed. For internal
  5714. * use only.
  5715. * @return {?}
  5716. */
  5717. ngOnDestroy() { this.formDirective && this.formDirective.removeControl(this); }
  5718. /**
  5719. * \@description
  5720. * Returns an array that represents the path from the top-level form to this control.
  5721. * Each index is the string name of the control on that level.
  5722. * @return {?}
  5723. */
  5724. get path() {
  5725. return this._parent ? controlPath(this.name, this._parent) : [this.name];
  5726. }
  5727. /**
  5728. * \@description
  5729. * The top-level directive for this control if present, otherwise null.
  5730. * @return {?}
  5731. */
  5732. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  5733. /**
  5734. * \@description
  5735. * Synchronous validator function composed of all the synchronous validators
  5736. * registered with this directive.
  5737. * @return {?}
  5738. */
  5739. get validator() { return composeValidators(this._rawValidators); }
  5740. /**
  5741. * \@description
  5742. * Async validator function composed of all the async validators registered with this
  5743. * directive.
  5744. * @return {?}
  5745. */
  5746. get asyncValidator() {
  5747. return composeAsyncValidators(this._rawAsyncValidators);
  5748. }
  5749. /**
  5750. * \@description
  5751. * Sets the new value for the view model and emits an `ngModelChange` event.
  5752. *
  5753. * @param {?} newValue The new value emitted by `ngModelChange`.
  5754. * @return {?}
  5755. */
  5756. viewToModelUpdate(newValue) {
  5757. this.viewModel = newValue;
  5758. this.update.emit(newValue);
  5759. }
  5760. /**
  5761. * @private
  5762. * @return {?}
  5763. */
  5764. _setUpControl() {
  5765. this._setUpdateStrategy();
  5766. this._isStandalone() ? this._setUpStandalone() :
  5767. this.formDirective.addControl(this);
  5768. this._registered = true;
  5769. }
  5770. /**
  5771. * @private
  5772. * @return {?}
  5773. */
  5774. _setUpdateStrategy() {
  5775. if (this.options && this.options.updateOn != null) {
  5776. this.control._updateOn = this.options.updateOn;
  5777. }
  5778. }
  5779. /**
  5780. * @private
  5781. * @return {?}
  5782. */
  5783. _isStandalone() {
  5784. return !this._parent || !!(this.options && this.options.standalone);
  5785. }
  5786. /**
  5787. * @private
  5788. * @return {?}
  5789. */
  5790. _setUpStandalone() {
  5791. setUpControl(this.control, this);
  5792. this.control.updateValueAndValidity({ emitEvent: false });
  5793. }
  5794. /**
  5795. * @private
  5796. * @return {?}
  5797. */
  5798. _checkForErrors() {
  5799. if (!this._isStandalone()) {
  5800. this._checkParentType();
  5801. }
  5802. this._checkName();
  5803. }
  5804. /**
  5805. * @private
  5806. * @return {?}
  5807. */
  5808. _checkParentType() {
  5809. if (!(this._parent instanceof NgModelGroup) &&
  5810. this._parent instanceof AbstractFormGroupDirective) {
  5811. TemplateDrivenErrors.formGroupNameException();
  5812. }
  5813. else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  5814. TemplateDrivenErrors.modelParentException();
  5815. }
  5816. }
  5817. /**
  5818. * @private
  5819. * @return {?}
  5820. */
  5821. _checkName() {
  5822. if (this.options && this.options.name)
  5823. this.name = this.options.name;
  5824. if (!this._isStandalone() && !this.name) {
  5825. TemplateDrivenErrors.missingNameException();
  5826. }
  5827. }
  5828. /**
  5829. * @private
  5830. * @param {?} value
  5831. * @return {?}
  5832. */
  5833. _updateValue(value) {
  5834. resolvedPromise$1.then((/**
  5835. * @return {?}
  5836. */
  5837. () => { this.control.setValue(value, { emitViewToModelChange: false }); }));
  5838. }
  5839. /**
  5840. * @private
  5841. * @param {?} changes
  5842. * @return {?}
  5843. */
  5844. _updateDisabled(changes) {
  5845. /** @type {?} */
  5846. const disabledValue = changes['isDisabled'].currentValue;
  5847. /** @type {?} */
  5848. const isDisabled = disabledValue === '' || (disabledValue && disabledValue !== 'false');
  5849. resolvedPromise$1.then((/**
  5850. * @return {?}
  5851. */
  5852. () => {
  5853. if (isDisabled && !this.control.disabled) {
  5854. this.control.disable();
  5855. }
  5856. else if (!isDisabled && this.control.disabled) {
  5857. this.control.enable();
  5858. }
  5859. }));
  5860. }
  5861. }
  5862. NgModel.decorators = [
  5863. { type: Directive, args: [{
  5864. selector: '[ngModel]:not([formControlName]):not([formControl])',
  5865. providers: [formControlBinding],
  5866. exportAs: 'ngModel'
  5867. },] }
  5868. ];
  5869. /** @nocollapse */
  5870. NgModel.ctorParameters = () => [
  5871. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }] },
  5872. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  5873. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] },
  5874. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] }
  5875. ];
  5876. NgModel.propDecorators = {
  5877. name: [{ type: Input }],
  5878. isDisabled: [{ type: Input, args: ['disabled',] }],
  5879. model: [{ type: Input, args: ['ngModel',] }],
  5880. options: [{ type: Input, args: ['ngModelOptions',] }],
  5881. update: [{ type: Output, args: ['ngModelChange',] }]
  5882. };
  5883. /**
  5884. * @fileoverview added by tsickle
  5885. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5886. */
  5887. /**
  5888. * \@description
  5889. *
  5890. * Adds `novalidate` attribute to all forms by default.
  5891. *
  5892. * `novalidate` is used to disable browser's native form validation.
  5893. *
  5894. * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
  5895. *
  5896. * ```
  5897. * <form ngNativeValidate></form>
  5898. * ```
  5899. *
  5900. * \@publicApi
  5901. * \@ngModule ReactiveFormsModule
  5902. * \@ngModule FormsModule
  5903. */
  5904. class ɵNgNoValidate {
  5905. }
  5906. ɵNgNoValidate.decorators = [
  5907. { type: Directive, args: [{
  5908. selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
  5909. host: { 'novalidate': '' },
  5910. },] }
  5911. ];
  5912. /**
  5913. * @fileoverview added by tsickle
  5914. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  5915. */
  5916. /**
  5917. * Token to provide to turn off the ngModel warning on formControl and formControlName.
  5918. * @type {?}
  5919. */
  5920. const NG_MODEL_WITH_FORM_CONTROL_WARNING = new InjectionToken('NgModelWithFormControlWarning');
  5921. /** @type {?} */
  5922. const formControlBinding$1 = {
  5923. provide: NgControl,
  5924. useExisting: forwardRef((/**
  5925. * @return {?}
  5926. */
  5927. () => FormControlDirective))
  5928. };
  5929. /**
  5930. * \@description
  5931. * * Syncs a standalone `FormControl` instance to a form control element.
  5932. *
  5933. * @see [Reactive Forms Guide](guide/reactive-forms)
  5934. * @see `FormControl`
  5935. * @see `AbstractControl`
  5936. *
  5937. * \@usageNotes
  5938. *
  5939. * ### Registering a single form control
  5940. *
  5941. * The following examples shows how to register a standalone control and set its value.
  5942. *
  5943. * {\@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
  5944. *
  5945. * ### Use with ngModel
  5946. *
  5947. * Support for using the `ngModel` input property and `ngModelChange` event with reactive
  5948. * form directives has been deprecated in Angular v6 and will be removed in Angular v7.
  5949. *
  5950. * Now deprecated:
  5951. *
  5952. * ```html
  5953. * <input [formControl]="control" [(ngModel)]="value">
  5954. * ```
  5955. *
  5956. * ```ts
  5957. * this.value = 'some value';
  5958. * ```
  5959. *
  5960. * This has been deprecated for a few reasons. First, developers have found this pattern
  5961. * confusing. It seems like the actual `ngModel` directive is being used, but in fact it's
  5962. * an input/output property named `ngModel` on the reactive form directive that simply
  5963. * approximates (some of) its behavior. Specifically, it allows getting/setting the value
  5964. * and intercepting value events. However, some of `ngModel`'s other features - like
  5965. * delaying updates with`ngModelOptions` or exporting the directive - simply don't work,
  5966. * which has understandably caused some confusion.
  5967. *
  5968. * In addition, this pattern mixes template-driven and reactive forms strategies, which
  5969. * we generally don't recommend because it doesn't take advantage of the full benefits of
  5970. * either strategy. Setting the value in the template violates the template-agnostic
  5971. * principles behind reactive forms, whereas adding a `FormControl`/`FormGroup` layer in
  5972. * the class removes the convenience of defining forms in the template.
  5973. *
  5974. * To update your code before v7, you'll want to decide whether to stick with reactive form
  5975. * directives (and get/set values using reactive forms patterns) or switch over to
  5976. * template-driven directives.
  5977. *
  5978. * After (choice 1 - use reactive forms):
  5979. *
  5980. * ```html
  5981. * <input [formControl]="control">
  5982. * ```
  5983. *
  5984. * ```ts
  5985. * this.control.setValue('some value');
  5986. * ```
  5987. *
  5988. * After (choice 2 - use template-driven forms):
  5989. *
  5990. * ```html
  5991. * <input [(ngModel)]="value">
  5992. * ```
  5993. *
  5994. * ```ts
  5995. * this.value = 'some value';
  5996. * ```
  5997. *
  5998. * By default, when you use this pattern, you will see a deprecation warning once in dev
  5999. * mode. You can choose to silence this warning by providing a config for
  6000. * `ReactiveFormsModule` at import time:
  6001. *
  6002. * ```ts
  6003. * imports: [
  6004. * ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'});
  6005. * ]
  6006. * ```
  6007. *
  6008. * Alternatively, you can choose to surface a separate warning for each instance of this
  6009. * pattern with a config value of `"always"`. This may help to track down where in the code
  6010. * the pattern is being used as the code is being updated.
  6011. *
  6012. * \@ngModule ReactiveFormsModule
  6013. * \@publicApi
  6014. */
  6015. class FormControlDirective extends NgControl {
  6016. /**
  6017. * @param {?} validators
  6018. * @param {?} asyncValidators
  6019. * @param {?} valueAccessors
  6020. * @param {?} _ngModelWarningConfig
  6021. */
  6022. constructor(validators, asyncValidators, valueAccessors, _ngModelWarningConfig) {
  6023. super();
  6024. this._ngModelWarningConfig = _ngModelWarningConfig;
  6025. /**
  6026. * @deprecated as of v6
  6027. */
  6028. this.update = new EventEmitter();
  6029. /**
  6030. * \@description
  6031. * Instance property used to track whether an ngModel warning has been sent out for this
  6032. * particular `FormControlDirective` instance. Used to support warning config of "always".
  6033. *
  6034. * \@internal
  6035. */
  6036. this._ngModelWarningSent = false;
  6037. this._rawValidators = validators || [];
  6038. this._rawAsyncValidators = asyncValidators || [];
  6039. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  6040. }
  6041. /**
  6042. * \@description
  6043. * Triggers a warning that this input should not be used with reactive forms.
  6044. * @param {?} isDisabled
  6045. * @return {?}
  6046. */
  6047. set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); }
  6048. /**
  6049. * \@description
  6050. * A lifecycle method called when the directive's inputs change. For internal use
  6051. * only.
  6052. *
  6053. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  6054. * @return {?}
  6055. */
  6056. ngOnChanges(changes) {
  6057. if (this._isControlChanged(changes)) {
  6058. setUpControl(this.form, this);
  6059. if (this.control.disabled && (/** @type {?} */ (this.valueAccessor)).setDisabledState) {
  6060. (/** @type {?} */ ((/** @type {?} */ (this.valueAccessor)).setDisabledState))(true);
  6061. }
  6062. this.form.updateValueAndValidity({ emitEvent: false });
  6063. }
  6064. if (isPropertyUpdated(changes, this.viewModel)) {
  6065. _ngModelWarning('formControl', FormControlDirective, this, this._ngModelWarningConfig);
  6066. this.form.setValue(this.model);
  6067. this.viewModel = this.model;
  6068. }
  6069. }
  6070. /**
  6071. * \@description
  6072. * Returns an array that represents the path from the top-level form to this control.
  6073. * Each index is the string name of the control on that level.
  6074. * @return {?}
  6075. */
  6076. get path() { return []; }
  6077. /**
  6078. * \@description
  6079. * Synchronous validator function composed of all the synchronous validators
  6080. * registered with this directive.
  6081. * @return {?}
  6082. */
  6083. get validator() { return composeValidators(this._rawValidators); }
  6084. /**
  6085. * \@description
  6086. * Async validator function composed of all the async validators registered with this
  6087. * directive.
  6088. * @return {?}
  6089. */
  6090. get asyncValidator() {
  6091. return composeAsyncValidators(this._rawAsyncValidators);
  6092. }
  6093. /**
  6094. * \@description
  6095. * The `FormControl` bound to this directive.
  6096. * @return {?}
  6097. */
  6098. get control() { return this.form; }
  6099. /**
  6100. * \@description
  6101. * Sets the new value for the view model and emits an `ngModelChange` event.
  6102. *
  6103. * @param {?} newValue The new value for the view model.
  6104. * @return {?}
  6105. */
  6106. viewToModelUpdate(newValue) {
  6107. this.viewModel = newValue;
  6108. this.update.emit(newValue);
  6109. }
  6110. /**
  6111. * @private
  6112. * @param {?} changes
  6113. * @return {?}
  6114. */
  6115. _isControlChanged(changes) {
  6116. return changes.hasOwnProperty('form');
  6117. }
  6118. }
  6119. /**
  6120. * \@description
  6121. * Static property used to track whether any ngModel warnings have been sent across
  6122. * all instances of FormControlDirective. Used to support warning config of "once".
  6123. *
  6124. * \@internal
  6125. */
  6126. FormControlDirective._ngModelWarningSentOnce = false;
  6127. FormControlDirective.decorators = [
  6128. { type: Directive, args: [{ selector: '[formControl]', providers: [formControlBinding$1], exportAs: 'ngForm' },] }
  6129. ];
  6130. /** @nocollapse */
  6131. FormControlDirective.ctorParameters = () => [
  6132. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  6133. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] },
  6134. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] },
  6135. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_MODEL_WITH_FORM_CONTROL_WARNING,] }] }
  6136. ];
  6137. FormControlDirective.propDecorators = {
  6138. form: [{ type: Input, args: ['formControl',] }],
  6139. isDisabled: [{ type: Input, args: ['disabled',] }],
  6140. model: [{ type: Input, args: ['ngModel',] }],
  6141. update: [{ type: Output, args: ['ngModelChange',] }]
  6142. };
  6143. /**
  6144. * @fileoverview added by tsickle
  6145. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6146. */
  6147. /** @type {?} */
  6148. const formDirectiveProvider$1 = {
  6149. provide: ControlContainer,
  6150. useExisting: forwardRef((/**
  6151. * @return {?}
  6152. */
  6153. () => FormGroupDirective))
  6154. };
  6155. /**
  6156. * \@description
  6157. *
  6158. * Binds an existing `FormGroup` to a DOM element.
  6159. *
  6160. * This directive accepts an existing `FormGroup` instance. It will then use this
  6161. * `FormGroup` instance to match any child `FormControl`, `FormGroup`,
  6162. * and `FormArray` instances to child `FormControlName`, `FormGroupName`,
  6163. * and `FormArrayName` directives.
  6164. *
  6165. * @see [Reactive Forms Guide](guide/reactive-forms)
  6166. * @see `AbstractControl`
  6167. *
  6168. * ### Register Form Group
  6169. *
  6170. * The following example registers a `FormGroup` with first name and last name controls,
  6171. * and listens for the *ngSubmit* event when the button is clicked.
  6172. *
  6173. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  6174. *
  6175. * \@ngModule ReactiveFormsModule
  6176. * \@publicApi
  6177. */
  6178. class FormGroupDirective extends ControlContainer {
  6179. /**
  6180. * @param {?} _validators
  6181. * @param {?} _asyncValidators
  6182. */
  6183. constructor(_validators, _asyncValidators) {
  6184. super();
  6185. this._validators = _validators;
  6186. this._asyncValidators = _asyncValidators;
  6187. /**
  6188. * \@description
  6189. * Reports whether the form submission has been triggered.
  6190. */
  6191. this.submitted = false;
  6192. /**
  6193. * \@description
  6194. * Tracks the list of added `FormControlName` instances
  6195. */
  6196. this.directives = [];
  6197. /**
  6198. * \@description
  6199. * Tracks the `FormGroup` bound to this directive.
  6200. */
  6201. this.form = (/** @type {?} */ (null));
  6202. /**
  6203. * \@description
  6204. * Emits an event when the form submission has been triggered.
  6205. */
  6206. this.ngSubmit = new EventEmitter();
  6207. }
  6208. /**
  6209. * \@description
  6210. * A lifecycle method called when the directive's inputs change. For internal use only.
  6211. *
  6212. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  6213. * @return {?}
  6214. */
  6215. ngOnChanges(changes) {
  6216. this._checkFormPresent();
  6217. if (changes.hasOwnProperty('form')) {
  6218. this._updateValidators();
  6219. this._updateDomValue();
  6220. this._updateRegistrations();
  6221. }
  6222. }
  6223. /**
  6224. * \@description
  6225. * Returns this directive's instance.
  6226. * @return {?}
  6227. */
  6228. get formDirective() { return this; }
  6229. /**
  6230. * \@description
  6231. * Returns the `FormGroup` bound to this directive.
  6232. * @return {?}
  6233. */
  6234. get control() { return this.form; }
  6235. /**
  6236. * \@description
  6237. * Returns an array representing the path to this group. Because this directive
  6238. * always lives at the top level of a form, it always an empty array.
  6239. * @return {?}
  6240. */
  6241. get path() { return []; }
  6242. /**
  6243. * \@description
  6244. * Method that sets up the control directive in this group, re-calculates its value
  6245. * and validity, and adds the instance to the internal list of directives.
  6246. *
  6247. * @param {?} dir The `FormControlName` directive instance.
  6248. * @return {?}
  6249. */
  6250. addControl(dir) {
  6251. /** @type {?} */
  6252. const ctrl = this.form.get(dir.path);
  6253. setUpControl(ctrl, dir);
  6254. ctrl.updateValueAndValidity({ emitEvent: false });
  6255. this.directives.push(dir);
  6256. return ctrl;
  6257. }
  6258. /**
  6259. * \@description
  6260. * Retrieves the `FormControl` instance from the provided `FormControlName` directive
  6261. *
  6262. * @param {?} dir The `FormControlName` directive instance.
  6263. * @return {?}
  6264. */
  6265. getControl(dir) { return (/** @type {?} */ (this.form.get(dir.path))); }
  6266. /**
  6267. * \@description
  6268. * Removes the `FormControlName` instance from the internal list of directives
  6269. *
  6270. * @param {?} dir The `FormControlName` directive instance.
  6271. * @return {?}
  6272. */
  6273. removeControl(dir) { removeDir(this.directives, dir); }
  6274. /**
  6275. * Adds a new `FormGroupName` directive instance to the form.
  6276. *
  6277. * @param {?} dir The `FormGroupName` directive instance.
  6278. * @return {?}
  6279. */
  6280. addFormGroup(dir) {
  6281. /** @type {?} */
  6282. const ctrl = this.form.get(dir.path);
  6283. setUpFormContainer(ctrl, dir);
  6284. ctrl.updateValueAndValidity({ emitEvent: false });
  6285. }
  6286. /**
  6287. * No-op method to remove the form group.
  6288. *
  6289. * @param {?} dir The `FormGroupName` directive instance.
  6290. * @return {?}
  6291. */
  6292. removeFormGroup(dir) { }
  6293. /**
  6294. * \@description
  6295. * Retrieves the `FormGroup` for a provided `FormGroupName` directive instance
  6296. *
  6297. * @param {?} dir The `FormGroupName` directive instance.
  6298. * @return {?}
  6299. */
  6300. getFormGroup(dir) { return (/** @type {?} */ (this.form.get(dir.path))); }
  6301. /**
  6302. * Adds a new `FormArrayName` directive instance to the form.
  6303. *
  6304. * @param {?} dir The `FormArrayName` directive instance.
  6305. * @return {?}
  6306. */
  6307. addFormArray(dir) {
  6308. /** @type {?} */
  6309. const ctrl = this.form.get(dir.path);
  6310. setUpFormContainer(ctrl, dir);
  6311. ctrl.updateValueAndValidity({ emitEvent: false });
  6312. }
  6313. /**
  6314. * No-op method to remove the form array.
  6315. *
  6316. * @param {?} dir The `FormArrayName` directive instance.
  6317. * @return {?}
  6318. */
  6319. removeFormArray(dir) { }
  6320. /**
  6321. * \@description
  6322. * Retrieves the `FormArray` for a provided `FormArrayName` directive instance.
  6323. *
  6324. * @param {?} dir The `FormArrayName` directive instance.
  6325. * @return {?}
  6326. */
  6327. getFormArray(dir) { return (/** @type {?} */ (this.form.get(dir.path))); }
  6328. /**
  6329. * Sets the new value for the provided `FormControlName` directive.
  6330. *
  6331. * @param {?} dir The `FormControlName` directive instance.
  6332. * @param {?} value The new value for the directive's control.
  6333. * @return {?}
  6334. */
  6335. updateModel(dir, value) {
  6336. /** @type {?} */
  6337. const ctrl = (/** @type {?} */ (this.form.get(dir.path)));
  6338. ctrl.setValue(value);
  6339. }
  6340. /**
  6341. * \@description
  6342. * Method called with the "submit" event is triggered on the form.
  6343. * Triggers the `ngSubmit` emitter to emit the "submit" event as its payload.
  6344. *
  6345. * @param {?} $event The "submit" event object
  6346. * @return {?}
  6347. */
  6348. onSubmit($event) {
  6349. ((/** @type {?} */ (this))).submitted = true;
  6350. syncPendingControls(this.form, this.directives);
  6351. this.ngSubmit.emit($event);
  6352. return false;
  6353. }
  6354. /**
  6355. * \@description
  6356. * Method called when the "reset" event is triggered on the form.
  6357. * @return {?}
  6358. */
  6359. onReset() { this.resetForm(); }
  6360. /**
  6361. * \@description
  6362. * Resets the form to an initial value and resets its submitted status.
  6363. *
  6364. * @param {?=} value The new value for the form.
  6365. * @return {?}
  6366. */
  6367. resetForm(value = undefined) {
  6368. this.form.reset(value);
  6369. ((/** @type {?} */ (this))).submitted = false;
  6370. }
  6371. /**
  6372. * \@internal
  6373. * @return {?}
  6374. */
  6375. _updateDomValue() {
  6376. this.directives.forEach((/**
  6377. * @param {?} dir
  6378. * @return {?}
  6379. */
  6380. dir => {
  6381. /** @type {?} */
  6382. const newCtrl = this.form.get(dir.path);
  6383. if (dir.control !== newCtrl) {
  6384. cleanUpControl(dir.control, dir);
  6385. if (newCtrl)
  6386. setUpControl(newCtrl, dir);
  6387. ((/** @type {?} */ (dir))).control = newCtrl;
  6388. }
  6389. }));
  6390. this.form._updateTreeValidity({ emitEvent: false });
  6391. }
  6392. /**
  6393. * @private
  6394. * @return {?}
  6395. */
  6396. _updateRegistrations() {
  6397. this.form._registerOnCollectionChange((/**
  6398. * @return {?}
  6399. */
  6400. () => this._updateDomValue()));
  6401. if (this._oldForm)
  6402. this._oldForm._registerOnCollectionChange((/**
  6403. * @return {?}
  6404. */
  6405. () => { }));
  6406. this._oldForm = this.form;
  6407. }
  6408. /**
  6409. * @private
  6410. * @return {?}
  6411. */
  6412. _updateValidators() {
  6413. /** @type {?} */
  6414. const sync = composeValidators(this._validators);
  6415. this.form.validator = Validators.compose([(/** @type {?} */ (this.form.validator)), (/** @type {?} */ (sync))]);
  6416. /** @type {?} */
  6417. const async = composeAsyncValidators(this._asyncValidators);
  6418. this.form.asyncValidator = Validators.composeAsync([(/** @type {?} */ (this.form.asyncValidator)), (/** @type {?} */ (async))]);
  6419. }
  6420. /**
  6421. * @private
  6422. * @return {?}
  6423. */
  6424. _checkFormPresent() {
  6425. if (!this.form) {
  6426. ReactiveErrors.missingFormException();
  6427. }
  6428. }
  6429. }
  6430. FormGroupDirective.decorators = [
  6431. { type: Directive, args: [{
  6432. selector: '[formGroup]',
  6433. providers: [formDirectiveProvider$1],
  6434. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  6435. exportAs: 'ngForm'
  6436. },] }
  6437. ];
  6438. /** @nocollapse */
  6439. FormGroupDirective.ctorParameters = () => [
  6440. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  6441. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }
  6442. ];
  6443. FormGroupDirective.propDecorators = {
  6444. form: [{ type: Input, args: ['formGroup',] }],
  6445. ngSubmit: [{ type: Output }]
  6446. };
  6447. /**
  6448. * @fileoverview added by tsickle
  6449. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6450. */
  6451. /** @type {?} */
  6452. const formGroupNameProvider = {
  6453. provide: ControlContainer,
  6454. useExisting: forwardRef((/**
  6455. * @return {?}
  6456. */
  6457. () => FormGroupName))
  6458. };
  6459. /**
  6460. * \@description
  6461. *
  6462. * Syncs a nested `FormGroup` to a DOM element.
  6463. *
  6464. * This directive can only be used with a parent `FormGroupDirective`.
  6465. *
  6466. * It accepts the string name of the nested `FormGroup` to link, and
  6467. * looks for a `FormGroup` registered with that name in the parent
  6468. * `FormGroup` instance you passed into `FormGroupDirective`.
  6469. *
  6470. * Use nested form groups to validate a sub-group of a
  6471. * form separately from the rest or to group the values of certain
  6472. * controls into their own nested object.
  6473. *
  6474. * @see [Reactive Forms Guide](guide/reactive-forms)
  6475. *
  6476. * \@usageNotes
  6477. *
  6478. * ### Access the group by name
  6479. *
  6480. * The following example uses the {\@link AbstractControl#get get} method to access the
  6481. * associated `FormGroup`
  6482. *
  6483. * ```ts
  6484. * this.form.get('name');
  6485. * ```
  6486. *
  6487. * ### Access individual controls in the group
  6488. *
  6489. * The following example uses the {\@link AbstractControl#get get} method to access
  6490. * individual controls within the group using dot syntax.
  6491. *
  6492. * ```ts
  6493. * this.form.get('name.first');
  6494. * ```
  6495. *
  6496. * ### Register a nested `FormGroup`.
  6497. *
  6498. * The following example registers a nested *name* `FormGroup` within an existing `FormGroup`,
  6499. * and provides methods to retrieve the nested `FormGroup` and individual controls.
  6500. *
  6501. * {\@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
  6502. *
  6503. * \@ngModule ReactiveFormsModule
  6504. * \@publicApi
  6505. */
  6506. class FormGroupName extends AbstractFormGroupDirective {
  6507. /**
  6508. * @param {?} parent
  6509. * @param {?} validators
  6510. * @param {?} asyncValidators
  6511. */
  6512. constructor(parent, validators, asyncValidators) {
  6513. super();
  6514. this._parent = parent;
  6515. this._validators = validators;
  6516. this._asyncValidators = asyncValidators;
  6517. }
  6518. /**
  6519. * \@internal
  6520. * @return {?}
  6521. */
  6522. _checkParentType() {
  6523. if (_hasInvalidParent(this._parent)) {
  6524. ReactiveErrors.groupParentException();
  6525. }
  6526. }
  6527. }
  6528. FormGroupName.decorators = [
  6529. { type: Directive, args: [{ selector: '[formGroupName]', providers: [formGroupNameProvider] },] }
  6530. ];
  6531. /** @nocollapse */
  6532. FormGroupName.ctorParameters = () => [
  6533. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] },
  6534. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  6535. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }
  6536. ];
  6537. FormGroupName.propDecorators = {
  6538. name: [{ type: Input, args: ['formGroupName',] }]
  6539. };
  6540. /** @type {?} */
  6541. const formArrayNameProvider = {
  6542. provide: ControlContainer,
  6543. useExisting: forwardRef((/**
  6544. * @return {?}
  6545. */
  6546. () => FormArrayName))
  6547. };
  6548. /**
  6549. * \@description
  6550. *
  6551. * Syncs a nested `FormArray` to a DOM element.
  6552. *
  6553. * This directive is designed to be used with a parent `FormGroupDirective` (selector:
  6554. * `[formGroup]`).
  6555. *
  6556. * It accepts the string name of the nested `FormArray` you want to link, and
  6557. * will look for a `FormArray` registered with that name in the parent
  6558. * `FormGroup` instance you passed into `FormGroupDirective`.
  6559. *
  6560. * @see [Reactive Forms Guide](guide/reactive-forms)
  6561. * @see `AbstractControl`
  6562. *
  6563. * \@usageNotes
  6564. *
  6565. * ### Example
  6566. *
  6567. * {\@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
  6568. *
  6569. * \@ngModule ReactiveFormsModule
  6570. * \@publicApi
  6571. */
  6572. class FormArrayName extends ControlContainer {
  6573. /**
  6574. * @param {?} parent
  6575. * @param {?} validators
  6576. * @param {?} asyncValidators
  6577. */
  6578. constructor(parent, validators, asyncValidators) {
  6579. super();
  6580. this._parent = parent;
  6581. this._validators = validators;
  6582. this._asyncValidators = asyncValidators;
  6583. }
  6584. /**
  6585. * \@description
  6586. * A lifecycle method called when the directive's inputs are initialized. For internal use only.
  6587. *
  6588. * @throws If the directive does not have a valid parent.
  6589. * @return {?}
  6590. */
  6591. ngOnInit() {
  6592. this._checkParentType();
  6593. (/** @type {?} */ (this.formDirective)).addFormArray(this);
  6594. }
  6595. /**
  6596. * \@description
  6597. * A lifecycle method called before the directive's instance is destroyed. For internal use only.
  6598. * @return {?}
  6599. */
  6600. ngOnDestroy() {
  6601. if (this.formDirective) {
  6602. this.formDirective.removeFormArray(this);
  6603. }
  6604. }
  6605. /**
  6606. * \@description
  6607. * The `FormArray` bound to this directive.
  6608. * @return {?}
  6609. */
  6610. get control() { return (/** @type {?} */ (this.formDirective)).getFormArray(this); }
  6611. /**
  6612. * \@description
  6613. * The top-level directive for this group if present, otherwise null.
  6614. * @return {?}
  6615. */
  6616. get formDirective() {
  6617. return this._parent ? (/** @type {?} */ (this._parent.formDirective)) : null;
  6618. }
  6619. /**
  6620. * \@description
  6621. * Returns an array that represents the path from the top-level form to this control.
  6622. * Each index is the string name of the control on that level.
  6623. * @return {?}
  6624. */
  6625. get path() { return controlPath(this.name, this._parent); }
  6626. /**
  6627. * \@description
  6628. * Synchronous validator function composed of all the synchronous validators registered with this
  6629. * directive.
  6630. * @return {?}
  6631. */
  6632. get validator() { return composeValidators(this._validators); }
  6633. /**
  6634. * \@description
  6635. * Async validator function composed of all the async validators registered with this directive.
  6636. * @return {?}
  6637. */
  6638. get asyncValidator() {
  6639. return composeAsyncValidators(this._asyncValidators);
  6640. }
  6641. /**
  6642. * @private
  6643. * @return {?}
  6644. */
  6645. _checkParentType() {
  6646. if (_hasInvalidParent(this._parent)) {
  6647. ReactiveErrors.arrayParentException();
  6648. }
  6649. }
  6650. }
  6651. FormArrayName.decorators = [
  6652. { type: Directive, args: [{ selector: '[formArrayName]', providers: [formArrayNameProvider] },] }
  6653. ];
  6654. /** @nocollapse */
  6655. FormArrayName.ctorParameters = () => [
  6656. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] },
  6657. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  6658. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] }
  6659. ];
  6660. FormArrayName.propDecorators = {
  6661. name: [{ type: Input, args: ['formArrayName',] }]
  6662. };
  6663. /**
  6664. * @param {?} parent
  6665. * @return {?}
  6666. */
  6667. function _hasInvalidParent(parent) {
  6668. return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) &&
  6669. !(parent instanceof FormArrayName);
  6670. }
  6671. /**
  6672. * @fileoverview added by tsickle
  6673. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6674. */
  6675. /** @type {?} */
  6676. const controlNameBinding = {
  6677. provide: NgControl,
  6678. useExisting: forwardRef((/**
  6679. * @return {?}
  6680. */
  6681. () => FormControlName))
  6682. };
  6683. /**
  6684. * \@description
  6685. * Syncs a `FormControl` in an existing `FormGroup` to a form control
  6686. * element by name.
  6687. *
  6688. * @see [Reactive Forms Guide](guide/reactive-forms)
  6689. * @see `FormControl`
  6690. * @see `AbstractControl`
  6691. *
  6692. * \@usageNotes
  6693. *
  6694. * ### Register `FormControl` within a group
  6695. *
  6696. * The following example shows how to register multiple form controls within a form group
  6697. * and set their value.
  6698. *
  6699. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  6700. *
  6701. * To see `formControlName` examples with different form control types, see:
  6702. *
  6703. * * Radio buttons: `RadioControlValueAccessor`
  6704. * * Selects: `SelectControlValueAccessor`
  6705. *
  6706. * ### Use with ngModel
  6707. *
  6708. * Support for using the `ngModel` input property and `ngModelChange` event with reactive
  6709. * form directives has been deprecated in Angular v6 and will be removed in Angular v7.
  6710. *
  6711. * Now deprecated:
  6712. *
  6713. * ```html
  6714. * <form [formGroup]="form">
  6715. * <input formControlName="first" [(ngModel)]="value">
  6716. * </form>
  6717. * ```
  6718. *
  6719. * ```ts
  6720. * this.value = 'some value';
  6721. * ```
  6722. *
  6723. * This has been deprecated for a few reasons. First, developers have found this pattern
  6724. * confusing. It seems like the actual `ngModel` directive is being used, but in fact it's
  6725. * an input/output property named `ngModel` on the reactive form directive that simply
  6726. * approximates (some of) its behavior. Specifically, it allows getting/setting the value
  6727. * and intercepting value events. However, some of `ngModel`'s other features - like
  6728. * delaying updates with`ngModelOptions` or exporting the directive - simply don't work,
  6729. * which has understandably caused some confusion.
  6730. *
  6731. * In addition, this pattern mixes template-driven and reactive forms strategies, which
  6732. * we generally don't recommend because it doesn't take advantage of the full benefits of
  6733. * either strategy. Setting the value in the template violates the template-agnostic
  6734. * principles behind reactive forms, whereas adding a `FormControl`/`FormGroup` layer in
  6735. * the class removes the convenience of defining forms in the template.
  6736. *
  6737. * To update your code before v7, you'll want to decide whether to stick with reactive form
  6738. * directives (and get/set values using reactive forms patterns) or switch over to
  6739. * template-driven directives.
  6740. *
  6741. * After (choice 1 - use reactive forms):
  6742. *
  6743. * ```html
  6744. * <form [formGroup]="form">
  6745. * <input formControlName="first">
  6746. * </form>
  6747. * ```
  6748. *
  6749. * ```ts
  6750. * this.form.get('first').setValue('some value');
  6751. * ```
  6752. *
  6753. * After (choice 2 - use template-driven forms):
  6754. *
  6755. * ```html
  6756. * <input [(ngModel)]="value">
  6757. * ```
  6758. *
  6759. * ```ts
  6760. * this.value = 'some value';
  6761. * ```
  6762. *
  6763. * By default, when you use this pattern, you will see a deprecation warning once in dev
  6764. * mode. You can choose to silence this warning by providing a config for
  6765. * `ReactiveFormsModule` at import time:
  6766. *
  6767. * ```ts
  6768. * imports: [
  6769. * ReactiveFormsModule.withConfig({warnOnNgModelWithFormControl: 'never'})
  6770. * ]
  6771. * ```
  6772. *
  6773. * Alternatively, you can choose to surface a separate warning for each instance of this
  6774. * pattern with a config value of `"always"`. This may help to track down where in the code
  6775. * the pattern is being used as the code is being updated.
  6776. *
  6777. * \@ngModule ReactiveFormsModule
  6778. * \@publicApi
  6779. */
  6780. class FormControlName extends NgControl {
  6781. /**
  6782. * @param {?} parent
  6783. * @param {?} validators
  6784. * @param {?} asyncValidators
  6785. * @param {?} valueAccessors
  6786. * @param {?} _ngModelWarningConfig
  6787. */
  6788. constructor(parent, validators, asyncValidators, valueAccessors, _ngModelWarningConfig) {
  6789. super();
  6790. this._ngModelWarningConfig = _ngModelWarningConfig;
  6791. this._added = false;
  6792. /**
  6793. * @deprecated as of v6
  6794. */
  6795. this.update = new EventEmitter();
  6796. /**
  6797. * \@description
  6798. * Instance property used to track whether an ngModel warning has been sent out for this
  6799. * particular FormControlName instance. Used to support warning config of "always".
  6800. *
  6801. * \@internal
  6802. */
  6803. this._ngModelWarningSent = false;
  6804. this._parent = parent;
  6805. this._rawValidators = validators || [];
  6806. this._rawAsyncValidators = asyncValidators || [];
  6807. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  6808. }
  6809. /**
  6810. * \@description
  6811. * Triggers a warning that this input should not be used with reactive forms.
  6812. * @param {?} isDisabled
  6813. * @return {?}
  6814. */
  6815. set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); }
  6816. /**
  6817. * \@description
  6818. * A lifecycle method called when the directive's inputs change. For internal use only.
  6819. *
  6820. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  6821. * @return {?}
  6822. */
  6823. ngOnChanges(changes) {
  6824. if (!this._added)
  6825. this._setUpControl();
  6826. if (isPropertyUpdated(changes, this.viewModel)) {
  6827. _ngModelWarning('formControlName', FormControlName, this, this._ngModelWarningConfig);
  6828. this.viewModel = this.model;
  6829. this.formDirective.updateModel(this, this.model);
  6830. }
  6831. }
  6832. /**
  6833. * \@description
  6834. * Lifecycle method called before the directive's instance is destroyed. For internal use only.
  6835. * @return {?}
  6836. */
  6837. ngOnDestroy() {
  6838. if (this.formDirective) {
  6839. this.formDirective.removeControl(this);
  6840. }
  6841. }
  6842. /**
  6843. * \@description
  6844. * Sets the new value for the view model and emits an `ngModelChange` event.
  6845. *
  6846. * @param {?} newValue The new value for the view model.
  6847. * @return {?}
  6848. */
  6849. viewToModelUpdate(newValue) {
  6850. this.viewModel = newValue;
  6851. this.update.emit(newValue);
  6852. }
  6853. /**
  6854. * \@description
  6855. * Returns an array that represents the path from the top-level form to this control.
  6856. * Each index is the string name of the control on that level.
  6857. * @return {?}
  6858. */
  6859. get path() { return controlPath(this.name, (/** @type {?} */ (this._parent))); }
  6860. /**
  6861. * \@description
  6862. * The top-level directive for this group if present, otherwise null.
  6863. * @return {?}
  6864. */
  6865. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  6866. /**
  6867. * \@description
  6868. * Synchronous validator function composed of all the synchronous validators
  6869. * registered with this directive.
  6870. * @return {?}
  6871. */
  6872. get validator() { return composeValidators(this._rawValidators); }
  6873. /**
  6874. * \@description
  6875. * Async validator function composed of all the async validators registered with this
  6876. * directive.
  6877. * @return {?}
  6878. */
  6879. get asyncValidator() {
  6880. return (/** @type {?} */ (composeAsyncValidators(this._rawAsyncValidators)));
  6881. }
  6882. /**
  6883. * @private
  6884. * @return {?}
  6885. */
  6886. _checkParentType() {
  6887. if (!(this._parent instanceof FormGroupName) &&
  6888. this._parent instanceof AbstractFormGroupDirective) {
  6889. ReactiveErrors.ngModelGroupException();
  6890. }
  6891. else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) &&
  6892. !(this._parent instanceof FormArrayName)) {
  6893. ReactiveErrors.controlParentException();
  6894. }
  6895. }
  6896. /**
  6897. * @private
  6898. * @return {?}
  6899. */
  6900. _setUpControl() {
  6901. this._checkParentType();
  6902. ((/** @type {?} */ (this))).control = this.formDirective.addControl(this);
  6903. if (this.control.disabled && (/** @type {?} */ (this.valueAccessor)).setDisabledState) {
  6904. (/** @type {?} */ ((/** @type {?} */ (this.valueAccessor)).setDisabledState))(true);
  6905. }
  6906. this._added = true;
  6907. }
  6908. }
  6909. /**
  6910. * \@description
  6911. * Static property used to track whether any ngModel warnings have been sent across
  6912. * all instances of FormControlName. Used to support warning config of "once".
  6913. *
  6914. * \@internal
  6915. */
  6916. FormControlName._ngModelWarningSentOnce = false;
  6917. FormControlName.decorators = [
  6918. { type: Directive, args: [{ selector: '[formControlName]', providers: [controlNameBinding] },] }
  6919. ];
  6920. /** @nocollapse */
  6921. FormControlName.ctorParameters = () => [
  6922. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf }] },
  6923. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] }] },
  6924. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] }] },
  6925. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] }] },
  6926. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [NG_MODEL_WITH_FORM_CONTROL_WARNING,] }] }
  6927. ];
  6928. FormControlName.propDecorators = {
  6929. name: [{ type: Input, args: ['formControlName',] }],
  6930. isDisabled: [{ type: Input, args: ['disabled',] }],
  6931. model: [{ type: Input, args: ['ngModel',] }],
  6932. update: [{ type: Output, args: ['ngModelChange',] }]
  6933. };
  6934. /**
  6935. * @fileoverview added by tsickle
  6936. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  6937. */
  6938. /**
  6939. * \@description
  6940. * Provider which adds `RequiredValidator` to the `NG_VALIDATORS` multi-provider list.
  6941. * @type {?}
  6942. */
  6943. const REQUIRED_VALIDATOR = {
  6944. provide: NG_VALIDATORS,
  6945. useExisting: forwardRef((/**
  6946. * @return {?}
  6947. */
  6948. () => RequiredValidator)),
  6949. multi: true
  6950. };
  6951. /**
  6952. * \@description
  6953. * Provider which adds `CheckboxRequiredValidator` to the `NG_VALIDATORS` multi-provider list.
  6954. * @type {?}
  6955. */
  6956. const CHECKBOX_REQUIRED_VALIDATOR = {
  6957. provide: NG_VALIDATORS,
  6958. useExisting: forwardRef((/**
  6959. * @return {?}
  6960. */
  6961. () => CheckboxRequiredValidator)),
  6962. multi: true
  6963. };
  6964. /**
  6965. * \@description
  6966. * A directive that adds the `required` validator to any controls marked with the
  6967. * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
  6968. *
  6969. * @see [Form Validation](guide/form-validation)
  6970. *
  6971. * \@usageNotes
  6972. *
  6973. * ### Adding a required validator using template-driven forms
  6974. *
  6975. * ```
  6976. * <input name="fullName" ngModel required>
  6977. * ```
  6978. *
  6979. * \@ngModule FormsModule
  6980. * \@ngModule ReactiveFormsModule
  6981. * \@publicApi
  6982. */
  6983. class RequiredValidator {
  6984. /**
  6985. * \@description
  6986. * Tracks changes to the required attribute bound to this directive.
  6987. * @return {?}
  6988. */
  6989. get required() { return this._required; }
  6990. /**
  6991. * @param {?} value
  6992. * @return {?}
  6993. */
  6994. set required(value) {
  6995. this._required = value != null && value !== false && `${value}` !== 'false';
  6996. if (this._onChange)
  6997. this._onChange();
  6998. }
  6999. /**
  7000. * \@description
  7001. * Method that validates whether the control is empty.
  7002. * Returns the validation result if enabled, otherwise null.
  7003. * @param {?} control
  7004. * @return {?}
  7005. */
  7006. validate(control) {
  7007. return this.required ? Validators.required(control) : null;
  7008. }
  7009. /**
  7010. * \@description
  7011. * Registers a callback function to call when the validator inputs change.
  7012. *
  7013. * @param {?} fn The callback function
  7014. * @return {?}
  7015. */
  7016. registerOnValidatorChange(fn) { this._onChange = fn; }
  7017. }
  7018. RequiredValidator.decorators = [
  7019. { type: Directive, args: [{
  7020. selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
  7021. providers: [REQUIRED_VALIDATOR],
  7022. host: { '[attr.required]': 'required ? "" : null' }
  7023. },] }
  7024. ];
  7025. RequiredValidator.propDecorators = {
  7026. required: [{ type: Input }]
  7027. };
  7028. /**
  7029. * A Directive that adds the `required` validator to checkbox controls marked with the
  7030. * `required` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
  7031. *
  7032. * @see [Form Validation](guide/form-validation)
  7033. *
  7034. * \@usageNotes
  7035. *
  7036. * ### Adding a required checkbox validator using template-driven forms
  7037. *
  7038. * The following example shows how to add a checkbox required validator to an input attached to an ngModel binding.
  7039. *
  7040. * ```
  7041. * <input type="checkbox" name="active" ngModel required>
  7042. * ```
  7043. *
  7044. * \@publicApi
  7045. * \@ngModule FormsModule
  7046. * \@ngModule ReactiveFormsModule
  7047. */
  7048. class CheckboxRequiredValidator extends RequiredValidator {
  7049. /**
  7050. * \@description
  7051. * Method that validates whether or not the checkbox has been checked.
  7052. * Returns the validation result if enabled, otherwise null.
  7053. * @param {?} control
  7054. * @return {?}
  7055. */
  7056. validate(control) {
  7057. return this.required ? Validators.requiredTrue(control) : null;
  7058. }
  7059. }
  7060. CheckboxRequiredValidator.decorators = [
  7061. { type: Directive, args: [{
  7062. selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
  7063. providers: [CHECKBOX_REQUIRED_VALIDATOR],
  7064. host: { '[attr.required]': 'required ? "" : null' }
  7065. },] }
  7066. ];
  7067. /**
  7068. * \@description
  7069. * Provider which adds `EmailValidator` to the `NG_VALIDATORS` multi-provider list.
  7070. * @type {?}
  7071. */
  7072. const EMAIL_VALIDATOR = {
  7073. provide: NG_VALIDATORS,
  7074. useExisting: forwardRef((/**
  7075. * @return {?}
  7076. */
  7077. () => EmailValidator)),
  7078. multi: true
  7079. };
  7080. /**
  7081. * A directive that adds the `email` validator to controls marked with the
  7082. * `email` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
  7083. *
  7084. * @see [Form Validation](guide/form-validation)
  7085. *
  7086. * \@usageNotes
  7087. *
  7088. * ### Adding an email validator
  7089. *
  7090. * The following example shows how to add an email validator to an input attached to an ngModel binding.
  7091. *
  7092. * ```
  7093. * <input type="email" name="email" ngModel email>
  7094. * <input type="email" name="email" ngModel email="true">
  7095. * <input type="email" name="email" ngModel [email]="true">
  7096. * ```
  7097. *
  7098. * \@publicApi
  7099. * \@ngModule FormsModule
  7100. * \@ngModule ReactiveFormsModule
  7101. */
  7102. class EmailValidator {
  7103. /**
  7104. * \@description
  7105. * Tracks changes to the email attribute bound to this directive.
  7106. * @param {?} value
  7107. * @return {?}
  7108. */
  7109. set email(value) {
  7110. this._enabled = value === '' || value === true || value === 'true';
  7111. if (this._onChange)
  7112. this._onChange();
  7113. }
  7114. /**
  7115. * \@description
  7116. * Method that validates whether an email address is valid.
  7117. * Returns the validation result if enabled, otherwise null.
  7118. * @param {?} control
  7119. * @return {?}
  7120. */
  7121. validate(control) {
  7122. return this._enabled ? Validators.email(control) : null;
  7123. }
  7124. /**
  7125. * \@description
  7126. * Registers a callback function to call when the validator inputs change.
  7127. *
  7128. * @param {?} fn The callback function
  7129. * @return {?}
  7130. */
  7131. registerOnValidatorChange(fn) { this._onChange = fn; }
  7132. }
  7133. EmailValidator.decorators = [
  7134. { type: Directive, args: [{
  7135. selector: '[email][formControlName],[email][formControl],[email][ngModel]',
  7136. providers: [EMAIL_VALIDATOR]
  7137. },] }
  7138. ];
  7139. EmailValidator.propDecorators = {
  7140. email: [{ type: Input }]
  7141. };
  7142. /**
  7143. * \@description
  7144. * Provider which adds `MinLengthValidator` to the `NG_VALIDATORS` multi-provider list.
  7145. * @type {?}
  7146. */
  7147. const MIN_LENGTH_VALIDATOR = {
  7148. provide: NG_VALIDATORS,
  7149. useExisting: forwardRef((/**
  7150. * @return {?}
  7151. */
  7152. () => MinLengthValidator)),
  7153. multi: true
  7154. };
  7155. /**
  7156. * A directive that adds minimum length validation to controls marked with the
  7157. * `minlength` attribute. The directive is provided with the `NG_VALIDATORS` mult-provider list.
  7158. *
  7159. * @see [Form Validation](guide/form-validation)
  7160. *
  7161. * \@usageNotes
  7162. *
  7163. * ### Adding a minimum length validator
  7164. *
  7165. * The following example shows how to add a minimum length validator to an input attached to an
  7166. * ngModel binding.
  7167. *
  7168. * ```html
  7169. * <input name="firstName" ngModel minlength="4">
  7170. * ```
  7171. *
  7172. * \@ngModule ReactiveFormsModule
  7173. * \@ngModule FormsModule
  7174. * \@publicApi
  7175. */
  7176. class MinLengthValidator {
  7177. /**
  7178. * \@description
  7179. * A lifecycle method called when the directive's inputs change. For internal use
  7180. * only.
  7181. *
  7182. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  7183. * @return {?}
  7184. */
  7185. ngOnChanges(changes) {
  7186. if ('minlength' in changes) {
  7187. this._createValidator();
  7188. if (this._onChange)
  7189. this._onChange();
  7190. }
  7191. }
  7192. /**
  7193. * \@description
  7194. * Method that validates whether the value meets a minimum length
  7195. * requirement. Returns the validation result if enabled, otherwise null.
  7196. * @param {?} control
  7197. * @return {?}
  7198. */
  7199. validate(control) {
  7200. return this.minlength == null ? null : this._validator(control);
  7201. }
  7202. /**
  7203. * \@description
  7204. * Registers a callback function to call when the validator inputs change.
  7205. *
  7206. * @param {?} fn The callback function
  7207. * @return {?}
  7208. */
  7209. registerOnValidatorChange(fn) { this._onChange = fn; }
  7210. /**
  7211. * @private
  7212. * @return {?}
  7213. */
  7214. _createValidator() {
  7215. this._validator = Validators.minLength(parseInt(this.minlength, 10));
  7216. }
  7217. }
  7218. MinLengthValidator.decorators = [
  7219. { type: Directive, args: [{
  7220. selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
  7221. providers: [MIN_LENGTH_VALIDATOR],
  7222. host: { '[attr.minlength]': 'minlength ? minlength : null' }
  7223. },] }
  7224. ];
  7225. MinLengthValidator.propDecorators = {
  7226. minlength: [{ type: Input }]
  7227. };
  7228. /**
  7229. * \@description
  7230. * Provider which adds `MaxLengthValidator` to the `NG_VALIDATORS` multi-provider list.
  7231. * @type {?}
  7232. */
  7233. const MAX_LENGTH_VALIDATOR = {
  7234. provide: NG_VALIDATORS,
  7235. useExisting: forwardRef((/**
  7236. * @return {?}
  7237. */
  7238. () => MaxLengthValidator)),
  7239. multi: true
  7240. };
  7241. /**
  7242. * A directive that adds max length validation to controls marked with the
  7243. * `maxlength` attribute. The directive is provided with the `NG_VALIDATORS` multi-provider list.
  7244. *
  7245. * @see [Form Validation](guide/form-validation)
  7246. *
  7247. * \@usageNotes
  7248. *
  7249. * ### Adding a maximum length validator
  7250. *
  7251. * The following example shows how to add a maximum length validator to an input attached to an
  7252. * ngModel binding.
  7253. *
  7254. * ```html
  7255. * <input name="firstName" ngModel maxlength="25">
  7256. * ```
  7257. *
  7258. * \@ngModule ReactiveFormsModule
  7259. * \@ngModule FormsModule
  7260. * \@publicApi
  7261. */
  7262. class MaxLengthValidator {
  7263. /**
  7264. * \@description
  7265. * A lifecycle method called when the directive's inputs change. For internal use
  7266. * only.
  7267. *
  7268. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  7269. * @return {?}
  7270. */
  7271. ngOnChanges(changes) {
  7272. if ('maxlength' in changes) {
  7273. this._createValidator();
  7274. if (this._onChange)
  7275. this._onChange();
  7276. }
  7277. }
  7278. /**
  7279. * \@description
  7280. * Method that validates whether the value exceeds
  7281. * the maximum length requirement.
  7282. * @param {?} control
  7283. * @return {?}
  7284. */
  7285. validate(control) {
  7286. return this.maxlength != null ? this._validator(control) : null;
  7287. }
  7288. /**
  7289. * \@description
  7290. * Registers a callback function to call when the validator inputs change.
  7291. *
  7292. * @param {?} fn The callback function
  7293. * @return {?}
  7294. */
  7295. registerOnValidatorChange(fn) { this._onChange = fn; }
  7296. /**
  7297. * @private
  7298. * @return {?}
  7299. */
  7300. _createValidator() {
  7301. this._validator = Validators.maxLength(parseInt(this.maxlength, 10));
  7302. }
  7303. }
  7304. MaxLengthValidator.decorators = [
  7305. { type: Directive, args: [{
  7306. selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
  7307. providers: [MAX_LENGTH_VALIDATOR],
  7308. host: { '[attr.maxlength]': 'maxlength ? maxlength : null' }
  7309. },] }
  7310. ];
  7311. MaxLengthValidator.propDecorators = {
  7312. maxlength: [{ type: Input }]
  7313. };
  7314. /**
  7315. * \@description
  7316. * Provider which adds `PatternValidator` to the `NG_VALIDATORS` multi-provider list.
  7317. * @type {?}
  7318. */
  7319. const PATTERN_VALIDATOR = {
  7320. provide: NG_VALIDATORS,
  7321. useExisting: forwardRef((/**
  7322. * @return {?}
  7323. */
  7324. () => PatternValidator)),
  7325. multi: true
  7326. };
  7327. /**
  7328. * \@description
  7329. * A directive that adds regex pattern validation to controls marked with the
  7330. * `pattern` attribute. The regex must match the entire control value.
  7331. * The directive is provided with the `NG_VALIDATORS` multi-provider list.
  7332. *
  7333. * @see [Form Validation](guide/form-validation)
  7334. *
  7335. * \@usageNotes
  7336. *
  7337. * ### Adding a pattern validator
  7338. *
  7339. * The following example shows how to add a pattern validator to an input attached to an
  7340. * ngModel binding.
  7341. *
  7342. * ```html
  7343. * <input name="firstName" ngModel pattern="[a-zA-Z ]*">
  7344. * ```
  7345. *
  7346. * \@ngModule ReactiveFormsModule
  7347. * \@ngModule FormsModule
  7348. * \@publicApi
  7349. */
  7350. class PatternValidator {
  7351. /**
  7352. * \@description
  7353. * A lifecycle method called when the directive's inputs change. For internal use
  7354. * only.
  7355. *
  7356. * @param {?} changes A object of key/value pairs for the set of changed inputs.
  7357. * @return {?}
  7358. */
  7359. ngOnChanges(changes) {
  7360. if ('pattern' in changes) {
  7361. this._createValidator();
  7362. if (this._onChange)
  7363. this._onChange();
  7364. }
  7365. }
  7366. /**
  7367. * \@description
  7368. * Method that validates whether the value matches the
  7369. * the pattern requirement.
  7370. * @param {?} control
  7371. * @return {?}
  7372. */
  7373. validate(control) { return this._validator(control); }
  7374. /**
  7375. * \@description
  7376. * Registers a callback function to call when the validator inputs change.
  7377. *
  7378. * @param {?} fn The callback function
  7379. * @return {?}
  7380. */
  7381. registerOnValidatorChange(fn) { this._onChange = fn; }
  7382. /**
  7383. * @private
  7384. * @return {?}
  7385. */
  7386. _createValidator() { this._validator = Validators.pattern(this.pattern); }
  7387. }
  7388. PatternValidator.decorators = [
  7389. { type: Directive, args: [{
  7390. selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
  7391. providers: [PATTERN_VALIDATOR],
  7392. host: { '[attr.pattern]': 'pattern ? pattern : null' }
  7393. },] }
  7394. ];
  7395. PatternValidator.propDecorators = {
  7396. pattern: [{ type: Input }]
  7397. };
  7398. /**
  7399. * @fileoverview added by tsickle
  7400. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7401. */
  7402. /** @type {?} */
  7403. const SHARED_FORM_DIRECTIVES = [
  7404. ɵNgNoValidate,
  7405. NgSelectOption,
  7406. ɵNgSelectMultipleOption,
  7407. DefaultValueAccessor,
  7408. NumberValueAccessor,
  7409. RangeValueAccessor,
  7410. CheckboxControlValueAccessor,
  7411. SelectControlValueAccessor,
  7412. SelectMultipleControlValueAccessor,
  7413. RadioControlValueAccessor,
  7414. NgControlStatus,
  7415. NgControlStatusGroup,
  7416. RequiredValidator,
  7417. MinLengthValidator,
  7418. MaxLengthValidator,
  7419. PatternValidator,
  7420. CheckboxRequiredValidator,
  7421. EmailValidator,
  7422. ];
  7423. /** @type {?} */
  7424. const TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm, NgFormSelectorWarning];
  7425. /** @type {?} */
  7426. const REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
  7427. /**
  7428. * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
  7429. */
  7430. class ɵInternalFormsSharedModule {
  7431. }
  7432. ɵInternalFormsSharedModule.decorators = [
  7433. { type: NgModule, args: [{
  7434. declarations: SHARED_FORM_DIRECTIVES,
  7435. exports: SHARED_FORM_DIRECTIVES,
  7436. },] }
  7437. ];
  7438. /**
  7439. * @fileoverview added by tsickle
  7440. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7441. */
  7442. /**
  7443. * @param {?} options
  7444. * @return {?}
  7445. */
  7446. function isAbstractControlOptions(options) {
  7447. return ((/** @type {?} */ (options))).asyncValidators !== undefined ||
  7448. ((/** @type {?} */ (options))).validators !== undefined ||
  7449. ((/** @type {?} */ (options))).updateOn !== undefined;
  7450. }
  7451. /**
  7452. * \@description
  7453. * Creates an `AbstractControl` from a user-specified configuration.
  7454. *
  7455. * The `FormBuilder` provides syntactic sugar that shortens creating instances of a `FormControl`,
  7456. * `FormGroup`, or `FormArray`. It reduces the amount of boilerplate needed to build complex
  7457. * forms.
  7458. *
  7459. * @see [Reactive Forms Guide](/guide/reactive-forms)
  7460. *
  7461. * \@publicApi
  7462. */
  7463. class FormBuilder {
  7464. /**
  7465. * \@description
  7466. * Construct a new `FormGroup` instance.
  7467. *
  7468. * @param {?} controlsConfig A collection of child controls. The key for each child is the name
  7469. * under which it is registered.
  7470. *
  7471. * @param {?=} options Configuration options object for the `FormGroup`. The object can
  7472. * have two shapes:
  7473. *
  7474. * 1) `AbstractControlOptions` object (preferred), which consists of:
  7475. * * `validators`: A synchronous validator function, or an array of validator functions
  7476. * * `asyncValidators`: A single async validator or array of async validator functions
  7477. * * `updateOn`: The event upon which the control should be updated (options: 'change' | 'blur' |
  7478. * submit')
  7479. *
  7480. * 2) Legacy configuration object, which consists of:
  7481. * * `validator`: A synchronous validator function, or an array of validator functions
  7482. * * `asyncValidator`: A single async validator or array of async validator functions
  7483. *
  7484. * @return {?}
  7485. */
  7486. group(controlsConfig, options = null) {
  7487. /** @type {?} */
  7488. const controls = this._reduceControls(controlsConfig);
  7489. /** @type {?} */
  7490. let validators = null;
  7491. /** @type {?} */
  7492. let asyncValidators = null;
  7493. /** @type {?} */
  7494. let updateOn = undefined;
  7495. if (options != null) {
  7496. if (isAbstractControlOptions(options)) {
  7497. // `options` are `AbstractControlOptions`
  7498. validators = options.validators != null ? options.validators : null;
  7499. asyncValidators = options.asyncValidators != null ? options.asyncValidators : null;
  7500. updateOn = options.updateOn != null ? options.updateOn : undefined;
  7501. }
  7502. else {
  7503. // `options` are legacy form group options
  7504. validators = options['validator'] != null ? options['validator'] : null;
  7505. asyncValidators = options['asyncValidator'] != null ? options['asyncValidator'] : null;
  7506. }
  7507. }
  7508. return new FormGroup(controls, { asyncValidators, updateOn, validators });
  7509. }
  7510. /**
  7511. * \@description
  7512. * Construct a new `FormControl` with the given state, validators and options.
  7513. *
  7514. * \@usageNotes
  7515. *
  7516. * ### Initialize a control as disabled
  7517. *
  7518. * The following example returns a control with an initial value in a disabled state.
  7519. *
  7520. * <code-example path="forms/ts/formBuilder/form_builder_example.ts"
  7521. * linenums="false" region="disabled-control">
  7522. * </code-example>
  7523. * @param {?} formState Initializes the control with an initial state value, or
  7524. * with an object that contains both a value and a disabled status.
  7525. *
  7526. * @param {?=} validatorOrOpts A synchronous validator function, or an array of
  7527. * such functions, or an `AbstractControlOptions` object that contains
  7528. * validation functions and a validation trigger.
  7529. *
  7530. * @param {?=} asyncValidator A single async validator or array of async validator
  7531. * functions.
  7532. *
  7533. * @return {?}
  7534. */
  7535. control(formState, validatorOrOpts, asyncValidator) {
  7536. return new FormControl(formState, validatorOrOpts, asyncValidator);
  7537. }
  7538. /**
  7539. * Constructs a new `FormArray` from the given array of configurations,
  7540. * validators and options.
  7541. *
  7542. * @param {?} controlsConfig An array of child controls or control configs. Each
  7543. * child control is given an index when it is registered.
  7544. *
  7545. * @param {?=} validatorOrOpts A synchronous validator function, or an array of
  7546. * such functions, or an `AbstractControlOptions` object that contains
  7547. * validation functions and a validation trigger.
  7548. *
  7549. * @param {?=} asyncValidator A single async validator or array of async validator
  7550. * functions.
  7551. * @return {?}
  7552. */
  7553. array(controlsConfig, validatorOrOpts, asyncValidator) {
  7554. /** @type {?} */
  7555. const controls = controlsConfig.map((/**
  7556. * @param {?} c
  7557. * @return {?}
  7558. */
  7559. c => this._createControl(c)));
  7560. return new FormArray(controls, validatorOrOpts, asyncValidator);
  7561. }
  7562. /**
  7563. * \@internal
  7564. * @param {?} controlsConfig
  7565. * @return {?}
  7566. */
  7567. _reduceControls(controlsConfig) {
  7568. /** @type {?} */
  7569. const controls = {};
  7570. Object.keys(controlsConfig).forEach((/**
  7571. * @param {?} controlName
  7572. * @return {?}
  7573. */
  7574. controlName => {
  7575. controls[controlName] = this._createControl(controlsConfig[controlName]);
  7576. }));
  7577. return controls;
  7578. }
  7579. /**
  7580. * \@internal
  7581. * @param {?} controlConfig
  7582. * @return {?}
  7583. */
  7584. _createControl(controlConfig) {
  7585. if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup ||
  7586. controlConfig instanceof FormArray) {
  7587. return controlConfig;
  7588. }
  7589. else if (Array.isArray(controlConfig)) {
  7590. /** @type {?} */
  7591. const value = controlConfig[0];
  7592. /** @type {?} */
  7593. const validator = controlConfig.length > 1 ? controlConfig[1] : null;
  7594. /** @type {?} */
  7595. const asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null;
  7596. return this.control(value, validator, asyncValidator);
  7597. }
  7598. else {
  7599. return this.control(controlConfig);
  7600. }
  7601. }
  7602. }
  7603. FormBuilder.decorators = [
  7604. { type: Injectable }
  7605. ];
  7606. /**
  7607. * @fileoverview added by tsickle
  7608. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7609. */
  7610. /**
  7611. * \@publicApi
  7612. * @type {?}
  7613. */
  7614. const VERSION = new Version('8.1.0');
  7615. /**
  7616. * @fileoverview added by tsickle
  7617. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7618. */
  7619. /**
  7620. * Exports the required providers and directives for template-driven forms,
  7621. * making them available for import by NgModules that import this module.
  7622. *
  7623. * @see [Forms Guide](/guide/forms)
  7624. *
  7625. * \@publicApi
  7626. */
  7627. class FormsModule {
  7628. /**
  7629. * \@description
  7630. * Provides options for configuring the template-driven forms module.
  7631. *
  7632. * @param {?} opts An object of configuration options
  7633. * * `warnOnDeprecatedNgFormSelector` Configures when to emit a warning when the deprecated
  7634. * `ngForm` selector is used.
  7635. * @return {?}
  7636. */
  7637. static withConfig(opts) {
  7638. return {
  7639. ngModule: FormsModule,
  7640. providers: [{ provide: NG_FORM_SELECTOR_WARNING, useValue: opts.warnOnDeprecatedNgFormSelector }]
  7641. };
  7642. }
  7643. }
  7644. FormsModule.decorators = [
  7645. { type: NgModule, args: [{
  7646. declarations: TEMPLATE_DRIVEN_DIRECTIVES,
  7647. providers: [RadioControlRegistry],
  7648. exports: [ɵInternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
  7649. },] }
  7650. ];
  7651. /**
  7652. * Exports the required infrastructure and directives for reactive forms,
  7653. * making them available for import by NgModules that import this module.
  7654. * @see [Forms](guide/reactive-forms)
  7655. *
  7656. * @see [Reactive Forms Guide](/guide/reactive-forms)
  7657. *
  7658. * \@publicApi
  7659. */
  7660. class ReactiveFormsModule {
  7661. /**
  7662. * \@description
  7663. * Provides options for configuring the reactive forms module.
  7664. *
  7665. * @param {?} opts An object of configuration options
  7666. * * `warnOnNgModelWithFormControl` Configures when to emit a warning when an `ngModel`
  7667. * binding is used with reactive form directives.
  7668. * @return {?}
  7669. */
  7670. static withConfig(opts) {
  7671. return {
  7672. ngModule: ReactiveFormsModule,
  7673. providers: [{
  7674. provide: NG_MODEL_WITH_FORM_CONTROL_WARNING,
  7675. useValue: opts.warnOnNgModelWithFormControl
  7676. }]
  7677. };
  7678. }
  7679. }
  7680. ReactiveFormsModule.decorators = [
  7681. { type: NgModule, args: [{
  7682. declarations: [REACTIVE_DRIVEN_DIRECTIVES],
  7683. providers: [FormBuilder, RadioControlRegistry],
  7684. exports: [ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
  7685. },] }
  7686. ];
  7687. /**
  7688. * @fileoverview added by tsickle
  7689. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7690. */
  7691. /**
  7692. * @fileoverview added by tsickle
  7693. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7694. */
  7695. /**
  7696. * @fileoverview added by tsickle
  7697. * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
  7698. */
  7699. /**
  7700. * Generated bundle index. Do not edit.
  7701. */
  7702. export { ɵInternalFormsSharedModule as ɵangular_packages_forms_forms_d, ɵInternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES as ɵangular_packages_forms_forms_c, SHARED_FORM_DIRECTIVES as ɵangular_packages_forms_forms_a, TEMPLATE_DRIVEN_DIRECTIVES as ɵangular_packages_forms_forms_b, CHECKBOX_VALUE_ACCESSOR as ɵangular_packages_forms_forms_e, DEFAULT_VALUE_ACCESSOR as ɵangular_packages_forms_forms_f, AbstractControlStatus as ɵangular_packages_forms_forms_g, ngControlStatusHost as ɵangular_packages_forms_forms_h, formDirectiveProvider as ɵangular_packages_forms_forms_i, NG_FORM_SELECTOR_WARNING as ɵangular_packages_forms_forms_j, formControlBinding as ɵangular_packages_forms_forms_k, modelGroupProvider as ɵangular_packages_forms_forms_l, ɵNgNoValidate as ɵangular_packages_forms_forms_z, ɵNgNoValidate, NUMBER_VALUE_ACCESSOR as ɵangular_packages_forms_forms_m, RADIO_VALUE_ACCESSOR as ɵangular_packages_forms_forms_n, RadioControlRegistry as ɵangular_packages_forms_forms_o, RANGE_VALUE_ACCESSOR as ɵangular_packages_forms_forms_p, NG_MODEL_WITH_FORM_CONTROL_WARNING as ɵangular_packages_forms_forms_q, formControlBinding$1 as ɵangular_packages_forms_forms_r, controlNameBinding as ɵangular_packages_forms_forms_s, formDirectiveProvider$1 as ɵangular_packages_forms_forms_t, formArrayNameProvider as ɵangular_packages_forms_forms_v, formGroupNameProvider as ɵangular_packages_forms_forms_u, SELECT_VALUE_ACCESSOR as ɵangular_packages_forms_forms_w, ɵNgSelectMultipleOption as ɵangular_packages_forms_forms_y, ɵNgSelectMultipleOption, SELECT_MULTIPLE_VALUE_ACCESSOR as ɵangular_packages_forms_forms_x, CHECKBOX_REQUIRED_VALIDATOR as ɵangular_packages_forms_forms_bb, EMAIL_VALIDATOR as ɵangular_packages_forms_forms_bc, MAX_LENGTH_VALIDATOR as ɵangular_packages_forms_forms_be, MIN_LENGTH_VALIDATOR as ɵangular_packages_forms_forms_bd, PATTERN_VALIDATOR as ɵangular_packages_forms_forms_bf, REQUIRED_VALIDATOR as ɵangular_packages_forms_forms_ba, AbstractControlDirective, AbstractFormGroupDirective, CheckboxControlValueAccessor, ControlContainer, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE, DefaultValueAccessor, NgControl, NgControlStatus, NgControlStatusGroup, NgForm, NgFormSelectorWarning, NgModel, NgModelGroup, NumberValueAccessor, RadioControlValueAccessor, RangeValueAccessor, FormControlDirective, FormControlName, FormGroupDirective, FormArrayName, FormGroupName, NgSelectOption, SelectControlValueAccessor, SelectMultipleControlValueAccessor, CheckboxRequiredValidator, EmailValidator, MaxLengthValidator, MinLengthValidator, PatternValidator, RequiredValidator, FormBuilder, AbstractControl, FormArray, FormControl, FormGroup, NG_ASYNC_VALIDATORS, NG_VALIDATORS, Validators, VERSION, FormsModule, ReactiveFormsModule };
  7703. //# sourceMappingURL=forms.js.map