# ZAPISKI ## ajax: ```javascript= $.ajax({ url: "/api/getWeather", data: { zipcode: 97201 }, success: function( result ) { $( "#weather-temp" ).html( "<strong>" + result + "</strong> degrees" ); } }); ``` ## delovanje ajax ```htmlmixed <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> ``` ## UVOD ## Ajax ajax: https://jquery.com/ https://cdnjs.com/libraries/jquery ### datoteka: main.py ```python= from flask import Flask, render_template import random app = Flask('app') @app.route('/') def hello_world(): return render_template("index.html") #generira random število @app.route('/rnd') def random_number(): return str(random.randint(0, 100)) app.run(host='0.0.0.0', port=8080, debug=True) ``` ### mapa: template, datoteka: index.html ```htmlmixed= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Ajax Test</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <div id="rnd"> Ni še podatkov </div> <script> console.log("Pozdrav iz skripte") // javascript print function refresh() { // refresh funkcija var div_rnd = document.getElementById("rnd") // vzemanje rnd podatkov iz konzole $.ajax({ url: "/rnd", success: function( result ) { console.log(result) //doda podatke v konzolo div_rnd.innerHTML = result //doda podatke v div } }); } setInterval(refresh, 1000) // osveževanje </script> </body> </html> ``` ### rezultat ![image](https://hackmd.io/_uploads/rJncDbj3a.png) ![image](https://hackmd.io/_uploads/ryUnwWjn6.png) --- ## Ajax in vreme api api: https://openweathermap.org/ ### datoteka: main.py ```python= from flask import Flask, render_template, request import requests app = Flask('app') api_key = "5f5c8f523ca2bf8d20d9babb8676c5f4" def get_w_api(lon, lat, units): base_url = f"https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={api_key}" call = requests.get(base_url).json() feels_like = call["main"]["feels_like"] country = call["name"] icon = call["weather"][0]["icon"] img = f"https://openweathermap.org/img/wn/{icon}@2x.png" return {"feels_like": feels_like, "country": country, "icon": img} @app.route('/') #main route def hello_world(): return render_template("index.html") @app.route('/weather') #vreme def weather(): return render_template("weather.html") @app.route('/getWeather') #api def get_weather(): print(request.args) #sprejemanje podatkov iz /weather lon = request.args.get("lon", -1) lat = request.args.get("lat", -1) units = request.args.get("units", -1) return get_w_api(lon, lat, units) #get weather api funkcija # return request.args app.run(host='0.0.0.0', port=8080, debug = True) ``` ### mapa: template, datoteka: index.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Document</title> </head> <body> <h1> Index </h1> <a href="/weather"> Vreme </a> </body> </html> ``` ### mapa: template, datoteka: weather.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Document</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <a href="/"> nazaj </a> <h1> Vreme </h1> <input type="text" id="lat" placeholder="Vnesi lat"><br> <input type="text" id="lon" placeholder="Vnesi lot"><br> <select id="units"> <option value="metric"> Metrične enote </option> <option value="imperial"> Imperialne enote </option> </select> <button onclick="refresh_weather()"> Klik za vreme </button> <div id="feels_like"></div> <div id="country"></div> <div id="icon"></div> <script> function refresh_weather() { // klicanje DOM elementov let lat = document.getElementById("lat").value //z let povemo, da je to spremenljivka let lon = document.getElementById("lon").value let units = document.getElementById("units").value let feels_like = document.getElementById("feels_like") let country = document.getElementById("country") let icon = document.getElementById("icon") // klic na route /getWeather // -> pošljemo podatke lat, lon, units $.ajax({ url: "/getWeather", data: { //dictionary v js lat : lat, lon : lon, units: units }, success: function( result ) { feels_like.innerHTML = result.feels_like country.innerHTML = result.country icon.innerHTML = result.icon } }); } </script> </body> </html> ``` ### rezultat ![image](https://hackmd.io/_uploads/HkYcI416T.png) ![image](https://hackmd.io/_uploads/BJm2U4ka6.png) --- ## Number API API: http://numbersapi.com ### datoteka: main.py ```python= from flask import Flask, render_template, request import random, requests app = Flask('app') @app.route('/') def hello_world(): return render_template("index.html") @app.route('/getFacts') def get_facts(): number = request.args.get("number", -1) izbira = request.args.get("izbira", -1) call = requests.get(f"http://numbersapi.com/{number}/{izbira}") return {"odgovor": call.text} app.run(host='0.0.0.0', port=8080, debug=True) ``` ### mapa: template, datoteka: index.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Številke</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> Vnesi število: <input type="number" id="stevilo"> <select id="izbire"> <option value="math"> math </option> <option value="trivia"> trivia </option> <option value="year"> year </option> </select> <br> <button onclick="prikaz()"> Pošlji </button> <div id="output"></div> <script> function prikaz() { let number = document.getElementById("stevilo").value let izbira = document.getElementById("izbire").value console.log(number, izbira) let output = document.getElementById("output") $.ajax({ url: "/getFacts", data: { number : number, izbira : izbira }, success: function( result ) { console.log(result) output.innerHTML = result.odgovor } }); } </script> </body> </html> ``` ### rezultat ![image](https://hackmd.io/_uploads/Hy1uw_6pT.png) --- ## Copy-Paste ### datoteka: main.py ```python= ``` ### mapa: template, datoteka: index.html ```htmlmixed= ``` ### rezultat --- # VAJE ## NAREDI FLASK AJAX(povezava z API) ### navodila Argumente routov ne sprejemamo več kar preko /route/< arg1 >/< arg2 > ampak preko request.args (Ajax data) - /coinFlip - naredi kovanec.html, se ob kliku na gumb izpiše naključna stran in slika kovanca. - /randomQuote - na qoute.html se ob osvežitvi strani pokaže nov random quote. - /randomNum/ - na rndnum.html naredi 2 inputa za min in max vrednost. Ob pritisku na gumb se na strani pokaže naključne številka med min in max. - /randPassword/ - na password.html 1 input za dolžino gesla in en gumb, ki na strani izpiše novo generirano geslo. - /randDice/ - 2 inputa, 1 gumb. Ob pritisku na gumb izpiši podatke, ki jih vrača zgorni route. Vse naloge razen 2. zahtevajo Ajax klic! Namig: ```python= // nastavljanje <script> var myDiv = document.getElementById('myDiv'); myDiv.innerHTML = '<img src="https://www.example.com/myimage.jpg" alt="My Image" width="200" height="150">'; // ne pozabi spremeniti src-ja slike! </script> ``` - Naredi spletno stran na routu (/investing), ki vpraša uporabnika po začetni investiciji, leto in mesec kdaj bi investirali. In pa še delnico v katero bi takrat investirali. Program s pomočjo API-ja Alpa Vantage (poglej si route TIME_SERIES_INTRADAY ). Izpiši koliko denarja in koliko % bi zaslužili/izgubili s takšno inveticijo DO danes. Za vrednost delnice uporabi kar zadnjo "close" ceno v izbranem dnevu. (iz Alpha Vantage) ker v 6. vaji ne moremo vpisati kar Microsoft, moramo najti kratko ime (ticker) od njihove delnice. Recimo od Microsoft delnica ima ticker MSFT. Če želimo, da lahko uporabnik vpiše kar Microsoft lahko uporabiš route "Search Endpoint", ki najde Ticker ime po ključnih besedah. ### rešitev #### datoteka: main.py ```python= from flask import Flask, render_template, request import random import string # naloga 4 app = Flask('app') @app.route('/') def main(): return render_template("index.html") #1. /coinFlip tails = {"img": "https://i.postimg.cc/zysdXN8w/tail.png", "status": "tails"} head = {"img": "https://i.postimg.cc/CBNJNfDJ/head.png", "status": "head"} @app.route('/coins') def coins(): return render_template("kovanec.html") @app.route('/coinFlip') def coin_flip(): print(random.choice([tails, head])) return random.choice([tails, head]) #----------------------------------------------------------------------------- #2. /randomQuote quotes = [ "The greatest glory in living lies not in never falling, but in rising every time we fall.", "The way to get started is to quit talking and begin doing.", "Your time is limited, so don't waste it living someone else's life. Don't be trapped by dogma – which is living with the results of other people's thinking.", "The future belongs to those who believe in the beauty of their dreams.", "If you look at what you have in life, you'll always have more. If you look at what you don't have in life, you'll never have enough.", "If you set your goals ridiculously high and it's a failure, you will fail above everyone else's success.", "You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us. And the world will live as one.", "You must be the change you wish to see in the world.", "Spread love everywhere you go. Let no one ever come to you without leaving happier.", "The only thing we have to fear is fear itself." ] @app.route('/quote') def quote(): return render_template("quote.html") @app.route('/randomQuote') def random_quote(): return {"quote": random.choice(quotes)} #----------------------------------------------------------------------------- #3. /randomNum/<min>/<max> @app.route('/rndnumber') def rndnumber(): return render_template("rndnumber.html") @app.route('/randomNum') def random_num(): min_number = request.args.get("min", 0) max_number = request.args.get("max", 0) rndNum = random.randrange(int(min_number), int(max_number) + 1) # {"number": str(random.randrange(int(min), int(max) + 1)), "min" : min, "max": max} return {"number": rndNum, "min": min_number, "max": max_number} #----------------------------------------------------------------------------- #4. /randPassword/<length> lowercase = string.ascii_lowercase uppercase = string.ascii_uppercase special_characters = string.punctuation @app.route('/password') def password(): print("tuki") return render_template("password.html") @app.route('/randPassword') def random_password(): password = "" dolzina = request.args.get("dolzina", 0) for st in range(int(dolzina)): izbira = random.choice([lowercase, uppercase, special_characters]) password += izbira[random.randrange(0, len(izbira) + 1)] return {"password": password} #----------------------------------------------------------------------------- #5. /randDice/<sides>/<numDices> @app.route('/rand_dice') def random_dice(): return render_template("random_dice.html") @app.route('/randDice') def randomDice(): numbers = [] #shranjevanje rezultatov metov kock sides = request.args.get("st_strani", 0) num_dices = request.args.get("st_metov", 0) for st in range(int(num_dices)): numbers.append(random.randrange(0, int(sides) + 1)) #dodajanje dobljenih rezultatov return {"meti": numbers , "sestevek" : sum(numbers)} #----------------------------------------------------------------------------- #6. /investing app.run(host='0.0.0.0', port=8080, debug=True) ``` #### mapa: template, datoteka: index.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Main</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <h1> Splete strani </h1> <a href="/coins"> Coins </a><br> <a href="/quote"> Quote </a><br> <a href="/rndnumber"> Random number </a><br> <a href="/password"> Password generator </a><br> <a href="/rand_dice"> Throw a dice </a> </body> </html> ``` #### mapa: template, datoteka: kovanec.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Kovanec</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <button onclick="prikaz()"> Pridobi kovanec </button> <h1 id="output"></h1> <div id="slika"></div> <script> function prikaz() { let output = document.getElementById("output") let slika = document.getElementById("slika") $.ajax({ url: "/coinFlip", success: function( result ) { console.log(result) output.innerHTML = result.status slika.innerHTML = '<img src='+ result.img + ' height="100" width="100">'; } }); } </script> </body> </html> ``` #### mapa: template, datoteka: quote.html ```htmlmixed= <!DOCTYPE html> <html> <head> <title>Quote</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> <div id="quote"></div> <script> let quote = document.getElementById("quote") $.ajax({ url: "/randomQuote", success: function( result ) { console.log(result) quote.innerHTML = result.quote } }); </script> </body> </html> ``` #### mapa: template, datoteka: rndnumber.html ```htmlmixed= <!DOCTYPE html> <html lang="en"> <head> <title>Random number</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> Min število: <input type="number" id="min"></input><br> Max število: <input type="number" id="max"></input><br> <button onclick="prikaz()"> Random število </button><br> <div> Random number: <div id="random_number"></div></div><br> <div> Min number: <div id="min_number"></div></div><br> <div> Max number: <div id="max_number"></div></div><br> <script> function prikaz() { let min = document.getElementById("min").value let max = document.getElementById("max").value $.ajax({ url: "/randomNum", data: { min : min, max : max }, success: function( result ) { console.log(result) random_number.innerHTML = result.number min_number.innerHTML = result.min max_number.innerHTML = result.max } }); } </script> </body> </html> ``` #### mapa: template, datoteka: password.html ```htmlmixed= <!DOCTYPE html> <html lang="en"> <head> <title>Password generator</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> Dolžina gesla: <input type="number" id="dolzina"></input><br> <button onclick="prikaz()"> Generiraj </button><br> <div id="output"></div> <script> function prikaz() { let dolzina = document.getElementById("dolzina").value $.ajax({ url: "/randPassword", data: { dolzina : dolzina }, success: function( result ) { console.log(result) output.innerHTML = result.password } }); } </script> </body> </html> ``` #### mapa: template, datoteka: random_dice.html ```htmlmixed= <!DOCTYPE html> <html lang="en"> <head> <title>Dice thrower</title> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> </head> <body> Stevilo metov: <input type="number" id="st_metov"></input><br> Stevilo strani: <input type="number" id="st_strani"></input><br> <button onclick="prikaz()"> Generiraj </button><br> <div id="meti"></div> <div id="numbers"></div> <script> function prikaz() { let st_metov = document.getElementById("st_metov").value let st_strani = document.getElementById("st_strani").value $.ajax({ url: "/randDice", data: { st_metov : st_metov, st_strani: st_strani }, success: function( result ) { console.log(result) meti.innerHTML = result.meti numbers.innerHTML = result.sestevek } }); } </script> </body> </html> ``` #### mapa: template, datoteka: invest.html ```htmlmixed= ``` #### rezultat index.html ![image](https://hackmd.io/_uploads/r1hT_j-Ca.png) /coinFlip ![image](https://hackmd.io/_uploads/BkE0J1P0a.png) /randomQuote ![image](https://hackmd.io/_uploads/rkki11PR6.png) /randomNum ![image](https://hackmd.io/_uploads/H1_ygyPCT.png) /randPassword ![image](https://hackmd.io/_uploads/HkdVXJD0T.png) /randDice ![image](https://hackmd.io/_uploads/HkTnekvA6.png) --- ## Meme vaja ### navodila S pomočjo API-ja https://imgflip.com/api generiraj meme. Tvoja stran naj ima dropdown menu za izbiro "meme templata" in inpute za tekst. Iz routa "/get_memes" pridobi vse možne meme "template" in jih napolni v HTML dropdown ob naložitvi tvoje strani. Tu si pomagaj z Jinja for zanko. Recimo če Jinji pošljemo slovar iz /get_memes: S pomočjo API-ja: https://imgflip.com/api generiraj meme. Tvoja stran naj ima dropdown menu za izbiro "meme templata" in inpute za tekst. Iz routa "/get_memes" pridobi vse možne meme "template" in jih napolni v HTML dropdown ob naložitvi tvoje strani. Tu si pomagaj z Jinja for zanko. recimo če Jinji pošljemo slovar iz /get_memes: ```python= {% for item in options %} <option value={{ item.id }}>{{ item.name }}</option> {% endfor %} ``` Za določen meme izvemo tudi koliko "box-ov" ima oz. na koliko mest na sliki lahko vpišemo tekst. Za pomoč funkcija, ki genereria inpute, glede na podano število boxov (n). Doda n inputov v div z ID "inputDiv" ```python= function addDivs( numInputs) { // 1. Pridobi referenco na div, kjer imamo inpute let div = document.getElementById("inputDiv"); // 2. Pobrišemo star HTML v divu div.innerHTML = ''; // 3. Dodaj inpute z ID-ji input1, input2, ... for (let i = 0; i < numInputs; i++) { let input = document.createElement('input'); input.type = 'text'; input.id = 'input' + (i + 1); div.appendChild(input); } } ``` Za pomoč še funkcija, ki pogleda vse inpute (pogleda do n). ```python= function readInputs(n) { let div = document.getElementById("inputDiv"); let inputData = {}; // To store the collected data for (let i = 1; i <= n; i++) { const input = div.getElementById(`input${i}`); inputData[`input${i}`] = input.value; } return inputData; } Ko kliknemo gumb ob izbranem "meme templatu" in izpolnjenih "boxih" nam stran generira meme. ``` ### rešitev ```python= ``` #### mapa: template, datoteka: rezultat.html ```htmlmixed= ``` #### rezultat --- ## COPY PASTE ### navodila ```python= ``` #### mapa: template, datoteka: rezultat.html ```htmlmixed= ``` #### rezultat ---