HTML
HTML copied to clipboard
.textContent not working properly
Hi.
I will try explain my problem, but please, forgive my terrible english.
First case
- I have a table with 1 example line
- When I click in some button I remove this line and then add a new one with the form data
- After add a couple of lines I click in save button, send a POST and persist this data in the database
- Everything works great
Second case (error)
- Now I have some data in database, so I create the table without the example line and list all data from database in that table
- When I click in the button for add a new data from the from the textContent not works: all the td is blank (but the input hidden in each td works great)
What I test?
I put some console.log/debug
in my code and I notice when I get the tablet
element, I get undefined instead of HTML object
lib.
My code
HTML
<!-- LINK TO ADD NEW ITEMS FROM FORM -->
<div class="field">
<a href="#" class="ui green button add-dynamic-table" data-table="#customer-team-table" data-field-form="customer_team" data-field-name="customerteam" data-message="#team-message">{!! trans('messages.btn.add') !!}</a>
</div>
<!-- THE TABLE -->
<table class='ui table' id="customer-team-table">
<thead>
<tr>
<th>{!! trans('messages.field.id') !!}</th>
<th>{!! trans('messages.field.position_id') !!}</th>
<th>{!! trans('messages.field.name') !!}</th>
<th>{!! trans('messages.field.work_phone') !!}</th>
<th>{!! trans('messages.field.mobile_phone') !!}</th>
<th>{!! trans('messages.field.email') !!}</th>
<th class='actions'>{!! trans('messages.field.actions') !!}</th>
</tr>
</thead>
<tbody>
@if (!empty($customer) and ($customer->customerTeam->count() > 0))
@foreach ($customer->customerTeam as $team)
<tr>
<td>{!! $team->id !!}</td>
<td>{!! $team->position->name !!}</td>
<td>{!! $team->name !!}</td>
<td>{!! $team->work_phone !!}</td>
<td>{!! $team->mobile_phone !!}</td>
<td>{!! $team->email !!}</td>
<td class='actions'>
<a class="ui icon mini button red destroy-modal" data-destroy-route='{!! URL::route("customerteams.destroy", $team->id) !!}'>
<i class="trash icon"></i>
</a>
</td>
</tr>
@endforeach
@else
<tr>
<td colspan="7">{!! trans('messages.text.empty_table') !!}</td>
</tr>
@endif
</tbody>
</table>
Javascript
$('.add-dynamic-table').click(function(event) {
event.preventDefault();
var name = undefined;
var input_form = $(this).data('field-form');
var input_name = $(this).data('field-name');
var fields = HTML.query('.fields [name^="' + input_form + '"]');
var table = HTML.query($(this).data('table'));
// remove the example line when table is empty
if ($($(this).data('table') + ' tbody tr td[colspan="7"]').length == 1) {
$($(this).data('table') + ' tbody tr').remove();
}
// create a new TR
var tr = table.query('tbody').add('tr');
// create a new TD inside this TR with just a "-" (not work)
tr.add('td').textContent = '-';
var id = $($(this).data('table')).find('tbody tr').length + 1;
fields.each(function(field) {
var $name = field.each('name').toString();
$name = $name.match(/\[(.*?)\]/)[1];
// create a new TD inside this TR
var td = tr.add('td');
// set the textContent based on tagName (not work)
if ($(field).prop('tagName') == 'SELECT') {
td.textContent = $(field).find('option:selected').text();
} else if ($(field).prop('tagName') == 'INPUT') {
td.textContent = field.each('value');
}
// add an input hidden inside this TD (works)
var input = td.add('input[type="hidden"]');
input.each('name', input_name + '[' + id + ']' + '[' + $name + ']');
input.each('value', field.each('value'));
});
// add TD in this TR with a trash link button
var td = tr.add('td.actions');
var a = td.add('a.ui.icon.mini.button.red.destroy-modal');
a.add('i.icon.trash');
});
If you need more informations, tell me please.
I can solve this partially doing that:
tr.add('td{someValueHere');
But in my old code I need after that add an input inside this td
, because that I need the td
variable, otherwise I need to do...
tr.add('td{someValueHere').add('input......');
And that's much complicated in my case.
Backing to the problem:
Why using textContent( )
not work and using td{someValue}
work?
Why do you assume it is textContent
that isn't working? Are you sure that the value(s) you are pulling out of the input or select elements are being returned as you expect?
In any case, the textContent
property is not created/defined by HTML.js. It's just part of the DOM. So i doubt that is where the problem lies.
Also, if you want better help, i actually need a lot less information, not more. There is so much going on there in your mish-mash of jQuery and HTML.js code. I need a smaller example of the problem that i can run, if i'm going to be able to help. Or, failing that, put your whole example up somewhere public (like jsfiddle) so that i can see it in action, at least.
What I know is:
When the table is empty, the same code works. When the table has some rows and I need to add a new one without remove the others, the code not works. It's the same code.
I solve that using the create tag and set value syntax - tag{value}
.
Part of the code:
...
var fields = HTML.query('.fields [name^="' + input_form + '"]');
...
fields.each(function(field) {
...
if ($(field).prop('tagName') == 'SELECT') {
td.textContent = $(field).find('option:selected').text();
} else if ($(field).prop('tagName') == 'INPUT') {
td.textContent = field.each('value');
}
...
}
I identify what tag is and set the textContent
of this new td
.
I set a lot console.log
in my code, and if I get this $(field).find('option:selected').text();
or field.each('value');
I get the correctly values, not null
, empty
or undefined
.
But when the table
has a few rows inside tbody
and I do not remove them the problem occurs.
I don't really know how to explain it to you better, mainly because my English is not so good.
But overall this is the problem. I was four hours trying to figure out if it was my mistake, but have not found anything yet. So I decided the way I told you above. For the moment it is working.
I will try to simulate the same problem again, but now I am in doubt whether I continue using HTML.js
or if I migrate everything to the 'DOMx`.
What do you advise?
I'm glad you found a workaround. I still can't figure out the exact problem without having a runnable example. The code, despite its many quirky and inefficient parts, is not making it clear to me what's going wrong.
I would certainly consider switching to DOMx, but i can't say that will fix things, since i haven't identified the problem.
Why do you do field.each('value')
? Are there times when field
might be a list instead of a single element? It doesn't look that way in your code.
Hmmmmm... maybe thats the problem. I notice when the textContent
not work the td
element created by HTML has an array element inside, something like this element[0]
or array[0]
. I do not remember.
I will try this tonight.
Thanks sir!
Now I not understand... why field.each('value')
return an array?
input value Array[1]
0: "[email protected]"
length: 1
__proto__: Array[0]
http://nbubna.github.io/HTML/#each(property)
That's the API. It's for getting properties from multiple items at once. If you have a single item and want a single value, you just use the property: field.value
Still no work, and just in one location and for one table.
Thats my case:
1 - I fill the form
2 - I press the button
3 - My script run and add a new line with blank text in all td
s
4 - In the console I can see each value inputed in form correctly, but texContent
not work.
editar:596 tr [tr, tr]
editar:603 name ["customer_class_start[program_id]"]
editar:604 value 4
editar:605 text Programa Antes da Pré-escolaPrograma Estruturado de Baixo CustoPrograma Intensivão Meio-AnoPrograma Reforço EscolarPrograma de Alfabetização 2.0
editar:618 tagName SELECT
editar:620 select value Programa Intensivão Meio-Ano
editar:603 name ["customer_class_start[year]"]
editar:604 value 2013
editar:605 text
editar:618 tagName INPUT
editar:624 input value 2013
editar:603 name ["customer_class_start[start_date]"]
editar:604 value 2013-01-01
editar:605 text
editar:618 tagName INPUT
editar:624 input value 2013-01-01
editar:603 name ["customer_class_start[school_days]"]
editar:604 value 2012
editar:605 text
editar:618 tagName INPUT
editar:624 input value 2012
editar:603 name ["customer_class_start[students]"]
editar:604 value 220
editar:605 text
editar:618 tagName INPUT
editar:624 input value 220
The script still the same, but I change each('value')
for just 'value' like you said.
...
var fields = HTML.query('.fields [name^="' + input_form + '"]');
...
fields.each(function(field) {
...
if ($(field).prop('tagName') == 'SELECT') {
td.textContent = $(field).find('option:selected').text();
} else if ($(field).prop('tagName') == 'INPUT') {
td.textContent = field.value;
}
...
}
I really don't know where is the problem.
I convert my code to DOMx but get the following error (I'll post that in DOMx repository too).
Uncaught HierarchyRequestError: Failed to execute 'appendChild'
on 'Node': Only one element on document allowed.
I get this error when I try to do that:
var tr = table.query('tbody').append('tr');
tr.append('td').textContent = '-';
fields.each(function(field) {
var td = tr.append('td'); // HERE I GET THE ERROR
});
I think I found something.
When I execute in Google Chrome console this code:
var table = document.query('#my-table-id');
I get undefined.
So I wait 2 seconds and execute the same code... and I get the table.
Why that delay?
I figure out something:
- I get the some table by id
- then I append some
tr
and return that to a var calledtr
- the I create some
td
and return the value of append to the vartd
- In the final... the table still the same..
So I try to append this new tr
to a table: nothing happens.
Maybe the problem was that... how to use your lib manipulating each element separately and then join all together?
Sorry for my incredible english.
This would be sooo much easier with a working example.
The first post is a complete working example.
Anyway, I will try solve that.
Thanks for your time sir.
The markup for the first post is embedded in some unspecified template language. It may be a working example for you. It is not for me. I would like to help you, but i have an incomplete picture of what is happening and limited time to spend combing through a large section of code.
No problem my friend, I understand your point.
I will try write and functional* example for you tonight.
Thanks anyway.