Repository: ipython/ipython

Issue:
Widget TextView Placeholder
Mainly also a question to @jdfreder , 

Is there a way to have placeholder in text widget, especially when default value is empty string, it would be nice. 

I'm not familiar with widget infrastructure to find how to do it. Any advice appreciated ! 



Discussion:
There isn't a way now, but it would be easy to add.  I can do that for you if you'd like, or if you're interested in learning about the widget stuff I can point you in the right direction so you can add it.

yes, point me to the right direction ! Still 24h of sprint !

You'll need to work in two files,
Python - `ipython/IPython/html/widgets/widget_string.py`
JS - `ipython/IPython/html/static/widgets/js/widget_string.js`

The widget framework works by syncing traitlets with `sync=True` applied to them.  The first step will be to add a traitlet to the `TextWidget` in the Python file. Something like 

``` python
placeholder = Unicode('Type here...', sync=True)
```

The second step is to listen to that value in Javascript.  There are two ways to do this.  Right now most widgets are implemented such that all changes are handled in the `update:` function.  `update:` will fire when ever a value (any and all values) changes in the model.  The new way, which I'm trying to use more often, is to use Backbone trait specific events.  I recommend you use the new method but in the end it's up to you. 

The syntax to register an event handler is 

``` js
this.model.on('change:TRAITNAME', function(model, value, options) {this.HANDLER();}, this);
```

where `TRAITNAME` would be `placeholder` in this example
and `HANDLER` would be the name of the method to handle the changes.  You could just as easily inline the function here using a closure.

See the `AccordionView` constructor in `ipython/IPython/html/static/widgets/widget_selectioncontainer.js` for an example of how this is done.

You'll be adding this handling code inside `TextView` in `ipython/IPython/html/static/widgets/widget_string.js`.  `this.$textbox` is a jQuery handle to the textbox control.  You'll have to lookup how to set the Bootstrap placeholder text via Javascript.

Let me know if I can help some more...  I look forward to seeing the changes.

Really appreciated, enough instruction to do that in the plane if I cannot tackle it before leaving ! 

I'll see if I can do this today at the sprint!


Resolving patch:
diff --git a/IPython/html/widgets/widget_string.py b/IPython/html/widgets/widget_string.py
--- a/IPython/html/widgets/widget_string.py
+++ b/IPython/html/widgets/widget_string.py
@@ -23,6 +23,7 @@ class _StringWidget(DOMWidget):
     value = Unicode(help="String value", sync=True)
     disabled = Bool(False, help="Enable or disable user changes", sync=True)
     description = Unicode(help="Description of the value this widget represents", sync=True)
+    placeholder = Unicode("", help="Placeholder text to display when nothing has been typed", sync=True)
 
 
 class HTMLWidget(_StringWidget):


Test patch:
diff --git a/IPython/html/tests/widgets/widget_string.js b/IPython/html/tests/widgets/widget_string.js
--- a/IPython/html/tests/widgets/widget_string.js
+++ b/IPython/html/tests/widgets/widget_string.js
@@ -7,8 +7,8 @@ casper.notebook_test(function () {
     this.execute_cell_then(index);
 
     var string_index = this.append_cell(
-        'string_widget = [widgets.TextWidget(value = "xyz"),\n' +
-        '    widgets.TextareaWidget(value = "xyz"),\n' +
+        'string_widget = [widgets.TextWidget(value = "xyz", placeholder = "abc"),\n' +
+        '    widgets.TextareaWidget(value = "xyz", placeholder = "def"),\n' +
         '    widgets.HTMLWidget(value = "xyz"),\n' +
         '    widgets.LatexWidget(value = "$\\\\LaTeX{}$")]\n' +
         '[display(widget) for widget in string_widget]\n'+
@@ -41,5 +41,13 @@ casper.notebook_test(function () {
         this.test.assert(this.cell_element_exists(string_index, 
             '.widget-area .widget-subarea div span.MathJax_Preview'),
             'MathJax parsed the LaTeX successfully.');
+
+        this.test.assert(this.cell_element_function(index, 
+            '.widget-area .widget-subarea .widget-hbox textarea', 'attr', ['placeholder'])=='def',
+            'Python set textarea placeholder.');
+
+        this.test.assert(this.cell_element_function(index, 
+            '.widget-area .widget-subarea .widget-hbox-single input[type=text]', 'attr', ['placeholder'])=='abc',
+            'Python set textbox placehoder.');
     });
-});
\ No newline at end of file
+});