Revision ccd822a8

b/invitations/invitations.py
1 1
from django import forms
2 2
from django.conf import settings
3 3
from django.db import transaction
4
from django.forms.util import ErrorList
4 5
from django.http import HttpResponse, HttpResponseRedirect
5 6
from django.shortcuts import render_to_response
7
from django.template import Template
8
from django.template.context import Context, RequestContext
6 9
from django.template.loader import render_to_string
7 10
from synnefo.api.common import method_not_allowed
8 11
from synnefo.db.models import Invitations, SynnefoUser
9 12
from synnefo.logic import users
10 13

  
11 14
class InvitationForm(forms.Form):
12
    emails = forms.Textarea
13

  
14
    def send_emails(self, request):
15
        if request.method == 'POST': # If the form has been submitted...
16
            form = InvitationForm(request.POST) # A form bound to the POST data
17
            if form.is_valid(): # All validation rules pass
18
                # Process the data in form.cleaned_data
19
                # ...
20
                return HttpResponseRedirect('/thanks/') # Redirect after POST
21
        else:
22
            form = InvitationForm() # An unbound form
15
    name = forms.CharField(required=True)
16
    email = forms.EmailField(required=True)
17

  
18
def send_emails(request):
19
    if request.method == 'POST':
20
        form = InvitationForm(request.POST)
21
        if form.is_valid():
22
            # Process the data in form.cleaned_data
23
            return HttpResponseRedirect('/invitation/')
24
    else:
25
        form = InvitationForm() # An unbound form
23 26

  
24
        return render_to_response('invitation.html', {'form': form,})
27
    return render_to_response('invitations.html', {'form': form,})
25 28

  
26 29
def inv_demux(request):
27 30
    if request.method == 'GET':
28 31
        invitations = Invitations.objects.filter(source = request.user)
29
        data = render_to_string('invitations.html', {'invitations': invitations})
32
        form = InvitationForm()
33
        data = render_to_string('invitations.html', {'invitations': invitations, 'form':form})
30 34
        return  HttpResponse(data)
31 35
    elif request.method == 'POST':
32
        f = InvitationForm(request)
36
        return send_emails(request)
33 37
    else:
34 38
        method_not_allowed(request)
35 39

  
b/invitations/templates/invitations.html
4 4
<head>
5 5
    <title>Αποστολή προσκλήσεων σε χρήστες</title>
6 6
    <script src="/static/jquery.tools.min.js"></script>
7

  
7
    <script src="/static/jquery.dynamicField.js"></script>
8 8
    <script type="text/javascript">
9 9

  
10 10
    $(document).ready(function() {
11
        $("#emaillist").click(function(){
12
            $("#emaillist").text('');
13
        });
11
         $("#invform #removable-name-container-1").dynamicField();
14 12
    });
15 13

  
16 14
    </script>
17 15

  
18 16
    <style type="text/css">
19
        
17

  
20 18
    </style>
21 19
</head>
22 20
<body>
23
{% if error_message %}<div id="error"><strong>{{ error_message }}</strong></div>{% endif %}
24

  
25
<form id="" action="/invitations/" method="post">
26
{% csrf_token %}
27
        <label for="emaillist">Email για αποστολή προσκλήσεων (διαθέσιμες: 
28
            <span id="remaining">{{ invitations.count }}</span>
29
            )
30
        </label>
31
        <textarea id="emaillist" rows="24" cols="80">
32
Εισάγετε τη λίστα των διευθύνσεων email στις οποίες θέλετε να αποσταλούν προσκλήσεις, μια σε κάθε γραμμή.
33
Οι διευθύνσεις θα πρέπει να είναι στη μορφή: Όνομα Επίθετο <uname@domain.tld>, για παράδειγμα:
34

  
35
Donald Knuth <knuth@stanford.edu>
36
Dennis Ritchie <drm@bell.com>
37

  
38
        </textarea>
39
        <br/>
40
        <input type="submit" value="Αποστολή Προσκλήσεων" />
21
<form action="/invitation/" method="post" id="invform">
22
    {% csrf_token %}
23
    <div id="fieldheaders">
24
        <span id="field_name_name">Όνομα</span>
25
        <span id="field_email_name">Email</span>
26
    </div>
27
    <div id="fields">
28
        <div id="removable-name-container-1" class="removable-field-row">
29
            <label for="name_1">Name</label>
30
            <input type="text" name="name_1" id="name_1" value="" class="textInput removable" />
31
            <label for="email_1">Email</label>
32
            <input type="text" name="email_1" id="email_1" value="" class="textInput removable" />
33
            <img src="/static/spacer.gif" width="16" height="16" alt="" title="Remove This Item" class="" />
34
        </div>
35

  
36
        <div id="add-name-container" class="add-field-container">
37
        <span class="add-field-trigger">
38
            <img src="/static/add.gif" alt="" title="Add New Item" />
39
            Add Row
40
        </span>
41
        </div>
42
    </div>
43
    <p><input type="submit" value="Αποστολή Προσκλήσεων" /></p>
41 44
</form>
42 45

  
43 46
<div id="invsent">
b/invitations/urls.py
2 2

  
3 3

  
4 4
urlpatterns = patterns('synnefo.invitations.invitations',
5
    (r'^$', 'inv_demux')
5
    (r'^$', 'inv_demux'),
6
    (r'^/$', 'inv_demux'),
6 7
)
b/ui/static/jquery.dynamicField.js
1
/*
2
*	jQuery dynamicField plugin
3
*	Copyright 2009, Matt Quackenbush (http://www.quackfuzed.com/)
4
*
5
*	Find usage demos at http://www.quackfuzed.com/demos/jQuery/dynamicField/index.cfm)
6
*
7
*	Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
8
*	and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
9
*
10
*	Version: 1.0
11
*	Date:	 8/13/2009
12
*/
13
;(function($) {
14
	$.fn.dynamicField = function(options) {
15
		if ( $(this).attr("id") == undefined ) {
16
			alert("The dynamicField plugin could not be initialized.\n\nPlease check the selector.");
17
			return $;
18
		}
19
		
20
		var f = $(this);
21
		
22
		var settings = $.extend({
23
			maxFields: 5,
24
			removeImgSrc: "/static/cross.png",
25
			spacerImgSrc: "/static/spacer.gif",
26
			addTriggerClass: "add-field-trigger",
27
			removeImgClass: "remove-field-trigger",
28
			hideClass: "hide",
29
			cloneContainerId: f.attr("id").replace(/^(.+)([_-][0-9]+)$/,"$1"),
30
			rowContainerClass: f.attr("class"),
31
			labelText: f.children("label")
32
							.html(),
33
			baseName: f.children("input")
34
								.attr("name")
35
								.replace(/^(.+[_-])([0-9]+)$/,"$1"),
36
            baseNames: baseNames(),
37
			addContainerId: "add-" + f.children("input")
38
								.attr("name")
39
								.replace(/^(.+)([_-][0-9]+)$/,"$1")
40
								.replace(/_/g,"-") + "-container"
41
		},options);
42
		
43
		var getFields = function() {
44
			return $("div." + settings.rowContainerClass);
45
		};
46

  
47
        function baseNames() {
48
            var names = new Array();
49
            $.each(f.children("input"), function(index, child){
50
                var name = child.name.replace(/^(.+[_-])([0-9]+)$/,"$1")
51
                names.push(name);
52
            });
53
            return names;
54
        }
55
		
56
		// handle hide/show, etc
57
		var addRemoveBtnCk = function() {
58
			var fields = getFields();
59
			var len = fields.length;
60
			
61
			fields.each(function(i,elem) {
62
				$(elem)
63
					.children("img")
64
					.attr({
65
						"src":(len == 1) ? settings.spacerImgSrc : settings.removeImgSrc,
66
						"class":(len == 1) ? "" : settings.removeImgClass
67
					});
68
			});
69
			
70
			if ( len > (settings.maxFields-1) ) {
71
				$("div#" + settings.addContainerId).addClass(settings.hideClass);
72
			} else {
73
				$("div#" + settings.addContainerId).removeClass(settings.hideClass);
74
			}
75
		};
76
		
77
		// handle field removal
78
		$("img." + settings.removeImgClass).live("click",function() {
79
			// remove the selected row
80
			$(this).parent("div." + settings.rowContainerClass).remove();
81
			
82
			// rebrand the remaining fields sequentially
83
			getFields().each(function(i,elem) {
84
				var pos = new Number(i+1);
85
				var d = $(elem)
86
							.attr("id",settings.cloneContainerId + "-" + pos);
87
				
88
				d.children("label")
89
							.attr("for",settings.baseName + pos)
90
							.html((pos > 1) ? "" : settings.labelText);
91
				
92
				d.children("input")
93
							.attr({
94
								"id":settings.baseName + pos,
95
								"name":settings.baseName + pos
96
							});
97
			});
98
			
99
			addRemoveBtnCk();
100
		});
101
		
102
		// handle field add
103
		$("div#" + settings.addContainerId + " span." + settings.addTriggerClass).click(function() {
104
			var len = getFields().length;
105
			var pos = new Number(len+1);
106
			var newDiv = f
107
							.clone()
108
							.attr("id",settings.cloneContainerId + "-" + pos)
109
							.addClass(settings.rowContainerClass);
110
			
111
			newDiv.children("label")
112
							.attr("for",settings.baseName + pos)
113
							.html("");
114
			
115
			newDiv.children("input")
116
							.attr({
117
								"id":settings.baseName + pos,
118
								"name":settings.baseName + pos,
119
								"value":""
120
							});
121
			
122
			newDiv.children("img")
123
							.attr("src",settings.removeImgSrc);
124
			
125
			if ( len > 0 ) {
126
				$("div#" + settings.cloneContainerId + "-" + len).after(newDiv);
127
			} else {
128
				$("div#" + settings.addContainerId).before(newDiv);
129
			}
130
			
131
			addRemoveBtnCk();
132
		});
133
	};
134
})(jQuery);

Also available in: Unified diff