diff --git a/components/editorControls/MultipleTextstring/MultipleTextstring.css b/components/editorControls/MultipleTextstring/MultipleTextstring.css
new file mode 100644
index 0000000000..f09eda3acf
--- /dev/null
+++ b/components/editorControls/MultipleTextstring/MultipleTextstring.css
@@ -0,0 +1,33 @@
+.MultipleTextstring
+{
+ float: left;
+ padding-bottom: 5px;
+}
+.MultipleTextstring .textstring-row
+{
+ clear: both;
+ float: left;
+ margin-bottom: 5px;
+ width: 451px;
+}
+.MultipleTextstring .textstring-row .textstring-row-field
+{
+ float: left;
+ width: 435px;
+}
+.MultipleTextstring .textstring-row .textstring-row-sort
+{
+ float: right;
+ cursor: move;
+ padding-top: 2px;
+ height: 18px;
+ width: 16px;
+}
+.MultipleTextstring .textstring-row-placeholder
+{
+ clear: both;
+ float: left;
+ background-color: #FFEE99;
+ margin-bottom: 5px;
+ width: 451px;
+}
diff --git a/components/editorControls/MultipleTextstring/MultipleTextstring.js b/components/editorControls/MultipleTextstring/MultipleTextstring.js
new file mode 100644
index 0000000000..bdd299f856
--- /dev/null
+++ b/components/editorControls/MultipleTextstring/MultipleTextstring.js
@@ -0,0 +1,122 @@
+(function ($) {
+ // jquery plugin for the multiple textstring
+ $.fn.MultipleTextstring = function (hiddenId, minimum, maximum) {
+ var $this = $(this),
+ $hidden = $(hiddenId),
+ $inputs = $this.find('.umbEditorTextField');
+
+ $this.sortable({
+ axis: 'y',
+ containment: $this.closest('.propertyItemContent'),
+ items: '.textstring-row',
+ handle: '.textstring-row-sort',
+ forcePlaceholderSize: true,
+ placeholder: 'textstring-row-placeholder',
+ stop: function (event, ui) {
+ // re-populate the hidden field
+ populateHiddenField();
+ }
+ });
+
+ $this.find('.add_row').click(function () {
+ var $parent = $(this).parent().parent();
+ var $row = $parent.clone(true); // clone the row
+ var $input = $row.find('.umbEditorTextField');
+
+ if ($inputs.length < maximum || maximum <= 0) {
+
+ // clear the text field
+ $input.val('');
+
+ // append the new row
+ $row.insertAfter($parent);
+
+ // set the focus
+ $input.focus();
+
+ // re-populate the hidden field
+ populateHiddenField();
+ }
+
+ return false;
+ });
+
+ $this.find('.remove_row').click(function () {
+
+ // make sure the user wants to remove the row
+ if (confirm('Are you sure you want to delete this row?')) {
+
+ //var $input = $this.find('.umbEditorTextField');
+
+ // check if this is the last row...
+ if ($inputs.length == 1) {
+
+ // ... if so, just clear it.
+ $inputs.val('').focus();
+
+ } else if ($inputs.length > minimum) {
+
+ var $parent = $(this).parent().parent();
+
+ // set the focus
+ $parent.prev().find('.umbEditorTextField').focus();
+
+ // remove the row
+ $parent.remove();
+ }
+
+ // re-populate the hidden field
+ populateHiddenField();
+ }
+
+ return false;
+ });
+
+ $inputs.blur(function () {
+ // re-populate the hidden field
+ populateHiddenField();
+ });
+
+ $inputs.keydown(function (e) {
+ var keyCode = e.keyCode || e.which;
+
+ // if ENTER is pressed
+ if (keyCode == 13) {
+
+ e.preventDefault();
+
+ // add a new row
+ return $(this).parent().find('.add_row').click();
+ }
+
+ // if BACKSPACE if pressed and the textstring value is empty
+ if (keyCode == 8 && $(this).val() == '') {
+
+ e.preventDefault();
+
+ // remove the row
+ return $(this).parent().find('.remove_row').click();
+ }
+
+ });
+
+ function populateHiddenField() {
+ var values = []; // initialise an array of values
+
+ // re-bind the text inputs
+ $inputs = $this.find('.umbEditorTextField');
+
+ // loop through each of the testxtring elements (needs to be a live query)
+ $inputs.each(function () {
+
+ // add the value to the array
+ values.push(this.value);
+
+ });
+
+ // implode the array into the hidden field
+ $hidden.val(values.join('\n'));
+ }
+
+ }
+})(jQuery);
\ No newline at end of file
diff --git a/components/editorControls/MultipleTextstring/MultipleTextstringControl.cs b/components/editorControls/MultipleTextstring/MultipleTextstringControl.cs
index 28083636d0..fb925d4ee1 100644
--- a/components/editorControls/MultipleTextstring/MultipleTextstringControl.cs
+++ b/components/editorControls/MultipleTextstring/MultipleTextstringControl.cs
@@ -10,178 +10,178 @@ using umbraco.cms.businesslogic.datatype;
namespace umbraco.editorControls.MultipleTextstring
{
- ///
- /// The MultipleTextstring control sets a character limit on a TextBox.
- ///
- [ValidationProperty("IsValid")]
- public class MultipleTextstringControl : PlaceHolder
- {
- ///
- /// Field for the list of values.
- ///
- private List values;
+ ///
+ /// The MultipleTextstring control sets a character limit on a TextBox.
+ ///
+ [ValidationProperty("IsValid")]
+ public class MultipleTextstringControl : PlaceHolder
+ {
+ ///
+ /// Field for the list of values.
+ ///
+ private List values;
- ///
- /// The HiddenField to store the selected values.
- ///
- private HiddenField SelectedValues = new HiddenField();
+ ///
+ /// The HiddenField to store the selected values.
+ ///
+ private HiddenField SelectedValues = new HiddenField();
- ///
- /// Gets or sets the options.
- ///
- /// The options.
- public MultipleTextstringOptions Options { get; set; }
+ ///
+ /// Gets or sets the options.
+ ///
+ /// The options.
+ public MultipleTextstringOptions Options { get; set; }
- ///
- /// Gets the value of IsValid.
- ///
- /// Returns 'Valid' if valid, otherwise an empty string.
- public string IsValid
- {
- get
- {
- if (!string.IsNullOrEmpty(this.Values))
- {
- return "Valid";
- }
+ ///
+ /// Gets the value of IsValid.
+ ///
+ /// Returns 'Valid' if valid, otherwise an empty string.
+ public string IsValid
+ {
+ get
+ {
+ if (!string.IsNullOrEmpty(this.Values))
+ {
+ return "Valid";
+ }
- return string.Empty;
- }
- }
+ return string.Empty;
+ }
+ }
- ///
- /// Gets or sets the values.
- ///
- /// The values.
- public string Values
- {
- get
- {
- return this.SelectedValues.Value;
- }
+ ///
+ /// Gets or sets the values.
+ ///
+ /// The values.
+ public string Values
+ {
+ get
+ {
+ return this.SelectedValues.Value;
+ }
- set
- {
- this.SelectedValues.Value = value;
- }
- }
+ set
+ {
+ this.SelectedValues.Value = value;
+ }
+ }
- ///
- /// Initialize the control, make sure children are created
- ///
- /// An object that contains the event data.
- protected override void OnInit(EventArgs e)
- {
- base.OnInit(e);
+ ///
+ /// Initialize the control, make sure children are created
+ ///
+ /// An object that contains the event data.
+ protected override void OnInit(EventArgs e)
+ {
+ base.OnInit(e);
- this.EnsureChildControls();
- }
+ this.EnsureChildControls();
+ }
- ///
- /// Add the resources (sytles/scripts)
- ///
- /// The object that contains the event data.
- protected override void OnLoad(EventArgs e)
- {
- base.OnLoad(e);
+ ///
+ /// Add the resources (sytles/scripts)
+ ///
+ /// The object that contains the event data.
+ protected override void OnLoad(EventArgs e)
+ {
+ base.OnLoad(e);
- // Adds the client dependencies.
- this.AddResourceToClientDependency("umbraco.editorControls.MultipleTextstring.MultipleTextstring.css", ClientDependencyType.Css);
- this.AddResourceToClientDependency("umbraco.editorControls.MultipleTextstring.MultipleTextstring.js", ClientDependencyType.Javascript);
- }
+ // Adds the client dependencies.
+ this.RegisterEmbeddedClientResource("umbraco.editorControls.MultipleTextstring.MultipleTextstring.css", ClientDependencyType.Css);
+ this.RegisterEmbeddedClientResource("umbraco.editorControls.MultipleTextstring.MultipleTextstring.js", ClientDependencyType.Javascript);
+ }
- ///
- /// Raises the event.
- ///
- /// An object that contains the event data.
- protected override void OnPreRender(EventArgs e)
- {
- base.OnPreRender(e);
+ ///
+ /// Raises the event.
+ ///
+ /// An object that contains the event data.
+ protected override void OnPreRender(EventArgs e)
+ {
+ base.OnPreRender(e);
- // initalise the string array/list.
- this.values = new List();
+ // initalise the string array/list.
+ this.values = new List();
- // load the values into a string array/list.
- if (!string.IsNullOrEmpty(this.Values))
- {
- this.values.AddRange(this.Values.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
- }
+ // load the values into a string array/list.
+ if (!string.IsNullOrEmpty(this.Values))
+ {
+ this.values.AddRange(this.Values.Split(new[] { Environment.NewLine }, StringSplitOptions.None));
+ }
- // check the minimum number allowed, add extra fields.
- if (this.values.Count < this.Options.Minimum && this.Options.Minimum > 1)
- {
- this.values.AddRange(new string(',', this.Options.Minimum - 1).Split(new[] { ',' }, StringSplitOptions.None));
- }
+ // check the minimum number allowed, add extra fields.
+ if (this.values.Count < this.Options.Minimum && this.Options.Minimum > 1)
+ {
+ this.values.AddRange(new string(',', this.Options.Minimum - 1).Split(new[] { ',' }, StringSplitOptions.None));
+ }
- // check the maxmimum number allowed, remove the excess.
- if (this.values.Count > this.Options.Maximum && this.Options.Maximum > 0)
- {
- this.values.RemoveRange(this.Options.Maximum, this.values.Count - this.Options.Maximum);
- }
+ // check the maxmimum number allowed, remove the excess.
+ if (this.values.Count > this.Options.Maximum && this.Options.Maximum > 0)
+ {
+ this.values.RemoveRange(this.Options.Maximum, this.values.Count - this.Options.Maximum);
+ }
- // if there are no selected values...
- if (this.values.Count == 0)
- {
- // ... then add an empty string to display a single textstring box.
- this.values.Add(string.Empty);
- }
- }
+ // if there are no selected values...
+ if (this.values.Count == 0)
+ {
+ // ... then add an empty string to display a single textstring box.
+ this.values.Add(string.Empty);
+ }
+ }
- ///
- /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
- ///
- protected override void CreateChildControls()
- {
- base.CreateChildControls();
+ ///
+ /// Called by the ASP.NET page framework to notify server controls that use composition-based implementation to create any child controls they contain in preparation for posting back or rendering.
+ ///
+ protected override void CreateChildControls()
+ {
+ base.CreateChildControls();
- this.EnsureChildControls();
+ this.EnsureChildControls();
- // populate the control's attributes.
- this.SelectedValues.ID = this.SelectedValues.ClientID;
+ // populate the control's attributes.
+ this.SelectedValues.ID = this.SelectedValues.ClientID;
- // add the controls.
- this.Controls.Add(this.SelectedValues);
- }
+ // add the controls.
+ this.Controls.Add(this.SelectedValues);
+ }
- ///
- /// Sends server control content to a provided object, which writes the content to be rendered on the client.
- ///
- /// The object that receives the server control content.
- protected override void Render(HtmlTextWriter writer)
- {
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "MultipleTextstring");
- writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
+ ///
+ /// Sends server control content to a provided object, which writes the content to be rendered on the client.
+ ///
+ /// The object that receives the server control content.
+ protected override void Render(HtmlTextWriter writer)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "MultipleTextstring");
+ writer.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
- // loop through each value
- foreach (string value in this.values)
- {
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "textstring-row");
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
+ // loop through each value
+ foreach (string value in this.values)
+ {
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "textstring-row");
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
- // input tag
- writer.AddAttribute(HtmlTextWriterAttribute.Class, "textstring-row-field");
- writer.RenderBeginTag(HtmlTextWriterTag.Div);
- writer.WriteLine("", value.Replace("'", "'"));
+ // input tag
+ writer.AddAttribute(HtmlTextWriterAttribute.Class, "textstring-row-field");
+ writer.RenderBeginTag(HtmlTextWriterTag.Div);
+ writer.WriteLine("", value.Replace("'", "'"));
- // append the add/remove buttons
- writer.WriteLine("
", GlobalSettings.Path);
- writer.WriteLine("
", GlobalSettings.Path);
- writer.RenderEndTag(); // .textstring-row-field
+ // append the add/remove buttons
+ writer.WriteLine("
", GlobalSettings.Path);
+ writer.WriteLine("
", GlobalSettings.Path);
+ writer.RenderEndTag(); // .textstring-row-field
- writer.WriteLine("", GlobalSettings.Path);
+ writer.WriteLine("", GlobalSettings.Path);
- writer.RenderEndTag(); // .textstring-row
- }
+ writer.RenderEndTag(); // .textstring-row
+ }
- this.SelectedValues.RenderControl(writer);
+ this.SelectedValues.RenderControl(writer);
- writer.RenderEndTag(); // .MultipleTextstring
+ writer.RenderEndTag(); // .MultipleTextstring
- // add jquery window load event
- var javascriptMethod = string.Format("jQuery('#{0}').MultipleTextstring('#{1}', {2}, {3});", this.ClientID, this.SelectedValues.ClientID, this.Options.Minimum, this.Options.Maximum);
- var javascript = string.Concat("");
- writer.WriteLine(javascript);
- }
- }
+ // add jquery window load event
+ var javascriptMethod = string.Format("jQuery('#{0}').MultipleTextstring('#{1}', {2}, {3});", this.ClientID, this.SelectedValues.ClientID, this.Options.Minimum, this.Options.Maximum);
+ var javascript = string.Concat("");
+ writer.WriteLine(javascript);
+ }
+ }
}
\ No newline at end of file