Dynamicznie wczytywana lista dwupoziomowa z pliku JSON pobranego z zewnętrznego serwera do aplikacji Phonegap z użyciem wirtualnej listy wygląda następująco.
Jest to fragment aplikacji dla pola Paintball.
Najważniejsza linijka to ta, gdzie deklarujemy listę:
Strona join.html w aplikacji (trzeba ustawić routing):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | <div class="page" data-name="join"> <div class="navbar"> <div class="navbar-inner sliding"> <div class="left"> <a href="#" class="link back" id="backButton"> <i class="icon icon-back"></i> <span class="ios-only">Powrót</span> </a> </div> <div class="title">Wybierz mecz</div> <div class="subnavbar"> <form data-search-container=".virtual-list" data-search-item="li" data-search-in=".item-title" class="searchbar searchbar-init"> <div class="searchbar-inner"> <div class="searchbar-input-wrap"> <input type="search" placeholder="Szukaj"/> <i class="searchbar-icon"></i> <span class="input-clear-button"></span> </div> <span class="searchbar-disable-button">Ignoruj</span> </div> </form> </div> </div> </div> <div class="searchbar-backdrop"></div> <div class="page-content"> <div class="list simple-list searchbar-not-found"> <ul> <li> <a class="item-link smart-select smart-select-init" data-open-in="sheet"> <select name="team"> <option value="-1" selected>Brak połączenia</option> </select> <div class="item-content"> <div class="item-inner"> <div class="item-title">Nie można wczytać listy meczów</div> </div> </div> </a> </li> </ul> </div> <div class="list virtual-list media-list searchbar-found"></div> </div> </div> |
Do tego aplikacja w standardowym dla Framework7 pliku app.js:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 | // Dom7 var $$ = Dom7; // Framework7 App main instance var app = new Framework7({ root: '#app', // App root element id: 'com.fxteam.tournament', // App bundle ID name: 'Torunament', // App name theme: 'auto', // Automatic theme detection // App root data data: function () { return { user: { firstName: 'Adam', lastName: 'Fulara', }, }; }, // App root methods methods: { helloWorld: function () { app.dialog.alert('Hello World!'); }, }, // App routes routes: routes, }); // Init/Create main view var mainView = app.views.create('.view-main', { url: '/' }); // Login Screen Demo $$('#my-login-screen .login-button').on('click', function () { var username = $$('#my-login-screen [name="username"]').val(); var password = $$('#my-login-screen [name="password"]').val(); // Close login screen app.loginScreen.close('#my-login-screen'); // Alert username and password app.dialog.alert('Username: ' + username + '<br>Password: ' + password); }); //////////////////////////////////////////////// var globalData = { //FX dane globalne matches: null, //dane JSON meczu match: null, connectedToGame : false, listOfMatches: Array(0), virtualList: null, currentGameId: -1, //id z bazy currentGameTeamNo: -1, //0 pierwsza drużyna, 1 druga - z tablicy indeks status: '' } //FX: //////////////////////////////////////////////////////////////////////////// // JOIN Page $$(document).on('page:init', '.page[data-name="join"]', function (e) { app.preloader.show(); if (globalData.virtualList) //jeśli lista była już raz inicjowana trzeba ją wyczyścić { app.virtualList.destroy(globalData.virtualList); globalData.listOfMatches = []; //czyścimy tablicę do ponownego wczytania JSON } // app.preloader.show(); app.request.json('http://asg.fulara.com/model/match_list.php', function(data) { app.preloader.hide(); globalData.matches = data; for(var i=0; i<globalData.matches.length; i++) { //tworzenie virtual List Framework7 - listy meczy globalData.listOfMatches.push({ title: globalData.matches[i]["name"], subtitle: globalData.matches[i]["startTime"], teamA: globalData.matches[i]["teams"][0]["teamName"], //na razie tylko 2 drużyny tu: 0, 1 teamB: globalData.matches[i]["teams"][1]["teamName"], matchId: globalData.matches[i]["matchId"] }); } globalData.virtualList = app.virtualList.create({ //tworzenie wirtualnej listy meczy el: '.virtual-list', items: globalData.listOfMatches, searchAll: function (query, items) { var found = []; for (var i = 0; i < items.length; i++) { if (items[i].title.toLowerCase().indexOf(query.toLowerCase()) >= 0 || query.trim() === '') found.push(i); } return found; //return array with mathced indexes }, // List item Template7 template itemTemplate: '<li>' + '<a href="#" class="item-link item-content">' + '<select id="{{matchId}}" name="team">'+ '<option value="null" selected disabled hidden> Wybierz drużynę</option>'+ '<option value="0">{{teamA}}</option>'+ '<option value="1">{{teamB}}</option>'+ '</select>'+ '<div class="item-content">'+ '<div class="item-inner">' + '<div class="item-title-row">' + '<div class="item-title">{{title}}</div>' + '</div>' + '<div class="item-subtitle">{{subtitle}}</div>' + '</div>' + '</div>' + '</a>' + '</li>', // Item height height: app.theme === 'ios' ? 63 : 73, }); //end create virtual list function searchArrayIndex(selectedId) {//na podstawie Id pola z bazy danych zwraca indeks z tablicy globalData matches o tym ID for (var i=0; i<globalData.matches.length; i++) if (globalData.matches[i].matchId == selectedId) return i; return 0; } $$("select").change( function(event) { //Wybranie meczu w listy, powrót do głównej storny var selectId=event.target.id; //Pobranie ID selecta (jest kilka na stornie) var selectedTeam = document.getElementById(selectId).value; //pobranie z selecta wybranej drużyny $$("#match").removeClass("disabled"); //uaktywnienie przycisku meczowego $$("#join").addClass("disabled"); var idInArray = searchArrayIndex(selectId); var statusColor = globalData.matches[idInArray]["teams"][selectedTeam]["teamFlag"]; globalData.status='<DIV style="color: ' + statusColor + '">W grze: ' + globalData.matches[idInArray]["name"] + ": " + globalData.matches[idInArray]["teams"][selectedTeam]["teamName"] + '</DIV>'; document.getElementById("statusInfo").innerHTML = globalData.status; globalData.connectedToGame = true; //jesteśmy w grze, zapamiętaj globalData.currentGameId = selectId; globalData.currentDameTeamNo = selectedTeam; $$("#backButton").click(); //powrót do głównej strony }); }); //end of JSON load });//end init page 'join' function; ////////////////////////////// // MATCH Page: - przykładowa inna strona - niepotrzebna w tym przykładzie $$(document).on('page:init', '.page[data-name="match"]', function (e) { document.getElementById("matchDescription").innerHTML = globalData.status; $$("#leave").on('click',function() { //Opuszczenie meczu $$("#match").addClass("disabled"); //uaktywnienie przycisku $$("#join").removeClass("disabled"); document.getElementById("statusInfo").innerHTML="Niepołączony"; //pasek statusowy document.getElementById("statusInfo").style.color = 'black'; globalData.connectedToGame = false; globalData.match = null; $$("#matchBackButton").click(); }); }); |
A po stronie serwera pobieranie pliku JSON (w pliku connect.php oprócz połączenia ustawiamy UTF8 – wymagane przy JSON):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | <?php include "connection.php"; //wzór pliku we wpisie "Pełny panel administracyjny MySQLi" if ($sql = $baza->prepare( " SELECT tournament_match.id, tournament_field.name, start_time, end_time, id_field FROM tournament_match INNER JOIN tournament_field ON tournament_match.id_field = tournament_field.id" )) { $sql->execute(); //wykonaj SQL $sql->bind_result($matchId, $name, $startTime,$endTime, $idField); while ($sql->fetch()) $listOfMatches[] = array( "matchId" => $matchId, "name" => $name, "startTime" => $startTime, "endTime" => $endTime, "idField" => $idField ); //dla każdego nazwiska tworzy 2 pary, nazwiska przekonwertowane do UTF $sql->close(); } foreach ($listOfMatches as &$match) //dla każdego meczu wczytaj drużyny, które są do tego meczu zapisane { $sql = $baza->prepare( " SELECT name, description, points, flag FROM tournament_team WHERE match_id = ?"); //wczytuje po kolei wszystkie drużyny związane z meczem (pewno są dwie, ale można więcej) $sql->bind_param( "i", $match["matchId"]); $sql->execute(); $sql->bind_result($teamName, $teamDescription, $teamPoints, $teamFlag); $id_druzyny = 0; //indeks w tablicy drużyn do meczu while ($sql->fetch()) { $matchTeam = array( "teamName" => $teamName, "teamDescription" => $teamDescription, "teamPoints" => $teamPoints, "teamFlag" => $teamFlag ); $match["teams"][$id_druzyny++] = $matchTeam; //kolejna drużyna } $sql->close(); } $baza->close(); echo json_encode($listOfMatches, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); ?> |
Lista jest dwupoziomowa – to znaczy mamy pola meczowe, z których każde ma zadeklarowane drużyny (w tej wersji – dwie)