PowerApps on mitä suurimmissa määrin kansalaiskehittäjien työkalu. Tuotteeseen on kuitenkin ilmestynyt mörkö, jota kansalaiskehittäjien on vaikea selättää.

Tarkoitan tietenkin komponenttia (component) .

Komponentit ovat mahtavia. Niiden avulla PowerAppsissa voi rakentaa uudelleenkäytettäviä osia (katso aikaisemmat esimerkit: navigaatio ja alatunniste).

Uudelleenkäytettävyydellä on kuitenkin hintansa. Komponentit rakennetaan täysin eristettynä (encapsulated) varsinaisesta PowerAppsista. Ne eivät esimerkiksi näe PowerAppsin muuttujia. Tämän vuoksi komponenttien tekeminen voi tuntua vaikealta.

Rakennetaan tällä kertaa yksinkertaiselta kuulostava komponentti. Modaalinen dialogi -ikkuna.

  • Käyttäjä painaa sovelluksessa painiketta (esim. tallenna)
  • Käyttäjälle avautuu ikkuna, jossa varmistetaan haluaako hän varmasti suorittaa toiminnon. Käyttäjä ei voi tehdä mitään muuta, kuin vastata kysymykseen. Varsinainen sovellus on ”lukittuna”.
  • Käyttäjän painaessa ”kyllä” tai ”ei”, suljetaan avautunut ikkuna ja ohjelma suorittaa toimenpiteen vastauksen mukaisesti

Ei voi olla vaikeaa?

Dialogi-ikkunan rakentaminen

Luodaan uusi komponentti (cmpDialog). Asetetaan sen leveys ja korkeus vastaamaan sitä käyttävän PowerAppsin leveyttä ja korkeutta. Näin komponenttimme peittää koko sovelluksen.

Näyttökuva 2019-3-27 kello 19.25.28.png

Lisätään komponentin pohjaksi suorakulmio (rectangle).

Näyttökuva 2019-3-27 kello 19.27.08.png

Täytetään suorakulmiolla koko näyttö ja vaihdetaan sen väri läpikuultavaksi harmaaksi.

Näyttökuva 2019-3-27 kello 19.28.55.png

Lisätään toinen suorakulmio, joka toimii varsinaisena dialogi-ikkunana. Asetetaan sen pohjaväri valkoiseksi. Viimeistellään se ohuilla mustilla reunoilla.

Näyttökuva 2019-3-27 kello 19.31.34.png

Lisätään dialogiin otsikko, kuvausteksti sekä Ok ja peruuta -painikkeet.

Näyttökuva 2019-3-27 kello 19.36.36.png

Mukautettujen ominaisuuksien (custom properties) lisääminen

PowerAppsin ja dialogin välillä kulkee kahdenlaista tietoa

  • dialogissa käytettävät tekstit (komponentin syöte-ominaisuus)
  • käyttäjän dialogissa tekemä valinta (komponentin tuloste-ominaisuus)

Luodaan otsikkoa ja kuvausta vastaavat mukautetut ominaisuudet.

Näyttökuva 2019-3-27 kello 19.38.02.png

Asetetaan kuvausteksien sisällöt viittaamaan juuri luomiimme ominaisuuksiin.

Näyttökuva 2019-3-27 kello 19.40.27.png

Tieto käyttäjän tekemästä valinnasta (=painamasta painikkeesta) välitetään PowerAppsille tuloste-ominaisuutena (output property).

Näyttökuva 2019-3-28 kello 18.44.56.png

Käytetään seuraavia arvoja

  • 1 = OK
  • 2  = Peruuta

Arvot päivitetään komponentin sisäiseen muuttujaan käyttäjän painaessa painiketta.

Näyttökuva 2019-3-28 kello 18.46.50.png

Sama muuttuja toimii komponentin output arvona.

Näyttökuva 2019-3-28 kello 18.49.16.png

Tähän asti kaikki on hienoa.

Dialogin avaaminen ja käyttäjän vastaukseen reagoiminen

Lisätään dialogi-komponentti sovellukseemme. Haluamme dialogin ilmestyvän käyttäjän painaessa oikean yläreunan painiketta.

Näyttökuva 2019-3-31 kello 14.09.58.png

Painikkeen takana oleva logiikka voisi nopeasti ajateltuna olla seuraava

  • Asetetaan dialogin näkyvyyden (visible) määrittelevän muuttujan arvoksi true
  • Poimitaan muuttujaan käyttäjän dialogissa antama vastaus (mitä painikketta hän on painanut)
  • Asetetaan dialogin näkyvyyden määrittelevän muuttujan arvoksi false

Toteutus näyttää tältä.

Set(dialogVisible, true); 
Set(getAnswerFromdialog,cmpDialog_1.Answer);
Set(dialogVisible, false)

Näyttökuva 2019-3-28 kello 18.53.13.png

Komponentin näkyvyyttä säädetään dialogVisible-muuttujan avulla.

Näyttökuva 2019-3-28 kello 18.58.46.png

Enempää tuskin voisi mennä ajatuksenjuoksu pieleen.

Komponentin ominaisuudet eivät ole tapahtumia (event). Niillä on aina joku arvo. Aivan aluksi arvo voi olla tyhjä, mutta sekin lasketaan.

Painikkeen OnSelect-komennot

Set(dialogVisible, true); 
Set(getAnswerFromdialog,cmpDialog_1.Answer);
Set(dialogVisible, false)

hurahtavat suoraan läpi. Dialogi avautuu, muuttujaan asetetaan komponetin output-propertyn arvo (tyhjä), jonka jälkeen dialogi sulkeutuu.

Käyttäjä ei ehdi huomata mitään.

Dialogin avaaminen ja sulkeminen

Täytyy keksiä tapa, jolla dialogi saadaan näkyville käyttäjän painettua painiketta. Sekä sulkeutumaan käyttäjän painettua OK tai Peruuta -painiketta dialogissa.

Kuulostaa yksinkertaiselta. Mutta miten komponentti kertoo sovelluksellemme käyttäjän painaneen painiketta?

Yksi keino on pelata kahdella totuusarvo (boolean) -muuttujalla. Toinen niistä on sovelluksessa ja toinen komponentissa.

  • Sovelluksen muuttujan arvo välitetään komponentille input-propertynä
  • Komponentin totuusarvo välitetään sovellukselle output-propertynä

Varsinainen logiikka menee seuraavasti

  • Sovelluksen dialogVisible-muuttujan arvo vaihdetaan aina käyttäjäen painettua dialogin avaavaa painiketta
  • Mikäli sovelluksen ja komponentin dialogVisible-muuttujien arvot ovat samat, on käyttäjä painanut sovelluksen painiketta, mutta ei ole vielä antanut vastaustaan avautuneessa dialogissa. Tällöin dialogin kuuluu olla näkyvillä.
  • Käyttäjän vastattua dialogissa, asetetaan komponentin dialogVisible-muuttujan arvoksi sovelluksen dialogVisible vastakohta. Nyt muuttujien arvot ovat erit ja dialogi piilotetaan.

Näin dialogi ilmestyy näkyviin käyttäjän painettua sovelluksen painiketta. Ja se menee piiloon käyttäjän painettua mitä tahansa dialogin painiketta.

Dialogin avaavan painikkeen OnSelect näyttää tältä.

Näyttökuva 2019-3-28 kello 19.42.36.png

Painikkeella päivitettävä muuttuja (dialogVisible) toimii komponentin visible-ominaisuuden arvona

Näyttökuva 2019-3-28 kello 19.45.29.png

Komponentissa painikkeen painamisen yhteydessä päivitetään komponentin boolean-muuttujan arvoksi sovelluksen muuttujan vastakohta.

Näyttökuva 2019-3-28 kello 19.52.12.png

Muuttujan arvo välitetään sovellukselle output-ominaisuuden avulla.

Näyttökuva 2019-3-28 kello 20.18.30.png

Komponentin näkyvyys määräytyy näiden muuttujien avulla. Dialogi näkyy, mikäli muuttujien arvot ovat samat.

Näyttökuva 2019-3-28 kello 20.19.15.png

 

Nyt dialogi tulee esiin sitä pyydettäessä ja katoaa käyttäjän annettua vastauksen.

Mutta ongelmat eivät lopu tähän.

Miten sovelluksessa reagoidaan komponentissa tehtyyn valintaan?

Haluamme tehdä sovelluksessa eri toimintoja sen perusteella, mitä käyttäjä on dialogissa valinnut.

Miten tämä onnistuu? Komponentin output-propertyllä kun on aina arvo.

Havainnollistetaan ongelmaa muokkaamalla painikkeen OnSelect -ominaisuutta seuraavasti.

Set(DialogVisible,!DialogVisible);
Set(getAnswerFromdialog,cmpDialog_1.Answer);
Notify(Text(getAnswerFromdialog),NotificationType.Information)

Näyttökuva 2019-3-28 kello 20.20.15.png

Painiketta painettaessa

  • Avataan dialogi
  • Poimitaan käyttäjän vastaus muuttujaan
  • Näytetään vastaus käyttäjälle

Mutta dialogin avauduttua näytetään käyttäjälle myös vastaus. Koska dialogin output-propertyssä on aina arvo. Ensimmäisellä kerralla tyhjä ja sen jälkeen aina edeltävän kerran vastaus.

Näyttökuva 2019-3-28 kello 20.21.11.png

Miten saamme aikaiseksi tapahtuman (event), kun komponentissa sellaista ei ole?

Tietenkin ajastimella (timer)!

Lisätään näytölle ajastin, joka käynnistyy dialogin kadotessa näytöltä.

Start: !cmpDialog_1.Visible

Näyttökuva 2019-3-28 kello 20.22.18.png

Ajastimen käynnistyessä (OnTimerStart) ajetaan seuraava komento.

If(
    cmpDialog_1.Answer = 1;
    Notify(
        "Vastasit kyllä";
        NotificationType.Success
    );
    Notify(
        "Vastasit Ei";
        NotificationType.Error
    )
)

Näyttökuva 2019-3-30 kello 15.30.47.png

Käyttäjälle näytetään ilmoitus vasta hänen painettua dialogista painiketta. Ilmoituksen sisältö riippuu painetusta painikkeesta. Ilmoituksen sijaan voisimme tallentaa lomakkeen, poistaa tietueen. jne sen perusteella mitä käyttäjä dialogista valitsi.

Helppoa?

Yhteenveto

Komponentit ovat oiva lisä PowerAppsiin. Useimmissa tapauksissa ne helpottavat sovellusten rakentajien elämää.

Tällä kertaa niin ei käynyt. Dialogi-komponentin käyttäminen sovelluksessa ei ole intuitiivista. Oikeastaan se on uskomattoman sekavaa.

Ohessa video lopputuloksesta. Jos joku haluaa vielä tämänkin jälkeen katsoa miltä se näyttää.

Minä taidan toteuttaa dialogini toistaiseksi jollain muulla tavalla.