UI for Zipcoin Blue

forms.js 182KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996
  1. /**
  2. * @license Angular v5.2.11
  3. * (c) 2010-2018 Google, Inc. https://angular.io/
  4. * License: MIT
  5. */
  6. import { Directive, ElementRef, EventEmitter, Host, Inject, Injectable, InjectionToken, Injector, Input, NgModule, Optional, Output, Renderer2, Self, SkipSelf, Version, forwardRef, ɵisObservable, ɵisPromise, ɵlooseIdentical } from '@angular/core';
  7. import { forkJoin } from 'rxjs/observable/forkJoin';
  8. import { fromPromise } from 'rxjs/observable/fromPromise';
  9. import { map } from 'rxjs/operator/map';
  10. import { ɵgetDOM } from '@angular/platform-browser';
  11. /**
  12. * @fileoverview added by tsickle
  13. * @suppress {checkTypes} checked by tsc
  14. */
  15. /**
  16. * @license
  17. * Copyright Google Inc. All Rights Reserved.
  18. *
  19. * Use of this source code is governed by an MIT-style license that can be
  20. * found in the LICENSE file at https://angular.io/license
  21. */
  22. /**
  23. * Base class for control directives.
  24. *
  25. * Only used internally in the forms module.
  26. *
  27. * \@stable
  28. * @abstract
  29. */
  30. class AbstractControlDirective {
  31. /**
  32. * The value of the control.
  33. * @return {?}
  34. */
  35. get value() { return this.control ? this.control.value : null; }
  36. /**
  37. * A control is `valid` when its `status === VALID`.
  38. *
  39. * In order to have this status, the control must have passed all its
  40. * validation checks.
  41. * @return {?}
  42. */
  43. get valid() { return this.control ? this.control.valid : null; }
  44. /**
  45. * A control is `invalid` when its `status === INVALID`.
  46. *
  47. * In order to have this status, the control must have failed
  48. * at least one of its validation checks.
  49. * @return {?}
  50. */
  51. get invalid() { return this.control ? this.control.invalid : null; }
  52. /**
  53. * A control is `pending` when its `status === PENDING`.
  54. *
  55. * In order to have this status, the control must be in the
  56. * middle of conducting a validation check.
  57. * @return {?}
  58. */
  59. get pending() { return this.control ? this.control.pending : null; }
  60. /**
  61. * A control is `disabled` when its `status === DISABLED`.
  62. *
  63. * Disabled controls are exempt from validation checks and
  64. * are not included in the aggregate value of their ancestor
  65. * controls.
  66. * @return {?}
  67. */
  68. get disabled() { return this.control ? this.control.disabled : null; }
  69. /**
  70. * A control is `enabled` as long as its `status !== DISABLED`.
  71. *
  72. * In other words, it has a status of `VALID`, `INVALID`, or
  73. * `PENDING`.
  74. * @return {?}
  75. */
  76. get enabled() { return this.control ? this.control.enabled : null; }
  77. /**
  78. * Returns any errors generated by failing validation. If there
  79. * are no errors, it will return null.
  80. * @return {?}
  81. */
  82. get errors() { return this.control ? this.control.errors : null; }
  83. /**
  84. * A control is `pristine` if the user has not yet changed
  85. * the value in the UI.
  86. *
  87. * Note that programmatic changes to a control's value will
  88. * *not* mark it dirty.
  89. * @return {?}
  90. */
  91. get pristine() { return this.control ? this.control.pristine : null; }
  92. /**
  93. * A control is `dirty` if the user has changed the value
  94. * in the UI.
  95. *
  96. * Note that programmatic changes to a control's value will
  97. * *not* mark it dirty.
  98. * @return {?}
  99. */
  100. get dirty() { return this.control ? this.control.dirty : null; }
  101. /**
  102. * A control is marked `touched` once the user has triggered
  103. * a `blur` event on it.
  104. * @return {?}
  105. */
  106. get touched() { return this.control ? this.control.touched : null; }
  107. /**
  108. * @return {?}
  109. */
  110. get status() { return this.control ? this.control.status : null; }
  111. /**
  112. * A control is `untouched` if the user has not yet triggered
  113. * a `blur` event on it.
  114. * @return {?}
  115. */
  116. get untouched() { return this.control ? this.control.untouched : null; }
  117. /**
  118. * Emits an event every time the validation status of the control
  119. * is re-calculated.
  120. * @return {?}
  121. */
  122. get statusChanges() {
  123. return this.control ? this.control.statusChanges : null;
  124. }
  125. /**
  126. * Emits an event every time the value of the control changes, in
  127. * the UI or programmatically.
  128. * @return {?}
  129. */
  130. get valueChanges() {
  131. return this.control ? this.control.valueChanges : null;
  132. }
  133. /**
  134. * Returns an array that represents the path from the top-level form
  135. * to this control. Each index is the string name of the control on
  136. * that level.
  137. * @return {?}
  138. */
  139. get path() { return null; }
  140. /**
  141. * Resets the form control. This means by default:
  142. *
  143. * * it is marked as `pristine`
  144. * * it is marked as `untouched`
  145. * * value is set to null
  146. *
  147. * For more information, see {\@link AbstractControl}.
  148. * @param {?=} value
  149. * @return {?}
  150. */
  151. reset(value = undefined) {
  152. if (this.control)
  153. this.control.reset(value);
  154. }
  155. /**
  156. * Returns true if the control with the given path has the error specified. Otherwise
  157. * returns false.
  158. *
  159. * If no path is given, it checks for the error on the present control.
  160. * @param {?} errorCode
  161. * @param {?=} path
  162. * @return {?}
  163. */
  164. hasError(errorCode, path) {
  165. return this.control ? this.control.hasError(errorCode, path) : false;
  166. }
  167. /**
  168. * Returns error data if the control with the given path has the error specified. Otherwise
  169. * returns null or undefined.
  170. *
  171. * If no path is given, it checks for the error on the present control.
  172. * @param {?} errorCode
  173. * @param {?=} path
  174. * @return {?}
  175. */
  176. getError(errorCode, path) {
  177. return this.control ? this.control.getError(errorCode, path) : null;
  178. }
  179. }
  180. /**
  181. * @fileoverview added by tsickle
  182. * @suppress {checkTypes} checked by tsc
  183. */
  184. /**
  185. * @license
  186. * Copyright Google Inc. All Rights Reserved.
  187. *
  188. * Use of this source code is governed by an MIT-style license that can be
  189. * found in the LICENSE file at https://angular.io/license
  190. */
  191. /**
  192. * A directive that contains multiple {\@link NgControl}s.
  193. *
  194. * Only used by the forms module.
  195. *
  196. * \@stable
  197. * @abstract
  198. */
  199. class ControlContainer extends AbstractControlDirective {
  200. /**
  201. * Get the form to which this container belongs.
  202. * @return {?}
  203. */
  204. get formDirective() { return null; }
  205. /**
  206. * Get the path to this container.
  207. * @return {?}
  208. */
  209. get path() { return null; }
  210. }
  211. /**
  212. * @fileoverview added by tsickle
  213. * @suppress {checkTypes} checked by tsc
  214. */
  215. /**
  216. * @license
  217. * Copyright Google Inc. All Rights Reserved.
  218. *
  219. * Use of this source code is governed by an MIT-style license that can be
  220. * found in the LICENSE file at https://angular.io/license
  221. */
  222. /**
  223. * @param {?} value
  224. * @return {?}
  225. */
  226. function isEmptyInputValue(value) {
  227. // we don't check for string here so it also works with arrays
  228. return value == null || value.length === 0;
  229. }
  230. /**
  231. * Providers for validators to be used for {\@link FormControl}s in a form.
  232. *
  233. * Provide this using `multi: true` to add validators.
  234. *
  235. * ### Example
  236. *
  237. * ```typescript
  238. * \@Directive({
  239. * selector: '[custom-validator]',
  240. * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
  241. * })
  242. * class CustomValidatorDirective implements Validator {
  243. * validate(control: AbstractControl): ValidationErrors | null {
  244. * return {"custom": true};
  245. * }
  246. * }
  247. * ```
  248. *
  249. * \@stable
  250. */
  251. const NG_VALIDATORS = new InjectionToken('NgValidators');
  252. /**
  253. * Providers for asynchronous validators to be used for {\@link FormControl}s
  254. * in a form.
  255. *
  256. * Provide this using `multi: true` to add validators.
  257. *
  258. * See {\@link NG_VALIDATORS} for more details.
  259. *
  260. * \@stable
  261. */
  262. const NG_ASYNC_VALIDATORS = new InjectionToken('NgAsyncValidators');
  263. 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])?)*$/;
  264. /**
  265. * Provides a set of validators used by form controls.
  266. *
  267. * A validator is a function that processes a {\@link FormControl} or collection of
  268. * controls and returns a map of errors. A null map means that validation has passed.
  269. *
  270. * ### Example
  271. *
  272. * ```typescript
  273. * var loginControl = new FormControl("", Validators.required)
  274. * ```
  275. *
  276. * \@stable
  277. */
  278. class Validators {
  279. /**
  280. * Validator that requires controls to have a value greater than a number.
  281. * `min()` exists only as a function, not as a directive. For example,
  282. * `control = new FormControl('', Validators.min(3));`.
  283. * @param {?} min
  284. * @return {?}
  285. */
  286. static min(min) {
  287. return (control) => {
  288. if (isEmptyInputValue(control.value) || isEmptyInputValue(min)) {
  289. return null; // don't validate empty values to allow optional controls
  290. }
  291. const /** @type {?} */ value = parseFloat(control.value);
  292. // Controls with NaN values after parsing should be treated as not having a
  293. // minimum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-min
  294. return !isNaN(value) && value < min ? { 'min': { 'min': min, 'actual': control.value } } : null;
  295. };
  296. }
  297. /**
  298. * Validator that requires controls to have a value less than a number.
  299. * `max()` exists only as a function, not as a directive. For example,
  300. * `control = new FormControl('', Validators.max(15));`.
  301. * @param {?} max
  302. * @return {?}
  303. */
  304. static max(max) {
  305. return (control) => {
  306. if (isEmptyInputValue(control.value) || isEmptyInputValue(max)) {
  307. return null; // don't validate empty values to allow optional controls
  308. }
  309. const /** @type {?} */ value = parseFloat(control.value);
  310. // Controls with NaN values after parsing should be treated as not having a
  311. // maximum, per the HTML forms spec: https://www.w3.org/TR/html5/forms.html#attr-input-max
  312. return !isNaN(value) && value > max ? { 'max': { 'max': max, 'actual': control.value } } : null;
  313. };
  314. }
  315. /**
  316. * Validator that requires controls to have a non-empty value.
  317. * @param {?} control
  318. * @return {?}
  319. */
  320. static required(control) {
  321. return isEmptyInputValue(control.value) ? { 'required': true } : null;
  322. }
  323. /**
  324. * Validator that requires control value to be true.
  325. * @param {?} control
  326. * @return {?}
  327. */
  328. static requiredTrue(control) {
  329. return control.value === true ? null : { 'required': true };
  330. }
  331. /**
  332. * Validator that performs email validation.
  333. * @param {?} control
  334. * @return {?}
  335. */
  336. static email(control) {
  337. return EMAIL_REGEXP.test(control.value) ? null : { 'email': true };
  338. }
  339. /**
  340. * Validator that requires controls to have a value of a minimum length.
  341. * @param {?} minLength
  342. * @return {?}
  343. */
  344. static minLength(minLength) {
  345. return (control) => {
  346. if (isEmptyInputValue(control.value)) {
  347. return null; // don't validate empty values to allow optional controls
  348. }
  349. const /** @type {?} */ length = control.value ? control.value.length : 0;
  350. return length < minLength ?
  351. { 'minlength': { 'requiredLength': minLength, 'actualLength': length } } :
  352. null;
  353. };
  354. }
  355. /**
  356. * Validator that requires controls to have a value of a maximum length.
  357. * @param {?} maxLength
  358. * @return {?}
  359. */
  360. static maxLength(maxLength) {
  361. return (control) => {
  362. const /** @type {?} */ length = control.value ? control.value.length : 0;
  363. return length > maxLength ?
  364. { 'maxlength': { 'requiredLength': maxLength, 'actualLength': length } } :
  365. null;
  366. };
  367. }
  368. /**
  369. * Validator that requires a control to match a regex to its value.
  370. * @param {?} pattern
  371. * @return {?}
  372. */
  373. static pattern(pattern) {
  374. if (!pattern)
  375. return Validators.nullValidator;
  376. let /** @type {?} */ regex;
  377. let /** @type {?} */ regexStr;
  378. if (typeof pattern === 'string') {
  379. regexStr = '';
  380. if (pattern.charAt(0) !== '^')
  381. regexStr += '^';
  382. regexStr += pattern;
  383. if (pattern.charAt(pattern.length - 1) !== '$')
  384. regexStr += '$';
  385. regex = new RegExp(regexStr);
  386. }
  387. else {
  388. regexStr = pattern.toString();
  389. regex = pattern;
  390. }
  391. return (control) => {
  392. if (isEmptyInputValue(control.value)) {
  393. return null; // don't validate empty values to allow optional controls
  394. }
  395. const /** @type {?} */ value = control.value;
  396. return regex.test(value) ? null :
  397. { 'pattern': { 'requiredPattern': regexStr, 'actualValue': value } };
  398. };
  399. }
  400. /**
  401. * No-op validator.
  402. * @param {?} c
  403. * @return {?}
  404. */
  405. static nullValidator(c) { return null; }
  406. /**
  407. * @param {?} validators
  408. * @return {?}
  409. */
  410. static compose(validators) {
  411. if (!validators)
  412. return null;
  413. const /** @type {?} */ presentValidators = /** @type {?} */ (validators.filter(isPresent));
  414. if (presentValidators.length == 0)
  415. return null;
  416. return function (control) {
  417. return _mergeErrors(_executeValidators(control, presentValidators));
  418. };
  419. }
  420. /**
  421. * @param {?} validators
  422. * @return {?}
  423. */
  424. static composeAsync(validators) {
  425. if (!validators)
  426. return null;
  427. const /** @type {?} */ presentValidators = /** @type {?} */ (validators.filter(isPresent));
  428. if (presentValidators.length == 0)
  429. return null;
  430. return function (control) {
  431. const /** @type {?} */ observables = _executeAsyncValidators(control, presentValidators).map(toObservable);
  432. return map.call(forkJoin(observables), _mergeErrors);
  433. };
  434. }
  435. }
  436. /**
  437. * @param {?} o
  438. * @return {?}
  439. */
  440. function isPresent(o) {
  441. return o != null;
  442. }
  443. /**
  444. * @param {?} r
  445. * @return {?}
  446. */
  447. function toObservable(r) {
  448. const /** @type {?} */ obs = ɵisPromise(r) ? fromPromise(r) : r;
  449. if (!(ɵisObservable(obs))) {
  450. throw new Error(`Expected validator to return Promise or Observable.`);
  451. }
  452. return obs;
  453. }
  454. /**
  455. * @param {?} control
  456. * @param {?} validators
  457. * @return {?}
  458. */
  459. function _executeValidators(control, validators) {
  460. return validators.map(v => v(control));
  461. }
  462. /**
  463. * @param {?} control
  464. * @param {?} validators
  465. * @return {?}
  466. */
  467. function _executeAsyncValidators(control, validators) {
  468. return validators.map(v => v(control));
  469. }
  470. /**
  471. * @param {?} arrayOfErrors
  472. * @return {?}
  473. */
  474. function _mergeErrors(arrayOfErrors) {
  475. const /** @type {?} */ res = arrayOfErrors.reduce((res, errors) => {
  476. return errors != null ? Object.assign({}, /** @type {?} */ ((res)), errors) : /** @type {?} */ ((res));
  477. }, {});
  478. return Object.keys(res).length === 0 ? null : res;
  479. }
  480. /**
  481. * @fileoverview added by tsickle
  482. * @suppress {checkTypes} checked by tsc
  483. */
  484. /**
  485. * @license
  486. * Copyright Google Inc. All Rights Reserved.
  487. *
  488. * Use of this source code is governed by an MIT-style license that can be
  489. * found in the LICENSE file at https://angular.io/license
  490. */
  491. /**
  492. * A `ControlValueAccessor` acts as a bridge between the Angular forms API and a
  493. * native element in the DOM.
  494. *
  495. * Implement this interface if you want to create a custom form control directive
  496. * that integrates with Angular forms.
  497. *
  498. * \@stable
  499. * @record
  500. */
  501. /**
  502. * Used to provide a {\@link ControlValueAccessor} for form controls.
  503. *
  504. * See {\@link DefaultValueAccessor} for how to implement one.
  505. * \@stable
  506. */
  507. const NG_VALUE_ACCESSOR = new InjectionToken('NgValueAccessor');
  508. /**
  509. * @fileoverview added by tsickle
  510. * @suppress {checkTypes} checked by tsc
  511. */
  512. /**
  513. * @license
  514. * Copyright Google Inc. All Rights Reserved.
  515. *
  516. * Use of this source code is governed by an MIT-style license that can be
  517. * found in the LICENSE file at https://angular.io/license
  518. */
  519. const CHECKBOX_VALUE_ACCESSOR = {
  520. provide: NG_VALUE_ACCESSOR,
  521. useExisting: forwardRef(() => CheckboxControlValueAccessor),
  522. multi: true,
  523. };
  524. /**
  525. * The accessor for writing a value and listening to changes on a checkbox input element.
  526. *
  527. * ### Example
  528. * ```
  529. * <input type="checkbox" name="rememberLogin" ngModel>
  530. * ```
  531. *
  532. * \@stable
  533. */
  534. class CheckboxControlValueAccessor {
  535. /**
  536. * @param {?} _renderer
  537. * @param {?} _elementRef
  538. */
  539. constructor(_renderer, _elementRef) {
  540. this._renderer = _renderer;
  541. this._elementRef = _elementRef;
  542. this.onChange = (_) => { };
  543. this.onTouched = () => { };
  544. }
  545. /**
  546. * @param {?} value
  547. * @return {?}
  548. */
  549. writeValue(value) {
  550. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', value);
  551. }
  552. /**
  553. * @param {?} fn
  554. * @return {?}
  555. */
  556. registerOnChange(fn) { this.onChange = fn; }
  557. /**
  558. * @param {?} fn
  559. * @return {?}
  560. */
  561. registerOnTouched(fn) { this.onTouched = fn; }
  562. /**
  563. * @param {?} isDisabled
  564. * @return {?}
  565. */
  566. setDisabledState(isDisabled) {
  567. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  568. }
  569. }
  570. CheckboxControlValueAccessor.decorators = [
  571. { type: Directive, args: [{
  572. selector: 'input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]',
  573. host: { '(change)': 'onChange($event.target.checked)', '(blur)': 'onTouched()' },
  574. providers: [CHECKBOX_VALUE_ACCESSOR]
  575. },] },
  576. ];
  577. /** @nocollapse */
  578. CheckboxControlValueAccessor.ctorParameters = () => [
  579. { type: Renderer2, },
  580. { type: ElementRef, },
  581. ];
  582. /**
  583. * @fileoverview added by tsickle
  584. * @suppress {checkTypes} checked by tsc
  585. */
  586. /**
  587. * @license
  588. * Copyright Google Inc. All Rights Reserved.
  589. *
  590. * Use of this source code is governed by an MIT-style license that can be
  591. * found in the LICENSE file at https://angular.io/license
  592. */
  593. const DEFAULT_VALUE_ACCESSOR = {
  594. provide: NG_VALUE_ACCESSOR,
  595. useExisting: forwardRef(() => DefaultValueAccessor),
  596. multi: true
  597. };
  598. /**
  599. * We must check whether the agent is Android because composition events
  600. * behave differently between iOS and Android.
  601. * @return {?}
  602. */
  603. function _isAndroid() {
  604. const /** @type {?} */ userAgent = ɵgetDOM() ? ɵgetDOM().getUserAgent() : '';
  605. return /android (\d+)/.test(userAgent.toLowerCase());
  606. }
  607. /**
  608. * Turn this mode on if you want form directives to buffer IME input until compositionend
  609. * \@experimental
  610. */
  611. const COMPOSITION_BUFFER_MODE = new InjectionToken('CompositionEventMode');
  612. /**
  613. * The default accessor for writing a value and listening to changes that is used by the
  614. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  615. *
  616. * ### Example
  617. * ```
  618. * <input type="text" name="searchQuery" ngModel>
  619. * ```
  620. *
  621. * \@stable
  622. */
  623. class DefaultValueAccessor {
  624. /**
  625. * @param {?} _renderer
  626. * @param {?} _elementRef
  627. * @param {?} _compositionMode
  628. */
  629. constructor(_renderer, _elementRef, _compositionMode) {
  630. this._renderer = _renderer;
  631. this._elementRef = _elementRef;
  632. this._compositionMode = _compositionMode;
  633. this.onChange = (_) => { };
  634. this.onTouched = () => { };
  635. /**
  636. * Whether the user is creating a composition string (IME events).
  637. */
  638. this._composing = false;
  639. if (this._compositionMode == null) {
  640. this._compositionMode = !_isAndroid();
  641. }
  642. }
  643. /**
  644. * @param {?} value
  645. * @return {?}
  646. */
  647. writeValue(value) {
  648. const /** @type {?} */ normalizedValue = value == null ? '' : value;
  649. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  650. }
  651. /**
  652. * @param {?} fn
  653. * @return {?}
  654. */
  655. registerOnChange(fn) { this.onChange = fn; }
  656. /**
  657. * @param {?} fn
  658. * @return {?}
  659. */
  660. registerOnTouched(fn) { this.onTouched = fn; }
  661. /**
  662. * @param {?} isDisabled
  663. * @return {?}
  664. */
  665. setDisabledState(isDisabled) {
  666. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  667. }
  668. /**
  669. * \@internal
  670. * @param {?} value
  671. * @return {?}
  672. */
  673. _handleInput(value) {
  674. if (!this._compositionMode || (this._compositionMode && !this._composing)) {
  675. this.onChange(value);
  676. }
  677. }
  678. /**
  679. * \@internal
  680. * @return {?}
  681. */
  682. _compositionStart() { this._composing = true; }
  683. /**
  684. * \@internal
  685. * @param {?} value
  686. * @return {?}
  687. */
  688. _compositionEnd(value) {
  689. this._composing = false;
  690. this._compositionMode && this.onChange(value);
  691. }
  692. }
  693. DefaultValueAccessor.decorators = [
  694. { type: Directive, args: [{
  695. selector: 'input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]',
  696. // TODO: vsavkin replace the above selector with the one below it once
  697. // https://github.com/angular/angular/issues/3011 is implemented
  698. // selector: '[ngModel],[formControl],[formControlName]',
  699. host: {
  700. '(input)': '$any(this)._handleInput($event.target.value)',
  701. '(blur)': 'onTouched()',
  702. '(compositionstart)': '$any(this)._compositionStart()',
  703. '(compositionend)': '$any(this)._compositionEnd($event.target.value)'
  704. },
  705. providers: [DEFAULT_VALUE_ACCESSOR]
  706. },] },
  707. ];
  708. /** @nocollapse */
  709. DefaultValueAccessor.ctorParameters = () => [
  710. { type: Renderer2, },
  711. { type: ElementRef, },
  712. { type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [COMPOSITION_BUFFER_MODE,] },] },
  713. ];
  714. /**
  715. * @fileoverview added by tsickle
  716. * @suppress {checkTypes} checked by tsc
  717. */
  718. /**
  719. * @license
  720. * Copyright Google Inc. All Rights Reserved.
  721. *
  722. * Use of this source code is governed by an MIT-style license that can be
  723. * found in the LICENSE file at https://angular.io/license
  724. */
  725. /**
  726. * @param {?} validator
  727. * @return {?}
  728. */
  729. function normalizeValidator(validator) {
  730. if ((/** @type {?} */ (validator)).validate) {
  731. return (c) => (/** @type {?} */ (validator)).validate(c);
  732. }
  733. else {
  734. return /** @type {?} */ (validator);
  735. }
  736. }
  737. /**
  738. * @param {?} validator
  739. * @return {?}
  740. */
  741. function normalizeAsyncValidator(validator) {
  742. if ((/** @type {?} */ (validator)).validate) {
  743. return (c) => (/** @type {?} */ (validator)).validate(c);
  744. }
  745. else {
  746. return /** @type {?} */ (validator);
  747. }
  748. }
  749. /**
  750. * @fileoverview added by tsickle
  751. * @suppress {checkTypes} checked by tsc
  752. */
  753. /**
  754. * @license
  755. * Copyright Google Inc. All Rights Reserved.
  756. *
  757. * Use of this source code is governed by an MIT-style license that can be
  758. * found in the LICENSE file at https://angular.io/license
  759. */
  760. const NUMBER_VALUE_ACCESSOR = {
  761. provide: NG_VALUE_ACCESSOR,
  762. useExisting: forwardRef(() => NumberValueAccessor),
  763. multi: true
  764. };
  765. /**
  766. * The accessor for writing a number value and listening to changes that is used by the
  767. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  768. *
  769. * ### Example
  770. * ```
  771. * <input type="number" [(ngModel)]="age">
  772. * ```
  773. */
  774. class NumberValueAccessor {
  775. /**
  776. * @param {?} _renderer
  777. * @param {?} _elementRef
  778. */
  779. constructor(_renderer, _elementRef) {
  780. this._renderer = _renderer;
  781. this._elementRef = _elementRef;
  782. this.onChange = (_) => { };
  783. this.onTouched = () => { };
  784. }
  785. /**
  786. * @param {?} value
  787. * @return {?}
  788. */
  789. writeValue(value) {
  790. // The value needs to be normalized for IE9, otherwise it is set to 'null' when null
  791. const /** @type {?} */ normalizedValue = value == null ? '' : value;
  792. this._renderer.setProperty(this._elementRef.nativeElement, 'value', normalizedValue);
  793. }
  794. /**
  795. * @param {?} fn
  796. * @return {?}
  797. */
  798. registerOnChange(fn) {
  799. this.onChange = (value) => { fn(value == '' ? null : parseFloat(value)); };
  800. }
  801. /**
  802. * @param {?} fn
  803. * @return {?}
  804. */
  805. registerOnTouched(fn) { this.onTouched = fn; }
  806. /**
  807. * @param {?} isDisabled
  808. * @return {?}
  809. */
  810. setDisabledState(isDisabled) {
  811. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  812. }
  813. }
  814. NumberValueAccessor.decorators = [
  815. { type: Directive, args: [{
  816. selector: 'input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]',
  817. host: {
  818. '(change)': 'onChange($event.target.value)',
  819. '(input)': 'onChange($event.target.value)',
  820. '(blur)': 'onTouched()'
  821. },
  822. providers: [NUMBER_VALUE_ACCESSOR]
  823. },] },
  824. ];
  825. /** @nocollapse */
  826. NumberValueAccessor.ctorParameters = () => [
  827. { type: Renderer2, },
  828. { type: ElementRef, },
  829. ];
  830. /**
  831. * @fileoverview added by tsickle
  832. * @suppress {checkTypes} checked by tsc
  833. */
  834. /**
  835. * @license
  836. * Copyright Google Inc. All Rights Reserved.
  837. *
  838. * Use of this source code is governed by an MIT-style license that can be
  839. * found in the LICENSE file at https://angular.io/license
  840. */
  841. /**
  842. * @return {?}
  843. */
  844. function unimplemented() {
  845. throw new Error('unimplemented');
  846. }
  847. /**
  848. * A base class that all control directive extend.
  849. * It binds a {\@link FormControl} object to a DOM element.
  850. *
  851. * Used internally by Angular forms.
  852. *
  853. * \@stable
  854. * @abstract
  855. */
  856. class NgControl extends AbstractControlDirective {
  857. constructor() {
  858. super(...arguments);
  859. /**
  860. * \@internal
  861. */
  862. this._parent = null;
  863. this.name = null;
  864. this.valueAccessor = null;
  865. /**
  866. * \@internal
  867. */
  868. this._rawValidators = [];
  869. /**
  870. * \@internal
  871. */
  872. this._rawAsyncValidators = [];
  873. }
  874. /**
  875. * @return {?}
  876. */
  877. get validator() { return /** @type {?} */ (unimplemented()); }
  878. /**
  879. * @return {?}
  880. */
  881. get asyncValidator() { return /** @type {?} */ (unimplemented()); }
  882. }
  883. /**
  884. * @fileoverview added by tsickle
  885. * @suppress {checkTypes} checked by tsc
  886. */
  887. /**
  888. * @license
  889. * Copyright Google Inc. All Rights Reserved.
  890. *
  891. * Use of this source code is governed by an MIT-style license that can be
  892. * found in the LICENSE file at https://angular.io/license
  893. */
  894. const RADIO_VALUE_ACCESSOR = {
  895. provide: NG_VALUE_ACCESSOR,
  896. useExisting: forwardRef(() => RadioControlValueAccessor),
  897. multi: true
  898. };
  899. /**
  900. * Internal class used by Angular to uncheck radio buttons with the matching name.
  901. */
  902. class RadioControlRegistry {
  903. constructor() {
  904. this._accessors = [];
  905. }
  906. /**
  907. * @param {?} control
  908. * @param {?} accessor
  909. * @return {?}
  910. */
  911. add(control, accessor) {
  912. this._accessors.push([control, accessor]);
  913. }
  914. /**
  915. * @param {?} accessor
  916. * @return {?}
  917. */
  918. remove(accessor) {
  919. for (let /** @type {?} */ i = this._accessors.length - 1; i >= 0; --i) {
  920. if (this._accessors[i][1] === accessor) {
  921. this._accessors.splice(i, 1);
  922. return;
  923. }
  924. }
  925. }
  926. /**
  927. * @param {?} accessor
  928. * @return {?}
  929. */
  930. select(accessor) {
  931. this._accessors.forEach((c) => {
  932. if (this._isSameGroup(c, accessor) && c[1] !== accessor) {
  933. c[1].fireUncheck(accessor.value);
  934. }
  935. });
  936. }
  937. /**
  938. * @param {?} controlPair
  939. * @param {?} accessor
  940. * @return {?}
  941. */
  942. _isSameGroup(controlPair, accessor) {
  943. if (!controlPair[0].control)
  944. return false;
  945. return controlPair[0]._parent === accessor._control._parent &&
  946. controlPair[1].name === accessor.name;
  947. }
  948. }
  949. RadioControlRegistry.decorators = [
  950. { type: Injectable },
  951. ];
  952. /** @nocollapse */
  953. RadioControlRegistry.ctorParameters = () => [];
  954. /**
  955. * \@whatItDoes Writes radio control values and listens to radio control changes.
  956. *
  957. * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
  958. * to keep the view synced with the {\@link FormControl} model.
  959. *
  960. * \@howToUse
  961. *
  962. * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
  963. * value accessor will be active on any radio control that has a form directive. You do
  964. * **not** need to add a special selector to activate it.
  965. *
  966. * ### How to use radio buttons with form directives
  967. *
  968. * To use radio buttons in a template-driven form, you'll want to ensure that radio buttons
  969. * in the same group have the same `name` attribute. Radio buttons with different `name`
  970. * attributes do not affect each other.
  971. *
  972. * {\@example forms/ts/radioButtons/radio_button_example.ts region='TemplateDriven'}
  973. *
  974. * When using radio buttons in a reactive form, radio buttons in the same group should have the
  975. * same `formControlName`. You can also add a `name` attribute, but it's optional.
  976. *
  977. * {\@example forms/ts/reactiveRadioButtons/reactive_radio_button_example.ts region='Reactive'}
  978. *
  979. * * **npm package**: `\@angular/forms`
  980. *
  981. * \@stable
  982. */
  983. class RadioControlValueAccessor {
  984. /**
  985. * @param {?} _renderer
  986. * @param {?} _elementRef
  987. * @param {?} _registry
  988. * @param {?} _injector
  989. */
  990. constructor(_renderer, _elementRef, _registry, _injector) {
  991. this._renderer = _renderer;
  992. this._elementRef = _elementRef;
  993. this._registry = _registry;
  994. this._injector = _injector;
  995. this.onChange = () => { };
  996. this.onTouched = () => { };
  997. }
  998. /**
  999. * @return {?}
  1000. */
  1001. ngOnInit() {
  1002. this._control = this._injector.get(NgControl);
  1003. this._checkName();
  1004. this._registry.add(this._control, this);
  1005. }
  1006. /**
  1007. * @return {?}
  1008. */
  1009. ngOnDestroy() { this._registry.remove(this); }
  1010. /**
  1011. * @param {?} value
  1012. * @return {?}
  1013. */
  1014. writeValue(value) {
  1015. this._state = value === this.value;
  1016. this._renderer.setProperty(this._elementRef.nativeElement, 'checked', this._state);
  1017. }
  1018. /**
  1019. * @param {?} fn
  1020. * @return {?}
  1021. */
  1022. registerOnChange(fn) {
  1023. this._fn = fn;
  1024. this.onChange = () => {
  1025. fn(this.value);
  1026. this._registry.select(this);
  1027. };
  1028. }
  1029. /**
  1030. * @param {?} value
  1031. * @return {?}
  1032. */
  1033. fireUncheck(value) { this.writeValue(value); }
  1034. /**
  1035. * @param {?} fn
  1036. * @return {?}
  1037. */
  1038. registerOnTouched(fn) { this.onTouched = fn; }
  1039. /**
  1040. * @param {?} isDisabled
  1041. * @return {?}
  1042. */
  1043. setDisabledState(isDisabled) {
  1044. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1045. }
  1046. /**
  1047. * @return {?}
  1048. */
  1049. _checkName() {
  1050. if (this.name && this.formControlName && this.name !== this.formControlName) {
  1051. this._throwNameError();
  1052. }
  1053. if (!this.name && this.formControlName)
  1054. this.name = this.formControlName;
  1055. }
  1056. /**
  1057. * @return {?}
  1058. */
  1059. _throwNameError() {
  1060. throw new Error(`
  1061. If you define both a name and a formControlName attribute on your radio button, their values
  1062. must match. Ex: <input type="radio" formControlName="food" name="food">
  1063. `);
  1064. }
  1065. }
  1066. RadioControlValueAccessor.decorators = [
  1067. { type: Directive, args: [{
  1068. selector: 'input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]',
  1069. host: { '(change)': 'onChange()', '(blur)': 'onTouched()' },
  1070. providers: [RADIO_VALUE_ACCESSOR]
  1071. },] },
  1072. ];
  1073. /** @nocollapse */
  1074. RadioControlValueAccessor.ctorParameters = () => [
  1075. { type: Renderer2, },
  1076. { type: ElementRef, },
  1077. { type: RadioControlRegistry, },
  1078. { type: Injector, },
  1079. ];
  1080. RadioControlValueAccessor.propDecorators = {
  1081. "name": [{ type: Input },],
  1082. "formControlName": [{ type: Input },],
  1083. "value": [{ type: Input },],
  1084. };
  1085. /**
  1086. * @fileoverview added by tsickle
  1087. * @suppress {checkTypes} checked by tsc
  1088. */
  1089. /**
  1090. * @license
  1091. * Copyright Google Inc. All Rights Reserved.
  1092. *
  1093. * Use of this source code is governed by an MIT-style license that can be
  1094. * found in the LICENSE file at https://angular.io/license
  1095. */
  1096. const RANGE_VALUE_ACCESSOR = {
  1097. provide: NG_VALUE_ACCESSOR,
  1098. useExisting: forwardRef(() => RangeValueAccessor),
  1099. multi: true
  1100. };
  1101. /**
  1102. * The accessor for writing a range value and listening to changes that is used by the
  1103. * {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName} directives.
  1104. *
  1105. * ### Example
  1106. * ```
  1107. * <input type="range" [(ngModel)]="age" >
  1108. * ```
  1109. */
  1110. class RangeValueAccessor {
  1111. /**
  1112. * @param {?} _renderer
  1113. * @param {?} _elementRef
  1114. */
  1115. constructor(_renderer, _elementRef) {
  1116. this._renderer = _renderer;
  1117. this._elementRef = _elementRef;
  1118. this.onChange = (_) => { };
  1119. this.onTouched = () => { };
  1120. }
  1121. /**
  1122. * @param {?} value
  1123. * @return {?}
  1124. */
  1125. writeValue(value) {
  1126. this._renderer.setProperty(this._elementRef.nativeElement, 'value', parseFloat(value));
  1127. }
  1128. /**
  1129. * @param {?} fn
  1130. * @return {?}
  1131. */
  1132. registerOnChange(fn) {
  1133. this.onChange = (value) => { fn(value == '' ? null : parseFloat(value)); };
  1134. }
  1135. /**
  1136. * @param {?} fn
  1137. * @return {?}
  1138. */
  1139. registerOnTouched(fn) { this.onTouched = fn; }
  1140. /**
  1141. * @param {?} isDisabled
  1142. * @return {?}
  1143. */
  1144. setDisabledState(isDisabled) {
  1145. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1146. }
  1147. }
  1148. RangeValueAccessor.decorators = [
  1149. { type: Directive, args: [{
  1150. selector: 'input[type=range][formControlName],input[type=range][formControl],input[type=range][ngModel]',
  1151. host: {
  1152. '(change)': 'onChange($event.target.value)',
  1153. '(input)': 'onChange($event.target.value)',
  1154. '(blur)': 'onTouched()'
  1155. },
  1156. providers: [RANGE_VALUE_ACCESSOR]
  1157. },] },
  1158. ];
  1159. /** @nocollapse */
  1160. RangeValueAccessor.ctorParameters = () => [
  1161. { type: Renderer2, },
  1162. { type: ElementRef, },
  1163. ];
  1164. /**
  1165. * @fileoverview added by tsickle
  1166. * @suppress {checkTypes} checked by tsc
  1167. */
  1168. /**
  1169. * @license
  1170. * Copyright Google Inc. All Rights Reserved.
  1171. *
  1172. * Use of this source code is governed by an MIT-style license that can be
  1173. * found in the LICENSE file at https://angular.io/license
  1174. */
  1175. const SELECT_VALUE_ACCESSOR = {
  1176. provide: NG_VALUE_ACCESSOR,
  1177. useExisting: forwardRef(() => SelectControlValueAccessor),
  1178. multi: true
  1179. };
  1180. /**
  1181. * @param {?} id
  1182. * @param {?} value
  1183. * @return {?}
  1184. */
  1185. function _buildValueString(id, value) {
  1186. if (id == null)
  1187. return `${value}`;
  1188. if (value && typeof value === 'object')
  1189. value = 'Object';
  1190. return `${id}: ${value}`.slice(0, 50);
  1191. }
  1192. /**
  1193. * @param {?} valueString
  1194. * @return {?}
  1195. */
  1196. function _extractId(valueString) {
  1197. return valueString.split(':')[0];
  1198. }
  1199. /**
  1200. * \@whatItDoes Writes values and listens to changes on a select element.
  1201. *
  1202. * Used by {\@link NgModel}, {\@link FormControlDirective}, and {\@link FormControlName}
  1203. * to keep the view synced with the {\@link FormControl} model.
  1204. *
  1205. * \@howToUse
  1206. *
  1207. * If you have imported the {\@link FormsModule} or the {\@link ReactiveFormsModule}, this
  1208. * value accessor will be active on any select control that has a form directive. You do
  1209. * **not** need to add a special selector to activate it.
  1210. *
  1211. * ### How to use select controls with form directives
  1212. *
  1213. * To use a select in a template-driven form, simply add an `ngModel` and a `name`
  1214. * attribute to the main `<select>` tag.
  1215. *
  1216. * If your option values are simple strings, you can bind to the normal `value` property
  1217. * on the option. If your option values happen to be objects (and you'd like to save the
  1218. * selection in your form as an object), use `ngValue` instead:
  1219. *
  1220. * {\@example forms/ts/selectControl/select_control_example.ts region='Component'}
  1221. *
  1222. * In reactive forms, you'll also want to add your form directive (`formControlName` or
  1223. * `formControl`) on the main `<select>` tag. Like in the former example, you have the
  1224. * choice of binding to the `value` or `ngValue` property on the select's options.
  1225. *
  1226. * {\@example forms/ts/reactiveSelectControl/reactive_select_control_example.ts region='Component'}
  1227. *
  1228. * ### Caveat: Option selection
  1229. *
  1230. * Angular uses object identity to select option. It's possible for the identities of items
  1231. * to change while the data does not. This can happen, for example, if the items are produced
  1232. * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
  1233. * second response will produce objects with different identities.
  1234. *
  1235. * To customize the default option comparison algorithm, `<select>` supports `compareWith` input.
  1236. * `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
  1237. * If `compareWith` is given, Angular selects option by the return value of the function.
  1238. *
  1239. * #### Syntax
  1240. *
  1241. * ```
  1242. * <select [compareWith]="compareFn" [(ngModel)]="selectedCountries">
  1243. * <option *ngFor="let country of countries" [ngValue]="country">
  1244. * {{country.name}}
  1245. * </option>
  1246. * </select>
  1247. *
  1248. * compareFn(c1: Country, c2: Country): boolean {
  1249. * return c1 && c2 ? c1.id === c2.id : c1 === c2;
  1250. * }
  1251. * ```
  1252. *
  1253. * Note: We listen to the 'change' event because 'input' events aren't fired
  1254. * for selects in Firefox and IE:
  1255. * https://bugzilla.mozilla.org/show_bug.cgi?id=1024350
  1256. * https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/4660045/
  1257. *
  1258. * * **npm package**: `\@angular/forms`
  1259. *
  1260. * \@stable
  1261. */
  1262. class SelectControlValueAccessor {
  1263. /**
  1264. * @param {?} _renderer
  1265. * @param {?} _elementRef
  1266. */
  1267. constructor(_renderer, _elementRef) {
  1268. this._renderer = _renderer;
  1269. this._elementRef = _elementRef;
  1270. /**
  1271. * \@internal
  1272. */
  1273. this._optionMap = new Map();
  1274. /**
  1275. * \@internal
  1276. */
  1277. this._idCounter = 0;
  1278. this.onChange = (_) => { };
  1279. this.onTouched = () => { };
  1280. this._compareWith = ɵlooseIdentical;
  1281. }
  1282. /**
  1283. * @param {?} fn
  1284. * @return {?}
  1285. */
  1286. set compareWith(fn) {
  1287. if (typeof fn !== 'function') {
  1288. throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
  1289. }
  1290. this._compareWith = fn;
  1291. }
  1292. /**
  1293. * @param {?} value
  1294. * @return {?}
  1295. */
  1296. writeValue(value) {
  1297. this.value = value;
  1298. const /** @type {?} */ id = this._getOptionId(value);
  1299. if (id == null) {
  1300. this._renderer.setProperty(this._elementRef.nativeElement, 'selectedIndex', -1);
  1301. }
  1302. const /** @type {?} */ valueString = _buildValueString(id, value);
  1303. this._renderer.setProperty(this._elementRef.nativeElement, 'value', valueString);
  1304. }
  1305. /**
  1306. * @param {?} fn
  1307. * @return {?}
  1308. */
  1309. registerOnChange(fn) {
  1310. this.onChange = (valueString) => {
  1311. this.value = this._getOptionValue(valueString);
  1312. fn(this.value);
  1313. };
  1314. }
  1315. /**
  1316. * @param {?} fn
  1317. * @return {?}
  1318. */
  1319. registerOnTouched(fn) { this.onTouched = fn; }
  1320. /**
  1321. * @param {?} isDisabled
  1322. * @return {?}
  1323. */
  1324. setDisabledState(isDisabled) {
  1325. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1326. }
  1327. /**
  1328. * \@internal
  1329. * @return {?}
  1330. */
  1331. _registerOption() { return (this._idCounter++).toString(); }
  1332. /**
  1333. * \@internal
  1334. * @param {?} value
  1335. * @return {?}
  1336. */
  1337. _getOptionId(value) {
  1338. for (const /** @type {?} */ id of Array.from(this._optionMap.keys())) {
  1339. if (this._compareWith(this._optionMap.get(id), value))
  1340. return id;
  1341. }
  1342. return null;
  1343. }
  1344. /**
  1345. * \@internal
  1346. * @param {?} valueString
  1347. * @return {?}
  1348. */
  1349. _getOptionValue(valueString) {
  1350. const /** @type {?} */ id = _extractId(valueString);
  1351. return this._optionMap.has(id) ? this._optionMap.get(id) : valueString;
  1352. }
  1353. }
  1354. SelectControlValueAccessor.decorators = [
  1355. { type: Directive, args: [{
  1356. selector: 'select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]',
  1357. host: { '(change)': 'onChange($event.target.value)', '(blur)': 'onTouched()' },
  1358. providers: [SELECT_VALUE_ACCESSOR]
  1359. },] },
  1360. ];
  1361. /** @nocollapse */
  1362. SelectControlValueAccessor.ctorParameters = () => [
  1363. { type: Renderer2, },
  1364. { type: ElementRef, },
  1365. ];
  1366. SelectControlValueAccessor.propDecorators = {
  1367. "compareWith": [{ type: Input },],
  1368. };
  1369. /**
  1370. * \@whatItDoes Marks `<option>` as dynamic, so Angular can be notified when options change.
  1371. *
  1372. * \@howToUse
  1373. *
  1374. * See docs for {\@link SelectControlValueAccessor} for usage examples.
  1375. *
  1376. * \@stable
  1377. */
  1378. class NgSelectOption {
  1379. /**
  1380. * @param {?} _element
  1381. * @param {?} _renderer
  1382. * @param {?} _select
  1383. */
  1384. constructor(_element, _renderer, _select) {
  1385. this._element = _element;
  1386. this._renderer = _renderer;
  1387. this._select = _select;
  1388. if (this._select)
  1389. this.id = this._select._registerOption();
  1390. }
  1391. /**
  1392. * @param {?} value
  1393. * @return {?}
  1394. */
  1395. set ngValue(value) {
  1396. if (this._select == null)
  1397. return;
  1398. this._select._optionMap.set(this.id, value);
  1399. this._setElementValue(_buildValueString(this.id, value));
  1400. this._select.writeValue(this._select.value);
  1401. }
  1402. /**
  1403. * @param {?} value
  1404. * @return {?}
  1405. */
  1406. set value(value) {
  1407. this._setElementValue(value);
  1408. if (this._select)
  1409. this._select.writeValue(this._select.value);
  1410. }
  1411. /**
  1412. * \@internal
  1413. * @param {?} value
  1414. * @return {?}
  1415. */
  1416. _setElementValue(value) {
  1417. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  1418. }
  1419. /**
  1420. * @return {?}
  1421. */
  1422. ngOnDestroy() {
  1423. if (this._select) {
  1424. this._select._optionMap.delete(this.id);
  1425. this._select.writeValue(this._select.value);
  1426. }
  1427. }
  1428. }
  1429. NgSelectOption.decorators = [
  1430. { type: Directive, args: [{ selector: 'option' },] },
  1431. ];
  1432. /** @nocollapse */
  1433. NgSelectOption.ctorParameters = () => [
  1434. { type: ElementRef, },
  1435. { type: Renderer2, },
  1436. { type: SelectControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
  1437. ];
  1438. NgSelectOption.propDecorators = {
  1439. "ngValue": [{ type: Input, args: ['ngValue',] },],
  1440. "value": [{ type: Input, args: ['value',] },],
  1441. };
  1442. /**
  1443. * @fileoverview added by tsickle
  1444. * @suppress {checkTypes} checked by tsc
  1445. */
  1446. /**
  1447. * @license
  1448. * Copyright Google Inc. All Rights Reserved.
  1449. *
  1450. * Use of this source code is governed by an MIT-style license that can be
  1451. * found in the LICENSE file at https://angular.io/license
  1452. */
  1453. const SELECT_MULTIPLE_VALUE_ACCESSOR = {
  1454. provide: NG_VALUE_ACCESSOR,
  1455. useExisting: forwardRef(() => SelectMultipleControlValueAccessor),
  1456. multi: true
  1457. };
  1458. /**
  1459. * @param {?} id
  1460. * @param {?} value
  1461. * @return {?}
  1462. */
  1463. function _buildValueString$1(id, value) {
  1464. if (id == null)
  1465. return `${value}`;
  1466. if (typeof value === 'string')
  1467. value = `'${value}'`;
  1468. if (value && typeof value === 'object')
  1469. value = 'Object';
  1470. return `${id}: ${value}`.slice(0, 50);
  1471. }
  1472. /**
  1473. * @param {?} valueString
  1474. * @return {?}
  1475. */
  1476. function _extractId$1(valueString) {
  1477. return valueString.split(':')[0];
  1478. }
  1479. /**
  1480. * The accessor for writing a value and listening to changes on a select element.
  1481. *
  1482. * ### Caveat: Options selection
  1483. *
  1484. * Angular uses object identity to select options. It's possible for the identities of items
  1485. * to change while the data does not. This can happen, for example, if the items are produced
  1486. * from an RPC to the server, and that RPC is re-run. Even if the data hasn't changed, the
  1487. * second response will produce objects with different identities.
  1488. *
  1489. * To customize the default option comparison algorithm, `<select multiple>` supports `compareWith`
  1490. * input. `compareWith` takes a **function** which has two arguments: `option1` and `option2`.
  1491. * If `compareWith` is given, Angular selects options by the return value of the function.
  1492. *
  1493. * #### Syntax
  1494. *
  1495. * ```
  1496. * <select multiple [compareWith]="compareFn" [(ngModel)]="selectedCountries">
  1497. * <option *ngFor="let country of countries" [ngValue]="country">
  1498. * {{country.name}}
  1499. * </option>
  1500. * </select>
  1501. *
  1502. * compareFn(c1: Country, c2: Country): boolean {
  1503. * return c1 && c2 ? c1.id === c2.id : c1 === c2;
  1504. * }
  1505. * ```
  1506. *
  1507. * \@stable
  1508. */
  1509. class SelectMultipleControlValueAccessor {
  1510. /**
  1511. * @param {?} _renderer
  1512. * @param {?} _elementRef
  1513. */
  1514. constructor(_renderer, _elementRef) {
  1515. this._renderer = _renderer;
  1516. this._elementRef = _elementRef;
  1517. /**
  1518. * \@internal
  1519. */
  1520. this._optionMap = new Map();
  1521. /**
  1522. * \@internal
  1523. */
  1524. this._idCounter = 0;
  1525. this.onChange = (_) => { };
  1526. this.onTouched = () => { };
  1527. this._compareWith = ɵlooseIdentical;
  1528. }
  1529. /**
  1530. * @param {?} fn
  1531. * @return {?}
  1532. */
  1533. set compareWith(fn) {
  1534. if (typeof fn !== 'function') {
  1535. throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
  1536. }
  1537. this._compareWith = fn;
  1538. }
  1539. /**
  1540. * @param {?} value
  1541. * @return {?}
  1542. */
  1543. writeValue(value) {
  1544. this.value = value;
  1545. let /** @type {?} */ optionSelectedStateSetter;
  1546. if (Array.isArray(value)) {
  1547. // convert values to ids
  1548. const /** @type {?} */ ids = value.map((v) => this._getOptionId(v));
  1549. optionSelectedStateSetter = (opt, o) => { opt._setSelected(ids.indexOf(o.toString()) > -1); };
  1550. }
  1551. else {
  1552. optionSelectedStateSetter = (opt, o) => { opt._setSelected(false); };
  1553. }
  1554. this._optionMap.forEach(optionSelectedStateSetter);
  1555. }
  1556. /**
  1557. * @param {?} fn
  1558. * @return {?}
  1559. */
  1560. registerOnChange(fn) {
  1561. this.onChange = (_) => {
  1562. const /** @type {?} */ selected = [];
  1563. if (_.hasOwnProperty('selectedOptions')) {
  1564. const /** @type {?} */ options = _.selectedOptions;
  1565. for (let /** @type {?} */ i = 0; i < options.length; i++) {
  1566. const /** @type {?} */ opt = options.item(i);
  1567. const /** @type {?} */ val = this._getOptionValue(opt.value);
  1568. selected.push(val);
  1569. }
  1570. }
  1571. else {
  1572. const /** @type {?} */ options = /** @type {?} */ (_.options);
  1573. for (let /** @type {?} */ i = 0; i < options.length; i++) {
  1574. const /** @type {?} */ opt = options.item(i);
  1575. if (opt.selected) {
  1576. const /** @type {?} */ val = this._getOptionValue(opt.value);
  1577. selected.push(val);
  1578. }
  1579. }
  1580. }
  1581. this.value = selected;
  1582. fn(selected);
  1583. };
  1584. }
  1585. /**
  1586. * @param {?} fn
  1587. * @return {?}
  1588. */
  1589. registerOnTouched(fn) { this.onTouched = fn; }
  1590. /**
  1591. * @param {?} isDisabled
  1592. * @return {?}
  1593. */
  1594. setDisabledState(isDisabled) {
  1595. this._renderer.setProperty(this._elementRef.nativeElement, 'disabled', isDisabled);
  1596. }
  1597. /**
  1598. * \@internal
  1599. * @param {?} value
  1600. * @return {?}
  1601. */
  1602. _registerOption(value) {
  1603. const /** @type {?} */ id = (this._idCounter++).toString();
  1604. this._optionMap.set(id, value);
  1605. return id;
  1606. }
  1607. /**
  1608. * \@internal
  1609. * @param {?} value
  1610. * @return {?}
  1611. */
  1612. _getOptionId(value) {
  1613. for (const /** @type {?} */ id of Array.from(this._optionMap.keys())) {
  1614. if (this._compareWith(/** @type {?} */ ((this._optionMap.get(id)))._value, value))
  1615. return id;
  1616. }
  1617. return null;
  1618. }
  1619. /**
  1620. * \@internal
  1621. * @param {?} valueString
  1622. * @return {?}
  1623. */
  1624. _getOptionValue(valueString) {
  1625. const /** @type {?} */ id = _extractId$1(valueString);
  1626. return this._optionMap.has(id) ? /** @type {?} */ ((this._optionMap.get(id)))._value : valueString;
  1627. }
  1628. }
  1629. SelectMultipleControlValueAccessor.decorators = [
  1630. { type: Directive, args: [{
  1631. selector: 'select[multiple][formControlName],select[multiple][formControl],select[multiple][ngModel]',
  1632. host: { '(change)': 'onChange($event.target)', '(blur)': 'onTouched()' },
  1633. providers: [SELECT_MULTIPLE_VALUE_ACCESSOR]
  1634. },] },
  1635. ];
  1636. /** @nocollapse */
  1637. SelectMultipleControlValueAccessor.ctorParameters = () => [
  1638. { type: Renderer2, },
  1639. { type: ElementRef, },
  1640. ];
  1641. SelectMultipleControlValueAccessor.propDecorators = {
  1642. "compareWith": [{ type: Input },],
  1643. };
  1644. /**
  1645. * Marks `<option>` as dynamic, so Angular can be notified when options change.
  1646. *
  1647. * ### Example
  1648. *
  1649. * ```
  1650. * <select multiple name="city" ngModel>
  1651. * <option *ngFor="let c of cities" [value]="c"></option>
  1652. * </select>
  1653. * ```
  1654. */
  1655. class NgSelectMultipleOption {
  1656. /**
  1657. * @param {?} _element
  1658. * @param {?} _renderer
  1659. * @param {?} _select
  1660. */
  1661. constructor(_element, _renderer, _select) {
  1662. this._element = _element;
  1663. this._renderer = _renderer;
  1664. this._select = _select;
  1665. if (this._select) {
  1666. this.id = this._select._registerOption(this);
  1667. }
  1668. }
  1669. /**
  1670. * @param {?} value
  1671. * @return {?}
  1672. */
  1673. set ngValue(value) {
  1674. if (this._select == null)
  1675. return;
  1676. this._value = value;
  1677. this._setElementValue(_buildValueString$1(this.id, value));
  1678. this._select.writeValue(this._select.value);
  1679. }
  1680. /**
  1681. * @param {?} value
  1682. * @return {?}
  1683. */
  1684. set value(value) {
  1685. if (this._select) {
  1686. this._value = value;
  1687. this._setElementValue(_buildValueString$1(this.id, value));
  1688. this._select.writeValue(this._select.value);
  1689. }
  1690. else {
  1691. this._setElementValue(value);
  1692. }
  1693. }
  1694. /**
  1695. * \@internal
  1696. * @param {?} value
  1697. * @return {?}
  1698. */
  1699. _setElementValue(value) {
  1700. this._renderer.setProperty(this._element.nativeElement, 'value', value);
  1701. }
  1702. /**
  1703. * \@internal
  1704. * @param {?} selected
  1705. * @return {?}
  1706. */
  1707. _setSelected(selected) {
  1708. this._renderer.setProperty(this._element.nativeElement, 'selected', selected);
  1709. }
  1710. /**
  1711. * @return {?}
  1712. */
  1713. ngOnDestroy() {
  1714. if (this._select) {
  1715. this._select._optionMap.delete(this.id);
  1716. this._select.writeValue(this._select.value);
  1717. }
  1718. }
  1719. }
  1720. NgSelectMultipleOption.decorators = [
  1721. { type: Directive, args: [{ selector: 'option' },] },
  1722. ];
  1723. /** @nocollapse */
  1724. NgSelectMultipleOption.ctorParameters = () => [
  1725. { type: ElementRef, },
  1726. { type: Renderer2, },
  1727. { type: SelectMultipleControlValueAccessor, decorators: [{ type: Optional }, { type: Host },] },
  1728. ];
  1729. NgSelectMultipleOption.propDecorators = {
  1730. "ngValue": [{ type: Input, args: ['ngValue',] },],
  1731. "value": [{ type: Input, args: ['value',] },],
  1732. };
  1733. /**
  1734. * @fileoverview added by tsickle
  1735. * @suppress {checkTypes} checked by tsc
  1736. */
  1737. /**
  1738. * @license
  1739. * Copyright Google Inc. All Rights Reserved.
  1740. *
  1741. * Use of this source code is governed by an MIT-style license that can be
  1742. * found in the LICENSE file at https://angular.io/license
  1743. */
  1744. /**
  1745. * @param {?} name
  1746. * @param {?} parent
  1747. * @return {?}
  1748. */
  1749. function controlPath(name, parent) {
  1750. return [.../** @type {?} */ ((parent.path)), name];
  1751. }
  1752. /**
  1753. * @param {?} control
  1754. * @param {?} dir
  1755. * @return {?}
  1756. */
  1757. function setUpControl(control, dir) {
  1758. if (!control)
  1759. _throwError(dir, 'Cannot find control with');
  1760. if (!dir.valueAccessor)
  1761. _throwError(dir, 'No value accessor for form control with');
  1762. control.validator = Validators.compose([/** @type {?} */ ((control.validator)), dir.validator]);
  1763. control.asyncValidator = Validators.composeAsync([/** @type {?} */ ((control.asyncValidator)), dir.asyncValidator]); /** @type {?} */
  1764. ((dir.valueAccessor)).writeValue(control.value);
  1765. setUpViewChangePipeline(control, dir);
  1766. setUpModelChangePipeline(control, dir);
  1767. setUpBlurPipeline(control, dir);
  1768. if (/** @type {?} */ ((dir.valueAccessor)).setDisabledState) {
  1769. control.registerOnDisabledChange((isDisabled) => { /** @type {?} */ ((/** @type {?} */ ((dir.valueAccessor)).setDisabledState))(isDisabled); });
  1770. }
  1771. // re-run validation when validator binding changes, e.g. minlength=3 -> minlength=4
  1772. dir._rawValidators.forEach((validator) => {
  1773. if ((/** @type {?} */ (validator)).registerOnValidatorChange)
  1774. /** @type {?} */ (((/** @type {?} */ (validator)).registerOnValidatorChange))(() => control.updateValueAndValidity());
  1775. });
  1776. dir._rawAsyncValidators.forEach((validator) => {
  1777. if ((/** @type {?} */ (validator)).registerOnValidatorChange)
  1778. /** @type {?} */ (((/** @type {?} */ (validator)).registerOnValidatorChange))(() => control.updateValueAndValidity());
  1779. });
  1780. }
  1781. /**
  1782. * @param {?} control
  1783. * @param {?} dir
  1784. * @return {?}
  1785. */
  1786. function cleanUpControl(control, dir) {
  1787. /** @type {?} */ ((dir.valueAccessor)).registerOnChange(() => _noControlError(dir)); /** @type {?} */
  1788. ((dir.valueAccessor)).registerOnTouched(() => _noControlError(dir));
  1789. dir._rawValidators.forEach((validator) => {
  1790. if (validator.registerOnValidatorChange) {
  1791. validator.registerOnValidatorChange(null);
  1792. }
  1793. });
  1794. dir._rawAsyncValidators.forEach((validator) => {
  1795. if (validator.registerOnValidatorChange) {
  1796. validator.registerOnValidatorChange(null);
  1797. }
  1798. });
  1799. if (control)
  1800. control._clearChangeFns();
  1801. }
  1802. /**
  1803. * @param {?} control
  1804. * @param {?} dir
  1805. * @return {?}
  1806. */
  1807. function setUpViewChangePipeline(control, dir) {
  1808. /** @type {?} */ ((dir.valueAccessor)).registerOnChange((newValue) => {
  1809. control._pendingValue = newValue;
  1810. control._pendingChange = true;
  1811. control._pendingDirty = true;
  1812. if (control.updateOn === 'change')
  1813. updateControl(control, dir);
  1814. });
  1815. }
  1816. /**
  1817. * @param {?} control
  1818. * @param {?} dir
  1819. * @return {?}
  1820. */
  1821. function setUpBlurPipeline(control, dir) {
  1822. /** @type {?} */ ((dir.valueAccessor)).registerOnTouched(() => {
  1823. control._pendingTouched = true;
  1824. if (control.updateOn === 'blur' && control._pendingChange)
  1825. updateControl(control, dir);
  1826. if (control.updateOn !== 'submit')
  1827. control.markAsTouched();
  1828. });
  1829. }
  1830. /**
  1831. * @param {?} control
  1832. * @param {?} dir
  1833. * @return {?}
  1834. */
  1835. function updateControl(control, dir) {
  1836. dir.viewToModelUpdate(control._pendingValue);
  1837. if (control._pendingDirty)
  1838. control.markAsDirty();
  1839. control.setValue(control._pendingValue, { emitModelToViewChange: false });
  1840. control._pendingChange = false;
  1841. }
  1842. /**
  1843. * @param {?} control
  1844. * @param {?} dir
  1845. * @return {?}
  1846. */
  1847. function setUpModelChangePipeline(control, dir) {
  1848. control.registerOnChange((newValue, emitModelEvent) => {
  1849. /** @type {?} */ ((
  1850. // control -> view
  1851. dir.valueAccessor)).writeValue(newValue);
  1852. // control -> ngModel
  1853. if (emitModelEvent)
  1854. dir.viewToModelUpdate(newValue);
  1855. });
  1856. }
  1857. /**
  1858. * @param {?} control
  1859. * @param {?} dir
  1860. * @return {?}
  1861. */
  1862. function setUpFormContainer(control, dir) {
  1863. if (control == null)
  1864. _throwError(dir, 'Cannot find control with');
  1865. control.validator = Validators.compose([control.validator, dir.validator]);
  1866. control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
  1867. }
  1868. /**
  1869. * @param {?} dir
  1870. * @return {?}
  1871. */
  1872. function _noControlError(dir) {
  1873. return _throwError(dir, 'There is no FormControl instance attached to form control element with');
  1874. }
  1875. /**
  1876. * @param {?} dir
  1877. * @param {?} message
  1878. * @return {?}
  1879. */
  1880. function _throwError(dir, message) {
  1881. let /** @type {?} */ messageEnd;
  1882. if (/** @type {?} */ ((dir.path)).length > 1) {
  1883. messageEnd = `path: '${(/** @type {?} */ ((dir.path))).join(' -> ')}'`;
  1884. }
  1885. else if (/** @type {?} */ ((dir.path))[0]) {
  1886. messageEnd = `name: '${dir.path}'`;
  1887. }
  1888. else {
  1889. messageEnd = 'unspecified name attribute';
  1890. }
  1891. throw new Error(`${message} ${messageEnd}`);
  1892. }
  1893. /**
  1894. * @param {?} validators
  1895. * @return {?}
  1896. */
  1897. function composeValidators(validators) {
  1898. return validators != null ? Validators.compose(validators.map(normalizeValidator)) : null;
  1899. }
  1900. /**
  1901. * @param {?} validators
  1902. * @return {?}
  1903. */
  1904. function composeAsyncValidators(validators) {
  1905. return validators != null ? Validators.composeAsync(validators.map(normalizeAsyncValidator)) :
  1906. null;
  1907. }
  1908. /**
  1909. * @param {?} changes
  1910. * @param {?} viewModel
  1911. * @return {?}
  1912. */
  1913. function isPropertyUpdated(changes, viewModel) {
  1914. if (!changes.hasOwnProperty('model'))
  1915. return false;
  1916. const /** @type {?} */ change = changes['model'];
  1917. if (change.isFirstChange())
  1918. return true;
  1919. return !ɵlooseIdentical(viewModel, change.currentValue);
  1920. }
  1921. const BUILTIN_ACCESSORS = [
  1922. CheckboxControlValueAccessor,
  1923. RangeValueAccessor,
  1924. NumberValueAccessor,
  1925. SelectControlValueAccessor,
  1926. SelectMultipleControlValueAccessor,
  1927. RadioControlValueAccessor,
  1928. ];
  1929. /**
  1930. * @param {?} valueAccessor
  1931. * @return {?}
  1932. */
  1933. function isBuiltInAccessor(valueAccessor) {
  1934. return BUILTIN_ACCESSORS.some(a => valueAccessor.constructor === a);
  1935. }
  1936. /**
  1937. * @param {?} form
  1938. * @param {?} directives
  1939. * @return {?}
  1940. */
  1941. function syncPendingControls(form, directives) {
  1942. form._syncPendingControls();
  1943. directives.forEach(dir => {
  1944. const /** @type {?} */ control = /** @type {?} */ (dir.control);
  1945. if (control.updateOn === 'submit' && control._pendingChange) {
  1946. dir.viewToModelUpdate(control._pendingValue);
  1947. control._pendingChange = false;
  1948. }
  1949. });
  1950. }
  1951. /**
  1952. * @param {?} dir
  1953. * @param {?} valueAccessors
  1954. * @return {?}
  1955. */
  1956. function selectValueAccessor(dir, valueAccessors) {
  1957. if (!valueAccessors)
  1958. return null;
  1959. if (!Array.isArray(valueAccessors))
  1960. _throwError(dir, 'Value accessor was not provided as an array for form control with');
  1961. let /** @type {?} */ defaultAccessor = undefined;
  1962. let /** @type {?} */ builtinAccessor = undefined;
  1963. let /** @type {?} */ customAccessor = undefined;
  1964. valueAccessors.forEach((v) => {
  1965. if (v.constructor === DefaultValueAccessor) {
  1966. defaultAccessor = v;
  1967. }
  1968. else if (isBuiltInAccessor(v)) {
  1969. if (builtinAccessor)
  1970. _throwError(dir, 'More than one built-in value accessor matches form control with');
  1971. builtinAccessor = v;
  1972. }
  1973. else {
  1974. if (customAccessor)
  1975. _throwError(dir, 'More than one custom value accessor matches form control with');
  1976. customAccessor = v;
  1977. }
  1978. });
  1979. if (customAccessor)
  1980. return customAccessor;
  1981. if (builtinAccessor)
  1982. return builtinAccessor;
  1983. if (defaultAccessor)
  1984. return defaultAccessor;
  1985. _throwError(dir, 'No valid value accessor for form control with');
  1986. return null;
  1987. }
  1988. /**
  1989. * @template T
  1990. * @param {?} list
  1991. * @param {?} el
  1992. * @return {?}
  1993. */
  1994. function removeDir(list, el) {
  1995. const /** @type {?} */ index = list.indexOf(el);
  1996. if (index > -1)
  1997. list.splice(index, 1);
  1998. }
  1999. /**
  2000. * @fileoverview added by tsickle
  2001. * @suppress {checkTypes} checked by tsc
  2002. */
  2003. /**
  2004. * @license
  2005. * Copyright Google Inc. All Rights Reserved.
  2006. *
  2007. * Use of this source code is governed by an MIT-style license that can be
  2008. * found in the LICENSE file at https://angular.io/license
  2009. */
  2010. /**
  2011. * This is a base class for code shared between {\@link NgModelGroup} and {\@link FormGroupName}.
  2012. *
  2013. * \@stable
  2014. */
  2015. class AbstractFormGroupDirective extends ControlContainer {
  2016. /**
  2017. * @return {?}
  2018. */
  2019. ngOnInit() {
  2020. this._checkParentType(); /** @type {?} */
  2021. ((this.formDirective)).addFormGroup(this);
  2022. }
  2023. /**
  2024. * @return {?}
  2025. */
  2026. ngOnDestroy() {
  2027. if (this.formDirective) {
  2028. this.formDirective.removeFormGroup(this);
  2029. }
  2030. }
  2031. /**
  2032. * Get the {\@link FormGroup} backing this binding.
  2033. * @return {?}
  2034. */
  2035. get control() { return /** @type {?} */ ((this.formDirective)).getFormGroup(this); }
  2036. /**
  2037. * Get the path to this control group.
  2038. * @return {?}
  2039. */
  2040. get path() { return controlPath(this.name, this._parent); }
  2041. /**
  2042. * Get the {\@link Form} to which this group belongs.
  2043. * @return {?}
  2044. */
  2045. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  2046. /**
  2047. * @return {?}
  2048. */
  2049. get validator() { return composeValidators(this._validators); }
  2050. /**
  2051. * @return {?}
  2052. */
  2053. get asyncValidator() {
  2054. return composeAsyncValidators(this._asyncValidators);
  2055. }
  2056. /**
  2057. * \@internal
  2058. * @return {?}
  2059. */
  2060. _checkParentType() { }
  2061. }
  2062. /**
  2063. * @fileoverview added by tsickle
  2064. * @suppress {checkTypes} checked by tsc
  2065. */
  2066. /**
  2067. * @license
  2068. * Copyright Google Inc. All Rights Reserved.
  2069. *
  2070. * Use of this source code is governed by an MIT-style license that can be
  2071. * found in the LICENSE file at https://angular.io/license
  2072. */
  2073. class AbstractControlStatus {
  2074. /**
  2075. * @param {?} cd
  2076. */
  2077. constructor(cd) { this._cd = cd; }
  2078. /**
  2079. * @return {?}
  2080. */
  2081. get ngClassUntouched() { return this._cd.control ? this._cd.control.untouched : false; }
  2082. /**
  2083. * @return {?}
  2084. */
  2085. get ngClassTouched() { return this._cd.control ? this._cd.control.touched : false; }
  2086. /**
  2087. * @return {?}
  2088. */
  2089. get ngClassPristine() { return this._cd.control ? this._cd.control.pristine : false; }
  2090. /**
  2091. * @return {?}
  2092. */
  2093. get ngClassDirty() { return this._cd.control ? this._cd.control.dirty : false; }
  2094. /**
  2095. * @return {?}
  2096. */
  2097. get ngClassValid() { return this._cd.control ? this._cd.control.valid : false; }
  2098. /**
  2099. * @return {?}
  2100. */
  2101. get ngClassInvalid() { return this._cd.control ? this._cd.control.invalid : false; }
  2102. /**
  2103. * @return {?}
  2104. */
  2105. get ngClassPending() { return this._cd.control ? this._cd.control.pending : false; }
  2106. }
  2107. const ngControlStatusHost = {
  2108. '[class.ng-untouched]': 'ngClassUntouched',
  2109. '[class.ng-touched]': 'ngClassTouched',
  2110. '[class.ng-pristine]': 'ngClassPristine',
  2111. '[class.ng-dirty]': 'ngClassDirty',
  2112. '[class.ng-valid]': 'ngClassValid',
  2113. '[class.ng-invalid]': 'ngClassInvalid',
  2114. '[class.ng-pending]': 'ngClassPending',
  2115. };
  2116. /**
  2117. * Directive automatically applied to Angular form controls that sets CSS classes
  2118. * based on control status. The following classes are applied as the properties
  2119. * become true:
  2120. *
  2121. * * ng-valid
  2122. * * ng-invalid
  2123. * * ng-pending
  2124. * * ng-pristine
  2125. * * ng-dirty
  2126. * * ng-untouched
  2127. * * ng-touched
  2128. *
  2129. * \@stable
  2130. */
  2131. class NgControlStatus extends AbstractControlStatus {
  2132. /**
  2133. * @param {?} cd
  2134. */
  2135. constructor(cd) { super(cd); }
  2136. }
  2137. NgControlStatus.decorators = [
  2138. { type: Directive, args: [{ selector: '[formControlName],[ngModel],[formControl]', host: ngControlStatusHost },] },
  2139. ];
  2140. /** @nocollapse */
  2141. NgControlStatus.ctorParameters = () => [
  2142. { type: NgControl, decorators: [{ type: Self },] },
  2143. ];
  2144. /**
  2145. * Directive automatically applied to Angular form groups that sets CSS classes
  2146. * based on control status (valid/invalid/dirty/etc).
  2147. *
  2148. * \@stable
  2149. */
  2150. class NgControlStatusGroup extends AbstractControlStatus {
  2151. /**
  2152. * @param {?} cd
  2153. */
  2154. constructor(cd) { super(cd); }
  2155. }
  2156. NgControlStatusGroup.decorators = [
  2157. { type: Directive, args: [{
  2158. selector: '[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]',
  2159. host: ngControlStatusHost
  2160. },] },
  2161. ];
  2162. /** @nocollapse */
  2163. NgControlStatusGroup.ctorParameters = () => [
  2164. { type: ControlContainer, decorators: [{ type: Self },] },
  2165. ];
  2166. /**
  2167. * @fileoverview added by tsickle
  2168. * @suppress {checkTypes} checked by tsc
  2169. */
  2170. /**
  2171. * @license
  2172. * Copyright Google Inc. All Rights Reserved.
  2173. *
  2174. * Use of this source code is governed by an MIT-style license that can be
  2175. * found in the LICENSE file at https://angular.io/license
  2176. */
  2177. /**
  2178. * Indicates that a FormControl is valid, i.e. that no errors exist in the input value.
  2179. */
  2180. const VALID = 'VALID';
  2181. /**
  2182. * Indicates that a FormControl is invalid, i.e. that an error exists in the input value.
  2183. */
  2184. const INVALID = 'INVALID';
  2185. /**
  2186. * Indicates that a FormControl is pending, i.e. that async validation is occurring and
  2187. * errors are not yet available for the input value.
  2188. */
  2189. const PENDING = 'PENDING';
  2190. /**
  2191. * Indicates that a FormControl is disabled, i.e. that the control is exempt from ancestor
  2192. * calculations of validity or value.
  2193. */
  2194. const DISABLED = 'DISABLED';
  2195. /**
  2196. * @param {?} control
  2197. * @param {?} path
  2198. * @param {?} delimiter
  2199. * @return {?}
  2200. */
  2201. function _find(control, path, delimiter) {
  2202. if (path == null)
  2203. return null;
  2204. if (!(path instanceof Array)) {
  2205. path = (/** @type {?} */ (path)).split(delimiter);
  2206. }
  2207. if (path instanceof Array && (path.length === 0))
  2208. return null;
  2209. return (/** @type {?} */ (path)).reduce((v, name) => {
  2210. if (v instanceof FormGroup) {
  2211. return v.controls[name] || null;
  2212. }
  2213. if (v instanceof FormArray) {
  2214. return v.at(/** @type {?} */ (name)) || null;
  2215. }
  2216. return null;
  2217. }, control);
  2218. }
  2219. /**
  2220. * @param {?=} validatorOrOpts
  2221. * @return {?}
  2222. */
  2223. function coerceToValidator(validatorOrOpts) {
  2224. const /** @type {?} */ validator = /** @type {?} */ ((isOptionsObj(validatorOrOpts) ? (/** @type {?} */ (validatorOrOpts)).validators :
  2225. validatorOrOpts));
  2226. return Array.isArray(validator) ? composeValidators(validator) : validator || null;
  2227. }
  2228. /**
  2229. * @param {?=} asyncValidator
  2230. * @param {?=} validatorOrOpts
  2231. * @return {?}
  2232. */
  2233. function coerceToAsyncValidator(asyncValidator, validatorOrOpts) {
  2234. const /** @type {?} */ origAsyncValidator = /** @type {?} */ ((isOptionsObj(validatorOrOpts) ? (/** @type {?} */ (validatorOrOpts)).asyncValidators :
  2235. asyncValidator));
  2236. return Array.isArray(origAsyncValidator) ? composeAsyncValidators(origAsyncValidator) :
  2237. origAsyncValidator || null;
  2238. }
  2239. /**
  2240. * @record
  2241. */
  2242. /**
  2243. * @param {?=} validatorOrOpts
  2244. * @return {?}
  2245. */
  2246. function isOptionsObj(validatorOrOpts) {
  2247. return validatorOrOpts != null && !Array.isArray(validatorOrOpts) &&
  2248. typeof validatorOrOpts === 'object';
  2249. }
  2250. /**
  2251. * \@whatItDoes This is the base class for {\@link FormControl}, {\@link FormGroup}, and
  2252. * {\@link FormArray}.
  2253. *
  2254. * It provides some of the shared behavior that all controls and groups of controls have, like
  2255. * running validators, calculating status, and resetting state. It also defines the properties
  2256. * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be
  2257. * instantiated directly.
  2258. *
  2259. * \@stable
  2260. * @abstract
  2261. */
  2262. class AbstractControl {
  2263. /**
  2264. * @param {?} validator
  2265. * @param {?} asyncValidator
  2266. */
  2267. constructor(validator, asyncValidator) {
  2268. this.validator = validator;
  2269. this.asyncValidator = asyncValidator;
  2270. /**
  2271. * \@internal
  2272. */
  2273. this._onCollectionChange = () => { };
  2274. /**
  2275. * A control is `pristine` if the user has not yet changed
  2276. * the value in the UI.
  2277. *
  2278. * Note that programmatic changes to a control's value will
  2279. * *not* mark it dirty.
  2280. */
  2281. this.pristine = true;
  2282. /**
  2283. * A control is marked `touched` once the user has triggered
  2284. * a `blur` event on it.
  2285. */
  2286. this.touched = false;
  2287. /**
  2288. * \@internal
  2289. */
  2290. this._onDisabledChange = [];
  2291. }
  2292. /**
  2293. * The parent control.
  2294. * @return {?}
  2295. */
  2296. get parent() { return this._parent; }
  2297. /**
  2298. * A control is `valid` when its `status === VALID`.
  2299. *
  2300. * In order to have this status, the control must have passed all its
  2301. * validation checks.
  2302. * @return {?}
  2303. */
  2304. get valid() { return this.status === VALID; }
  2305. /**
  2306. * A control is `invalid` when its `status === INVALID`.
  2307. *
  2308. * In order to have this status, the control must have failed
  2309. * at least one of its validation checks.
  2310. * @return {?}
  2311. */
  2312. get invalid() { return this.status === INVALID; }
  2313. /**
  2314. * A control is `pending` when its `status === PENDING`.
  2315. *
  2316. * In order to have this status, the control must be in the
  2317. * middle of conducting a validation check.
  2318. * @return {?}
  2319. */
  2320. get pending() { return this.status == PENDING; }
  2321. /**
  2322. * A control is `disabled` when its `status === DISABLED`.
  2323. *
  2324. * Disabled controls are exempt from validation checks and
  2325. * are not included in the aggregate value of their ancestor
  2326. * controls.
  2327. * @return {?}
  2328. */
  2329. get disabled() { return this.status === DISABLED; }
  2330. /**
  2331. * A control is `enabled` as long as its `status !== DISABLED`.
  2332. *
  2333. * In other words, it has a status of `VALID`, `INVALID`, or
  2334. * `PENDING`.
  2335. * @return {?}
  2336. */
  2337. get enabled() { return this.status !== DISABLED; }
  2338. /**
  2339. * A control is `dirty` if the user has changed the value
  2340. * in the UI.
  2341. *
  2342. * Note that programmatic changes to a control's value will
  2343. * *not* mark it dirty.
  2344. * @return {?}
  2345. */
  2346. get dirty() { return !this.pristine; }
  2347. /**
  2348. * A control is `untouched` if the user has not yet triggered
  2349. * a `blur` event on it.
  2350. * @return {?}
  2351. */
  2352. get untouched() { return !this.touched; }
  2353. /**
  2354. * Returns the update strategy of the `AbstractControl` (i.e.
  2355. * the event on which the control will update itself).
  2356. * Possible values: `'change'` (default) | `'blur'` | `'submit'`
  2357. * @return {?}
  2358. */
  2359. get updateOn() {
  2360. return this._updateOn ? this._updateOn : (this.parent ? this.parent.updateOn : 'change');
  2361. }
  2362. /**
  2363. * Sets the synchronous validators that are active on this control. Calling
  2364. * this will overwrite any existing sync validators.
  2365. * @param {?} newValidator
  2366. * @return {?}
  2367. */
  2368. setValidators(newValidator) {
  2369. this.validator = coerceToValidator(newValidator);
  2370. }
  2371. /**
  2372. * Sets the async validators that are active on this control. Calling this
  2373. * will overwrite any existing async validators.
  2374. * @param {?} newValidator
  2375. * @return {?}
  2376. */
  2377. setAsyncValidators(newValidator) {
  2378. this.asyncValidator = coerceToAsyncValidator(newValidator);
  2379. }
  2380. /**
  2381. * Empties out the sync validator list.
  2382. * @return {?}
  2383. */
  2384. clearValidators() { this.validator = null; }
  2385. /**
  2386. * Empties out the async validator list.
  2387. * @return {?}
  2388. */
  2389. clearAsyncValidators() { this.asyncValidator = null; }
  2390. /**
  2391. * Marks the control as `touched`.
  2392. *
  2393. * This will also mark all direct ancestors as `touched` to maintain
  2394. * the model.
  2395. * @param {?=} opts
  2396. * @return {?}
  2397. */
  2398. markAsTouched(opts = {}) {
  2399. (/** @type {?} */ (this)).touched = true;
  2400. if (this._parent && !opts.onlySelf) {
  2401. this._parent.markAsTouched(opts);
  2402. }
  2403. }
  2404. /**
  2405. * Marks the control as `untouched`.
  2406. *
  2407. * If the control has any children, it will also mark all children as `untouched`
  2408. * to maintain the model, and re-calculate the `touched` status of all parent
  2409. * controls.
  2410. * @param {?=} opts
  2411. * @return {?}
  2412. */
  2413. markAsUntouched(opts = {}) {
  2414. (/** @type {?} */ (this)).touched = false;
  2415. this._pendingTouched = false;
  2416. this._forEachChild((control) => { control.markAsUntouched({ onlySelf: true }); });
  2417. if (this._parent && !opts.onlySelf) {
  2418. this._parent._updateTouched(opts);
  2419. }
  2420. }
  2421. /**
  2422. * Marks the control as `dirty`.
  2423. *
  2424. * This will also mark all direct ancestors as `dirty` to maintain
  2425. * the model.
  2426. * @param {?=} opts
  2427. * @return {?}
  2428. */
  2429. markAsDirty(opts = {}) {
  2430. (/** @type {?} */ (this)).pristine = false;
  2431. if (this._parent && !opts.onlySelf) {
  2432. this._parent.markAsDirty(opts);
  2433. }
  2434. }
  2435. /**
  2436. * Marks the control as `pristine`.
  2437. *
  2438. * If the control has any children, it will also mark all children as `pristine`
  2439. * to maintain the model, and re-calculate the `pristine` status of all parent
  2440. * controls.
  2441. * @param {?=} opts
  2442. * @return {?}
  2443. */
  2444. markAsPristine(opts = {}) {
  2445. (/** @type {?} */ (this)).pristine = true;
  2446. this._pendingDirty = false;
  2447. this._forEachChild((control) => { control.markAsPristine({ onlySelf: true }); });
  2448. if (this._parent && !opts.onlySelf) {
  2449. this._parent._updatePristine(opts);
  2450. }
  2451. }
  2452. /**
  2453. * Marks the control as `pending`.
  2454. * @param {?=} opts
  2455. * @return {?}
  2456. */
  2457. markAsPending(opts = {}) {
  2458. (/** @type {?} */ (this)).status = PENDING;
  2459. if (this._parent && !opts.onlySelf) {
  2460. this._parent.markAsPending(opts);
  2461. }
  2462. }
  2463. /**
  2464. * Disables the control. This means the control will be exempt from validation checks and
  2465. * excluded from the aggregate value of any parent. Its status is `DISABLED`.
  2466. *
  2467. * If the control has children, all children will be disabled to maintain the model.
  2468. * @param {?=} opts
  2469. * @return {?}
  2470. */
  2471. disable(opts = {}) {
  2472. (/** @type {?} */ (this)).status = DISABLED;
  2473. (/** @type {?} */ (this)).errors = null;
  2474. this._forEachChild((control) => { control.disable(Object.assign({}, opts, { onlySelf: true })); });
  2475. this._updateValue();
  2476. if (opts.emitEvent !== false) {
  2477. (/** @type {?} */ (this.valueChanges)).emit(this.value);
  2478. (/** @type {?} */ (this.statusChanges)).emit(this.status);
  2479. }
  2480. this._updateAncestors(opts);
  2481. this._onDisabledChange.forEach((changeFn) => changeFn(true));
  2482. }
  2483. /**
  2484. * Enables the control. This means the control will be included in validation checks and
  2485. * the aggregate value of its parent. Its status is re-calculated based on its value and
  2486. * its validators.
  2487. *
  2488. * If the control has children, all children will be enabled.
  2489. * @param {?=} opts
  2490. * @return {?}
  2491. */
  2492. enable(opts = {}) {
  2493. (/** @type {?} */ (this)).status = VALID;
  2494. this._forEachChild((control) => { control.enable(Object.assign({}, opts, { onlySelf: true })); });
  2495. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  2496. this._updateAncestors(opts);
  2497. this._onDisabledChange.forEach((changeFn) => changeFn(false));
  2498. }
  2499. /**
  2500. * @param {?} opts
  2501. * @return {?}
  2502. */
  2503. _updateAncestors(opts) {
  2504. if (this._parent && !opts.onlySelf) {
  2505. this._parent.updateValueAndValidity(opts);
  2506. this._parent._updatePristine();
  2507. this._parent._updateTouched();
  2508. }
  2509. }
  2510. /**
  2511. * @param {?} parent
  2512. * @return {?}
  2513. */
  2514. setParent(parent) { this._parent = parent; }
  2515. /**
  2516. * Re-calculates the value and validation status of the control.
  2517. *
  2518. * By default, it will also update the value and validity of its ancestors.
  2519. * @param {?=} opts
  2520. * @return {?}
  2521. */
  2522. updateValueAndValidity(opts = {}) {
  2523. this._setInitialStatus();
  2524. this._updateValue();
  2525. if (this.enabled) {
  2526. this._cancelExistingSubscription();
  2527. (/** @type {?} */ (this)).errors = this._runValidator();
  2528. (/** @type {?} */ (this)).status = this._calculateStatus();
  2529. if (this.status === VALID || this.status === PENDING) {
  2530. this._runAsyncValidator(opts.emitEvent);
  2531. }
  2532. }
  2533. if (opts.emitEvent !== false) {
  2534. (/** @type {?} */ (this.valueChanges)).emit(this.value);
  2535. (/** @type {?} */ (this.statusChanges)).emit(this.status);
  2536. }
  2537. if (this._parent && !opts.onlySelf) {
  2538. this._parent.updateValueAndValidity(opts);
  2539. }
  2540. }
  2541. /**
  2542. * \@internal
  2543. * @param {?=} opts
  2544. * @return {?}
  2545. */
  2546. _updateTreeValidity(opts = { emitEvent: true }) {
  2547. this._forEachChild((ctrl) => ctrl._updateTreeValidity(opts));
  2548. this.updateValueAndValidity({ onlySelf: true, emitEvent: opts.emitEvent });
  2549. }
  2550. /**
  2551. * @return {?}
  2552. */
  2553. _setInitialStatus() {
  2554. (/** @type {?} */ (this)).status = this._allControlsDisabled() ? DISABLED : VALID;
  2555. }
  2556. /**
  2557. * @return {?}
  2558. */
  2559. _runValidator() {
  2560. return this.validator ? this.validator(this) : null;
  2561. }
  2562. /**
  2563. * @param {?=} emitEvent
  2564. * @return {?}
  2565. */
  2566. _runAsyncValidator(emitEvent) {
  2567. if (this.asyncValidator) {
  2568. (/** @type {?} */ (this)).status = PENDING;
  2569. const /** @type {?} */ obs = toObservable(this.asyncValidator(this));
  2570. this._asyncValidationSubscription =
  2571. obs.subscribe((errors) => this.setErrors(errors, { emitEvent }));
  2572. }
  2573. }
  2574. /**
  2575. * @return {?}
  2576. */
  2577. _cancelExistingSubscription() {
  2578. if (this._asyncValidationSubscription) {
  2579. this._asyncValidationSubscription.unsubscribe();
  2580. }
  2581. }
  2582. /**
  2583. * Sets errors on a form control.
  2584. *
  2585. * This is used when validations are run manually by the user, rather than automatically.
  2586. *
  2587. * Calling `setErrors` will also update the validity of the parent control.
  2588. *
  2589. * ### Example
  2590. *
  2591. * ```
  2592. * const login = new FormControl("someLogin");
  2593. * login.setErrors({
  2594. * "notUnique": true
  2595. * });
  2596. *
  2597. * expect(login.valid).toEqual(false);
  2598. * expect(login.errors).toEqual({"notUnique": true});
  2599. *
  2600. * login.setValue("someOtherLogin");
  2601. *
  2602. * expect(login.valid).toEqual(true);
  2603. * ```
  2604. * @param {?} errors
  2605. * @param {?=} opts
  2606. * @return {?}
  2607. */
  2608. setErrors(errors, opts = {}) {
  2609. (/** @type {?} */ (this)).errors = errors;
  2610. this._updateControlsErrors(opts.emitEvent !== false);
  2611. }
  2612. /**
  2613. * Retrieves a child control given the control's name or path.
  2614. *
  2615. * Paths can be passed in as an array or a string delimited by a dot.
  2616. *
  2617. * To get a control nested within a `person` sub-group:
  2618. *
  2619. * * `this.form.get('person.name');`
  2620. *
  2621. * -OR-
  2622. *
  2623. * * `this.form.get(['person', 'name']);`
  2624. * @param {?} path
  2625. * @return {?}
  2626. */
  2627. get(path) { return _find(this, path, '.'); }
  2628. /**
  2629. * Returns error data if the control with the given path has the error specified. Otherwise
  2630. * returns null or undefined.
  2631. *
  2632. * If no path is given, it checks for the error on the present control.
  2633. * @param {?} errorCode
  2634. * @param {?=} path
  2635. * @return {?}
  2636. */
  2637. getError(errorCode, path) {
  2638. const /** @type {?} */ control = path ? this.get(path) : this;
  2639. return control && control.errors ? control.errors[errorCode] : null;
  2640. }
  2641. /**
  2642. * Returns true if the control with the given path has the error specified. Otherwise
  2643. * returns false.
  2644. *
  2645. * If no path is given, it checks for the error on the present control.
  2646. * @param {?} errorCode
  2647. * @param {?=} path
  2648. * @return {?}
  2649. */
  2650. hasError(errorCode, path) { return !!this.getError(errorCode, path); }
  2651. /**
  2652. * Retrieves the top-level ancestor of this control.
  2653. * @return {?}
  2654. */
  2655. get root() {
  2656. let /** @type {?} */ x = this;
  2657. while (x._parent) {
  2658. x = x._parent;
  2659. }
  2660. return x;
  2661. }
  2662. /**
  2663. * \@internal
  2664. * @param {?} emitEvent
  2665. * @return {?}
  2666. */
  2667. _updateControlsErrors(emitEvent) {
  2668. (/** @type {?} */ (this)).status = this._calculateStatus();
  2669. if (emitEvent) {
  2670. (/** @type {?} */ (this.statusChanges)).emit(this.status);
  2671. }
  2672. if (this._parent) {
  2673. this._parent._updateControlsErrors(emitEvent);
  2674. }
  2675. }
  2676. /**
  2677. * \@internal
  2678. * @return {?}
  2679. */
  2680. _initObservables() {
  2681. (/** @type {?} */ (this)).valueChanges = new EventEmitter();
  2682. (/** @type {?} */ (this)).statusChanges = new EventEmitter();
  2683. }
  2684. /**
  2685. * @return {?}
  2686. */
  2687. _calculateStatus() {
  2688. if (this._allControlsDisabled())
  2689. return DISABLED;
  2690. if (this.errors)
  2691. return INVALID;
  2692. if (this._anyControlsHaveStatus(PENDING))
  2693. return PENDING;
  2694. if (this._anyControlsHaveStatus(INVALID))
  2695. return INVALID;
  2696. return VALID;
  2697. }
  2698. /**
  2699. * \@internal
  2700. * @param {?} status
  2701. * @return {?}
  2702. */
  2703. _anyControlsHaveStatus(status) {
  2704. return this._anyControls((control) => control.status === status);
  2705. }
  2706. /**
  2707. * \@internal
  2708. * @return {?}
  2709. */
  2710. _anyControlsDirty() {
  2711. return this._anyControls((control) => control.dirty);
  2712. }
  2713. /**
  2714. * \@internal
  2715. * @return {?}
  2716. */
  2717. _anyControlsTouched() {
  2718. return this._anyControls((control) => control.touched);
  2719. }
  2720. /**
  2721. * \@internal
  2722. * @param {?=} opts
  2723. * @return {?}
  2724. */
  2725. _updatePristine(opts = {}) {
  2726. (/** @type {?} */ (this)).pristine = !this._anyControlsDirty();
  2727. if (this._parent && !opts.onlySelf) {
  2728. this._parent._updatePristine(opts);
  2729. }
  2730. }
  2731. /**
  2732. * \@internal
  2733. * @param {?=} opts
  2734. * @return {?}
  2735. */
  2736. _updateTouched(opts = {}) {
  2737. (/** @type {?} */ (this)).touched = this._anyControlsTouched();
  2738. if (this._parent && !opts.onlySelf) {
  2739. this._parent._updateTouched(opts);
  2740. }
  2741. }
  2742. /**
  2743. * \@internal
  2744. * @param {?} formState
  2745. * @return {?}
  2746. */
  2747. _isBoxedValue(formState) {
  2748. return typeof formState === 'object' && formState !== null &&
  2749. Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState;
  2750. }
  2751. /**
  2752. * \@internal
  2753. * @param {?} fn
  2754. * @return {?}
  2755. */
  2756. _registerOnCollectionChange(fn) { this._onCollectionChange = fn; }
  2757. /**
  2758. * \@internal
  2759. * @param {?=} opts
  2760. * @return {?}
  2761. */
  2762. _setUpdateStrategy(opts) {
  2763. if (isOptionsObj(opts) && (/** @type {?} */ (opts)).updateOn != null) {
  2764. this._updateOn = /** @type {?} */ (((/** @type {?} */ (opts)).updateOn));
  2765. }
  2766. }
  2767. }
  2768. /**
  2769. * \@whatItDoes Tracks the value and validation status of an individual form control.
  2770. *
  2771. * It is one of the three fundamental building blocks of Angular forms, along with
  2772. * {\@link FormGroup} and {\@link FormArray}.
  2773. *
  2774. * \@howToUse
  2775. *
  2776. * When instantiating a {\@link FormControl}, you can pass in an initial value as the
  2777. * first argument. Example:
  2778. *
  2779. * ```ts
  2780. * const ctrl = new FormControl('some value');
  2781. * console.log(ctrl.value); // 'some value'
  2782. * ```
  2783. *
  2784. * You can also initialize the control with a form state object on instantiation,
  2785. * which includes both the value and whether or not the control is disabled.
  2786. * You can't use the value key without the disabled key; both are required
  2787. * to use this way of initialization.
  2788. *
  2789. * ```ts
  2790. * const ctrl = new FormControl({value: 'n/a', disabled: true});
  2791. * console.log(ctrl.value); // 'n/a'
  2792. * console.log(ctrl.status); // 'DISABLED'
  2793. * ```
  2794. *
  2795. * The second {\@link FormControl} argument can accept one of three things:
  2796. * * a sync validator function
  2797. * * an array of sync validator functions
  2798. * * an options object containing validator and/or async validator functions
  2799. *
  2800. * Example of a single sync validator function:
  2801. *
  2802. * ```ts
  2803. * const ctrl = new FormControl('', Validators.required);
  2804. * console.log(ctrl.value); // ''
  2805. * console.log(ctrl.status); // 'INVALID'
  2806. * ```
  2807. *
  2808. * Example using options object:
  2809. *
  2810. * ```ts
  2811. * const ctrl = new FormControl('', {
  2812. * validators: Validators.required,
  2813. * asyncValidators: myAsyncValidator
  2814. * });
  2815. * ```
  2816. *
  2817. * The options object can also be used to define when the control should update.
  2818. * By default, the value and validity of a control updates whenever the value
  2819. * changes. You can configure it to update on the blur event instead by setting
  2820. * the `updateOn` option to `'blur'`.
  2821. *
  2822. * ```ts
  2823. * const c = new FormControl('', { updateOn: 'blur' });
  2824. * ```
  2825. *
  2826. * You can also set `updateOn` to `'submit'`, which will delay value and validity
  2827. * updates until the parent form of the control fires a submit event.
  2828. *
  2829. * See its superclass, {\@link AbstractControl}, for more properties and methods.
  2830. *
  2831. * * **npm package**: `\@angular/forms`
  2832. *
  2833. * \@stable
  2834. */
  2835. class FormControl extends AbstractControl {
  2836. /**
  2837. * @param {?=} formState
  2838. * @param {?=} validatorOrOpts
  2839. * @param {?=} asyncValidator
  2840. */
  2841. constructor(formState = null, validatorOrOpts, asyncValidator) {
  2842. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  2843. /**
  2844. * \@internal
  2845. */
  2846. this._onChange = [];
  2847. this._applyFormState(formState);
  2848. this._setUpdateStrategy(validatorOrOpts);
  2849. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  2850. this._initObservables();
  2851. }
  2852. /**
  2853. * Set the value of the form control to `value`.
  2854. *
  2855. * If `onlySelf` is `true`, this change will only affect the validation of this `FormControl`
  2856. * and not its parent component. This defaults to false.
  2857. *
  2858. * If `emitEvent` is `true`, this
  2859. * change will cause a `valueChanges` event on the `FormControl` to be emitted. This defaults
  2860. * to true (as it falls through to `updateValueAndValidity`).
  2861. *
  2862. * If `emitModelToViewChange` is `true`, the view will be notified about the new value
  2863. * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not
  2864. * specified.
  2865. *
  2866. * If `emitViewToModelChange` is `true`, an ngModelChange event will be fired to update the
  2867. * model. This is the default behavior if `emitViewToModelChange` is not specified.
  2868. * @param {?} value
  2869. * @param {?=} options
  2870. * @return {?}
  2871. */
  2872. setValue(value, options = {}) {
  2873. (/** @type {?} */ (this)).value = this._pendingValue = value;
  2874. if (this._onChange.length && options.emitModelToViewChange !== false) {
  2875. this._onChange.forEach((changeFn) => changeFn(this.value, options.emitViewToModelChange !== false));
  2876. }
  2877. this.updateValueAndValidity(options);
  2878. }
  2879. /**
  2880. * Patches the value of a control.
  2881. *
  2882. * This function is functionally the same as {\@link FormControl#setValue setValue} at this level.
  2883. * It exists for symmetry with {\@link FormGroup#patchValue patchValue} on `FormGroups` and
  2884. * `FormArrays`, where it does behave differently.
  2885. * @param {?} value
  2886. * @param {?=} options
  2887. * @return {?}
  2888. */
  2889. patchValue(value, options = {}) {
  2890. this.setValue(value, options);
  2891. }
  2892. /**
  2893. * Resets the form control. This means by default:
  2894. *
  2895. * * it is marked as `pristine`
  2896. * * it is marked as `untouched`
  2897. * * value is set to null
  2898. *
  2899. * You can also reset to a specific form state by passing through a standalone
  2900. * value or a form state object that contains both a value and a disabled state
  2901. * (these are the only two properties that cannot be calculated).
  2902. *
  2903. * Ex:
  2904. *
  2905. * ```ts
  2906. * this.control.reset('Nancy');
  2907. *
  2908. * console.log(this.control.value); // 'Nancy'
  2909. * ```
  2910. *
  2911. * OR
  2912. *
  2913. * ```
  2914. * this.control.reset({value: 'Nancy', disabled: true});
  2915. *
  2916. * console.log(this.control.value); // 'Nancy'
  2917. * console.log(this.control.status); // 'DISABLED'
  2918. * ```
  2919. * @param {?=} formState
  2920. * @param {?=} options
  2921. * @return {?}
  2922. */
  2923. reset(formState = null, options = {}) {
  2924. this._applyFormState(formState);
  2925. this.markAsPristine(options);
  2926. this.markAsUntouched(options);
  2927. this.setValue(this.value, options);
  2928. this._pendingChange = false;
  2929. }
  2930. /**
  2931. * \@internal
  2932. * @return {?}
  2933. */
  2934. _updateValue() { }
  2935. /**
  2936. * \@internal
  2937. * @param {?} condition
  2938. * @return {?}
  2939. */
  2940. _anyControls(condition) { return false; }
  2941. /**
  2942. * \@internal
  2943. * @return {?}
  2944. */
  2945. _allControlsDisabled() { return this.disabled; }
  2946. /**
  2947. * Register a listener for change events.
  2948. * @param {?} fn
  2949. * @return {?}
  2950. */
  2951. registerOnChange(fn) { this._onChange.push(fn); }
  2952. /**
  2953. * \@internal
  2954. * @return {?}
  2955. */
  2956. _clearChangeFns() {
  2957. this._onChange = [];
  2958. this._onDisabledChange = [];
  2959. this._onCollectionChange = () => { };
  2960. }
  2961. /**
  2962. * Register a listener for disabled events.
  2963. * @param {?} fn
  2964. * @return {?}
  2965. */
  2966. registerOnDisabledChange(fn) {
  2967. this._onDisabledChange.push(fn);
  2968. }
  2969. /**
  2970. * \@internal
  2971. * @param {?} cb
  2972. * @return {?}
  2973. */
  2974. _forEachChild(cb) { }
  2975. /**
  2976. * \@internal
  2977. * @return {?}
  2978. */
  2979. _syncPendingControls() {
  2980. if (this.updateOn === 'submit') {
  2981. if (this._pendingDirty)
  2982. this.markAsDirty();
  2983. if (this._pendingTouched)
  2984. this.markAsTouched();
  2985. if (this._pendingChange) {
  2986. this.setValue(this._pendingValue, { onlySelf: true, emitModelToViewChange: false });
  2987. return true;
  2988. }
  2989. }
  2990. return false;
  2991. }
  2992. /**
  2993. * @param {?} formState
  2994. * @return {?}
  2995. */
  2996. _applyFormState(formState) {
  2997. if (this._isBoxedValue(formState)) {
  2998. (/** @type {?} */ (this)).value = this._pendingValue = formState.value;
  2999. formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) :
  3000. this.enable({ onlySelf: true, emitEvent: false });
  3001. }
  3002. else {
  3003. (/** @type {?} */ (this)).value = this._pendingValue = formState;
  3004. }
  3005. }
  3006. }
  3007. /**
  3008. * \@whatItDoes Tracks the value and validity state of a group of {\@link FormControl}
  3009. * instances.
  3010. *
  3011. * A `FormGroup` aggregates the values of each child {\@link FormControl} into one object,
  3012. * with each control name as the key. It calculates its status by reducing the statuses
  3013. * of its children. For example, if one of the controls in a group is invalid, the entire
  3014. * group becomes invalid.
  3015. *
  3016. * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular,
  3017. * along with {\@link FormControl} and {\@link FormArray}.
  3018. *
  3019. * \@howToUse
  3020. *
  3021. * When instantiating a {\@link FormGroup}, pass in a collection of child controls as the first
  3022. * argument. The key for each child will be the name under which it is registered.
  3023. *
  3024. * ### Example
  3025. *
  3026. * ```
  3027. * const form = new FormGroup({
  3028. * first: new FormControl('Nancy', Validators.minLength(2)),
  3029. * last: new FormControl('Drew'),
  3030. * });
  3031. *
  3032. * console.log(form.value); // {first: 'Nancy', last; 'Drew'}
  3033. * console.log(form.status); // 'VALID'
  3034. * ```
  3035. *
  3036. * You can also include group-level validators as the second arg, or group-level async
  3037. * validators as the third arg. These come in handy when you want to perform validation
  3038. * that considers the value of more than one child control.
  3039. *
  3040. * ### Example
  3041. *
  3042. * ```
  3043. * const form = new FormGroup({
  3044. * password: new FormControl('', Validators.minLength(2)),
  3045. * passwordConfirm: new FormControl('', Validators.minLength(2)),
  3046. * }, passwordMatchValidator);
  3047. *
  3048. *
  3049. * function passwordMatchValidator(g: FormGroup) {
  3050. * return g.get('password').value === g.get('passwordConfirm').value
  3051. * ? null : {'mismatch': true};
  3052. * }
  3053. * ```
  3054. *
  3055. * Like {\@link FormControl} instances, you can alternatively choose to pass in
  3056. * validators and async validators as part of an options object.
  3057. *
  3058. * ```
  3059. * const form = new FormGroup({
  3060. * password: new FormControl('')
  3061. * passwordConfirm: new FormControl('')
  3062. * }, {validators: passwordMatchValidator, asyncValidators: otherValidator});
  3063. * ```
  3064. *
  3065. * The options object can also be used to set a default value for each child
  3066. * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
  3067. * group level, all child controls will default to 'blur', unless the child
  3068. * has explicitly specified a different `updateOn` value.
  3069. *
  3070. * ```ts
  3071. * const c = new FormGroup({
  3072. * one: new FormControl()
  3073. * }, {updateOn: 'blur'});
  3074. * ```
  3075. *
  3076. * * **npm package**: `\@angular/forms`
  3077. *
  3078. * \@stable
  3079. */
  3080. class FormGroup extends AbstractControl {
  3081. /**
  3082. * @param {?} controls
  3083. * @param {?=} validatorOrOpts
  3084. * @param {?=} asyncValidator
  3085. */
  3086. constructor(controls, validatorOrOpts, asyncValidator) {
  3087. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  3088. this.controls = controls;
  3089. this._initObservables();
  3090. this._setUpdateStrategy(validatorOrOpts);
  3091. this._setUpControls();
  3092. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  3093. }
  3094. /**
  3095. * Registers a control with the group's list of controls.
  3096. *
  3097. * This method does not update the value or validity of the control, so for most cases you'll want
  3098. * to use {\@link FormGroup#addControl addControl} instead.
  3099. * @param {?} name
  3100. * @param {?} control
  3101. * @return {?}
  3102. */
  3103. registerControl(name, control) {
  3104. if (this.controls[name])
  3105. return this.controls[name];
  3106. this.controls[name] = control;
  3107. control.setParent(this);
  3108. control._registerOnCollectionChange(this._onCollectionChange);
  3109. return control;
  3110. }
  3111. /**
  3112. * Add a control to this group.
  3113. * @param {?} name
  3114. * @param {?} control
  3115. * @return {?}
  3116. */
  3117. addControl(name, control) {
  3118. this.registerControl(name, control);
  3119. this.updateValueAndValidity();
  3120. this._onCollectionChange();
  3121. }
  3122. /**
  3123. * Remove a control from this group.
  3124. * @param {?} name
  3125. * @return {?}
  3126. */
  3127. removeControl(name) {
  3128. if (this.controls[name])
  3129. this.controls[name]._registerOnCollectionChange(() => { });
  3130. delete (this.controls[name]);
  3131. this.updateValueAndValidity();
  3132. this._onCollectionChange();
  3133. }
  3134. /**
  3135. * Replace an existing control.
  3136. * @param {?} name
  3137. * @param {?} control
  3138. * @return {?}
  3139. */
  3140. setControl(name, control) {
  3141. if (this.controls[name])
  3142. this.controls[name]._registerOnCollectionChange(() => { });
  3143. delete (this.controls[name]);
  3144. if (control)
  3145. this.registerControl(name, control);
  3146. this.updateValueAndValidity();
  3147. this._onCollectionChange();
  3148. }
  3149. /**
  3150. * Check whether there is an enabled control with the given name in the group.
  3151. *
  3152. * It will return false for disabled controls. If you'd like to check for existence in the group
  3153. * only, use {\@link AbstractControl#get get} instead.
  3154. * @param {?} controlName
  3155. * @return {?}
  3156. */
  3157. contains(controlName) {
  3158. return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled;
  3159. }
  3160. /**
  3161. * Sets the value of the {\@link FormGroup}. It accepts an object that matches
  3162. * the structure of the group, with control names as keys.
  3163. *
  3164. * This method performs strict checks, so it will throw an error if you try
  3165. * to set the value of a control that doesn't exist or if you exclude the
  3166. * value of a control.
  3167. *
  3168. * ### Example
  3169. *
  3170. * ```
  3171. * const form = new FormGroup({
  3172. * first: new FormControl(),
  3173. * last: new FormControl()
  3174. * });
  3175. * console.log(form.value); // {first: null, last: null}
  3176. *
  3177. * form.setValue({first: 'Nancy', last: 'Drew'});
  3178. * console.log(form.value); // {first: 'Nancy', last: 'Drew'}
  3179. *
  3180. * ```
  3181. * @param {?} value
  3182. * @param {?=} options
  3183. * @return {?}
  3184. */
  3185. setValue(value, options = {}) {
  3186. this._checkAllValuesPresent(value);
  3187. Object.keys(value).forEach(name => {
  3188. this._throwIfControlMissing(name);
  3189. this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  3190. });
  3191. this.updateValueAndValidity(options);
  3192. }
  3193. /**
  3194. * Patches the value of the {\@link FormGroup}. It accepts an object with control
  3195. * names as keys, and will do its best to match the values to the correct controls
  3196. * in the group.
  3197. *
  3198. * It accepts both super-sets and sub-sets of the group without throwing an error.
  3199. *
  3200. * ### Example
  3201. *
  3202. * ```
  3203. * const form = new FormGroup({
  3204. * first: new FormControl(),
  3205. * last: new FormControl()
  3206. * });
  3207. * console.log(form.value); // {first: null, last: null}
  3208. *
  3209. * form.patchValue({first: 'Nancy'});
  3210. * console.log(form.value); // {first: 'Nancy', last: null}
  3211. *
  3212. * ```
  3213. * @param {?} value
  3214. * @param {?=} options
  3215. * @return {?}
  3216. */
  3217. patchValue(value, options = {}) {
  3218. Object.keys(value).forEach(name => {
  3219. if (this.controls[name]) {
  3220. this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  3221. }
  3222. });
  3223. this.updateValueAndValidity(options);
  3224. }
  3225. /**
  3226. * Resets the {\@link FormGroup}. This means by default:
  3227. *
  3228. * * The group and all descendants are marked `pristine`
  3229. * * The group and all descendants are marked `untouched`
  3230. * * The value of all descendants will be null or null maps
  3231. *
  3232. * You can also reset to a specific form state by passing in a map of states
  3233. * that matches the structure of your form, with control names as keys. The state
  3234. * can be a standalone value or a form state object with both a value and a disabled
  3235. * status.
  3236. *
  3237. * ### Example
  3238. *
  3239. * ```ts
  3240. * this.form.reset({first: 'name', last: 'last name'});
  3241. *
  3242. * console.log(this.form.value); // {first: 'name', last: 'last name'}
  3243. * ```
  3244. *
  3245. * - OR -
  3246. *
  3247. * ```
  3248. * this.form.reset({
  3249. * first: {value: 'name', disabled: true},
  3250. * last: 'last'
  3251. * });
  3252. *
  3253. * console.log(this.form.value); // {first: 'name', last: 'last name'}
  3254. * console.log(this.form.get('first').status); // 'DISABLED'
  3255. * ```
  3256. * @param {?=} value
  3257. * @param {?=} options
  3258. * @return {?}
  3259. */
  3260. reset(value = {}, options = {}) {
  3261. this._forEachChild((control, name) => {
  3262. control.reset(value[name], { onlySelf: true, emitEvent: options.emitEvent });
  3263. });
  3264. this.updateValueAndValidity(options);
  3265. this._updatePristine(options);
  3266. this._updateTouched(options);
  3267. }
  3268. /**
  3269. * The aggregate value of the {\@link FormGroup}, including any disabled controls.
  3270. *
  3271. * If you'd like to include all values regardless of disabled status, use this method.
  3272. * Otherwise, the `value` property is the best way to get the value of the group.
  3273. * @return {?}
  3274. */
  3275. getRawValue() {
  3276. return this._reduceChildren({}, (acc, control, name) => {
  3277. acc[name] = control instanceof FormControl ? control.value : (/** @type {?} */ (control)).getRawValue();
  3278. return acc;
  3279. });
  3280. }
  3281. /**
  3282. * \@internal
  3283. * @return {?}
  3284. */
  3285. _syncPendingControls() {
  3286. let /** @type {?} */ subtreeUpdated = this._reduceChildren(false, (updated, child) => {
  3287. return child._syncPendingControls() ? true : updated;
  3288. });
  3289. if (subtreeUpdated)
  3290. this.updateValueAndValidity({ onlySelf: true });
  3291. return subtreeUpdated;
  3292. }
  3293. /**
  3294. * \@internal
  3295. * @param {?} name
  3296. * @return {?}
  3297. */
  3298. _throwIfControlMissing(name) {
  3299. if (!Object.keys(this.controls).length) {
  3300. throw new Error(`
  3301. There are no form controls registered with this group yet. If you're using ngModel,
  3302. you may want to check next tick (e.g. use setTimeout).
  3303. `);
  3304. }
  3305. if (!this.controls[name]) {
  3306. throw new Error(`Cannot find form control with name: ${name}.`);
  3307. }
  3308. }
  3309. /**
  3310. * \@internal
  3311. * @param {?} cb
  3312. * @return {?}
  3313. */
  3314. _forEachChild(cb) {
  3315. Object.keys(this.controls).forEach(k => cb(this.controls[k], k));
  3316. }
  3317. /**
  3318. * \@internal
  3319. * @return {?}
  3320. */
  3321. _setUpControls() {
  3322. this._forEachChild((control) => {
  3323. control.setParent(this);
  3324. control._registerOnCollectionChange(this._onCollectionChange);
  3325. });
  3326. }
  3327. /**
  3328. * \@internal
  3329. * @return {?}
  3330. */
  3331. _updateValue() { (/** @type {?} */ (this)).value = this._reduceValue(); }
  3332. /**
  3333. * \@internal
  3334. * @param {?} condition
  3335. * @return {?}
  3336. */
  3337. _anyControls(condition) {
  3338. let /** @type {?} */ res = false;
  3339. this._forEachChild((control, name) => {
  3340. res = res || (this.contains(name) && condition(control));
  3341. });
  3342. return res;
  3343. }
  3344. /**
  3345. * \@internal
  3346. * @return {?}
  3347. */
  3348. _reduceValue() {
  3349. return this._reduceChildren({}, (acc, control, name) => {
  3350. if (control.enabled || this.disabled) {
  3351. acc[name] = control.value;
  3352. }
  3353. return acc;
  3354. });
  3355. }
  3356. /**
  3357. * \@internal
  3358. * @param {?} initValue
  3359. * @param {?} fn
  3360. * @return {?}
  3361. */
  3362. _reduceChildren(initValue, fn) {
  3363. let /** @type {?} */ res = initValue;
  3364. this._forEachChild((control, name) => { res = fn(res, control, name); });
  3365. return res;
  3366. }
  3367. /**
  3368. * \@internal
  3369. * @return {?}
  3370. */
  3371. _allControlsDisabled() {
  3372. for (const /** @type {?} */ controlName of Object.keys(this.controls)) {
  3373. if (this.controls[controlName].enabled) {
  3374. return false;
  3375. }
  3376. }
  3377. return Object.keys(this.controls).length > 0 || this.disabled;
  3378. }
  3379. /**
  3380. * \@internal
  3381. * @param {?} value
  3382. * @return {?}
  3383. */
  3384. _checkAllValuesPresent(value) {
  3385. this._forEachChild((control, name) => {
  3386. if (value[name] === undefined) {
  3387. throw new Error(`Must supply a value for form control with name: '${name}'.`);
  3388. }
  3389. });
  3390. }
  3391. }
  3392. /**
  3393. * \@whatItDoes Tracks the value and validity state of an array of {\@link FormControl},
  3394. * {\@link FormGroup} or {\@link FormArray} instances.
  3395. *
  3396. * A `FormArray` aggregates the values of each child {\@link FormControl} into an array.
  3397. * It calculates its status by reducing the statuses of its children. For example, if one of
  3398. * the controls in a `FormArray` is invalid, the entire array becomes invalid.
  3399. *
  3400. * `FormArray` is one of the three fundamental building blocks used to define forms in Angular,
  3401. * along with {\@link FormControl} and {\@link FormGroup}.
  3402. *
  3403. * \@howToUse
  3404. *
  3405. * When instantiating a {\@link FormArray}, pass in an array of child controls as the first
  3406. * argument.
  3407. *
  3408. * ### Example
  3409. *
  3410. * ```
  3411. * const arr = new FormArray([
  3412. * new FormControl('Nancy', Validators.minLength(2)),
  3413. * new FormControl('Drew'),
  3414. * ]);
  3415. *
  3416. * console.log(arr.value); // ['Nancy', 'Drew']
  3417. * console.log(arr.status); // 'VALID'
  3418. * ```
  3419. *
  3420. * You can also include array-level validators and async validators. These come in handy
  3421. * when you want to perform validation that considers the value of more than one child
  3422. * control.
  3423. *
  3424. * The two types of validators can be passed in separately as the second and third arg
  3425. * respectively, or together as part of an options object.
  3426. *
  3427. * ```
  3428. * const arr = new FormArray([
  3429. * new FormControl('Nancy'),
  3430. * new FormControl('Drew')
  3431. * ], {validators: myValidator, asyncValidators: myAsyncValidator});
  3432. * ```
  3433. *
  3434. * The options object can also be used to set a default value for each child
  3435. * control's `updateOn` property. If you set `updateOn` to `'blur'` at the
  3436. * array level, all child controls will default to 'blur', unless the child
  3437. * has explicitly specified a different `updateOn` value.
  3438. *
  3439. * ```ts
  3440. * const c = new FormArray([
  3441. * new FormControl()
  3442. * ], {updateOn: 'blur'});
  3443. * ```
  3444. *
  3445. * ### Adding or removing controls
  3446. *
  3447. * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods
  3448. * in `FormArray` itself. These methods ensure the controls are properly tracked in the
  3449. * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate
  3450. * the `FormArray` directly, as that will result in strange and unexpected behavior such
  3451. * as broken change detection.
  3452. *
  3453. * * **npm package**: `\@angular/forms`
  3454. *
  3455. * \@stable
  3456. */
  3457. class FormArray extends AbstractControl {
  3458. /**
  3459. * @param {?} controls
  3460. * @param {?=} validatorOrOpts
  3461. * @param {?=} asyncValidator
  3462. */
  3463. constructor(controls, validatorOrOpts, asyncValidator) {
  3464. super(coerceToValidator(validatorOrOpts), coerceToAsyncValidator(asyncValidator, validatorOrOpts));
  3465. this.controls = controls;
  3466. this._initObservables();
  3467. this._setUpdateStrategy(validatorOrOpts);
  3468. this._setUpControls();
  3469. this.updateValueAndValidity({ onlySelf: true, emitEvent: false });
  3470. }
  3471. /**
  3472. * Get the {\@link AbstractControl} at the given `index` in the array.
  3473. * @param {?} index
  3474. * @return {?}
  3475. */
  3476. at(index) { return this.controls[index]; }
  3477. /**
  3478. * Insert a new {\@link AbstractControl} at the end of the array.
  3479. * @param {?} control
  3480. * @return {?}
  3481. */
  3482. push(control) {
  3483. this.controls.push(control);
  3484. this._registerControl(control);
  3485. this.updateValueAndValidity();
  3486. this._onCollectionChange();
  3487. }
  3488. /**
  3489. * Insert a new {\@link AbstractControl} at the given `index` in the array.
  3490. * @param {?} index
  3491. * @param {?} control
  3492. * @return {?}
  3493. */
  3494. insert(index, control) {
  3495. this.controls.splice(index, 0, control);
  3496. this._registerControl(control);
  3497. this.updateValueAndValidity();
  3498. }
  3499. /**
  3500. * Remove the control at the given `index` in the array.
  3501. * @param {?} index
  3502. * @return {?}
  3503. */
  3504. removeAt(index) {
  3505. if (this.controls[index])
  3506. this.controls[index]._registerOnCollectionChange(() => { });
  3507. this.controls.splice(index, 1);
  3508. this.updateValueAndValidity();
  3509. }
  3510. /**
  3511. * Replace an existing control.
  3512. * @param {?} index
  3513. * @param {?} control
  3514. * @return {?}
  3515. */
  3516. setControl(index, control) {
  3517. if (this.controls[index])
  3518. this.controls[index]._registerOnCollectionChange(() => { });
  3519. this.controls.splice(index, 1);
  3520. if (control) {
  3521. this.controls.splice(index, 0, control);
  3522. this._registerControl(control);
  3523. }
  3524. this.updateValueAndValidity();
  3525. this._onCollectionChange();
  3526. }
  3527. /**
  3528. * Length of the control array.
  3529. * @return {?}
  3530. */
  3531. get length() { return this.controls.length; }
  3532. /**
  3533. * Sets the value of the {\@link FormArray}. It accepts an array that matches
  3534. * the structure of the control.
  3535. *
  3536. * This method performs strict checks, so it will throw an error if you try
  3537. * to set the value of a control that doesn't exist or if you exclude the
  3538. * value of a control.
  3539. *
  3540. * ### Example
  3541. *
  3542. * ```
  3543. * const arr = new FormArray([
  3544. * new FormControl(),
  3545. * new FormControl()
  3546. * ]);
  3547. * console.log(arr.value); // [null, null]
  3548. *
  3549. * arr.setValue(['Nancy', 'Drew']);
  3550. * console.log(arr.value); // ['Nancy', 'Drew']
  3551. * ```
  3552. * @param {?} value
  3553. * @param {?=} options
  3554. * @return {?}
  3555. */
  3556. setValue(value, options = {}) {
  3557. this._checkAllValuesPresent(value);
  3558. value.forEach((newValue, index) => {
  3559. this._throwIfControlMissing(index);
  3560. this.at(index).setValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  3561. });
  3562. this.updateValueAndValidity(options);
  3563. }
  3564. /**
  3565. * Patches the value of the {\@link FormArray}. It accepts an array that matches the
  3566. * structure of the control, and will do its best to match the values to the correct
  3567. * controls in the group.
  3568. *
  3569. * It accepts both super-sets and sub-sets of the array without throwing an error.
  3570. *
  3571. * ### Example
  3572. *
  3573. * ```
  3574. * const arr = new FormArray([
  3575. * new FormControl(),
  3576. * new FormControl()
  3577. * ]);
  3578. * console.log(arr.value); // [null, null]
  3579. *
  3580. * arr.patchValue(['Nancy']);
  3581. * console.log(arr.value); // ['Nancy', null]
  3582. * ```
  3583. * @param {?} value
  3584. * @param {?=} options
  3585. * @return {?}
  3586. */
  3587. patchValue(value, options = {}) {
  3588. value.forEach((newValue, index) => {
  3589. if (this.at(index)) {
  3590. this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: options.emitEvent });
  3591. }
  3592. });
  3593. this.updateValueAndValidity(options);
  3594. }
  3595. /**
  3596. * Resets the {\@link FormArray}. This means by default:
  3597. *
  3598. * * The array and all descendants are marked `pristine`
  3599. * * The array and all descendants are marked `untouched`
  3600. * * The value of all descendants will be null or null maps
  3601. *
  3602. * You can also reset to a specific form state by passing in an array of states
  3603. * that matches the structure of the control. The state can be a standalone value
  3604. * or a form state object with both a value and a disabled status.
  3605. *
  3606. * ### Example
  3607. *
  3608. * ```ts
  3609. * this.arr.reset(['name', 'last name']);
  3610. *
  3611. * console.log(this.arr.value); // ['name', 'last name']
  3612. * ```
  3613. *
  3614. * - OR -
  3615. *
  3616. * ```
  3617. * this.arr.reset([
  3618. * {value: 'name', disabled: true},
  3619. * 'last'
  3620. * ]);
  3621. *
  3622. * console.log(this.arr.value); // ['name', 'last name']
  3623. * console.log(this.arr.get(0).status); // 'DISABLED'
  3624. * ```
  3625. * @param {?=} value
  3626. * @param {?=} options
  3627. * @return {?}
  3628. */
  3629. reset(value = [], options = {}) {
  3630. this._forEachChild((control, index) => {
  3631. control.reset(value[index], { onlySelf: true, emitEvent: options.emitEvent });
  3632. });
  3633. this.updateValueAndValidity(options);
  3634. this._updatePristine(options);
  3635. this._updateTouched(options);
  3636. }
  3637. /**
  3638. * The aggregate value of the array, including any disabled controls.
  3639. *
  3640. * If you'd like to include all values regardless of disabled status, use this method.
  3641. * Otherwise, the `value` property is the best way to get the value of the array.
  3642. * @return {?}
  3643. */
  3644. getRawValue() {
  3645. return this.controls.map((control) => {
  3646. return control instanceof FormControl ? control.value : (/** @type {?} */ (control)).getRawValue();
  3647. });
  3648. }
  3649. /**
  3650. * \@internal
  3651. * @return {?}
  3652. */
  3653. _syncPendingControls() {
  3654. let /** @type {?} */ subtreeUpdated = this.controls.reduce((updated, child) => {
  3655. return child._syncPendingControls() ? true : updated;
  3656. }, false);
  3657. if (subtreeUpdated)
  3658. this.updateValueAndValidity({ onlySelf: true });
  3659. return subtreeUpdated;
  3660. }
  3661. /**
  3662. * \@internal
  3663. * @param {?} index
  3664. * @return {?}
  3665. */
  3666. _throwIfControlMissing(index) {
  3667. if (!this.controls.length) {
  3668. throw new Error(`
  3669. There are no form controls registered with this array yet. If you're using ngModel,
  3670. you may want to check next tick (e.g. use setTimeout).
  3671. `);
  3672. }
  3673. if (!this.at(index)) {
  3674. throw new Error(`Cannot find form control at index ${index}`);
  3675. }
  3676. }
  3677. /**
  3678. * \@internal
  3679. * @param {?} cb
  3680. * @return {?}
  3681. */
  3682. _forEachChild(cb) {
  3683. this.controls.forEach((control, index) => { cb(control, index); });
  3684. }
  3685. /**
  3686. * \@internal
  3687. * @return {?}
  3688. */
  3689. _updateValue() {
  3690. (/** @type {?} */ (this)).value =
  3691. this.controls.filter((control) => control.enabled || this.disabled)
  3692. .map((control) => control.value);
  3693. }
  3694. /**
  3695. * \@internal
  3696. * @param {?} condition
  3697. * @return {?}
  3698. */
  3699. _anyControls(condition) {
  3700. return this.controls.some((control) => control.enabled && condition(control));
  3701. }
  3702. /**
  3703. * \@internal
  3704. * @return {?}
  3705. */
  3706. _setUpControls() {
  3707. this._forEachChild((control) => this._registerControl(control));
  3708. }
  3709. /**
  3710. * \@internal
  3711. * @param {?} value
  3712. * @return {?}
  3713. */
  3714. _checkAllValuesPresent(value) {
  3715. this._forEachChild((control, i) => {
  3716. if (value[i] === undefined) {
  3717. throw new Error(`Must supply a value for form control at index: ${i}.`);
  3718. }
  3719. });
  3720. }
  3721. /**
  3722. * \@internal
  3723. * @return {?}
  3724. */
  3725. _allControlsDisabled() {
  3726. for (const /** @type {?} */ control of this.controls) {
  3727. if (control.enabled)
  3728. return false;
  3729. }
  3730. return this.controls.length > 0 || this.disabled;
  3731. }
  3732. /**
  3733. * @param {?} control
  3734. * @return {?}
  3735. */
  3736. _registerControl(control) {
  3737. control.setParent(this);
  3738. control._registerOnCollectionChange(this._onCollectionChange);
  3739. }
  3740. }
  3741. /**
  3742. * @fileoverview added by tsickle
  3743. * @suppress {checkTypes} checked by tsc
  3744. */
  3745. /**
  3746. * @license
  3747. * Copyright Google Inc. All Rights Reserved.
  3748. *
  3749. * Use of this source code is governed by an MIT-style license that can be
  3750. * found in the LICENSE file at https://angular.io/license
  3751. */
  3752. const formDirectiveProvider = {
  3753. provide: ControlContainer,
  3754. useExisting: forwardRef(() => NgForm)
  3755. };
  3756. const resolvedPromise = Promise.resolve(null);
  3757. /**
  3758. * \@whatItDoes Creates a top-level {\@link FormGroup} instance and binds it to a form
  3759. * to track aggregate form value and validation status.
  3760. *
  3761. * \@howToUse
  3762. *
  3763. * As soon as you import the `FormsModule`, this directive becomes active by default on
  3764. * all `<form>` tags. You don't need to add a special selector.
  3765. *
  3766. * You can export the directive into a local template variable using `ngForm` as the key
  3767. * (ex: `#myForm="ngForm"`). This is optional, but useful. Many properties from the underlying
  3768. * {\@link FormGroup} instance are duplicated on the directive itself, so a reference to it
  3769. * will give you access to the aggregate value and validity status of the form, as well as
  3770. * user interaction properties like `dirty` and `touched`.
  3771. *
  3772. * To register child controls with the form, you'll want to use {\@link NgModel} with a
  3773. * `name` attribute. You can also use {\@link NgModelGroup} if you'd like to create
  3774. * sub-groups within the form.
  3775. *
  3776. * You can listen to the directive's `ngSubmit` event to be notified when the user has
  3777. * triggered a form submission. The `ngSubmit` event will be emitted with the original form
  3778. * submission event.
  3779. *
  3780. * In template driven forms, all `<form>` tags are automatically tagged as `NgForm`.
  3781. * If you want to import the `FormsModule` but skip its usage in some forms,
  3782. * for example, to use native HTML5 validation, you can add `ngNoForm` and the `<form>`
  3783. * tags won't create an `NgForm` directive. In reactive forms, using `ngNoForm` is
  3784. * unnecessary because the `<form>` tags are inert. In that case, you would
  3785. * refrain from using the `formGroup` directive.
  3786. *
  3787. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  3788. *
  3789. * * **npm package**: `\@angular/forms`
  3790. *
  3791. * * **NgModule**: `FormsModule`
  3792. *
  3793. * \@stable
  3794. */
  3795. class NgForm extends ControlContainer {
  3796. /**
  3797. * @param {?} validators
  3798. * @param {?} asyncValidators
  3799. */
  3800. constructor(validators, asyncValidators) {
  3801. super();
  3802. this.submitted = false;
  3803. this._directives = [];
  3804. this.ngSubmit = new EventEmitter();
  3805. this.form =
  3806. new FormGroup({}, composeValidators(validators), composeAsyncValidators(asyncValidators));
  3807. }
  3808. /**
  3809. * @return {?}
  3810. */
  3811. ngAfterViewInit() { this._setUpdateStrategy(); }
  3812. /**
  3813. * @return {?}
  3814. */
  3815. get formDirective() { return this; }
  3816. /**
  3817. * @return {?}
  3818. */
  3819. get control() { return this.form; }
  3820. /**
  3821. * @return {?}
  3822. */
  3823. get path() { return []; }
  3824. /**
  3825. * @return {?}
  3826. */
  3827. get controls() { return this.form.controls; }
  3828. /**
  3829. * @param {?} dir
  3830. * @return {?}
  3831. */
  3832. addControl(dir) {
  3833. resolvedPromise.then(() => {
  3834. const /** @type {?} */ container = this._findContainer(dir.path);
  3835. (/** @type {?} */ (dir)).control = /** @type {?} */ (container.registerControl(dir.name, dir.control));
  3836. setUpControl(dir.control, dir);
  3837. dir.control.updateValueAndValidity({ emitEvent: false });
  3838. this._directives.push(dir);
  3839. });
  3840. }
  3841. /**
  3842. * @param {?} dir
  3843. * @return {?}
  3844. */
  3845. getControl(dir) { return /** @type {?} */ (this.form.get(dir.path)); }
  3846. /**
  3847. * @param {?} dir
  3848. * @return {?}
  3849. */
  3850. removeControl(dir) {
  3851. resolvedPromise.then(() => {
  3852. const /** @type {?} */ container = this._findContainer(dir.path);
  3853. if (container) {
  3854. container.removeControl(dir.name);
  3855. }
  3856. removeDir(this._directives, dir);
  3857. });
  3858. }
  3859. /**
  3860. * @param {?} dir
  3861. * @return {?}
  3862. */
  3863. addFormGroup(dir) {
  3864. resolvedPromise.then(() => {
  3865. const /** @type {?} */ container = this._findContainer(dir.path);
  3866. const /** @type {?} */ group = new FormGroup({});
  3867. setUpFormContainer(group, dir);
  3868. container.registerControl(dir.name, group);
  3869. group.updateValueAndValidity({ emitEvent: false });
  3870. });
  3871. }
  3872. /**
  3873. * @param {?} dir
  3874. * @return {?}
  3875. */
  3876. removeFormGroup(dir) {
  3877. resolvedPromise.then(() => {
  3878. const /** @type {?} */ container = this._findContainer(dir.path);
  3879. if (container) {
  3880. container.removeControl(dir.name);
  3881. }
  3882. });
  3883. }
  3884. /**
  3885. * @param {?} dir
  3886. * @return {?}
  3887. */
  3888. getFormGroup(dir) { return /** @type {?} */ (this.form.get(dir.path)); }
  3889. /**
  3890. * @param {?} dir
  3891. * @param {?} value
  3892. * @return {?}
  3893. */
  3894. updateModel(dir, value) {
  3895. resolvedPromise.then(() => {
  3896. const /** @type {?} */ ctrl = /** @type {?} */ (this.form.get(/** @type {?} */ ((dir.path))));
  3897. ctrl.setValue(value);
  3898. });
  3899. }
  3900. /**
  3901. * @param {?} value
  3902. * @return {?}
  3903. */
  3904. setValue(value) { this.control.setValue(value); }
  3905. /**
  3906. * @param {?} $event
  3907. * @return {?}
  3908. */
  3909. onSubmit($event) {
  3910. (/** @type {?} */ (this)).submitted = true;
  3911. syncPendingControls(this.form, this._directives);
  3912. this.ngSubmit.emit($event);
  3913. return false;
  3914. }
  3915. /**
  3916. * @return {?}
  3917. */
  3918. onReset() { this.resetForm(); }
  3919. /**
  3920. * @param {?=} value
  3921. * @return {?}
  3922. */
  3923. resetForm(value = undefined) {
  3924. this.form.reset(value);
  3925. (/** @type {?} */ (this)).submitted = false;
  3926. }
  3927. /**
  3928. * @return {?}
  3929. */
  3930. _setUpdateStrategy() {
  3931. if (this.options && this.options.updateOn != null) {
  3932. this.form._updateOn = this.options.updateOn;
  3933. }
  3934. }
  3935. /**
  3936. * \@internal
  3937. * @param {?} path
  3938. * @return {?}
  3939. */
  3940. _findContainer(path) {
  3941. path.pop();
  3942. return path.length ? /** @type {?} */ (this.form.get(path)) : this.form;
  3943. }
  3944. }
  3945. NgForm.decorators = [
  3946. { type: Directive, args: [{
  3947. selector: 'form:not([ngNoForm]):not([formGroup]),ngForm,[ngForm]',
  3948. providers: [formDirectiveProvider],
  3949. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  3950. outputs: ['ngSubmit'],
  3951. exportAs: 'ngForm'
  3952. },] },
  3953. ];
  3954. /** @nocollapse */
  3955. NgForm.ctorParameters = () => [
  3956. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  3957. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  3958. ];
  3959. NgForm.propDecorators = {
  3960. "options": [{ type: Input, args: ['ngFormOptions',] },],
  3961. };
  3962. /**
  3963. * @fileoverview added by tsickle
  3964. * @suppress {checkTypes} checked by tsc
  3965. */
  3966. /**
  3967. * @license
  3968. * Copyright Google Inc. All Rights Reserved.
  3969. *
  3970. * Use of this source code is governed by an MIT-style license that can be
  3971. * found in the LICENSE file at https://angular.io/license
  3972. */
  3973. const FormErrorExamples = {
  3974. formControlName: `
  3975. <div [formGroup]="myGroup">
  3976. <input formControlName="firstName">
  3977. </div>
  3978. In your class:
  3979. this.myGroup = new FormGroup({
  3980. firstName: new FormControl()
  3981. });`,
  3982. formGroupName: `
  3983. <div [formGroup]="myGroup">
  3984. <div formGroupName="person">
  3985. <input formControlName="firstName">
  3986. </div>
  3987. </div>
  3988. In your class:
  3989. this.myGroup = new FormGroup({
  3990. person: new FormGroup({ firstName: new FormControl() })
  3991. });`,
  3992. formArrayName: `
  3993. <div [formGroup]="myGroup">
  3994. <div formArrayName="cities">
  3995. <div *ngFor="let city of cityArray.controls; index as i">
  3996. <input [formControlName]="i">
  3997. </div>
  3998. </div>
  3999. </div>
  4000. In your class:
  4001. this.cityArray = new FormArray([new FormControl('SF')]);
  4002. this.myGroup = new FormGroup({
  4003. cities: this.cityArray
  4004. });`,
  4005. ngModelGroup: `
  4006. <form>
  4007. <div ngModelGroup="person">
  4008. <input [(ngModel)]="person.name" name="firstName">
  4009. </div>
  4010. </form>`,
  4011. ngModelWithFormGroup: `
  4012. <div [formGroup]="myGroup">
  4013. <input formControlName="firstName">
  4014. <input [(ngModel)]="showMoreControls" [ngModelOptions]="{standalone: true}">
  4015. </div>
  4016. `
  4017. };
  4018. /**
  4019. * @fileoverview added by tsickle
  4020. * @suppress {checkTypes} checked by tsc
  4021. */
  4022. /**
  4023. * @license
  4024. * Copyright Google Inc. All Rights Reserved.
  4025. *
  4026. * Use of this source code is governed by an MIT-style license that can be
  4027. * found in the LICENSE file at https://angular.io/license
  4028. */
  4029. class TemplateDrivenErrors {
  4030. /**
  4031. * @return {?}
  4032. */
  4033. static modelParentException() {
  4034. throw new Error(`
  4035. ngModel cannot be used to register form controls with a parent formGroup directive. Try using
  4036. formGroup's partner directive "formControlName" instead. Example:
  4037. ${FormErrorExamples.formControlName}
  4038. Or, if you'd like to avoid registering this form control, indicate that it's standalone in ngModelOptions:
  4039. Example:
  4040. ${FormErrorExamples.ngModelWithFormGroup}`);
  4041. }
  4042. /**
  4043. * @return {?}
  4044. */
  4045. static formGroupNameException() {
  4046. throw new Error(`
  4047. ngModel cannot be used to register form controls with a parent formGroupName or formArrayName directive.
  4048. Option 1: Use formControlName instead of ngModel (reactive strategy):
  4049. ${FormErrorExamples.formGroupName}
  4050. Option 2: Update ngModel's parent be ngModelGroup (template-driven strategy):
  4051. ${FormErrorExamples.ngModelGroup}`);
  4052. }
  4053. /**
  4054. * @return {?}
  4055. */
  4056. static missingNameException() {
  4057. throw new Error(`If ngModel is used within a form tag, either the name attribute must be set or the form
  4058. control must be defined as 'standalone' in ngModelOptions.
  4059. Example 1: <input [(ngModel)]="person.firstName" name="first">
  4060. Example 2: <input [(ngModel)]="person.firstName" [ngModelOptions]="{standalone: true}">`);
  4061. }
  4062. /**
  4063. * @return {?}
  4064. */
  4065. static modelGroupParentException() {
  4066. throw new Error(`
  4067. ngModelGroup cannot be used with a parent formGroup directive.
  4068. Option 1: Use formGroupName instead of ngModelGroup (reactive strategy):
  4069. ${FormErrorExamples.formGroupName}
  4070. Option 2: Use a regular form tag instead of the formGroup directive (template-driven strategy):
  4071. ${FormErrorExamples.ngModelGroup}`);
  4072. }
  4073. }
  4074. /**
  4075. * @fileoverview added by tsickle
  4076. * @suppress {checkTypes} checked by tsc
  4077. */
  4078. /**
  4079. * @license
  4080. * Copyright Google Inc. All Rights Reserved.
  4081. *
  4082. * Use of this source code is governed by an MIT-style license that can be
  4083. * found in the LICENSE file at https://angular.io/license
  4084. */
  4085. const modelGroupProvider = {
  4086. provide: ControlContainer,
  4087. useExisting: forwardRef(() => NgModelGroup)
  4088. };
  4089. /**
  4090. * \@whatItDoes Creates and binds a {\@link FormGroup} instance to a DOM element.
  4091. *
  4092. * \@howToUse
  4093. *
  4094. * This directive can only be used as a child of {\@link NgForm} (or in other words,
  4095. * within `<form>` tags).
  4096. *
  4097. * Use this directive if you'd like to create a sub-group within a form. This can
  4098. * come in handy if you want to validate a sub-group of your form separately from
  4099. * the rest of your form, or if some values in your domain model make more sense to
  4100. * consume together in a nested object.
  4101. *
  4102. * Pass in the name you'd like this sub-group to have and it will become the key
  4103. * for the sub-group in the form's full value. You can also export the directive into
  4104. * a local template variable using `ngModelGroup` (ex: `#myGroup="ngModelGroup"`).
  4105. *
  4106. * {\@example forms/ts/ngModelGroup/ng_model_group_example.ts region='Component'}
  4107. *
  4108. * * **npm package**: `\@angular/forms`
  4109. *
  4110. * * **NgModule**: `FormsModule`
  4111. *
  4112. * \@stable
  4113. */
  4114. class NgModelGroup extends AbstractFormGroupDirective {
  4115. /**
  4116. * @param {?} parent
  4117. * @param {?} validators
  4118. * @param {?} asyncValidators
  4119. */
  4120. constructor(parent, validators, asyncValidators) {
  4121. super();
  4122. this._parent = parent;
  4123. this._validators = validators;
  4124. this._asyncValidators = asyncValidators;
  4125. }
  4126. /**
  4127. * \@internal
  4128. * @return {?}
  4129. */
  4130. _checkParentType() {
  4131. if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  4132. TemplateDrivenErrors.modelGroupParentException();
  4133. }
  4134. }
  4135. }
  4136. NgModelGroup.decorators = [
  4137. { type: Directive, args: [{ selector: '[ngModelGroup]', providers: [modelGroupProvider], exportAs: 'ngModelGroup' },] },
  4138. ];
  4139. /** @nocollapse */
  4140. NgModelGroup.ctorParameters = () => [
  4141. { type: ControlContainer, decorators: [{ type: Host }, { type: SkipSelf },] },
  4142. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  4143. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  4144. ];
  4145. NgModelGroup.propDecorators = {
  4146. "name": [{ type: Input, args: ['ngModelGroup',] },],
  4147. };
  4148. /**
  4149. * @fileoverview added by tsickle
  4150. * @suppress {checkTypes} checked by tsc
  4151. */
  4152. /**
  4153. * @license
  4154. * Copyright Google Inc. All Rights Reserved.
  4155. *
  4156. * Use of this source code is governed by an MIT-style license that can be
  4157. * found in the LICENSE file at https://angular.io/license
  4158. */
  4159. const formControlBinding = {
  4160. provide: NgControl,
  4161. useExisting: forwardRef(() => NgModel)
  4162. };
  4163. /**
  4164. * `ngModel` forces an additional change detection run when its inputs change:
  4165. * E.g.:
  4166. * ```
  4167. * <div>{{myModel.valid}}</div>
  4168. * <input [(ngModel)]="myValue" #myModel="ngModel">
  4169. * ```
  4170. * I.e. `ngModel` can export itself on the element and then be used in the template.
  4171. * Normally, this would result in expressions before the `input` that use the exported directive
  4172. * to have and old value as they have been
  4173. * dirty checked before. As this is a very common case for `ngModel`, we added this second change
  4174. * detection run.
  4175. *
  4176. * Notes:
  4177. * - this is just one extra run no matter how many `ngModel` have been changed.
  4178. * - this is a general problem when using `exportAs` for directives!
  4179. */
  4180. const resolvedPromise$1 = Promise.resolve(null);
  4181. /**
  4182. * \@whatItDoes Creates a {\@link FormControl} instance from a domain model and binds it
  4183. * to a form control element.
  4184. *
  4185. * The {\@link FormControl} instance will track the value, user interaction, and
  4186. * validation status of the control and keep the view synced with the model. If used
  4187. * within a parent form, the directive will also register itself with the form as a child
  4188. * control.
  4189. *
  4190. * \@howToUse
  4191. *
  4192. * This directive can be used by itself or as part of a larger form. All you need is the
  4193. * `ngModel` selector to activate it.
  4194. *
  4195. * It accepts a domain model as an optional {\@link Input}. If you have a one-way binding
  4196. * to `ngModel` with `[]` syntax, changing the value of the domain model in the component
  4197. * class will set the value in the view. If you have a two-way binding with `[()]` syntax
  4198. * (also known as 'banana-box syntax'), the value in the UI will always be synced back to
  4199. * the domain model in your class as well.
  4200. *
  4201. * If you wish to inspect the properties of the associated {\@link FormControl} (like
  4202. * validity state), you can also export the directive into a local template variable using
  4203. * `ngModel` as the key (ex: `#myVar="ngModel"`). You can then access the control using the
  4204. * directive's `control` property, but most properties you'll need (like `valid` and `dirty`)
  4205. * will fall through to the control anyway, so you can access them directly. You can see a
  4206. * full list of properties directly available in {\@link AbstractControlDirective}.
  4207. *
  4208. * The following is an example of a simple standalone control using `ngModel`:
  4209. *
  4210. * {\@example forms/ts/simpleNgModel/simple_ng_model_example.ts region='Component'}
  4211. *
  4212. * When using the `ngModel` within `<form>` tags, you'll also need to supply a `name` attribute
  4213. * so that the control can be registered with the parent form under that name.
  4214. *
  4215. * It's worth noting that in the context of a parent form, you often can skip one-way or
  4216. * two-way binding because the parent form will sync the value for you. You can access
  4217. * its properties by exporting it into a local template variable using `ngForm` (ex:
  4218. * `#f="ngForm"`). Then you can pass it where it needs to go on submit.
  4219. *
  4220. * If you do need to populate initial values into your form, using a one-way binding for
  4221. * `ngModel` tends to be sufficient as long as you use the exported form's value rather
  4222. * than the domain model's value on submit.
  4223. *
  4224. * Take a look at an example of using `ngModel` within a form:
  4225. *
  4226. * {\@example forms/ts/simpleForm/simple_form_example.ts region='Component'}
  4227. *
  4228. * To see `ngModel` examples with different form control types, see:
  4229. *
  4230. * * Radio buttons: {\@link RadioControlValueAccessor}
  4231. * * Selects: {\@link SelectControlValueAccessor}
  4232. *
  4233. * **npm package**: `\@angular/forms`
  4234. *
  4235. * **NgModule**: `FormsModule`
  4236. *
  4237. * \@stable
  4238. */
  4239. class NgModel extends NgControl {
  4240. /**
  4241. * @param {?} parent
  4242. * @param {?} validators
  4243. * @param {?} asyncValidators
  4244. * @param {?} valueAccessors
  4245. */
  4246. constructor(parent, validators, asyncValidators, valueAccessors) {
  4247. super();
  4248. this.control = new FormControl();
  4249. /**
  4250. * \@internal
  4251. */
  4252. this._registered = false;
  4253. this.update = new EventEmitter();
  4254. this._parent = parent;
  4255. this._rawValidators = validators || [];
  4256. this._rawAsyncValidators = asyncValidators || [];
  4257. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  4258. }
  4259. /**
  4260. * @param {?} changes
  4261. * @return {?}
  4262. */
  4263. ngOnChanges(changes) {
  4264. this._checkForErrors();
  4265. if (!this._registered)
  4266. this._setUpControl();
  4267. if ('isDisabled' in changes) {
  4268. this._updateDisabled(changes);
  4269. }
  4270. if (isPropertyUpdated(changes, this.viewModel)) {
  4271. this._updateValue(this.model);
  4272. this.viewModel = this.model;
  4273. }
  4274. }
  4275. /**
  4276. * @return {?}
  4277. */
  4278. ngOnDestroy() { this.formDirective && this.formDirective.removeControl(this); }
  4279. /**
  4280. * @return {?}
  4281. */
  4282. get path() {
  4283. return this._parent ? controlPath(this.name, this._parent) : [this.name];
  4284. }
  4285. /**
  4286. * @return {?}
  4287. */
  4288. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  4289. /**
  4290. * @return {?}
  4291. */
  4292. get validator() { return composeValidators(this._rawValidators); }
  4293. /**
  4294. * @return {?}
  4295. */
  4296. get asyncValidator() {
  4297. return composeAsyncValidators(this._rawAsyncValidators);
  4298. }
  4299. /**
  4300. * @param {?} newValue
  4301. * @return {?}
  4302. */
  4303. viewToModelUpdate(newValue) {
  4304. this.viewModel = newValue;
  4305. this.update.emit(newValue);
  4306. }
  4307. /**
  4308. * @return {?}
  4309. */
  4310. _setUpControl() {
  4311. this._setUpdateStrategy();
  4312. this._isStandalone() ? this._setUpStandalone() :
  4313. this.formDirective.addControl(this);
  4314. this._registered = true;
  4315. }
  4316. /**
  4317. * @return {?}
  4318. */
  4319. _setUpdateStrategy() {
  4320. if (this.options && this.options.updateOn != null) {
  4321. this.control._updateOn = this.options.updateOn;
  4322. }
  4323. }
  4324. /**
  4325. * @return {?}
  4326. */
  4327. _isStandalone() {
  4328. return !this._parent || !!(this.options && this.options.standalone);
  4329. }
  4330. /**
  4331. * @return {?}
  4332. */
  4333. _setUpStandalone() {
  4334. setUpControl(this.control, this);
  4335. this.control.updateValueAndValidity({ emitEvent: false });
  4336. }
  4337. /**
  4338. * @return {?}
  4339. */
  4340. _checkForErrors() {
  4341. if (!this._isStandalone()) {
  4342. this._checkParentType();
  4343. }
  4344. this._checkName();
  4345. }
  4346. /**
  4347. * @return {?}
  4348. */
  4349. _checkParentType() {
  4350. if (!(this._parent instanceof NgModelGroup) &&
  4351. this._parent instanceof AbstractFormGroupDirective) {
  4352. TemplateDrivenErrors.formGroupNameException();
  4353. }
  4354. else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
  4355. TemplateDrivenErrors.modelParentException();
  4356. }
  4357. }
  4358. /**
  4359. * @return {?}
  4360. */
  4361. _checkName() {
  4362. if (this.options && this.options.name)
  4363. this.name = this.options.name;
  4364. if (!this._isStandalone() && !this.name) {
  4365. TemplateDrivenErrors.missingNameException();
  4366. }
  4367. }
  4368. /**
  4369. * @param {?} value
  4370. * @return {?}
  4371. */
  4372. _updateValue(value) {
  4373. resolvedPromise$1.then(() => { this.control.setValue(value, { emitViewToModelChange: false }); });
  4374. }
  4375. /**
  4376. * @param {?} changes
  4377. * @return {?}
  4378. */
  4379. _updateDisabled(changes) {
  4380. const /** @type {?} */ disabledValue = changes['isDisabled'].currentValue;
  4381. const /** @type {?} */ isDisabled = disabledValue === '' || (disabledValue && disabledValue !== 'false');
  4382. resolvedPromise$1.then(() => {
  4383. if (isDisabled && !this.control.disabled) {
  4384. this.control.disable();
  4385. }
  4386. else if (!isDisabled && this.control.disabled) {
  4387. this.control.enable();
  4388. }
  4389. });
  4390. }
  4391. }
  4392. NgModel.decorators = [
  4393. { type: Directive, args: [{
  4394. selector: '[ngModel]:not([formControlName]):not([formControl])',
  4395. providers: [formControlBinding],
  4396. exportAs: 'ngModel'
  4397. },] },
  4398. ];
  4399. /** @nocollapse */
  4400. NgModel.ctorParameters = () => [
  4401. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host },] },
  4402. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  4403. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  4404. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  4405. ];
  4406. NgModel.propDecorators = {
  4407. "name": [{ type: Input },],
  4408. "isDisabled": [{ type: Input, args: ['disabled',] },],
  4409. "model": [{ type: Input, args: ['ngModel',] },],
  4410. "options": [{ type: Input, args: ['ngModelOptions',] },],
  4411. "update": [{ type: Output, args: ['ngModelChange',] },],
  4412. };
  4413. /**
  4414. * @fileoverview added by tsickle
  4415. * @suppress {checkTypes} checked by tsc
  4416. */
  4417. /**
  4418. * @license
  4419. * Copyright Google Inc. All Rights Reserved.
  4420. *
  4421. * Use of this source code is governed by an MIT-style license that can be
  4422. * found in the LICENSE file at https://angular.io/license
  4423. */
  4424. class ReactiveErrors {
  4425. /**
  4426. * @return {?}
  4427. */
  4428. static controlParentException() {
  4429. throw new Error(`formControlName must be used with a parent formGroup directive. You'll want to add a formGroup
  4430. directive and pass it an existing FormGroup instance (you can create one in your class).
  4431. Example:
  4432. ${FormErrorExamples.formControlName}`);
  4433. }
  4434. /**
  4435. * @return {?}
  4436. */
  4437. static ngModelGroupException() {
  4438. throw new Error(`formControlName cannot be used with an ngModelGroup parent. It is only compatible with parents
  4439. that also have a "form" prefix: formGroupName, formArrayName, or formGroup.
  4440. Option 1: Update the parent to be formGroupName (reactive form strategy)
  4441. ${FormErrorExamples.formGroupName}
  4442. Option 2: Use ngModel instead of formControlName (template-driven strategy)
  4443. ${FormErrorExamples.ngModelGroup}`);
  4444. }
  4445. /**
  4446. * @return {?}
  4447. */
  4448. static missingFormException() {
  4449. throw new Error(`formGroup expects a FormGroup instance. Please pass one in.
  4450. Example:
  4451. ${FormErrorExamples.formControlName}`);
  4452. }
  4453. /**
  4454. * @return {?}
  4455. */
  4456. static groupParentException() {
  4457. throw new Error(`formGroupName must be used with a parent formGroup directive. You'll want to add a formGroup
  4458. directive and pass it an existing FormGroup instance (you can create one in your class).
  4459. Example:
  4460. ${FormErrorExamples.formGroupName}`);
  4461. }
  4462. /**
  4463. * @return {?}
  4464. */
  4465. static arrayParentException() {
  4466. throw new Error(`formArrayName must be used with a parent formGroup directive. You'll want to add a formGroup
  4467. directive and pass it an existing FormGroup instance (you can create one in your class).
  4468. Example:
  4469. ${FormErrorExamples.formArrayName}`);
  4470. }
  4471. /**
  4472. * @return {?}
  4473. */
  4474. static disabledAttrWarning() {
  4475. console.warn(`
  4476. It looks like you're using the disabled attribute with a reactive form directive. If you set disabled to true
  4477. when you set up this control in your component class, the disabled attribute will actually be set in the DOM for
  4478. you. We recommend using this approach to avoid 'changed after checked' errors.
  4479. Example:
  4480. form = new FormGroup({
  4481. first: new FormControl({value: 'Nancy', disabled: true}, Validators.required),
  4482. last: new FormControl('Drew', Validators.required)
  4483. });
  4484. `);
  4485. }
  4486. }
  4487. /**
  4488. * @fileoverview added by tsickle
  4489. * @suppress {checkTypes} checked by tsc
  4490. */
  4491. /**
  4492. * @license
  4493. * Copyright Google Inc. All Rights Reserved.
  4494. *
  4495. * Use of this source code is governed by an MIT-style license that can be
  4496. * found in the LICENSE file at https://angular.io/license
  4497. */
  4498. const formControlBinding$1 = {
  4499. provide: NgControl,
  4500. useExisting: forwardRef(() => FormControlDirective)
  4501. };
  4502. /**
  4503. * \@whatItDoes Syncs a standalone {\@link FormControl} instance to a form control element.
  4504. *
  4505. * In other words, this directive ensures that any values written to the {\@link FormControl}
  4506. * instance programmatically will be written to the DOM element (model -> view). Conversely,
  4507. * any values written to the DOM element through user input will be reflected in the
  4508. * {\@link FormControl} instance (view -> model).
  4509. *
  4510. * \@howToUse
  4511. *
  4512. * Use this directive if you'd like to create and manage a {\@link FormControl} instance directly.
  4513. * Simply create a {\@link FormControl}, save it to your component class, and pass it into the
  4514. * {\@link FormControlDirective}.
  4515. *
  4516. * This directive is designed to be used as a standalone control. Unlike {\@link FormControlName},
  4517. * it does not require that your {\@link FormControl} instance be part of any parent
  4518. * {\@link FormGroup}, and it won't be registered to any {\@link FormGroupDirective} that
  4519. * exists above it.
  4520. *
  4521. * **Get the value**: the `value` property is always synced and available on the
  4522. * {\@link FormControl} instance. See a full list of available properties in
  4523. * {\@link AbstractControl}.
  4524. *
  4525. * **Set the value**: You can pass in an initial value when instantiating the {\@link FormControl},
  4526. * or you can set it programmatically later using {\@link AbstractControl#setValue setValue} or
  4527. * {\@link AbstractControl#patchValue patchValue}.
  4528. *
  4529. * **Listen to value**: If you want to listen to changes in the value of the control, you can
  4530. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  4531. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  4532. * re-calculated.
  4533. *
  4534. * ### Example
  4535. *
  4536. * {\@example forms/ts/simpleFormControl/simple_form_control_example.ts region='Component'}
  4537. *
  4538. * * **npm package**: `\@angular/forms`
  4539. *
  4540. * * **NgModule**: `ReactiveFormsModule`
  4541. *
  4542. * \@stable
  4543. */
  4544. class FormControlDirective extends NgControl {
  4545. /**
  4546. * @param {?} validators
  4547. * @param {?} asyncValidators
  4548. * @param {?} valueAccessors
  4549. */
  4550. constructor(validators, asyncValidators, valueAccessors) {
  4551. super();
  4552. this.update = new EventEmitter();
  4553. this._rawValidators = validators || [];
  4554. this._rawAsyncValidators = asyncValidators || [];
  4555. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  4556. }
  4557. /**
  4558. * @param {?} isDisabled
  4559. * @return {?}
  4560. */
  4561. set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); }
  4562. /**
  4563. * @param {?} changes
  4564. * @return {?}
  4565. */
  4566. ngOnChanges(changes) {
  4567. if (this._isControlChanged(changes)) {
  4568. setUpControl(this.form, this);
  4569. if (this.control.disabled && /** @type {?} */ ((this.valueAccessor)).setDisabledState) {
  4570. /** @type {?} */ ((/** @type {?} */ ((this.valueAccessor)).setDisabledState))(true);
  4571. }
  4572. this.form.updateValueAndValidity({ emitEvent: false });
  4573. }
  4574. if (isPropertyUpdated(changes, this.viewModel)) {
  4575. this.form.setValue(this.model);
  4576. this.viewModel = this.model;
  4577. }
  4578. }
  4579. /**
  4580. * @return {?}
  4581. */
  4582. get path() { return []; }
  4583. /**
  4584. * @return {?}
  4585. */
  4586. get validator() { return composeValidators(this._rawValidators); }
  4587. /**
  4588. * @return {?}
  4589. */
  4590. get asyncValidator() {
  4591. return composeAsyncValidators(this._rawAsyncValidators);
  4592. }
  4593. /**
  4594. * @return {?}
  4595. */
  4596. get control() { return this.form; }
  4597. /**
  4598. * @param {?} newValue
  4599. * @return {?}
  4600. */
  4601. viewToModelUpdate(newValue) {
  4602. this.viewModel = newValue;
  4603. this.update.emit(newValue);
  4604. }
  4605. /**
  4606. * @param {?} changes
  4607. * @return {?}
  4608. */
  4609. _isControlChanged(changes) {
  4610. return changes.hasOwnProperty('form');
  4611. }
  4612. }
  4613. FormControlDirective.decorators = [
  4614. { type: Directive, args: [{ selector: '[formControl]', providers: [formControlBinding$1], exportAs: 'ngForm' },] },
  4615. ];
  4616. /** @nocollapse */
  4617. FormControlDirective.ctorParameters = () => [
  4618. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  4619. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  4620. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  4621. ];
  4622. FormControlDirective.propDecorators = {
  4623. "form": [{ type: Input, args: ['formControl',] },],
  4624. "model": [{ type: Input, args: ['ngModel',] },],
  4625. "update": [{ type: Output, args: ['ngModelChange',] },],
  4626. "isDisabled": [{ type: Input, args: ['disabled',] },],
  4627. };
  4628. /**
  4629. * @fileoverview added by tsickle
  4630. * @suppress {checkTypes} checked by tsc
  4631. */
  4632. /**
  4633. * @license
  4634. * Copyright Google Inc. All Rights Reserved.
  4635. *
  4636. * Use of this source code is governed by an MIT-style license that can be
  4637. * found in the LICENSE file at https://angular.io/license
  4638. */
  4639. const formDirectiveProvider$1 = {
  4640. provide: ControlContainer,
  4641. useExisting: forwardRef(() => FormGroupDirective)
  4642. };
  4643. /**
  4644. * \@whatItDoes Binds an existing {\@link FormGroup} to a DOM element.
  4645. *
  4646. * \@howToUse
  4647. *
  4648. * This directive accepts an existing {\@link FormGroup} instance. It will then use this
  4649. * {\@link FormGroup} instance to match any child {\@link FormControl}, {\@link FormGroup},
  4650. * and {\@link FormArray} instances to child {\@link FormControlName}, {\@link FormGroupName},
  4651. * and {\@link FormArrayName} directives.
  4652. *
  4653. * **Set value**: You can set the form's initial value when instantiating the
  4654. * {\@link FormGroup}, or you can set it programmatically later using the {\@link FormGroup}'s
  4655. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}
  4656. * methods.
  4657. *
  4658. * **Listen to value**: If you want to listen to changes in the value of the form, you can subscribe
  4659. * to the {\@link FormGroup}'s {\@link AbstractControl#valueChanges valueChanges} event. You can also
  4660. * listen to its {\@link AbstractControl#statusChanges statusChanges} event to be notified when the
  4661. * validation status is re-calculated.
  4662. *
  4663. * Furthermore, you can listen to the directive's `ngSubmit` event to be notified when the user has
  4664. * triggered a form submission. The `ngSubmit` event will be emitted with the original form
  4665. * submission event.
  4666. *
  4667. * ### Example
  4668. *
  4669. * In this example, we create form controls for first name and last name.
  4670. *
  4671. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  4672. *
  4673. * **npm package**: `\@angular/forms`
  4674. *
  4675. * **NgModule**: {\@link ReactiveFormsModule}
  4676. *
  4677. * \@stable
  4678. */
  4679. class FormGroupDirective extends ControlContainer {
  4680. /**
  4681. * @param {?} _validators
  4682. * @param {?} _asyncValidators
  4683. */
  4684. constructor(_validators, _asyncValidators) {
  4685. super();
  4686. this._validators = _validators;
  4687. this._asyncValidators = _asyncValidators;
  4688. this.submitted = false;
  4689. this.directives = [];
  4690. this.form = /** @type {?} */ ((null));
  4691. this.ngSubmit = new EventEmitter();
  4692. }
  4693. /**
  4694. * @param {?} changes
  4695. * @return {?}
  4696. */
  4697. ngOnChanges(changes) {
  4698. this._checkFormPresent();
  4699. if (changes.hasOwnProperty('form')) {
  4700. this._updateValidators();
  4701. this._updateDomValue();
  4702. this._updateRegistrations();
  4703. }
  4704. }
  4705. /**
  4706. * @return {?}
  4707. */
  4708. get formDirective() { return this; }
  4709. /**
  4710. * @return {?}
  4711. */
  4712. get control() { return this.form; }
  4713. /**
  4714. * @return {?}
  4715. */
  4716. get path() { return []; }
  4717. /**
  4718. * @param {?} dir
  4719. * @return {?}
  4720. */
  4721. addControl(dir) {
  4722. const /** @type {?} */ ctrl = this.form.get(dir.path);
  4723. setUpControl(ctrl, dir);
  4724. ctrl.updateValueAndValidity({ emitEvent: false });
  4725. this.directives.push(dir);
  4726. return ctrl;
  4727. }
  4728. /**
  4729. * @param {?} dir
  4730. * @return {?}
  4731. */
  4732. getControl(dir) { return /** @type {?} */ (this.form.get(dir.path)); }
  4733. /**
  4734. * @param {?} dir
  4735. * @return {?}
  4736. */
  4737. removeControl(dir) { removeDir(this.directives, dir); }
  4738. /**
  4739. * @param {?} dir
  4740. * @return {?}
  4741. */
  4742. addFormGroup(dir) {
  4743. const /** @type {?} */ ctrl = this.form.get(dir.path);
  4744. setUpFormContainer(ctrl, dir);
  4745. ctrl.updateValueAndValidity({ emitEvent: false });
  4746. }
  4747. /**
  4748. * @param {?} dir
  4749. * @return {?}
  4750. */
  4751. removeFormGroup(dir) { }
  4752. /**
  4753. * @param {?} dir
  4754. * @return {?}
  4755. */
  4756. getFormGroup(dir) { return /** @type {?} */ (this.form.get(dir.path)); }
  4757. /**
  4758. * @param {?} dir
  4759. * @return {?}
  4760. */
  4761. addFormArray(dir) {
  4762. const /** @type {?} */ ctrl = this.form.get(dir.path);
  4763. setUpFormContainer(ctrl, dir);
  4764. ctrl.updateValueAndValidity({ emitEvent: false });
  4765. }
  4766. /**
  4767. * @param {?} dir
  4768. * @return {?}
  4769. */
  4770. removeFormArray(dir) { }
  4771. /**
  4772. * @param {?} dir
  4773. * @return {?}
  4774. */
  4775. getFormArray(dir) { return /** @type {?} */ (this.form.get(dir.path)); }
  4776. /**
  4777. * @param {?} dir
  4778. * @param {?} value
  4779. * @return {?}
  4780. */
  4781. updateModel(dir, value) {
  4782. const /** @type {?} */ ctrl = /** @type {?} */ (this.form.get(dir.path));
  4783. ctrl.setValue(value);
  4784. }
  4785. /**
  4786. * @param {?} $event
  4787. * @return {?}
  4788. */
  4789. onSubmit($event) {
  4790. (/** @type {?} */ (this)).submitted = true;
  4791. syncPendingControls(this.form, this.directives);
  4792. this.ngSubmit.emit($event);
  4793. return false;
  4794. }
  4795. /**
  4796. * @return {?}
  4797. */
  4798. onReset() { this.resetForm(); }
  4799. /**
  4800. * @param {?=} value
  4801. * @return {?}
  4802. */
  4803. resetForm(value = undefined) {
  4804. this.form.reset(value);
  4805. (/** @type {?} */ (this)).submitted = false;
  4806. }
  4807. /**
  4808. * \@internal
  4809. * @return {?}
  4810. */
  4811. _updateDomValue() {
  4812. this.directives.forEach(dir => {
  4813. const /** @type {?} */ newCtrl = this.form.get(dir.path);
  4814. if (dir.control !== newCtrl) {
  4815. cleanUpControl(dir.control, dir);
  4816. if (newCtrl)
  4817. setUpControl(newCtrl, dir);
  4818. (/** @type {?} */ (dir)).control = newCtrl;
  4819. }
  4820. });
  4821. this.form._updateTreeValidity({ emitEvent: false });
  4822. }
  4823. /**
  4824. * @return {?}
  4825. */
  4826. _updateRegistrations() {
  4827. this.form._registerOnCollectionChange(() => this._updateDomValue());
  4828. if (this._oldForm)
  4829. this._oldForm._registerOnCollectionChange(() => { });
  4830. this._oldForm = this.form;
  4831. }
  4832. /**
  4833. * @return {?}
  4834. */
  4835. _updateValidators() {
  4836. const /** @type {?} */ sync = composeValidators(this._validators);
  4837. this.form.validator = Validators.compose([/** @type {?} */ ((this.form.validator)), /** @type {?} */ ((sync))]);
  4838. const /** @type {?} */ async = composeAsyncValidators(this._asyncValidators);
  4839. this.form.asyncValidator = Validators.composeAsync([/** @type {?} */ ((this.form.asyncValidator)), /** @type {?} */ ((async))]);
  4840. }
  4841. /**
  4842. * @return {?}
  4843. */
  4844. _checkFormPresent() {
  4845. if (!this.form) {
  4846. ReactiveErrors.missingFormException();
  4847. }
  4848. }
  4849. }
  4850. FormGroupDirective.decorators = [
  4851. { type: Directive, args: [{
  4852. selector: '[formGroup]',
  4853. providers: [formDirectiveProvider$1],
  4854. host: { '(submit)': 'onSubmit($event)', '(reset)': 'onReset()' },
  4855. exportAs: 'ngForm'
  4856. },] },
  4857. ];
  4858. /** @nocollapse */
  4859. FormGroupDirective.ctorParameters = () => [
  4860. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  4861. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  4862. ];
  4863. FormGroupDirective.propDecorators = {
  4864. "form": [{ type: Input, args: ['formGroup',] },],
  4865. "ngSubmit": [{ type: Output },],
  4866. };
  4867. /**
  4868. * @fileoverview added by tsickle
  4869. * @suppress {checkTypes} checked by tsc
  4870. */
  4871. /**
  4872. * @license
  4873. * Copyright Google Inc. All Rights Reserved.
  4874. *
  4875. * Use of this source code is governed by an MIT-style license that can be
  4876. * found in the LICENSE file at https://angular.io/license
  4877. */
  4878. const formGroupNameProvider = {
  4879. provide: ControlContainer,
  4880. useExisting: forwardRef(() => FormGroupName)
  4881. };
  4882. /**
  4883. * \@whatItDoes Syncs a nested {\@link FormGroup} to a DOM element.
  4884. *
  4885. * \@howToUse
  4886. *
  4887. * This directive can only be used with a parent {\@link FormGroupDirective} (selector:
  4888. * `[formGroup]`).
  4889. *
  4890. * It accepts the string name of the nested {\@link FormGroup} you want to link, and
  4891. * will look for a {\@link FormGroup} registered with that name in the parent
  4892. * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
  4893. *
  4894. * Nested form groups can come in handy when you want to validate a sub-group of a
  4895. * form separately from the rest or when you'd like to group the values of certain
  4896. * controls into their own nested object.
  4897. *
  4898. * **Access the group**: You can access the associated {\@link FormGroup} using the
  4899. * {\@link AbstractControl#get get} method. Ex: `this.form.get('name')`.
  4900. *
  4901. * You can also access individual controls within the group using dot syntax.
  4902. * Ex: `this.form.get('name.first')`
  4903. *
  4904. * **Get the value**: the `value` property is always synced and available on the
  4905. * {\@link FormGroup}. See a full list of available properties in {\@link AbstractControl}.
  4906. *
  4907. * **Set the value**: You can set an initial value for each child control when instantiating
  4908. * the {\@link FormGroup}, or you can set it programmatically later using
  4909. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
  4910. *
  4911. * **Listen to value**: If you want to listen to changes in the value of the group, you can
  4912. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  4913. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  4914. * re-calculated.
  4915. *
  4916. * ### Example
  4917. *
  4918. * {\@example forms/ts/nestedFormGroup/nested_form_group_example.ts region='Component'}
  4919. *
  4920. * * **npm package**: `\@angular/forms`
  4921. *
  4922. * * **NgModule**: `ReactiveFormsModule`
  4923. *
  4924. * \@stable
  4925. */
  4926. class FormGroupName extends AbstractFormGroupDirective {
  4927. /**
  4928. * @param {?} parent
  4929. * @param {?} validators
  4930. * @param {?} asyncValidators
  4931. */
  4932. constructor(parent, validators, asyncValidators) {
  4933. super();
  4934. this._parent = parent;
  4935. this._validators = validators;
  4936. this._asyncValidators = asyncValidators;
  4937. }
  4938. /**
  4939. * \@internal
  4940. * @return {?}
  4941. */
  4942. _checkParentType() {
  4943. if (_hasInvalidParent(this._parent)) {
  4944. ReactiveErrors.groupParentException();
  4945. }
  4946. }
  4947. }
  4948. FormGroupName.decorators = [
  4949. { type: Directive, args: [{ selector: '[formGroupName]', providers: [formGroupNameProvider] },] },
  4950. ];
  4951. /** @nocollapse */
  4952. FormGroupName.ctorParameters = () => [
  4953. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  4954. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  4955. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  4956. ];
  4957. FormGroupName.propDecorators = {
  4958. "name": [{ type: Input, args: ['formGroupName',] },],
  4959. };
  4960. const formArrayNameProvider = {
  4961. provide: ControlContainer,
  4962. useExisting: forwardRef(() => FormArrayName)
  4963. };
  4964. /**
  4965. * \@whatItDoes Syncs a nested {\@link FormArray} to a DOM element.
  4966. *
  4967. * \@howToUse
  4968. *
  4969. * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
  4970. * `[formGroup]`).
  4971. *
  4972. * It accepts the string name of the nested {\@link FormArray} you want to link, and
  4973. * will look for a {\@link FormArray} registered with that name in the parent
  4974. * {\@link FormGroup} instance you passed into {\@link FormGroupDirective}.
  4975. *
  4976. * Nested form arrays can come in handy when you have a group of form controls but
  4977. * you're not sure how many there will be. Form arrays allow you to create new
  4978. * form controls dynamically.
  4979. *
  4980. * **Access the array**: You can access the associated {\@link FormArray} using the
  4981. * {\@link AbstractControl#get get} method on the parent {\@link FormGroup}.
  4982. * Ex: `this.form.get('cities')`.
  4983. *
  4984. * **Get the value**: the `value` property is always synced and available on the
  4985. * {\@link FormArray}. See a full list of available properties in {\@link AbstractControl}.
  4986. *
  4987. * **Set the value**: You can set an initial value for each child control when instantiating
  4988. * the {\@link FormArray}, or you can set the value programmatically later using the
  4989. * {\@link FormArray}'s {\@link AbstractControl#setValue setValue} or
  4990. * {\@link AbstractControl#patchValue patchValue} methods.
  4991. *
  4992. * **Listen to value**: If you want to listen to changes in the value of the array, you can
  4993. * subscribe to the {\@link FormArray}'s {\@link AbstractControl#valueChanges valueChanges} event.
  4994. * You can also listen to its {\@link AbstractControl#statusChanges statusChanges} event to be
  4995. * notified when the validation status is re-calculated.
  4996. *
  4997. * **Add new controls**: You can add new controls to the {\@link FormArray} dynamically by calling
  4998. * its {\@link FormArray#push push} method.
  4999. * Ex: `this.form.get('cities').push(new FormControl());`
  5000. *
  5001. * ### Example
  5002. *
  5003. * {\@example forms/ts/nestedFormArray/nested_form_array_example.ts region='Component'}
  5004. *
  5005. * * **npm package**: `\@angular/forms`
  5006. *
  5007. * * **NgModule**: `ReactiveFormsModule`
  5008. *
  5009. * \@stable
  5010. */
  5011. class FormArrayName extends ControlContainer {
  5012. /**
  5013. * @param {?} parent
  5014. * @param {?} validators
  5015. * @param {?} asyncValidators
  5016. */
  5017. constructor(parent, validators, asyncValidators) {
  5018. super();
  5019. this._parent = parent;
  5020. this._validators = validators;
  5021. this._asyncValidators = asyncValidators;
  5022. }
  5023. /**
  5024. * @return {?}
  5025. */
  5026. ngOnInit() {
  5027. this._checkParentType(); /** @type {?} */
  5028. ((this.formDirective)).addFormArray(this);
  5029. }
  5030. /**
  5031. * @return {?}
  5032. */
  5033. ngOnDestroy() {
  5034. if (this.formDirective) {
  5035. this.formDirective.removeFormArray(this);
  5036. }
  5037. }
  5038. /**
  5039. * @return {?}
  5040. */
  5041. get control() { return /** @type {?} */ ((this.formDirective)).getFormArray(this); }
  5042. /**
  5043. * @return {?}
  5044. */
  5045. get formDirective() {
  5046. return this._parent ? /** @type {?} */ (this._parent.formDirective) : null;
  5047. }
  5048. /**
  5049. * @return {?}
  5050. */
  5051. get path() { return controlPath(this.name, this._parent); }
  5052. /**
  5053. * @return {?}
  5054. */
  5055. get validator() { return composeValidators(this._validators); }
  5056. /**
  5057. * @return {?}
  5058. */
  5059. get asyncValidator() {
  5060. return composeAsyncValidators(this._asyncValidators);
  5061. }
  5062. /**
  5063. * @return {?}
  5064. */
  5065. _checkParentType() {
  5066. if (_hasInvalidParent(this._parent)) {
  5067. ReactiveErrors.arrayParentException();
  5068. }
  5069. }
  5070. }
  5071. FormArrayName.decorators = [
  5072. { type: Directive, args: [{ selector: '[formArrayName]', providers: [formArrayNameProvider] },] },
  5073. ];
  5074. /** @nocollapse */
  5075. FormArrayName.ctorParameters = () => [
  5076. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  5077. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  5078. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  5079. ];
  5080. FormArrayName.propDecorators = {
  5081. "name": [{ type: Input, args: ['formArrayName',] },],
  5082. };
  5083. /**
  5084. * @param {?} parent
  5085. * @return {?}
  5086. */
  5087. function _hasInvalidParent(parent) {
  5088. return !(parent instanceof FormGroupName) && !(parent instanceof FormGroupDirective) &&
  5089. !(parent instanceof FormArrayName);
  5090. }
  5091. /**
  5092. * @fileoverview added by tsickle
  5093. * @suppress {checkTypes} checked by tsc
  5094. */
  5095. /**
  5096. * @license
  5097. * Copyright Google Inc. All Rights Reserved.
  5098. *
  5099. * Use of this source code is governed by an MIT-style license that can be
  5100. * found in the LICENSE file at https://angular.io/license
  5101. */
  5102. const controlNameBinding = {
  5103. provide: NgControl,
  5104. useExisting: forwardRef(() => FormControlName)
  5105. };
  5106. /**
  5107. * \@whatItDoes Syncs a {\@link FormControl} in an existing {\@link FormGroup} to a form control
  5108. * element by name.
  5109. *
  5110. * In other words, this directive ensures that any values written to the {\@link FormControl}
  5111. * instance programmatically will be written to the DOM element (model -> view). Conversely,
  5112. * any values written to the DOM element through user input will be reflected in the
  5113. * {\@link FormControl} instance (view -> model).
  5114. *
  5115. * \@howToUse
  5116. *
  5117. * This directive is designed to be used with a parent {\@link FormGroupDirective} (selector:
  5118. * `[formGroup]`).
  5119. *
  5120. * It accepts the string name of the {\@link FormControl} instance you want to
  5121. * link, and will look for a {\@link FormControl} registered with that name in the
  5122. * closest {\@link FormGroup} or {\@link FormArray} above it.
  5123. *
  5124. * **Access the control**: You can access the {\@link FormControl} associated with
  5125. * this directive by using the {\@link AbstractControl#get get} method.
  5126. * Ex: `this.form.get('first');`
  5127. *
  5128. * **Get value**: the `value` property is always synced and available on the {\@link FormControl}.
  5129. * See a full list of available properties in {\@link AbstractControl}.
  5130. *
  5131. * **Set value**: You can set an initial value for the control when instantiating the
  5132. * {\@link FormControl}, or you can set it programmatically later using
  5133. * {\@link AbstractControl#setValue setValue} or {\@link AbstractControl#patchValue patchValue}.
  5134. *
  5135. * **Listen to value**: If you want to listen to changes in the value of the control, you can
  5136. * subscribe to the {\@link AbstractControl#valueChanges valueChanges} event. You can also listen to
  5137. * {\@link AbstractControl#statusChanges statusChanges} to be notified when the validation status is
  5138. * re-calculated.
  5139. *
  5140. * ### Example
  5141. *
  5142. * In this example, we create form controls for first name and last name.
  5143. *
  5144. * {\@example forms/ts/simpleFormGroup/simple_form_group_example.ts region='Component'}
  5145. *
  5146. * To see `formControlName` examples with different form control types, see:
  5147. *
  5148. * * Radio buttons: {\@link RadioControlValueAccessor}
  5149. * * Selects: {\@link SelectControlValueAccessor}
  5150. *
  5151. * **npm package**: `\@angular/forms`
  5152. *
  5153. * **NgModule**: {\@link ReactiveFormsModule}
  5154. *
  5155. * \@stable
  5156. */
  5157. class FormControlName extends NgControl {
  5158. /**
  5159. * @param {?} parent
  5160. * @param {?} validators
  5161. * @param {?} asyncValidators
  5162. * @param {?} valueAccessors
  5163. */
  5164. constructor(parent, validators, asyncValidators, valueAccessors) {
  5165. super();
  5166. this._added = false;
  5167. this.update = new EventEmitter();
  5168. this._parent = parent;
  5169. this._rawValidators = validators || [];
  5170. this._rawAsyncValidators = asyncValidators || [];
  5171. this.valueAccessor = selectValueAccessor(this, valueAccessors);
  5172. }
  5173. /**
  5174. * @param {?} isDisabled
  5175. * @return {?}
  5176. */
  5177. set isDisabled(isDisabled) { ReactiveErrors.disabledAttrWarning(); }
  5178. /**
  5179. * @param {?} changes
  5180. * @return {?}
  5181. */
  5182. ngOnChanges(changes) {
  5183. if (!this._added)
  5184. this._setUpControl();
  5185. if (isPropertyUpdated(changes, this.viewModel)) {
  5186. this.viewModel = this.model;
  5187. this.formDirective.updateModel(this, this.model);
  5188. }
  5189. }
  5190. /**
  5191. * @return {?}
  5192. */
  5193. ngOnDestroy() {
  5194. if (this.formDirective) {
  5195. this.formDirective.removeControl(this);
  5196. }
  5197. }
  5198. /**
  5199. * @param {?} newValue
  5200. * @return {?}
  5201. */
  5202. viewToModelUpdate(newValue) {
  5203. this.viewModel = newValue;
  5204. this.update.emit(newValue);
  5205. }
  5206. /**
  5207. * @return {?}
  5208. */
  5209. get path() { return controlPath(this.name, /** @type {?} */ ((this._parent))); }
  5210. /**
  5211. * @return {?}
  5212. */
  5213. get formDirective() { return this._parent ? this._parent.formDirective : null; }
  5214. /**
  5215. * @return {?}
  5216. */
  5217. get validator() { return composeValidators(this._rawValidators); }
  5218. /**
  5219. * @return {?}
  5220. */
  5221. get asyncValidator() {
  5222. return /** @type {?} */ ((composeAsyncValidators(this._rawAsyncValidators)));
  5223. }
  5224. /**
  5225. * @return {?}
  5226. */
  5227. _checkParentType() {
  5228. if (!(this._parent instanceof FormGroupName) &&
  5229. this._parent instanceof AbstractFormGroupDirective) {
  5230. ReactiveErrors.ngModelGroupException();
  5231. }
  5232. else if (!(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) &&
  5233. !(this._parent instanceof FormArrayName)) {
  5234. ReactiveErrors.controlParentException();
  5235. }
  5236. }
  5237. /**
  5238. * @return {?}
  5239. */
  5240. _setUpControl() {
  5241. this._checkParentType();
  5242. (/** @type {?} */ (this)).control = this.formDirective.addControl(this);
  5243. if (this.control.disabled && /** @type {?} */ ((this.valueAccessor)).setDisabledState) {
  5244. /** @type {?} */ ((/** @type {?} */ ((this.valueAccessor)).setDisabledState))(true);
  5245. }
  5246. this._added = true;
  5247. }
  5248. }
  5249. FormControlName.decorators = [
  5250. { type: Directive, args: [{ selector: '[formControlName]', providers: [controlNameBinding] },] },
  5251. ];
  5252. /** @nocollapse */
  5253. FormControlName.ctorParameters = () => [
  5254. { type: ControlContainer, decorators: [{ type: Optional }, { type: Host }, { type: SkipSelf },] },
  5255. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALIDATORS,] },] },
  5256. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_ASYNC_VALIDATORS,] },] },
  5257. { type: Array, decorators: [{ type: Optional }, { type: Self }, { type: Inject, args: [NG_VALUE_ACCESSOR,] },] },
  5258. ];
  5259. FormControlName.propDecorators = {
  5260. "name": [{ type: Input, args: ['formControlName',] },],
  5261. "model": [{ type: Input, args: ['ngModel',] },],
  5262. "update": [{ type: Output, args: ['ngModelChange',] },],
  5263. "isDisabled": [{ type: Input, args: ['disabled',] },],
  5264. };
  5265. /**
  5266. * @fileoverview added by tsickle
  5267. * @suppress {checkTypes} checked by tsc
  5268. */
  5269. /**
  5270. * @license
  5271. * Copyright Google Inc. All Rights Reserved.
  5272. *
  5273. * Use of this source code is governed by an MIT-style license that can be
  5274. * found in the LICENSE file at https://angular.io/license
  5275. */
  5276. /**
  5277. * An interface that can be implemented by classes that can act as validators.
  5278. *
  5279. * ## Usage
  5280. *
  5281. * ```typescript
  5282. * \@Directive({
  5283. * selector: '[custom-validator]',
  5284. * providers: [{provide: NG_VALIDATORS, useExisting: CustomValidatorDirective, multi: true}]
  5285. * })
  5286. * class CustomValidatorDirective implements Validator {
  5287. * validate(c: Control): {[key: string]: any} {
  5288. * return {"custom": true};
  5289. * }
  5290. * }
  5291. * ```
  5292. *
  5293. * \@stable
  5294. * @record
  5295. */
  5296. /**
  5297. * \@experimental
  5298. * @record
  5299. */
  5300. const REQUIRED_VALIDATOR = {
  5301. provide: NG_VALIDATORS,
  5302. useExisting: forwardRef(() => RequiredValidator),
  5303. multi: true
  5304. };
  5305. const CHECKBOX_REQUIRED_VALIDATOR = {
  5306. provide: NG_VALIDATORS,
  5307. useExisting: forwardRef(() => CheckboxRequiredValidator),
  5308. multi: true
  5309. };
  5310. /**
  5311. * A Directive that adds the `required` validator to any controls marked with the
  5312. * `required` attribute, via the {\@link NG_VALIDATORS} binding.
  5313. *
  5314. * ### Example
  5315. *
  5316. * ```
  5317. * <input name="fullName" ngModel required>
  5318. * ```
  5319. *
  5320. * \@stable
  5321. */
  5322. class RequiredValidator {
  5323. /**
  5324. * @return {?}
  5325. */
  5326. get required() { return this._required; }
  5327. /**
  5328. * @param {?} value
  5329. * @return {?}
  5330. */
  5331. set required(value) {
  5332. this._required = value != null && value !== false && `${value}` !== 'false';
  5333. if (this._onChange)
  5334. this._onChange();
  5335. }
  5336. /**
  5337. * @param {?} c
  5338. * @return {?}
  5339. */
  5340. validate(c) {
  5341. return this.required ? Validators.required(c) : null;
  5342. }
  5343. /**
  5344. * @param {?} fn
  5345. * @return {?}
  5346. */
  5347. registerOnValidatorChange(fn) { this._onChange = fn; }
  5348. }
  5349. RequiredValidator.decorators = [
  5350. { type: Directive, args: [{
  5351. selector: ':not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]',
  5352. providers: [REQUIRED_VALIDATOR],
  5353. host: { '[attr.required]': 'required ? "" : null' }
  5354. },] },
  5355. ];
  5356. /** @nocollapse */
  5357. RequiredValidator.ctorParameters = () => [];
  5358. RequiredValidator.propDecorators = {
  5359. "required": [{ type: Input },],
  5360. };
  5361. /**
  5362. * A Directive that adds the `required` validator to checkbox controls marked with the
  5363. * `required` attribute, via the {\@link NG_VALIDATORS} binding.
  5364. *
  5365. * ### Example
  5366. *
  5367. * ```
  5368. * <input type="checkbox" name="active" ngModel required>
  5369. * ```
  5370. *
  5371. * \@experimental
  5372. */
  5373. class CheckboxRequiredValidator extends RequiredValidator {
  5374. /**
  5375. * @param {?} c
  5376. * @return {?}
  5377. */
  5378. validate(c) {
  5379. return this.required ? Validators.requiredTrue(c) : null;
  5380. }
  5381. }
  5382. CheckboxRequiredValidator.decorators = [
  5383. { type: Directive, args: [{
  5384. selector: 'input[type=checkbox][required][formControlName],input[type=checkbox][required][formControl],input[type=checkbox][required][ngModel]',
  5385. providers: [CHECKBOX_REQUIRED_VALIDATOR],
  5386. host: { '[attr.required]': 'required ? "" : null' }
  5387. },] },
  5388. ];
  5389. /** @nocollapse */
  5390. CheckboxRequiredValidator.ctorParameters = () => [];
  5391. /**
  5392. * Provider which adds {\@link EmailValidator} to {\@link NG_VALIDATORS}.
  5393. */
  5394. const EMAIL_VALIDATOR = {
  5395. provide: NG_VALIDATORS,
  5396. useExisting: forwardRef(() => EmailValidator),
  5397. multi: true
  5398. };
  5399. /**
  5400. * A Directive that adds the `email` validator to controls marked with the
  5401. * `email` attribute, via the {\@link NG_VALIDATORS} binding.
  5402. *
  5403. * ### Example
  5404. *
  5405. * ```
  5406. * <input type="email" name="email" ngModel email>
  5407. * <input type="email" name="email" ngModel email="true">
  5408. * <input type="email" name="email" ngModel [email]="true">
  5409. * ```
  5410. *
  5411. * \@experimental
  5412. */
  5413. class EmailValidator {
  5414. /**
  5415. * @param {?} value
  5416. * @return {?}
  5417. */
  5418. set email(value) {
  5419. this._enabled = value === '' || value === true || value === 'true';
  5420. if (this._onChange)
  5421. this._onChange();
  5422. }
  5423. /**
  5424. * @param {?} c
  5425. * @return {?}
  5426. */
  5427. validate(c) {
  5428. return this._enabled ? Validators.email(c) : null;
  5429. }
  5430. /**
  5431. * @param {?} fn
  5432. * @return {?}
  5433. */
  5434. registerOnValidatorChange(fn) { this._onChange = fn; }
  5435. }
  5436. EmailValidator.decorators = [
  5437. { type: Directive, args: [{
  5438. selector: '[email][formControlName],[email][formControl],[email][ngModel]',
  5439. providers: [EMAIL_VALIDATOR]
  5440. },] },
  5441. ];
  5442. /** @nocollapse */
  5443. EmailValidator.ctorParameters = () => [];
  5444. EmailValidator.propDecorators = {
  5445. "email": [{ type: Input },],
  5446. };
  5447. /**
  5448. * \@stable
  5449. * @record
  5450. */
  5451. /**
  5452. * \@stable
  5453. * @record
  5454. */
  5455. /**
  5456. * Provider which adds {\@link MinLengthValidator} to {\@link NG_VALIDATORS}.
  5457. *
  5458. * ## Example:
  5459. *
  5460. * {\@example common/forms/ts/validators/validators.ts region='min'}
  5461. */
  5462. const MIN_LENGTH_VALIDATOR = {
  5463. provide: NG_VALIDATORS,
  5464. useExisting: forwardRef(() => MinLengthValidator),
  5465. multi: true
  5466. };
  5467. /**
  5468. * A directive which installs the {\@link MinLengthValidator} for any `formControlName`,
  5469. * `formControl`, or control with `ngModel` that also has a `minlength` attribute.
  5470. *
  5471. * \@stable
  5472. */
  5473. class MinLengthValidator {
  5474. /**
  5475. * @param {?} changes
  5476. * @return {?}
  5477. */
  5478. ngOnChanges(changes) {
  5479. if ('minlength' in changes) {
  5480. this._createValidator();
  5481. if (this._onChange)
  5482. this._onChange();
  5483. }
  5484. }
  5485. /**
  5486. * @param {?} c
  5487. * @return {?}
  5488. */
  5489. validate(c) {
  5490. return this.minlength == null ? null : this._validator(c);
  5491. }
  5492. /**
  5493. * @param {?} fn
  5494. * @return {?}
  5495. */
  5496. registerOnValidatorChange(fn) { this._onChange = fn; }
  5497. /**
  5498. * @return {?}
  5499. */
  5500. _createValidator() {
  5501. this._validator = Validators.minLength(parseInt(this.minlength, 10));
  5502. }
  5503. }
  5504. MinLengthValidator.decorators = [
  5505. { type: Directive, args: [{
  5506. selector: '[minlength][formControlName],[minlength][formControl],[minlength][ngModel]',
  5507. providers: [MIN_LENGTH_VALIDATOR],
  5508. host: { '[attr.minlength]': 'minlength ? minlength : null' }
  5509. },] },
  5510. ];
  5511. /** @nocollapse */
  5512. MinLengthValidator.ctorParameters = () => [];
  5513. MinLengthValidator.propDecorators = {
  5514. "minlength": [{ type: Input },],
  5515. };
  5516. /**
  5517. * Provider which adds {\@link MaxLengthValidator} to {\@link NG_VALIDATORS}.
  5518. *
  5519. * ## Example:
  5520. *
  5521. * {\@example common/forms/ts/validators/validators.ts region='max'}
  5522. */
  5523. const MAX_LENGTH_VALIDATOR = {
  5524. provide: NG_VALIDATORS,
  5525. useExisting: forwardRef(() => MaxLengthValidator),
  5526. multi: true
  5527. };
  5528. /**
  5529. * A directive which installs the {\@link MaxLengthValidator} for any `formControlName,
  5530. * `formControl`,
  5531. * or control with `ngModel` that also has a `maxlength` attribute.
  5532. *
  5533. * \@stable
  5534. */
  5535. class MaxLengthValidator {
  5536. /**
  5537. * @param {?} changes
  5538. * @return {?}
  5539. */
  5540. ngOnChanges(changes) {
  5541. if ('maxlength' in changes) {
  5542. this._createValidator();
  5543. if (this._onChange)
  5544. this._onChange();
  5545. }
  5546. }
  5547. /**
  5548. * @param {?} c
  5549. * @return {?}
  5550. */
  5551. validate(c) {
  5552. return this.maxlength != null ? this._validator(c) : null;
  5553. }
  5554. /**
  5555. * @param {?} fn
  5556. * @return {?}
  5557. */
  5558. registerOnValidatorChange(fn) { this._onChange = fn; }
  5559. /**
  5560. * @return {?}
  5561. */
  5562. _createValidator() {
  5563. this._validator = Validators.maxLength(parseInt(this.maxlength, 10));
  5564. }
  5565. }
  5566. MaxLengthValidator.decorators = [
  5567. { type: Directive, args: [{
  5568. selector: '[maxlength][formControlName],[maxlength][formControl],[maxlength][ngModel]',
  5569. providers: [MAX_LENGTH_VALIDATOR],
  5570. host: { '[attr.maxlength]': 'maxlength ? maxlength : null' }
  5571. },] },
  5572. ];
  5573. /** @nocollapse */
  5574. MaxLengthValidator.ctorParameters = () => [];
  5575. MaxLengthValidator.propDecorators = {
  5576. "maxlength": [{ type: Input },],
  5577. };
  5578. const PATTERN_VALIDATOR = {
  5579. provide: NG_VALIDATORS,
  5580. useExisting: forwardRef(() => PatternValidator),
  5581. multi: true
  5582. };
  5583. /**
  5584. * A Directive that adds the `pattern` validator to any controls marked with the
  5585. * `pattern` attribute, via the {\@link NG_VALIDATORS} binding. Uses attribute value
  5586. * as the regex to validate Control value against. Follows pattern attribute
  5587. * semantics; i.e. regex must match entire Control value.
  5588. *
  5589. * ### Example
  5590. *
  5591. * ```
  5592. * <input [name]="fullName" pattern="[a-zA-Z ]*" ngModel>
  5593. * ```
  5594. * \@stable
  5595. */
  5596. class PatternValidator {
  5597. /**
  5598. * @param {?} changes
  5599. * @return {?}
  5600. */
  5601. ngOnChanges(changes) {
  5602. if ('pattern' in changes) {
  5603. this._createValidator();
  5604. if (this._onChange)
  5605. this._onChange();
  5606. }
  5607. }
  5608. /**
  5609. * @param {?} c
  5610. * @return {?}
  5611. */
  5612. validate(c) { return this._validator(c); }
  5613. /**
  5614. * @param {?} fn
  5615. * @return {?}
  5616. */
  5617. registerOnValidatorChange(fn) { this._onChange = fn; }
  5618. /**
  5619. * @return {?}
  5620. */
  5621. _createValidator() { this._validator = Validators.pattern(this.pattern); }
  5622. }
  5623. PatternValidator.decorators = [
  5624. { type: Directive, args: [{
  5625. selector: '[pattern][formControlName],[pattern][formControl],[pattern][ngModel]',
  5626. providers: [PATTERN_VALIDATOR],
  5627. host: { '[attr.pattern]': 'pattern ? pattern : null' }
  5628. },] },
  5629. ];
  5630. /** @nocollapse */
  5631. PatternValidator.ctorParameters = () => [];
  5632. PatternValidator.propDecorators = {
  5633. "pattern": [{ type: Input },],
  5634. };
  5635. /**
  5636. * @fileoverview added by tsickle
  5637. * @suppress {checkTypes} checked by tsc
  5638. */
  5639. /**
  5640. * @license
  5641. * Copyright Google Inc. All Rights Reserved.
  5642. *
  5643. * Use of this source code is governed by an MIT-style license that can be
  5644. * found in the LICENSE file at https://angular.io/license
  5645. */
  5646. /**
  5647. * \@whatItDoes Creates an {\@link AbstractControl} from a user-specified configuration.
  5648. *
  5649. * It is essentially syntactic sugar that shortens the `new FormGroup()`,
  5650. * `new FormControl()`, and `new FormArray()` boilerplate that can build up in larger
  5651. * forms.
  5652. *
  5653. * \@howToUse
  5654. *
  5655. * To use, inject `FormBuilder` into your component class. You can then call its methods
  5656. * directly.
  5657. *
  5658. * {\@example forms/ts/formBuilder/form_builder_example.ts region='Component'}
  5659. *
  5660. * * **npm package**: `\@angular/forms`
  5661. *
  5662. * * **NgModule**: {\@link ReactiveFormsModule}
  5663. *
  5664. * \@stable
  5665. */
  5666. class FormBuilder {
  5667. /**
  5668. * Construct a new {\@link FormGroup} with the given map of configuration.
  5669. * Valid keys for the `extra` parameter map are `validator` and `asyncValidator`.
  5670. *
  5671. * See the {\@link FormGroup} constructor for more details.
  5672. * @param {?} controlsConfig
  5673. * @param {?=} extra
  5674. * @return {?}
  5675. */
  5676. group(controlsConfig, extra = null) {
  5677. const /** @type {?} */ controls = this._reduceControls(controlsConfig);
  5678. const /** @type {?} */ validator = extra != null ? extra['validator'] : null;
  5679. const /** @type {?} */ asyncValidator = extra != null ? extra['asyncValidator'] : null;
  5680. return new FormGroup(controls, validator, asyncValidator);
  5681. }
  5682. /**
  5683. * Construct a new {\@link FormControl} with the given `formState`,`validator`, and
  5684. * `asyncValidator`.
  5685. *
  5686. * `formState` can either be a standalone value for the form control or an object
  5687. * that contains both a value and a disabled status.
  5688. *
  5689. * @param {?} formState
  5690. * @param {?=} validator
  5691. * @param {?=} asyncValidator
  5692. * @return {?}
  5693. */
  5694. control(formState, validator, asyncValidator) {
  5695. return new FormControl(formState, validator, asyncValidator);
  5696. }
  5697. /**
  5698. * Construct a {\@link FormArray} from the given `controlsConfig` array of
  5699. * configuration, with the given optional `validator` and `asyncValidator`.
  5700. * @param {?} controlsConfig
  5701. * @param {?=} validator
  5702. * @param {?=} asyncValidator
  5703. * @return {?}
  5704. */
  5705. array(controlsConfig, validator, asyncValidator) {
  5706. const /** @type {?} */ controls = controlsConfig.map(c => this._createControl(c));
  5707. return new FormArray(controls, validator, asyncValidator);
  5708. }
  5709. /**
  5710. * \@internal
  5711. * @param {?} controlsConfig
  5712. * @return {?}
  5713. */
  5714. _reduceControls(controlsConfig) {
  5715. const /** @type {?} */ controls = {};
  5716. Object.keys(controlsConfig).forEach(controlName => {
  5717. controls[controlName] = this._createControl(controlsConfig[controlName]);
  5718. });
  5719. return controls;
  5720. }
  5721. /**
  5722. * \@internal
  5723. * @param {?} controlConfig
  5724. * @return {?}
  5725. */
  5726. _createControl(controlConfig) {
  5727. if (controlConfig instanceof FormControl || controlConfig instanceof FormGroup ||
  5728. controlConfig instanceof FormArray) {
  5729. return controlConfig;
  5730. }
  5731. else if (Array.isArray(controlConfig)) {
  5732. const /** @type {?} */ value = controlConfig[0];
  5733. const /** @type {?} */ validator = controlConfig.length > 1 ? controlConfig[1] : null;
  5734. const /** @type {?} */ asyncValidator = controlConfig.length > 2 ? controlConfig[2] : null;
  5735. return this.control(value, validator, asyncValidator);
  5736. }
  5737. else {
  5738. return this.control(controlConfig);
  5739. }
  5740. }
  5741. }
  5742. FormBuilder.decorators = [
  5743. { type: Injectable },
  5744. ];
  5745. /** @nocollapse */
  5746. FormBuilder.ctorParameters = () => [];
  5747. /**
  5748. * @fileoverview added by tsickle
  5749. * @suppress {checkTypes} checked by tsc
  5750. */
  5751. /**
  5752. * @license
  5753. * Copyright Google Inc. All Rights Reserved.
  5754. *
  5755. * Use of this source code is governed by an MIT-style license that can be
  5756. * found in the LICENSE file at https://angular.io/license
  5757. */
  5758. /**
  5759. * \@stable
  5760. */
  5761. const VERSION = new Version('5.2.11');
  5762. /**
  5763. * @fileoverview added by tsickle
  5764. * @suppress {checkTypes} checked by tsc
  5765. */
  5766. /**
  5767. * @license
  5768. * Copyright Google Inc. All Rights Reserved.
  5769. *
  5770. * Use of this source code is governed by an MIT-style license that can be
  5771. * found in the LICENSE file at https://angular.io/license
  5772. */
  5773. /**
  5774. * \@whatItDoes Adds `novalidate` attribute to all forms by default.
  5775. *
  5776. * `novalidate` is used to disable browser's native form validation.
  5777. *
  5778. * If you want to use native validation with Angular forms, just add `ngNativeValidate` attribute:
  5779. *
  5780. * ```
  5781. * <form ngNativeValidate></form>
  5782. * ```
  5783. *
  5784. * \@experimental
  5785. */
  5786. class NgNoValidate {
  5787. }
  5788. NgNoValidate.decorators = [
  5789. { type: Directive, args: [{
  5790. selector: 'form:not([ngNoForm]):not([ngNativeValidate])',
  5791. host: { 'novalidate': '' },
  5792. },] },
  5793. ];
  5794. /** @nocollapse */
  5795. NgNoValidate.ctorParameters = () => [];
  5796. /**
  5797. * @fileoverview added by tsickle
  5798. * @suppress {checkTypes} checked by tsc
  5799. */
  5800. /**
  5801. * @license
  5802. * Copyright Google Inc. All Rights Reserved.
  5803. *
  5804. * Use of this source code is governed by an MIT-style license that can be
  5805. * found in the LICENSE file at https://angular.io/license
  5806. */
  5807. const SHARED_FORM_DIRECTIVES = [
  5808. NgNoValidate,
  5809. NgSelectOption,
  5810. NgSelectMultipleOption,
  5811. DefaultValueAccessor,
  5812. NumberValueAccessor,
  5813. RangeValueAccessor,
  5814. CheckboxControlValueAccessor,
  5815. SelectControlValueAccessor,
  5816. SelectMultipleControlValueAccessor,
  5817. RadioControlValueAccessor,
  5818. NgControlStatus,
  5819. NgControlStatusGroup,
  5820. RequiredValidator,
  5821. MinLengthValidator,
  5822. MaxLengthValidator,
  5823. PatternValidator,
  5824. CheckboxRequiredValidator,
  5825. EmailValidator,
  5826. ];
  5827. const TEMPLATE_DRIVEN_DIRECTIVES = [NgModel, NgModelGroup, NgForm];
  5828. const REACTIVE_DRIVEN_DIRECTIVES = [FormControlDirective, FormGroupDirective, FormControlName, FormGroupName, FormArrayName];
  5829. /**
  5830. * Internal module used for sharing directives between FormsModule and ReactiveFormsModule
  5831. */
  5832. class InternalFormsSharedModule {
  5833. }
  5834. InternalFormsSharedModule.decorators = [
  5835. { type: NgModule, args: [{
  5836. declarations: SHARED_FORM_DIRECTIVES,
  5837. exports: SHARED_FORM_DIRECTIVES,
  5838. },] },
  5839. ];
  5840. /** @nocollapse */
  5841. InternalFormsSharedModule.ctorParameters = () => [];
  5842. /**
  5843. * @fileoverview added by tsickle
  5844. * @suppress {checkTypes} checked by tsc
  5845. */
  5846. /**
  5847. * @license
  5848. * Copyright Google Inc. All Rights Reserved.
  5849. *
  5850. * Use of this source code is governed by an MIT-style license that can be
  5851. * found in the LICENSE file at https://angular.io/license
  5852. */
  5853. /**
  5854. * The ng module for forms.
  5855. * \@stable
  5856. */
  5857. class FormsModule {
  5858. }
  5859. FormsModule.decorators = [
  5860. { type: NgModule, args: [{
  5861. declarations: TEMPLATE_DRIVEN_DIRECTIVES,
  5862. providers: [RadioControlRegistry],
  5863. exports: [InternalFormsSharedModule, TEMPLATE_DRIVEN_DIRECTIVES]
  5864. },] },
  5865. ];
  5866. /** @nocollapse */
  5867. FormsModule.ctorParameters = () => [];
  5868. /**
  5869. * The ng module for reactive forms.
  5870. * \@stable
  5871. */
  5872. class ReactiveFormsModule {
  5873. }
  5874. ReactiveFormsModule.decorators = [
  5875. { type: NgModule, args: [{
  5876. declarations: [REACTIVE_DRIVEN_DIRECTIVES],
  5877. providers: [FormBuilder, RadioControlRegistry],
  5878. exports: [InternalFormsSharedModule, REACTIVE_DRIVEN_DIRECTIVES]
  5879. },] },
  5880. ];
  5881. /** @nocollapse */
  5882. ReactiveFormsModule.ctorParameters = () => [];
  5883. /**
  5884. * @fileoverview added by tsickle
  5885. * @suppress {checkTypes} checked by tsc
  5886. */
  5887. /**
  5888. * @license
  5889. * Copyright Google Inc. All Rights Reserved.
  5890. *
  5891. * Use of this source code is governed by an MIT-style license that can be
  5892. * found in the LICENSE file at https://angular.io/license
  5893. */
  5894. /**
  5895. * @fileoverview added by tsickle
  5896. * @suppress {checkTypes} checked by tsc
  5897. */
  5898. /**
  5899. * @license
  5900. * Copyright Google Inc. All Rights Reserved.
  5901. *
  5902. * Use of this source code is governed by an MIT-style license that can be
  5903. * found in the LICENSE file at https://angular.io/license
  5904. */
  5905. /**
  5906. * @module
  5907. * @description
  5908. * Entry point for all public APIs of this package.
  5909. */
  5910. // This file only reexports content of the `src` folder. Keep it that way.
  5911. /**
  5912. * @fileoverview added by tsickle
  5913. * @suppress {checkTypes} checked by tsc
  5914. */
  5915. /**
  5916. * Generated bundle index. Do not edit.
  5917. */
  5918. export { AbstractControlDirective, AbstractFormGroupDirective, CheckboxControlValueAccessor, ControlContainer, NG_VALUE_ACCESSOR, COMPOSITION_BUFFER_MODE, DefaultValueAccessor, NgControl, NgControlStatus, NgControlStatusGroup, NgForm, NgModel, NgModelGroup, RadioControlValueAccessor, 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, InternalFormsSharedModule as ɵba, REACTIVE_DRIVEN_DIRECTIVES as ɵz, SHARED_FORM_DIRECTIVES as ɵx, TEMPLATE_DRIVEN_DIRECTIVES as ɵy, CHECKBOX_VALUE_ACCESSOR as ɵa, DEFAULT_VALUE_ACCESSOR as ɵb, AbstractControlStatus as ɵc, ngControlStatusHost as ɵd, formDirectiveProvider as ɵe, formControlBinding as ɵf, modelGroupProvider as ɵg, NgNoValidate as ɵbf, NUMBER_VALUE_ACCESSOR as ɵbb, NumberValueAccessor as ɵbc, RADIO_VALUE_ACCESSOR as ɵh, RadioControlRegistry as ɵi, RANGE_VALUE_ACCESSOR as ɵbd, RangeValueAccessor as ɵbe, formControlBinding$1 as ɵj, controlNameBinding as ɵk, formDirectiveProvider$1 as ɵl, formArrayNameProvider as ɵn, formGroupNameProvider as ɵm, SELECT_VALUE_ACCESSOR as ɵo, NgSelectMultipleOption as ɵq, SELECT_MULTIPLE_VALUE_ACCESSOR as ɵp, CHECKBOX_REQUIRED_VALIDATOR as ɵs, EMAIL_VALIDATOR as ɵt, MAX_LENGTH_VALIDATOR as ɵv, MIN_LENGTH_VALIDATOR as ɵu, PATTERN_VALIDATOR as ɵw, REQUIRED_VALIDATOR as ɵr };
  5919. //# sourceMappingURL=forms.js.map