Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.textContent not working properly #22

Open
patrickmaciel opened this issue Jul 29, 2015 · 15 comments
Open

.textContent not working properly #22

patrickmaciel opened this issue Jul 29, 2015 · 15 comments

Comments

@patrickmaciel
Copy link

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.

@patrickmaciel
Copy link
Author

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?

@nbubna
Copy link
Owner

nbubna commented Jul 30, 2015

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.

@patrickmaciel
Copy link
Author

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?

@nbubna
Copy link
Owner

nbubna commented Jul 31, 2015

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.

@patrickmaciel
Copy link
Author

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!

@patrickmaciel
Copy link
Author

Now I not understand... why field.each('value') return an array?

input value Array[1]
    0: "josegon@example.com.br"
    length: 1
    __proto__: Array[0]

@nbubna
Copy link
Owner

nbubna commented Jul 31, 2015

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

@patrickmaciel
Copy link
Author

Still no work, and just in one location and for one table.

Thats my case:

1 - I fill the form

captura de tela 2015-08-01 21 17 53

2 - I press the button

3 - My script run and add a new line with blank text in all tds

captura de tela 2015-08-01 21 18 04

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.

@patrickmaciel
Copy link
Author

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
      });

@patrickmaciel
Copy link
Author

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?

@patrickmaciel
Copy link
Author

I figure out something:

  • I get the some table by id
  • then I append some tr and return that to a var called tr
  • the I create some tdand return the value of append to the var td
  • 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.

@nbubna
Copy link
Owner

nbubna commented Aug 3, 2015

This would be sooo much easier with a working example.

@patrickmaciel
Copy link
Author

The first post is a complete working example.

Anyway, I will try solve that.

Thanks for your time sir.

@nbubna nbubna reopened this Aug 3, 2015
@nbubna
Copy link
Owner

nbubna commented Aug 4, 2015

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.

@patrickmaciel
Copy link
Author

No problem my friend, I understand your point.

I will try write and functional* example for you tonight.

Thanks anyway.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants