Max Segal Max Segal - 1 month ago 13
HTML Question

How to change only text inside td of table table using JQuery

I am trying to update the text inside a cell that contains also an input box.
In line

$(ib).closest('td').prop('textContent',888);
I am assigning the value 888 to the text but this results in assignment of cell's text to "888" but also for some reason deleting the input box.

My code (Django template):

{% extends "base.html" %}
{% block head_scripts %}
<script type="text/javascript" src="/static/script/api_recs.js"></script>
<script type="text/javascript" src="/static/script/site_filter.js"></script>

<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.12/css/jquery.dataTables.min.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/buttons/1.2.2/css/buttons.dataTables.min.css"/>

<script type="text/javascript" src="https://code.jquery.com/jquery-2.2.3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jszip/2.5.0/jszip.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/1.10.12/js/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.2.2/js/dataTables.buttons.min.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/buttons/1.2.2/js/buttons.html5.min.js"></script>

{% endblock %}

{% block title %}
Schedule Match
{% endblock %}

{% block styles %}
<style type="text/css">
tfoot {
display: table-header-group;
}

</style>
{% endblock %}

{% block content %}

<table id='pm_table' class="display" cellspacing="0" width="100%">
<thead>
<tr>
{% for col_name in table_headers%}
<th>{{col_name}}</th>
{% endfor %}
</tr>
</thead>
<tfoot>
<tr>
{% for col_name in table_headers%}
<th>{{col_name}}</th>
{% endfor %}
</tr>
</tfoot>
<tbody>
{% for data_row in table_data%}
<tr>
{% for item in data_row%}
<td>{{item}}</td>
{% endfor%}
</tr>
{% endfor %}
</tbody>
</table>

<script>
$(document).ready(function() {
var SITE_ID_COL = 0;
var PRIORITY_COL = 3;
var IS_SCHEDULED_COL = 4;

// priority input box
$("#pm_table td:nth-child(" + PRIORITY_COL + ")").each(function() {

// $(this).children().css('visibility', 'hidden');
$(this).css('text-align', 'center');
// $(this).css('font-size', 0);

var $input_box = $('<input type="text" class="priority_changed" />')
$input_box.prop('value', $(this).text());
$input_box.prop('size', 1);
$input_box.css('text-align', 'center');
$input_box.prependTo(this);
});
// remember old value of input box
$("#pm_table td:nth-child(" + PRIORITY_COL + ")").on('focus', '.priority_changed', function() {
this.old_val = this.value;

});
// priority input box listener
$('#pm_table').on('change', '.priority_changed', function() {
var $changed_tr = $(this).closest('td').closest('tr');
var site_id = $changed_tr.children().eq(SITE_ID_COL).text();
var old_val = parseInt($(this).closest('td').text());
var ib = this;

// confirm change
if (!confirm('Change priority for site ' + site_id + ' from ' + this.old_val + ' to ' + this.value + " ?")) {
//revert input box value
$(this).prop('value', this.old_val);
} else {
// make the change in db
new_val = this.value;
var url = '/api/manage/schedule_match/set_priority/' + site_id + '/' + new_val + '/';

$.ajax({
type: 'POST',
url: url,
success: function(result) {
res = JSON.parse(result) // todo read res
alert('SUCCESSFULLY changed priority for site ' + site_id + ' from ' + ib.old_val + ' to ' + res.new_val + ".");
$(ib).closest('td').prop('textContent',888);



},
error: function() {
alert('ERROR updating database!');
//revert input box state
$(ib).prop('value', ib.old_val);
},
});
}
});
</script>
{% endblock %}


I tried
$(ib).closest('td').text(888);
and many different properties like innerText, innerHtml,
$(ib).closest('td').childNodes[1].prop('text',888)
but without result in right direction.
What am I doing wrong here?

Answer

You should change your template to have a span inside td. Like:

<tbody>
    {% for data_row in table_data%}
    <tr>
        {% for item in data_row%}
        <td><span>{{item}}</span></td>
        {% endfor%}
    </tr>
    {% endfor %}
</tbody>

Then you can use $(ib).closest('td').children('span').text(888) to change the text without deleting the input box.