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