Expandable Text Box

So, I don’t know if this is a coincidence with installing the new Skuid into my sandbox or if there is now something wrong with the javascript, but this code is no longer working. Here is the code that I have running in the javascript as an in-line snippet. Any ideas of what might have happened?

// Expanding Textareas v0.1.2// MIT License
// https://github.com/bgrins/ExpandingTextareas

(function(factory) {
// Add jQuery via AMD registration or browser globals
if (typeof define === ‘function’ && define.amd) {
define([ ‘jquery’ ], factory);
}
else {
factory(jQuery);
}
}(function ($) {

var Expanding = function($textarea, opts) {
Expanding._registry.push(this);

this.$textarea = $textarea;
this.$textCopy = $("<span />");
this.$clone = $("<pre class='expanding-clone'>

").prepend(this.$textCopy);

this._resetStyles();
this._setCloneStyles();
this._setTextareaStyles();

$textarea
  .wrap($("<div class='expanding-wrapper' style='position:relative' />"))
  .after(this.$clone);

this.attach();
this.update();
if (opts.update) $textarea.bind("update.expanding", opts.update);

};

// Stores (active) ‘Expanding’ instances
// Destroyed instances are removed
Expanding._registry = ;

// Returns the ‘Expanding’ instance given a DOM node
Expanding.getExpandingInstance = function(textarea) {
var $textareas = $.map(Expanding._registry, function(instance) {
return instance.$textarea[0];
}),
index = $.inArray(textarea, $textareas);
return index > -1 ? Expanding._registry[index] : null;
};

// Returns the version of Internet Explorer or -1
// (indicating the use of another browser).
// From: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA
var ieVersion = (function() {
var v = -1;
if (navigator.appName === “Microsoft Internet Explorer”) {
var ua = navigator.userAgent;
var re = new RegExp(“MSIE ([0-9]{1,}[.0-9]{0,})”);
if (re.exec(ua) !== null) v = parseFloat(RegExp.$1);
}
return v;
})();

// Check for oninput support
// IE9 supports oninput, but not when deleting text, so keyup is used.
// onpropertychange is supported by IE8/9, but may not be fired unless
// attached with ‘attachEvent’
// (see: http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire),
// and so is avoided altogether.
var inputSupported = “oninput” in document.createElement(“input”) && ieVersion !== 9;

Expanding.prototype = {

// Attaches input events
// Only attaches 'keyup' events if 'input' is not fully suported
attach: function() {
  var events = 'input.expanding change.expanding',
    _this = this;
  if(!inputSupported) events += ' keyup.expanding';
  this.$textarea.bind(events, function() { _this.update(); });
},

// Updates the clone with the textarea value
update: function() {
  this.$textCopy.text(this.$textarea.val().replace(/

/g, "
"));

  // Use 'triggerHandler' to prevent conflicts with 'update' in Prototype.js
  this.$textarea.triggerHandler("update.expanding");
},

// Tears down the plugin: removes generated elements, applies styles
// that were prevously present, removes instance from registry,
// unbinds events
destroy: function() {
  this.$clone.remove();
  this.$textarea
    .unwrap()
    .attr('style', this._oldTextareaStyles || '');
  delete this._oldTextareaStyles;
  var index = $.inArray(this, Expanding._registry);
  if (index > -1) Expanding._registry.splice(index, 1);
  this.$textarea.unbind(
    'input.expanding change.expanding keyup.expanding update.expanding');
},

// Applies reset styles to the textarea and clone
// Stores the original textarea styles in case of destroying
_resetStyles: function() {
  this._oldTextareaStyles = this.$textarea.attr('style');

  this.$textarea.add(this.$clone).css({
    margin: 0,
    webkitBoxSizing: "border-box",
    mozBoxSizing: "border-box",
    boxSizing: "border-box",
    width: "100%"
  });
},

// Sets the basic clone styles and copies styles over from the textarea
_setCloneStyles: function() {
  var css = {
    display: 'block',
    border: '0 solid',
    visibility: 'hidden',
    minHeight: this.$textarea.outerHeight()
  };

  if(this.$textarea.attr("wrap") === "off") css.overflowX = "scroll";
  else css.whiteSpace = "pre-wrap";

  this.$clone.css(css);
  this._copyTextareaStylesToClone();
},

_copyTextareaStylesToClone: function() {
  var _this = this,
    properties = [
      'lineHeight', 'textDecoration', 'letterSpacing',
      'fontSize', 'fontFamily', 'fontStyle',
      'fontWeight', 'textTransform', 'textAlign',
      'direction', 'wordSpacing', 'fontSizeAdjust',
      'wordWrap', 'word-break',
      'borderLeftWidth', 'borderRightWidth',
      'borderTopWidth','borderBottomWidth',
      'paddingLeft', 'paddingRight',
      'paddingTop','paddingBottom', 'maxHeight'];

  $.each(properties, function(i, property) {
    var val = _this.$textarea.css(property);

    // Prevent overriding percentage css values.
    if(_this.$clone.css(property) !== val) {
      _this.$clone.css(property, val);
      if(property === 'maxHeight' &amp;&amp; val !== 'none') {
        _this.$clone.css('overflow', 'hidden');
      }
    }
  });
},

_setTextareaStyles: function() {
  this.$textarea.css({
    position: "absolute",
    top: 0,
    left: 0,
    height: "100%",
    resize: "none",
    overflow: "auto"
  });
}

};

$.expanding = $.extend({
autoInitialize: true,
initialSelector: “textarea.expanding”,
opts: {
update: function() { }
}
}, $.expanding || {});

$.fn.expanding = function(o) {

if (o === "destroy") {
  this.each(function() {
    var instance = Expanding.getExpandingInstance(this);
    if (instance) instance.destroy();
  });
  return this;
}

// Checks to see if any of the given DOM nodes have the
// expanding behaviour.
if (o === "active") {
  return !!this.filter(function() {
    return !!Expanding.getExpandingInstance(this);
  }).length;
}

var opts = $.extend({ }, $.expanding.opts, o);

this.filter("textarea").each(function() {
  var visible = this.offsetWidth > 0 || this.offsetHeight > 0,
      initialized = Expanding.getExpandingInstance(this);

  if(visible &amp;&amp; !initialized) new Expanding($(this), opts);
  else {
    if(!visible) _warn("ExpandingTextareas: attempt to initialize an invisible textarea. Call expanding() again once it has been inserted into the page and/or is visible.");
    if(initialized) _warn("ExpandingTextareas: attempt to initialize a textarea that has already been initialized. Subsequent calls are ignored.");
  }
});
return this;

};

function _warn(text) {
if(window.console && console.warn) console.warn(text);
}

$(function () {
if ($.expanding.autoInitialize) {
$($.expanding.initialSelector).expanding();
}
});

}));

var $ = skuid.$, field = arguments[0], value = arguments[1];
var model = field.model, row = field.row;

var containerDiv = field.element;
var fieldText = $(‘’ + value + ‘’);

//Update field value when text is changed
$(fieldText).bind(‘input propertychange’, function() {
var fieldsToUpdate = {};
fieldsToUpdate[field.id] = $(this).val();

model.updateRow(row, fieldsToUpdate);

});

$(containerDiv).append(fieldText);

if (field.mode == ‘edit’) {
$(containerDiv).append(fieldText);
}
else {
$(containerDiv).append($(‘

’).html(value));
}

What happens is when I try to type, it allows me to type one character and then the focus of the cursor goes somewhere else on the page. 

One explanation for the symptom you are having is that you have another ‘iFrame based include’ somewhere else on the page that is using the same model as its source.  When the model detects changes (ie a new character typed in the textbox) it tells the iFrame to rerender - which grabs focus.   It is best to provide a model just for the iframe includes.   If this is a wild goose chase let me know. 

Thanks for your quick response Rob!

I tried just creating a new page all together with just a single text box, a single text field, and a single model to test out this javascript and I am getting the same result. I’m not sure if this is exactly what you are asking about, but let me know if there is another way to test this out.

I’m not exactly sure how the above code would have worked before, as the Expanding plugin has to be initialized using the jQuery expanding() plugin syntax in order for it to be used programmatically (see the “Manual” section in the Github docs for the plugin), but this approach should work:

  1. Change the “Resource Location” of your existing JavaScript Resource from Inline (Snippet) to regular Inline — this step is very very important.
  2. Change the “Resource Body” to be the following:
// Expanding Textareas v0.1.2
// MIT License
// <a href="https://github.com/bgrins/ExpandingTextareas" title="Link: https://github.com/bgrins/ExpandingTextareas">https://github.com/bgrins/ExpandingTextareas</a>
(function(factory) {
  // Add jQuery via AMD registration or browser globals
  if (typeof define === 'function' &amp;&amp; define.amd) {
    define([ 'jquery' ], factory);
  }
  else {
    factory(skuid.$);
  }
}(function ($) {
  var Expanding = function($textarea, opts) {
    Expanding._registry.push(this);
    this.$textarea = $textarea;
    this.$textCopy = $("<span />");
    this.$clone = $("<pre class='expanding-clone'>
</pre>").prepend(this.$textCopy);
    this._resetStyles();
    this._setCloneStyles();
    this._setTextareaStyles();
    $textarea
      .wrap($("<div class='expanding-wrapper' style='position:relative' />"))
      .after(this.$clone);
    this.attach();
    this.update();
    if (opts.update) $textarea.bind("update.expanding", opts.update);
  };
  // Stores (active) 'Expanding' instances
  // Destroyed instances are removed
  Expanding._registry = [];
  // Returns the 'Expanding' instance given a DOM node
  Expanding.getExpandingInstance = function(textarea) {
    var $textareas = $.map(Expanding._registry, function(instance) {
        return instance.$textarea[0];
      }),
      index = $.inArray(textarea, $textareas);
    return index > -1 ? Expanding._registry[index] : null;
  };
  // Returns the version of Internet Explorer or -1
  // (indicating the use of another browser).
  // From: <a href="http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA" title="Link: http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA">http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA
</a>  var ieVersion = (function() {
    var v = -1;
    if (navigator.appName === "Microsoft Internet Explorer") {
      var ua = navigator.userAgent;
      var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
      if (re.exec(ua) !== null) v = parseFloat(RegExp.$1);
    }
    return v;
  })();
  // Check for oninput support
  // IE9 supports oninput, but not when deleting text, so keyup is used.
  // onpropertychange _is_ supported by IE8/9, but may not be fired unless
  // attached with 'attachEvent'
  // (see: <a href="http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire">http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire</a>),
  // and so is avoided altogether.
  var inputSupported = "oninput" in document.createElement("input") &amp;&amp; ieVersion !== 9;
  Expanding.prototype = {
    // Attaches input events
    // Only attaches 'keyup' events if 'input' is not fully suported
    attach: function() {
      var events = 'input.expanding change.expanding',
        _this = this;
      if(!inputSupported) events += ' keyup.expanding';
      this.$textarea.bind(events, function() { _this.update(); });
    },
    // Updates the clone with the textarea value
    update: function() {
      this.$textCopy.text(this.$textarea.val().replace(/
/g, "
"));
      // Use 'triggerHandler' to prevent conflicts with 'update' in Prototype.js
      this.$textarea.triggerHandler("update.expanding");
    },
    // Tears down the plugin: removes generated elements, applies styles
    // that were prevously present, removes instance from registry,
    // unbinds events
    destroy: function() {
      this.$clone.remove();
      this.$textarea
        .unwrap()
        .attr('style', this._oldTextareaStyles || '');
      delete this._oldTextareaStyles;
      var index = $.inArray(this, Expanding._registry);
      if (index > -1) Expanding._registry.splice(index, 1);
      this.$textarea.unbind(
        'input.expanding change.expanding keyup.expanding update.expanding');
    },
    // Applies reset styles to the textarea and clone
    // Stores the original textarea styles in case of destroying
    _resetStyles: function() {
      this._oldTextareaStyles = this.$textarea.attr('style');
      this.$textarea.add(this.$clone).css({
        margin: 0,
        webkitBoxSizing: "border-box",
        mozBoxSizing: "border-box",
        boxSizing: "border-box",
        width: "100%"
      });
    },
    // Sets the basic clone styles and copies styles over from the textarea
    _setCloneStyles: function() {
      var css = {
        display: 'block',
        border: '0 solid',
        visibility: 'hidden',
        minHeight: this.$textarea.outerHeight()
      };
      if(this.$textarea.attr("wrap") === "off") css.overflowX = "scroll";
      else css.whiteSpace = "pre-wrap";
      this.$clone.css(css);
      this._copyTextareaStylesToClone();
    },
    _copyTextareaStylesToClone: function() {
      var _this = this,
        properties = [
          'lineHeight', 'textDecoration', 'letterSpacing',
          'fontSize', 'fontFamily', 'fontStyle',
          'fontWeight', 'textTransform', 'textAlign',
          'direction', 'wordSpacing', 'fontSizeAdjust',
          'wordWrap', 'word-break',
          'borderLeftWidth', 'borderRightWidth',
          'borderTopWidth','borderBottomWidth',
          'paddingLeft', 'paddingRight',
          'paddingTop','paddingBottom', 'maxHeight'];
      $.each(properties, function(i, property) {
        var val = _this.$textarea.css(property);
        // Prevent overriding percentage css values.
        if(_this.$clone.css(property) !== val) {
          _this.$clone.css(property, val);
          if(property === 'maxHeight' &amp;&amp; val !== 'none') {
            _this.$clone.css('overflow', 'hidden');
          }
        }
      });
    },
    _setTextareaStyles: function() {
      this.$textarea.css({
        position: "absolute",
        top: 0,
        left: 0,
        height: "100%",
        resize: "none",
        overflow: "auto"
      });
    }
  };
  $.expanding = $.extend({
    autoInitialize: true,
    initialSelector: "textarea.expanding",
    opts: {
      update: function() { }
    }
  }, $.expanding || {});
  $.fn.expanding = function(o) {
    if (o === "destroy") {
      this.each(function() {
        var instance = Expanding.getExpandingInstance(this);
        if (instance) instance.destroy();
      });
      return this;
    }
    // Checks to see if any of the given DOM nodes have the
    // expanding behaviour.
    if (o === "active") {
      return !!this.filter(function() {
        return !!Expanding.getExpandingInstance(this);
      }).length;
    }
    var opts = $.extend({ }, $.expanding.opts, o);
    this.filter("textarea").each(function() {
      var visible = this.offsetWidth > 0 || this.offsetHeight > 0,
          initialized = Expanding.getExpandingInstance(this);
      if(visible &amp;&amp; !initialized) new Expanding($(this), opts);
      else {
        if(!visible) _warn("ExpandingTextareas: attempt to initialize an invisible textarea. Call expanding() again once it has been inserted into the page and/or is visible.");
        if(initialized) _warn("ExpandingTextareas: attempt to initialize a textarea that has already been initialized. Subsequent calls are ignored.");
      }
    });
    return this;
  };
  function _warn(text) {
    if(window.console &amp;&amp; console.warn) console.warn(text);
  }
  $(function () {
    if ($.expanding.autoInitialize) {
      $($.expanding.initialSelector).expanding();
    }
  });
}));
// Register the TextExpander snippet
skuid.snippet.registerSnippet('TextExpander',function(){
    var $ = skuid.$;
    var field = arguments[0];
    var value = skuid.utils.decodeHTML(arguments[1]);
    
    skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
   
    field.element.find('textarea').expanding();
});
  1. Save, and preview.

Thank you very much for taking the time to respond.

Do I need to do anything with the Field Renderering? I changed the field rendering to standard on all of the text fields. I also have tried changed the javascript resource from in-line (Snippet) to in-line and then copied and pasted your code, but the text boxes are not expanding.

Any ideas?

You will need to change the Field Renderer on all of your Textarea fields to be “Custom”, and for Render Snippet, enter “TextExpander”.

I just tried that and it isn’t working for me. Here is a screen shot of the how I have it set up. Any ideas of what I might be doing wrong?

That all looks correct. 

It works for field editors but not for tables. Nate, are you using a table?

I tested it out and I have my field editor default mode set to “edit”, but when I change it to “read with inline-edit” it works correctly. Is there a way to change it to expand the text box when the view is in the default mode of “edit”?

Any ideas of how to get this to work with the default mode of “edit”?

Use this code instead for the Inline Resource body, it should work with default mode of “Edit” or “Read with Inline-Edit”.

(All I changed was a little bit at the bottom, changing the Custom Field Renderer Snippet, to wait for the element to be added to the DOM before applying the expanding() plugin. This is a common pitfall for initial edit-mode renderers.)

// Expanding Textareas v0.1.2// MIT License// <a target="_blank" rel="nofollow" href="https://github.com/bgrins/ExpandingTextareas" title="Link: https://github.com/bgrins/ExpandingTextareas">https://github.com/bgrins/ExpandingTextareas</a>
(function(factory) {
  // Add jQuery via AMD registration or browser globals
  if (typeof define === 'function' &amp;&amp; define.amd) {
    define([ 'jquery' ], factory);
  }
  else {
    factory(skuid.$);
  }
}(function ($) {
  var Expanding = function($textarea, opts) {
    Expanding._registry.push(this);
    this.$textarea = $textarea;
    this.$textCopy = $("<span />");
    this.$clone = $("<pre class='expanding-clone'>
</pre>").prepend(this.$textCopy);
    this._resetStyles();
    this._setCloneStyles();
    this._setTextareaStyles();
    $textarea
      .wrap($("<div class='expanding-wrapper' style='position:relative' />"))
      .after(this.$clone);
    this.attach();
    this.update();
    if (opts.update) $textarea.bind("update.expanding", opts.update);
  };
  // Stores (active) 'Expanding' instances
  // Destroyed instances are removed
  Expanding._registry = [];
  // Returns the 'Expanding' instance given a DOM node
  Expanding.getExpandingInstance = function(textarea) {
    var $textareas = $.map(Expanding._registry, function(instance) {
        return instance.$textarea[0];
      }),
      index = $.inArray(textarea, $textareas);
    return index > -1 ? Expanding._registry[index] : null;
  };
  // Returns the version of Internet Explorer or -1
  // (indicating the use of another browser).
  // From: <a target="_blank" rel="nofollow" href="http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA" title="Link httpmsdnmicrosoftcomen-uslibraryms537509vvs85aspxParsingUA">http://msdn.microsoft.com/en-us/library/ms537509(v=vs.85).aspx#ParsingUA
</a>  var ieVersion = (function() {
    var v = -1;
    if (navigator.appName === "Microsoft Internet Explorer") {
      var ua = navigator.userAgent;
      var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
      if (re.exec(ua) !== null) v = parseFloat(RegExp.$1);
    }
    return v;
  })();
  // Check for oninput support
  // IE9 supports oninput, but not when deleting text, so keyup is used.
  // onpropertychange _is_ supported by IE8/9, but may not be fired unless
  // attached with 'attachEvent'
  // (see: <a target="_blank" rel="nofollow" href="http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire">http://stackoverflow.com/questions/18436424/ie-onpropertychange-event-doesnt-fire</a>),
  // and so is avoided altogether.
  var inputSupported = "oninput" in document.createElement("input") &amp;&amp; ieVersion !== 9;
  Expanding.prototype = {
    // Attaches input events
    // Only attaches 'keyup' events if 'input' is not fully suported
    attach: function() {
      var events = 'input.expanding change.expanding',
        _this = this;
      if(!inputSupported) events += ' keyup.expanding';
      this.$textarea.bind(events, function() { _this.update(); });
    },
    // Updates the clone with the textarea value
    update: function() {
      this.$textCopy.text(this.$textarea.val().replace(/
/g, "
"));
      // Use 'triggerHandler' to prevent conflicts with 'update' in Prototype.js
      this.$textarea.triggerHandler("update.expanding");
    },
    // Tears down the plugin: removes generated elements, applies styles
    // that were prevously present, removes instance from registry,
    // unbinds events
    destroy: function() {
      this.$clone.remove();
      this.$textarea
        .unwrap()
        .attr('style', this._oldTextareaStyles || '');
      delete this._oldTextareaStyles;
      var index = $.inArray(this, Expanding._registry);
      if (index > -1) Expanding._registry.splice(index, 1);
      this.$textarea.unbind(
        'input.expanding change.expanding keyup.expanding update.expanding');
    },
    // Applies reset styles to the textarea and clone
    // Stores the original textarea styles in case of destroying
    _resetStyles: function() {
      this._oldTextareaStyles = this.$textarea.attr('style');
      this.$textarea.add(this.$clone).css({
        margin: 0,
        webkitBoxSizing: "border-box",
        mozBoxSizing: "border-box",
        boxSizing: "border-box",
        width: "100%"
      });
    },
    // Sets the basic clone styles and copies styles over from the textarea
    _setCloneStyles: function() {
      var css = {
        display: 'block',
        border: '0 solid',
        visibility: 'hidden',
        minHeight: this.$textarea.outerHeight()
      };
      if(this.$textarea.attr("wrap") === "off") css.overflowX = "scroll";
      else css.whiteSpace = "pre-wrap";
      this.$clone.css(css);
      this._copyTextareaStylesToClone();
    },
    _copyTextareaStylesToClone: function() {
      var _this = this,
        properties = [
          'lineHeight', 'textDecoration', 'letterSpacing',
          'fontSize', 'fontFamily', 'fontStyle',
          'fontWeight', 'textTransform', 'textAlign',
          'direction', 'wordSpacing', 'fontSizeAdjust',
          'wordWrap', 'word-break',
          'borderLeftWidth', 'borderRightWidth',
          'borderTopWidth','borderBottomWidth',
          'paddingLeft', 'paddingRight',
          'paddingTop','paddingBottom', 'maxHeight'];
      $.each(properties, function(i, property) {
        var val = _this.$textarea.css(property);
        // Prevent overriding percentage css values.
        if(_this.$clone.css(property) !== val) {
          _this.$clone.css(property, val);
          if(property === 'maxHeight' &amp;&amp; val !== 'none') {
            _this.$clone.css('overflow', 'hidden');
          }
        }
      });
    },
    _setTextareaStyles: function() {
      this.$textarea.css({
        position: "absolute",
        top: 0,
        left: 0,
        height: "100%",
        resize: "none",
        overflow: "auto"
      });
    }
  };
  $.expanding = $.extend({
    autoInitialize: true,
    initialSelector: "textarea.expanding",
    opts: {
      update: function() { }
    }
  }, $.expanding || {});
  $.fn.expanding = function(o) {
    if (o === "destroy") {
      this.each(function() {
        var instance = Expanding.getExpandingInstance(this);
        if (instance) instance.destroy();
      });
      return this;
    }
    // Checks to see if any of the given DOM nodes have the
    // expanding behaviour.
    if (o === "active") {
      return !!this.filter(function() {
        return !!Expanding.getExpandingInstance(this);
      }).length;
    }
    var opts = $.extend({ }, $.expanding.opts, o);
    this.filter("textarea").each(function() {
      var visible = this.offsetWidth > 0 || this.offsetHeight > 0,
          initialized = Expanding.getExpandingInstance(this);
      if(visible &amp;&amp; !initialized) new Expanding($(this), opts);
      else {
        if(!visible) _warn("ExpandingTextareas: attempt to initialize an invisible textarea. Call expanding() again once it has been inserted into the page and/or is visible.");
        if(initialized) _warn("ExpandingTextareas: attempt to initialize a textarea that has already been initialized. Subsequent calls are ignored.");
      }
    });
    return this;
  };
  function _warn(text) {
    if(window.console &amp;&amp; console.warn) console.warn(text);
  }
  $(function () {
    if ($.expanding.autoInitialize) {
      $($.expanding.initialSelector).expanding();
    }
  });
}));
(function(skuid){
    // Register the TextExpander snippet
    skuid.snippet.registerSnippet('TextExpander',function(){
    var $ = skuid.$;
    var field = arguments[0];
    var value = skuid.utils.decodeHTML(arguments[1]);
    
    skuid.ui.fieldRenderers[field.metadata.displaytype][field.mode](field,value);
   
   if (!field.element.parent().length) {
       setTimeout(function(){
          field.element.find('textarea').expanding(); 
       },1500);   
   } else {
       field.element.find('textarea').expanding(); 
   }
    
});
})(skuid);

Thank you very much! That did the trick!

Emily,

This is great! One question. I removed the ‘+ value +’ section because it showed “null” in my text box instead of the text box being blank. The text box is now glitchy. You have to copy and paste things twice in order for it to show in the text box. Do you know how I can fix the glitches but keep the text box blank on page load?

Tami - I think that’s because you are in a new data entry scenario.  Right? In that case the Value is null.  I think you need to check whether Value is present and if not - define the value field with some hard coding,  maybe just a space,  maybe a prepopulated text.

This way the expanding text box can carry a value - regardless of whether or not there is anything in the data. 

Hi Rob,

You are correct. I tried defining the value field with some hard coding but that is where the glitches came in. So if I defined value as a sting or spaces so it is blank, then when I go to enter new data into that field you have to click twice in order to type in the box.

For example I have a list of items I want to paste in the expandable box. I click in the box and click paste. Nothing happens. I have to put my cursor in the box again and paste. Then the data sticks.

I experienced the same issue Nate did with it allowing me to type one character and then the focus of the cursor goes somewhere else on the page. I tried the above code but the text box does not expand. Will the above code work for a text box?

Originally I just used just the skuid portion of the code as an inline snippet. It expanded a text box but the pesky not being able to type thing became an issue:

var $ = skuid.$, field = arguments[0], value = arguments[1];

var model = field.model, row = field.row; var containerDiv = field.element; var fieldText = $('<textarea class="expanding">' + value + '</textarea>'); //Update field value when text is changed $(fieldText).bind('input propertychange', function() { var fieldsToUpdate = {}; fieldsToUpdate[field.id] = $(this).val(); model.updateRow(row, fieldsToUpdate); }); $(containerDiv).append(fieldText);

Our experience with the scenario you describe is as follows. 
1. You have a template with an iFrame somewhere else on your page that is tied to this same model. 
2. When you type a character - the model detects changes, the template says “Ooh - I saw changes and need to let my iFrame know about it” and focus is grabbed by the template. 
3. Having lost focus on your text box, you do somthing like hit the back-space and your browser takes you back a page.   ACK!

So tie the template to another model (even if it sourcing exactly the same data from the same objects)… 

And yes - Text Fields should work with the code above. 

Hi Rob,

I understand what you are saying about what is happening. However, I don’t think I have anything else tied to this model. This model has one field “Invoice Number”. That field is in a field editor (inside a panel set).

I use this field to filter data in another table. The other table is attached to a different model. 

Based on the set up do you see how this could be happening.