marcus-h
7/15/2013 - 9:41 PM

AngularJS and Drupal example Details at https://www.lullabot.com/blog/article/move-logic-front-end-angularjs

<?php
/**
 * @file
 * AngularJS template to render a weather block.
 */
?>
<div ng-controller="MyModuleWeather">
  <label for="city">City</label>
  <input type="text" ng-model="city" /></br>
  <label for="units">Units</label>
  <input type="radio" ng-model="units" value="metric"/> Metric
  <input type="radio" ng-model="units" value="imperial"/> Imperial</br>
  <button ng-click="change()">Change</button>
  <h3>{{data.name}}</h3>
  <p>{{description}}</p>
  <p>Temperature: {{main.temp}}</p>
  <p>Wind speed: {{wind.speed}}</p>
</div>
<?php
/**
 * @file mymodule.module
 *
 * Implements an AngularJS-driven block.
 */

/**
 * Implements hook_block_info().
 */
function mymodule_block_info() {
  $blocks['weather'] = array(
    'info' => t('Weather'),
  );

  return $blocks;
}

/**
 * Implements hook_block_view().
 */
function mymodule_block_view($delta = '') {
  $block = array();

  switch ($delta) {
    case 'weather':
      $path = drupal_get_path('module', 'mymodule');
      $block['subject'] = t('Weather status');
      $block['content'] = array(
        '#theme' => 'weather_status',
        '#attached' => array(
          'js' => array(
            'https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js',
            $path . '/mymodule.js',
          ),
        ),
      );
      break;
  }
  return $block;
}

/**
 * Implements hook_theme().
 */
function mymodule_theme() {
  return array(
    'weather_status' => array(
      'template' => 'weather-status',
      'variables' => array(),
    ),
  );
}
/**
 * Renders the weather status for a city.
 */
var app = angular.module('myapp', [])
.controller('MyModuleWeather', function($scope, $http, $log) {
  // Set default values for our form fields.
  $scope.city = 'Madrid';
  $scope.units = 'metric';

  // Define a function to process form submission.
  $scope.change = function() {
    // Fetch the data from the public API through JSONP.
    // See http://openweathermap.org/API#weather.
    var url = 'http://api.openweathermap.org/data/2.5/weather';
    $http.jsonp(url, { params : {
        q : $scope.city,
        units : $scope.units,
        callback: 'JSON_CALLBACK'
      }}).
      success(function(data, status, headers, config) {
        $scope.main = data.main;
        $scope.wind = data.wind;
        $scope.description = data.weather[0].description;
      }).
      error(function(data, status, headers, config) {
        // Log an error in the browser's console.
        $log.error('Could not retrieve data from ' + url);
      });
  };

  // Trigger form submission for first load.
  $scope.change();
});
name = My module
description = Implements an AngularJS-driven block
core = 7.x
<?php

/**
 * @file
 * Default theme implementation to display the basic html structure of a single
 * Drupal page.
 *
 * Variables:
 * - $css: An array of CSS files for the current page.
 * - $language: (object) The language the site is being displayed in.
 *   $language->language contains its textual representation.
 *   $language->dir contains the language direction. It will either be 'ltr' or 'rtl'.
 * - $rdf_namespaces: All the RDF namespace prefixes used in the HTML document.
 * - $grddl_profile: A GRDDL profile allowing agents to extract the RDF data.
 * - $head_title: A modified version of the page title, for use in the TITLE
 *   tag.
 * - $head_title_array: (array) An associative array containing the string parts
 *   that were used to generate the $head_title variable, already prepared to be
 *   output as TITLE tag. The key/value pairs may contain one or more of the
 *   following, depending on conditions:
 *   - title: The title of the current page, if any.
 *   - name: The name of the site.
 *   - slogan: The slogan of the site, if any, and if there is no title.
 * - $head: Markup for the HEAD section (including meta tags, keyword tags, and
 *   so on).
 * - $styles: Style tags necessary to import all CSS files for the page.
 * - $scripts: Script tags necessary to load the JavaScript files and settings
 *   for the page.
 * - $page_top: Initial markup from any modules that have altered the
 *   page. This variable should always be output first, before all other dynamic
 *   content.
 * - $page: The rendered page content.
 * - $page_bottom: Final closing markup from any modules that have altered the
 *   page. This variable should always be output last, after all other dynamic
 *   content.
 * - $classes String of classes that can be used to style contextually through
 *   CSS.
 *
 * @see template_preprocess()
 * @see template_preprocess_html()
 * @see template_process()
 *
 * @ingroup themeable
 */
?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
  "http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html data-ng-app="myapp" xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>

<head profile="<?php print $grddl_profile; ?>">
  <?php print $head; ?>
  <title><?php print $head_title; ?></title>
  <?php print $styles; ?>
  <?php print $scripts; ?>
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
  <div id="skip-link">
    <a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
  </div>
  <?php print $page_top; ?>
  <?php print $page; ?>
  <?php print $page_bottom; ?>
</body>
</html>