[Jifty-commit] r3637 - in jifty/trunk: lib/Jifty/Action lib/Jifty/Plugin lib/Jifty/Plugin/GoogleMap share/web/static/js

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Mon Jul 9 19:37:52 EDT 2007


Author: clkao
Date: Mon Jul  9 19:37:52 2007
New Revision: 3637

Added:
   jifty/trunk/lib/Jifty/Plugin/GoogleMap/
   jifty/trunk/lib/Jifty/Plugin/GoogleMap.pm
   jifty/trunk/lib/Jifty/Plugin/GoogleMap/Widget.pm
   jifty/trunk/share/web/static/js/google_map.js
Modified:
   jifty/trunk/lib/Jifty/Action/Record.pm
   jifty/trunk/lib/Jifty/Web/Form/Field.pm

Log:
First cut of GoogleMap plugin.  You can now declare a column
as geolocation, and you'll be able to display and edit it
with a google map widget.


Modified: jifty/trunk/lib/Jifty/Action/Record.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Action/Record.pm	(original)
+++ jifty/trunk/lib/Jifty/Action/Record.pm	Mon Jul  9 19:37:52 2007
@@ -309,7 +309,7 @@
             }
 
             # If we're hand-coding a render_as, hints or label, let's use it.
-            for (qw(render_as label hints max_length mandatory sort_order)) {
+            for (qw(render_as label hints max_length mandatory sort_order container)) {
 
                 if ( defined (my $val = $column->$_) ) {
                     $info->{$_} = $val;

Added: jifty/trunk/lib/Jifty/Plugin/GoogleMap.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/GoogleMap.pm	Mon Jul  9 19:37:52 2007
@@ -0,0 +1,81 @@
+use strict;
+use warnings;
+
+package Jifty::Plugin::GoogleMap;
+use base qw/Jifty::Plugin Class::Accessor::Fast/;
+
+
+=head1 NAME
+
+Jifty::Plugin::GoogleMap
+
+=head1 SYNOPSIS
+
+# In your jifty config.yml under the framework section:
+
+  Plugins:
+    - GoogleMap:
+        apikey: ABQIAAAA66LEkTHjdh-UhDZ_NkfdjBTb-vLQlFZmc2N8bgWI8YDPp5FEVBTjCfxPSocuJ53SPMNQDO7Sywpp_w
+
+# note that this is an api for http://localhost:8888/
+
+=head1 DESCRIPTION
+
+This plugin provides auto-compilation and on-wire compression of your
+application's CSS and Javascript. It is enabled by default, unless
+your C<ConfigFileVersion> is greater or equal than 2.
+
+It also supports js minifier, you will need to specify the full path.
+The jsmin can be obtained from
+L<http://www.crockford.com/javascript/jsmin.html>.
+
+Note that you will need to use C<ConfigFileVersion> 2 to be able to
+configure jsmin feature.
+
+=cut
+
+__PACKAGE__->mk_accessors(qw(apikey));
+
+=head2 init
+
+Initializes the compression object. Takes a paramhash containing keys
+'css' and 'js' which can be used to disable compression on files of
+that type.
+
+=cut
+
+sub init {
+    my $self = shift;
+    my %opt  = @_;
+    $self->apikey( $opt{apikey} );
+    Jifty->web->external_javascript_libs(["http://maps.google.com/maps?file=api&v=2&key=".$self->apikey]);
+    Jifty->web->add_javascript(qw( google_map.js ) );
+}
+
+sub _geolocation {
+    my ($column, $from) = @_;
+    my $name = $column->name;
+    $column->virtual(1);
+    $column->container(1);
+    for (qw(x y)) {
+        Jifty::DBI::Schema::_init_column_for(
+            Jifty::DBI::Column->new({ type => 'double',
+                                      name => $name."_$_",
+                                      render_as => 'hidden',
+                                      writable => $column->writable,
+                                      readable => $column->readable }),
+            $from);
+    }
+    no strict 'refs';
+    *{$from.'::'.$name} = sub { return { map { my $method = "${name}_$_"; $_ => $_[0]->$method } qw(x y) } };
+    *{$from.'::'.'set_'.$name} = sub { die "not yet" };
+}
+
+use Jifty::DBI::Schema;
+Jifty::DBI::Schema->register_types(
+    GeoLocation =>
+        sub { _init_handler is \&_geolocation, render_as 'Jifty::Plugin::GoogleMap::Widget' },
+);
+
+
+1;

Added: jifty/trunk/lib/Jifty/Plugin/GoogleMap/Widget.pm
==============================================================================
--- (empty file)
+++ jifty/trunk/lib/Jifty/Plugin/GoogleMap/Widget.pm	Mon Jul  9 19:37:52 2007
@@ -0,0 +1,98 @@
+use warnings;
+use strict;
+ 
+package Jifty::Plugin::GoogleMap::Widget;
+
+use base qw/Jifty::Web::Form::Field/;
+
+=head1 NAME
+
+Jifty::Plugin::GoogleMap::Widget - google map widget for geolocation display and editing
+
+=head1 METHODS
+
+
+=cut
+
+sub accessors { shift->SUPER::accessors() };
+
+=head2 render_widget
+
+Renders form fields as googlemap widget.
+
+=cut
+
+# XXX: doesn't work
+#use Template::Declare;
+#use Template::Declare::Tags;
+
+sub render_widget {
+    my $self  = shift;
+
+    my $action = $self->action;
+
+    my ($x, $y) = map { $action->form_field($self->name . "_$_")->current_value } qw( x y );
+    my ($xid, $yid) = map { $action->form_field($self->name . "_$_")->element_id } qw( x y );
+    my $use_default = defined $x ? 0 : 1;
+    ($x, $y) = (-71.2, 42.4) if $use_default;
+    my $zoom_level = $use_default ? 1 : 13;
+
+    Jifty->web->out(qq{<div @{[$self->_widget_class]} id="@{[$self->element_id]}" style="left: 200px; width: 200px; height: 200px"></div>});
+    Jifty->web->out(qq{<script type="text/javascript">
+(function() {
+if (GBrowserIsCompatible()) {
+         var map = new GMap2(document.getElementById("@{[$self->element_id]}"));
+         map.enableScrollWheelZoom();
+         map.addControl(new GSmallZoomControl());
+         map.addControl(new EditLocationControl());
+         map.setCenter(new GLatLng($y, $x), $zoom_level);
+         map._jifty_form_x = "$xid";
+         map._jifty_form_y = "$yid";
+         if (!$use_default) {// XXX should be compile time
+           map._jifty_location = new GMarker(new GLatLng($y, $x));
+           map.addOverlay(map._jifty_location);
+         }
+GEvent.addListener(map, "click", function(marker, point) {
+  if (!marker && map._jifty_edit_control.editing) {
+    map.removeOverlay(map._jifty_location);
+    map._jifty_location = new GMarker(point)
+    map.addOverlay(map._jifty_location);
+  }
+
+});
+      }
+})()
+</script>
+});
+
+
+    return '';
+    Template::Declare->new_buffer_frame;
+
+    div { { id is $self->element_id, style is "width: 200px; height: 200px" } };
+    outs('hi');
+    script { { type is "text/javascript" };
+      qq{if (GBrowserIsCompatible()) {
+         var map = new GMap2(document.getElementById("@{[$self->element_id]}"));
+         map.setCenter(new GLatLng(37.4419, -122.1419), 13);
+      }}
+    };
+
+warn "-----------_".Template::Declare->buffer->data;
+    Jifty->web->out(Template::Declare->buffer->data);
+    Template::Declare->end_buffer_frame;
+    return '';
+}
+
+=head2 render_value
+
+Renders value as a checkbox widget.
+
+=cut
+
+sub render_value {
+    $_->render_widget;
+    return '';
+}
+
+1;

Modified: jifty/trunk/lib/Jifty/Web/Form/Field.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Field.pm	(original)
+++ jifty/trunk/lib/Jifty/Web/Form/Field.pm	Mon Jul  9 19:37:52 2007
@@ -79,8 +79,10 @@
 
     # If they key and/or value imply that this argument is going to be
     # a mapped argument, then do the mapping and mark the field as hidden.
+    # but ignore that if the field is a container in the model
     my ($key, $value) = Jifty::Request::Mapper->query_parameters($self->input_name, $self->current_value);
-    if ($key ne $self->input_name) {
+    warn "$key vs ".$self->input_name;
+    if ($key ne $self->input_name && !$self->action->arguments->{$self->name}{container}) {
         Jifty::Util->require('Jifty::Web::Form::Field::Hidden');
         bless $self, "Jifty::Web::Form::Field::Hidden";
         $self->input_name($key);

Added: jifty/trunk/share/web/static/js/google_map.js
==============================================================================
--- (empty file)
+++ jifty/trunk/share/web/static/js/google_map.js	Mon Jul  9 19:37:52 2007
@@ -0,0 +1,58 @@
+// XXX: move me to Plugin/GoogleMap's share when that works
+
+if (GMap2) {
+    //document.body.onunload = "GUnload()";
+
+function EditLocationControl() {
+}
+EditLocationControl.prototype = new GControl();
+
+
+EditLocationControl.prototype.initialize = function(map) {
+  var container = document.createElement("div");
+
+  var EditDiv = document.createElement("div");
+  this.setButtonStyle_(EditDiv);
+  container.appendChild(EditDiv);
+  EditDiv.appendChild(document.createTextNode("Edit"));
+  var editctl = this;
+  GEvent.addDomListener(EditDiv, "click", function() {
+    if (editctl.editing) {
+        var point = map._jifty_location.getPoint();
+	$(map._jifty_form_x).value = point.lng()
+	$(map._jifty_form_y).value = point.lat()
+	EditDiv.innerHTML = "Edit";
+    }
+    else {
+	EditDiv.innerHTML = "Done";
+	editctl.editing = true;
+    }
+  });
+
+  map.getContainer().appendChild(container);
+  map._jifty_edit_control = this;
+  this.editing = false;
+  return container;
+}
+
+
+EditLocationControl.prototype.getDefaultPosition = function() {
+  return new GControlPosition(G_ANCHOR_BOTTOM_RIGHT, new GSize(7, 7));
+}
+
+EditLocationControl.prototype.setButtonStyle_ = function(button) {
+  button.style.textDecoration = "underline";
+  button.style.color = "#0000cc";
+  button.style.backgroundColor = "white";
+  button.style.font = "small Arial";
+  button.style.fontSize = "0.8em";
+  button.style.border = "1px solid black";
+  button.style.padding = "2px";
+  button.style.marginBottom = "3px";
+  button.style.textAlign = "center";
+  button.style.width = "4em";
+  button.style.cursor = "pointer";
+}
+
+
+}


More information about the Jifty-commit mailing list