Izrada iskačućeg prozora (Modal)

Miodrag Trajanovic
7 min readJul 7, 2019

--

Izrada iskačućeg prozora (Modal)

U mnogim slučajevima potrebno je da se pojavi neki prostor na veb stranici sa nekim posebnim sadržajem koji bi korisnku omogućio na primer prijavu na neki veb prostor, registraciju, objašnjenje nekog drugog sadržaja.

Nebitno da li će to biti kao neki iskačući oblačić ili neki veći prostor sa nekim dodatnim infomracijama o nekoj temi.

Taj iskačući deo je potrebno da ima neke svoje osobine, ali i da putem prihvatanja vrednosti odredjenih unapred stanja da dodatne vrednosti prihvati kao props u react aplikacijama. I to kao svoje pod komponente (children)

Ovakvi delovi veb stranica uobičajeno se nazivaju Modal-i i popup-si. U oba slučaja možemo ih pozvati nekim od dogadjaja nebitno da li klikom miša, pritiskom na neko dugme tastature ili područje za pritisak kod mobilnih veb aplikacija.

Sastav ovakvih komponenti

Jednom rečiju ove komponente koje se pojavljuju i mogu prihvatiti i prikazati sadržaj drugih komponenti u sebi na veb stranicama su u samoj svojoj biti div html tagovi izmedju kojih se dodaje kod java skripta, kojim se omogućava da se njima dodaju drugi delovi ili komponente.

Kod koji one vraćaju bio bi nešto nalik ovom. Gde imamo dva div taga, gde prvi odredjuje dogadjanje sa pozadinom ispred koje se pojavljuje kontejner sa ciljnim sadržajem.

<div style ={stilovi.background} >
<div style ={stilovi.container} >
{this.props.children}
</div>
</div>

Dok sama komponenta u aplikacije bi se mogla pozvati sa rastavljenim tagovima

<Model>

<h1>Neki sasdrazj</h1>

</Model>

Razlog za ovakav sadržaj koda je to što se sadržaj izmedju h1 tagova tretira u ovom slučaju kao podkomponeta ili child jer na to obavezuje javaskript kod

{this.props.children}

Koji kaže da sve što se nadje izmedju tagova

<Model>

</Model>

je sadržaj podkomponete react aplikacije, to jest da to samo se može kako je postavljeno vrednostima stanja pročitati i prikazati bez ikavih promena. Što je i osnov razmene podataka izmedju roditeljske i dečije komponente. Naravno, svemu ovom da bi se osigurao siguran prikaz komponente Model iznad svih ostalih potrebno je i dodati css kod z-index: 1000; ili neki veći broj . Veći broj omogućava postavljanje ispred ostalih , a manji suprotno. Dobra je primena ovog kod neki animacija.

Drugo što je bitno da bi sve ovo moglo da radi je dogadjaji kojim bi se omogućilo prikazivanje ovakvih komponenti i njihovih budućih sadržaja. To se postiže dodavanjem novih vednosti stanja koje omogućavaju da se ove komponente prikažu. Te je zato potrebno da se i u polaznim komponentam gde se ove pozivaju odrediti polazno stanje. Koje je u ovim situacijama da se ovakve komponente ne prikazuju odmah nego po potrebi. Pa je to polazno stanje u našem slučaju kod niže:

state={ showModal : false };

I sve dok je ovo stanje aktivno komponenta se ne prikazuje, a biće prikazana kada se ova vrednost stanja promeni na istinu ili true.

onClick ={()=> this.setState({ showModal: true })

Ne bitno da li će ovo biti vezano za celokupnu površinu ekranskog prikaza ili za samo jedno jedino slovo na njoj. Odvijaće se potpuno isti dogadjaj. To jest komponenta biće prikazana sve dok ne kliknemo van tog dela površine gde smo odredili daje pozove i prikaže ili na nešto drugo na površini prikazane komponente. Ili možda na neko dugme na tastaturi. Sasvim sve jedno. U ovom slučaju to se dešava ako se klikne na deo koji se odnosi na komponentu pod nazivom Clickable, koja sadrži dogadjaj onClick koji postavlja novu vrednost stanja za promenjivu showModal.

<Clickable

onClick ={()=> this.setState({
showModal : true,
})
}>
<Title>Singup</Title>
</Clickable>

Naravno mogao sam upotrebiti bilo koje ime za ovu komponentu, kao i za komponentu Title.

Komponeneta Clickable

Šta je ovde posebno? Ovim sadržaj koda hteo sam da prikažem mogućnosti za konstrukciju samomg koda i način pozivanja css koda u react aplikacijama.

Css kod nemora biti napisan samo u okviru css failova, već može da bude i ovako napisan u okviru koda same komponente, što se može suresti kod posebne aplikacije Rekit kojom isto tako možete izradjivati aplikacije u reactu. Bliže o ovome na linku

https://rekit.js.org/

Dok sam način pozivanja css koda može se pozivati skraćeno upotrebom spred operatora ( upotreba tri tačke ispred naziva onog što u ovom slučaju pozivamo).

Stilove smeštamo u JSON formatu kao vrednosti promenjive ili konstante

// Stulovi za komponenetu Clickableconst clickableStyles = {cursor: 'pointer', userSelect: 'none'};

I pozivamo kao kod dole niže:

...clickableStyles

Ovim načinom sve vrednosti kostante dodeljuju onamo gde ih pozivamo. Napravljena je Clikable komponenta napravljena je s ciljem da se prikaže način za povezivanje više akcija koje se pozivaju na izvršenje jednim pozivom. Gde su takodje zadane početne vrednosti stanja dogadjaja koji će biti upotrebljeni, a koji se takodje prikazuju čime se upotpunjava slika radnji u prikazu.

Dogadjaje koje sam obuhvatio vezani su za pokazivač kojim upravlja uredjaj pod nazivom MIŠ. I to:

mouseOut, mouseOver koji otkrivaju prolazak pokazivača preko dela na veb stranici (efekt hover) i da li je levi tasteer miša pritisnut ili ne ( mouseDown i mouseUp). U ovu svrhu može se upotrebiti i pritisak na taster tastature desktop računara ili područja za pritisak kod mobilnih aplikacija.

// Stilovi za komponenetu Clickableconst clickableStyles = {cursor: 'pointer', userSelect: 'none'};// komponeneta Clickableclass Clickable extends React.Component {    state={hover: false, down: false};    mouseOver =()=>{
this.setState({ hover: true})
};
mouseOut =()=>{
this.setState({ hover: false})
};
mouseDown =()=>{
this.setState({ down: true})
};
mouseUp =()=>{
this.setState({ down: false})
};
render() { // console.log(this.state,'klikable'); return( <div onMouseOver={this.mouseOver} onMouseOut={this.mouseOut} onMouseDown={this.mouseDown} onMouseUp ={ this.mouseUp} onClick={this.props.onClick} style={{...clickableStyles,color: this.state.down ? 'black' : 'white',opacity: this.state.hover ? 0.5 : 1
}}
>
{this.props.children}
</div>
);
}
}

Kao što kod prikazuje opet je upotrebljen div tag koji sadrži u sebi pozive vednosti dogadjanja i stilove izgleda opisa, ali opet je prisutno postavljenje kojim se odreduje da je ono što izmedju tagova kojim se odredjuje komponenta prilikom poziva u drugim komponentama je sadržaj kalsifikovan kao pod komponeneta, jer se vrši očitavanje vrednosti postavljenih vrednostima stanja {this.props.children}.
Dok je upotrebom

onClick={this.props.onClick}

prihvaćeno da se upotrebom očitanih vrednosti props one i pozivaju iz stanja sa mesta poziva gde se komponeta i postavlja

<Clickable onClick ={()=> this.setState({ showModal: true }) }>

Tako da je omogućeno da klikom na sveukupnoj površini koju zauzima komponenta Clickable, odredjeno css stilom omogućava da možemo da klikom promenimo stanje promenjive showModal ili direktno klikom na podkomponentu Title. Dok se komponenta Modal poziva postavljenim kodom van nje. U ovom slučaju upotrebljen je operator &&. Koji vraća istinu ako su oba uslova ispunjenja. Znači ako je vrednost stanja promenjive showModal istinita i ako postoji u ovom slučaju komponenta Model. U suprotnom komponenta Model u ovom slučaju neće biti prikazana.

{this.state.showModal &&<Model onClosed={this.zatvori} >                      
<div style={{backgroundColor: 'pink',height:80}}>
<h1>Zaglavlje Modala</h1>
<div style={{color: 'darkblue'}}>
<h1>Naslov Modala</h1>
</div>
</div>
<div><h1>Telo Modala</h1></div> <div> <h1>Dno Modala</h1> <button style={{backgroundColor:'pink',marginRight:10}}>
Dugme prvo
</button>
<button onClick={this.zatvori}>
Zatvori
</button>
</div>
</Model>}

Sklanjanje ili isključenje pozvane komponente Modal

U ovu namenu primenjen je metod zatvori, čijim se pozivanjem vrednost stanja promenjive showModal menja, u prvobitno stanje neistina (false)

zatvori=()=>{
this.setState({showModal: false})
};

Njegovim pozivom se obustavlja prikazivanje komponente Model. Ali obustavljanje prikazivanja pozvane komponente potrebno je omogućiti i klikom bilo gde na ekranskom prikazu ili na neko dugme i sl. Ova promena stanja se u komponenti Model očitava kao props

this.props.onClosed();

koje se poziva u metodu

clickedBackground = () =>{
this.props.onClosed() ;
};

Koji se nalazi u kodu same komponete Model. I on omgućava da se klikom bilo gde pa i preko same komponente izazove njeno zatvaranje (ne prikazivanje).

Što nije dobro. Pa se primenom koda koji se odnosi na sam kontejner u kome je smeštena (u komponenti Model)pod komponenta dodat uslov propagacije, odnosno da se njenim zaustavljanjem onemogućava navedena pojava.

<div style ={stilovi.container}

onClick = {e => e.stopPropagation()}>
{this.props.children}
</div>

Napomena: stilovi.container je klasičan način pozivanja vrednosti iz konstante i on se primenjuje svuda u prorgamiranju gde su programski govori nastali iz programskog govora C. Tačka izmedju ovih reči ima ulogu nastavka slično kao kod računske radnje plus prilikom računanja, sa bitnom razlikom što se kod ovih slučajeva kaže: iz promenjive ili konstante ili nečeg drugog uzima za dodelu vrednosti vrednost koju nam daje sadržj koji sadrži druga reč. Na netu pronaćićete tako nesto kao (Concatenation), u prevodu

Povezivanje dvaju nizova.

Postoje dva operatora niza. Prvi je operator ulančavanja (‘.’) Koji vraća ulančavanje njegovih desnih i lijevih argumenata. Drugi je spajajući operator dodjeljivanja (‘. =’), Koji dodaje argument s desne strane argumentu na lijevoj strani.

Kompletan kod svih komponenti

/** * Created by trika on 06-Jul-19. */import React from 'react';const styles = {
kontejner:{
width:'100%',
height:'100%',
backgroundImage:'linear-gradient(to top right, Pink, Purple)',
// backgroundColor: ' yellow',
display:'flex',
alignItems:'center',
justifyContent:'center'
},
drugi_stil: {
color: 'red'
}
};
export default class App extends React.Component{ state={ showModal : false }; zatvori=()=>{
this.setState({showModal: false})
};
render(){ return( <div style={styles.kontejner}>
<Clickable onClick ={()=> this.setState({
showModal: true,
})
}>
<Title>Singup</Title> </Clickable> {this.state.showModal &&
<Model onClosed={this.zatvori} >
<div
style={{backgroundColor: 'pink',height:80}}>
Zaglavlje Modala
<div style={{color: 'darkblue'}}>
Naslov Modala
</div>
</div>
<div>Telo Modala</div> <div> Dno Modala <button
style={{backgroundColor:'pink',marginRight:10}}
>
Dugme prvo
</button>
<button onClick={this.zatvori}>
Zatvori
</button>
</div>
</Model>}
</div>
)
}
}
// stilovi za komponentu Titleconst titleStyles ={ color:'red', fontSize: 90, textTransform:'uppercase',letterSpacing:6};// Komponeneta Titleconst Title = ({children})=>{ return( <div style={titleStyles}> {children} </div> );};// dodavanje podrucja u kome se moze kliknuti// Stulovi za komponenetu Clickableconst clickableStyles = {cursor: 'pointer', userSelect: 'none'};// komponeneta Clickableclass Clickable extends React.Component { state={hover: false, down: false}; mouseOver =()=>{ this.setState({ hover: true}) }; mouseOut =()=>{ this.setState({ hover: false}) }; mouseDown =()=>{ this.setState({ down: true}) }; mouseUp =()=>{ this.setState({ down: false}) }; render() { // console.log(this.state,'klikable'); return( <div onMouseOver={this.mouseOver} onMouseOut={this.mouseOut} onMouseDown={this.mouseDown} onMouseUp ={ this.mouseUp} onClick={this.props.onClick} style={{ ...clickableStyles,color: this.state.down ? 'black' : 'white',opacity: this.state.hover ? 0.5 : 1 }} > {this.props.children} </div> ); }}// modal stilviconst stilovi ={ background:{ position:'absolute', top:0, left:0, width: '100%', height: '100%', backgroundColor: '#33330088', display:'flex', alignItems:'center', justifyContent:'center' }, container:{ backgroundColor: 'darkblue', borderRadius:'10', boxShadow:' 0 0 10px #440000ee', // velicina prozora modala width: 650, height: 200, color:'green', padding: 50 }};// modal komponenta class Model extends React.Component { clickedBackground = () =>{ this.props.onClosed() ; }; render() { console.log(this.state,'iz modala'); return( <div style ={stilovi.background}onClick = {this.clickedBackground}> <div style ={stilovi.container}onClick = {e => e.stopPropagation()}> {this.props.children} </div> </div> ); }}

--

--

Miodrag Trajanovic

Simple MAN, on the path of knowledge, time, I observe the world from the island of knowledge that I built with the help of my teachers that God Himself gave me