]> err.no Git - sope/blob - sope-appserver/WEPrototype/WELiveLink.m
started WEPrototype library
[sope] / sope-appserver / WEPrototype / WELiveLink.m
1 /*
2   Copyright (C) 2005 Helge Hess
3
4   This file is part of SOPE.
5
6   SOPE is free software; you can redistribute it and/or modify it under
7   the terms of the GNU Lesser General Public License as published by the
8   Free Software Foundation; either version 2, or (at your option) any
9   later version.
10
11   SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12   WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
14   License for more details.
15
16   You should have received a copy of the GNU Lesser General Public
17   License along with SOPE; see the file COPYING.  If not, write to the
18   Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19   02111-1307, USA.
20 */
21
22 #import <NGObjWeb/WODynamicElement.h>
23
24 /*
25   WELiveLink
26
27   Inspired by the link_to_remote() RoR function.
28 */
29
30 @interface WELiveLink : WODynamicElement
31 {
32   WOAssociation *string;
33   WOAssociation *updateID;
34   WOAssociation *position;
35   
36   WOAssociation *actionClass;
37   WOAssociation *directActionName;
38   WOAssociation *href;
39   
40   WOAssociation *confirmText;
41   
42   WOElement *template;
43 }
44
45 @end
46
47 #include "WEPrototypeScript.h"
48 #include "common.h"
49
50 @implementation WELiveLink
51
52 - (id)initWithName:(NSString *)_name
53   associations:(NSDictionary *)_config
54   template:(WOElement *)_tmp
55 {
56   if ((self = [super initWithName:_name associations:_config template:_tmp])) {
57     self->template = [_tmp retain];
58     
59     self->string           = WEPExtGetProperty(_config, @"string");
60     self->updateID         = WEPExtGetProperty(_config, @"updateID");
61     self->position         = WEPExtGetProperty(_config, @"position");
62     self->actionClass      = WEPExtGetProperty(_config, @"actionClass");
63     self->directActionName = WEPExtGetProperty(_config, @"directActionName");
64     self->href             = WEPExtGetProperty(_config, @"href");
65     self->confirmText      = WEPExtGetProperty(_config, @"confirmText");
66   }
67   return self;
68 }
69
70 - (void)dealloc {
71   [self->updateID         release];
72   [self->position         release];
73   [self->actionClass      release];
74   [self->directActionName release];
75   [self->href             release];
76   [self->confirmText      release];
77   [self->string           release];
78   [self->template         release];
79   [super dealloc];
80 }
81
82 /* generating response */
83
84 - (NSString *)linkInContext:(WOContext *)_ctx {
85   if (self->directActionName != nil) {
86     NSString *ac, *da;
87     
88     ac = [self->actionClass      stringValueInComponent:[_ctx component]];
89     da = [self->directActionName stringValueInComponent:[_ctx component]];
90
91     if ([ac length] > 0)
92       da = [[ac stringByAppendingString:@"/"] stringByAppendingString:da];
93     
94     return [_ctx directActionURLForActionNamed:da queryDictionary:nil];
95   }
96   
97   if (self->href != nil)
98     return [self->href stringValueInComponent:[_ctx component]];
99   
100   [self logWithFormat:@"ERROR: no binding for link!"];
101   return nil;
102 }
103
104 - (void)appendJavaScriptToResponse:(WOResponse *)_response
105   inContext:(WOContext *)_ctx
106 {
107   /*
108     new Ajax.Updater('time_div', 
109                      '/hello_world/say_when', 
110                      {insertion:Insertion.After, asynchronous:true}); 
111     return false;
112   */
113   WOComponent *sComponent;
114   NSString *s;
115   BOOL     closeBracket = NO, isDOM = NO;
116   
117   sComponent = [_ctx component];
118   
119   /* check for confirm panel */
120   
121   s = [self->confirmText stringValueInComponent:sComponent];
122   if ([s length] > 0) {
123     [_response appendContentString:@"if (confirm('"];
124     [_response appendContentHTMLAttributeValue:s];
125     [_response appendContentString:@"')) { "];
126     closeBracket = YES;
127   }
128   
129   /* whether to update an element */
130   
131   s = [self->updateID stringValueInComponent:sComponent];
132   if ([s length] > 0) {
133     [_response appendContentString:@"new Ajax.Updater('"];
134     [_response appendContentHTMLAttributeValue:s];
135     [_response appendContentString:@"', '"];
136     isDOM = YES;
137   }
138   else {
139     [_response appendContentString:@"new Ajax.Request('"];
140   }
141   
142   /* Link */
143   
144   if ((s = [self linkInContext:_ctx]) != nil)
145     [_response appendContentHTMLAttributeValue:s];
146   [_response appendContentString:@"'"];
147   
148   /* parameters */
149
150   [_response appendContentString:@", {"];
151   
152   if (isDOM) {
153     s = [self->position stringValueInComponent:sComponent];
154     if ([s length] > 0) {
155       [_response appendContentString:@"insertion: Insertion."];
156       [_response appendContentString:[s capitalizedString]];
157       [_response appendContentString:@", "];
158     }
159   }
160   
161   [_response appendContentString:@"asynchronous: true }"];
162   
163   /* close function */
164   
165   [_response appendContentString:@");"];
166   
167   /* close confirm panel if */
168   
169   if (closeBracket) [_response appendContentString:@"}"];
170   
171   /* always: do not follow link target */
172   [_response appendContentString:@" return false;"];
173 }
174
175 - (void)appendToResponse:(WOResponse *)_response inContext:(WOContext *)_ctx {
176   NSString *s;
177   
178   /* first ensure that prototype is loaded */
179   [WEPrototypeScript appendToResponse:_response inContext:_ctx];
180   
181   /* start link tag */
182   
183   [_response appendContentString:@"<a href=\"#\" onclick=\""];
184   
185   /* generate JavaScript */
186
187   [self appendJavaScriptToResponse:_response inContext:_ctx];
188   
189   /* finish link start tag */
190   
191   [_response appendContentString:@"\""];
192   
193   [self appendExtraAttributesToResponse:_response inContext:_ctx];
194   if (self->otherTagString != nil) {
195     [_response appendContentString:@" "];
196     s = [self->otherTagString stringValueInComponent:[_ctx component]];
197     [_response appendContentString:s];
198   }
199   [_response appendContentString:@">"];
200   
201   /* generate content */
202   
203   if ((s = [self->string stringValueInComponent:[_ctx component]]) != nil)
204     [_response appendContentHTMLString:s];
205   
206   [self->template appendToResponse:_response inContext:_ctx];
207   
208   /* close anker */
209   [_response appendContentString:@"</a>"];
210 }
211
212 @end /* WELiveLink */