Deimantas Brandišauskas
Deimantas Brandišauskas

Reputation: 1772

Kendo UI + PhoneGap not working

I downloaded KENDO UI and imported /js and /css folders to my project directory. Now, I'm crreating new index.html project and referencing my all Kendo UI files in the /js and /css folders. But nothing happening. No styles, no js, nothing. Just plain HTML and nothing else. I just don't know what I'm doing wrong so I hope someone could help me with this. Here is my index.html file

    <!DOCTYPE html>
<html>

    <head>
        <title>Where is my car?</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <script src="js/jquery.min.js"></script>
        <script src="js/kendo.mobile.min.js"></script>
        <link href="styles/kendo.common.min.css" rel="stylesheet" />
        <link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
    </head>

    <body>
        <header data-role="header">
            <h1>Where is my car?</h1>
        </header>
        <div id="content" data-role="content">
            <p>asfdasfdasdfasdfasdfasdfs</p>
            <a class="button" data-role="button" href="map.html?requestType=set" id="set-car-position">Set position</a>
            <a class="button" data-role="button" href="map.html?requestType=get" id="find-car" data-role="button">Find car</a>
            <a class="button" data-role="button" href="positions.html" id="positions-history" data-role="button">Positions history</a>
        </div>
        <footer data-role="footer">
            <h3>Created by </h3>
            <a data-icon="info" data-iconpos="notext" class="ui-btn-right">Credits</a>
        </footer>
        <style scoped>
            #button-badge .button {
                margin-left: 1em;
                text-align: center;
            }
            #button-home .head, #facility .head, #sports .head {
                display: block;
                margin: 1em;
                height: 120px;
                -webkit-background-size: 100% auto;
                background-size: 100% auto;
            }
            .km-ios .head, .km-blackberry .head {
                -webkit-border-radius: 10px;
                border-radius: 10px;
            }
        </style>
    </body>

</html>

DEMO in jsfiddle ->> http://jsfiddle.net/ep5e8/.

Thank you for any help.

EDIT:

index.html:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Where is my car?</title>
        <script src="cordova.js"></script>
        <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
        <script src="js/functions.js"></script>
        <script src="js/maps.js"></script>
        <script src="js/positions.js"></script>
        <!-- Kendo UI Mobile CSS -->
        <link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <!-- jQuery JavaScript -->
        <script src="js/jquery.min.js"></script>
        <!-- Kendo UI Mobile combined JavaScript -->
        <script src="js/kendo.mobile.min.js"></script>
        <script src="js/jquery.min.js"></script>
        <script src="js/kendo.mobile.min.js"></script>
        <script src="content/shared/js/console.js"></script>
        <link href="styles/kendo.common.min.css" rel="stylesheet" />
        <link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <script>
            $(document).one('deviceready', initApplication);
        </script>
    </head>

    <body>
        <div id="welcome-page" data-role="view">
            <header data-role="header">
                <div data-role="navbar">
                    <span data-role="view-title">Where is my car?</span>
                </div>
            </header>
            <div id="content" data-role="content">
                <p>Where is my car? lets you bookmark where you parked your car on a map and then find a route when you want to return to it. The app will also save a log of your saved positions (up to 50).</p>
                <a href="map.html?requestType=set" id="set-car-position" data-role="button" style="background-color: green">Set position</a>
                <a href="map.html?requestType=get" id="find-car" data-role="button" style="background-color: green">Find car</a>
                <a href="positions.html" id="positions-history" data-role="button" style="background-color: green">Positions history</a>
            </div>
            <!--Kendo Mobile Footer -->
            <footer data-role="footer">
                <!-- Kendo Mobile TabStrip widget -->
                <div data-role="tabstrip">
                    <h3>Created by</h3>
                </div>
            </footer>
        </div>
        <script>
            // Initialize a new Kendo Mobile Application
            var app = new kendo.mobile.Application();
        </script>
    </body>

</html>

positions.html:

<!DOCTYPE html>
<html>
   <head>
      <meta charset="UTF-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1">
      <title>Positions' history</title>
   </head>
   <body>
      <div id="positions-page" data-role="page">
         <header data-role="header">
            <a href="#" data-icon="back" data-rel="back" data-iconpos="notext" title="Go back">Back</a>
            <h1>Positions' history</h1>
         </header>
         <div id="content" data-role="content">
            <ul id="positions-list" data-role="listview" data-inset="true" data-split-icon="delete" data-filter="true">
            </ul>
         </div>
         <footer data-role="footer">
            <h3>Created by </h3>
         </footer>
      </div>
   </body>
</html>

map.html:

<!DOCTYPE html>
<html>
   <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Where is my car?</title>
        <script src="cordova.js"></script>
        <script src="http://maps.google.com/maps/api/js?sensor=true"></script>
        <script src="js/functions.js"></script>
        <script src="js/maps.js"></script>
        <script src="js/positions.js"></script>
        <!-- Kendo UI Mobile CSS -->
        <link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <!-- jQuery JavaScript -->
        <script src="js/jquery.min.js"></script>
        <!-- Kendo UI Mobile combined JavaScript -->
        <script src="js/kendo.mobile.min.js"></script>
        <script src="js/jquery.min.js"></script>
        <script src="js/kendo.mobile.min.js"></script>
        <script src="content/shared/js/console.js"></script>
        <link href="styles/kendo.common.min.css" rel="stylesheet" />
        <link href="styles/kendo.mobile.all.min.css" rel="stylesheet" />
        <script>
            $(document).one('deviceready', initApplication);
        </script>
    </head>
   <body>
      <div id="map-page" data-role="layout">
          <header data-role="header">
                <div data-role="navbar">
                    <a href="#" data-icon="back" data-rel="back" data-iconpos="notext" title="Go back">Back</a>
                    <span data-role="view-title">Where is my car?</span>
                </div>
            </header>
         <div id="content" data-role="content">
            <div id="map">
            </div>
         </div>
      </div>
       <script>
            // Initialize a new Kendo Mobile Application
            var app = new kendo.mobile.Application();
        </script>
   </body>
</html>

functions.js:

function checkRequirements()
{
   if (navigator.network.connection.type == Connection.NONE)
   {
      navigator.notification.alert(
         'To use this app you must enable your internet connection',
         function(){},
         'Warning'
      );
      return false;
   }

   return true;
}

function updateIcons()
{
   if ($(window).width() > 480)
   {
      $('a[data-icon], button[data-icon]').each(
         function()
         {
            $(this).removeAttr('data-iconpos');
         }
      );
   }
   else
   {
      $('a[data-icon], button[data-icon]').each(
         function()
         {
            $(this).attr('data-iconpos', 'notext');
         }
      );
   }
}

function urlParam(name)
{
   var results = new RegExp('[\\?&amp;]' + name + '=([^&amp;#]*)').exec(window.location.href);
   if (results != null && typeof results[1] !== 'undefined')
      return results[1];
   else
      return null;
}

/**
 * Initialize the application
 */
function initApplication()
{
   $('#set-car-position, #find-car').click(function() {
      if (checkRequirements() === false)
      {
         $(this).removeClass('ui-btn-active');
         return false;
      }
   });
   $(document).on('pagebeforecreate orientationchange', updateIcons);
   $('#map-page').live(
      'pageshow',
      function()
      {
         var requestType = urlParam('requestType');
         var positionIndex = urlParam('index');
         var geolocationOptions = {
            timeout: 15 * 1000, // 15 seconds
            maximumAge: 10 * 1000, // 10 seconds
            enableHighAccuracy: true
         };
         var position = new Position();

         $.mobile.loading('show');
         // If the parameter requestType is 'set', the user wants to set
         // his car position else he want to retrieve the position
         if (requestType == 'set')
         {
            navigator.geolocation.getCurrentPosition(
               function(location)
               {
                  // Save the position in the history log
                  position.savePosition(
                     new Coords(
                        location.coords.latitude,
                        location.coords.longitude,
                        location.coords.accuracy
                     )
                  );
                  // Update the saved position to set the address name
                  Map.requestLocation(location);
                  Map.displayMap(location, null);
                  navigator.notification.alert(
                     'Your position has been saved',
                     function(){},
                     'Info'
                  );
               },
               function(error)
               {
                  navigator.notification.alert(
                     'Unable to retrieve your position. Is your GPS enabled?',
                     function(){
                        alert("Unable to retrieve the position: " + error.message);
                     },
                     'Error'
                  );
                  $.mobile.changePage('index.html');
               },
               geolocationOptions
            );
         }
         else
         {
            if (position.getPositions().length == 0)
            {
               navigator.notification.alert(
                  'You have not set a position',
                  function(){},
                  'Error'
               );
               $.mobile.changePage('index.html');
               return false;
            }
            else
            {
               navigator.geolocation.watchPosition(
                  function(location)
                  {
                     // If positionIndex parameter isn't set, the user wants to retrieve
                     // the last saved position. Otherwise he accessed the map page
                     // from the history page, so he wants to see an old position
                     if (positionIndex == undefined)
                        Map.displayMap(location, position.getPositions()[0]);
                     else
                        Map.displayMap(location, position.getPositions()[positionIndex]);
                  },
                  function(error)
                  {
                     console.log("Unable to retrieve the position: " + error.message);
                  },
                  geolocationOptions
               );
            }
         }
      }
   );
   $('#positions-page').live(
      'pageinit',
      function()
      {
         createPositionsHistoryList('positions-list', (new Position()).getPositions());
      }
   );
}

/**
 * Create the positions' history list
 */
function createPositionsHistoryList(idElement, positions)
{
   if (positions == null || positions.length == 0)
      return;

   $('#' + idElement).empty();
   var $listElement, $linkElement, dateTime;
   for(var i = 0; i < positions.length; i++)
   {
      $listElement = $('<li>');
      $linkElement = $('<a>');
      $linkElement
      .attr('href', '#')
      .click(
         function()
         {
            if (checkRequirements() === false)
               return false;

            $.mobile.changePage(
               'map.html',
               {
                  data: {
                     requestType: 'get',
                     index: $(this).closest('li').index()
                  }
               }
            );
         }
      );

      if (positions[i].address == '' || positions[i].address == null)
         $linkElement.text('Address not found');
      else
         $linkElement.text(positions[i].address);

      dateTime = new Date(positions[i].datetime);
      $linkElement.text(
         $linkElement.text() + ' @ ' +
         dateTime.toLocaleDateString() + ' ' +
         dateTime.toLocaleTimeString()
      );

      // Append the link to the <li> element
      $listElement.append($linkElement);

      $linkElement = $('<a>');
      $linkElement.attr('href', '#')
      .text('Delete')
      .click(
         function()
         {
            var position = new Position();
            var oldLenght = position.getPositions().length;
            var $parentUl = $(this).closest('ul');

            position.deletePosition($(this).closest('li').index());
            if (oldLenght == position.getPositions().length + 1)
            {
               $(this).closest('li').remove();
               $parentUl.listview('refresh');
            }
            else
            {
               navigator.notification.alert(
                  'Position not deleted. Something gone wrong so please try again.',
                  function(){},
                  'Error'
               );
            }

         }
      );
      // Append the link to the <li> element
      $listElement.append($linkElement);

      // Append the <li> element to the <ul> element
      $('#' + idElement).append($listElement);
   }
   $('#' + idElement).listview('refresh');
}

maps.js:

function Map()
{
}

/**
 * Display the map showing the user position or the latter and the car position
 */
Map.displayMap = function(userPosition, carPosition)
{
   var userLatLng = null;
   var carLatLng = null;

   if (userPosition != null)
      userLatLng = new google.maps.LatLng(userPosition.coords.latitude, userPosition.coords.longitude);
   if (carPosition != null)
      carLatLng = new google.maps.LatLng(carPosition.position.latitude, carPosition.position.longitude);

   var options = {
      zoom: 20,
      disableDefaultUI: true,
      streetViewControl: true,
      center: userLatLng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
   }

   var map = new google.maps.Map(document.getElementById('map'), options);
   var marker = new google.maps.Marker({
      position: userLatLng,
      map: map,
      title: 'Your position'
   });
   // If carLatLng is null means that the function has been called when the
   // user set his current position and that is when he parked the car so the
   // icon will be shown accordingly.
   if (carLatLng == null)
      marker.setIcon('images/car-marker.png');
   else
      marker.setIcon('images/user-marker.png');
   var circle = new google.maps.Circle({
      center: userLatLng,
      radius: userPosition.coords.accuracy,
      map: map,
      fillColor: '#70E7FF',
      fillOpacity: 0.2,
      strokeColor: '#0000FF',
      strokeOpacity: 1.0
   });
   map.fitBounds(circle.getBounds());

   if (carLatLng != null)
   {
      marker = new google.maps.Marker({
         position: carLatLng,
         map: map,
         icon: 'images/car-marker.png',
         title: 'Car position'
      });
      circle = new google.maps.Circle({
         center: carLatLng,
         radius: carPosition.position.accuracy,
         map: map,
         fillColor: '#70E7FF',
         fillOpacity: 0.2,
         strokeColor: '#0000FF',
         strokeOpacity: 1.0
      });

      // Display route to the car
      options = {
         suppressMarkers: true,
         map: map,
         preserveViewport: true
      }
      this.setRoute(new google.maps.DirectionsRenderer(options), userLatLng, carLatLng);
   }

   $.mobile.loading('hide');
}

/**
 * Calculate the route from the user to his car
 */
Map.setRoute = function(directionsDisplay, userLatLng, carLatLng)
{
   var directionsService = new google.maps.DirectionsService();
   var request = {
      origin: userLatLng,
      destination: carLatLng,
      travelMode: google.maps.DirectionsTravelMode.WALKING,
      unitSystem: google.maps.UnitSystem.METRIC
   };

   directionsService.route(
      request,
      function(response, status)
      {
         if (status == google.maps.DirectionsStatus.OK)
            directionsDisplay.setDirections(response);
         else
         {
            navigator.notification.alert(
               'Unable to retrieve a route to your car. However, you can still find it by your own.',
               function(){},
               'Warning'
            );
         }
      }
   );
}

/**
 * Request the address of the retrieved location
 */
Map.requestLocation = function(position)
{
   new google.maps.Geocoder().geocode(
      {
         'location': new google.maps.LatLng(position.coords.latitude, position.coords.longitude)
      },
      function(results, status)
      {
         if (status == google.maps.GeocoderStatus.OK)
         {
            var positions = new Position();
            positions.updatePosition(0, positions.getPositions()[0].coords, results[0].formatted_address);
         }
      }
   );
}

positions.js

function Position(position, address, datetime)
{
   var _db = window.localStorage;
   var MAX_POSITIONS = 50;

   this.position = position;
   this.address = address;
   this.datetime = datetime;

   this.getMaxPositions = function()
   {
      return MAX_POSITIONS;
   }

   this.savePosition = function(position, address)
   {
      if (!_db)
      {
         console.log('The database is null. Unable to save position');
         navigator.notification.alert(
            'Unable to save position',
            function(){},
            'Error'
         );
      }

      var positions = this.getPositions();
      if (positions == null)
         positions = [];

      positions.unshift(new Position(position, address, new Date()));
      // Only the top MAX_POSITIONS results are needed
      if (positions.length > this.MAX_POSITIONS)
         positions = positions.slice(0, this.MAX_POSITIONS);

      _db.setItem('positions', JSON.stringify(positions));

      return positions;
   }

   this.updatePosition = function(index, position, address)
   {
      if (!_db)
      {
         console.log('The database is null. Unable to update position');
         navigator.notification.alert(
            'Unable to update position',
            function(){},
            'Error'
         );
      }

      var positions = this.getPositions();
      if (positions != null && positions[index] != undefined)
      {
         positions[index].coords = position;
         positions[index].address = address;
      }

      _db.setItem('positions', JSON.stringify(positions));

      return positions;
   }

   this.deletePosition = function(index)
   {
      if (!_db)
      {
         console.log('The database is null. Unable to delete position');
         navigator.notification.alert(
            'Unable to delete position',
            function(){},
            'Error'
         );
      }

      var positions = this.getPositions();
      if (positions != null && positions[index] != undefined)
         positions.splice(index, 1);

      _db.setItem('positions', JSON.stringify(positions));

      return positions;
   }

   this.getPositions = function()
   {
      if (!_db)
      {
         console.log('The database is null. Unable to retrieve positions');
         navigator.notification.alert(
            'Unable to retrieve positions',
            function(){},
            'Error'
         );
      }

      var positions = JSON.parse(_db.getItem('positions'));
      if (positions == null)
         positions = [];

      return positions;
   }

}

function Coords(latitude, longitude, accuracy)
{
   this.latitude = latitude;
   this.longitude = longitude;
   this.accuracy = accuracy;
}

style.css:

.ui-header .ui-title,
.ui-footer .ui-title,
.ui-btn-inner *
{
   white-space: normal !important;
}

.photo
{
   display: block;
   margin: 0px auto;
}

dl.informations dt
{
   font-weight: bold;
}

#map
{
   width: 100%;
   height: 600px;
}

Sorry for this amount of code, but I just can't convert a design and functionality from jQM to KendoUI Mobile.

Upvotes: 0

Views: 2046

Answers (1)

VicM
VicM

Reputation: 2479

Kendo initialization

You are missing the code bits that let kendo do its magic. I am assuming that you are using Kendo UI Mobile.

The following should be inserted before your closing body tag.

<script>
// Initialize a new Kendo Mobile Application
var app = new kendo.mobile.Application();
</script>

You can read the following doc with more related details: http://docs.kendoui.com/getting-started/introduction

Kendo Views

Also I noticed that you are not using any view. I am not sure what you want to achieve but tipically when using Kendo you should have a view that wraps the header, content and footer code.

View documentation: http://docs.kendoui.com/getting-started/mobile/view

I suggest reading the documentation stated above (if you haven´t already do so) and to try the examples first, and then start writing your code.

Snippet

<!-- Kendo Mobile View -->
<div data-role="view" data-title="View" id="index">
    <!--Kendo Mobile Header -->

On the other hand, it is difficult to check the full code working as it should be in the jsfiddle as you are not linking or copy pasting the CSS and JS files that you are stating in the code.

EDIT Regarding data source

I just skimmed your code but It seems you are not using the Kendo DataSource. Read the following document which explains how to bind data to your controls.

http://docs.kendoui.com/howto/use-the-datasource-component

http://docs.kendoui.com/getting-started/data-attribute-initialization

Bear in mind that jQM and Kendo UI mobile have very different approaches. Kendo uses a Model View ViewModel (MVVM) so a bit of work should be required to move the jquery - jQM code to Kendo, it is basically a matters of structure.

Again, before start playing with Kendo I strongly recommend reading the documentation. You could think you are wasting time, however reading the doc will save you tons of time and headaches.

Upvotes: 2

Related Questions