Custom JQuery Sortable Accordion With Create/Delete levels - Delete Broke

At a minimum, this removes the the content I wish to be removed.

$(".RemoveSection").click(function(){
	event.stopPropagation();
	$(this).parent().parent().remove();
})

Then I would presume I would need to add the following:

	$( "#accordion" ).accordion( "destroy" );
	create_accordian('#accordion');

However this does not work, the close button does not work on the new accordion levels…

I would also like to be left with a minim of one level

http://rafflebananza.com/assets/global/plugins/SlickGrid-master/examples/xample4-model.html#

Best Regards,
Tim

At the risk of making a fool of myself I think you need something like this:

change:


$(".RemoveSection").click(function(){

To this:


$( ".options-panel" ).on( "click",".RemoveSection", function() {

and then I don’t think you will need the accordion destroy or re-initialise.


$( ".options-panel" ).on( "click",".RemoveSection", function() {
// $(".RemoveSection").click(function(){
	event.stopPropagation();
	$(this).parent().parent().remove();
	// $( "#accordion" ).accordion( "destroy" );
	// create_accordian('#accordion');
})
    //$('.RemoveSection').click(function(event){

etc.....

I’m sure that when one of the JS experts look in they can tidy this up for you :slight_smile:

I’ve just updated the live version with:

$( ".options-panel" ).on( "click",".RemoveSection", function() {
	event.stopPropagation();
	$(this).parent().parent().remove();
})

Add a row and then delete number two and try to expand number 1.

Yes it looks as though you do need to start the whole thing again.

e.g.


$( ".options-panel" ).on( "click",".RemoveSection", function() {
	event.stopPropagation();
	$(this).parent().parent().remove();
[B]   $( "#accordion" ).accordion( "destroy" );
    create_accordian('#accordion');[/B]
})


That seems to work but I can’t help feeling there’s a better way to do this rather than destroying and re-creating it each time. Maybe @Pullo or Paul can help?

In jQuery UI 1.10.0 a new method refresh was implemented to refresh the accordion in such a case.

I tried adding this to your site, but it introduced some unexpected behaviour (in that the panel heights were then calculated incorrectly).

Looking at the code, there are several things that could be improved upon, for example this humungous lump of inline HTML could be replaced by a template of some sort:

$(InputsWrapper).append('<div class="group"><h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" role="tab" aria-expanded="false" aria-selected="false" tabindex="0"><span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#"><span id="accordionheadder">Column 1</span></a></h3><div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" role="tabpanel" style="display: none;"><div class="group"><div class="boo"><span id="CoulmTitle">Column 1</span><br><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Title"><label for="username">Please enter the title for the data under this column</label></div><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Width (px)"><label for="username">Please enter initial (page load) width for this column</label></div></div><div class="row"><div class="dropdown"><select id="age" name="age"><option>&nbsp;&nbsp;&nbsp;&nbsp;Column Input Type</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input</option><option>&nbsp;&nbsp;Descriptive Text Input</option><option> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Check/Tick</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker</option></select></div></div></div></div></div>');

If you fancy refactoring your code somewhat, let me know and I’m sure that in so doing, we can incorporate the newer version of jQuery UI and the refresh method.

If this is something you just want to work and not to have to think about any further, then simply go with what Paul suggested.

Thanks Pullo for jumping in :slight_smile:

I would love any opportunity to have assistance in creating content for my new NGO acting charitable organisation. My plan is to work as much as my abilities will take me with help where I can find it, however, maybe I thought I could do more than what I first thought and I wouldn’t want to use up all your time.

Updated to my server here is what I am trying to achieve.

  1. Column Title edits header title
    [LIST]
  2. Works on all as long as ID starts with ‘ColumTitle_’
    [/LIST]
  3. Pixels and percentage fields modify each other
    [LIST]
  4. I’ve only been able to get this to work for one, not multiple.
    [/LIST]
  5. Adding new column function
    [LIST]
  6. Currently does not but should work exactly the same as the others.
    [/LIST]
  7. delete function
    [LIST]
  8. Should only delete if there are more than one available
    [/LIST]
  9. Expandable and sortable

Any help with the following or as suggested with sorting of what must be my newbie messy ways then I would be very grateful.

Best Regards,
Tim

Hey,

Well, we have two things here - the slick grid and the accordion.

I would suggest splitting this in two and looking at the accordion first.

Could you make a test page with just the accordion and the necessary JavaScript?

Yes sure, the Slickgrid I’ve not been working on, eventually it will work with it but not at the moment. I’ll post in 5 mins or so, going to remove the Slickgrid.

Slickgrid is a later date thing, this will be too advanced for me to actually edit the table writing data into a file and whatnot.

http://rafflebananza.com/assets/global/plugins/SlickGrid-master/examples/TableEditor.html

Kept in the style sheets as some slickgrid styles effect this page, mainly my modifications in example.css.

Ok, well let’s start with running your code through the W3C validator.
It produces 5 errors:

Line 30, Column 113: Stray end tag input.
&#8230;e="text" name="mytext[]" id="ColumnTitle_1" placeholder="Column Title"></input>

Error Line 34, Column 132: Stray end tag input.
&#8230;text[]" id="Pixels_1" placeholder="px" style="width:80px; float:left;"></input>

Error Line 36, Column 135: Stray end tag input.
&#8230;t[]" id="Percentage_1" placeholder="%" style="width:80px; float:left;"></input>

Error Line 31, Column 46: The for attribute of the label element must refer to a form control.
&#8230;                 <label for="username">Please enter the title for the data und&#8230;

Error Line 37, Column 46: The for attribute of the label element must refer to a form control.
&#8230;                 <label for="username">Please enter initial (page load) width &#8230;

Let’s fix those by removing the closing input tags (not necessary) and by removing the for attributes.
We can also remove the commented out code and fix the indentation, so that things are easier to read.

Another thing I’ve done is to remove superfluous comments, e.g.

var MaxInputs = 8; //maximum input boxes allowed

becomes:

var MaxInputs = 8;

as the name MaxInputs speaks for itself.

This, gives us this:

<!DOCTYPE HTML>
<html>
  <head>
    <base href="http://rafflebananza.com/assets/global/plugins/SlickGrid-master/examples/" />
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>SlickGrid example 5: Refactoring</title>
    <link rel="stylesheet" href="../slick.grid.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.pager.css" type="text/css" />
    <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css" />
    <link rel="stylesheet" href="examples.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.columnpicker.css" type="text/css" />
  </head>

  <body>
    <div>
      <div class="options-panel">
        <b>Edit Columns</b>
        <hr/>
        <div id='accordion'>
          <div class='group'>
            <h3>
              <span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span>
              <a href='#' class="headertitle"><span id="accordionheadder">Column 1</span></a>
            </h3>
            <div>
              <div class='group'>
                <div class="boo">
                  <span id="CoulmTitle">Column 1</span><br/>
                  <div class="row">
                    <input type="text" name="mytext[]" id="ColumnTitle_1" placeholder="Column Title">
                    <label>Please enter the title for the data under this column</label>
                  </div>
                  <div class="row">
                    <input type="number" name="mytext[]" id="Pixels_1" placeholder="px" style="width:80px; float:left;">
                    <div style="height:27px; width:35px;float:left;padding-top:10px; text-align:center; font-size:17px; color:#CCC">or</div>
                    <input type="number" name="mytext[]" id="Percentage_1" placeholder="%" style="width:80px; float:left;">
                    <label>Please enter initial (page load) width for this column</label>
                  </div>
                </div>
                <div class="row">
                  <div class="dropdown">
                    <select id="ColumnType_1" name="age">
                      <option selected disabled>
                        &nbsp;&nbsp;&nbsp;&nbsp;Column Input Type
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input
                      </option>
                      <option>
                        &nbsp;&nbsp;Descriptive Text Input
                      </option>
                      <option> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Check/Tick</option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker
                      </option>
                    </select>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="AddNewColumn" id="AddButton">
          <div class="ui-accordion ui-widget ui-helper-reset ui-accordion-icons ui-sortable" role="tablist">
            <div class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
              <div class="group">
                <h3>
                  <span class="ui-icon ui-icon-plus"></span>
                  <a href='#'>Add New</a>
                </h3>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div id="inlineFilterPanel" style="display:none;background:#dddddd;padding:3px;color:black;">
      Show tasks with title including
      <input type="text" id="txtSearch2">and % at least &nbsp;
      <div style="width:100px;display:inline-block;" id="pcSlider2"></div>
    </div>

    <script src="../lib/jquery-1.7.min.js"></script>
    <script src="../lib/jquery-ui-1.8.16.custom.min.js"></script>
    <script src="../lib/jquery.event.drag-2.2.js"></script>

    <script type="text/javascript">
      $(function() {
        function create_accordian(str) {
          $(str)
          .accordion({
            header: '> div > h3',
            autoHeight: false,
            active: false,
            collapsible: true,
          })
          .sortable({
            axis: 'y',
            handle: 'h3',
            cancel: '.RemoveSection',
            stop: function( event, ui ) {
              // IE doesn't register the blur when sorting
              // so trigger focusout handlers to remove .ui-state-focus
              ui.item.children( 'h3' ).triggerHandler( 'focusout' );
            }
          });
        }

        var MaxInputs = 8; 
        var InputsWrapper = $("#accordion"); 
        var AddButton = $("#AddButton"); 
        var x = InputsWrapper.length; 
        var FieldCount = 1;

        $(AddButton).click(function(e){
          if (x <= MaxInputs){
            FieldCount++; 
            $(InputsWrapper).append('<div class="group"><h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" role="tab" aria-expanded="false" aria-selected="false" tabindex="0"><span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#"><span id="accordionheadder">Column 1</span></a></h3><div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" role="tabpanel" style="display: none;"><div class="group"><div class="boo"><span id="CoulmTitle">Column 1</span><br><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Title"><label for="username">Please enter the title for the data under this column</label></div><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Width (px)"><label for="username">Please enter initial (page load) width for this column</label></div></div><div class="row"><div class="dropdown"><select id="age" name="age"><option>&nbsp;&nbsp;&nbsp;&nbsp;Column Input Type</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input</option><option>&nbsp;&nbsp;Descriptive Text Input</option><option> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Check/Tick</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker</option></select></div></div></div></div></div>');
            $( "#accordion" ).accordion( "destroy" );
            create_accordian('#accordion');
            x++; //text box increment
          }

          var ColumLength = $("span[id*=CoulmTitle]").length;
          
          if (ColumLength == 1) {
            $("span[id*=CoulmTitle]:first").html("Column 1");
          }

          for (var i = 1; i < ColumLength; i++) {
            $("span[id*=CoulmTitle]").each(function () {
              $(this).html("Column " + i + "");
              i++;
            });
          }

          for (var i = 1; i < ColumLength; i++) {
            $("span[id*=accordionheadder]").each(function () {
              $(this).html("Column " + i + "");
              i++;
            })
          }
          return false;
        });

        $(".options-panel").on("click", ".RemoveSection", function() {
          event.stopPropagation();
          $(this).parent().parent().remove();
          $( "#accordion" ).accordion( "destroy" );
          create_accordian('#accordion');
        })

        $(document).on('keyup', 'input[id^="ColumnTitle"]', function () {
          var value = this.value.length > 0?true:false;
          if(value){
            $(this).closest('[role="tabpanel"]').prev().find('#accordionheadder').text(this.value);
            $(this).parents('.boo').find('#CoulmTitle').text(this.value);
          }
        });

        var X = 542;
        var inp1 = document.getElementById('Pixels_1'),
            inp2 = document.getElementById('Percentage_1');

        inp1.onchange = function() {
          var num = this.value = Math.max(Math.min(this.value, X), 0);
          inp2.value = Math.floor(num / X * 100);
        };

        inp2.onchange = function() {
          var num = this.value = Math.max(Math.min(this.value, 100), 0);
          inp1.value = Math.floor(num * X / 100);
        };

        $('.RemoveSection').hover(function(){ 
          $(this).parent().css({'background':'url("http://code.jquery.com/ui/1.8.23/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png") repeat-x scroll 50% 50% #E6E6E6','color':'#555555','border':'1px solid #D3D3D3'}); 
        }, function(){ 
          $(this).parent().removeAttr('style'); 
        });

        $('input').focus(function() {
          if ($(this).val() == "Column Title") {
            $(this).closest('[role="tabpanel"]').prev().find('#accordionheadder').text('Untitled Column');
            $(this).parents('.boo').find('#CoulmTitle').text('Untitled Column');
          };
        });

        create_accordian('#accordion');
        create_accordian('#accordion1');
        create_accordian('#accordion2');
      });
    </script>
  </body>
</html>

Which is already a bit easier to work with.

Is that ok so far or do you have any questions?

This is pretty straight forward so far.I forgot about those closing inputs,I did not think they were needed but JSFiddle likes them… I’ve uploaded the new code to the server, thank you.

No problemo :slight_smile:

So, before we get on to the JavaScript, let’s remove the inline CSS.

Basically inline anything is horrible and you should aim for a separation of concerns.
This will make maintaining your app that much easier in the long run.

To illustrate what I mean, in the following inline CSS, the height declaration is not applied, as you have forgotten the colon.

<span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;">

With the following formatting, it becomes obvious:

.RemoveSection{
  z-index: 99999;
  position: absolute;
  margin-left: 430px;
  top: 7px;
  width: 32px;
  height: 32px;
}

This declaration actually caused the button to get pushed down, so I removed it.

Anyway, this gives us:

<!DOCTYPE HTML>
<html>
  <head>
    <base href="http://rafflebananza.com/assets/global/plugins/SlickGrid-master/examples/" />
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>SlickGrid example 5: Refactoring</title>
    <link rel="stylesheet" href="../slick.grid.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.pager.css" type="text/css" />
    <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css" />
    <link rel="stylesheet" href="examples.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.columnpicker.css" type="text/css" />
    <style>
      .RemoveSection{
        z-index: 99999;
        position: absolute;
        margin-left: 430px;
        top: 7px;
        width: 32px;
      }
      #Pixels_1, #Percentage_1{
        width: 80px; 
        float: left;
      }
      div.divider{
        height: 27px; 
        width: 35px;
        float: left;
        padding-top: 10px; 
        text-align: center; 
        font-size: 17px; 
        color: #CCC;
      }
      #pcSlider2{
        width: 100px;
        display: inline-block; 
      }
      #inlineFilterPanel{
        display: none;
        background: #DDD;
        padding: 3px;
        color: black;
      }
    </style>
  </head>

  <body>
    <div>
      <div class="options-panel">
        <strong>Edit Columns</strong>
        <hr/>
        <div id='accordion'>
          <div class='group'>
            <h3>
              <span class="RemoveSection" style=""><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span>
              <a href='#' class="headertitle"><span id="accordionheadder">Column 1</span></a>
            </h3>
            <div>
              <div class='group'>
                <div class="boo">
                  <span id="CoulmTitle">Column 1</span><br/>
                  <div class="row">
                    <input type="text" name="mytext[]" id="ColumnTitle_1" placeholder="Column Title">
                    <label>Please enter the title for the data under this column</label>
                  </div>
                  <div class="row">
                    <input type="number" name="mytext[]" id="Pixels_1" placeholder="px">
                    <div class="divider">or</div>
                    <input type="number" name="mytext[]" id="Percentage_1" placeholder="%">
                    <label>Please enter initial (page load) width for this column</label>
                  </div>
                </div>
                <div class="row">
                  <div class="dropdown">
                    <select id="ColumnType_1" name="age">
                      <option selected>
                        &nbsp;&nbsp;&nbsp;&nbsp;Column Input Type
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input
                      </option>
                      <option>
                        &nbsp;&nbsp;Descriptive Text Input
                      </option>
                      <option> 
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check/Tick
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker
                      </option>
                    </select>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="AddNewColumn" id="AddButton">
          <div class="ui-accordion ui-widget ui-helper-reset ui-accordion-icons ui-sortable" role="tablist">
            <div class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
              <div class="group">
                <h3>
                  <span class="ui-icon ui-icon-plus"></span>
                  <a href='#'>Add New</a>
                </h3>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <div id="inlineFilterPanel">
      Show tasks with title including
      <input type="text" id="txtSearch2">and % at least
      <div id="pcSlider2"></div>
    </div>

    <script src="../lib/jquery-1.7.min.js"></script>
    <script src="../lib/jquery-ui-1.8.16.custom.min.js"></script>
    <script src="../lib/jquery.event.drag-2.2.js"></script>

    <script type="text/javascript">
      $(function() {
        function create_accordian(str) {
          $(str)
          .accordion({
            header: '> div > h3',
            autoHeight: false,
            active: false,
            collapsible: true,
          })
          .sortable({
            axis: 'y',
            handle: 'h3',
            cancel: '.RemoveSection',
            stop: function( event, ui ) {
              // IE doesn't register the blur when sorting
              // so trigger focusout handlers to remove .ui-state-focus
              ui.item.children( 'h3' ).triggerHandler( 'focusout' );
            }
          });
        }

        var MaxInputs = 8; 
        var InputsWrapper = $("#accordion"); 
        var AddButton = $("#AddButton"); 
        var x = InputsWrapper.length; 
        var FieldCount = 1;

        $(AddButton).click(function(e){
          if (x <= MaxInputs){
            FieldCount++; 
            $(InputsWrapper).append('<div class="group"><h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" role="tab" aria-expanded="false" aria-selected="false" tabindex="0"><span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#"><span id="accordionheadder">Column 1</span></a></h3><div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" role="tabpanel" style="display: none;"><div class="group"><div class="boo"><span id="CoulmTitle">Column 1</span><br><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Title"><label for="username">Please enter the title for the data under this column</label></div><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Width (px)"><label for="username">Please enter initial (page load) width for this column</label></div></div><div class="row"><div class="dropdown"><select id="age" name="age"><option>&nbsp;&nbsp;&nbsp;&nbsp;Column Input Type</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input</option><option>&nbsp;&nbsp;Descriptive Text Input</option><option> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Check/Tick</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker</option></select></div></div></div></div></div>');
            $( "#accordion" ).accordion( "destroy" );
            create_accordian('#accordion');
            x++; //text box increment
          }

          var ColumLength = $("span[id*=CoulmTitle]").length;
          
          if (ColumLength == 1) {
            $("span[id*=CoulmTitle]:first").html("Column 1");
          }

          for (var i = 1; i < ColumLength; i++) {
            $("span[id*=CoulmTitle]").each(function () {
              $(this).html("Column " + i + "");
              i++;
            });
          }

          for (var i = 1; i < ColumLength; i++) {
            $("span[id*=accordionheadder]").each(function () {
              $(this).html("Column " + i + "");
              i++;
            })
          }
          return false;
        });

        $(".options-panel").on("click", ".RemoveSection", function() {
          event.stopPropagation();
          $(this).parent().parent().remove();
          $( "#accordion" ).accordion( "destroy" );
          create_accordian('#accordion');
        })

        $(document).on('keyup', 'input[id^="ColumnTitle"]', function () {
          var value = this.value.length > 0?true:false;
          if(value){
            $(this).closest('[role="tabpanel"]').prev().find('#accordionheadder').text(this.value);
            $(this).parents('.boo').find('#CoulmTitle').text(this.value);
          }
        });

        var X = 542;
        var inp1 = document.getElementById('Pixels_1'),
            inp2 = document.getElementById('Percentage_1');

        inp1.onchange = function() {
          var num = this.value = Math.max(Math.min(this.value, X), 0);
          inp2.value = Math.floor(num / X * 100);
        };

        inp2.onchange = function() {
          var num = this.value = Math.max(Math.min(this.value, 100), 0);
          inp1.value = Math.floor(num * X / 100);
        };

        $('.RemoveSection').hover(function(){ 
          $(this).parent().css({'background':'url("http://code.jquery.com/ui/1.8.23/themes/base/images/ui-bg_glass_75_e6e6e6_1x400.png") repeat-x scroll 50% 50% #E6E6E6','color':'#555555','border':'1px solid #D3D3D3'}); 
        }, function(){ 
          $(this).parent().removeAttr('style'); 
        });

        $('input').focus(function() {
          if ($(this).val() == "Column Title") {
            $(this).closest('[role="tabpanel"]').prev().find('#accordionheadder').text('Untitled Column');
            $(this).parents('.boo').find('#CoulmTitle').text('Untitled Column');
          };
        });

        create_accordian('#accordion');
        create_accordian('#accordion1');
        create_accordian('#accordion2');
      });
    </script>
  </body>
</html>

@Paul_O_B ;
Is there any way to center the options in the select element using CSS. I don’t like all of those non-breaking spaces.

@MrTIMarshall ;
So, apart from be able to dynamically add and remove rows, is there anything else this accordion needs to be able to do that I’m not aware of?

I did not know this was not good to use, this is one which I am surprised about!

I know this is messy, I understand that there is no other way, text-align on a select is not currently cross-browser. It works with firefox but not with chrome. This is the best I found without making your own drop-down.

Yup, you’ll see why in a bit when we get to refactoring the JavaScript.
I’m a bit busy right now, but watch this space and I’ll post more either tonight or tomorrow.

It’s taking a long time to set up this website and it will take at a minimum another year. You are helping which I am very grateful for, sparing your own time. I don’t expect you to be there 24/7, I just thank you for the time which you can help. :slight_smile:

You can do it in Firefox as you might expect.


select, option {
    text-align: center;
}

But Chrome and IE don’t allow it to be centred and I don’t believe there is any solution to this other than select replacement script.

Ok, let’s leave the &nbsp; characters where they are then.

Back to your script, I made the following changes:

I bumped the versions of jQuery and jQuery UI. I also extracted the JS into its own file:

<script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>

Then, in the JavaScript I did the following:

var $newRow = $("#accordion").html();

$("#AddButton").on("click", function(event){
  event.preventDefault();
  $("#accordion").append($newRow).accordion("refresh");
});

Now $newRow holds a reference to the HTML we need to insert when a user clicks on “Add New”, so we can get rid of:

$(InputsWrapper).append('<div class="group"><h3 class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all" role="tab" aria-expanded="false" aria-selected="false" tabindex="0"><span class="RemoveSection" style="z-index:99999;position:absolute;margin-left:430px;top:7px;width:32px;height32px;"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span><span class="ui-icon ui-icon-triangle-1-e"></span><a href="#"><span id="accordionheadder">Column 1</span></a></h3><div class="ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom" role="tabpanel" style="display: none;"><div class="group"><div class="boo"><span id="CoulmTitle">Column 1</span><br><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Title"><label for="username">Please enter the title for the data under this column</label></div><div class="row"><input type="text" name="mytext[]" id="field_1" value="Column Width (px)"><label for="username">Please enter initial (page load) width for this column</label></div></div><div class="row"><div class="dropdown"><select id="age" name="age"><option>&nbsp;&nbsp;&nbsp;&nbsp;Column Input Type</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input</option><option>&nbsp;&nbsp;Descriptive Text Input</option><option> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Check/Tick</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar</option><option>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker</option></select></div></div></div></div></div>')
;

Although, for this to work fully, I had to change a couple of ids into classes (as ids are unique to a page).

We can also take advantage of the .refresh() method to avoid permanently destroying and re-initializing the accordion.

Here’s what we have so far:

<!DOCTYPE HTML>
<html>
  <head>
    <base href="http://rafflebananza.com/assets/global/plugins/SlickGrid-master/examples/" />
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>SlickGrid example 5: Refactoring</title>
    <link rel="stylesheet" href="../slick.grid.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.pager.css" type="text/css" />
    <link rel="stylesheet" href="../css/smoothness/jquery-ui-1.8.16.custom.css" type="text/css" />
    <link rel="stylesheet" href="examples.css" type="text/css" />
    <link rel="stylesheet" href="../controls/slick.columnpicker.css" type="text/css" />
    <style>
      .removeSection{
        z-index: 99999;
        position: absolute;
        margin-left: 430px;
        top: 7px;
        width: 32px;
      }
      .pixels, .percentage{
        width: 80px; 
        float: left;
      }
      div.divider{
        height: 27px; 
        width: 35px;
        float: left;
        padding-top: 10px; 
        text-align: center; 
        font-size: 17px; 
        color: #CCC;
      }
      .accordionHeader{
        position: relative;
        left: 15px;
      }
    </style>
  </head>

  <body>
    <div>
      <div class="options-panel">
        <strong>Edit Columns</strong>
        <hr/>
        <div id="accordion">
          <div class="group">
            <h3>
              <span class="removeSection"><a href="#" class="removeclass"><span class="ui-icon ui-icon-circle-close"></span></a></span>
              <a href="#" class="headertitle"><span class="accordionHeader">Column 1</span></a>
            </h3>
            <div>
              <div class="group">
                <div class="boo">
                  <span class="columnTitle">Column 1</span><br/>
                  <div class="row">
                    <input type="text" name="mytext[]" class="columnTitle" placeholder="Column Title">
                    <label>Please enter the title for the data under this column</label>
                  </div>
                  <div class="row">
                    <input type="number" name="mytext[]" class="pixels" placeholder="px">
                    <div class="divider">or</div>
                    <input type="number" name="mytext[]" class="percentage" placeholder="%">
                    <label>Please enter initial (page load) width for this column</label>
                  </div>
                </div>
                <div class="row">
                  <div class="dropdown">
                    <select name="age">
                      <option selected>
                        &nbsp;&nbsp;&nbsp;&nbsp;Column Input Type
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Simple Text Input
                      </option>
                      <option>
                        &nbsp;&nbsp;Descriptive Text Input
                      </option>
                      <option> 
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Check/Tick
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Progress Bar
                      </option>
                      <option>
                        &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Date Picker
                      </option>
                    </select>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
        <div class="AddNewColumn" id="AddButton">
          <div class="ui-accordion ui-widget ui-helper-reset ui-accordion-icons ui-sortable" role="tablist">
            <div class="ui-accordion-header ui-helper-reset ui-state-default ui-corner-all">
              <div class="group">
                <h3>
                  <span class="ui-icon ui-icon-plus"></span>
                  <a href="#">Add New</a>
                </h3>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
    <script src="../lib/jquery.event.drag-2.2.js"></script>
    
    <script>
      function create_accordion(str) {
        $(str)
        .accordion({
          header: "> div > h3",
          heightStyle: "content",
          active: false,
          collapsible: true,
        })
        .sortable({
          axis: "y",
          handle: "h3",
          cancel: ".RemoveSection",
          stop: function( event, ui ) {
            // IE doesn't register the blur when sorting
            // so trigger focusout handlers to remove .ui-state-focus
            ui.item.children("h3").triggerHandler("focusout");
          }
        });
      }

      var $newRow = $("#accordion").html();

      $("#AddButton").on("click", function(event){
        event.preventDefault();
        $("#accordion").append($newRow).accordion("refresh");
      });

      create_accordion("#accordion");
    </script>
  </body>
</html>

Demo

The next thing to do is to limit the amount of new accordions that may be added.

In your code you had set it to 8. This meant that the user could add 8, but deleted panels also counted towards the total.

Is it your intention to have deleted panels include in the total?

On the page on which I presume is your server? I’ve noticed the styling is slightly different, only minor alterations, however, you may be looking at implementing this part at a later date but I must ask in case it is something you have missed out?

  1. Column Title should edit the Accordion header title.
  2. Width inputs should effect each other. Var x in the version on my site will be the table width.

Is it your intention to have deleted panels include in the total?

I don’t have a clue what this means exactly. This part of the website is for the administration panel to edit or create a new table. I am thinking able implementing an undo feature if this is anything to do with deleted being saved?..

What do you mean by a deleted panel?

I also forgot to mention the delete function.

I’m going to sleep now as it’s pretty late so I’ll be back on tomorrow morning. Thank you so far for your amazing help!

Best Regards,
Tim