##// END OF EJS Templates
Added TextBox submit event
Jonathan Frederic -
Show More
@@ -1,147 +1,158 b''
1 //----------------------------------------------------------------------------
1 //----------------------------------------------------------------------------
2 // Copyright (C) 2013 The IPython Development Team
2 // Copyright (C) 2013 The IPython Development Team
3 //
3 //
4 // Distributed under the terms of the BSD License. The full license is in
4 // Distributed under the terms of the BSD License. The full license is in
5 // the file COPYING, distributed as part of this software.
5 // the file COPYING, distributed as part of this software.
6 //----------------------------------------------------------------------------
6 //----------------------------------------------------------------------------
7
7
8 //============================================================================
8 //============================================================================
9 // StringWidget
9 // StringWidget
10 //============================================================================
10 //============================================================================
11
11
12 /**
12 /**
13 * @module IPython
13 * @module IPython
14 * @namespace IPython
14 * @namespace IPython
15 **/
15 **/
16
16
17 define(["notebook/js/widget"], function(widget_manager){
17 define(["notebook/js/widget"], function(widget_manager){
18 var StringWidgetModel = IPython.WidgetModel.extend({});
18 var StringWidgetModel = IPython.WidgetModel.extend({});
19 widget_manager.register_widget_model('StringWidgetModel', StringWidgetModel);
19 widget_manager.register_widget_model('StringWidgetModel', StringWidgetModel);
20
20
21 var LabelView = IPython.WidgetView.extend({
21 var LabelView = IPython.WidgetView.extend({
22
22
23 // Called when view is rendered.
23 // Called when view is rendered.
24 render : function(){
24 render : function(){
25 this.$el = $('<div />');
25 this.$el = $('<div />');
26 this.update(); // Set defaults.
26 this.update(); // Set defaults.
27 },
27 },
28
28
29 // Handles: Backend -> Frontend Sync
29 // Handles: Backend -> Frontend Sync
30 // Frontent -> Frontend Sync
30 // Frontent -> Frontend Sync
31 update : function(){
31 update : function(){
32 this.$el.html(this.model.get('value'));
32 this.$el.html(this.model.get('value'));
33 return IPython.WidgetView.prototype.update.call(this);
33 return IPython.WidgetView.prototype.update.call(this);
34 },
34 },
35
35
36 });
36 });
37
37
38 widget_manager.register_widget_view('LabelView', LabelView);
38 widget_manager.register_widget_view('LabelView', LabelView);
39
39
40 var TextAreaView = IPython.WidgetView.extend({
40 var TextAreaView = IPython.WidgetView.extend({
41
41
42 // Called when view is rendered.
42 // Called when view is rendered.
43 render : function(){
43 render : function(){
44 this.$el
44 this.$el
45 .addClass('widget-hbox')
45 .addClass('widget-hbox')
46 .html('');
46 .html('');
47 this.$label = $('<div />')
47 this.$label = $('<div />')
48 .appendTo(this.$el)
48 .appendTo(this.$el)
49 .addClass('widget-hlabel')
49 .addClass('widget-hlabel')
50 .hide();
50 .hide();
51 this.$textbox = $('<textarea />')
51 this.$textbox = $('<textarea />')
52 .attr('rows', 5)
52 .attr('rows', 5)
53 .addClass('widget-text')
53 .addClass('widget-text')
54 .appendTo(this.$el);
54 .appendTo(this.$el);
55 this.$el_to_style = this.$textbox; // Set default element to style
55 this.$el_to_style = this.$textbox; // Set default element to style
56 this.update(); // Set defaults.
56 this.update(); // Set defaults.
57 },
57 },
58
58
59 // Handles: Backend -> Frontend Sync
59 // Handles: Backend -> Frontend Sync
60 // Frontent -> Frontend Sync
60 // Frontent -> Frontend Sync
61 update : function(){
61 update : function(){
62 if (!this.user_invoked_update) {
62 if (!this.user_invoked_update) {
63 this.$textbox.val(this.model.get('value'));
63 this.$textbox.val(this.model.get('value'));
64 }
64 }
65
65
66 var disabled = this.model.get('disabled');
66 var disabled = this.model.get('disabled');
67 this.$textbox.prop('disabled', disabled);
67 this.$textbox.prop('disabled', disabled);
68
68
69 var description = this.model.get('description');
69 var description = this.model.get('description');
70 if (description.length == 0) {
70 if (description.length == 0) {
71 this.$label.hide();
71 this.$label.hide();
72 } else {
72 } else {
73 this.$label.html(description);
73 this.$label.html(description);
74 this.$label.show();
74 this.$label.show();
75 }
75 }
76 return IPython.WidgetView.prototype.update.call(this);
76 return IPython.WidgetView.prototype.update.call(this);
77 },
77 },
78
78
79 events: {"keyup textarea" : "handleChanging",
79 events: {"keyup textarea" : "handleChanging",
80 "paste textarea" : "handleChanging",
80 "paste textarea" : "handleChanging",
81 "cut textarea" : "handleChanging"},
81 "cut textarea" : "handleChanging"},
82
82
83 // Handles and validates user input.
83 // Handles and validates user input.
84 handleChanging: function(e) {
84 handleChanging: function(e) {
85 this.user_invoked_update = true;
85 this.user_invoked_update = true;
86 this.model.set('value', e.target.value);
86 this.model.set('value', e.target.value);
87 this.model.update_other_views(this);
87 this.model.update_other_views(this);
88 this.user_invoked_update = false;
88 this.user_invoked_update = false;
89 },
89 },
90 });
90 });
91
91
92 widget_manager.register_widget_view('TextAreaView', TextAreaView);
92 widget_manager.register_widget_view('TextAreaView', TextAreaView);
93
93
94 var TextBoxView = IPython.WidgetView.extend({
94 var TextBoxView = IPython.WidgetView.extend({
95
95
96 // Called when view is rendered.
96 // Called when view is rendered.
97 render : function(){
97 render : function(){
98 this.$el
98 this.$el
99 .addClass('widget-hbox-single')
99 .addClass('widget-hbox-single')
100 .html('');
100 .html('');
101 this.$label = $('<div />')
101 this.$label = $('<div />')
102 .addClass('widget-hlabel')
102 .addClass('widget-hlabel')
103 .appendTo(this.$el)
103 .appendTo(this.$el)
104 .hide();
104 .hide();
105 this.$textbox = $('<input type="text" />')
105 this.$textbox = $('<input type="text" />')
106 .addClass('input')
106 .addClass('input')
107 .addClass('widget-text')
107 .addClass('widget-text')
108 .appendTo(this.$el);
108 .appendTo(this.$el);
109 this.$el_to_style = this.$textbox; // Set default element to style
109 this.$el_to_style = this.$textbox; // Set default element to style
110 this.update(); // Set defaults.
110 this.update(); // Set defaults.
111 },
111 },
112
112
113 // Handles: Backend -> Frontend Sync
113 // Handles: Backend -> Frontend Sync
114 // Frontent -> Frontend Sync
114 // Frontent -> Frontend Sync
115 update : function(){
115 update : function(){
116 if (!this.user_invoked_update) {
116 if (!this.user_invoked_update) {
117 this.$textbox.val(this.model.get('value'));
117 this.$textbox.val(this.model.get('value'));
118 }
118 }
119
119
120 var disabled = this.model.get('disabled');
120 var disabled = this.model.get('disabled');
121 this.$textbox.prop('disabled', disabled);
121 this.$textbox.prop('disabled', disabled);
122
122
123 var description = this.model.get('description');
123 var description = this.model.get('description');
124 if (description.length == 0) {
124 if (description.length == 0) {
125 this.$label.hide();
125 this.$label.hide();
126 } else {
126 } else {
127 this.$label.html(description);
127 this.$label.html(description);
128 this.$label.show();
128 this.$label.show();
129 }
129 }
130 return IPython.WidgetView.prototype.update.call(this);
130 return IPython.WidgetView.prototype.update.call(this);
131 },
131 },
132
132
133 events: {"keyup input" : "handleChanging",
133 events: {"keyup input" : "handleChanging",
134 "paste input" : "handleChanging",
134 "paste input" : "handleChanging",
135 "cut input" : "handleChanging"},
135 "cut input" : "handleChanging",
136 "keypress input" : "handleKeypress"},
136
137
137 // Handles and validates user input.
138 // Handles and validates user input.
138 handleChanging: function(e) {
139 handleChanging: function(e) {
139 this.user_invoked_update = true;
140 this.user_invoked_update = true;
140 this.model.set('value', e.target.value);
141 this.model.set('value', e.target.value);
141 this.model.update_other_views(this);
142 this.model.update_other_views(this);
142 this.user_invoked_update = false;
143 this.user_invoked_update = false;
143 },
144 },
145
146 // Handles text submition
147 handleKeypress: function(e) {
148 if (e.keyCode == 13) { // Return key
149 this.user_invoked_update = true;
150 this.model.set('submits', this.model.get('submits') + 1);
151 this.model.update_other_views(this);
152 this.user_invoked_update = false;
153 }
154 },
144 });
155 });
145
156
146 widget_manager.register_widget_view('TextBoxView', TextBoxView);
157 widget_manager.register_widget_view('TextBoxView', TextBoxView);
147 });
158 });
@@ -1,30 +1,79 b''
1 """StringWidget class.
1 """StringWidget class.
2
2
3 Represents a unicode string using a widget.
3 Represents a unicode string using a widget.
4 """
4 """
5 #-----------------------------------------------------------------------------
5 #-----------------------------------------------------------------------------
6 # Copyright (c) 2013, the IPython Development Team.
6 # Copyright (c) 2013, the IPython Development Team.
7 #
7 #
8 # Distributed under the terms of the Modified BSD License.
8 # Distributed under the terms of the Modified BSD License.
9 #
9 #
10 # The full license is in the file COPYING.txt, distributed with this software.
10 # The full license is in the file COPYING.txt, distributed with this software.
11 #-----------------------------------------------------------------------------
11 #-----------------------------------------------------------------------------
12
12
13 #-----------------------------------------------------------------------------
13 #-----------------------------------------------------------------------------
14 # Imports
14 # Imports
15 #-----------------------------------------------------------------------------
15 #-----------------------------------------------------------------------------
16 import inspect
17 import types
18
16 from .widget import Widget
19 from .widget import Widget
17 from IPython.utils.traitlets import Unicode, Bool, List
20 from IPython.utils.traitlets import Unicode, Bool, List, Int
18
21
19 #-----------------------------------------------------------------------------
22 #-----------------------------------------------------------------------------
20 # Classes
23 # Classes
21 #-----------------------------------------------------------------------------
24 #-----------------------------------------------------------------------------
22 class StringWidget(Widget):
25 class StringWidget(Widget):
23 target_name = Unicode('StringWidgetModel')
26 target_name = Unicode('StringWidgetModel')
24 default_view_name = Unicode('TextBoxView')
27 default_view_name = Unicode('TextBoxView')
25
28
26 # Keys
29 # Keys
27 _keys = ['value', 'disabled', 'description']
30 _keys = ['value', 'disabled', 'description', 'submits']
28 value = Unicode(help="String value")
31 value = Unicode(help="String value")
29 disabled = Bool(False, help="Enable or disable user changes")
32 disabled = Bool(False, help="Enable or disable user changes")
30 description = Unicode(help="Description of the value this widget represents")
33 description = Unicode(help="Description of the value this widget represents")
34 submits = Int(0, help="Used to capture and fire submission ")
35
36
37 def __init__(self, **kwargs):
38 super(StringWidget, self).__init__(**kwargs)
39 self._submission_callbacks = []
40
41
42 def on_submit(self, callback, remove=False):
43 """Register a callback to handle text submission (triggered when the
44 user clicks enter).
45
46 Parameters
47 callback: Method handle
48 Function to be called when the text has been submitted. Function
49 can have two possible signatures:
50 callback()
51 callback(sender)
52 remove: bool (optional)
53 Whether or not to unregister the callback"""
54 if remove and callback in self._submission_callbacks:
55 self._submission_callbacks.remove(callback)
56 elif not remove and not callback in self._submission_callbacks:
57 self._submission_callbacks.append(callback)
58
59
60 def _submits_changed(self, name, old_value, new_value):
61 """Handles when a string widget view is submitted."""
62 if new_value > old_value:
63 for handler in self._submission_callbacks:
64 if callable(handler):
65 argspec = inspect.getargspec(handler)
66 nargs = len(argspec[0])
67
68 # Bound methods have an additional 'self' argument
69 if isinstance(handler, types.MethodType):
70 nargs -= 1
71
72 # Call the callback
73 if nargs == 0:
74 handler()
75 elif nargs == 1:
76 handler(self)
77 else:
78 raise TypeError('StringWidget submit callback must ' \
79 'accept 0 or 1 arguments.')
General Comments 0
You need to be logged in to leave comments. Login now