Komponente web aplikacije 12/16/2018 8 Dinamika na klijentskoj strani •To su web strane koje...
Transcript of Komponente web aplikacije 12/16/2018 8 Dinamika na klijentskoj strani •To su web strane koje...
12/16/2018
1
Uvod u web programiranje
Komponente web aplikacije
•Web server
•Browser
•HTTP (Hypertext Transfer Protocol)
2
12/16/2018
2
Web server
• Web server je softver koji upravlja web stranama i čini ih raspoloživim za browsere klijenata
• IIS(Internet Information Services) je web server koji se isporučuje uz Windows operativne sisteme
• Skladišti web stranice
• Obrađuje korisničke zahteve
• Izvršavanje serverskog koda
• Šalje HTML sadržaj klijentu putem HTTP protokola
3
Najpoznatiji web serveri• Apache, Tomcat, JBoss (Linux)
• Internet Information Services (Windows, Microsoft)
• Server za razvoj aplikacija - live server
4
12/16/2018
3
Web server
5
Često se pod web serverom podrazumeva i računar na kome se program (servis) web server izvršava
Web browseri
• Google Chrome
• Mozilla Firefox
• Microsoft Edge
6
12/16/2018
4
Uloga web browsera
• Web browser je program za pristup internetu
• U browseru se unosi adresa web strane čime se generiše zahtev ka web serveru
• Web browser omogućava prikaz web strane koju kao odgovor na zahtev vraća web server
• Web strana se sastoji od HTML teksta
• HTML je platformski nezavistan jezik baziran na tekstu
• Web browseri omogućavaju izvršavanje klijentskog koda kao što je javascript
7
HTTP
• Hypertext Transfer Protocol je jedan od internet protokola
• HTTP je komunikacioni protokol baziran na tekstu koga web browser koristi da bi uputio zahtev web serveru, a web server da bi poslao odgovor nazad ka web browseru
• HTTP poruke se razmenjuju korišćenjem porta 80
• HTTPS je varijanta HTTP protokola koja koristi algoritam za zaštitu sadržaja zahteva i odgovora i koristi port 443
8
12/16/2018
5
Statička Web strana
• Sastoji se od HTML koda kreiranog u tekst editoru ili nekom od editora za Web strane
• Preporučuje se editor VS Code
• Statička web strana se može kreirati u VS 2017
• Ima ekstenziju .html
• Isporučuje se korisniku onako kako se čuva na serveru
• To je html dokument koji se čuva na fajl sistemu servera
• Prikazuje iste informacije svim korisnicima
• Statička html strana ne može npr. prikazati tekuće vreme na serveru kada jegenerisan zahtev
9
VS Code editor
10
12/16/2018
6
VS Code upotreba Emmet html snipeta
11
Primer statičke strane-1<!DOCTYPE html><html lang="en">
<head><title>Statička web strana</title>
</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1">
</head><body>
<h1>Statička strana</h1><p>
Sadrzaj staticke strane se ne menja, vec je strana ista za sve korisnike.</p>
</body></html>
12
12/16/2018
7
Ekstenzija Live Server
13
Strana pokrenuta na serveru
14
12/16/2018
8
Dinamika na klijentskoj strani
• To su web strane koje izvršavaju i klijentski kod
• Autor web strane kreira html dokument, autor takođe piše skup instrukcija u nekom drugom jeziku (npr. java script) koji se može nalaziti u istom html fajlu ili u odvojenom fajlu
• Korisnik u svom web browser-u zahteva web stranu
• Web server locira web stranu i fajl koji sadrži instrukcije
• Web server šalje HTML strim i instrukcije nazad do klijenta
• Modul unutar browser-a obrađuje instrukcije i konvertuje ih u HTML unutar htm strane
• Browser obrađuje HTML stranu i prikazuje je klijentu
15
Nedostaci korišćenja klijentskih skriptova
• Potrebno je dosta vremena da se strana učita
• Različiti browseri mogu interpretiraju skript kod na klijentskoj strani različito
• Problem sa korišćenjem serverskih resursa kao što je npr. baza podataka
• Skript kod na klijentskoj strani nije bezbedan
16
12/16/2018
9
Primer pisanja klijentskog koda<body>
<script>function Promeni(a=0) {
var slika = document.getElementById("img1"); if (a == 0) {
slika.src = "Slike/1.gif";}if (a == 1) {
slika.src = "Slike/2.gif";}
}</script>
<h1>Dinamika na klijentskoj strani</h1><img id="img1" src="Slike/1.gif" alt="Broj 1" width="150" onmouseover="Promeni(1)"
onmouseout="Promeni()" ></body>
17
VS Code
18
12/16/2018
10
Dinamika na klijentskoj strani
19
Dinamika na serverskoj strani
• ASP.NET Core MVC web aplikacije
• Serverski kod se piše u programskom jeziku C#
• Korisnik unosi URL adresu u browseru i korisnički zahtev se prosleđuje serveru
• Web server obrađuje zahtev, locira klasu – kontroler, locira metodu kontrolera i eventualno prosleđuje parametre metodi
• Izvršava se serverski kod, tako što kontroler preuzima podatke iz baze posredstvom modela, prosleđuje ih pogledu, koji je zadužen za generisanje korisničkog interfejsa
• Generiše se html i web server prosleđuje html klijentu
• Browser klijenta interpretira html i prikazuje stranu u web browseru
20
12/16/2018
11
Uvod u Html
Šta je HTML?
• HTML je akronim od Hyper Text Markup Language• Hyper text je tekst koji sadrži linkove ka drugim dokumentima• HTML je opisni jezik namenjen za opis web strana• HTML jezik je skup opisnih tagova• HTML dokumenti sadrže HTML tagove i običan tekst• HTML se koristi za kreiranja sadržaja strane i metapodataka
koje koriste browseri da prikažu informacije• HTML strane mogu se kreirati i pomoću najjednostavnijeg
tekstualnog editora• HTML stranice imaju ekstenziju .html
22
12/16/2018
12
Okruženje VS Code
• Kreiraj folder HTML
• Otvori folder u okruženju VS Code File->Open Folder
• Kreirajte novi fajl pod nazivom Strana01.html
23
Kreiranje html fajla u okruženju VS Code
24snippet: html:5
12/16/2018
13
Struktura html strane
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Prva html strana</title>
</head>
<body>
</body></html>
25
Pokretanje strane na Live Serveru
26
12/16/2018
14
Osnovna struktura HTML dokumenta
• DOCTYPE deklaracija koja služi sa specificiranje verzije HTML-a koga stranica koristi
• Html sekcija sadrži zaglavlje html dokumenta i telo html dokumenta
• Zaglavlje sadrži informacije o html strani koje koristi browser i mašine za pretraživanje, tu je i naslov strane
• Telo sadrži deo html strane koji je vidljiv korisniku
27
DOCTYPE deklaracija
<!DOCTYPE html> Radi se o html deklaraciji verzija 5
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
Document Type Definition
28
12/16/2018
15
Kreiranje css fajla
29
Referenciranje css fajlasnippet: link:css
30
12/16/2018
16
Head deo HTML dokumenta
31
<head><meta charset="UTF-8"><title>Prva html strana</title><link rel="stylesheet" href="Stil1.css">
</head>
Izgled html strane
32
12/16/2018
17
Metapodaci
• Meta element je opcioni element koji se nalazi unutar head elementa
• Pomoću meta elementa se specificira i skup karaktera koji se koriste na strani charset='utf-8'
• Koristi se za specificiranje metapodataka koji obezbeđuju informacije o sadržaju dokumenta
• Neki meta elementi obezbeđuju informacije koje mašine za pretraživanje koriste pri indeksiranju strana
33
Element <meta/>
<head><title>Prva html strana</title>
<meta charset="utf-8" /><link href="StyleSheet1.css" rel="stylesheet" /><meta name="keywords" content="HTML, CSS, XML, JavaScript, C#, ASP.NET"/><meta name="description" content="Uvod u HTML5 programiranje" /><meta name="author" content="Goran Aritonovic" />
</head>
34
12/16/2018
18
Elementi atributi i sadržaj
• Svaki html element govori browseru o informaciji koja se nalazi između njegovog početnog i završnog taga
• Elementi koji nemaju sadržaj nazivaju se prazni elementi, i oni se zatvaraju u početnom tagu, npr.
<br>
• Atributi se nalaze unutar start taga elementa i imaju svoje ime i vrednost
• Ime atributa treba biti napisano malim slovima
<imetaga atr1="vr1">sadrzaj</imetaga>
35
Naslovi i paragrafi
• Tag <p> služi za definisanje paragrafa
• Browser automatski dodaje praznu liniju pre i posle paragrafa
• Gornja i donja margina paragrafa je 1em odnosno 16px
• Tagovi <h1>, <h2>, <h3>, <h4>, <h5> i <h6> služe za definisanje 6 nivoa naslova
• Spadaju u grupu blok elemenata, tj. počinju novom linijom kada se prikazuju
36
12/16/2018
19
Telo html dokumenta
<body><h1>Element h1</h1><h2>Element h2</h2><h3>Element h3</h3><h4>Element h4</h4><h5>Element h5</h5><h6>Element h6</h6>
<p>Prvi paragraf</p><p>Drugi paragraf</p>
</body>
37
Prikaz HTML dokumenta
38
CRL + SHIFT + I
12/16/2018
20
Definicije elemenata
39
HTML komentari
• Komentari se ne prikazuju u browseru
• Koriste se i pri debagovanju koda
<!--Ovo se nece prikazati-->
40
12/16/2018
21
Inline elementi
• To su elementi koji ne počinju novom linijom i nalaze se unutar blok elemenata
• <strong> element služi za definisanje teksta koji je važniji u odnosu na tekst koji ga okružuje, obično browser renderuje taj tekst kao boldovan
• <em> element služi za naglašavanje teksta, i browser ga renderuje obično kao iskošeni tekst
• Moguće je koristiti <b> i <i> elemente za prikaz boldovanog i iskošenog teksta
41
Podrazumevana definicija strong i em elementa
<style type="text/css">strong {
font-weight: bold;}
em {font-style: italic;
}</style>
42
12/16/2018
22
Upotreba strong i em elementa
<p>Ovo je <strong>vazan tekst</strong> u odnosu na okolni tekst <em>Ovo je naglaseni tekst.</em></p>
43
Markiranje teksta
44
<h2>Ovo je <mark>markirani</mark> tekst</h2>
12/16/2018
23
Tagovi <br> i <hr>Tag <br> je prazan tag koji se koristi za završetak tekuće linije teksta i prelazak u novu liniju.
<hr> tag se koristi za prikaz horizontalne linije
<body><p>
Prvi paragraf</p><hr><p>
Ovo je drugi paragraf <br />Ovo je prva linija teksta <br />Ovo je druga linija teksta <br/>Ovo je treca linija teksta
</p></body> 45
Prikaz na web strani
46
12/16/2018
24
Kreiranje odeljka
• Element div definiše odeljak html dokumenta
• Koristi se za grupisanje blok elemenata
• Div element je blok element koji se koristi za podelu HTML dokumenta u logičke celine
• Može se formatirati i pozicionirati korišćenjem css-a
• Može sadržati tekst, inline elemente i druge blok elemente
• Podrazumevano div element nema margine, border i padding
47
Definicija div elementa<!DOCTYPE html><html><head>
<meta charset="utf-8" /><title>Element div</title>
</head><body>
<div>Prvi div
</div><div>
Drugi div</div>
</body></html>
48
12/16/2018
25
Odeljak
49
<div style="width:300px; height:100px; background-color:#0094ff; padding:5px;"><h2>Naslov</h2><p>Paragraf</p>
</div>
Podela strane na logičke celine<body>
<div class="container"><header>
<h1>Tehnologije</h1></header><nav>
<ul><li><a href="#">HTML</a></li><li><a href="#">CSS</a></li><li><a href="#">JavaScript</a></li>
</ul></nav>
<article><p>
</p></article>
<footer>Copyright © BBS2017
</footer>
</div></body> 50
12/16/2018
26
Css za pozicioniranje
51
<style>div.container {
width: 100%;margin:auto;border:1px solid grey;
}header, footer {
padding: 10px;color: white;background-color: #0c4182;clear: left;text-align: center;
}nav {
float: left;max-width: 160px;margin: 0;padding: 10px;
} article {
margin-left: 150px;border-left: 1px solid gray;padding: 10px;overflow: hidden;
}</style>
Prostorna organizacija strane
52
12/16/2018
27
Span element
• Span element je inline element
• Koristi se za grupisanje inline elemenata
• Omogućava da se identifikuje tekst koji će se formatirati sa css-om
• Omogućava da se tekst unutar nekog blok elementa formatira na specijalan način
• Span element omogućava različite manipulacije tekstom pomoću javascript koda
53
Span element<!DOCTYPE html><html><head>
<title>Span element</title><style>
.blue {color: blue;font-weight: bold;
}.green {
color: green;font-weight: bold;
}p {
color: gray;}
</style></head><body>
<p>Ovo je <span class="blue">plava boja</span>, a ovo je<span class="green">zelena boja</span> teksta.
</p></body></html> 54
12/16/2018
28
Ilustracija upotrebe span elementa
55
Prikaz specijalnih karaktera
Result Description Entity Name
non-breaking space
< less than <
> greater than >
& ampersand &
¢ cent ¢
£ pound £
¥ yen ¥
€ euro €
© copyright ©
® registered trademark ®
56
12/16/2018
29
Liste
• Liste sa bulitima(ul - unordered list)
• Liste sa brojevima (ol-ordered list)
• Opisne liste (dl – description list)
57
Liste sa bulitima
58
Stilovi liste
list-style-type:disc (podrazumevana opcija)
list-style-type:circle
list-style-type:square
list-style-type:none
<body><p>Ovo su HTML editori:</p><ul>
<li>Notepad++</li><li>VS Code</li><li>Visual Studio</li>
</ul><p>Editori koda:</p>
</body>
12/16/2018
30
Podrazumevano formatiranje ul elementa
59
ul {display: block;list-style-type: disc;margin-top: 1em;margin-bottom: 1 em;margin-left: 0;margin-right: 0;padding-left: 40px;
}
Lista sa bulitima
60
<head><title></title><meta charset="utf-8" /><style>
ul{list-style-type:square;padding:20px;
}</style>
</head>
12/16/2018
31
Horizontalni prikaz liste
61
<style>ul{
padding:0px;}li{
display:inline;}
</style>
Liste sa brojevima
62
<body><p>Staticke web strane se kreiraju na sledeci nacin:</p><ol>
<li>Kreira se novi tekst fajl</li><li>Unutra se dodaje HTML</li><li>Fajl se cuva unutar web sajta</li>
</ol><p>Kraj</p>
</body>
list-style-type: decimal;
12/16/2018
32
Liste sa brojevima
63
<style>ol{
list-style-type:lower-alpha;}
</style>
Opisna lista
<dl><dt>Ime: </dt><dd>Marko</dd>
<dt>Prezime: </dt><dd>Petrovic</dd>
<dt>Starost: </dt><dd>23</dd>
</dl>
64
12/16/2018
33
Podrazumevanevrednosti opisne liste
65
dd {display: block;margin-left: 40px;
}
dt {display: block;
}
Ugnježdavanje listi
<body><ul>
<li>Opcija 1</li><li>Opcija 2 </li><li>
Opcija 3 <ul>
<li>Opcija 3.1</li><li>Opcija 3.2</li>
</ul></li><li>Opcija 4</li>
</ul></body></html>
66
12/16/2018
34
Prikaz ugnježdenih listi
67
<img> element
• Koristi se za prikaz slike na web strani
• Atribut src specificira lokaciju slike koju treba prikazati, ovo je obavezan atribut
• Atribut alt specificira alternativni tekst kada se slika iz nekog razloga ne može prikazati
• Atributi height, width specificiraju dimenzije slike u pikselima
• Atribut title definiše hover tekst iznad slike
68
12/16/2018
35
<img> element<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Prikaz slike</title>
</head>
<body>
<img src="/Slike/html.png" alt="HTML 5 logo" title="HTML 5" width="100" height="100">
</body>
</html>
69
Prikaz slike
70
12/16/2018
36
<a> anchor element
• Atribut href specificira web stranu na koju se vrši linkovanje
• Atribut target specificira, gde se prikazuje linkovana strana:• _blank, otvara se u novom prozoru ili tabu• _self, otvara se u istom frejmu gde je kliknuto (default opcija)
• Može se specificirati URL u istom folderu, URL u odnosu na root web sajta ili relativno u odnosu na tekući folder
• Može se specificirati URL na različitom serveru
• Može se specificirati deo html dokumenta na koji se vrši navigacija #fragment2
71
Definisanje linkova
72
<a href="/Folder1/Stranaf1.html">U odnosu na root</a>
<a href="../Folder1/Stranaf1.html">Prvo se pomeramo nivo gore</a>
<a href="Stranaf1.html">Isti folder kao tekuca strana</a>
<a href="http://www.Microsoft.com"> URL na razlicitom serveru</a>
<a href="Folder11/Strana11.html">Relativna adresa u odnosu na tekuci folder</a>
12/16/2018
37
Link na element strane
<body><p><a href="#p4">Idi poglavlje 4</a></p>
<h2>poglavlje 1</h2><p>ovo poglavlje objasnjava text text</p>
<h2>poglavlje 2</h2><p>ovo poglavlje objasnjava text text</p>
<h2>poglavlje 3</h2><p>ovo poglavlje objasnjava text text</p>
<h2 id="p4">poglavlje 4</h2><p>ovo poglavlje objasnjava text text</p>
<h2>poglavlje 5</h2><p>ovo poglavlje objasnjava text text</p>
73
Slika kao link
<!DOCTYPE html><html><head>
<title></title><meta charset="utf-8" /></head><body>
<a href="Strana01.html"><img src="Slike/logo.png" width="100" />
</a></body></html>
74
12/16/2018
38
Tabela
75
<head><title></title>
<meta charset="utf-8" /><style>
table{width:200px;
}</style>
</head><body>
<table><tr>
<td>Marko</td><td>Markovic</td><td>50</td>
</tr><tr>
<td>Mika</td><td>Mikic</td><td>94</td>
</tr><tr>
<td>Laza</td><td>Lazic</td><td>80</td>
</tr></table>
</body>
Tabela sa naslovom
76
<table><tr>
<th>Ime</th><th>Prezime</th><th>Poeni</th>
</tr><tr>
<td>Marko</td><td>Markovic</td><td>50</td>
</tr><tr>
<td>Mika</td><td>Mikic</td><td>94</td>
</tr><tr>
<td>Laza</td><td>Lazic</td><td>80</td>
</tr></table>
12/16/2018
39
Levo ravnjanje naslova
77
<style>table{
width:200px;}th {text-align: left;}
</style>
Definisanje bordera table i ćelija tabele
78
<style>table{
width:200px;}th {text-align: left;} table, th, td {border: 1px solid black;}
</style>
12/16/2018
40
Svojstvo border-collapse
79
table, th, td {border: 1px solid black;border-collapse:collapse;}
Definisanje padding za ćelije
80
th, td {padding: 10px;
}
12/16/2018
41
Naslov tabele
81
<table><caption>Rezultati</caption>
<tr><th>Ime</th><th>Prezime</th><th>Poeni</th>
</tr><tr>
<td>Marko</td><td>Markovic</td><td>50</td>
</tr><tr>
<td>Mika</td><td>Mikic</td><td>94</td>
</tr><tr>
<td>Laza</td><td>Lazic</td><td>80</td>
</tr>
</table>
Definisanje boja tabele
82
table{width:200px;background-color:#e4a027;
}
th{background-color: #4CAF50;color:white;
}
12/16/2018
42
Formatiranje neparnih redova
83
table tr:nth-child(2n+1) {background-color: #e24949;
}
Pitanje 1
Za prikaz liste sa bulitima koristi se:a. <ol>b. <ul>c. <bl>
Odgovor: b
84
12/16/2018
43
Pitanje 2
Kako se kod html hiperlinka <a> specificira strana na koju se vrši redirekcijaa. pomoću atributa hrefb. pomoću atributa urlc. pomoću teksta koji je prikazan između početnog i završnog taga
Odgovor: a
85
Pitanje 3
Unutar definicijsle liste nalaze se:a. <li> elementib. <ul> elementic. <dt> i <dd> elementi
Odgovor: c
86
12/16/2018
44
Pitanje 4
Koji od navedenih html elemenata ne pripada grupi blok elemenata:a. <span>b. <div>c. <p>
Odgovor: a
87
Pitanje 5
Zaokružite Microsoftov web server za windows operativne sisteme:a. Apacheb. Internet Information Servicesc. JBoss
Odgovor: b
88
12/16/2018
45
Uvod u JavaScript
JavaScript varijante
• JavaScript je prvenstveno korišćen za klijentsko programiranje• Client-side JavaScript • Izvršava se u browseru klijenta
• Postoji i JavaScript kod koji se izvršava na serveru• Server-side JavaScript , izvršava se na serveru i kreira dinamički sadržaj koji se
šalje do browsera• Node.js serverski Java script, nastao 2009. godine• Node.js je serverska platforma bazirana na script mašini Google chrome
browsera• Godine 2010 napravljen je menadžer pakeda za Node.js pod nazivom npm
90
12/16/2018
46
TypeScript
• TypeScript je programski jezik otvorenog koda razvijen od strane Microsofta, 2012. godine
• Kompajlira se u čist JavaScript
• Tekuća verzija TypeScript 3.1
• TypeScript je programski jezik koji predstavlja proširenje javascripta, dodaje tipove podataka, klase i module u JavaScript
• Koristi se za kreiranje javascript koda koji se može izvršavati i na klijentu i na serveru
91
Klijentski JavaScript
• Koristi se za izradu klijentskih delova web aplikacija
• Baziran na C sintaksi
• Java script kod se interpretira (ne kompajlira se)
• JavaScript je programski jezik koji podržava:• Promenljive za čuvanje informacija
• Operatore za izvođenje operacija i poređenje
• Funkcije za grupisanje koda u celine koje se mogu više puta pozivati
• Uslovne izraze i programske petlje za kontrolu programskog toka
• Mogućnost kreiranja objekata sa svojstvima, metodama i događajima
92
12/16/2018
47
Izvršavanje klijentskog javascript koda
93
Funkcionisanje JavaScripta
• JavaScript se koristi u kombinaciji sa objektnim modelom dokumenta (DOM) da bi se web strana učinila dinamičkom
• Kata se HTML document učita u browser kreira se njegov objektni model, odnosno obejkat pod nazivom document
• Objekat document je deo objekta window koji predstavlja prozor browsera
• JavaScript može modifikovati web stranu kada se ona učitava u browser ili kao odgovor na akciju korisnika
94
12/16/2018
48
JavaScript sintaksa
• JavaScript naredba predstavlja liniju JavaScript koda koji treba da se izvrši
• Naredba u JavaScriptu treba biti napisana u jednoj liniji i treba da se završava operatorom ;
• JavaScript naredbe se grupišu unutar bloka { }
• JavaScript je osetljiv na velika i mala slova
95
Pisanje javascript-a
• Ubacivanje javascript koda u html dokument• u telu html dokumenta
• u head delu html dokumenta
• Pisanje javascript koda u zasebnom . js dokumentu i njegovo referenciranje upotrebom src atributa
• Pisanje javascript koda u zasebnom .js dokumentu na mreži i njegovo referenciranje upotrebom src atributa
• Preferira se pisanje javascript koda neposredno pre završnog body taga radi bržeg učitavanja strane
96
12/16/2018
49
Javascript kod u body delu strane
97
<body><p>Prvi paragraf</p><script>
document.write("test");</script><p>Poslednji paragraf</p>
</body>
<body><p>Prvi paragraf</p><p>Poslednji paragraf</p><script>
document.write("test");</script>
</body>
Ekstenzija za JavaScript
98
12/16/2018
50
Prikazivanje rezultata na konzoli
<body><h1>Prikaz na konzoli</h1><script>
//clgconsole.log("test1");console.log("test2");
</script><h3>Kraj dokumenta</h3>
</body>
99
JavaScript kod u head delu strane
<!DOCTYPE html><html><head><title></title><meta charset="utf-8" />
<script>document.write("test");
</script></head><body>
<p>Prvi paragraf</p><p>Poslednji paragraf</p>
</body></html>
100
12/16/2018
51
Referenciranje eksternog js fajla
<html><head>
<title>Pisanje javascript koda</title><meta charset="utf-8" />
<script src="KlijentskiKod.js"></script></head><body>
<p>Prvi paragraf</p><p>Poslednji paragraf</p>
</body></html>
101
//KlijentskiKod.jsdocument.write("test");
Postavljena prekidna tačka
102
12/16/2018
52
Nastavljeno izvršavanje koda
103
Komentari
<script>// prikaz poruke korisnikudocument.write("Dobar dan svima");/* Mozete koristit multi-line komentarda biste dodali vise informacija */alert("Dobar dan svima, takodje!");
</script>
104
12/16/2018
53
Promenljive• Promenljive u JavaScriptu počinju slovom ili donjom crtom
• Koristi se ključna reč var za deklarisanje promenljivih
• Imena promenljivih su case - sensitive
• Promenljiva može biti nedefinisana a takođe može imati i null vrednost
105
<script>//deklarisanje promenljivevar x;// promenljiva x nema vrednostconsole.log(x);
var y = null; // null promenljivaconsole.log(y);
// deklarisanje i inicijalizacija promenljivevar poruka = "Pozdrav svima";console.log(poruka);</script>
Tipovi podataka
• Za razliku od C# ne može se specificirati tip promenljive u javascriptu
• Promenljiva se deklariše korišćenjem ključne reči var, a zatim JavaScript sam pokušava da odredi njen tip
• JavaScript prepoznaje tri prosta tipa:• string
• number
• boolean
106
12/16/2018
54
JavaScript stringovi
<script>var s1 = "Prvi string";var s2 = "Drugi string\
proteze se\na tri linije";
var s3 = "\"Treci string\"";
document.write(s1 + "<br>");document.write(s2 + "<br>");document.write(s3 + "<br>");
document.write(typeof (s1) + "<br>");</script>
107
Stringovi se mogu pisati i između jednostrukih navodnika
JavaScript brojevi
<script>var b1 = 2;var b2 = 3.45;
document.write(b1 + "<br>");document.write(b2 + "<br>");document.write(typeof (b1));
</script>
108
12/16/2018
55
Templejt literali
109
<script>var a = 10;var b = 20;
var s1 = `Rezultat: ${a} + ${b} = ${a + b}`;
var s2 = `<table><tr><td>${a}</td><td>${b}</td></tr></table>`;document.write(s2);
</script>
JavaScript logičke vrednosti<script>
var a = true;var b = false;
document.write(a + "<br>");document.write(b + "<br>");document.write(typeof (a));
</script>
110
12/16/2018
56
Automatska konverzija u logički tip -1
111
<script>var broj = 22;// svaki broj razlicit od nule se konvertuje u trueif (broj) {
document.write("broj konvertovan u true");}
</script>
Automatska konverzija u logički tip -2
112
<script>var poruka = "test";// svaki neprazan string se konvertuje u trueif (poruka){
document.write("string konvertovan u true");}
</script>
12/16/2018
57
Aritmetički operatori
• Sabiranje (+)
• Oduzimanje (-)
• Množenje (*)
• Deljenje (/)
• Celobrojni ostatak (%)
• Inkerementiranje (++)
• Dekrementiranje (--)
113
Operatori dodeljivanja
<script>x = y;x += y; //x = x + yx -= y; //x = x - yx *= y; //x = x * yx /= y; //x = x / yx %= y; //x = x % y
</script>
114
12/16/2018
58
Operatori poređenja
• Promenljive se konvertuju u isti tip pre poređenja sledećim operatorima:• == (jednako)• != (različito)• > (veće)• < (manje)• >= (veće ili jednako)• <= (manje ili jednako)
• Promenljive se ne konvertuju u isti tip pre poređenja• === (jednakost po vrednosti i tipu)• !== (nejednakosto po vrednosti ili tipu)
115
Logički operatori
• x && y (logičko I)
• x || y (logičko ILI)
• !x (logičko NE)
116
12/16/2018
59
Rad sa operandom tipa string
• Sabiranje – operand koji nije tipa string se konvertuje u string i radi se konkatenacija (sabiranje, tj. spajanje stringova)
• Ostale operacije – string se konvertuje u broj, a zatim se obavlja operacija; ako konverzija ne uspe, dobija se vrednost NaN (Not a Number)
117
<script>var a = 1 + "1";var b = 2 * "3";document.write("a=" + a + "<br>");document.write("b=" + b + "<br>");
</script>
Rad sa brojevima
<script>var x1 = 55;var y1 = 44;var z1 = x1 + y1;document.write("z1= " + z1 + "<br>");document.write(typeof (z1));
</script>
118
12/16/2018
60
Rad sa boolean vrednostima
<script>var a = true;var b = false;var c = a || b;var d = a && b;
document.write("a = " + a + "<br>");document.write("b = " + b + "<br>");document.write("c = " + c + "<br>");document.write("d = " + d + "<br>");document.write(typeof (a));
</script>
119
Uslovni operator
x = (uslov) ? value1 : value2;
<script>var a = Math.round(10 * Math.random());var b = 10 * Math.random();
var c = a > b ? a : b;
document.write("a = " + a + "<br>");document.write("b = " + b + "<br>");document.write("c = " + c + "<br>");
</script>
120
Math.random() [0, 1)
12/16/2018
61
Naredba if
<script>
var a = 10 * Math.random();var b = 10 * Math.random();var c;
if (a > b) {c = a + b;
}else {
c = a * b;}document.write("a = " + a + "<br>");document.write("b = " + b + "<br>");document.write("c=" + c + "<br>");
</script>
121
Rad sa datumom
Metoda Opis
getDate() Get the day as a number (1-31)
getDay() Get the weekday a number (0-6)
getFullYear() Get the four digit year (yyyy)
getHours() Get the hour (0-23)
getMilliseconds() Get the milliseconds (0-999)
getMinutes() Get the minutes (0-59)
getMonth() Get the month (0-11)
getSeconds() Get the seconds (0-59)
getTime() Get the time (milliseconds since January 1, 1970)
var d = new Date();
122
12/16/2018
62
Prikaz datuma i vremena
123
<script>var d = new Date();console.log(d);console.log(d.toLocaleDateString("sr-Latn-RS"));console.log(d.toLocaleTimeString("sr-Latn-RS"));
</script>
if-else if -else<script>
var sati = new Date().getHours();
if (sati < 6) {document.write("Dobra noc<br>");
}else if (sati < 11) {
document.write("Dobro jutro<br>");}else if (sati < 19) {
document.write("Dobar dan<br>");}else {
document.write("Dobro vece<br>");}
</script>
124
12/16/2018
63
Switch selekcija<script>
var redniBroj = new Date().getDay();var dan = "";switch (redniBroj) {
case 0:dan = "Nedelja";break;
case 1:dan = "Ponedeljak";break;
case 2:dan = "Utorak";break;
case 3:dan = "Sreda";break;
case 4:dan = "Cetvrtak";break;
case 5:dan = "Petak";break;
case 6:dan = "Subota";break;
}document.write("Danas je : " + dan);
</script>
125
While petlja<script>
var i = 0;var s = "<ul>";while (i < 10) {
s += "<li>" + "stavka" + i + "</li>";i++;
}s += "</ul>";document.write(s + "<br>");
</script>
126
12/16/2018
64
Do-while petlja
<script>var i = 10;
do {document.write(i + "<br>");i--;
} while (i>0);</script>
127
For petlja
<body><script>for (var i = 0; i < 10; i++) {
console.log(i);}</script>
</body>
128
12/16/2018
65
JavaScript funkcije
Definisanje funkcije• Funkcija je imenovana sekvenca naredbi koja služi za izvršavanje specifičnog zadatka
• Argumentima funkcije se može pristupiti samo unutar tela funkcije
• Funkcija može vratiti vrednost
• Funkcija može definisati lokalnu promenljivu
• Globalne promenljive definisane izvan funkcije vidljive su u svim funkcijama skript sekcije
function aName( argument1, argument2, …,argumentN ) {
statement1;statement2;...statementN;
}
130
12/16/2018
66
Primer funkcije<script>
function Pomnozi(a, b) {console.log(`a = ${a}`);console.log(`b = ${b}`);return a * b;
}
var a1 = 5;var b1 = 6;var rezultat = Pomnozi(a1, b1);console.log(`${a1} * ${b1} = ${rezultat}`);
a1 = 7;b1 = 9;rezultat = Pomnozi(a1, b1);console.log(`${a1} * ${b1} = ${rezultat}`);
</script>
131
Oblast važenja promenljivih• Java Script promenljiva deklarisana sa var može biti globalna ili lokalna kada se definiše unutar
neke funkcije
• Globalna promenljiva se definiše izvan funkcije
• Promenljiva tipa var ne podržava oblast važenja na nivou bloka
• Oblast važenja var promenljive je ograničena na funkciju u kojoj je promenljiva definisana
<script>function VarTest() {
if (true) {var a = 7;console.log(`Unutar bloka a = ${a}`);
}console.log(`Van bloka a = ${a}`);
}VarTest();
</script>132
12/16/2018
67
Promenljiva deklarisana sa let<script>
function LetTest() {let a = 5;if (true) {
let a = 7;console.log(`Blok if: a = ${a}`);
}console.log(`Blok funkcije: a = ${a}`);
}
LetTest();
</script>
Vidljivost let promenljive je ograničena na blok.
133
Singleton objekti
• Singleton patern obezbeđuje da može postojati samo jedna instanca klase
• Math i JSON su singleton objekti
<script>var poluprecnik = 10 * Math.random();var obim = 2 * poluprecnik * Math.PI;var povrsina = Math.pow(poluprecnik, 2) * Math.PI;
console.log(`R= ${poluprecnik}`);console.log(`O= ${obim}`);console.log(`P = ${povrsina}`);
</script>
134
12/16/2018
68
Funkcija alert()
<script>alert("Pozdrav svima");//window.alert("Pozdrav svima");
</script>
Prikazuje prozor sa porukom i dugmetom OKMora se zatvoriti prozir da bi se koristili drugi delovi dokumenta
135
Funkcija confirm()
- Uzima u obzir akciju korisnika
- vraća rezultat (true ili false)
136
<script>var rezultat = confirm("Odaberite OK ili Cancel?");if (rezultat) {
console.log("Odabrali ste dugme OK");}else {
console.log("Odabrali ste dugme Cancel");}
</script>
12/16/2018
69
Prozor confirm()
137
Funkcija prompt()
<script>var grad = prompt("Unesite grad", "Beograd");if (grad != null) {
console.log(grad);}else {
console.log("Kliknuli ste na Cancel dugme");}
</script>
Funkcija vraća uneti string ili null ako je korisnik kliknuo na Cancel dugme
138
12/16/2018
70
Prozor prompt()
139
Funkcija isNaN()
• Određuje da li vrednost koja se prosleđuje funkciji predstavlja ilegalan broj NaN
• Funkcija vraća logičku vrednost true ili false<script>
var a = isNaN(123);var b = isNaN("Hello");
console.log(a);console.log(b);
</script>
140
12/16/2018
71
Funkcije parseInt() , parseFloat()• Funkcija parseInt() parsira string i vraća ceo broj
• Ako prvi karakter ne može da se konvertuje funkcija parseInt() vraća vrednost NaN
141
<script>var c1 = parseInt("123");var c2 = parseInt("345.567");var c3 = parseInt("40godina");var c4 = parseInt("godina40");
console.log(`${c1},${c2},${c3},${c4}`);
</script>
JavaScript nizovi
12/16/2018
72
Nizovi• JavaScript nizovi se koriste za čuvanje više vrednosti u jednoj promenljivoj
• Članovima niza pristupa se na osnovu indeksa koji je baziran na 0
• Nizovi su specijalni tipovi objekata
143
<script>var x = [1, 3, 5, 7, 9];var brojClanova = x.length;var x0 = x[0];
document.write("Tip:" + typeof (x) + "<br>");document.write("Broj clanova: " + brojClanova + "<br>");document.write("Prvi clan:" + x0);
</script>
Kreiranje inicijalizovanog niza i prolazak for petljom<script>
var x = [1, 3, 5, 7, 9];for (let i = 0; i < x.length; i++) {
console.log(x[i]);}
</script>
144
12/16/2018
73
Prolazak kroz niz forin petljom
<script>var x = [1, 3, 5, 7, 9];
//finfor (const i in x) {
document.write(i + ":" +x[i] + "<br>");}
</script>
145
Kreiranje neinicijalizovanog niza i prolazak forin petljom
<script>var x =[];x[0] = 1;x[1] = 4;x[2] = 7;
for (const i in x) {console.log(x[i]);
}</script>
146
12/16/2018
74
Dodavanje elementa na kraj niza<script>
var a = [1, 5, 7, 9];
var duzina = a.push(11);
document.write("Duzina niza: " + duzina + "<br>");for (var i in a) {
document.write(a[i] + "<br>");}
</script>
Metoda push() dodaje element u niz i vraća broj članova novog niza.
147
Metoda pop()
Uklanja element sa kraja niza i vraća taj element.
<script>var a = [1, 2, 4, 6, 8];var poslednji = a.pop();
document.write("Uklonjeni clan je: " + poslednji + "<br>");
for (var i = 0; i < a.length; i++) {document.write(a[i] + "<br>");
}</script>
148
12/16/2018
75
Metoda splice()
• Dodaje/uklanja elemente iz niza i vraća uklonjene stavke
<script>var imena = ["Marko", "Ivan", "Lazar"];//ubaci na poziciju 1imena.splice(1,0,"Jovan");
for (let i = 0; i < imena.length; i++) {console.log(imena[i]);
}</script>
149
Brisanje elementa sa pozicije<script>
var imena = ["Marko", "Ivan", "Lazar","Jovan"];//obrisi sa pozicije 2imena.splice(2,1);
for (let i = 0; i < imena.length; i++) {console.log(imena[i]);
}</script>
150
12/16/2018
76
Svojstvo undefined<script>
var a = [];a[2] = 3;
for (var i = 0; i < a.length; i++) {document.write(a[i] + "<br>");
}</script>
<script>var a = [];a[2] = 3;
for (var i = 0; i < a.length; i++) {if (a[i] == undefined) {
a[i] = 0;}document.write(a[i] + "<br>");
}</script>
151
Pitanje 1Ukoliko html strana u svojoj <body> sekciji sadrži javascript kod tada se on izvršava :
a) na serverub) na klijentuc) i na serveru i na klijentu
Odgovor: b
152
12/16/2018
77
Pitanje 2
Jezik javascript ne poznaje sledeći tip podataka:a. floatb. numberc. boolean
Odgovor: a
153
Pitanje 3
Za deklarisanje javascript promenljive čija je oblast važenja ograničena na funkciju koristi se ključna reč:a. variableb. varc. unknown
Odgovor: b
154
12/16/2018
78
Pitanje 4
Šta se dobija izvršavanjem sledećeg javascript koda:
<script>var a = 2 * "3";document.write("a=" + a + "<br>");</script>
a. a=Nanb. a=2*3c. a=6
Odgovor: c
155
Pitanje 5
Deklarisanje i inicijalizacija javascript niza je ispravno izvršena u primeru pod opcijom:a. var a = [1, 2, 3, 4];b. var b = {1,2,3,4};c. var c= (1,2,3,4);
Odgovor: a
156
12/16/2018
79
Pitanje 6
Šta se dobija izvršavanjem sledećeg javascript koda:<script >var osoba = { "ime": "Pera", "prezime": "Peric", "starost": 30, "telefon": "123456" }for (var i in osoba) {
document.write(i + " ");}</script>a. Pera Peric 30 123456 b. ime prezime starost telefonc. ime:Pera prezime:Peric starost:30 telefon:123456
Odgovor: b
157
JavaScript objekti i klase
12/16/2018
80
JavaScript objektiSadrže imenovane vrednost, tzv. parove (name,value). Parovi se sastoje odsvojstva i vrednosti razdvojenih sa :.
<script>var osoba = {ime:"Pera", prezime:"Peric", starost:24 };
document.write(osoba.ime + " " + osoba.prezime + " " + osoba.starost + "<br>");
document.write(osoba["ime"] + "<br>");document.write("<hr>");
for (var i in osoba) {document.write(i + " : " + osoba[i] + "<br>");
}</script>
159
Prikaz sadržaja objekta
160
12/16/2018
81
Definisanje metoda objekta
<script>
var osoba = {ime: "Marko",prezime: "Petrovic",starost: 24,PunoIme: function () {
return this.ime + " " + this.prezime;}
};
document.write(osoba.PunoIme());</script>
161
Kreiranje prototipa objekta, konstruktorska funkcija
function Osoba(ime, prezime, starost) {this.ime = ime;this.prezime = prezime;this.starost = starost;
}
var os1 = new Osoba("Marko", "Markovic", 21);
162
12/16/2018
82
Dodavanje metode u prototipfunction Osoba(ime, prezime, starost) {
this.ime = ime;this.prezime = prezime;this.starost = starost;this.Stampaj = function () {
document.write("Ime: " + this.ime + "<br>"+ "Prezime: " + this.prezime + "<br>"+ "Starost: " + this.starost + "<br>");
};}
var os1 = new Osoba("Marko", "Markovic", 21);os1.Stampaj();
163
Naknadno dodavanje metode u prototip<script>
function Osoba(ime, prezime, starost) {this.ime = ime;this.prezime = prezime;this.starost = starost;
}
Osoba.prototype.Stampaj = function () {document.write("Ime: " + this.ime + "<br>"
+ "Prezime: " + this.prezime + "<br>"+ "Starost: " + this.starost + "<br>");
}
var os1 = new Osoba("Marko", "Markovic", 21);os1.Stampaj();
</script>164
12/16/2018
83
JSON
• JavaScript Object Notation
•Browser i web server razmenjuju tekstualne podatke
• JSON je tekst i svaki JavaScript objekat na klijentu se može konvertovati u JSON i poslati do servera
• JSON tekst sa servera koji se šalje klijentu se takođe može konvertovati u JavaScript objekte
165
Json sintaksa• Podaci su parovi: naziv svojstva i vrednost
• Naziv svojsta i vrednost svojtva se razdvajaju sa :
• Svi nazivi svojstava se pišu između dvostrukih znakova navoda
• Vrednosti mogu biti:• stringovi
• brojevi
• logičke vrednosti
• nizovi
• objekti
• null
• Parovi naziv svojtsva-vrednost su međusobno razdvojeni zarezom
• Vitičaste zagrade čuvaju objekte
• Uglaste zagrade čuvaju nizove166
12/16/2018
84
Tipovi podataka u JSON tekstu
• Stringovi se pišu između dvostrukih navodnika
• Brojevi mogu biti realni ili celi
• Vrednost može biti true ili false
• Vrednost može biti null
167
JSON.stringfy() funkcija<script>
function Osoba(ime, prezime, starost) {this.ime = ime;this.prezime = prezime;this.starost = starost;
}var osoba = new Osoba("Marko", "Markovic", 25);var jsonText = JSON.stringify(osoba);console.log(jsonText);
</script>
168
Pretvara javascript objekat ili niz javascript objekata u tekst. Koristi se pri slanju podataka ka web serveru.
12/16/2018
85
Pretvaranje javascript niza u JSON tekst
169
<script>function Osoba(ime, prezime, starost) {
this.ime = ime;this.prezime = prezime;this.starost = starost;
}var os1 = new Osoba("Marko", "Markovic", 25);var os2 = new Osoba("Ivan", "Petrovic", 25);var os3 = new Osoba("Sanja", "Peric", 25);
var nizOsoba = new Array();nizOsoba.push(os1);nizOsoba.push(os2);nizOsoba.push(os3);
var jsonText = JSON.stringify(nizOsoba);console.log(jsonText);</script>
Metoda JSON.parse()-1
<script>var jsonString = `{
"ime":"Marko","prezime":"Markovic","starost":25}`;
var osoba = JSON.parse(jsonString);document.write(osoba.ime + " " + osoba.prezime);
</script>
170
Pretvara tekst obično dobijen od web servera u javascript objekat ili niz javascript objekata
12/16/2018
86
Metoda JSON.parse()-2
171
<script>var jsonString = `[
{"ime":"Marko","prezime":"Markovic","starost":25},{"ime":"Ivan","prezime":"Petrovic","starost":25},{"ime":"Sanja","prezime":"Peric","starost":25}]`;
var osobe = JSON.parse(jsonString);
for (var i in osobe) {document.write(osobe[i].ime + " " + osobe[i].prezime + "<br>");
}</script>
Klase
172
<script>
class Osoba {
constructor(OsobaId, Ime, Prezime, Adresa) {
this.OsobaId = OsobaId;
this.Ime = Ime;
this.Prezime = Prezime;
this.Adresa = Adresa;
}
ToString() {
return `${this.Ime} ${this.Prezime}`;
}
Stampaj() {
console.log(`${this.OsobaId} ${this.Ime} ${this.Prezime} ${this.Adresa}`);
}
}
var os1 = new Osoba(1,"Pera","Peric","Glavna 4");
os1.Stampaj();
</script>
12/16/2018
87
Objektni model browsera i objektni model dokumenta
Objektni model browsera (BOM)
• Osnova BOM-a je objekat window
• Objekat window predstavlja otvoreni prozor u browseru
• Svojstvo document vraća document objekat prozora
• Svojstvo history vraća history objekat prozora
• Svojstvo location vraća location objekat prozora
174
12/16/2018
88
Metode objekta window
• Metoda alert() prikazuje alert prozora dugmetom OK
• Metoda confirm() prikazuje prozor sa dugmetom OK i Cancel
• Metoda prompt() prikazuje prozor za unos teksta
• Metoda open() otvara novi prozor browsera
• Metoda print() štampa sadržaj tekućeg prozora
• Metoda setInterval() poziva funkciju ili izvršava specificirani izraz u datom intervalu u msec.
• Metoda setTimeout() poziva funkciju ili izvršava izraz nakon određenog broja msec.
175
Odloženo izvršavanje funkcije
<script>function PrikaziPoruku() {
alert("Pozdrav");}
setTimeout(PrikaziPoruku, 2000);</script>
176
<script>setTimeout(() => {
alert("Podrav");}, 2000);
</script>
12/16/2018
89
HTML DOM
• Kada se web strana učita u browser kreira se objektni model strane i objekat document
• HTML DOM (document object model) obezbeđuje programski interfejs za pristup i manipulaciju html dokumentima
• HTML elemente definiše kao objekte
• Definiše metode za pristup HTML elementima
• Definiše događaje za sve HTML elemente
177
HTML DOM stablo
HTML DOM model se sastoji od stabla objekata
178
12/16/2018
90
Metoda getElementById()
• Metoda getElementById() objekta document se koristi kada tražimo element na osnovu id atributa
• Id koji tražimo mora biti jedinstven za tu stranu
• Svojstvo innerHTML koristi se da pročita ili promeni html sadržaj nekog elementa
179
Čitanje html sadržaja nekog elementabody>
<h1 id="mojHeder" onclick="Prikazi()"><mark>Klikni ovde</mark></h1>
<script>function Prikazi() {
var h1 = document.getElementById("mojHeder");alert(h1.innerHTML);
}</script>
</body>
180
12/16/2018
91
Promena sadržaja paragrafa
<body><p id="p1" onclick="Promeni()">
<mark> Klikni </mark></p><script>
function Promeni() {var p1 = document.getElementById("p1");p1.innerHTML += "<br>" + new Date().toLocaleTimeString();
}</script>
</body>
181
Događaji kao atributi elementa<body>
<img src="/Slike/1.jpg" width="80" onclick="Pozdrav()"/><script>
function Pozdrav() {alert("Dobar dan");
}</script>
</body>
182
12/16/2018
92
Pretplata na događaj u javascriptu
<body><img id="img1" src="/Slike/1.jpg" />
<script>var slika = document.getElementById("img1");slika.onclick = function () {
alert("Pozdrav");};
</script></body>
183
HTML DOM addEventListener() metoda
184
<script>var slika = document.getElementById("img1");slika.addEventListener("click",Slika1_Click);
function Slika1_Click() {alert("Test");
}</script>
12/16/2018
93
HTML DOM removeEventListener() metoda<script>
var p1 = document.getElementById("p1");
p1.addEventListener("mousemove", Prikazi);p1.addEventListener("click",Odjava);
function Prikazi() {p1.innerHTML = Math.random();
}
function Odjava() {p1.removeEventListener("mousemove",Prikazi);
}
</script>
185
Svojstva i metode objekta element
• element.id – čita ili setuje id atribut elemeta
• element.style – čita ili setuje neki od atributa stila elementa
• element.attributes vraća kolekciju atributa elementa
• element.focus() – postavlja fokus na element
• element.getAttribute() – vraća specificirani atribut elementa
• element.removeAttribute() – uklanja specificirani atribut elementa
• Svojstvo element.childNodes vraća kolekciju child čvorova datog elementa
• element.firstChild – vraća prvi child čvor datog elementa
186
12/16/2018
94
Primer upotrebe objekta element<body>
<p id="p1">Prvi paragraf</p><script>
var p1 = document.getElementById("p1");
//iscitavanje id-a elementavar id1 = p1.id;var id2 = p1.getAttribute("id");
console.log(id1);console.log(id2);p1.setAttribute("class","plava");p1.style.color = "red";
</script></body>
<style>.plava{
background-color:#2b72a7;}
</style>
187
Objekat window.location
<body>
<p id="p1">
</p>
<button onclick="Prikazi()">Prikazi lokaciju</button>
<button onclick="NovaLokacija()">Strana02</button>
<br />
<script>
function Prikazi() {
var p1 = document.getElementById("p1");
p1.innerHTML = location.href;
}
function NovaLokacija() {
location.href = "/Strana02.html";
}
</script>
</body>
Objekat location sadrži podatke o tekućoj url adresi.
188
12/16/2018
95
Objekat window.history
<body><button onclick="Nazad()">Nazad</button><script>
function Nazad() {window.history.back()
} </script>
</body>
Sadrži informacije o stranama koje je posećivao korisnik.
189
Metoda getElementsByTagName()objekta document
• Vraća kolekciju elemenata sa odgovarajućim nazivom taga
• Koristi se length properti da se odredi broj članova u kolekciji
• Članovima kolekcije se pristupa preko indeksa
190
12/16/2018
96
Stil paragrafa
191
<style>p {
width: 100px;height: 50px;background-color: #0094ff;border: 1px solid red;margin: 10px;padding: 10px;
}</style>
<body><p></p><p></p><p></p><p></p>
</body>
Metoda getElementsByTagName() - primer
192
<script>document.body.onload = function () {
var lista = document.getElementsByTagName("p");
for (var i in lista) {lista[i].innerText = parseInt(i) + 1;
}};
</script>
12/16/2018
97
Metoda getElementsByClassName ()objekta document
• Vraća sve elemente sa specificiranim imenom klase
193
<style>p{
width: 100px;height: 50px;background-color: #0094ff;border: 1px solid red;margin: 10px;
}.p1 {
background-color: rgb(60, 47, 180);}
</style>
Primer
194
<body>
<p class="p1"></p>
<p></p>
<p class="p1"></p>
<p></p>
<p class="p1"></p>
<script>
document.body.onload = function () {
var lista = document.getElementsByClassName("p1");
for (var i in lista) {
lista[i].innerText = parseInt(i) + 1;
}
};
</script>
</body>
12/16/2018
98
Metode za kreiranje novih objekata u dokumentu• document.createElement(tagname)
• document.createTextNode(string)
• document.createAttribute(name, value)
195
Modifikacija liste<body>
<ul id="ul1">
</ul>
<script>
document.body.onload = function () {
var lista = document.getElementById("ul1");for (var i = 0; i < 5; i++) {
var stavka = document.createElement("li");stavka.innerText = "Stavka" + i;lista.appendChild(stavka);
}
};</script>
</body>
196
12/16/2018
99
Dinamičko definisanje sadržaja<body>
<div id="div1">Prvi div
</div><script>
document.body.onload = function () {var noviDiv = document.createElement("div");var noviSadrzaj = document.createTextNode("Pozdrav svima!");noviDiv.appendChild(noviSadrzaj);
var tekuciDiv = document.getElementById("div1");
document.body.insertBefore(noviDiv, tekuciDiv);};
</script></body>
197
Pitanje 1
Šta se dobija izvršavanjem sledećeg javascript koda:<script >
var osoba = { "ime": "Pera", "prezime": "Peric", "starost": 30}for (var i in osoba) {
document.write(i + " ");}
</script>a. Pera Peric 30b. ime prezime starost c. ime:Pera prezime:Peric starost:30
Odgovor: b
198
12/16/2018
100
Kreiranje HTML formi
Element <form>
• Element <form> obezbeđuje mehanizam za dobijanje korisničkog ulaza
• Atribut action specificira url adresu strane gde će podaci sa forme biti poslati
• Atribut method specificira kako će podaci biti poslati• GET metoda je podrazumevana opcija• POST je preferirana metoda
•Atribut enctype specificira na koji način se enkoduju podaci sa forme pre nego što se pošalju serveru
200
12/16/2018
101
Kontrole forme, element <input>
• Element <input> je osnovni element za unos podataka
• Ima više različitih oblika u zavisnosti od atributa type• type="text"
• type="password"
• type="hidden"
• type="checkbox"
• type="radio"
• type="reset"
• type="submit"
• type="image"
• type="button"
• type="file"
• type="email"
• .....
201
Atributi <input> elementa
• Atribut id koristi se za pristup elementu iz CSS-a ili javascripta• Atribut id mora biti jedinstven na formi
• Atribut value postavlja podrazumevanu vrednost za numeričke i tekstualne kontrole za unos podataka
• Atribut name se koristi od strane servera da se referenciraju polja forme kada se ona submituje, takođe se koristi za pristup elementu iz klijentskog koda
• Atribut placeholder opisuje očekivanu vrednost unutar nekog text polja
• Atribut required ukazuje da je polje obavezno i da se forma ne može submitovati ukoliko je polje prazno
202
12/16/2018
102
Kontrole forme
• Element <textarea> predstavlja multiline polje za unos teksta
• Element <select> se koristi za definisanje drop-down liste ili listbox kontrole
• Element <button> se koristi za definisanje dugmeta, podrazumevani tip dugmeta je submit dugme• Atribut type ima vrednosti button, reset i submit
• Element <fieldset> definiše grupu kontrola na formi• Unutar <fieldset> elementa se nalazi <legend> element, on mora biti prvi
element unutar <fieldset> elementa
• Element <label> element služi za pridruživanje teksta ulaznoj kontroli, na osnovu id atributa
203
Primer HTML forme
<form action="/Strana02.html" method="get" ><fieldset>
<legend>Vasi podaci
</legend><label for="textIme">Ime:</label> <br><input type="text" name="ime" id="textIme"> <br>
<label for="textPrezime">Prezime:</label> <br><input type="text" name="prezime" id="textPrezime"> <br><br>
<button type="submit">Posalji</button></fieldset>
</form>
204
12/16/2018
103
Primer HTML forme
205
Korisnički interfejs
206
<body><form action="" method="get">
<label for="Text1">Unesite prvi broj:</label> <br><input type="text" name="Text1" id="Text1"> <br>
<label for="Text2">Unesite drugi broj:</label> <br><input type="text" name="Text2" id="Text2"> <br> <br><input type="button" value="Izracunaj" onclick="Racunaj()">
</form><br><span id ="Span1"></span>
</body>
12/16/2018
104
Korisnički interfejs
207
Svojstvo value
• Svojstvo value koristi se za čitanje i setovanje tekst polja
208
<script>function Racunaj() {
var Text1 = document.getElementById("Text1");var Text2 = document.getElementById("Text2");var sp1 = document.getElementById("Span1");
var a = parseFloat(Text1.value);var b = parseFloat(Text2.value);var zbir = a + b;sp1.innerHTML = `<strong> Rezultat je: ${zbir} </strong>`;
}</script>
12/16/2018
105
Element <textarea>Ovo je multiline kontrola za unos teksta
<body><form action="">
<label for="TextArea1">Unesite komentar:</label> <br><textarea name="TextArea1" id="TextArea1" cols="30" rows="10"placeholder="Unesite komentar..."></textarea><br><input type="button" value="Prikazi" onclick="Prikazi()">
</form><br><span id="span1"></span>
</body>
209
Prikaz tekst oblasti
210
12/16/2018
106
Funkcija Prikazi()
<script>function Prikazi() {
var TextArea1 = document.getElementById("TextArea1");var span1 = document.getElementById("span1");span1.innerText = TextArea1.value;
}</script>
211
Atribut checked
• Koristi se sa kontrolama • <input type="checkbox">
• <input type="radio">
• Atribut checked vraća logičku vrednost
212
12/16/2018
107
Html checkbox<body>
<form action="">
<input id="CheckBox1" type="checkbox" name="CheckBox1" /><label for="CheckBox1">Stavka1</label><br />
<input id="CheckBox2" type="checkbox" name="CheckBox2" /><label for="CheckBox2">Stavka2</label><br />
<input id="CheckBox3" type="checkbox" name="CheckBox3" /><label for="CheckBox3">Stavka3</label><br />
<input id="Button1" type="button" value="Prikazi" onclick="Provera()" /></form><br /><br /><span id="span1"></span>
</body>
213
Funkcija Prikazi() -1
<script>function Prikazi() {
var sp1 = document.getElementById("Span1");var cb1 = document.getElementById("CheckBox1");var cb2 = document.getElementById("CheckBox2");var cb3 = document.getElementById("CheckBox3");var s = "";
if (!cb1.checked && !cb2.checked && !cb3.checked) {s = "Niste odabrali ni jednu opciju";
}...
}</script>
214
12/16/2018
108
Funkcija Prikazi() -2
215
else{s = "Odabrali ste sledece opcije:<br>";
if (cb1.checked) {s += "Opcija1<br>";
}if (cb2.checked) {
s += "Opcija2<br>";}if (cb3.checked) {
s += "Opcija3<br>";}
} sp1.innerHTML = s;
Prikaz CheckBoxova
216
12/16/2018
109
Slanje vrednosti checkboxova do servera
<form action="/Strana06.html"><input id="CheckBox1" type="checkbox" name="CheckBox1" value="true" /><label for="CheckBox1">Opcija1</label><br />
<input id="CheckBox2" type="checkbox" name="CheckBox2" value="true" /><label for="CheckBox2">Opcija2</label><br />
<input id="CheckBox3" type="checkbox" name="CheckBox3" value="true" /><label for="CheckBox3">Opcija3</label><br /><button type="submit">Posalji</button>
</form>
217
Generisani query string
218
12/16/2018
110
Grupa radio buttona, svojstvo name
<body><form action="" method="get">
<input type="radio" name="opcije" id="Radio1" value="v1"><label for="Radio1">Opcija1</label> <br>
<input type="radio" name="opcije" id="Radio2" value="v2"><label for="Radio2">Opcija2</label> <br>
<input type="radio" name="opcije" id="Radio3" value="v3"><label for="Radio3">Opcija3</label> <br><br><input type="button" value="Prikazi" onclick="Prikazi()">
</form><br><span id=Span1></span></body>
219
Iščitavanje selektovanog radio dugmeta, svojstvo checkedfunction Prikazi() {
var rb1 = document.getElementById("Radio1");
var rb2 = document.getElementById("Radio2");
var rb3 = document.getElementById("Radio3");
var sp1 = document.getElementById("Span1");
if (rb1.checked) {
sp1.innerHTML = "Odabrali ste opciju 1";
}
else if (rb2.checked) {
sp1.innerHTML = "Odabrali ste opciju 2";
}
else if (rb3.checked) {
sp1.innerHTML = "Odabrali ste opciju 3";
}
else {
sp1.innerHTML = "Niste odabrali nijednu opciju";
}
} 220
12/16/2018
111
Metoda getElementsByName() objekta document• Pretraga po vrednosti atributa name
• Vraća kolekciju elemenata sa specificiranim atributom name
• Članovim kolekcije se može pristupiti na osnovu indeksa
221
Pristup kolekciji radio buttonafunction Provera() {
var radioLista = document.getElementsByName("opcije");
var s = "";
for (var i = 0; i < radioLista.length; i++) {s += radioLista[i].id + " " + radioLista[i].checked + "<br>";
}document.getElementById("Span1").innerHTML = s;
}
222
12/16/2018
112
Slanje vrednosti radiobutton-a do servera<body>
<form action="/Strana09.html">
<input id="Radio1" name="opcije" type="radio" value="1" /><label for="Radio1">Opcija1</label><br />
<input id="Radio2" name="opcije" type="radio" value="2" /><label for="Radio2">Opcija2</label><br />
<input id="Radio3" name="opcije" type="radio" value="3" /><label for="Radio3">Opcija 3</label><br /><br/>
<button type="submit">Posalji</button></form>
</body>
223
Generisani query string
224
12/16/2018
113
Iščitavanje query stringa
<body><body>
<span id="sp1"></span><script>
document.body.onload = function () {var sp1 = document.getElementById("sp1");var queryString = location.search.substring(1);if (queryString == "") {
sp1.innerHTML = "Niste odabrali ni jednu opciju";return;
}var imeVrednost = queryString.split("=");sp1.innerHTML = "Odabrali ste vrednost: " + imeVrednost[1];
};</script>
</body></body>
225
Element <select>
• Sastoji se od kolekcije <option> elemenata
• Pomoću svojstva options pristupa se kolekciji stavki
• Pomoću svojstva value dobija se vrednost selektovane stavke
• Pomoću svojstva selectedIndex dobija se indeks selektovane stavke
• Pomoću svojstva selected proverava se (setuje se) da li je neka stavka selektovana
• Događaj onchange se izvršava kada korisnik promeni selekciju
226
12/16/2018
114
Upotreba select html elementa-1
<form action=""><select name="Select1" id="Select1">
<option value="1">Stavka1</option><option value="2">Stavka2</option><option value="3">Stavka3</option>
</select><br><br><input type="button" value="Prikazi" onclick="Prikazi()">
</form><br><br>
<span id="span1"></span>
227
Upotreba select html elementa-2
<script>function Prikazi() {
var Select1 = document.getElementById("Select1");var span1 = document.getElementById("span1");
var indeks = Select1.selectedIndex;var stavke = Select1.options;
var selektovano = stavke[indeks];span1.innerHTML = selektovano.text + "<br>" +
selektovano.value + "<br>" + Select1.value;}
</script>
228
12/16/2018
115
Element <select>
229
Definisanje prve stavke
230
<select id="Select1" onchange="Prikazi()"><option value="-1">--Odaberite stavku--</option><option value="1">opcija1</option><option value="2">opcija2</option><option value="3">opcija3</option><option value="4">opcija4</option>
</select>
12/16/2018
116
Upotreba onchange događaja-1<script>function Prikazi() {
var Select1 = document.getElementById("Select1");var span1 = document.getElementById("span1");
if (Select1.selectedIndex > 0) {var indeks = Select1.selectedIndex;var stavke = Select1.options;
var selektovano = stavke[indeks];span1.innerHTML = selektovano.text + "<br>" +
selektovano.value + "<br>" + Select1.value;}else{
span1.innerHTML = "";}
}</script>
231
Upotreba onchange događaja-2
232
12/16/2018
117
Slanje vrednosti do servera
233
<form action="/Strana03.html" onsubmit="return Validacija()"><select id="Select1" name="opcija">
<option value="-1">--Odaberite stavku--</option><option value="1">opcija1</option><option value="2">opcija2</option><option value="3">opcija3</option><option value="4">opcija4</option>
</select>
<br /><br /><input id="Submit1" type="submit" value="Posalji" />
</form>
<br /><span id="span1"></span>
Funkcija za validaciju
234
<script>function Validacija() {
var span1 = document.getElementById("span1");var Select1 = document.getElementById("Select1");if (Select1.selectedIndex > 0) {
return true;}else {
span1.innerHTML = "Odaberite opciju";return false;
}}
</script>
12/16/2018
118
Generisani query string
235
Elementi <select> i <optgroup>
<form><select id="Select1">
<optgroup label="grupa1"><option>Opcija11</option><option>Opcija12</option>
</optgroup><optgroup label="grupa2">
<option>Opcija21</option><option>Opcija22</option>
</optgroup>
</select></form>
236
12/16/2018
119
Html listbox-1<form>
<select id="Select1" size="4" onchange="Prikazi()"><option>Stavka1</option><option>Stavka2</option><option>Stavka3</option><option>Stavka4</option><option>Stavka5</option>
</select>
</form><br /><p id="p1">
</p>
237
Html listbox-2<script>
function Prikazi() {var Select1 = document.getElementById("Select1");var p1 = document.getElementById("p1");
var listaOpcija = Select1.options;var indeks = Select1.selectedIndex;
var vrednostSelStavke = Select1.value;console.log(vrednostSelStavke);
var selStavka = listaOpcija[indeks];
p1.innerHTML = "Vrednost: " + selStavka.value + "<br>" +"Tekst:" + selStavka.text;
}</script>
238
12/16/2018
120
Svojstvo Multiple<form>
<select id="Select1" size="4" name="Select1" multiple><option value="1">Stavka1</option><option value="2">Stavka2</option><option value="3">Stavka3</option><option value="4">Stavka4</option><option value="5">Stavka5</option>
</select><br /><br /><input id="Button1" type="button" value="Prikazi" onclick="Prikazi()" />
</form><br><br><span id="sp1">
</span>
239
Svojstvo Multiple-2function Prikazi() {
var Select1 = document.getElementById("Select1");var sp1 = document.getElementById("sp1");
var listaOpcija = Select1.options;
var s = "Odbrali ste sledece opcije: <ul>";for (var i = 0; i < listaOpcija.length; i++) {
if (listaOpcija[i].selected) {
s += "<li>" + listaOpcija[i].text+ " : " + listaOpcija[i].value + "</li>";
}}s += "</ul>";sp1.innerHTML = s;
}
240
12/16/2018
121
Korisnički interfejs
241
Element <datalist>
Koristi se za definisanje ulaznog elementa sa predefinisanim skupom vrednosti
<form action=""><datalist id="dl1">
<option>Opcija1</option><option>Opcija2</option><option>Opcija3</option>
</datalist><input type="text" name="Text1" id="Text1" list="dl1"><input type="button" value="Prikazi" onclick="Prikazi()">
</form>
<span id="sp1"></span>
242
12/16/2018
122
Iščitavanje text kontrole
<script>function Prikazi() {
var tb1 = document.getElementById("Text1");var sp1 = document.getElementById("sp1");sp1.innerHTML = tb1.value;
}</script>
243
Pitanje 1
Setovanje vrednosti tekst polja na vrednost 1:<input id="Text1" type="text" />korišćenjem javascripta i DOM-a vrši se upotrebom :a. document.getElementById("Text1").value = 1;b. document.getElementById("Text1").text = 1;c. document.getElementById("Text1").setText =1;
Odogovor: a
244
12/16/2018
123
Pitanje 2
Da bi tri html radio dugmeta <input type="radio"> pripadali istoj grupi moraju imati istu vrednostatributa:a. idb. namec. group
Odogovor: b
245
Pitanje 3
Unutar html forme nalazi se checkbox:<input id="CheckBox1" type="checkbox" name="CheckBox1" /><label for="CheckBox1">Stavka1</label>
Stanje html checkBox kontrole iščitava se linijom koda :
a. var op1 = document.getElementById("Checkbox1").checked;b. var op1 = document.getElementById("Checkbox1").ischecked();c. var op1 = document.getElement("Checkbox1").checked();
Odogovor: a
246
12/16/2018
124
Pitanje 4Dat je sledeći select element:<select name="ListBox1" id="ListBox1">
<option value="1">Stavka1</option><option value="2">Stavka2</option><option value="3">Stavka3</option>
</select>
Koji atribut treba definisati select elementu da bi u browseru bio prikazan ListBox:a. miltipleb. isListBoxc. size
Odogovor: c
247
Pitanje 5
Indeks selektovanog option elementa kod <select> elementa koji predstavlja dropdown listudobija se korišćenjem svojstva:a. selectionb. selectedIndexc. indexOf
Odogovor: b
248
12/16/2018
125
Pitanje 6Unutar <select> elementa definisan je sledeći option element:<option>opcija1</option>.Kada se pročita svojstvo value ovog option elementa dobija se vrednost:
a. nullb. opcija1c. undefined
Odogovor: b
249
Ajax zahtevi
12/16/2018
126
Uvod u AJAX
• AJAX = Asynchronous JavaScript and XML
• AJAX omogućava parcijalno ažuriranje html strane razmenom malih količina podataka sa serverom
• Ažuriranje strane se vrši asinhrono
• Pri klasičnom zahtevu html strana mora da promeni kompletni sadržaj iako se mali deo strane menja
• AJAX koristi• XMLHttpRequest objekat za razmenu podataka sa serverom• JavaScript/DOM za prikaz podataka
• Svi moderni browser podržavaju XMLHttpRequest obejkat
251
Slanje zahteva web serveru
var zahtev = new XMLHttpRequest();
zahtev.open("GET", "/Home/Index", true);zahtev.send();
open(method, url, async)• method- specificira se tip zahteva GET ili POST• url – adresa na serveru• async = true za asinhrone zahteve
send() - GETsend(string) - POST
252
12/16/2018
127
XMLHttpRequest objekat
• Svojstvo responseText, vraća tekst koji je odgovor servera
• Svojstvo responseXML, odgovor servera se tretira kao XML
• Svojstvo readystate čuva stanje zahteva• 0-zahtev nije inicijalizovan• 1-uspostavljena konekcija sa serverom• 2-zahtev primljen• 3-obrada zahteva• 4-zahtev obrađen i odgovor spreman
• Svojstvo onreadystatechange definiše funkciju koja se poziva kada se svojstvo readystate menja
• Svojstvo status• 200 – OK• 404- "Page not found"
253
Podešavanje VS Code okruženja
• Kreirajte folder Ajax
• Pokrenite VS Code i otvorite folder Ajax
• Instalirajte C# ekstenziju ukoliko nije instalirana
• Prikažite terminal View->Terminal
• Kreirajte .NET Core MVC web aplikaciju korišćenjem terminal unošenjem komande: dotnet new mvc
254
12/16/2018
128
Ekstenzija C#
255
Kreiranje ASP.NET web aplikacije
256
12/16/2018
129
Struktura kreirane aplikacije
257
Metoda Configure klase Startup
public void Configure(IApplicationBuilder app, IHostingEnvironment env){
if (env.IsDevelopment()){
app.UseDeveloperExceptionPage();}else{
app.UseExceptionHandler("/Home/Error");app.UseHsts();
}
app.UseHttpsRedirection();app.UseDefaultFiles();app.UseStaticFiles();app.UseCookiePolicy();
app.UseMvc(routes =>{
routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});}
Postavlja se početna strana sajta index.html
258
12/16/2018
130
Strana index.html
• Unutar foldera wwwroot kreiraj html stranu index.html
<!DOCTYPE html><html lang="en"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-
scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Pocetna</title>
</head><body>
<h1>Pocetna strana</h1></body></html>
259
Kompajliranje aplikacije
dotnet build – kompajlira projekat
260
12/16/2018
131
Pokretanje aplikacije
dotnet run – pokreće aplikaciju
261
Početna strana aplikacije
262
12/16/2018
132
Model folder klasa Osoba
namespace Ajax.Models{
public class Osoba{public int OsobaId { get; set; }public string Ime { get; set; }public string Prezime { get; set; }public string Telefon { get; set; }
}}
263
Klasa HomeController
namespace Ajax.Controllers{
public class HomeController : Controller{
public List<Osoba> listaOsoba = new List<Osoba>();
public HomeController(){
Osoba os1 = new Osoba { OsobaId = 1, Ime = "Janko", Prezime = "Petrovic", Telefon = "123-456" };Osoba os2 = new Osoba { OsobaId = 2, Ime = "Mika", Prezime = "Mikic", Telefon = "345-458" };Osoba os3 = new Osoba { OsobaId = 3, Ime = "Ivana", Prezime = "Ivanovic", Telefon = "567-785" };Osoba os4 = new Osoba { OsobaId = 4, Ime = "Jovana", Prezime = "Jovanovic", Telefon = "789-6756" };
listaOsoba.Add(os1);listaOsoba.Add(os2);listaOsoba.Add(os3);listaOsoba.Add(os4);
}
264
12/16/2018
133
Metoda Index klase HomeController
public JsonResult Index(int id = 0){
if (id == 0){
return Json(listaOsoba);}else{
Osoba os = listaOsoba.SingleOrDefault(o => o.OsobaId == id);
if (os != null){
return Json(os);}else{
return Json(new Osoba());}
}}
265
Podaci koje generiše server
https://localhost:5001/home/index/1
https://localhost:5001/home/index
266
12/16/2018
134
Strana index.html
<body>
<span id="span1"></span><hr><form>
Unesite id osobe:<input id="Text1" type="text"><br><input id="Button1" type="button" value="Pronadji"
onclick="PronadjiOsobu()"></form><br /><span id="span2"></span>
</body>
267
Javascript funkcija koja generiše ajax zahtev -1function PrikaziOsobe() {
var span1 = document.getElementById("span1");var zahtev = new XMLHttpRequest();
zahtev.open("GET", "/Home/Index", true);
zahtev.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var osobe = JSON.parse(this.responseText);
var s = "<ul>";
for (var i = 0; i < osobe.length; i++) {s += `<li>${osobe[i].ime}${osobe[i].prezime}</li>`;
}s += "</ul>";
span1.innerHTML = s;}
};
zahtev.send();} 268
12/16/2018
135
Generisanje AJAX zahteva
269
<script>
...PrikaziOsobe();
</script></body>
Prosleđivanje podataka ajax zahteva callback funkciji
• Podatke dobijene ajax zahtevom potrebno je proslediti nekoj funkciji
• Callback funkcija je funkcija koja se prosleđuje kao parametar drugoj funkciji
270
function CitajPodatke(CallBackFunkcija) {var span1 = document.getElementById("span1");var zahtev = new XMLHttpRequest();
zahtev.open("GET", "/Home/Index", true);
zahtev.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var osobe = JSON.parse(zahtev.responseText);CallBackFunkcija(osobe);
}};
zahtev.send();}
12/16/2018
136
Primer callback funkcije
271
function PrikaziOsobe(osobe) {var s = "<ul>";
for (var i = 0; i < osobe.length; i++) {s += `<li>${osobe[i].ime}${osobe[i].prezime}</li>`;
}s += "</ul>";
span1.innerHTML = s;}
<script>...CitajPodatke(PrikaziOsobe);</script>
Javascript funkcija PronadjiOsobu
function PronadjiOsobu() {
var span2 = document.getElementById("span2");var Text1 = document.getElementById("Text1");
var id = Text1.value;if (isNaN(id)) {
alert("Unesite broj");span2.innerHTML = "";Text1.value = "";return;
}
var zahtev = new XMLHttpRequest();zahtev.open("GET", `/Home/Index/${id}`, true);zahtev.send();
....
}
272
zahtev.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var osoba = JSON.parse(this.responseText);
if (osoba == null) {span2.innerHTML = "Nije pronadjena osoba";
}else {
span2.innerHTML = `Id: ${osoba.osobaId}<br>Ime: ${osoba.ime}<br>Prezime: ${osoba.prezime}<br>Telefon: ${osoba.telefon}`;
}}
};
12/16/2018
137
Rezultat pretrage
273
Validacija korisničkog unosa
12/16/2018
138
Validacija podataka na strani klijenta i strani servera
• Klijentska validacija:• Zavisi od verzije browsera• Trenutna povratna informacija• Redukuje broj slanja strane do servera
• Serverska validacija:• Ponovna provera podataka koji su
prošli klijentsku validaciju• Može se izvršiti validacija u odnosu na
sačuvane podatke
Client
Server
Korisnik unosi
podatke Poruka
greške
Validni?
Validni?
Ne
Ne
Da
Da
Obrada web
aplikacije
275
Atribut required
• Koristi se da se naznači da je unos podataka u polje obavezan
• Browser proverava da li je polje popunjeno pre submitovanja forme
276
12/16/2018
139
Atribut required <form>
<label for="TextIme">Unesite ime:</label><input id="TextIme" name="ime" type="text" required /><input id="Submit1" type="submit" value="Posalji" />
</form>
277
Validacija numeričkog ulaza<form>
Unesite procenat:<input id="Number1" type="number" min="0" max="100" name="procenat" required/><input id="Submit1" type="submit" value="Posalji" />
</form>
278
12/16/2018
140
Strana Strana03.html<form>
Ime:<br><input type="text" name="ime" id="TextIme" required autofocus><br> Prezime:<br><input type="text" name="prezime" id="TextPrezime" required><br> Lozinka:<br><input type="password" name="lozinka" id="TextLozinka" required><br> Potvrdi lozinku:<br><input type="password" name="potvrda" id="TextPotvrda" required><br>
<input type="submit" value="Posalji"></form><br><span id="span1"></span>
279
Funkcija za klijentsku validaciju<script>
function Validacija() {var sp1 = document.getElementById("span1");var lozinka = document.getElementById("TextLozinka");var potvrda = document.getElementById("TextPotvrda");
if (lozinka.value == potvrda.value) {return true;
}else {
sp1.innerHTML = "Potvrda ne odgovara lozinci";return false;
}}
</script>
280
12/16/2018
141
Poziv funkcije za klijentsku validaciju
<form action="/Strana04.html" onsubmit="return Validacija()">
281
Obrisani atributi required<form action="/Strana04.html" onsubmit="return Validacija()">
Ime:<br><input type="text" name="ime" id="TextIme" autofocus><br> Prezime:<br><input type="text" name="prezime" id="TextPrezime" ><br> Lozinka:<br><input type="password" name="lozinka" id="TextLozinka"><br> Potvrdi lozinku:<br><input type="password" name="potvrda" id="TextPotvrda"><br><input type="submit" value="Posalji">
</form>
282
Obrisani su atributi required da bi se to definisalo u klijentskoj validaciji
12/16/2018
142
Funkcija za klijentsku validaciju -1<script>
function Validacija() {var sp1 = document.getElementById("span1");var ime = document.getElementById("TextIme");var prezime = document.getElementById("TextPrezime");var lozinka = document.getElementById("TextLozinka");var potvrda = document.getElementById("TextPotvrda");sp1.innerHTML = "";
if (ime.value == "") {sp1.innerHTML = "Unesite ime";ime.focus();return false;
}if (prezime.value == "") {
sp1.innerHTML = "Unesite prezime";prezime.focus();return false;
}...
283
Funkcija za klijentsku validaciju -2if (lozinka.value == "") {
lozinka.focus();sp1.innerHTML = "Unesite lozinku";return false;
}
if (potvrda.value == "") {potvrda.focus();sp1.innerHTML = "Unesite potvrdu";return false;
}
if (lozinka.value != potvrda.value) {sp1.innerHTML = "Potvrda ne odgovara lozinci";return false;
}
return true;}
284
12/16/2018
143
Submit iz klijentske funkcije
<form id="form1" action="/Strana04.html">
Ime:
<br>
<input type="text" name="ime" id="TextIme" autofocus>
<br> Prezime:
<br>
<input type="text" name="prezime" id="TextPrezime" >
<br> Lozinka:
<br>
<input type="password" name="lozinka" id="TextLozinka">
<br> Potvrdi lozinku:
<br>
<input type="password" name="potvrda" id="TextPotvrda">
<br>
<input type="button" value="Posalji" onclick="Posalji()">
</form>
285
Umesto submit buttona postavljen je običan button
Submit iz klijentske funkcije
function Posalji() {if (Validacija()) {
var forma = document.getElementById("form1");forma.submit();
}}
286
12/16/2018
144
Metoda Registracija() na serveru-1public IActionResult Validacija(string ime, string prezime, string lozinka, string potvrda){
Dictionary<string,string> recnikGresaka = new Dictionary<string, string>();if (ime == null){
recnikGresaka.Add("ime", "Niste uneli ime");}if (prezime == null){
recnikGresaka.Add("prezime", "Niste uneli prezime");}
if (lozinka == null){
recnikGresaka.Add("lozinka", "Niste uneli lozinku");}
if (potvrda == null){
recnikGresaka.Add("potvrda", "Niste uneli potvrdu");}
287
Metoda Registracija() na serveru-2if (potvrda != lozinka)
{recnikGresaka.Add("potvrda1","Potvrda ne odgovara lozinci");
}
if (recnikGresaka.Count == 0){
return Redirect("/Strana05.html");}else{
StringBuilder sb = new StringBuilder(); foreach (string greska in recnikGresaka.Values){
sb.Append(greska);}return Redirect($"/index.html?greska={sb.ToString()}");
} }
288
12/16/2018
145
Poziv metode za serversku validaciju
<form id="form1" action="/Home/Validacija" method="post"><label for="TextIme">Unesi ime:</label> <br><input type="text" name="ime" id="TextIme" autofocus> <br>
<label for="TextPrezime">Unesi prezime:</label> <br><input type="text" name="prezime" id="TextPrezime"> <br>
<label for="TextLozinka">Unesi lozinku:</label> <br><input type="password" name="lozinka" id="TextLozinka"> <br>
<label for="TextPotvrda">Potvrdi lozinku:</label> <br><input type="password" name="potvrda" id="TextPotvrda"> <br>
<input type="submit" value="Posalji"></form><br><span id="span1"></span>
289
Rezultat serverske validacije
290
12/16/2018
146
Pitanje 1
Za generisanje AJAX ka web serveru koristi se sledeći javascript objekat:a. XMLHttpRequestb. AjaxRequestc. Ajax
Odgovor: a
291
Pitanje 2
Na koji način se u HTML 5 zahteva obavezan unos podataka u tekst polje <input type=text"> pre sabmitovanjahtml strane do servera:a. definiše se odgovarajući klijentski kodb. definiše se atribut required input elementac. atribut optional input elementa se postavi na vrednost false
Odogovor: b
292
12/16/2018
147
Stilizovanje HTML strana
CSS
• CSS je akronim za Cascading Style Sheets
• CSS je skup specifikacija(pravila) koje omogućavaju kontrolu nad prikazom elemenata web strane
• Pravilo unutar stila je instrukacija za formatiranje ili pozicioniranje
294
12/16/2018
148
CSS sintaksa
• CSS obezbeđuje standardni način koji opisuje kako će browser prikazati sadržaj na web strani
• Pomoću css selektora se definiše element ili grupa elemenata na koje se primenjuje pravilo
• Svako css pravilo ima istu osnovnu sintaksu:
selector {property1:value;property2:value;...propertyN:value;}
295
Vrste selektora
• Selektori elemenata• Npr h2{} selektor vraća sve h2 elemente na strani
• Selektori klase• Selektor .plava{} vraća sve elemente čiji je atribut class postavljen na vrednost
plava
• Selektor klase može vratiti elemente različitog tipa
• Id selektori• Id selektor #id1{} vraća element na strani čiji je atribut id jednak vrednosti id1
296
12/16/2018
149
Dodavanje CSS stilova na web stranu
• Postoji tri osnovna načina dodavanja stilova web strani:• Interni style sheet (formatiranje na nivou strane) tj. <style></style> elementa
unutar head dela web strane
• Dodavanje linka na eksterni style sheet tzv. globalno formatiranje
• Dodavanje inline stilova tj. formatiranje za konkretan HTML element
297
Selektori elemenata - interni stylesheet
<head>
<title>Selektori elemenata</title>
<meta charset="utf-8" />
<style>
h2{
font-size: 24px;
color:green;
}
em{
color: red;
}
p{
font-size: 20px;
color:blue;
}
</style>
</head>
298
12/16/2018
150
Rezultat formatiranja
<body><h2>Prvi h2 element</h2><h2>Drugi h2 element</h2><p>Obican tekst. <em>Vazan tekst</em> <br>Obican tekst.</p></body>
299
Dodavanje linka na eksterni css fajl
300
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-
scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Referenciranje eksternog css fajla</title><link rel="stylesheet" href="/Stil1.css">
<body>
12/16/2018
151
Dodavanje inline stilova
• Stil se primenjuje na određeni HTML element
• Najveći prioritet ima inline, zatim formatiranje na nivou strane i na kraju dolazi globalno formatiranje
301
<p style="width: 200px; height: 100px; background-color: lightblue; padding: 5px;">Paragraf na koji se primenjuje inline stil</p>
Selektori klase
• Selektor klase .kl selektuje sve elemente na strani sa atrubutom class jednakim "kl"
• Može se specificirati da će se klasa primeniti samo na određene html elemente• p.kl selektor se odnosi na sve paragrafe sa klasom "kl"
• Element može referencirati više od jedne klase
302
12/16/2018
152
Upotreba selektora klase -1<head>
<title>Selektori klase</title>
<meta charset="utf-8" />
<style>
.kl1{
background-color:lightgreen;
color:blue;
}
p.kl2{
border: 1px solid black;
color:red;
}
</style>
</head>
<body>
<p class="kl1">Prvi paragraf</p>
<p class="kl2">Drugi paragraf</p>
<p class="kl1 kl2">Treci paragraf</p>
</body>303
Upotreba selektora klase -2
p{width: 200px;height: 80px;padding: 5px;
}
304
12/16/2018
153
Id selektoriSelector #glavni selektuje element sa atributom id jednakim vrednosti glavni.
<head><title>Id selektori</title><meta charset="utf-8" /><style>
body{margin: 0px;
}#glavni{
width: 600px;margin: auto;background-color:lightblue;padding: 10px;
}</style>
</head><body>
<div id="glavni">Glavni div strane.
</div></body>
305
Grupisanje selektorah1 {
color:green; }
h2 {color:green;
}
p {color:green;
}
h1,h2,p{color:green;
}
306
12/16/2018
154
Selektori atributa
• Selektor input[type] selektuje sve elemente koji imaju type atribut nezavisno od njegove vrdnosti
• Selektor input[type=text] selektuje tekst polja
• Selektor input[type=password] – selektuje password polja
• Selektor input[type=number] – selektuje numerička polka
307
Formatiranje kontrola<style>
div.forma {
width: 300px;
border: 2px solid blue;
border-radius: 5px;
background-color: lightblue;
padding: 20px;
margin: auto;
}
label{
display:inline-block;
width: 120px;
}
input[type=text],input[type=password], button {
width: 160px;
height: 30px;
padding: 5px;
margin: 10px 0px;
box-sizing: border-box;
}
</style> 308
12/16/2018
155
Forma<div class="forma">
<form action=""><label for="TextIme">Unesite ime:</label><input id="TextIme" type="text" name="Ime" />
<label for="Password1">Unesite lozinku:</label><input id="Password1" type="password" name="lozinka" />
<label></label><button type="submit">Posalji</button>
</form></div>
309
Stilizovana forma
310
12/16/2018
156
Formatiranje teksta
Familije fontova
• Suns-serif (uglavnom za naslove)• Arial, Helvetica, Verdana
• Serif font (koriste se za velike paragrafe)• Times, Times New Roman, Georgia
• Monospaced font (za prikaz kompluterskog koda)• Courier New, Lucida Console
312
12/16/2018
157
Svojstvo font-family<style>
.f1{font-family:Arial, Helvetica, sans-serif;
}.f2{
font-family:'Times New Roman', Times, serif;}.f3{
font-family:Courier New, Courier, monospace;}
</style>
313
Prikaz fontova-1<body>
<p class="f1">Serifni fontovi<br />here are many variations ...
</p><p class="f2">
Sans-serif font<br/>here are many variations ...
</p><p class="f3">
Monospace font<br />here are many variations ... </p>
</body>
314
12/16/2018
158
Prikaz fontova-2
315
Upotreba web fontovahttps://fonts.google.com/
316
12/16/2018
159
Primer upotrebe Google fontova<link href="https://fonts.googleapis.com/css?family=Playfair+Display" rel="stylesheet">
<style>
.fs1{
font-family: 'Playfair Display', serif;
color:#3d74b1;
}
</style>
<p class="fs1">
Lorem Ipsum...
</p>
317
Svojstvo font-size
.fs1 {font-size:16px;
}.fs2 {
font-size:150%;/*Velicina fonta parent elementa * 150 % */}.fs3 {
font-size:1em; /*Osnovna velicina fonta strane obicno 16px*/}
318
12/16/2018
160
Prikaz fontova
<body><p class="fs1">Prvi paragraf 16 px</p><p class="fs2">Drugi paragraf 150 %</p><p class="fs3">Treci paragraf 1em</p><p>Podrazumevana velicina fonta</p>
</body>
319
font-style svojstvo<html xmlns="http://www.w3.org/1999/xhtml"><head>
<title>Font-Style</title><style type="text/css">
p.n {font-style: normal;
}p.i {
font-style: italic;}
</style></head><body>
<p class="n">Ovo je normalan tekst</p><p class="i">Ovo je iskoseni tekst</p>
</body></html>
320
12/16/2018
161
font-weight svojtsvo<head><title>font-weight</title><style type="text/css">p.normal {font-weight: normal;}
p.bold {font-weight: bold;}</style></head>
<body><p class="normal">Normalni tekst</p><p class="bold"> Boldovani tekst</p></body>
321
Heksadecimalna predstava boja<style>
.crvena {background-color: #ff0000;
}
.zelena {background-color: #00ff00;
}
.plava {background-color: #0000ff;
}</style>
<body><h2>HEX Color </h2>
<h2 class="crvena">#FF0000
</h2>
<h2 class="zelena">#00FF00
</h2>
<h2 class="plava">#0000FF
</h2></body>
322
12/16/2018
162
Korišćenje validnih imena boja
<style>.crvena{
background-color:red;}.zelena {
background-color:green;}
.plava {background-color:blue;
}</style>
323
Definisanje boje teksta
<style>body {
color: blue;}
h1 {color: green;
}</style>
324
12/16/2018
163
Definisanje prozračnosti tekstaopacity:1; /*neprozračan tekst*/opacity:0; /*nevidljiv tekst*/opacity:0.5; /*srednje proziranan tekst*/
<style>.p1{
color:red;opacity:0.5;
}
.p2{color:red;opacity:0;
}</style>
325
Ravnanje teksta<style>
.levo {text-align: left;
}
.desno {text-align: right;
}
.centrirano {text-align: center;
}</style>
326
12/16/2018
164
Css pozicioniranje
CSS Box model
• Box model tretira html elemenat kao kolekciju od 4 koncentrična pravougaonika koji prdstavljaji sadržaj, padding, granice i margine elementa
328
12/16/2018
165
CSS Box model-2
• Svojstva height i width definišu visinu i širinu sadržaja elementa u pikselima
• Širina i visina padding pravougonika definišu se svojstvom padding
• Border pravougaonik definiše se svojstvom border kojim se setuje širina pravougaonika, boja i stil
• Svojstva padding i border su složena svojstva
329
Svojstvo pading
.pad {padding-top: 10px;padding-right: 10px;padding-bottom: 10px;padding-left: 10px;
}
330
12/16/2018
166
Svojstvo border
• Svojstva border-with, border-style i border-color su takođe složena svojstva i koriste se kada su sve 4 vrednosti odgovarajućeg pravougaonika jednake
.bor{border-width: 2px;border-style: dotted;border-color: blue;
}
.b1 {border-left-style: dotted;border-left-width: 2px;}
331
Definisanje box-a<style>
body{margin:0px;
}#div1{
/*gornja desna donja leva margina*/margin: 10px 20px;width:200px;height:100px;background-color:#b0c2d8;padding:10px 15px;border: 5px solid #0c2196;color:#000000;
}</style>
332
<body><div id="div1">
Div1</div>
</body>
12/16/2018
167
Sadržaj elementa
333
Pading elementa
334
12/16/2018
168
Border elementa
335
Margine elementa
336
12/16/2018
169
Zauzet prostor od strane elementa
250px (sirina)+ 20px (levi i desni padding)+ 10px (levi i desni border)+ 40px (leva i desna margina)= 320px
<style>
p.p1{
width:250px;
height:30px;
padding:10px;
border:5px solid red;
margin:20px;
}
</style>
337
Svojstvo position
• Elementi su pozicionirani na strani korišćenjem normalnog toka (normal flow)
• Blok elementi se pozicioniraju odozgo na dole, a inline elementi s leva na desno (jer oni ne počinju u novoj liniji)
• Svojstvo position može imati sledeće vrednosti:• static - isto kao i normalni tok• relative - offset u odnosu na normal flow• absolute - pozicioniranje u odnosu na gornji levi ugao kontejnerskog
elementa• fixed - pozicioniranje u odnosu na gornji levi ugao browsera, ne menja se
pozicija pri skrolovanju
338
12/16/2018
170
Normalni tok -1
<body><p>Prvi</p><p>Drugi</p><p>Treci</p>
</body>
<style>body{margin:0px;
}p{
width:200px;height:100px;border:2px solid #1e1093;padding:10px;background-color:#00ff21;margin-top:0px;
}</style>
339
Normalni tok -2
340
12/16/2018
171
Pitanje 1Ako je unutar css fajla definisano formatiranje :
.naglasen {color:red;font-size:16pt;
}Paragraf koji koji treba da koristi gore definisano formatiranje specificira se izrazom:a. <p id="naglasen"> b. <p class="naglasen"> c. <p format=".naglasen">
Odgovor: b
341
Pitanje 2
Ukoliko je za paragraf definisana svojstvo "background-color" unutar inline stila (atributa style) , ali se takođe definicija za svojstvo "background-color" nalazi u eksternom css fajlu koga web strana referencira tada je pozadinska boja paragrafa na toj strain definisana:a. inline stilomb. css fajlomc. kombinacijom inline stila i css fajla
Odgovor: a
342
12/16/2018
172
Pitanje 3
Ukoliko želimo iskošeni tekst unutar div elementa čiji id atribut ima vrednost div1, tada prilikomdefinicije formatiranja unutar #div1{ } dela css fajla treba napisati:a. font-weight: italic;b. font-style: italic;c. font-style: italic;
Odgovor: b
343
Pitanje 4
Ako pri definisanju fomatiranja nekog elementa nije definisano njegovo svojstvo position,tada je podrazumevana vrednost svojstva position:a. relativeb. absolutec. static
Odgovor: c
344
12/16/2018
173
Uvod u jQuery
Node.js instalacija
346
12/16/2018
174
Node.js instalacija
https://nodejs.org/en/download/
347
Provera verzije npm menadžera
348
12/16/2018
175
Fajl package.json
• Kreira se korišćenjem komande: npm init --yes
• Specificira pakete od kojih zavisi projekat
• Specificira verziju pakata koju projekat koristi
• Omogućava lakše deljenje paketa
349
350
Instaliranje jQuery bibliotekenpm install jquery
12/16/2018
176
Instalirana jQuery biblioteka
351
Ekstenzija jQuery Code Snippets
352
12/16/2018
177
Izvršavanje koda kada je strana učitana
<body><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(document).ready(function () { console.log("Strana je ucitana u: " + new Date().toLocaleTimeString());
});</script>
</body>
353
Skraćenica za $(document).ready()
354
<script>$(function () {
console.log("Strana je ucitana u: " + new Date().toLocaleTimeString());
});</script>
$(document).ready(); == $();
12/16/2018
178
Osnovni jQuery selektori
• jQuery ima tri vrste selektora• Selektori elemenata
• Id selektori
• Selektori klase
355
Definisanje klasa stilova
<style>.plava {color: rgb(175, 185, 240);}
.crvena {color: rgb(238, 41, 41);}</style>
356
12/16/2018
179
Telo html dokumenta
<body><ul id="list1">
<li class="plava">Stavka 1</li><li class="plava">Stavka 2</li><li class="crvena">Stavka 3</li><li class="crvena">Stavka 4</li>
</ul><p class="plava">Ovo je paragraf 1</p><p>Ovo je paragraf 2</p><p class="crvena">Ovo je paragraf 3</p><p>Ovo je paragraf 4</p>
</body>
357
Selekcija svih paragrafa<script>
$(function () {$("p").css("border", "2px solid red");alert("Ima ukupno " + $("p").length + " paragrafa");
});</script>
358
12/16/2018
180
Selekcija na osnovu klase<script>
$(function () {$(".plava").css("border", "2px solid red");
});</script>
359
Selekcija elemenata određenog tipa na osnovu klase
<script>$(function () {
$("p.plava").css("border", "2px solid red");});
</script>
360
12/16/2018
181
Selektovanje prvog elementa određenog tipa
<script>$(function () {
$("p:first").css("border", "2px solid red");});
</script>
361
Selektovanje poslednjeg elementa određenog tipa
<script>$(function () {
$("p:last").css("border", "2px solid red");});
</script>
362
12/16/2018
182
Selektovanje parnih elementa određenog tipa
363
<script>$(function () {
$("p:even").css("border", "2px solid red");});
</script>
Selektovanje neparnih elementa određenog tipa
<script>$(function () {
$("p:odd").css("border", "2px solid red");});
</script>
364
12/16/2018
183
<script>$(function () {
$("#list1").css("border", "2px solid red");});
</script>
Selekcija elementa na osnovu Id selektora
365
Selektovanje prvog (poslednjeg) elementa određene klase
<script>$(function () {
$("li.plava:first").css("border", "2px solid green");$("li.crvena:last").css("border", "2px solid green");
});</script>
366
12/16/2018
184
Selektori :gt(index) i :lt(index)<script>
$(document).ready(function () {$("p:gt(0)").css("border", "3px solid red");// $("p:lt(2)").css("border", "3px solid red");
});</script>
367
Selektor :eq(index)
368
<script>$(function () {
$("p:eq(1)").css("border", "2px solid green");});
</script>
12/16/2018
185
Selektor :not(selector)
<script>$(function () {
$("p:not(:eq(2))").css("border", "2px solid green"); });
</script>
369
Selektor atributa $( "[attribute]" )
<script>$(function () {
$("p[class]").css("border", "2px solid green"); });
</script>
370
12/16/2018
186
Pronalaženje elementa sa datom vrednošću atributa
<script>$(function () {
$("p[class=plava]").css("border", "2px solid green"); });
</script>
371
Telo html dokumenta
<body><ul id="list1">
<li class="plava">Stavka 1</li><li class="plava">Stavka 2</li><li class="crvena">Stavka 3</li><li class="crvena">Stavka 4</li>
</ul><p class="plava">Ovo je paragraf 1</p><p class="text-left">Ovo je paragraf 2</p><p class="crvena">Ovo je paragraf 3</p><p class="text-center">Ovo je paragraf 4</p>
</body>
372
12/16/2018
187
Pronalaženje elementa čiji atribut počinje sa datom vrednošću
<script>$(function () {
$("p[class^=text]").css("border", "2px solid green"); });
</script>
373
Pronalaženje elementa čiji se atribut završava sa datom vrednošću
374
<script>
$(function () {
$("p[class$=na]").css("border", "2px solid green");
});
</script>
12/16/2018
188
Pronalaženje elementa čiji atribut sadržidatu vrednost
375
<script>$(function () {
$("p[class*=xt]").css("border", "2px solid green");
});</script>
jQuery( ":contains(text)" )
<script>$(function () {
$("p:contains(para)").css("border", "2px solid green"); });
</script>
376
12/16/2018
189
Funkcija css()
.css( "nazivSvojstva", "vrednostSvojstva")
<script>$(function () {
$("h1").css("color", "red");});
</script>
<script>$(function () {
// $("h1").css("color", "red");$("h1").css({
color: "red","font-size":"60px"
});});
</script> 377
Setovanje i čitanje atributa elementa, attr() funkcija
378
<script>
function Citaj() {
var src = $("img:first").attr("src");
alert(src);
}
function Promeni() {
//$("img").attr("src", "/Slike/3.jpg");
//$("img").attr("width", "200px");
$("img").attr({
src: "/Slike/3.jpg",
width:"200px",
title:"Jutarnja kafa"
});
}
</script>
12/16/2018
190
Setovanje atributa interfejs<img src="/Slike/1.jpg" /><img src="/Slike/2.jpg" /><img src="/Slike/3.jpg" /><br /><input id="Button1" type="button" value="Citaj" onclick="Citaj()" /><input id="Button2" type="button" value="Promeni" onclick="Promeni()" />
379
Funkcija append(htmlString)<body>
<ul id="ul1"><li>Stavka1</li><li>Stavka2</li>
</ul><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(function () {$("#ul1").append("<li>Stavka3</li>");var st4 = $("<li>Stavka4</li>");$("#ul1").append(st4);
});</script>
</body>
380
12/16/2018
191
Funkcija prepend()<body>
<ol><li>Stavka 1</li><li>Stavka 2</li><li>Stavka 3</li>
</ol><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(function () {$("ol").prepend("<li>Stavka 0</li>");
});</script>
</body>
381
Metode after() i before()<body>
<p id="p1">Sadrzaj paragrafa</p><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(function () {$("#p1").after("<p>Pozdrav1</p>");$("#p1").before("<p>Pozdrav2</p>");
}); </script>
</body>
382
12/16/2018
192
Funkcija .eq()<body>
<ul><li>Stavka1</li><li>Stavka2</li><li>Stavka3</li><li>Stavka4</li>
</ul><script src="/node_modules/jquery/dist/jquery.min.js"></script>
<script>
$(function () {
$("li").eq(1).css("color", "red");});
</script></body>
383
Funkcija detach()
<body><p id="p1">
Ovo je paragraf 1</p><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(function () {$("#p1").detach();
});</script>
</body>
384
12/16/2018
193
Metoda replaceWith(htmlString)
<body><p id="p1">
Ovo je paragraf 1</p><script src="/node_modules/jquery/dist/jquery.min.js"></script><script>
$(function () {$("#p1").replaceWith(`<p id="p2">Ovo je paragraf 2</p>`);
});</script>
</body>
385
Funkcija .find(selector)
386
Traži potomke datog elementa
<script>//drugi redvar tr = $("#table1").find("tr:eq(1)")tr.css("color", "red");
// prva celija redavar td = tr.find("td:eq(0)");td.css("background-color", "yellow");
</script>
<table id="table1">
<tr>
<td>Pera</td>
<td>Peric</td>
<td>25</td>
</tr>
<tr>
<td>Mika</td>
<td>Mikic</td>
<td>22</td>
</tr>
</table>
12/16/2018
194
html() funkcija<body>
<div><ul id="list1">
<li>Stavka1</li><li>Stavka2</li>
</ul></div>
<scriptsrc="/node_modules/jquery/dist/jquery.min.js"></script>
<script>$(function () {
alert($("#list1").html());});
</script></body>
387
Setovanje html-a elementa
<script>
$(function () {$("li:first").html("Prva stavka");
});</script>
388
12/16/2018
195
funkcija text()
<script>
$(function () {alert($("p:last").text());
});</script>
<body><div>
<p>Ovo je prvi paragraf</p><p>Ovo je drugi paragraf</p><p>Ovo je treci paragraf</p>
</div></body>
389
Setovanje teksta elementa
<script>$(function () {
$("p:last").text("Ovo je tekst poslednjeg paragrafa");});
</script>
390
12/16/2018
196
Funkcija val()<body>
<form>
<label for="Text1">Unesi tekst:</label> <br>
<input id="Text1" type="text" />
<br><br>
<input id="Button1" type="button" value="Kopiraj" onclick="Kopiraj()"/>
<br>
<br>
<input id="Text2" type="text" readonly />
</form>
<script src="/node_modules/jquery/dist/jquery.min.js"></script>
<script>
function Kopiraj() {
var t1 = $("#Text1").val();
$("#Text2").val(t1);
}
</script>
</body>391
Primer-funkcija val()
<form><label for="Text1">Unesite prvi operand</label><br><input id="Text1" type="text"><br /><label for="Text2">Unesite drugi operand</label><br><input id="Text2" type="text"><br ><br /><br /><input id="Button1" type="button" value="Izracunaj"
onclick="Izracunaj()"></form>
392
12/16/2018
197
Primer-2<script>
function Izracunaj() {var prvi = $("#Text1").val();var a = parseFloat(prvi);
var drugi = $("#Text2").val();var b = parseFloat(drugi);
var zbir = a + b;
alert("Zbir je " + zbir);
$("#Text1").val("");$("#Text2").val("");
}</script>
393
Iščitavanje kontrola forme
12/16/2018
198
Metoda prop()
<script>$(function () {
$("#CheckBox1").prop("checked", "true");$("#CheckBox2").prop("checked", "true");$("#CheckBox3").prop("checked", "true");
});</script>
if ($("#CheckBox1").prop("checked")) {}
395
Iščitavanje checkbox kontrola-html
<form><input id="Checkbox1" type="checkbox" name="Checkbox1" value="true" /><label for="Checkbox1">Opcija1</label><br />
<input id="Checkbox2" type="checkbox" name="Checkbox2" value="true" /><label for="Checkbox2">Opcija2</label><br />
<input id="Checkbox3" type="checkbox" name="Checkbox3" value="true" /><label for="Checkbox3">Opcija3</label><br /><br /><button type="button" onclick="Prikazi()">Prikazi</button>
</form>
<br /><br /><span id="span1"></span>
396
12/16/2018
199
Iščitavanje checkbox kontrola-script
<script>function Prikazi() {
var labela = $("#span1"); labela.html("");if ($("#Checkbox1").prop("checked")) {
labela.append("Opcija1<br>");}
if ($("#Checkbox2").prop("checked")) {labela.append("Opcija2<br>");
}
if ($("#Checkbox3").prop("checked")) {labela.append("Opcija3<br>");
}
}</script>
397
<script src="/lib/jquery/dist/jquery.min.js"></script>
Upotreba radio kontrola-html<form>
<input id="Radio1" name="opcije" type="radio" value="1" /><label for="Radio1">Opcija1</label><br />
<input id="Radio2" name="opcije" type="radio" value="2" /><label for="Radio2">Opcija2</label><br />
<input id="Radio3" name="opcije" type="radio" value="3" /><label for="Radio3">Opcija 3</label><br /><br />
<input id="Button1" type="submit" onclick="Citaj()" value="Citaj" /></form><br /><span id="span1"></span>
398
12/16/2018
200
Upotreba radio kontrola- klijentski kodfunction Citaj() {
var labela = $("#span1");var selektovano = $("input[name=opcije]:checked");
var vrednost = selektovano.val();
if (vrednost) {labela.text("Selektovana vrednost je: " + vrednost);
}else {
labela.text("Niste odabrali ni jednu opciju");}
}
399
Upotreba radio kontrola-3
400
12/16/2018
201
Iščitavanje dropdown liste-html
<form><select id="Select1" name="opcije">
<option value="0">Odaberite opciju</option><option value="1">Opcija1</option><option value="2">Opcija2</option><option value="3">Opcija3</option>
</select><br /><button type="button" onclick="prikazi()">Prikazi</button>
</form><br /><span id="span1"></span>
401
Iščitavanje dropdown liste-script
<script>function prikazi() {
var t = $("#Select1 option:selected").text();//var v = $("#Select1 option:selected").val();var v = $("#Select1").val();alert(t + " " + v);
}
402
12/16/2018
202
Pitanje 1
403
Selekcija svih paragrafa u script kodu korišćenjem jquery biblioteke vrši se korišćenjem izraza:a. $("p")b. $(".p")c. $("#p")
Odgovor: a
Pitanje 2
Da bi se napisao kod koga treba izvršiti kada se html dokument učita u browser koristi sejquery funkcija:a. loaded()b. ready()c. hover()
Odgovor: b
404
12/16/2018
203
Pitanje 3
Neka se u html formi nalazi tekst polje <input id="Text1" type="text" />.Vrednost koja je unešena u tekst polje iščitava se primenom jQuery na sledeći način:a. var prvi = $("#Text1").val();b. var prvi = $("#Text1").text();c. var prvi = $("#Text1").html();
Odgovor: a
405
Pitanje 4Ukoliko želimo da posredstvom jquery koda formatiramo neki html element koristićemo jqueryfunkciju:a. format()b. css()c. style()
Odgovor: b
406
12/16/2018
204
Pitanje 5
Ukoliko želimo da posredstvom jquery koda promenimo kompletan html nekom elementu koristićemo
jquery funkciju:
a. html()
b. text()
c. changehtml()
Odgovor: a
407
Pitanje 6Ako je data kontrola forme :<input id= "CheckBox1" type="checkbox"/>. Koji od navedenih izraza mora imati logičku vrednost true ako je ova checkbox kontrola čekirana?
a. $("#CheckBox1").isChecked("checked") b. $("#CheckBox1").prop("checked") c. $("#CheckBox1").checked("checked")
Odogovor: b
408
12/16/2018
205
Pitanje 7Ako forma sadrži 3 radio button kontrole sa istim atributom name postovaljenim na vrednost "opcije", tada se vrednost selektovanog radio dugmeta iščitava primenom jquery koda:
a. $("input[name=opcije]:checked").val()b. $("input[name=opcije]").val()c. $("input[name=opcije]:checked").text()
Odogovor: a
409
Pitanje 8
Ako forma sadrži <select id="Select1"> kontrolu sa više <option> elemenata. Vrednost selektovane opcije ove kontrole čita se primenom jquery koda:
a. $("#Select1 :selected").val()b. $("#Select1").val()c. $("#Select1 option:selected").html()
Odogovor: b
410
12/16/2018
206
jQuery AJAX
$.get() metoda
• $.get() metoda se koristi za asinhrone GET zahteve ka serveru
• Get zahtevi se keširaju i podaci uzeti GET zahtevom se ne menjaju
• Vraća jqXHR objekat koji nadograđuje funkcionalnost XMLHTTPRequest objekta
412
12/16/2018
207
Metoda $.getJSON(uri)
413
var zahtev = $.getJSON("/Home/VratiProizvode");
var zahtev = $.getJSON("/Home/NadjiProizvod" + id);
Učitavanje JSON podataka sa servera korišćenjem AJAX GET zahteva
Models folder klasa Proizvod
public class Proizvod{
public int ProizvodId { get; set; }public int KategorijaId { get; set; }public string NazivProizvoda { get; set; }public decimal Cena { get; set; }public int KolicinaNaLageru { get; set; }
}
414
12/16/2018
208
Klasa Konekcija, folder Controllers
415
static class Konekcija
{ public static string cnnMagacin = KreirajKonekciju();
public static string KreirajKonekciju()
{
SqlConnectionStringBuilder cnnSb = new SqlConnectionStringBuilder();
cnnSb.DataSource = @".\SqlExpress";
cnnSb.InitialCatalog = "Magacin";
cnnSb.IntegratedSecurity = true;
return cnnSb.ToString();
}
}
Metoda VratiProizvode() klasa HomeController -1
416
public JsonResult VratiProizvode()
{
List<Proizvod> lista = new List<Proizvod>();
using (SqlConnection konekcija = new SqlConnection(Konekcija.cnnMagacin))
{
using (SqlCommand komanda = new SqlCommand("SELECT * FROM Proizvod", konekcija))
{
try
{
konekcija.Open();
using (SqlDataReader dr = komanda.ExecuteReader())
{
while (dr.Read())
{
Proizvod p = new Proizvod
{
ProizvodId = dr.GetInt32(0),
KategorijaId = dr.GetInt32(1),
NazivProizvoda = dr.GetString(2),
Cena = dr.GetDecimal(3),
KolicinaNaLageru = dr.GetInt32(4)
};
...
12/16/2018
209
Metoda VratiProizvode() klasa HomeController -1lista.Add(p);
}
}
return Json(lista);
}
catch (Exception)
{
return Json("Greska");
}
}
}
}
417
Generisanje asinhronog get zahtevafunction PrikaziProizvode() {
var ul1 = $("#ul1");
var zahtev = $.getJSON("/Home/VratiProizvode");
zahtev.done(function (proizvodi) {for (var i in proizvodi) {
ul1.append(`<li>${proizvodi[i].proizvodId} ${proizvodi[i].nazivProizvoda}</li>`);}
});
zahtev.fail(function (gr) {$("#p1").text(gr.statusText);
});}
418
$(function () {PrikaziProizvode();
});
12/16/2018
210
Korisnički interfejs strane
419
<body><h1>Svi proizvodi</h1><ul id="ul1">
</ul></body>
Metoda NadjiProizvod() klasa HomeController -1
420
public JsonResult NadjiProizvod(int id){
using (SqlConnection konekcija = new SqlConnection(Konekcija.cnnMagacin)){
using (SqlCommand komanda = new SqlCommand("SELECT * FROM Proizvod WHERE ProizvodId = @ProizvodId", konekcija)){
....}
}}
12/16/2018
211
Metoda NadjiProizvod() klasa HomeController -2
421
try{
komanda.Parameters.AddWithValue("@ProizvodId", id);konekcija.Open();using (SqlDataReader dr = komanda.ExecuteReader()){
dr.Read();Proizvod p1 = new Proizvod{
ProizvodId = dr.GetInt32(0),KategorijaId = dr.GetInt32(1),NazivProizvoda = dr.GetString(2),Cena = dr.GetDecimal(3),KolicinaNaLageru = dr.GetInt32(4)
};return Json(p1);
}}catch (Exception){
return Json(new Proizvod());}
Korisnički interfejs strane<hr><form>
<label for="Number1">Unesite Id</label><br><input type="number" id="Number1"> <br>
<input id="Button1" type="button" value="Pronadji"onclick="Pronadji()" /></form><br><p id="p1"></p>
422
12/16/2018
212
Prosleđivanje parametara $.get() metodi
423
function Pronadji() {
var id = $("#Number1").val();
var zahtev = $.getJSON("/Home/NadjiProizvod/" + id);zahtev.done(function (proizvod) {
$("#p1").html(`${proizvod.proizvodId} <br>${proizvod.nazivProizvoda}<br>${proizvod.cena}`
);});
zahtev.fail(function (gr) {$("#p1").html(gr.statusText);
});
}
Rezultat zahteva
424
12/16/2018
213
$.post() metoda
• Glagol POST se koristi da se naznači da zahtev može promeniti podatke na serveru
• POST zahtevi se nikad ne keširaju
425
Korisnički interfejs
426
12/16/2018
214
Html forma
427
<body>
<form id="form1">
<label for="Select1"> Odaberite kategoriju:</label><br>
<select id="Select1" name="KategorijaId"></select>
<br>
<label for="TextNaziv"> Naziv proizvoda:</label> <br>
<input id="TextNaziv" type="text" name="NazivProizvoda" required><br>
<label for="TextCena">Cena:</label><br>
<input id="TextCena" type="text" name="Cena" required><br>
<label for="TextKolicina">Kolicina</label> <br>
<input id="TextKolicina" type="text" name="KolicinaNaLageru" required><br />
<br />
<input id="Button1" type="button" value="Sacuvaj" onclick="Sacuvaj()" />
</form>
<br>
<p id="p1"></p>
<a href="/index.html">Vidi proizvode</a>
</body>
HomeController -1
428
public JsonResult VratiKategorije()
{
List<Kategorija> listaKategorija = new List<Kategorija>();
using (SqlConnection konekcija = new SqlConnection(Konekcija.cnnMagacin))
{
using (SqlCommand komanda = new SqlCommand("SELECT * FROM Kategorija", konekcija))
{
...
}
}
}
12/16/2018
215
HomeController -2
429
try
{
konekcija.Open();
using (SqlDataReader dr = komanda.ExecuteReader())
{
while (dr.Read())
{
Kategorija k1 = new Kategorija();
k1.KategorijaId = dr.GetInt32(0);
k1.NazivKategorije = dr.GetString(1);
k1.OpisKategorije = dr.GetString(2);
listaKategorija.Add(k1);
}
}
return Json(listaKategorija);
}
catch (System.Exception)
{
return Json("greska");
}
Prikaz kategorija u select elementu
430
function PrikaziKategorije() {var zahtev = $.getJSON("/Home/VratiKategorije");zahtev.done(function (kategorije) {
for (var i = 0; i < kategorije.length; i++) {var stavka = $("<option></option>");stavka.attr("value", kategorije[i].kategorijaId);stavka.text(kategorije[i].nazivKategorije);$("#Select1").append(stavka);
}});
zahtev.fail(function (gr) {$("#p1").text(gr.statustext);
});}
$(function () {PrikaziKategorije();
});
12/16/2018
216
HomeController metoda UbaciProizvod() -1
[HttpPost]public static int UbaciProizvod(Proizvod p){
StringBuilder sb = new StringBuilder();sb.AppendLine("INSERT INTO Proizvod VALUES (@KategorijaId, @NazivProizvoda, @Cena,
@KolicinaNaLageru)");sb.AppendLine("SELECT CAST(SCOPE_IDENTITY() AS int)");
int Id = 0;using (SqlConnection konekcija = new SqlConnection(Konekcija.cnnMagacin)){...
}}
431
HomeController metoda UbaciProizvod() -2using (SqlCommand komanda = new SqlCommand(sb.ToString(), konekcija))
{try{
komanda.Parameters.AddWithValue("@KategorijaId", p.KategorijaId);komanda.Parameters.AddWithValue("@NazivProizvoda", p.NazivProizvoda);komanda.Parameters.AddWithValue("@Cena", p.Cena);komanda.Parameters.AddWithValue("@KolicinaNaLageru", p.KolicinaNaLageru);
konekcija.Open();Id = (int)komanda.ExecuteScalar();return Id;
}catch (Exception){
return -1;}
}
432
12/16/2018
217
jQuery biblioteka za validaciju
433
<script src="/lib/jquery/dist/jquery.min.js"></script><script src="/lib/jquery-validation/dist/jquery.validate.min.js"></script>
Serijalizacija forme
434
function Sacuvaj() {
$("#form1").validate();
if ($("#form1").valid() == false) {
alert("Podaci nisu validni");
return;
}
$("#Button1").attr("disabled", "disabled");
var podaci = $("#form1").serialize();
var zahtev = $.post("/Home/UbaciProizvod", podaci);
zahtev.done(function (rezultat) {
$("#p1").text(rezultat);
});
zahtev.fail(function (err) {
$("#p1").text(err.statusText);
});
$("#Button1").removeAttr("disabled");
}
12/16/2018
218
Metoda $.ajax()
• Izvršava asinhroni http AJAX zahtev
• Metodi $.ajax() prosleđuje se java script objekat koji sadrži key, value parove
• ključ type specificira tip zahteva (podrazumevano GET)
• ključ url specificira url adresu zahteva
• ključ data specificira podatke koji se prosleđuju do servera
• ključ dataType specificira tip podataka koje očekujemo od servera
• ključ contentType specificira tip podataka koje šaljemo ka serveru
435
Metoda $.ajax()
• Metoda $.ajax() vraća jqXHR objekat koji u sebi sadrži ugrađeni XMLHttpRequest objekat:
var zahtev = $.ajax({ ....
});
• zahtev.done(function(podaci){...}) –testiranje uspešnost ajax zahteva kada se podaci prosleđuju definisanoj callback anonimnoj funkciji
• zahtev.fail(function (xhr, status, error) {...}) – anonimna funkcija koja se izvršava u slučaju greške pri izvršavanju ajax zahteva
436
12/16/2018
219
Prosleđivanje name-value parova
437
var podaci = $("#form1").serialize();
var zahtev = $.ajax({type: "POST",url: "/Home/UbaciProizvod",data: podaci,dataType:"text"
});
contentType: "application/x-www-form-urlencoded; charset=UTF-8"
Pitanje 1
438
Odgovor: a
Kako se kod $.ajax() jquery metode specificira tip podataka koji se prosleđuju web
serveru
a. pomoću ključa contentType objekta koji se prosleđuje metodi
b. pomoću ključa dataType objekta koji se prosleđuje metodi
c. pomoću ključa type objekta koji se prosleđuje metodi
12/16/2018
220
Pitanje 2
439
Odgovor: c
Za generisanje GET zahteva ka web serveru kojim se od servera dobijaju podaci u
JSON formatu koristi se jquery funkcija
a. $.getJsonText()
b. $.Json()
c. $.getJSON()
Pitanje 3
440
Odgovor: c
Metoda $.ajax() jquery biblioteke može da generiše
a. GET zahtev
b. POST zahtev
c. GET zahtev i POST zahtev
12/16/2018
221
Lambda izrazi
Kreitanje konzolne .NET Core aplikacijedotnet new console
442
12/16/2018
222
Pokretanje konzolne aplikacije
dotnet run
443
Delegat Func<T,TResult> i lambda izrazi
• Delegat Func<TResult> je pokazivač na metodu bez ulaznih parametar
• Delegat Func<T,TResult> je pokazivač na metodu koja ima jedan ulazni parametar tipa T i vraća rezultat tipa TResult
• Func<T1,T2,TResult> je pokazivač na metodu sa dva ulazna parametra tipa T1 i T2 koja ima povratnu vrednost tipa TResult
• Lambda izraz je izraz koji vraća metodu
• Lambda izrazi se definišu korišćenjem => operatora
• Lambda izrazi imaju prirodnu i preciznu sintaksu
444
12/16/2018
223
x => x * x
Za dato x, izračunaj x * x
Visual C# izvodi tipove na osnovu konteksta u kome se nalazi lambda izraz
static void Main(string[] args){
Func<int, int> f1 = x => x *x;int rez = f1(5);Console.WriteLine(rez);
}
Lambda izraz sa jednim ulaznim parametrom
445
Lambda izraz za metodu sa dva ulazna parametra
static void Main(string[] args){
Func<int, int, int> f1 = (x, y) => x + y;int rez = f1(5, 6);Console.WriteLine($"Rezultat je: {rez}");
}
446
12/16/2018
224
Lambda izraz za metodu bez parametara
static void Main(string[] args){
Func<string> f1 = () => DateTime.Now.ToShortDateString();
string rez = f1();Console.WriteLine($"Rezultat je: {rez}");
}
447
Ekstenzione metode
• Ektenziona metoda omogućava da dodajemo metode u postojeću klasu bez potrebe da kreiramo izvedenu klasu
• To su statičke metode ali se pozivaju kao da su nestatičke metode klase koji proširujemo
• Definiše se statička klasa koja će sadržati ekstenzione metode
• Klasa mora biti vidljiva za kod koji će je pozivati
448
12/16/2018
225
Kreiranje ekstenzione metode
• Ekstenziona metoda je statička metoda sa najmanje istom vidljivošću kao i klasa koja je sadrži
• Prvi parametar ekstenzione metode je tip sa kojim metoda radi ispred koga se nalazi reč this
• Ovakva metoda se poziva kao da je instance metoda tipa koga proširuje
449
Primer ekstenzione metode koja proširuje klasu string
450
static class EkstenzioneMetode{
public static string VelikoPrvoSlovo(this string s){
s = s.Trim().ToLower();if (s.Length > 1){
return s.Substring(0, 1).ToUpper() + s.Substring(1);}return string.Empty;
}}
12/16/2018
226
Poziv ektenzione metode
451
static void Main(string[] args){
string s1 = "MARKO";string ime = s1.VelikoPrvoSlovo();Console.WriteLine(ime);
}
Marko
Klasa Enumerable
• Nalazi se u prostoru imena System.Linq
• TSource generički tip koga sadrži izvor podataka
• Statičke metode klase Enumerable su ekstenzione metode koje proširuju izvor podataka koji implementira IEnumerable<TSource> intefejs
• Statičke metode klase Enumerable omogućavaju da se pišu upiti nadbilo kojim izvorom podataka koji primenjuje interfejs IEnumerable<T>
452
public static class Enumerable
12/16/2018
227
Ekstenziona metoda Select klase Enumerable
public static IEnumerable<TResult> Select<TSource, TResult>(this IEnumerable<TSource> source,Func<TSource, TResult> selector
)
• Ekstenziona metoda Select proširuje tip IEnumerable<TSource>• source je izvor podataka koji imlementira interfejs IEnumerable• selector je anonimna transformaciona funkcija koja se primenjuje nad
svakim članom u izvoru podataka• Povratna vrednost je sekvenca nastala primenom transformacione
funkcije nad izvorom podataka
453
Primer upotrebe ekstenzione metode Select()
454
using System;using System.Linq;using System.Collections.Generic;using System.Text;
static void Main(string[] args){
int[] brojevi = { 1, 3, 5, 15, 9, 24 };
IEnumerable<int> kvadrati = brojevi.Select(x => x * x);StringBuilder sb = new StringBuilder();foreach (int i in kvadrati){
sb.AppendLine(i.ToString());}System.Console.WriteLine(sb.ToString());
}
12/16/2018
228
Ekstenziona metoda Where klase Enumerable
• Where ekstenziona metoda proširuje tip IEnumerable<TSource>
• source je izvor podataka koji imlementira interfejs IEnumerable
• Where ekstenziona metoda kao parametar ima instancu delegata Func<TSource, bool>, ova instanca je označena sa predicate
• Parametar predicate može biti bilo kakav lambda izraz (anonimna funkcija) sa ulazom tipa TSource i izlazom tipa bool
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate
)
455
Primer upotrebe Where ekstenzione metode -1
static void Main(string[] args){
int[] brojevi = { 0, 1, 2, 3, 4, 5, 6 };
// definisanje upita
IEnumerable<int> upit = brojevi.Where(n => n % 2 == 0);
StringBuilder sb = new StringBuilder();
foreach (int i in upit){
sb.AppendLine(i.ToString());}
System.Console.WriteLine(sb.ToString());}
456
12/16/2018
229
Primer upotrebe Where ekstenzione metode -2
457
static void Main(string[] args){
string[] imena = { "Marko", "Lazar", "Ivan", "Marija", "Jovana", "Jovan", "Desimir" };
IEnumerable<string> upit = imena.Where(s => s.StartsWith("m",StringComparison.CurrentCultureIgnoreCase));
StringBuilder sb = new StringBuilder();
foreach (string n in upit){
sb.AppendLine(n);}
System.Console.WriteLine(sb.ToString());
}
Kombinovanje metoda Where() i Select()
458
static void Main(string[] args){
string[] imena = { "Aca", "Pera", "Mika", "Lazar", "Ivana", "Jovan", "Jovana", "Djordje" };
IEnumerable<string> upit = imena.Where(s => s.Length == 5).Select(s => s.ToUpper());
StringBuilder sb = new StringBuilder();
foreach (string clan in upit){
sb.AppendLine(clan);}
System.Console.WriteLine(sb.ToString());}
12/16/2018
230
Klasa Kategorija
459
namespace LambdaIzrazi.Models{
class Kategorija{
public int KategorijaId { get; set; }public string NazivKategorije { get; set; }public string OpisKategorije { get; set; }
}
}
Klasa Proizvod
namespace LambdaIzrazi.Models{
class Proizvod{
public int ProizvodId { get; set; }public int KategorijaId { get; set; }public string NazivProizvoda { get; set; }public decimal Cena { get; set; }public int KolicinaNaLageru { get; set; }
}}
460
12/16/2018
231
Metoda VratiKategorije(), statička klasa Podaci
using System.Collections.Generic;namespace LambdaIzrazi.Models{
static class Podaci{
public static List<Kategorija> VratiKategorije(){
List<Kategorija> listaKategorija = new List<Kategorija>() {new Kategorija{KategorijaId=1,NazivKategorije="Laptopovi", OpisKategorije="Laptopovi razlicitih proizvodjaca" },new Kategorija{KategorijaId=2,NazivKategorije="Stampaci", OpisKategorije="Stampaci razlicitih proizvodjaca" },new Kategorija{KategorijaId=3,NazivKategorije="Tableti", OpisKategorije="Tablet racunari razlicitih proizvodjaca" }
};return listaKategorija;
}
}}
461
Metoda VratiProizvode() statička klasa Podaci
public static List<Proizvod> VratiProizvode(){
List<Proizvod> listaProizvoda = new List<Proizvod>() {new Proizvod{ProizvodId=1, KategorijaId=1,NazivProizvoda="Laptop Dell Inspiron N4050",Cena=30999.25M,KolicinaNaLageru=39 },new Proizvod{ProizvodId=2, KategorijaId=1,NazivProizvoda="Laptop Asus X55U-SX009D",Cena=32990.12M,KolicinaNaLageru=17 },new Proizvod{ProizvodId=3, KategorijaId=1,NazivProizvoda="Acer Aspire laptop E5-521G-47DX",Cena=41989,KolicinaNaLageru=25 },
new Proizvod{ProizvodId=4, KategorijaId=2,NazivProizvoda="Stampač Laser A4 Lexmark E260",Cena=8549.1M,KolicinaNaLageru=13 },new Proizvod{ProizvodId=5, KategorijaId=2,NazivProizvoda="Canon laserski stampac LBP-6670DN",Cena=31989.1M,KolicinaNaLageru=18 },new Proizvod{ProizvodId=6, KategorijaId=2,NazivProizvoda="Canon stampač imageCLASS LBP6030W",Cena=13589.12M,KolicinaNaLageru=11 },
new Proizvod{ProizvodId=7, KategorijaId=3,NazivProizvoda="Acer tablet B1-730HD 8GB",Cena=11999.3M,KolicinaNaLageru=12 },new Proizvod{ProizvodId=8, KategorijaId=3,NazivProizvoda="Asus tablet MeMO Pad 7 ME70C-1A003A",Cena=12999.9M,KolicinaNaLageru=14 },new Proizvod{ProizvodId=9, KategorijaId=3,NazivProizvoda="Goclever tablet ORION 70 L KB",Cena=5699.45M,KolicinaNaLageru=25 }
};
return listaProizvoda;}
462
12/16/2018
232
Inicijalizacija izvora podataka (klasa Program)
463
using System;using System.Linq;using System.Collections.Generic;using System.Text;using LambdaIzrazi.Models;
namespace LambdaIzrazi{
class Program{
private static List<Kategorija> listaKategorija = Podaci.VratiKategorije();private static List<Proizvod> listaProizvoda = Podaci.VratiProizvode();
static void Main(string[] args){
}}
}
Proizvodi kojih na lageru ima više od 20
464
static void Main(string[] args){
IEnumerable<Proizvod> upit = listaProizvoda.Where(p => p.KolicinaNaLageru > 20);
StringBuilder sb = new StringBuilder();
foreach (Proizvod p1 in upit){
sb.AppendLine("Naziv: " + p1.NazivProizvoda);sb.AppendLine("Cena: " + p1.Cena);sb.AppendLine("Kolicina: " + p1.KolicinaNaLageru);sb.AppendLine("".PadRight(100, '.'));
}System.Console.WriteLine(sb.ToString());
}
12/16/2018
233
Ekstenziona metoda SingleOrDefault()klase Enumerable
465
public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate
)
Vraća jedinstveni element sekvence koji zadovoljava uslov.Vraća podrazumavanu vrednost za element u izvoru podatakaukoliko ne postoji element.
Metoda SingleOrDefault() upotreba
466
static void Main(string[] args){
Proizvod p1 = listaProizvoda.SingleOrDefault(p => p.ProizvodId == 1);
if (p1 != null){
System.Console.WriteLine(p1.NazivProizvoda);}else{
System.Console.WriteLine("Ne postoji proizvod");}
}
12/16/2018
234
Metoda FirstOrDefault()
467
public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate
)
Vraća prvi element sekvence koji zadovoljava uslov ili podrazumevanu vrednost ukoliko takav element ne postoji
Metoda FirstOrDefault upotreba
468
static void Main(string[] args){
Proizvod p1 = listaProizvoda.FirstOrDefault(p => p.KategorijaId == 1);if (p1 != null){
System.Console.WriteLine( p1.NazivProizvoda);}else{
System.Console.WriteLine("Ne postoji proizvod");}
}
12/16/2018
235
Metoda OrderBy
469
public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(this IEnumerable<TSource> source,Func<TSource, TKey> keySelector
)
Sortira elemente sekvence u rastućem poretku prema ključukeySelektor - anonimna funkcija koja izdvaja ključ iz svakog elementa sekvence
Sortiranje rezultata
470
static void Main(string[] args){
IEnumerable<Proizvod> sortiraniProizvodi = listaProizvoda.Where(p => p.KategorijaId == 1).OrderBy(p => p.Cena);
StringBuilder sb = new StringBuilder();foreach (Proizvod p in sortiraniProizvodi){
sb.AppendLine(p.NazivProizvoda + " " + p.Cena);}System.Console.WriteLine(sb.ToString());
}
12/16/2018
236
Sortiranje u opadajućem poretku
471
static void Main(string[] args){
IEnumerable<Proizvod> sortiraniProizvodi = listaProizvoda.Where(p => p.KategorijaId == 1).OrderByDescending(p => p.Cena);
StringBuilder sb = new StringBuilder();foreach (Proizvod p in sortiraniProizvodi){
sb.AppendLine(p.NazivProizvoda + " " + p.Cena);}System.Console.WriteLine(sb.ToString());
}
Višestruko sortiranje
472
static void Main(string[] args){
IEnumerable<Proizvod> upit = listaProizvoda.OrderBy(p => p.KategorijaId).ThenByDescending(p => p.Cena);
StringBuilder sb = new StringBuilder();foreach (Proizvod p in upit){
sb.AppendLine(p.KategorijaId + " " +p.NazivProizvoda + " " + p.Cena);}
System.Console.WriteLine(sb.ToString());}
12/16/2018
237
Metoda Distinct()
473
Vraća jedinstvene elemente sekvence korišćenjem podrazumevanog komparatora jednakosti.
static void Main(string[] args){
List<int> brojevi = new List<int> { 21, 46, 46, 55, 17, 21, 55, 55 };IEnumerable<int> razlicitiBrojevi = brojevi.Distinct();
StringBuilder sb = new StringBuilder();foreach (int b in razlicitiBrojevi){
sb.AppendLine(b.ToString());}System.Console.WriteLine(sb.ToString());
}
Metoda Count()
474
public static int Count<TSource>(this IEnumerable<TSource> source
)
public static int Count<TSource>(this IEnumerable<TSource> source,Func<TSource, bool> predicate
)
12/16/2018
238
Metoda Count()
475
static void Main(string[] args){
List<int> brojevi = new List<int>{ 5, 4, 1, 3, 9, 8, 6, 7, 1, 0 };int ukupno = brojevi.Count();int neparnih = brojevi.Count(b => b % 2 == 1);int parnih = brojevi.Count(b => b % 2 == 0);
StringBuilder sb = new StringBuilder();sb.AppendLine("Ukupno: " + ukupno.ToString());sb.AppendLine("Neparnih: " + neparnih.ToString());sb.AppendLine("Parnih: " + parnih.ToString());
System.Console.WriteLine(sb.ToString());}
Metoda Min()
476
public static int Min(this IEnumerable<int> source
)
public static decimal Min<TSource>(this IEnumerable<TSource> source,Func<TSource, decimal> selector
)
selector - transformaciona funkcija koja svaku vrednost sekvence pretvara u decimal
12/16/2018
239
Metoda Max()
477
public static int Max(this IEnumerable<int> source
)
public static decimal Max<TSource>(this IEnumerable<TSource> source,Func<TSource, decimal> selector
)
Primer Min()/Max()
478
static void Main(string[] args){
int[] brojevi = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 };StringBuilder sb = new StringBuilder();
int minBroj = brojevi.Min();sb.AppendLine(minBroj.ToString());
decimal najJeftiniji = listaProizvoda.Min(p => p.Cena);sb.AppendLine(najJeftiniji.ToString());
System.Console.WriteLine(sb.ToString());}
12/16/2018
240
Metoda Average()
479
static void Main(string[] args){
List<int> brojevi = new List<int> { 78, 92, 100, 37, 81 };
StringBuilder sb = new StringBuilder();
double prosek = brojevi.Average();sb.AppendLine(prosek.ToString());
decimal prosecnaCena = listaProizvoda.Average(p => p.Cena);sb.AppendLine(prosecnaCena.ToString());
System.Console.WriteLine(sb.ToString());}
Metoda Sum()
480
static void Main(string[] args){
StringBuilder sb = new StringBuilder();
List<int> brojevi = new List<int> { 78, 92, 100, 37, 81 };int suma = brojevi.Sum();sb.AppendLine(suma.ToString());
int ukupnoLaptopova = listaProizvoda.Where(p => p.KategorijaId == 1).Sum(p => p.KolicinaNaLageru);
sb.AppendLine(ukupnoLaptopova.ToString());
System.Console.WriteLine(sb.ToString());}
12/16/2018
241
Metoda Take()
Vraća specificirani broj uzastopnih elemenata od početka sekvence.
481
public static IEnumerable<TSource> Take<TSource>(this IEnumerable<TSource> source,int count
)
Metoda Take() - primer
482
static void Main(string[] args){
int[] poeni = { 59, 82, 70, 56, 92, 98, 85 };
IEnumerable<int> najbolja3 =poeni.OrderByDescending(p => p).Take(3);
StringBuilder sb = new StringBuilder();foreach (int p in najbolja3){
sb.AppendLine(p.ToString());}
System.Console.WriteLine(sb.ToString());}
12/16/2018
242
Metoda Skip()Preskače određeni broj elemenata sa početka sekvence.
483
static void Main(string[] args){
int[] poeni = { 59, 82, 70, 56, 92, 98, 85 };
IEnumerable<int> preskociPrvaTri =poeni.OrderByDescending(p => p).Skip(3);
StringBuilder sb = new StringBuilder();foreach (int p in preskociPrvaTri){
sb.AppendLine(p.ToString());}
System.Console.WriteLine(sb.ToString());}
Pitanje 1
Delegat je tip koji:a. pokazuje na metodub. pokazuje na klasuc. pokazuje na svojstvo
Odogovor: a
484
12/16/2018
243
Pitanje 2
Pomoću lambda izraza definiše se:a. anonimna metodab. sql upitc. metoda koja ima svoje ime
Odogovor: a
485
Pitanje 3
486
Za pisanje upita primenom lambda izraza koriste sea. Metode klase Linqb. Ekstenzione metode klase Enumerablec. Metode interfejsa IEnumerable
Odogovor: b
12/16/2018
244
Pitanje 4
487
Ako je sa TSource označen tip podataka u izvoru podataka. Ekstenzione metodestatičke klase Enumerable proširuju :a. Izvor podataka koji implementira IEnumerable<TSource> interfejsb. Izvor podataka koji implementira ISqlSource<TSource> interfejsc. Izvor podataka koji implementira IComparable<TSource> interfejs
Odogovor: a
Entity Framework Core
12/16/2018
245
.NET Core konzolna aplikacija
489
Microsoft.EntityFrameworkCore.SqlServer
Project->Manage Nuget Packages
490
12/16/2018
246
EF Core Power Tools
https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools
491
Solution Explorer
492
12/16/2018
247
Desni klik na projekat pa opcija Edit
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup><OutputType>Exe</OutputType><TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup><PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.4" />
</ItemGroup>
</Project>
493
Baza Magacin
494
12/16/2018
248
Entity Framework Core
• EF Core je međuplatformska verzija Entity Frameworka
• EF Core je objektno-relacioni maper (O/RM) koji omogućava .NET programerima da rade sa bazom korišćenjem .NET objekata.
495
Strategije dizajna modela
• Database-first design, najpre se dizajnira i kreira baza podataka a zatim se generišu entiteti aplikacije
• Model-first design, najpre se dizajniraju entiteti za aplikaciju a zatim se kreira baza podataka na osnovu tih entiteta
496
12/16/2018
249
Pokreni EF Core Power Tools
497
Odabir konekcije
498
12/16/2018
250
Odabir tabela i kreiranje modela
499
Entitetska klasa Kategorija
namespace ConsoleEfCore.Models{
[Table("Kategorija")]public partial class Kategorija{
public Kategorija(){
Proizvodi = new HashSet<Proizvod>();}
public int KategorijaId { get; set; }[Required][StringLength(50)]public string NazivKategorije { get; set; }[Required][StringLength(100)]public string OpisKategorije { get; set; }
[InverseProperty("Kategorija")]public ICollection<Proizvod> Proizvodi { get; set; }
}}
500
12/16/2018
251
Entitetska klasa Proizvod
namespace ConsoleEfCore.Models{[Table("Proizvod")]public partial class Proizvod{
public int ProizvodId { get; set; }public int KategorijaId { get; set; }[Required][StringLength(50)]public string NazivProizvoda { get; set; }[Column(TypeName = "decimal(12, 3)")]public decimal Cena { get; set; }public int KolicinaNaLageru { get; set; }
[ForeignKey("KategorijaId")][InverseProperty("Proizvodi")]public Kategorija Kategorija { get; set; }
}
501
DbContext klasa namespace ConsoleEfCore.Models{public partial class MagacinContext : DbContext{
public virtual DbSet<Kategorija> Kategorije { get; set; }public virtual DbSet<Proizvod> Proizvodi { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder){
if (!optionsBuilder.IsConfigured){
optionsBuilder.UseSqlServer("Data Source=.\\SqlExpress;Initial Catalog=Magacin;Integrated Security=True");}
}
}
502
12/16/2018
252
DbContext klasa
• DbContext klasa je most za interakciju entitetskih klasa i baze podataka
• DbSet <TEntity> predstavlja kolekciju entitetskih objekata koji odgovaraju redovima tabele u bazi podataka
• DbContext sadrži svojstva za pristup DbSet-ovima DbSet<TEntity> za sve entitetske klase koje su mapirane u tabele baze
• DbContext klasa:– upravlja konekcijom sa odgovarajućom bazom podataka
– prati promene u objektima unutar DbSet ova
– čuva promene iz DbSetova u bazi podataka
503
Potrebne biblioteke
using System;using System.Collections.Generic;using System.Linq;using ConsoleEfCore.Models;using Microsoft.EntityFrameworkCore;
504
12/16/2018
253
Čitanje podataka sa odloženim izvršavanjem upita
static void PrikaziProizvode(){
using (MagacinContext db = new MagacinContext()){
DbSet<Proizvod> listaProizvoda = db.Proizvodi;
foreach (Proizvod p in listaProizvoda){
Console.WriteLine(p.NazivProizvoda);}
}}
505
static void Main(string[] args){
PrikaziProizvode();Console.ReadLine();
}
Čitanje podataka uz materijalizaciju upita
506
static void PrikaziProizvode1(){
using (MagacinContext db = new MagacinContext()){
List<Proizvod> listaProizvoda = db.Proizvodi.ToList();
foreach (Proizvod p in listaProizvoda){
Console.WriteLine(p.NazivProizvoda);}
}}
static void Main(string[] args){
PrikaziProizvode1();Console.ReadLine();
}
12/16/2018
254
Filtriranje podatakastatic void Laptopovi(){
using (MagacinContext db = new MagacinContext()){
IQueryable<Proizvod> listaProizvoda = db.Proizvodi.Where(p => p.KategorijaId == 1);
foreach (Proizvod p in listaProizvoda){
Console.WriteLine(p.NazivProizvoda + " " + p.Cena);}
}}
507
Prikaz podataka iz povezane tabele – Include()
static void Laptopovi(){
using (MagacinContext db = new MagacinContext()){
IQueryable<Proizvod> listaProizvoda = db.Proizvodi.Where(p => p.KategorijaId == 1).Include(p=>p.Kategorija) ;
foreach (Proizvod p in listaProizvoda){
Console.WriteLine(p.NazivProizvoda + " " + p.Cena + " " + p.Kategorija.NazivKategorije);}
}}
508
12/16/2018
255
Čitanje jednog redastatic void NadjiProizvod1(){
using (MagacinContext db = new MagacinContext()){
Proizvod p1 = db.Proizvodi.SingleOrDefault(p => p.ProizvodId == 1);
Console.WriteLine(p1.NazivProizvoda + " " + p1.KolicinaNaLageru + " " + p1.Cena);}
}
509
Čitanje jednog reda-2
static void NadjiProizvod2(){
using (MagacinContext db = new MagacinContext()){
Proizvod p1 = db.Proizvodi.Find(1);Console.WriteLine(p1.NazivProizvoda + " " + p1.KolicinaNaLageru + " " + p1.Cena);
}}
510
12/16/2018
256
Primer pisanja upita
511
static void PrikaziKategorije(){
using (MagacinContext db = new MagacinContext()){
IQueryable<Kategorija> queryKategorije = db.Kategorije.OrderBy(k => k.NazivKategorije).Select(k => k);
foreach (Kategorija k in queryKategorije){
Console.WriteLine(k.KategorijaId + ": " + k.NazivKategorije);}
}}
static void PrikaziProizvode(int id){
using (MagacinContext db = new MagacinContext()){
IQueryable<Proizvod> queryProizvodi = db.Proizvodi.Where(p => p.KategorijaId == id).OrderBy(p => p.NazivProizvoda);
Console.WriteLine($"Proizvodi iz kategorije {id} su:");foreach (Proizvod p in queryProizvodi){
Console.WriteLine(p.NazivProizvoda);}
}}
Prikaz podataka
static void Main(string[] args){
PrikaziKategorije();Console.WriteLine("Unesite Id kategorije:");
int id = int.Parse(Console.ReadLine());
PrikaziProizvode(id);
Console.ReadLine();}
512
12/16/2018
257
Ažuriranje podataka korišćenjem EF
• DbContext objekat sadrži entity objekte koji predstavljaju podatke u odgovarajućoj bazi podataka
• Ukoliko želimo da modifikujemo podatke u bazi prvo se vrši promena sadržaja DbContext objekta a zatim se od njega traži da sačuva promene u bazi podataka
513
Atačovani i detačovani objektiDbContext
Attached Entity Detached Entity
Attached
Managed by DbContext
Tracked
Can be persisted
Detached
Managed by DbContext
Tracked
Can be persisted
514
12/16/2018
258
Unos podatakastatic int UbaciKategoriju(){
using (MagacinContext db = new MagacinContext()){
Kategorija k = new Kategorija();try{
k.NazivKategorije = "Mobilni telefoni";k.OpisKategorije = "Mobilni telefoni razlicitih proizvodjaca";db.Kategorije.Add(k);db.SaveChanges();return k.KategorijaId;
}catch (Exception xcp){
Console.WriteLine(xcp.Message);return -1;
}
}
}
515
Main() metoda
static void Main(string[] args){
int id = UbaciKategoriju();Console.WriteLine($"Ubacena kategorija ciji je Id: {id}");Console.ReadLine();
}
516
12/16/2018
259
Prikaz unetog redastatic void PrikaziUnetiRed(int id){
using (MagacinContext db = new MagacinContext()){
Kategorija k1 = db.Kategorije.Find(id);
if (k1 != null){
Console.WriteLine(k1.NazivKategorije + "\n" + k1.OpisKategorije);}else{
Console.WriteLine("Ne postoji kategorija");}
}
}
517
Ažuriranje redastatic int PromeniUnetiRed(int id){
using (MagacinContext db = new MagacinContext()){
Kategorija k1 = db.Kategorije.Find(id);if (k1 != null){
try{
k1.NazivKategorije = "Mobilni uredjaji";k1.OpisKategorije = "Mobilni uredjaji i smart telefoni";db.SaveChanges();return 0;
}catch (Exception xcp){
Console.WriteLine(xcp.Message);return -1;
}
}else{
return -2;}
}}
518
12/16/2018
260
Main() metoda
static void Main(string[] args){
int rezultat = PromeniUnetiRed(4);if (rezultat == 0){
Console.WriteLine("Podaci promenjeni");}else if (rezultat == -1){
Console.WriteLine("Greska pri promeni");}else{
Console.WriteLine("Ne postoji red za dati id");}Console.ReadLine();
}
519
Brisanje redastatic int ObrisiRed(int id){
using (MagacinContext db = new MagacinContext()){
Kategorija k1 = db.Kategorije.Find(id);if (k1 != null){
try{
db.Kategorije.Remove(k1);db.SaveChanges();return 0;
}catch (Exception xcp){
Console.WriteLine(xcp.Message);return -1;
}
}else{
return -2;}
}
}520
12/16/2018
261
Main() metoda
static void Main(string[] args){
int rezultat = ObrisiRed(4);if (rezultat == 0){
Console.WriteLine("Podaci obrisani");}else if (rezultat == -1){
Console.WriteLine("Greska pri brisanju");}else{
Console.WriteLine("Ne postoji red za dati id");}Console.ReadLine();
}
521
Pitanje 1
Kod Entity Frameworka Core tehnologije osnovna klasa koja se koristi kao bazna klasa za manipulaciju sa entitetskimobjektima naziva se:a. DbContext klasab. DataSet klasac. EntityContext klasa
Odogovor: a
522
12/16/2018
262
Pitanje 2
Ako je MagacinEntities klasa izvedena iz DbContext klase kreirana na osnovu postojeće baze podataka. Neka je db instanaca MagacinEntities klase. Klasa MagacinEntities ima svojstvo Kategorije pomoću koga se pristupa DbSet objektu tipa DbSet<Kategorija> koji se sastoji od objekata entitetske klase Kategorija.Kako se pronalazi atačovani objekat čiji id ima vrednost 1:a. Kategorija k1 = db.Kategorije.Find(k=>k.id=1);b. Kategorija k1 = db.Kategorije.Select(1);c. Kategorija k1 = db.Kategorije.Find(1);
Odogovor: c
523
Pitanje 3
Da bi se promene unutar tipiziranog DbContext objekta označenog sa db sačuvale u bazi podatakapišemo sledeću liniju koda:a. db.Save();b. db. SaveToDatabase();c. db.SaveChanges();
Odogovor: c
524
12/16/2018
263
ASP.NET Core
• ASP.NET Core je besplatan, open-source web framework
• ASP.NET Core je modularni framework i radi na Windows, Linux, ili Macoperativnom sistemu
• Inicijalni naziv je bio ASP.NET 5 ali mu je ime promenjeno u ASP.NET Core 1.0(Jun 2016)
• Verzija ASP.NET Core 2.1 (30.05.2018)
• Isporučuje se u vidu Nuget paketa
• Omogućava kreiranje web aplikacija i web API-ja
• Lako se integriše sa različitim klijentskim tehnologijama
• Koristi Model-View-Controller (MVC) pattern
525
MVC patern
Models
Modeli su skup klasa koje
opisuju podatke sa kojima
radimo.
Views
Pogledi su komponente
koje generišu korisnički
interfejs aplikacije
MVC patern uključuje sledeće komponente:
Controllers
Kontroleri su komponente koje
upravljaju korisničkim zahtevima,
rade sa modelom, i odabiraju pogled
kome prosleđuju podatke
526
12/16/2018
264
Kreiranje ASP.NET Core web aplikacije -1
527
Kreiranje ASP.NET Core web aplikacije -2
528
12/16/2018
265
Struktura ASP.NET Core web aplikacije
529
Fajl .csproj<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup><TargetFramework>netcoreapp2.1</TargetFramework>
</PropertyGroup>
<ItemGroup><PackageReference Include="Microsoft.AspNetCore.App" />
</ItemGroup>
</Project>
530
12/16/2018
266
Dependencies (zavisnosti)
• Dependencies u ASP.NET Core 2.1 projektu su sve instalirane serverske biblioteke i klijentske biblioteke
• Serverske biblioteke se instaliraju korišćenjem NuGet menadžera paketa
• Klijentske biblioteke se instaliraju korišćenjem alata LibMan (Library Manage)
• LibMan preuzima pakete klijentskih biblioteka sa content delivery network (CDN)• CDNJS : https://cdnjs.com/• unpkg : https://unpkg.com/#/
• Klijentske biblioteke se nalaze u folderu wwwroot/lib
531
Nuget menadžer paketa
532
12/16/2018
267
Libman menadžer klijentskih biblioteka
533
Fajl libman.json{"version": "1.0","defaultProvider": "cdnjs","libraries": [{"library": "[email protected]","destination": "wwwroot/lib/font-awesome/"
}]
}
534
12/16/2018
268
Folder Properties fajl launchSettings.json{"iisSettings": {"windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": {"applicationUrl": "http://localhost:64639","sslPort": 0
}},"profiles": {"IIS Express": {"commandName": "IISExpress","launchBrowser": true,"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"}
},"WebCoreUvod": {"commandName": "Project","launchBrowser": true,"applicationUrl": "http://localhost:5000","environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"}
}}
}
Desni klik na projekat-> Properties -> Debug tab
535
Folder wwwroot
• Unutar podfoldera foldera wwwroot čuvaju se statički fajlovi
• Unutar klase Startup potrebno je omogućiti pristup statičkim fajlovima (konfigurisati middleware)
• Svi fajlovi unutar foldera wwwroot su javno dostupni• http://<app>/images/<imageFileName>
• http://localhost:59450/images/banner1.svg
536
12/16/2018
269
Fajl Program.cs
public class Program{
public static void Main(string[] args){
CreateWebHostBuilder(args).Build().Run();}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();}
537
Fajl Program.cs
• ASP.NET Core web aplikacija je konzolna aplikacija koj počinje izvršavanja od metode Main() u klasi Program
• Unutar Main() metode se kreira host za aplikaciju
• Default konfiguracija koristi Kestrel web server, koristi IIS integraciju, čita konfiguraciona setovanja iz appsettings.json i radi druge konfiguracije
• Kestrel web server je podrazumevano uključen u ASP.NET Core
projekt šablone
538
12/16/2018
270
Kestrel web server
539
• Kestrel ne podržava deljenje iste IP adrese i porta izmešu više aplikacija• Ne može da hostuje više web sajtova na istoj IP adresi i portu
• Integracija sa IIS web serverom• Reversni proxy server (IIS) prima HTTP zahteve sa interneta i prosleđuje ih kestrelu vršeći
prethodno neku obradu• Scenario koji zahteva reverzni proxy je kada imamo više aplikacija koje dele istu IP adresu i port i
rade na istom serveru
IoC (Inversion of Control) princip dizajna koda
• IoC je princip gde se kontrola toka programa invertuje, umesto da korisnički kod kontroliše tok programa i poziva biblioteke, to radi eksterni framework
• DI (Dependency Injection) dizajn pattern implementira IoC princip
• DI dizaj patern omogućava kreiranje slabo uparenih klasa
• ASP.Core ima ugrađen Dependency Injection container
• DI kontejner ubacuje objekat klase servisa u zavisnu klasu posredstvom konstruktora zavisne klase
540
12/16/2018
271
Klasa Startup
• Izvršava se kada aplikacija startuje
• Klasa Startup ima dve javne metode ConfigureServices i Configure.
• Metoda ConfigureServices se koristi za registraciju klasa tzv. servisa u DI kontejneru
• Servisi su klase od kojih zavise neke druge klase ASP.NET Core web aplikacije
• ConfigureServices metoda kao ulazni parametar ima IServiceCollection interfejs koji omogućava registraciju servisa u DI kontejneru
• Nakon registracije servis se može koristiti bilo gde u aplikaciji
• U aplikaciji je samo potrebno da u konstruktoru zavisne klase kao parametar definišemo referencu tipa servisa i DI kontejner će je automatski ubaciti
541
Metoda ConfigureServices
public void ConfigureServices(IServiceCollection services){
services.Configure<CookiePolicyOptions>(options =>{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
Metoda AddMvc() dodaje MVC servis u kolekciju servisa aplikacije. Aplikacija koristi MVC framework.
542
12/16/2018
272
Middleware
• ASP.NET Core uvodi koncept koji se zove middleware
• Middleware je komponenta (klasa) koja se izvršva pri svakom zahtevu
• Middleware se sastoji od komponenti koje obrađuju zahtev putem protočne obrade
• Middleware se konfiguriše unutar Configure metode Startup klase
• Redosled kojim su komponente dodate u metodu Configure određuju redosled kojim se pozivaju pri obradi zahteva i obrnutom redosledu pri odgovoru. Ovaj redosled je bitan za sigurnost, perfomanse aplikacije i njenu funkcionalnost.
543
Protočna obrada zahteva
• Zahtev se prosleđuje od jedne do druge komponente
• Svaka komponenta može odlučiti da ne prosledi zahtev sledećoj komponenti što se zove kratko spojanje protočne obrade zahteva
• Kratko spajanje je često poželjno jer se izbegava nepotreban rad.
• Npr. komponenta za obradu statičkih fajlova može vratiti zahtev za statičkim fajlom i prespojiti ostatak protočne obrade.
544
12/16/2018
273
Metoda Configure()public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{if (env.IsDevelopment()){
app.UseDeveloperExceptionPage();}else{
app.UseExceptionHandler("/Home/Error");}
app.UseStaticFiles();app.UseCookiePolicy();
app.UseMvc(routes =>{
routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});} 545
Metoda Configure()
• Ova metoda specificira kako aplikacija odgovara na HTTP zahteve
• Unutar ove klase se vrši protočna obrada zahteva, postoji tzv. request pipeline
• Metoda Configure ima dva ulazna parametra IApplicationBuilder i IHostingEnvironment.
• IApplicationBuilder obezbeđuje mehanizam da se konfiguriše protočna obrada
• IHostingEnvironment obezbeđuje informacije o okruženju u kome se aplikacija hostuje
• Metoda ConfigureServices() se poziva pre Configure() metode
546
12/16/2018
274
Prvo pokretanje ASP.NET Core web aplikacije
547
Prvo pokretanje ASP.NET Core web aplikacije
548
12/16/2018
275
Pokretanje aplikacije korišćenjem IIS-a
549
Klasa HomeController.cs
public class HomeController : Controller{
public IActionResult Index(){
return View();}
public IActionResult About(){
ViewData["Message"] = "Your application description page.";
return View();}
}
550
12/16/2018
276
Index pogled klase HomeController
551
ViewData
• ViewData je rečnik koji sadrži key-value parove
• Ključevi su stringovi a vrednosti su tipa object
• Koristi se za prosleđivanje podataka iz kontrolera ka pogledu
• Kada se pristupa podacima iz pogleda moramo izvršiti neophodno kastovanje ukoliko ne čuvamo stringove
552
12/16/2018
277
Prosleđivanje podataka Index pogledu HomeController klase
public IActionResult Index(){
ViewData.Add("brojPonavljanja", 5);ViewData["Poruka"]= "Uvod u ASP.NET Core web aplikacije";return View();
}
Kada se unutar akcione metode ne napiše ime pogleda kome se prosleđuju podaci,već samo return View(); onda se podaci prosleđuju pogledu koji ima isto ime kao iakciona metoda.
553
Pogled Index.cshtml
554
@{
ViewData["Title"] = "Home Page";
}
<br />
<br />
<div class="row">
@for (int i = 0; i < (int) ViewData["brojPonavljanja"]; i++)
{
<span>Poruka: @ViewData["Poruka"]</span><br />
}
</div>
12/16/2018
278
Generisani html
555
ViewBag
• Koristi se za prenos podataka iz kontrolera ka pogledu
• ViewBag je dinamički objekat unutar koga se dinamički definišu svojstva
• ViewBag ne zahteva kastovanje pri iščitavanju vrednosti iz njega
• Svojstvo unutar ViewBaga ne sme da se poklopi sa ključem ViewData rečnika
556
12/16/2018
279
Definisanje dinamičkih svojstava
557
public IActionResult Index(){
//ViewData.Add("brojPonavljanja", 5);//ViewData["Poruka"]= "Uvod u ASP.NET Core web aplikacije";ViewBag.brojPonavljanja = 5;ViewBag.Poruka = "Uvod u ASP.NET Core web aplikacije";return View();
}
Pogled Index.cshtml
558
<div class="row">
@for (int i = 0; i < ViewBag.brojPonavljanja; i++)
{
<span>Poruka: @ViewBag.Poruka</span><br />
}
</div>
12/16/2018
280
Pitanje 1
559
Odgovor: a
Unutar Main metode klase Program kod ASP.NET Core web aplikacije kreira se:
a. host za web aplikaciju
b. model klasa web aplikacije
c. kontroler za web aplikaciju
Pitanje 2
560
Odgovor: c
Servisi u terminologiji ASP.NET Core web aplikacija su:
a. Klase ASP.NET Core web aplikacije koje zavise od drugih klasa
b. Klase izvedene iz klase Controller
c. Klase od kojih zavise druge klase ASP.NET Core web aplikacije
12/16/2018
281
Pitanje 3
561
Odgovor: a
Registracija servisa - dodavanje servisa u kolekciju servisa
aplikacije, vrši se unutar
a. Metode ConfigureServices klase Startup
b. Metode ConfigureServices klase Program
c. Metode Configure klase Startup
Pitanje 4
562
Odgovor: c
Middleware komponenta se konfiguriše unutar metode:
a. ConfigureServices klase Startup
b. Middleware klase Startup
c. Metode Configure klase Startup
12/16/2018
282
Pitanje 5
563
Odgovor: a
ASP.NET Core web aplikacija ima ugrađen Dependency Injection kontejner kojia. Ubacuje objekat klase servisa u zavisnu klasub. Ubacuje pogled u ASP.NET Core web aplikacijuc. Ubacuje kontroler u ASP.NET Core web aplikaciju
Pitanje 6
564
Odgovor: c
Statički fajlovi kod ASP.NET Core web aplikacija čuvaju se unutar podfoldera sledećeg foldera:
a. Models
b. Data
c. wwwroot
12/16/2018
283
MVC model
MVC Model
• Model predstavlja domen aplikacije
• Svrha modela je da da smisao podacima
• Model se može koristiti kao kontejner za podatke koji se prikazuju na web strani
• Najčešće se kao model podataka koristi entitetski model
566
12/16/2018
284
Kreiranje ASP.NET Core web aplikacije
567
Klasa kao model – folder Models
[Table("Osoba")]public class Osoba{
public int OsobaId { get; set; }public string Ime { get; set; }public string Prezime { get; set; }public string Adresa { get; set; }
}
568
using System.ComponentModel.DataAnnotations.Schema;
12/16/2018
285
Interfejs ISkladiste
namespace WebMvcModel.Models{
public interface ISkladiste{
IEnumerable<Osoba> Osobe { get; }}
}
569
Models folder
570
public class OsobaSkladiste : ISkladiste{
public IEnumerable<Osoba> Osobe{
get{
Osoba os1 = new Osoba { OsobaId = 1, Ime = "Pera", Prezime = "Peric", Adresa = "Prvomajska 4" };Osoba os2 = new Osoba { OsobaId = 2, Ime = "Mika", Prezime = "Mikic", Adresa = "Glavna 12" };Osoba os3 = new Osoba { OsobaId = 3, Ime = "Laza", Prezime = "Lazic", Adresa = "Marije Bursac 2" };List<Osoba> listaOsoba = new List<Osoba>{
os1,os2,os3
};return listaOsoba;
}}
}
12/16/2018
286
Klasa Startup metoda ConfigureServices
571
public void ConfigureServices(IServiceCollection services){
services.Configure<CookiePolicyOptions>(options =>{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddTransient<ISkladiste, OsobaSkladiste>();services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
Kada komponenta poput kontrolera ima potrebe za implementacijom ISkladiste interfejsa ona će dobiti instancu klase OsobaSkladiste. Tranzientni servis se instancira pri svakom zahtevu za implementacijom (posredstvom konstruktora zavisne klase).
Modifikovana klasa HomeController
572
public class HomeController : Controller{
private readonly ISkladiste skladiste;
public HomeController(ISkladiste _skladiste){
skladiste = _skladiste;}public IActionResult Index(){
ViewBag.Poruka = "Lista osoba";
return View(skladiste.Osobe);}
}
12/16/2018
287
Ubacivanje zavisnosti u kontroler
• Kada MVC treba da kreira novu instancu klase HomeController da bi obradio HTTP zahtev on gleda konstruktor i uviđa da on zahteva objekat koji imlementra interfejs ISkladiste
• Da bi odredio koju implentacionu klasu trebakoristi MVC konsultuje Startup klasu koja govori da treba da koristi klasu OsobaSkladiste i da se pri svakom zahtevu treba kreirati nova instanca ove klase.
• MVC kreira objekat klase OsobaSkladiste i prosleđuje ga konstruktoru kontrolera
• Proces DI omogućava kontroleru da pristupi skladištu podataka kroz interfejs bez potrebe da zna koja se implementaciona klasa za to koristi
573
Kreiranje Index pogleda bazirano na modelu
574
12/16/2018
288
Direktiva @model
@model IEnumerable<WebMvcModeli.Models.Osoba>
@{
ViewData["Title"] = "Index";
}
Direktiva @model omogućava da se podacima koje je kontroler prosledio pogledu korišćenjem svojstva Model. Podaci koje prosleđuje kontroler su tipizirani, u ovom slučaju objekti klase Osoba.
575
Index pogled -1<h2>Index</h2>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>
Id
</th>
<th>
Ime
</th>
<th>
Prezime
</th>
<th>
Adresa
</th>
</tr>
</thead>
576
12/16/2018
289
Index pogled -2<tbody>
@foreach (Osoba os in Model) {
<tr>
<td>
@os.OsobaId
</td>
<td>
@os.Ime
</td>
<td>
@os.Prezime
</td>
<td>
@os.Adresa
</td>
</tr>
}
</tbody>
</table>
577
Prikaz Index pogleda
578
12/16/2018
290
Mvc model- code first pristup
Fajl appsettings.json
{"Logging": {"LogLevel": {
"Default": "Warning"}
},"AllowedHosts": "*","ConnectionStrings": {"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=OsobaDb0912;Integrated Security=True"
}}
580
12/16/2018
291
Klasa OsobaContext
581
using Microsoft.EntityFrameworkCore;
public class OsobaContext : DbContext{
public DbSet<Osoba> Osobe { get; set; }public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}
}
Metoda AddDbContext<TContext> interfejsa IServiceCollection• Ova metoda omogućava da DbContext<TContext> objekat bude
raspoloživ za ubacivanje od strane DI kontejnera
• Omogućava da DbContextOptions<TContext> objekat bude raspoloživ za ubacivanje od strane DI kontejnera
582
12/16/2018
292
Registrujemo DbContext kao servis
583
public void ConfigureServices(IServiceCollection services){
services.Configure<CookiePolicyOptions>(options =>{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;});
services.AddTransient<ISkladiste, OsobaSkladiste>();
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
Metoda AddDbContext registruje OsobaContext klasu kao servis. Konfiguriše se kontekst da koristi Sql Server bazu podataka. Instanca klase OsobaContext se ubacuje posredstvom DI kontejnera.
using Microsoft.EntityFrameworkCore;
Klasa OsobaContext
public class OsobaContext : DbContext{
public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}
public DbSet<Osoba> Osobe { get; set; }}
584
using Microsoft.EntityFrameworkCore;
Konstruktor DbContext klase mora imati kao parametar instancu klase DbContextOptions da bi se kreirao objekat DbContext. Ovu instancu ubacuje DI kontejner. Objekat DbContextOptions sadrži opcije za kreiranje DbContext objekta.
12/16/2018
293
Klasa OsobaSkladisteDb
585
namespace WebMvcModel.Models{
public class OsobaSkladisteDb : ISkladiste{
private readonly OsobaContext db;public OsobaSkladisteDb(OsobaContext _db){
db = _db;}
public IEnumerable<Osoba> Osobe => db.Osobe;}
}
Promena implementacione klase servisa
services.AddTransient<ISkladiste, OsobaSkladisteDb>();
586
12/16/2018
294
Code first migracije
• Omogućavaju kreiranje baze podataka na osnovu postojećih entitetskih klasa i DbContext klase
• Omogućavaju promenu baze podataka kada se promeni neka od entitetskih klasa i context klasa
• Komanda Add-Migrations Prva unutar alata Package Manager Console služi da se kreira nova migracija unutar klase Prva
• Nakon dodavanje migracije kreira se folder Migrationsunutar ASP.NET Core MVC web aplikacije
587
Dodavanje migracije
588
PM> Add-Migration Prva
12/16/2018
295
Klasa Prva.cs
589
public partial class Prva : Migration{
protected override void Up(MigrationBuilder migrationBuilder){
migrationBuilder.CreateTable(name: "Osoba",columns: table => new{
OsobaId = table.Column<int>(nullable: false).Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
Ime = table.Column<string>(nullable: true),Prezime = table.Column<string>(nullable: true),Adresa = table.Column<string>(nullable: true)
},constraints: table =>{
table.PrimaryKey("PK_Osoba", x => x.OsobaId);});
}
protected override void Down(MigrationBuilder migrationBuilder){
migrationBuilder.DropTable(name: "Osoba");
}}
Kreiranje baze na osnovu modela
590
PM> Update-Database Primena migracije na bazu
12/16/2018
296
Generisana baza podataka server (localdb)\MSSQLLocalDb
591
Index strana prikazuje podatake iz baze
592
12/16/2018
297
OsobaController
593
OsobaController
594
12/16/2018
298
Generisani pogledi
595
Index pogled klase OsobaController
596
12/16/2018
299
Unos podataka, poziv Create akcione metode
597
Model klasa sa anotacijama polja
[Table("Osoba")]public class Osoba{
public int OsobaId { get; set; }
[Required(ErrorMessage = "Morate uneti ime")][StringLength(30, ErrorMessage = "Ime je duzine do 30 karaktera")]public string Ime { get; set; }
[Required(ErrorMessage = "Morate uneti prezime")][StringLength(30, ErrorMessage = "Prezime je duzine do 30 karaktera")]public string Prezime { get; set; }
[Required(ErrorMessage = "Morate uneti adresu")][StringLength(60, ErrorMessage = "Adresa je duzine do 60 karaktera")]public string Adresa { get; set; }
}598
using System.ComponentModel.DataAnnotations;
12/16/2018
300
Dodavanje nove migracije
599
PM> Add-Migration Druga
Metoda Up() migracije
600
protected override void Up(MigrationBuilder migrationBuilder){
migrationBuilder.AlterColumn<string>(name: "Prezime",table: "Osoba",maxLength: 30,nullable: false,oldClrType: typeof(string),oldNullable: true);
migrationBuilder.AlterColumn<string>(name: "Ime",table: "Osoba",maxLength: 30,nullable: false,oldClrType: typeof(string),oldNullable: true);
migrationBuilder.AlterColumn<string>(name: "Adresa",table: "Osoba",maxLength: 60,nullable: false,oldClrType: typeof(string),oldNullable: true);
}
12/16/2018
301
Primena druge migracijePM> Update-Database
601
Validacija podataka
602
12/16/2018
302
Unos podataka
603
Mvc model- database first pristup
12/16/2018
303
Sql Server Object explored
605
Tabela u bazi OsobaDb0912ver1
CREATE TABLE Osoba(OsobaId int IDENTITY(1,1) PRIMARY KEY NOT NULL,Ime nvarchar(50) NOT NULL,Prezime nvarchar(50) NOT NULL,Adresa nvarchar(60) NOT NULL,DatumRodjenja date NOT NULL,Telefon varchar(20) NOT NULL)
606
12/16/2018
304
EF Core Power Tools -1
607
EF Core Power Tools -2
608
12/16/2018
305
Generisana entitetska klasanamespace WebMvcModel2.Models{
[Table("Osoba")]public partial class Osoba{
public int OsobaId { get; set; }
[Required][StringLength(50)]public string Ime { get; set; }
[Required][StringLength(50)]public string Prezime { get; set; }
[Required][StringLength(60)]public string Adresa { get; set; }
[Column(TypeName = "date")]public DateTime DatumRodjenja { get; set; }
[Required][StringLength(20)]public string Telefon { get; set; }
}}
609
Generisana DbContext klasa
namespace WebMvcModel2.Models{
public partial class OsobaContext : DbContext{
public OsobaContext(DbContextOptions<OsobaContext> options): base(options)
{}
public virtual DbSet<Osoba> Osobe { get; set; } }
}
610
12/16/2018
306
Modifikovani appsettings.json
611
{"Logging": {"LogLevel": {"Default": "Warning"
}},"AllowedHosts": "*","ConnectionStrings": {"DefaultConnection": "Data Source=(localdb)\\MSSQLLocalDB;Initial
Catalog=OsobaDb0912ver1;Integrated Security=True"}
}
Metoda ConfigureServices() klase Startup
612
public void ConfigureServices(IServiceCollection services){
services.Configure<CookiePolicyOptions>(options =>{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.options.CheckConsentNeeded = context => true;options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
using WebMvcModel2.Models;using Microsoft.EntityFrameworkCore;
12/16/2018
307
Format datuma i brojeva na serveru
613
public string Test1(){
DateTime dt = DateTime.Now;return dt.ToString("d");
}
public string Test2(){
decimal a = 12.342m;return a.ToString();
}
Metoda Configure() klase Startup
CultureInfo ci = new CultureInfo("sr-Latn-RS");ci.DateTimeFormat.DateSeparator = "/";ci.DateTimeFormat.ShortDatePattern = "d/M/yyyy";ci.NumberFormat.NumberDecimalSeparator = ".";
List<CultureInfo> podrzaneKulture = new List<CultureInfo> {ci};
RequestLocalizationOptions opcije = new RequestLocalizationOptions{
SupportedCultures = podrzaneKulture,DefaultRequestCulture = new RequestCulture(ci)
};
app.UseRequestLocalization(opcije);
614
12/16/2018
308
Promenjen format datuma i brojeva
615
Kreiranje OsobaController klase
616
12/16/2018
309
Modifikacija pogleda Create i Edit
617
<div class="form-group"><label asp-for="DatumRodjenja" class="control-label"></label><input type="text" asp-for="DatumRodjenja" class="form-control" /><span asp-validation-for="DatumRodjenja" class="text-danger"></span>
</div>
Validacija podataka
618
12/16/2018
310
Modifikovana model klasa
619
[Table("Osoba")]public partial class Osoba{
public int OsobaId { get; set; }
[Required(ErrorMessage ="Unesite ime")][StringLength(50,ErrorMessage ="Maksimalno 50 karaktera")]public string Ime { get; set; }
[Required(ErrorMessage = "Unesite prezime")][StringLength(50, ErrorMessage = "Maksimalno 50 karaktera")]public string Prezime { get; set; }
[Required(ErrorMessage ="Unesite adresu")][StringLength(60, ErrorMessage = "Maksimalno 60 karaktera")]public string Adresa { get; set; }
[Required(ErrorMessage ="Unesite datum rodjenja")][Display(Name ="Datum rodjenja")][DisplayFormat(DataFormatString ="{0:d.M.yyyy}",ApplyFormatInEditMode =true)]public DateTime DatumRodjenja { get; set; }
[Required(ErrorMessage ="Unesite telefon")][StringLength(20,ErrorMessage ="Maksimalno 20 karaktera")]public string Telefon { get; set; }
}
Prikaz validacionih gresaka
620
12/16/2018
311
Kreiranje MVC kontrolera
Kreiranje ASP.NET Core Web aplikacije
622
12/16/2018
312
Pojam kontrolera
• Kontroler je C# klasa čije su javne metode odgovorne za obradu HTTP zahteva kod ASP.NET Core MVC web aplikacija
• Ime kontrolerske klase se završava sa Controller
• Kontroler je klasa koja je obično izvedena iz bazne klase Controller
• Metoda kontrolera koja obrađuje HTTP zahtev naziva se akciona metoda ili akcija
• Svaki kontroler sadrži jednu ili više akcionih metoda
• Akciona metoda kontrolera mora biti javna, ne može biti statička, i ne može se overloadovati
• Akciona metoda može vratiti objekat bilo kog tipa
• Uobičajeno je da akciona metoda vraća objekat koji implementira IActionResult interfejs
• Akcija kontrolera prosleđuje podatke odgovarajućem pogledu
623
Rutiranje
• Rute opisuju kako se URL adrese zahteva mapiraju u akcije kontrolera
• Rute se definišu unutar middleware komponente za rutiranje
• Unutar Configure metode poziva se metoda UseMvc koja se koristi da se definišu rute
• Metoda MapRoute se koristi za kreiranje default rute
• Ako želimo da pozovemo Details akcionu metodu OsobaController klase i da toj metodi prosledimo id parametar vrednosti 3 potrebno je uneti sledeću adresu u browseru: http://<app>/osoba/details/3
624
public void Configure(IApplicationBuilder app, IHostingEnvironment env){
....app.UseMvc(routes =>{
routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});}
12/16/2018
313
HomeController
public class HomeController : Controller{
public IActionResult Index(){
return View();}
public IActionResult About(){
ViewData["Message"] = "Your application description page.";
return View();}
public IActionResult Contact(){
ViewData["Message"] = "Your contact page.";
return View();}
}625
Interfejs IActionResult
• Ovim interfejsom definiše se ugovor koji predstavlja rezultat izvršavanja akcione metode
• Obično akcione metode vraćaju objekat koji implementira IActionResult interfejs
• Metoda View() bazne klase Controller vraća instancu klase ViewResult
• Metoda Json() vraća objekat klase JsonResult i koristi se kada akciona metoda treba da generiše json string
626
12/16/2018
314
Model klasa Osoba i DbContext klasa OsobaContext
public class OsobaContext : DbContext{
public DbSet<Osoba> Osobe { get; set; }} 627
[Table("Osoba")]public class Osoba{
public int OsobaId { get; set; }
[Required][StringLength(30)]public string Ime { get; set; }
[Required][StringLength(30)]public string Prezime { get; set; }
[Required][StringLength(100)]public string Adresa { get; set; }
}
Definisanje konekcionog stringa u appsettings.json fajlu
{"Logging": {
"LogLevel": {"Default": "Warning"
}},"AllowedHosts": "*","ConnectionStrings": {"DefaultConnection": "Data Source=.\\SqlExpress;Initial Catalog=OsobaDb1512ver1;Integrated Security=true"
}
}
628
12/16/2018
315
Registrujemo DbContext kao servis
629
public void ConfigureServices(IServiceCollection services){
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
Promenimo DbContext klasu
namespace WebMvcKontroler.Models{
public class OsobaContext : DbContext{
public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}public DbSet<Osoba> Osobe { get; set; }
}}
using Microsoft.EntityFrameworkCore;
630
12/16/2018
316
Kreiranje baze podataka primenom migracija
PM> Add-Migration Prva
PM> Update-Database
631
Kreirana baza podataka
632
12/16/2018
317
Kreiranje kontrolera
633
Klasa OsobaController
public class OsobaController : Controller{
private readonly OsobaContext _context;
public OsobaController(OsobaContext context){
_context = context;}
}
634
12/16/2018
318
Akcija Index asinhrona verzija
using System.Threading.Tasks;using Microsoft.AspNetCore.Mvc;
using WebMvcKontroler.Models;using Microsoft.EntityFrameworkCore;
635
public async Task<IActionResult> Index(){
return View(await _context.Osobe.ToListAsync());}
Poziv Index akcije kontrolera Osoba
636
12/16/2018
319
Akciona metoda Details// GET: Osoba/Details/5public async Task<IActionResult> Details(int? id){
if (id == null){
return NotFound();}
var osoba = await _context.Osobe.FirstOrDefaultAsync(m => m.OsobaId == id);
if (osoba == null){
return NotFound();}
return View(osoba);}
637
Poziv Details akcije kontrolera Osoba
638
12/16/2018
320
Dodavanje middleware komponente za obradu odgovara sa kodnim statusom od 400 do 599
639
public void Configure(IApplicationBuilder app, IHostingEnvironment env){
app.UseStatusCodePages();app.UseStaticFiles();app.UseCookiePolicy();
app.UseMvc(routes =>{
routes.MapRoute(name: "default",template: "{controller=Home}/{action=Index}/{id?}");
});}
Loš poziv Details akcione metode
640
12/16/2018
321
GET i POST akciona metoda Create
// GET: Osoba/Createpublic IActionResult Create(){
return View();}
[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Create([Bind("OsobaId,Ime,Prezime,Adresa")] Osoba osoba){
if (ModelState.IsValid){
_context.Add(osoba);await _context.SaveChangesAsync();return RedirectToAction(nameof(Index));
}return View(osoba);
}
641
Model binding
• Model binding je process kreiranja .NET objekata korišćenjem podataka iz HTTP zahteva
• Kreirani objekti se prosleđuju akcionim metodama kontrolera
• Model binder je komponenta MVC aplikacije koja obezbeđuje podatke za akcione metode iz različitih delova HTTP zahteva
• Model binder koristi tri izvora podataka da bi mapirao HTTP zahteve u podatke neophodne akcionim metodama• vrednosti polja forme
• vrednosti parametara iz rute
• vrednosti parametara iz query stringova
642
12/16/2018
322
Svojstva i atributske klase koje koristi metoda Create• ValidateAntiForgeryToken predstavlja atributsku klasu koja sprečava
falsifikovanje zahteva
• ModelState je property kontrolera i sadrži kolekciju (name,value) parova koju su prosleđeni u POST zahtevu do servera, takođe sadrži i kolekciju grešaka za svaku vrednost koja je poslate do servera
• ModelState.IsValid ukazuje da su greške u modelu dodate u ModelState
• Pomoću atributske klase Bind se specificiraraju polja forme koja se koriste u kreiranju .NET objekata od strane model bindera
• Metoda RedirectToAction poziva akciju kontrolera koja se specificira kao string parameter metode
• Ključna reč nameof se koristi da se dobije ime promenljive, tipa ili metode
643
Poziv akcione metode Create kontrolera Osoba
644
12/16/2018
323
Edit GET metoda
public async Task<IActionResult> Edit(int? id){
if (id == null){
return NotFound();}
var osoba = await _context.Osobe.FindAsync(id);if (osoba == null){
return NotFound();}return View(osoba);
}
645
Edit POST metoda
646
private bool OsobaExists(int id){
return _context.Osobe.Any(e => e.OsobaId == id);}
[HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Edit(int id, [Bind("OsobaId,Ime,Prezime,Adresa")] Osoba osoba){
if (id != osoba.OsobaId){
return NotFound();}
if (ModelState.IsValid){
try{
_context.Update(osoba);await _context.SaveChangesAsync();
}catch (DbUpdateConcurrencyException){
if (!OsobaExists(osoba.OsobaId)){
return NotFound();}else{
throw;}
}return RedirectToAction(nameof(Index));
}return View(osoba);
}
12/16/2018
324
Poziv GET metode kontrolera Osoba
647
Delete GET metoda
public async Task<IActionResult> Delete(int? id){
if (id == null){
return NotFound();}
var osoba = await _context.Osobe.FirstOrDefaultAsync(m => m.OsobaId == id);
if (osoba == null){
return NotFound();}
return View(osoba);}
648
12/16/2018
325
Delete Post metoda
[HttpPost, ActionName("Delete")][ValidateAntiForgeryToken]public async Task<IActionResult> DeleteConfirmed(int id){
var osoba = await _context.Osobe.FindAsync(id);_context.Osobe.Remove(osoba);await _context.SaveChangesAsync();return RedirectToAction(nameof(Index));
}
ActionName klasa ukazuje da se radi o akciji Delete
649
Poziv akcije Delete kontrolera Osoba
650
12/16/2018
326
Pitanje 1
MVC web aplikacija se izvršava na adresi http://localhost/. Ako želimo da pozovemo Details akcionu metodu OsobaController klase i da toj metodi prosledimo vrednost 3 kao ulazni parametar ove metode, potrebno je uneti sledeću adresu u browseru:a. http://localhost/Osoba/Details/3b. http://localhost/OsobaController/details/3c. http://localhost/Osoba/details/?=3
Odgovor: a
651
Pitanje 2
Komponenta ASP.NET MVC web aplikacije koja je odgovorna za obradu zahteva naziva se:a. modelb. pogledc. kontroler
Odgovor: c
652
12/16/2018
327
Pitanje 3
Zaokruži netačno tvrđenje. Kontrolerska klasa:a. Ima ime koje se završava sa rečju Controllerb. Može biti izvedena iz klase Controllerc. Mora biti opisana atributskom klasom [Authorize]
Odgovor: c
653
Pitanje 4
Interfejs pomoću koga se specificira povratni tip akcione metode kontrolera je :a. IDbContextb. IActionResultc. IJson
Odgovor: b
654
12/16/2018
328
Pitanje 5
Ako akciona metoda kontrolera nije opisana atributskom klasom onda se ona može pozvati:a. GET zahtevb. POST zahtevc. I GET i POST zahtevom
Odgovor: c
655
Kreiranje MVC pogleda
12/16/2018
329
MVC pogled
• Kontroler prosleđuje podatke pogledu korišćenjem View metode
• Pogledi pridruženi kontroleru pod nazivom HomeController nalaze se u folderu Views/Home
• Ukoliko želimo da isti pogled pridružimo za dva ili više kontrolera stavljamo ga u folder Views/Shared
657
ASP.NET Core Web aplikacija
658
12/16/2018
330
Fajl _ViewImports.cshtml
659
@using WebMvcPogledi
@using WebMvcPogledi.Models
@addTagHelper *,
Microsoft.AspNetCore.Mvc.TagHelpers
Direktive koje se dele između različitih pogleda smeštaju se unutar fajla _ViewImports.cshtml
Pogled _Layout.cshtml
660
12/16/2018
331
_Layout.cshtml – head deo
661
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>@ViewData["Title"] - WebMvcPogledi</title>
<environment include="Development">
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
<link rel="stylesheet" href="~/css/site.css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/css/bootstrap.min.css"
asp-fallback-href="~/lib/bootstrap/dist/css/bootstrap.min.css"
asp-fallback-test-class="sr-only" asp-fallback-test-property="position" asp-fallback-test-
value="absolute" />
<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />
</environment>
</head>
_Layout.cshtml – body deo 1
662
<nav class="navbar navbar-inverse navbar-fixed-top"><div class="container">
<div class="navbar-header"><button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="sr-only">Toggle navigation</span><span class="icon-bar"></span><span class="icon-bar"></span><span class="icon-bar"></span>
</button><a asp-area="" asp-controller="Home" asp-action="Index" class="navbar-brand">WebMvcPogledi</a>
</div><div class="navbar-collapse collapse">
<ul class="nav navbar-nav"><li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li><li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li><li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul></div>
</div></nav>
12/16/2018
332
_Layout.cshtml – body deo 2
• Može biti samo jedna @RenderBody() metoda po layout strani
• Pomoću RenderBody() metode specificira se deo layout strane koji će biti popunjen sadržajem strane koja implementira layout stranu
663
<div class="container body-content">
@RenderBody()
<hr />
<footer>
<p>© 2018 - WebMvcPogledi</p>
</footer>
</div>
_Layout.cshtml – body deo 3• Metoda RenderSection() služi za definisanje sekcije na strani koja implementira layout
stranu
• Sekciju moramo definisati na strani koja impleentira layout osim ako ne napišemo required: false
664
<environment include="Development">
<script src="~/lib/jquery/dist/jquery.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script></environment>
<environment exclude="Development">
<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.2.0.min.js"
asp-fallback-src="~/lib/jquery/dist/jquery.min.js"
asp-fallback-test="window.jQuery"
crossorigin="anonymous"integrity="sha384-K+ctZQ+LL8q6tP7I94W+qzQsfRV2a+AfHIi9k8z8l9ggpc8X+Ytst4yBo/hH+8Fk">
</script>
<script src="https://ajax.aspnetcdn.com/ajax/bootstrap/3.3.7/bootstrap.min.js"
asp-fallback-src="~/lib/bootstrap/dist/js/bootstrap.min.js"
asp-fallback-test="window.jQuery && window.jQuery.fn && window.jQuery.fn.modal"
crossorigin="anonymous"integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa">
</script>
<script src="~/js/site.min.js" asp-append-version="true"></script>
</environment>
@RenderSection("Scripts", required: false)
12/16/2018
333
Model klasa[Table("Osoba")]public class Osoba{
public int OsobaId { get; set; }
[Display(Name = "Ime osobe")][Required(ErrorMessage = "Morate uneti ime")][StringLength(30, ErrorMessage ="Maksimalno 30 karaktera")]public string Ime { get; set; }
[Required(ErrorMessage = "Morate uneti prezime")][Display(Name = "Prezime osobe")][StringLength(30, ErrorMessage = "Maksimalno 30 karaktera")]public string Prezime { get; set; }
[Required(ErrorMessage = "Morate uneti adresu")][DataType(DataType.MultilineText)][StringLength(100, ErrorMessage = "Maksimalno 100 karaktera")]public string Adresa { get; set; }
}665
Fajl appsettings.json
666
{"Logging": {"IncludeScopes": false,"LogLevel": {"Default": "Warning"
}},"ConnectionStrings": {"DefaultConnection":
"Server=(local)\\SqlExpress;Database=OsobaDb1112;Trusted_Connection=True"}
}
12/16/2018
334
DbContext klasa
namespace WebMvcPogledi.Models{
public class OsobaContext : DbContext{
public virtual DbSet<Osoba> Osobe { get; set; }}
}
667
Registrujemo DbContext kao servis
668
public void ConfigureServices(IServiceCollection services){
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
12/16/2018
335
Izmenjena DbContext klasa
namespace WebMvcKontroler.Models{
public class OsobaContext : DbContext{
public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}public DbSet<Osoba> Osobe { get; set; }
}}
using Microsoft.EntityFrameworkCore;
669
Kreiranje kontrolera bez pogleda
670
12/16/2018
336
Kreiranje Index pogleda
671
Index.cshtml - 1.deo
672
@model IEnumerable<WebMvcPogledi.Models.Osoba>
@{
ViewData["Title"] = "Index";
}
<h2>Index</h2>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Ime)
</th>
<th>
@Html.DisplayNameFor(model => model.Prezime)
</th>
<th>
@Html.DisplayNameFor(model => model.Adresa)
</th>
<th></th>
</tr>
</thead>
<tbody>
12/16/2018
337
Index.cshtml - 2.deo
673
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Ime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Prezime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Adresa)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.OsobaId">Edit</a> |
<a asp-action="Details" asp-route-id="@item.OsobaId">Details</a> |
<a asp-action="Delete" asp-route-id="@item.OsobaId">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Anchor Tag helper
• Tag helper omogućava korišćenje serverskog koda u kreiranju i renderovanju HTML elemenata u Razor fajlovima
• Većina ugrađenih tag helpera se odnosi na postojeće HTML elemente i obezbeđuju serverske atribute za element
• Možemo kreirati i sopstvene tag helpere
• Anchor tag helper dodaje nove atribute elementu <a>...</a>• asp-controller specificira kontroler koji se koristi za generisanje URL adrese
• ako se ne specificira kontroler, onda se zove podrazumevani kontroler koji poziva pogled
• asp-action specificira metodu kontrolera koja se koristi za generisanjeURL adrese
• asp-route- bilo koju vrednost koji prosledimo nakon crtcie tretira se kao parametar rute
• asp-route-id
674
12/16/2018
338
HtmlHelper klasa metoda DisplayNameFor()
• Klasa HtmlHelper koristi se za renderovanje html kontrola u pogledu
• Html property pogleda služi da pristupimo instanci klase HtmlHelper
• Metoda DisplayNameFor() prikazuje ime svojstva odgovarajućeg člana model klase
• Prikazani tekst zavisi od modela, tj. da li se koristi anotacija [Display(Name="")] prilikom definisanja polja klase
675
<th>
@Html.DisplayNameFor(model => model.Ime)
</th>
<th>Ime osobe
</th>
Metoda DisplayFor() HtmlHelper klase
<td>@Html.DisplayFor(modelItem => modelItem.Adresa)
</td>
<td>Prvomajska 4
</td>
676
• Prikazuje vrednost određenog svojstva objekta model klase
• Ako je definisan [DisplayFormat] u zavisnosti od toga će biti prikazan npr. kratki format datuma
12/16/2018
339
Modifikovani Index pogled
677
@model IEnumerable<Osoba>
@{
ViewData["Title"] = "Index";}
<h2>Index</h2>
<p>
<a asp-action="Create">Nova osoba</a>
</p><table class="table">
<thead>
<tr>
<th>
Ime
</th><th>
Prezime
</th>
<th>
Adresa
</th><th></th>
</tr>
</thead>
<tbody>
@foreach (Osoba os in Model) {
<tr>
<td>
@os.Ime</td>
<td>
@os.Prezime
</td>
<td>
@os.Adresa</td>
<td>
<a asp-action="Edit" asp-route-id="@os.OsobaId">Promeni</a> |
<a asp-action="Details" asp-route-id="@os.OsobaId">Detalji</a> |
<a asp-action="Delete" asp-route-id="@os.OsobaId">Obrisi</a>
</td></tr>
}
</tbody>
</table>
</table>
Kreiranje pogleda Create
678
12/16/2018
340
Deo pogleda Create.cshtml
<div class="row">
<div class="col-md-4">
<form asp-action="Create">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-group">
<label asp-for="Ime" class="control-label"></label>
<input asp-for="Ime" class="form-control" />
<span asp-validation-for="Ime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Prezime" class="control-label"></label>
<input asp-for="Prezime" class="form-control" />
<span asp-validation-for="Prezime" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Adresa" class="control-label"></label>
<input asp-for="Adresa" class="form-control" />
<span asp-validation-for="Adresa" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</form>
</div>
</div>679
@model Osoba
Form tag helper
• Generiše action atribut forme na osnovu naziva kontrolera i akcione metode
• Generiše skriveni Request Verification Token da bi se sprečilo falsifikovanje zahteva
• POST metoda kontrolera proverava postojanje ovog tokena [ValidateAntiForgeryToken]
• asp-controller tag specificira kontroler koji se koristi za generisanje URL adrese
• Ako se ne specificira kontroler, onda se zove podrazumevani kontroler koji poziva pogled
• asp-action tag specificira metodu kontrolera koja se koristi za generisanjeURL adrese
680
<form asp-action="Create">
</form>
12/16/2018
341
Generisani html od strane form tag helpera
681
<form action="/osoba/Create" method="post"> <input name="__RequestVerificationToken" type="hidden"
value="CfDJ8BghgRQh7g5Hn2qw6LLgaeE33OG55fDf4WlUmdAbXvKCZ2HUKWELB9tO69x1_5bpdENgHALvyLWOEMvgAZDNwTdFrD5JKNbrXLzYTvXLSPfbpTeSiOXCSM90_h9yVtasiNUnG7QRP-B5y-MT_-XW-pw" /></form>
Label Tag Helper
• Generiše <label> element za svojstvo modela• Tag asp-for specificira svojstvo modela• Generiše vrednost za for atribut
682
<label asp-for="Ime" class="control-label"></label>
<label class="control-label" for="Ime">Ime osobe</label>
Generisani HTML:
12/16/2018
342
Input Tag Helper
• Binduje HTML <input> element za polje modela u razor pogledu
• Setuje atribut type generisanog input elementa u zavisnoti od tipa polja modela
• Generisani type atribut može se prebrisati ako ga ponovo definišemo za input element
• Generiše validacione atribute data-val- iz anotacionih atributa za polja klasa modela• data-val• data-val-required• data-val-length-max
....
683<input asp-for="Ime" class="form-control" />
Generisani html od strane input tag helpera
684
<input class="form-control" type="text" data-val="true" data-val-length="Maksimalno 30 karaktera"
data-val-length-max="30" data-val-required="Morate uneti ime" id="Ime" name="Ime" value="" />
Atributi za validaciju su definisani unutar bilioteke jquery.validate.unobtrusive.js<script src="/lib/jquery-validation/dist/jquery.validate.js"></script><script src="/lib/jquery-validation-unobtrusive/jquery.validate.unobtrusive.js"></script>
@section Scripts {
@{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
}
Ubacivanje validacionih biblioteka u Razor pogled:
12/16/2018
343
Validation Message Tag Helper
• Dodaje data-valmsg-for="svojstvo" atribut u span element
• Ovaj atribut prikazuje validacionu grešku unutar span elementa za određeno svojstvo
• Prikazana greška je rezultat klijentske validacije
• Validacija se takođe izvršava i na serveru
685
<span asp-validation-for="Ime" class="text-danger"></span>
<span class="text-danger field-validation-valid" data-valmsg-for="Ime" data-valmsg-replace="true"></span>
Validation Summary Tag Helper
• Dodaje atribut asp-validation-summary u div element
• Vrednost ovog atributa može biti:• ValidationSummary.All - prikazuju se validacione greške na nivou propertija i
na nivou modela• ValidationSummary.ModelOnly - prikazuju se validacione greške samo na
nivou modela• ValidationSummary.None
686
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
12/16/2018
344
Validacione greške na nivou modela
687
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
Prikaz svih validacionih grešaka
688
<div asp-validation-summary="All" class="text-danger"></div>
12/16/2018
345
Kreiranje Edit pogleda
689
Deo Edit pogleda
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="OsobaId" />
<div class="form-group">
<label asp-for="Ime" class="control-label"></label>
<input asp-for="Ime" class="form-control" />
<span asp-validation-for="Ime" class="text-danger"></span>
</div>
690
Kreiranje skrivenog polja kojim se prosleđuje OsobaId polje metodi kontrolera
<input type="hidden" data-val="true" data-val-required="The OsobaId field is required." id="OsobaId"
name="OsobaId" value="1" />
12/16/2018
346
Izgled strane za editovanje
691
Kreiranje Delete pogleda
692
12/16/2018
347
Delete.cshtml-1@model Osoba
@{
ViewData["Title"] = "Delete";
}
<h2>Delete</h2>
<h3>Are you sure you want to delete this?</h3>
<div>
<h4>Osoba</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Ime)
</dt>
<dd>
@Html.DisplayFor(model => model.Ime)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Prezime)
</dt>
<dd>
@Html.DisplayFor(model => model.Prezime)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Adresa)
</dt>
<dd>
@Html.DisplayFor(model => model.Adresa)
</dd>
</dl> 693
Delete.cshtml-2
<form asp-action="Delete">
<input type="hidden" asp-for="OsobaId" />
<input type="submit" value="Delete" class="btn btn-default" /> |
<a asp-action="Index">Back to List</a>
</form>
694
12/16/2018
348
Strana za brisanje
695
Pitanje 1
Ukoliko želimo da isti pogled pridružimo za dva ili više kontrolera stavljamo ga u folder:a. Views/Homeb. Views/Sharedc. Views/Index
Odgovor: b
696
12/16/2018
349
Pitanje 2
697
Index pogled koji odgovara kontroleru OsobaController je fajl:a. \Views\Osoba\Index.cshtmlb. \Views\OsobaController\Index.cshtmlc. \Views\Index.cshtmld. \Models\Osoba\Index.cshtml
Odgovor: a
Pitanje 3
698
Html helper metoda DisplayFor() prikazuje:a. Vrednost svojstva model klase za objekat koji trenutno prikazujeb. Naziv svojstva iz model klasec. generiše element <form>
Odgovor: a
12/16/2018
350
Pitanje 4
699
Html Helper metoda DisplayNameFor() prikazuje:a. Vrednost svojstva model klase za objekat koji trenutno prikazujeb. Naziv svojstva iz model klasec. generiše element <form>
Odgovor: b
Pitanje 5
700
Odgovor: a
Proces kreiranja .NET objekata na osnovu parametara
HTTP zahteva u metodama kontrolera naziva se
a. Model binding
b. Controller binding
c. Pogled binding
12/16/2018
351
Pitanje 6
701
Odgovor: b
Validnost podataka koji su prosleđeni do akcione metode
kontrolera proverava se korišćenjem izraza
a. ModeBinding.IsValid
b. ModelState.IsValid
c. Model.IsValid
Pitanje 7
702
Odgovor: a
Direktive koje se dele između različitih pogleda smeštaju se unuta sledećeg fajla Views/Shared
foldera
a. _ViewImports.cshtml
b. Imports.cshtml
c. _Layout.cshtml
12/16/2018
352
Pitanje 8
703
Odgovor: a
Klase koje omogućavaju serverskom kodu da ubacuje serverske atribute u postojeće html elemente i proširi njihovu funkcionalnost nazivaju se:a. tag helperib. html helperic. code helperi
Pitanje 9
704
Odgovor: a
Kako InputTagHelper specificira svojstvo modela za koje se kreira input kontrola
a. pomoću atributa asp-for
b. pomoću atributa type
c. pomoću atributa
12/16/2018
353
Parcijalni pogledi i View komponente
Kreiranje ASP.NET Core web aplikacije
706
12/16/2018
354
Model klasa[Table("Osoba")]public class Osoba{
public int OsobaId { get; set; }
[Display(Name = "Ime osobe")][Required(ErrorMessage = "Morate uneti ime")][StringLength(30, ErrorMessage ="Maksimalno 30 karaktera")]public string Ime { get; set; }
[Required(ErrorMessage = "Morate uneti prezime")][Display(Name = "Prezime osobe")][StringLength(30, ErrorMessage = "Maksimalno 30 karaktera")]public string Prezime { get; set; }
[Required(ErrorMessage = "Morate uneti adresu")][DataType(DataType.MultilineText)][StringLength(100, ErrorMessage = "Maksimalno 100 karaktera")]public string Adresa { get; set; }
}707
Definisanje konekcionog stringa u appsettings.json fajlu
{"Logging": {
"LogLevel": {"Default": "Warning"
}},"AllowedHosts": "*","ConnectionStrings": {
"DefaultConnection": "Data Source=.\\SqlExpress;Initial Catalog=OsobaDb1512ver2;Integrated Security=true"}
}
708
12/16/2018
355
Registrujemo DbContext kao servis
709
public void ConfigureServices(IServiceCollection services){
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
Promenimo DbContext klasu
namespace WebMvcKontroler.Models{
public class OsobaContext : DbContext{
public OsobaContext(DbContextOptions<OsobaContext> opcije) : base(opcije){}public DbSet<Osoba> Osobe { get; set; }
}}
using Microsoft.EntityFrameworkCore;
710
12/16/2018
356
Kreiranje baze podataka primenom migracija
PM> Add-Migration Prva
PM> Update-Database
711
Kreiranje kontrolera
712
12/16/2018
357
Parcijalni pogledi
• Služi za renderovanje sličnog HTML na različitim lokacijama web aplikacije
• Kreira se kao i običan pogled ali se čekira opcija Create as a Partial View
• Unutar parcijalnog pogleda se ne ubacuju tagovi <head>, <body>
• Parcijalni pogled počinje donjom crtom _PrikaziOsobe.cshtml
• Tipizirani pogled ima @model direktivu na početku fajla
713
Kreiranje parcijalnog pogleda u folderu Shared
714
12/16/2018
358
_PrikaziOsobe.cshtml@model IEnumerable<Osoba>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Ime)
</th>
<th>
@Html.DisplayNameFor(model => model.Prezime)
</th>
<th>
@Html.DisplayNameFor(model => model.Adresa)
</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Ime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Prezime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Adresa)
</td>
</tr>
}
</tbody>
</table> 715
Prosleđivanje podataka Index pogledu
716
public class HomeController : Controller{
private readonly OsobaContext db;
public HomeController(OsobaContext _db){
db = _db;}public IActionResult Index(){
return View(db.Osobe.ToList());}
}
12/16/2018
359
Poziv parcijalnog pogleda iz pogleda
• Metoda Html.PartialAsync() služi za poziv parcijalnog pogleda koji sadrži asinhroni kod
• Upotreba partial tag helpera
<partial name="_PrikaziOsobe" />
717
@await Html.PartialAsync("_PrikaziOsobe")
Index.cshtml
718
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv parcijalnog pogleda</h1>
@await Html.PartialAsync("_PrikaziOsobe")
</div>
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv parcijalnog pogleda</h1>
<partial name="_PrikaziOsobe" />
</div>
12/16/2018
360
Parcijalni pogled prikazan u okviru Index pogleda
719
Poziv parcijalnog pogleda u kodnom bloku
720
• Metoda Html.RenderPartialAsync se poziva unutar kodnog bloka
• Ubacuje rezultat direktno u odogovor
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv parcijalnog pogleda</h1>
@{
await Html.RenderPartialAsync("_PrikaziOsobe");
}
</div>
12/16/2018
361
Kreiranje pogleda unutar koga ubacujemo zavisnost
721
Klasa OsobaServis folder Servisi
public class OsobaServis{
private readonly OsobaContext db;public OsobaServis(OsobaContext _db){
db = _db;}
public IEnumerable<Osoba> VratiOsobe(){
return db.Osobe;}
}
_ViewImports.cshtml
722
@using WebParcijalniPogledi
@using WebParcijalniPogledi.Models
@addTagHelper *,
Microsoft.AspNetCore.Mvc.TagHelpers
@using WebParcijalniPogledi.Servisi
12/16/2018
362
Registracija servisa OsobaServis u DI kontejneru
723
public void ConfigureServices(IServiceCollection services){
services.AddDbContext<OsobaContext>(opcije =>opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddTransient<OsobaServis>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);}
Ubacivanje zavisnosti u pogled
@inject OsobaServis oServis
<table class="table table-bordered table-striped">
<tr>
<th>Id</th>
<th>Ime</th>
<th>Prezime</th>
</tr>
@foreach (var os in oServis.VratiOsobe())
{
<tr>
<td>@os.OsobaId</td>
<td>@os.Ime</td>
<td>@os.Prezime</td>
</tr>
}
</table> 724
_PrikaziOsobeDI.cshtml
12/16/2018
363
Index strana HomeController
725
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv parcijalnog pogleda</h1>
<partial name="_PrikaziOsobeDI"/>
</div>
Index strana nakon poziva parcijalnog pogleda
726
12/16/2018
364
View komponente
• View komponente ne koriste model binding kao parcijalni pogledi već zavise od podataka koji im se prosleđuju pri njihovom pozivu
• Često se poziva iz layout strane
• Sastoje se iz dva dela:• Klase koja je izvedena iz klase ViewComponent i završava se sa
ViewComponent• Rezultata koje vraća - obično pogled
• Logika View komponente se definiše u metodi InvokeAsync koja vraća IViewComponentResult
• Klasa može biti smeštena u bilo kom folderu aplikacije, obično folder Components
727
Klasa OsobaViewComponent
728
12/16/2018
365
Klasa OsobaViewComponent
namespace WebParcijalniPogledi.Components{
public class OsobaViewComponent : ViewComponent{
private readonly OsobaContext db;
public OsobaViewComponent(OsobaContext context){
db = context;}
public async Task<IViewComponentResult> InvokeAsync(){
return View(await db.Osobe.ToListAsync());}
}}
729
using Microsoft.AspNetCore.Mvc;using System.Threading.Tasks;using WebParcijalniPogledi.Models;using Microsoft.EntityFrameworkCore;
Poziv View komponente
• Obično se pogled koji odgovara View komponenti smešta unutar Views/Shared/Components/Ime_Componente foldera
• Podrazumevano ime pogleda za komponentu je Default.cshtml
• View komponenta se može pozivati direktno iz kontrolera ali je uobičajeno pozivamo iz pogleda
730
12/16/2018
366
Kreiranje pogleda za komponentu
731
Default.cshtml@model IEnumerable<Osoba>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Ime)
</th>
<th>
@Html.DisplayNameFor(model => model.Prezime)
</th>
<th>
@Html.DisplayNameFor(model => model.Adresa)
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model) {
<tr>
<td>
@Html.DisplayFor(modelItem => item.Ime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Prezime)
</td>
<td>
@Html.DisplayFor(modelItem => item.Adresa)
</td>
</tr>
}
</tbody>
</table>732
12/16/2018
367
Index pogled klasa HomeController
733
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv komponente</h1>
@await Component.InvokeAsync("Osoba")
</div>
Komponenta kao tag helper
734
@using WebParcijalniPogledi
@using WebParcijalniPogledi.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@using WebParcijalniPogledi.Servisi
@addTagHelper *,WebParcijalniPogledi
Registracija tag helpera _ViewImports.cshtml
@{
ViewData["Title"] = "Home Page";
}
<div class="row">
<h1>Poziv komponente</h1>
<vc:osoba></vc:osoba>
</div>
12/16/2018
368
Pitanje 1
Parcijalni pogled ne može da sadrži sledeći html element:a. <p>b. <div>c. <head>
Odgovor: c
735
Pitanje 2
Fajl koji predtsvlja Layout MVC web aplikacije pod nazivom _Layout.cshtml definiše se:a. unutar foldera Views/Homeb. unutar foldera Views/Sharedc. unutar foldera Models
Odgovor: b
736
12/16/2018
369
Pitanje 3
Unutar pogleda (cshtml) fajla podacima koje prosleđuje kontroler pristupa se:a. korišćenjem svojstva Modelb. korišćenjem ključne reči @modelc. korišćenjem klase ModelData
Odgovor: a
737
Pitanje 4
738
Odgovor: c
U ASP.NET Core MVC web aplikaciji kreiran je parcijalni pogled _PrikaziOsobe koji prikazuje kolekciju objekata klase Osoba u vidu tabele. Na koji način referenciramo ovaj pogled unutar Index pogleda
a. await Partial("_PrikaziOsobe ")b. awaitViewBag("_PrikaziOsobe ")c. await Html.PartialAsync("_PrikaziOsobe")
12/16/2018
370
Pitanje 5
739
Odgovor: b
Ubacivanje objekta oServis servis klase OsobaServis u pogled vrši se pomoću direktive
a. @import OsobaServis oServis
b. @inject OsobaServis oServis
c. @model OsobaServis oServis
Pitanje 6
740
Kreirana je komponenta OsobaViewComponent unutar Components foldera ASP.NET Core web aplikacije. Pogled komponete je fajl:
a. Views\Shared\Components\Osoba\Default.cshtmlb. Views\Components\Osoba\Osoba.cshtmlc. Views\Shared\Default.cshtml
Odgovor: a
12/16/2018
371
Pitanje 7
741
Odgovor: a
Poziv komponente koja je predstavljena klasom OsobaViewComponent unutar nekog cshtm fajla vrši se korišćenjem koda:a. @await Component.InvokeAsync("Osoba")b. @await Component.Invoke("OsobaViewComponent ")c. @await Component("Osoba")
Pitanje 8
742
Odgovor: c
Logika View komponente se definiše unutar sledeće metode klase View
komponente
a. InvokeComponent
b. View
c. InvokeAsync
12/16/2018
372
Sigurnost ASP.NET Core MVC aplikacija
Kreiranje ASP.NET Core web aplikacije
744
12/16/2018
373
Tipovi autentifikcije
• No Authentication
• Individual User Accounts (ASP.NET Identity, ranije poznat kao ASP.NET membership), podaci se čuvaju u SQL server bazi podataka
• Work and school account (Active Directory, Azure Active Directory ili Office 365)
• Windows Authentication (Intranet)
745
ASP.NET Core Identitysistem
• ASP.NET Core Identity sistem je sistem za autentifikaciju
• Možemo konfigurisati sistem da čuva informacije o korisnicima u bazi
• Koristi Entity Framework Core Code First pristup za kreiranje baze
746
12/16/2018
374
Fajl appsettings.json{"ConnectionStrings": {"DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=aspnet-
WebSigurnost-45B8465F-DE32-4FA6-A0D8-BD5503048DCF;Trusted_Connection=True;MultipleActiveResultSets=true"},"Logging": {"LogLevel": {"Default": "Warning"
}},"AllowedHosts": "*"
}
747
Metoda ConfigureServicespublic void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
Identity servis postaje raspoloživ kroz DI kontejner
748
12/16/2018
375
Metoda Configurepublic void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseDatabaseErrorPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
Dodaje se middleware komponenta za autentifikaciju
749
Scaffold Identity
750
12/16/2018
376
Scaffold Identity
751
Podešavanje pravila za lozinku i korisnikapublic void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.Configure<IdentityOptions>(options =>
{
// Podesavanje lozinke
options.Password.RequireDigit = false;
options.Password.RequiredLength = 3;
options.Password.RequireNonAlphanumeric = false;
options.Password.RequireUppercase = false;
options.Password.RequireLowercase = false;
options.Password.RequiredUniqueChars = 1;
// Podesavanje korisnika
options.User.RequireUniqueEmail = true;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
} 752
12/16/2018
377
Folder Migrations
753
PM> Update-Database
Kreirana baza podataka
754
12/16/2018
378
Pokretanje aplikacije
755
Registracija korisnika
756
12/16/2018
379
Prikaz logovanog korisnika
757
Strana za logovanje
758
12/16/2018
380
Klasa ApplicationDbContextusing System;using System.Collections.Generic;using System.Text;using Microsoft.AspNetCore.Identity.EntityFrameworkCore;using Microsoft.EntityFrameworkCore;
namespace WebSigurnost.Data{
public class ApplicationDbContext : IdentityDbContext{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options): base(options)
{}
}}
759
Klasa LoginModel
• Privatno readonly polje _signInManager tipa SignInManager<IdentityUser>
• Ovo polje se inicijalizuju u konstruktoru od strane DI kontejnera
• Metoda OnGetAsync() - GET metoda za logovanje
• Metoda OnPostAsync() –POST metoda za logovanje
• Metoda Logout() za uništavanje autentifikacionog kolačića
760
12/16/2018
381
Model klasa za logovanje
public class InputModel{
[Required][EmailAddress]public string Email { get; set; }
[Required][DataType(DataType.Password)]public string Password { get; set; }
[Display(Name = "Remember me?")]public bool RememberMe { get; set; }
}
761
Pogled za Logovanje
762
<div class="row">
<div class="col-md-4">
<section>
<form method="post"><h4>Use a local account to log in.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div>
<div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" /><span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span></div>
<div class="form-group">
<div class="checkbox">
<label asp-for="Input.RememberMe">
<input asp-for="Input.RememberMe" />
@Html.DisplayNameFor(m => m.Input.RememberMe)</label>
</div>
</div>
<div class="form-group">
<button type="submit" class="btn btn-default">Log in</button>
</div>
</form>
</section>
</div>
</div>
12/16/2018
382
Klasa RegisterModel
• Privatno readonly polje _signInManager tipa SignInManager<IdentityUser>
• Privatno readonly polje _userManager tipa UserManager<IdentityUser>
• Ova polje se inicijalizuju u konstruktoru od strane DI kontejnera
• Metoda OnGet() je GET metoda za registraciju
• Metoda OnPostAsync() je POST metoda za registraciju
763
Model klasa za registraciju
764
public class InputModel{
[Required][EmailAddress][Display(Name = "Email")]public string Email { get; set; }
[Required][StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.",
MinimumLength = 3)][DataType(DataType.Password)][Display(Name = "Password")]public string Password { get; set; }
[DataType(DataType.Password)][Display(Name = "Confirm password")][Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]public string ConfirmPassword { get; set; }
}
12/16/2018
383
Pogled za registraciju
765
<form asp-route-returnUrl="@Model.ReturnUrl" method="post">
<h4>Create a new account.</h4>
<hr />
<div asp-validation-summary="All" class="text-danger"></div><div class="form-group">
<label asp-for="Input.Email"></label>
<input asp-for="Input.Email" class="form-control" />
<span asp-validation-for="Input.Email" class="text-danger"></span>
</div>
<div class="form-group"><label asp-for="Input.Password"></label>
<input asp-for="Input.Password" class="form-control" />
<span asp-validation-for="Input.Password" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Input.ConfirmPassword"></label><input asp-for="Input.ConfirmPassword" class="form-control" />
<span asp-validation-for="Input.ConfirmPassword" class="text-danger"></span>
</div>
<button type="submit" class="btn btn-default">Register</button>
</form>
_LoginPartial.cshtml
766
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@if (SignInManager.IsSignedIn(User))
{
<form asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Action("Index", "Home", new { area = "" })" method="post"
id="logoutForm" class="navbar-right">
<ul class="nav navbar-nav navbar-right"><li>
<a asp-area="Identity" asp-page="/Account/Manage/Index" title="Manage">Hello @UserManager.GetUserName(User)!</a>
</li>
<li>
<button type="submit" class="btn btn-link navbar-btn navbar-link">Logout</button>
</li></ul>
</form>
}
else
{
<ul class="nav navbar-nav navbar-right"><li><a asp-area="Identity" asp-page="/Account/Register">Register</a></li>
<li><a asp-area="Identity" asp-page="/Account/Login">Login</a></li>
</ul>
}
12/16/2018
384
Ubacivanje parcijalnog pogleda za logovanje u Layout
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li><a asp-area="" asp-controller="Home" asp-action="Index">Home</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="About">About</a></li>
<li><a asp-area="" asp-controller="Home" asp-action="Contact">Contact</a></li>
</ul>
<partial name="_LoginPartial" />
</div>
767
Atributske klase
• Klasa [Authorise] služi za opisivanje kontrolera ili akcione metode kontrolera čime se dozvoljava pristup samo autorizovanim korisnicima
• Klasa [AllowAnonymous] atributska klasa se obično koristi u autorizovanim kontrolerima da bi se dozvolio pristup nekoj akcionoj metodi anonimnim korisnicima
768
12/16/2018
385
Model klasa[Table("Komentar")]public class Komentar{
public int KomentarId { get; set; }
public string Autor { get; set; }
[Display(Name = "Naslov komentara")][Required(ErrorMessage = "Unesite naslov komentara")][StringLength(50, ErrorMessage = "Najmanje {2} a navise {1} karaktera", MinimumLength = 10)]public string Naslov { get; set; }
[Display(Name = "Komentar")][Required(ErrorMessage ="Unesite komentar")][StringLength(100, ErrorMessage = "Najmanje {2} a najvise {1} karaktera", MinimumLength = 10)]public string SadrzajKomentara { get; set; }
}
769
DbContext klasa
namespace WebMvcSigurnost.Models{
public class KomentarContext : DbContext{
public virtual DbSet<Komentar> Osobe { get; set; }}
}
770
12/16/2018
386
Registrujemo DbContext kao servis
771
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();
services.AddDbContext<KomentarContext>(
opcije => opcije.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
);
Izmenjena DbContext klasa
772
public class KomentarContext : DbContext{
public KomentarContext(DbContextOptions<KomentarContext> opcije) : base(opcije){}
public virtual DbSet<Komentar> Osobe { get; set; }}
PM> Add-Migration Prva -Context KomentarContext
PM> Update-Database -Context KomentarContext
12/16/2018
387
Prikaz baze podataka
773
KomentarController klasa
774
12/16/2018
388
Autorizacija metoda Create, Edit i Deleteusing Microsoft.AspNetCore.Authorization;
[Authorize]public IActionResult Create(){
return View();}
[Authorize][HttpPost][ValidateAntiForgeryToken]public async Task<IActionResult> Create([Bind("KomentarId,Autor,Naslov,SadrzajKomentara")] Komentar komentar){
if (ModelState.IsValid){
_context.Add(komentar);await _context.SaveChangesAsync();return RedirectToAction(nameof(Index));
}return View(komentar);
} 775
Autorizacija kontrolera
[Authorize]public class KomentarController : Controller{
private readonly KomentarContext _context;
public KomentarController(KomentarContext contexT){
_context = context;}
[AllowAnonymous]// GET: Komentarpublic async Task<IActionResult> Index(){
return View(await _context.Osobe.ToListAsync());}
}
776
12/16/2018
389
Pitanje 1
Atributska klasa za opis akcione metode kontrolera pomoću koje se u autorizovanim kontrolerima dozvoljava pristup toj akcionoj metodi anonimnim korisnicima je:a. [UnAuthorize]b. [AllowAnonymous]c. [NoAuthorize]
Odgovor: b
777
Pitanje 2
778
Na koji način se zabranjuje neregistrovanim korisnicima ASP.NET Core MVC web
aplikacije, da pozivaju akcione metode nekog kontrolera?
a. Kontroler se opsije atributskom klasom [NoAnonymous]
b. Kontroler se opisuje atributskom klasom [Authenticate]
c. Kontroler se opisuje atributskom klasom [Authorize]
Odgovor: c
12/16/2018
390
Pitanje 3
779
Odgovor: a
ASP.NET Core Identity sistem za logovanje za rad sa logovanim korisnikom aplikacije
koristi klasu:
a. IdentityUser
b. User
c. LoggedUser
Pitanje 4
780
Odgovor: a
Konfigurisanje identity servisa kod asp.net core web aplikcije vrši se unutar ConfigureServices metode Startup klase pozivom metodea. services.AddDefaultIdentity<IdentityUser>()b. services.AddAutentitication<IdentityUser>()c. services.Add<IdentityUser>()