##// END OF EJS Templates
Add placeholder to textarea as well as text
Jessica B. Hamrick -
Show More
@@ -1,234 +1,246
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(["widgets/js/widget"], function(WidgetManager){
17 define(["widgets/js/widget"], function(WidgetManager){
18
18
19 var HTMLView = IPython.DOMWidgetView.extend({
19 var HTMLView = IPython.DOMWidgetView.extend({
20 render : function(){
20 render : function(){
21 // Called when view is rendered.
21 // Called when view is rendered.
22 this.update(); // Set defaults.
22 this.update(); // Set defaults.
23 },
23 },
24
24
25 update : function(){
25 update : function(){
26 // Update the contents of this view
26 // Update the contents of this view
27 //
27 //
28 // Called when the model is changed. The model may have been
28 // Called when the model is changed. The model may have been
29 // changed by another view or by a state update from the back-end.
29 // changed by another view or by a state update from the back-end.
30 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
30 this.$el.html(this.model.get('value')); // CAUTION! .html(...) CALL MANDITORY!!!
31 return HTMLView.__super__.update.apply(this);
31 return HTMLView.__super__.update.apply(this);
32 },
32 },
33 });
33 });
34 WidgetManager.register_widget_view('HTMLView', HTMLView);
34 WidgetManager.register_widget_view('HTMLView', HTMLView);
35
35
36
36
37 var LatexView = IPython.DOMWidgetView.extend({
37 var LatexView = IPython.DOMWidgetView.extend({
38 render : function(){
38 render : function(){
39 // Called when view is rendered.
39 // Called when view is rendered.
40 this.update(); // Set defaults.
40 this.update(); // Set defaults.
41 },
41 },
42
42
43 update : function(){
43 update : function(){
44 // Update the contents of this view
44 // Update the contents of this view
45 //
45 //
46 // Called when the model is changed. The model may have been
46 // Called when the model is changed. The model may have been
47 // changed by another view or by a state update from the back-end.
47 // changed by another view or by a state update from the back-end.
48 this.$el.text(this.model.get('value'));
48 this.$el.text(this.model.get('value'));
49 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
49 MathJax.Hub.Queue(["Typeset",MathJax.Hub,this.$el.get(0)]);
50
50
51 return LatexView.__super__.update.apply(this);
51 return LatexView.__super__.update.apply(this);
52 },
52 },
53 });
53 });
54 WidgetManager.register_widget_view('LatexView', LatexView);
54 WidgetManager.register_widget_view('LatexView', LatexView);
55
55
56
56
57 var TextareaView = IPython.DOMWidgetView.extend({
57 var TextareaView = IPython.DOMWidgetView.extend({
58 render: function(){
58 render: function(){
59 // Called when view is rendered.
59 // Called when view is rendered.
60 this.$el
60 this.$el
61 .addClass('widget-hbox');
61 .addClass('widget-hbox');
62 this.$label = $('<div />')
62 this.$label = $('<div />')
63 .appendTo(this.$el)
63 .appendTo(this.$el)
64 .addClass('widget-hlabel')
64 .addClass('widget-hlabel')
65 .hide();
65 .hide();
66 this.$textbox = $('<textarea />')
66 this.$textbox = $('<textarea />')
67 .attr('rows', 5)
67 .attr('rows', 5)
68 .addClass('widget-text')
68 .addClass('widget-text')
69 .appendTo(this.$el);
69 .appendTo(this.$el);
70 this.$el_to_style = this.$textbox; // Set default element to style
70 this.$el_to_style = this.$textbox; // Set default element to style
71 this.update(); // Set defaults.
71 this.update(); // Set defaults.
72
72
73 this.model.on('msg:custom', $.proxy(this._handle_textarea_msg, this));
73 this.model.on('msg:custom', $.proxy(this._handle_textarea_msg, this));
74 this.model.on('change:placeholder', function(model, value, options) {
75 this.update_placeholder(value);
76 }, this);
77
78 this.update_placeholder();
74 },
79 },
75
80
76 _handle_textarea_msg: function (content){
81 _handle_textarea_msg: function (content){
77 // Handle when a custom msg is recieved from the back-end.
82 // Handle when a custom msg is recieved from the back-end.
78 if (content.method == "scroll_to_bottom") {
83 if (content.method == "scroll_to_bottom") {
79 this.scroll_to_bottom();
84 this.scroll_to_bottom();
80 }
85 }
81 },
86 },
82
87
88 update_placeholder: function(value) {
89 if (!value) {
90 value = this.model.get('placeholder');
91 }
92 this.$textbox.attr('placeholder', value);
93 },
94
83 scroll_to_bottom: function (){
95 scroll_to_bottom: function (){
84 // Scroll the text-area view to the bottom.
96 // Scroll the text-area view to the bottom.
85 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
97 this.$textbox.scrollTop(this.$textbox[0].scrollHeight);
86 },
98 },
87
99
88 update: function(options){
100 update: function(options){
89 // Update the contents of this view
101 // Update the contents of this view
90 //
102 //
91 // Called when the model is changed. The model may have been
103 // Called when the model is changed. The model may have been
92 // changed by another view or by a state update from the back-end.
104 // changed by another view or by a state update from the back-end.
93 if (options === undefined || options.updated_view != this) {
105 if (options === undefined || options.updated_view != this) {
94 this.$textbox.val(this.model.get('value'));
106 this.$textbox.val(this.model.get('value'));
95
107
96 var disabled = this.model.get('disabled');
108 var disabled = this.model.get('disabled');
97 this.$textbox.prop('disabled', disabled);
109 this.$textbox.prop('disabled', disabled);
98
110
99 var description = this.model.get('description');
111 var description = this.model.get('description');
100 if (description.length === 0) {
112 if (description.length === 0) {
101 this.$label.hide();
113 this.$label.hide();
102 } else {
114 } else {
103 this.$label.text(description);
115 this.$label.text(description);
104 this.$label.show();
116 this.$label.show();
105 }
117 }
106 }
118 }
107 return TextareaView.__super__.update.apply(this);
119 return TextareaView.__super__.update.apply(this);
108 },
120 },
109
121
110 events: {
122 events: {
111 // Dictionary of events and their handlers.
123 // Dictionary of events and their handlers.
112 "keyup textarea" : "handleChanging",
124 "keyup textarea" : "handleChanging",
113 "paste textarea" : "handleChanging",
125 "paste textarea" : "handleChanging",
114 "cut textarea" : "handleChanging"
126 "cut textarea" : "handleChanging"
115 },
127 },
116
128
117 handleChanging: function(e) {
129 handleChanging: function(e) {
118 // Handles and validates user input.
130 // Handles and validates user input.
119
131
120 // Calling model.set will trigger all of the other views of the
132 // Calling model.set will trigger all of the other views of the
121 // model to update.
133 // model to update.
122 this.model.set('value', e.target.value, {updated_view: this});
134 this.model.set('value', e.target.value, {updated_view: this});
123 this.touch();
135 this.touch();
124 },
136 },
125 });
137 });
126 WidgetManager.register_widget_view('TextareaView', TextareaView);
138 WidgetManager.register_widget_view('TextareaView', TextareaView);
127
139
128
140
129 var TextView = IPython.DOMWidgetView.extend({
141 var TextView = IPython.DOMWidgetView.extend({
130 render: function(){
142 render: function(){
131 // Called when view is rendered.
143 // Called when view is rendered.
132 this.$el
144 this.$el
133 .addClass('widget-hbox-single');
145 .addClass('widget-hbox-single');
134 this.$label = $('<div />')
146 this.$label = $('<div />')
135 .addClass('widget-hlabel')
147 .addClass('widget-hlabel')
136 .appendTo(this.$el)
148 .appendTo(this.$el)
137 .hide();
149 .hide();
138 this.$textbox = $('<input type="text" />')
150 this.$textbox = $('<input type="text" />')
139 .addClass('input')
151 .addClass('input')
140 .addClass('widget-text')
152 .addClass('widget-text')
141 .appendTo(this.$el);
153 .appendTo(this.$el);
142 this.$el_to_style = this.$textbox; // Set default element to style
154 this.$el_to_style = this.$textbox; // Set default element to style
143 this.update(); // Set defaults.
155 this.update(); // Set defaults.
144 this.model.on('change:placeholder', function(model, value, options) {
156 this.model.on('change:placeholder', function(model, value, options) {
145 this.update_placeholder(value);
157 this.update_placeholder(value);
146 }, this);
158 }, this);
147
159
148 this.update_placeholder();
160 this.update_placeholder();
149 },
161 },
150
162
151 update_placeholder: function(value) {
163 update_placeholder: function(value) {
152 if (!value) {
164 if (!value) {
153 value = this.model.get('placeholder');
165 value = this.model.get('placeholder');
154 }
166 }
155 this.$textbox.attr('placeholder', value);
167 this.$textbox.attr('placeholder', value);
156 },
168 },
157
169
158 update: function(options){
170 update: function(options){
159 // Update the contents of this view
171 // Update the contents of this view
160 //
172 //
161 // Called when the model is changed. The model may have been
173 // Called when the model is changed. The model may have been
162 // changed by another view or by a state update from the back-end.
174 // changed by another view or by a state update from the back-end.
163 if (options === undefined || options.updated_view != this) {
175 if (options === undefined || options.updated_view != this) {
164 if (this.$textbox.val() != this.model.get('value')) {
176 if (this.$textbox.val() != this.model.get('value')) {
165 this.$textbox.val(this.model.get('value'));
177 this.$textbox.val(this.model.get('value'));
166 }
178 }
167
179
168 var disabled = this.model.get('disabled');
180 var disabled = this.model.get('disabled');
169 this.$textbox.prop('disabled', disabled);
181 this.$textbox.prop('disabled', disabled);
170
182
171 var description = this.model.get('description');
183 var description = this.model.get('description');
172 if (description.length === 0) {
184 if (description.length === 0) {
173 this.$label.hide();
185 this.$label.hide();
174 } else {
186 } else {
175 this.$label.text(description);
187 this.$label.text(description);
176 this.$label.show();
188 this.$label.show();
177 }
189 }
178 }
190 }
179 return TextView.__super__.update.apply(this);
191 return TextView.__super__.update.apply(this);
180 },
192 },
181
193
182 events: {
194 events: {
183 // Dictionary of events and their handlers.
195 // Dictionary of events and their handlers.
184 "keyup input" : "handleChanging",
196 "keyup input" : "handleChanging",
185 "paste input" : "handleChanging",
197 "paste input" : "handleChanging",
186 "cut input" : "handleChanging",
198 "cut input" : "handleChanging",
187 "keypress input" : "handleKeypress",
199 "keypress input" : "handleKeypress",
188 "blur input" : "handleBlur",
200 "blur input" : "handleBlur",
189 "focusout input" : "handleFocusOut"
201 "focusout input" : "handleFocusOut"
190 },
202 },
191
203
192 handleChanging: function(e) {
204 handleChanging: function(e) {
193 // Handles user input.
205 // Handles user input.
194
206
195 // Calling model.set will trigger all of the other views of the
207 // Calling model.set will trigger all of the other views of the
196 // model to update.
208 // model to update.
197 this.model.set('value', e.target.value, {updated_view: this});
209 this.model.set('value', e.target.value, {updated_view: this});
198 this.touch();
210 this.touch();
199 },
211 },
200
212
201 handleKeypress: function(e) {
213 handleKeypress: function(e) {
202 // Handles text submition
214 // Handles text submition
203 if (e.keyCode == 13) { // Return key
215 if (e.keyCode == 13) { // Return key
204 this.send({event: 'submit'});
216 this.send({event: 'submit'});
205 event.stopPropagation();
217 event.stopPropagation();
206 event.preventDefault();
218 event.preventDefault();
207 return false;
219 return false;
208 }
220 }
209 },
221 },
210
222
211 handleBlur: function(e) {
223 handleBlur: function(e) {
212 // Prevent a blur from firing if the blur was not user intended.
224 // Prevent a blur from firing if the blur was not user intended.
213 // This is a workaround for the return-key focus loss bug.
225 // This is a workaround for the return-key focus loss bug.
214 // TODO: Is the original bug actually a fault of the keyboard
226 // TODO: Is the original bug actually a fault of the keyboard
215 // manager?
227 // manager?
216 if (e.relatedTarget === null) {
228 if (e.relatedTarget === null) {
217 event.stopPropagation();
229 event.stopPropagation();
218 event.preventDefault();
230 event.preventDefault();
219 return false;
231 return false;
220 }
232 }
221 },
233 },
222
234
223 handleFocusOut: function(e) {
235 handleFocusOut: function(e) {
224 // Prevent a blur from firing if the blur was not user intended.
236 // Prevent a blur from firing if the blur was not user intended.
225 // This is a workaround for the return-key focus loss bug.
237 // This is a workaround for the return-key focus loss bug.
226 if (e.relatedTarget === null) {
238 if (e.relatedTarget === null) {
227 event.stopPropagation();
239 event.stopPropagation();
228 event.preventDefault();
240 event.preventDefault();
229 return false;
241 return false;
230 }
242 }
231 },
243 },
232 });
244 });
233 WidgetManager.register_widget_view('TextView', TextView);
245 WidgetManager.register_widget_view('TextView', TextView);
234 });
246 });
General Comments 0
You need to be logged in to leave comments. Login now