Я хочу добавить TD и TH рядом с моим текущим столбцом. Это должно быть добавлено, когда я нажимаю на ссылки.

Вот HTML:

<section class="yield-report-table">
  <table id="sorting">
    <tr class="headerrow ui-sortable">
      <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(1)</div></th>
      <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(2)</div></th>
    </tr>
    <tr>
      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
        </div>
      </td>

      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
        </div>
      </td> 
    </tr>
  </table> 
</section>

JS:

<script>
  $(function() {
    $('.report-icon-list .cht-add').on("click",function(){
      $i = $(".report-icon-list .cht-add").parents("td").index(this);
      $n = $(".report-icon-list .cht-add").parents("#sorting tr th").index(this);
      $(this).parents("td:eq("+$i+")").after("<td>discription</td>");
      $("#sorting tr th:eq("+$n+")").after("<th>heading</th>");
      alert($n)
  });
</script>

Я могу добавить тд рядом с текущим столбцом. Но они, наконец, добавляются в столбцы tr (row).

Рабочий пример: http://codepen.io/anon/pen/BjoGZm

< Сильный > Ток: введите описание изображения здесь

< Сильный > Ожидаемое : введите описание изображения здесь

4
Praveen 14 Дек 2015 в 13:04

5 ответов

Лучший ответ
$(function() {
    $('.report-icon-list .cht-add').on("click",function(){
        var td = $(this).parent().parent();
        var $i = td.index();
        td.after("<td>discription</td>");
        $("#sorting tr.headerrow > th:eq(" + $i + ")").after("<th>heading</th>");
    });
})

Попробуйте этот код, пожалуйста, это ваша потребность?

1
Zhang Chao 14 Дек 2015 в 10:43

Проверьте это http://jsfiddle.net/rvhgnmgq/1/

$(function() {
$('.report-icon-list .cht-add').on("click",function(){
var cellAndRow = $(this).parents('td,tr');
var cellIndex = cellAndRow[0].cellIndex
var rowIndex = cellAndRow[1].rowIndex;
//alert("cellIndex: "+cellIndex+"\n rowIndex:"+rowIndex);

 $(document.getElementById("sorting").rows[rowIndex].cells[cellIndex]).after("<td>Body Test"+new Date().getSeconds()+"</td>")


  var tr = document.getElementById('sorting').tHead.children[0],
    th = document.createElement('th');
th.innerHTML = "Second"+new Date().getSeconds();
$(tr.children[cellIndex]).after(th);

});

})


<section class="yield-report-table">
    <table id="sorting">
  <thead>
     <tr class="headerrow ui-sortable">
           <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(1)</div></th>
            <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(2)</div></th>
     </tr>
     </thead>
     <tbody>
    <tr>
       <td>
       <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
                           </div>
      </td>

      <td>
       <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
                           </div>
      </td>

    </tr>

    </tbody>

  </table>

</section>
0
HaBo 14 Дек 2015 в 15:00

Вы можете добавить после, прежде чем оба просто использовать раскрывающийся список, чтобы изменить шаблон

$(function() {
  var before = false;
  
  $( "select" ).change(function() {
 if($(this).val() == "before"){
 before = true
 }else{
 before = false
 }
});
    $('.report-icon-list .cht-add').on("click", function() {
        var ele = $(this).parents("td").addClass('selected');
      if(before){
         var i = $('td.selected').before("<td>discription</td>").index()-1

        $( "tr th:eq( "+i+")" ).before("<th>heading</th>");
      }else{
          var i = $('td.selected').after("<td>discription</td>").index()

        $( "tr th:eq( "+i+")" ).after("<th>heading</th>");
      }
       
        ele.removeClass('selected')
        

    });

})
td, th{border:#000 solid 1px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<select>
  <option value="before">before</option>
  <option selected value="after">after</option>
</select>
<section class="yield-report-table">
	<table id="sorting">
     <tr class="headerrow ui-sortable">
           <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(1)</div></th>
            <th class="ui-resizable tac"><div class="ui-resizable">First Year Corn <br>Non Limited N, High Pop(2)</div></th>
     </tr>
    <tr>
       <td>
       <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
	 				       </div>
      </td>
      
      <td class="c">
       <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
	 				       </div>
      </td>
     
    </tr>
    
 
    
  </table>
  
</section>
0
Keval Bhatt 14 Дек 2015 в 11:22

Как насчет этого:

  $(function() {
    $('.report-icon-list .cht-add').on("click",function(){
      var i = $(this).closest('td').index();
      console.log(i);
      $(this).closest('table').find('.headerrow').next('tr').find('td:nth-child('+(i+1)+')').after("<td>discription</td>");
      $(this).closest('table').find('.headerrow th:nth-child('+(i+1)+')').after("<th>heading</th>");
    });

    });

Codepen: http://codepen.io/anon/pen/objJNW

1
madalinivascu 14 Дек 2015 в 10:46

Я подумал, что предложу решение, которое не требует jQuery, хотя оно использует некоторые функции ECMAScript 6 (функции стрелок / жирных стрелок и Array.from()); альтернатива, ES5 / современная браузер-совместимая версия также предлагается ниже. Но, во-первых, решение ES6:

function addColumns() {
  // caching the clicked element,
  // the <a>, passed from the addEventListener()
  // method:
  var clicked = this,

  // retrieving the closest <td> element to the
  // clicked element:
    cell = clicked.closest('td'),

  // retrieving the closest <table> element:
    table = clicked.closest('table'),

  // converting the HTMLCollection of the 
  // table element's rows (HTMLTableElement.rows)
  // into an Array using Array.from():
    rowsArray = Array.from(table.rows),

  // getting the cellIndex of the <td>
  // containing the clicked <a>,
  // HTMLTableCellElement.cellIndex, the
  // index of the <td> amongst its siblings:
    index = cell.cellIndex,

  // three uninitialised variables for use in
  // the following forEach():
    cellType, newCell, next;

  // iterating over the rows of the <table>,
  // using Array.prototype.forEach(); 'row'
  // (the first, and only, argument) is the
  // current array-element of the array over
  // which we're iterating:
  rowsArray.forEach(function(row) {

    // retrieving the element child of the
    // current <tr> element at the index of
    // the clicked element's ancestor cell:
    cellType = row.children[index].tagName;

    // creating a new element of that type:
    newCell = document.createElement(cellType);

    // checking the element-type that was created:
    switch (cellType.toLowerCase()) {

      // if it was a <th>:
      case 'th':

        // we set the 'next' variable to the row's
        // child element at the next index to the
        // affected cell (containing the clicked <a>):
        next = row.children[index + 1];

        // we set the newCell's text-content to 'Header':
        newCell.textContent = 'Header';

        // if there is a sibling at the next index:
        if (next) {

          // we use Node.insertBefore() to insert the
          // newCell before the next-element:
          row.insertBefore(newCell, next);
        } else {

          // otherwise, if there is no 'next' then
          // we simply append the newCell to the
          // <tr> element-node:
          row.appendChild(newCell);
        }

        // causing evaluation to break from the switch:
        break;

      // if it's a <td> however, we:
      case 'td':

        // can simply use HTMLTableRowElement.insertCell()
        // to both create, and insert, a new cell at
        // the given index, 'pushing' subsequent siblings
        // 'along':
        row.insertCell(index + 1);
        break;
    }
  });
}

// getting the relevant links, using document.querySelectorAll():
var links = document.querySelectorAll('a.cht-add'),

  // converting the NodeList to an Array:
  arrayOfLinks = Array.from(links);

// using arrow function syntax to apply
// addEventListener() to each of the <a>
// elements in the array of links, to listen
// for the 'click' event, executing the
// addColumns() function in response:
arrayOfLinks.forEach(link => link.addEventListener('click', addColumns));
function addColumns() {
  var clicked = this,
    cell = clicked.closest('td'),
    table = clicked.closest('table'),
    rowsArray = Array.from(table.rows),
    index = cell.cellIndex,
    cellType, newCell, next;

  rowsArray.forEach(function(row) {
    cellType = row.children[index].tagName;
    newCell = document.createElement(cellType);
    switch (cellType.toLowerCase()) {
      case 'th':
        next = row.children[index + 1];
        newCell.textContent = 'Header';
        if (next) {
          row.insertBefore(newCell, next);
        } else {
          row.appendChild(newCell);
        }
        break;
      case 'td':
        row.insertCell(index + 1);
        break;
    }
  });
}


var links = document.querySelectorAll('a.cht-add'),
  arrayOfLinks = Array.from(links);

arrayOfLinks.forEach(link => link.addEventListener('click', addColumns));
table {
  border-collapse: collapse;
}
th,
td {
  border-bottom: 1px solid #000;
  padding: 0.5em;
}
th + th,
td + td {
  border-left: 1px solid #000;
}
<section class="yield-report-table">
  <table id="sorting">
    <tr class="headerrow ui-sortable">
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(1)</div>
      </th>
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(2)</div>
      </th>
    </tr>
    <tr>
      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
        </div>
      </td>

      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
        </div>
      </td>
    </tr>
  </table>
</section>

Демонстрация JS Fiddle.

Что касается альтернативной реализации, совместимой с ES5 / modern-browser, в приведенном ниже коде я прокомментирую только измененные части; весь некомментированный код остается таким же, как указано выше:

// a simple utillity function to find the closest
// element of a given type,
// startAt:   HTMLElement node,
// elemType:  String, the ancestor element type to
//                    find, with or without angle
//                    brackets, eg: '<div>', 'div'.
function closest(startAt, elemType) {

  // assigning the startAt node to a variable,
  // with which we can iterate through the
  // ancestor nodes:
  var current = startAt,

  // removing any non-alphabet characters from
  // the given String, to turn '<div>' into 'div';
  // the 'g' switch looks globally within the String
  // replacing all matches, the 'i' switch makes
  // the replacement case-insensitive, so 'i' and 'I'
  // will both be retained:
    tag = elemType.replace(/[^a-z]/gi, '');

  // if the tagName of the current element, in lower-case
  // is not equal to the tag we're looking for, and
  // it is not equal to 'html' (the root element):
  while (current.tagName.toLowerCase() !== tag && current.tagName.toLowerCase() !== 'body') {

    // we assign the parentNode of the current
    // node as the current node and the loop
    // continues until the conditions of the
    // while loop become false:
    current = current.parentNode;
  }

  // here we check whether the tagName of the current node,
  // assigned in the last iteration of the while loop, is
  // equal to 'body'; if it is then we return the initial
  // startAt node, if not we return the current node itself
  // to the calling context; this is a personal choice; you
  // may wish to return false, null, or any other value that
  // makes sense to your use-case:
  return current.tagName.toLowerCase() === 'body' ? startAt : current;
}

function addColumns() {
  var clicked = this,

    // instead of clicked.closest('td'), we use the
    // utility function (defined above) to retrieve
    // the closest 'td', and 'table', elements:
    cell = closest(clicked, 'td'),
    table = closest(cell, 'table'),

    // here we use Array.prototype.slice(), applied
    // with Function.prototype.call() to allow us to
    // use an Array method on an Array-like HTMLCollection:
    rowsArray = Array.prototype.slice.call(table.rows, 0),
    index = cell.cellIndex,
    cellType, newCell, next;

  rowsArray.forEach(function(row) {
    cellType = row.children[index].tagName;
    newCell = document.createElement(cellType);
    switch (cellType.toLowerCase()) {
      case 'th':
        next = row.children[index + 1];
        newCell.textContent = 'Header';
        if (next) {
          row.insertBefore(newCell, next);
        } else {
          row.appendChild(newCell);
        }
        break;
      case 'td':
        row.insertCell(index + 1);
        break;
    }
  });

}


var links = document.querySelectorAll('a.cht-add'),

// again, using Function.prototype.call() and
// Array.prototype.slice() to obtain an Array
// from an HTMLCollection:
  arrayOfLinks = Array.prototype.slice.call(links, 0);

// iterating over the array of links, with
// Array.prototype.forEach():
arrayOfLinks.forEach(function(link) {
  // links, the first and only argument is
  // the array-element of the Array over
  // which we're iterating (the name is
  // user-defined and can be anything
  // within the normal rules of variable
  // naming in JavaScript).

  // here we simply bind the addColumns()
  // function as the event-handler for
  // the click event:
  link.addEventListener('click', addColumns);
});
function closest(startAt, elemType) {
  var current = startAt,
    tag = elemType.replace(/[^a-z]/gi, '');

  while (current.tagName.toLowerCase() !== tag && current.tagName.toLowerCase() !== 'html') {
    current = current.parentNode;
  }

  return current.tagName.toLowerCase() === 'body' ? startAt : current;
}

function addColumns() {
  var clicked = this,
    cell = closest(clicked, 'td'),
    table = closest(cell, 'table'),
    rowsArray = Array.prototype.slice.call(table.rows, 0),
    index = cell.cellIndex,
    cellType, newCell, next;

  rowsArray.forEach(function(row) {
    cellType = row.children[index].tagName;
    newCell = document.createElement(cellType);
    switch (cellType.toLowerCase()) {
      case 'th':
        next = row.children[index + 1];
        newCell.textContent = 'Header';
        if (next) {
          row.insertBefore(newCell, next);
        } else {
          row.appendChild(newCell);
        }
        break;
      case 'td':
        row.insertCell(index + 1);
        break;
    }
  });

}


var links = document.querySelectorAll('a.cht-add'),
  arrayOfLinks = Array.prototype.slice.call(links, 0);

arrayOfLinks.forEach(function(link) {
  link.addEventListener('click', addColumns);
});
table {
  border-collapse: collapse;
}
th,
td {
  border-bottom: 1px solid #000;
  padding: 0.5em;
}
th + th,
td + td {
  border-left: 1px solid #000;
}
<section class="yield-report-table">
  <table id="sorting">
    <tr class="headerrow ui-sortable">
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(1)</div>
      </th>
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(2)</div>
      </th>
    </tr>
    <tr>
      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
        </div>
      </td>

      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
        </div>
      </td>
    </tr>
  </table>
</section>

Демонстрация JS Fiddle.

С jQuery, конечно:

function addColumn() {
  var clicked = $(this),
    cell = clicked.closest('td'),
    table = clicked.closest('table'),
    index = cell.prop('cellIndex'),
    th = $('<th />', {
      'text': 'Heading'
    }),
    td = $('<td />');

  table.find('tr > :nth-child(' + (index + 1) + ')').after(function(){
   return $(this).is('th') ? th.clone(true) : td.clone(true);
  })

}

$('td a.cht-add').on('click', addColumn);
function addColumn() {

  // caching the clicked element:
  var clicked = $(this),

  // traversing up the DOM tree from
  // the clicked element to its
  // closest ancestor <td> element:
    cell = clicked.closest('td'),

  // finding the closest <table>
  // ancestor element:
    table = clicked.closest('table'),

  // finding the cellIndex property
  // of the <td> among its siblings:
    index = cell.prop('cellIndex'),

  // creating a <th> element:
    th = $('<th />', {

      // setting its text to 'Heading':
      'text': 'Heading'
    }),

  // creating a <td> element:
    td = $('<td />');

  // starting from the <table> we find all the
  // element children of the <tr> elements which
  // match the ':nth-child(n)' rule, where n is
  // the zero-based index of the <td> ancestor
  // of the clicked element, with 1 added because
  // CSS is one-based;
  // we then use the after() method to insert a
  // new element node after the found ':nth-child(n)'
  // elements:
  table.find('tr > :nth-child(' + (index + 1) + ')').after(function() {

    // here, if the current element is a <th>, we return
    // a clone of the created <th> (earlier), if it is not
    // a <th> then we return a clone of the created <td>;
    // the Boolean true in the clone method simply means
    // that the clone retains any data and events that
    // were bound to the created nodes:
    return $(this).is('th') ? th.clone(true) : td.clone(true);
  })

}

// using the on() method to attach a click event-handler
// to the <a> elements with the class of 'cht-add' within
// a <td> element:
$('td a.cht-add').on('click', addColumn);
table {
  border-collapse: collapse;
}
th,
td {
  border-bottom: 1px solid #000;
  padding: 0.5em;
}
th + th,
td + td {
  border-left: 1px solid #000;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section class="yield-report-table">
  <table id="sorting">
    <tr class="headerrow ui-sortable">
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(1)</div>
      </th>
      <th class="ui-resizable tac">
        <div class="ui-resizable">First Year Corn
          <br>Non Limited N, High Pop(2)</div>
      </th>
    </tr>
    <tr>
      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">1</i></span></a>
        </div>
      </td>

      <td>
        <div class="report-icon-list bg-l-green">
          <a href="#" class="cht-add"><span><i class="cht-sprite">2</i></span></a>
        </div>
      </td>
    </tr>
  </table>
</section>

Демонстрация JS Fiddle.

Ссылки:

0
David says reinstate Monica 14 Дек 2015 в 16:13