[Jifty-commit] r1189 - in jifty/trunk: lib/Jifty lib/Jifty/Web/Form lib/Jifty/Web/Form/Field share/web/static/js

jifty-commit at lists.jifty.org jifty-commit at lists.jifty.org
Wed Jun 7 18:06:49 EDT 2006


Author: alexmv
Date: Wed Jun  7 18:06:46 2006
New Revision: 1189

Modified:
   jifty/trunk/   (props changed)
   jifty/trunk/lib/Jifty/Action.pm
   jifty/trunk/lib/Jifty/Web.pm
   jifty/trunk/lib/Jifty/Web/Form/Clickable.pm
   jifty/trunk/lib/Jifty/Web/Form/Element.pm
   jifty/trunk/lib/Jifty/Web/Form/Field/Button.pm
   jifty/trunk/share/web/static/js/bps_util.js
   jifty/trunk/share/web/static/js/jifty.js

Log:
 r13634 at zoq-fot-pik:  chmrr | 2006-06-07 18:05:59 -0400
  * Buttons can render as links
  * onclick actions on buttons work with action arguments now
  * they also work with action registration in the button


Modified: jifty/trunk/lib/Jifty/Action.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Action.pm	(original)
+++ jifty/trunk/lib/Jifty/Action.pm	Wed Jun  7 18:06:46 2006
@@ -436,12 +436,16 @@
 sub button {
     my $self = shift;
     my %args = ( arguments => {},
-                 submit => $self,
+                 submit    => $self,
+                 register  => 0,
                  @_);
 
-    # Unless we've printed a moniker for the action, we embed the
-    # action registration into the button
-    unless ( Jifty->web->form->printed_actions->{ $self->moniker } ) {
+    if ($args{register}) {
+        # If they ask us to register the action, do so
+        Jifty->web->form->register_action( $self );
+        Jifty->web->form->print_action_registration($self->moniker);
+    } elsif ( not Jifty->web->form->printed_actions->{ $self->moniker } ) {
+        # Otherwise, if we're not registered yet, do it in the button
         $args{parameters}{ $self->register_name } = ref $self;
         $args{parameters}{ $self->double_fallback_form_field_name($_) }
             = $self->argument_value($_) || $self->arguments->{$_}->{'default_value'}

Modified: jifty/trunk/lib/Jifty/Web.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web.pm	(original)
+++ jifty/trunk/lib/Jifty/Web.pm	Wed Jun  7 18:06:46 2006
@@ -332,6 +332,11 @@
 requested action but not in the C<PARAMHASH> list are set.  This
 implements "sticky fields".
 
+As a contrast to L<Jifty::Web::Form/add_action>, this does not add the
+action to the current form -- instead, the first form field to be
+rendered will automatically register the action in the current form
+field at that time.
+
 =cut
 
 sub new_action {

Modified: jifty/trunk/lib/Jifty/Web/Form/Clickable.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Clickable.pm	(original)
+++ jifty/trunk/lib/Jifty/Web/Form/Clickable.pm	Wed Jun  7 18:06:46 2006
@@ -25,10 +25,10 @@
 
 sub accessors {
     shift->SUPER::accessors,
-        qw(url escape_label tooltip continuation call returns submit preserve_state button);
+        qw(url escape_label tooltip continuation call returns submit preserve_state render_as_button render_as_link);
 }
 __PACKAGE__->mk_accessors(
-    qw(url escape_label tooltip continuation call returns submit preserve_state button)
+    qw(url escape_label tooltip continuation call returns submit preserve_state render_as_button render_as_link)
 );
 
 =head2 new PARAMHASH
@@ -97,15 +97,21 @@
 These will end up being submitted exactly like normal query
 parameters.
 
-=item button
+=item as_button
 
 By default, Jifty will attempt to make the clickable into a link
 rather than a button, if there are no actions to run on submit.
-Providing a true value for C<button> forces L<generate> to produce a
-L<Jifty::Web::Form::Clickable::InlineButton> instead of a
-L<Jifty::Web::Form::Link>.  Note that providing a false value will
-B<not> guarantee that you get a link, as a button may be necessary
-based on the presence of the L</submit> parameter.
+Providing a true value for C<as_button> forces L<generate> to produce
+a L<Jifty::Web::Form::Clickable::InlineButton> instead of a
+L<Jifty::Web::Form::Link>.
+
+=item as_link
+
+Attempt to rework a button into displaying as a link -- note that this
+only works in javascript browsers.  Supplying B<both> C<as_button> and
+C<as_link> will work, and not as perverse as it might sound at first
+-- it allows you to make any simple GET request into a POST request,
+while still appearing as a link (a GET request).
 
 =item Anything from L<Jifty::Web::Form::Element>
 
@@ -134,9 +140,12 @@
         submit         => [],
         preserve_state => 0,
         parameters     => {},
-        button         => 0,
+        as_button      => 0,
+        as_link        => 0,
         @_,
     );
+    $args{render_as_button} = delete $args{as_button};
+    $args{render_as_link}   = delete $args{as_link};
 
     $self->{parameters} = {};
 
@@ -465,6 +474,7 @@
             grep { defined $parameters{$_} } keys %parameters
     );
     $field->name( join '|', keys %{ $args{parameters} } );
+    $field->button_as_link($self->render_as_link);
 
     return $field;
 }
@@ -510,7 +520,7 @@
         }
     }
 
-    return ( ( not( $self->submit ) || @{ $self->submit } || $self->button )
+    return ( ( not( $self->submit ) || @{ $self->submit } || $self->render_as_button )
         ? $self->as_button(@_)
         : $self->as_link(@_) );
 }

Modified: jifty/trunk/lib/Jifty/Web/Form/Element.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Element.pm	(original)
+++ jifty/trunk/lib/Jifty/Web/Form/Element.pm	Wed Jun  7 18:06:46 2006
@@ -222,7 +222,11 @@
 
         my $string = join ";", (grep {not ref $_} (ref $value eq "ARRAY" ? @{$value} : ($value)));
         if (@fragments or @actions) {
-            my $update = "update( ". Jifty::JSON::objToJson( {actions => \@actions, fragments => \@fragments }, {singlequote => 1}) ." );";
+            # Uniqify action monikers
+            my %uniq;
+            @actions = grep {not $uniq{$_}++} @actions;
+
+            my $update = "update( ". Jifty::JSON::objToJson( {actions => \@actions, fragments => \@fragments }, {singlequote => 1}) .", this );";
             $string .= $self->javascript_preempt ? "return $update" : "$update; return true;";
         }
         $response .= qq| $trigger="$string"|;

Modified: jifty/trunk/lib/Jifty/Web/Form/Field/Button.pm
==============================================================================
--- jifty/trunk/lib/Jifty/Web/Form/Field/Button.pm	(original)
+++ jifty/trunk/lib/Jifty/Web/Form/Field/Button.pm	Wed Jun  7 18:06:46 2006
@@ -4,6 +4,17 @@
 package Jifty::Web::Form::Field::Button;
 
 use base qw/Jifty::Web::Form::Field/;
+__PACKAGE__->mk_accessors(qw/button_as_link/);
+
+=head2 accessors
+
+Provide the C<button_as_link> accessor (in addition to
+L<Jifty::Web::Form::Field>'s default accessors), which controls if the
+button is reworked in javascript to appear as a link.
+
+=cut
+
+sub accessors { shift->SUPER::accessors(), 'button_as_link' }
 
 =head2 render_widget
 
@@ -19,7 +30,8 @@
         'type="submit"',
         'name="' . $self->input_name . '" ',
         'value="' . _($self->label ). '"',
-        $self->_widget_class('button'),
+        'id="'. Jifty->web->serial . '"',
+        $self->_widget_class('button', ($self->button_as_link ? ("button_as_link") : ())),
         $self->javascript,
         ' />',
         "\n"

Modified: jifty/trunk/share/web/static/js/bps_util.js
==============================================================================
--- jifty/trunk/share/web/static/js/bps_util.js	(original)
+++ jifty/trunk/share/web/static/js/bps_util.js	Wed Jun  7 18:06:46 2006
@@ -38,6 +38,20 @@
     return false;
 }
 
+function buttonToLink(input) {
+    var e = $(input);
+    if (e) {
+        var link = document.createElement("a");
+        link.setAttribute("href","javascript:$('"+e.id+"').click()");
+        link.appendChild(document.createTextNode(e.getAttribute("value")));
+
+        Element.hide(e);
+        e.parentNode.insertBefore(link, e.nextSibling);
+        return true;
+    }
+    return false;
+}
+
 // onload handlers
 
 var onLoadStack     = new Array();

Modified: jifty/trunk/share/web/static/js/jifty.js
==============================================================================
--- jifty/trunk/share/web/static/js/jifty.js	(original)
+++ jifty/trunk/share/web/static/js/jifty.js	Wed Jun  7 18:06:46 2006
@@ -4,14 +4,23 @@
 /* Actions */
 var Action = Class.create();
 Action.prototype = {
-    // New takes the moniker, a string
+    // New takes the moniker (a string), and an optional array of form
+    // elements to additionally take into consideration
     initialize: function(moniker) {
         this.moniker = moniker;
 
+        // Extra form parameters
+        this.extras = $A();
+        if (arguments.length > 1) {
+            this.extras = arguments[1];
+        }
+
         this.register = $('J:A-' + this.moniker);  // Simple case -- no ordering information
         if (! this.register) {
-            // We need to go looking
-            var elements = document.getElementsByTagName('input');
+            // We need to go looking -- this also goes looking through this.extras, from above
+            var elements = $A(document.getElementsByTagName('input'));
+            for (var i = 0; i < this.extras.length; i++)
+                elements.push(this.extras[i]);
             for (var i = 0; i < elements.length; i++) {
                 if ((Form.Element.getMoniker(elements[i]) == this.moniker)
                  && (Form.Element.getType(elements[i]) == "registration")) {
@@ -31,6 +40,9 @@
     fields: function() {
         var elements = new Array;
         var possible = Form.getElements(this.form);
+        // Also pull from extra query parameters
+        for (var i = 0; i < this.extras.length; i++)
+            possible.push(this.extras[i]);
 
         for (var i = 0; i < possible.length; i++) {
             if (Form.Element.getMoniker(possible[i]) == this.moniker)
@@ -250,6 +262,9 @@
     getForm: function (element) {
         element = $(element);
 
+        if (element.virtualform)
+            return element.virtualform;
+
         if (element.form)
             return element.form;
 
@@ -260,7 +275,40 @@
             }
         }
         return null;
+    },
+
+    buttonArguments: function(element) {
+        element = $(element);
+        if (!element || (element.nodeName != 'INPUT') || (element.getAttribute("type") != "submit"))
+            return $H();
+        var extras = $H();
+
+        // Split other arguments out, if we're on a button
+        var pairs = element.getAttribute("name").split("|");
+        for (var i = 0; i < pairs.length; i++) {
+            var bits = pairs[i].split('=',2);
+            extras[bits[0]] = bits[1];
+        }
+        return extras;
+    },
+
+    buttonFormElements: function(element) {
+        element = $(element);
+
+        var extras = $A();
+        var args = Form.Element.buttonArguments(element);
+        var keys = args.keys();
+        for (var i = 0; i < keys.length; i++) {
+            var e = document.createElement("input");
+            e.setAttribute("type", "hidden");
+            e.setAttribute("name", keys[i]);
+            e.setAttribute("value", args[keys[i]]);
+            e['virtualform'] = element.form;
+            extras.push(e);
+        }
+        return extras;
     }
+
 });
 
 // Form elements should AJAX validate if the CSS says so
@@ -271,9 +319,15 @@
         } 
     },
     'input.date': function(e) {
-        if ( !Element.hasClassName( e, 'has-calendar-link' ) ) {
+        if ( !Element.hasClassName( e, 'has_calendar_link' ) ) {
             createCalendarLink(e);
-            Element.addClassName( e, 'has-calendar-link' );
+            Element.addClassName( e, 'has_calendar_link' );
+        }
+    },
+    'input.button_as_link': function(e) {
+        if ( !Element.hasClassName( e, 'is_button_as_link' ) ) {
+            buttonToLink(e);
+            Element.addClassName( e, 'is_button_as_link' );
         }
     }
 });
@@ -395,6 +449,7 @@
 function update() {
     show_wait_message();
     var named_args = arguments[0];
+    var trigger    = arguments[1];
 
     // The YAML/JSON data structure that will be sent
     var request = $H();
@@ -402,11 +457,14 @@
     // Set request base path
     request['path'] = '/__jifty/webservices/xml';
 
+    // Grab extra arguments (from a button)
+    var button_args = Form.Element.buttonFormElements(trigger);
+
     // Build actions structure
     request['actions'] = {};
     for (var i = 0; i < named_args['actions'].length; i++) {
         var moniker = named_args['actions'][i];
-        var a = new Action(moniker);
+        var a = new Action(moniker, button_args);
         a.disable_input_fields();
         if (a.register) {
             if (a.hasUpload())


More information about the Jifty-commit mailing list