How to differentiate inputs that have the same class?

Asked

Viewed 1,125 times

2

I would like, when clicking on an input, to fill in a variable with the given value, but these inputs are created dynamically with an iterator and all inputs have the same class. You can identify which input was clicked and get its value only?

Iterator is like this:

    <s:iterator value="planoVO.listaDeVigenciasCanalVendaVO" var="vigenciasPlanoCanalVenda">
                <tr>
                    <td width='40%'  align='center'>
                    </td>
                    <td width='40%'  align='center' >
                       <s:if test="%{status == 'Vigente'}">
                                 <input type="hidden" name="canalVendaVO.codigo"  id="codigoCanalVenda" class="codigoCanalVenda" value='<s:property value="canalVendaVO.codigo" />' />
                                 <input type="hidden" name="canalVendaVO.nome"  id="nomeCanalVenda" class="nomeCanalVenda" value='<s:property value="canalVendaVO.nome" />' />
                                 <s:property value="dataInicioVigenciaAssociacaoPlano"/>
                                 <input type="hidden" name="dataInicioVigenciaAssociacaoPlano"  id="dataInicioVigenciaAssociacaoPlano" class="dataInicioVigenciaAssociacaoPlano" value='<s:property value="dataInicioVigenciaAssociacaoPlano" />'/>
                                 &nbsp;&nbsp;&nbsp;&nbsp;At&eacute;&nbsp;&nbsp;&nbsp;&nbsp;
                                 <input type='text' data-mask="data" data-date-type="default"    size='10' maxlength='10' 
                                 value='<s:property value="dataFimVigenciaAssociacaoPlano"/>' id="dataFimVigenciaAssociacaoPlano" class="dataFimVigenciaPlanoVigente" />
                                 <input type="hidden" name="dataInicioAntesDeAlteracao" id="dataInicioAntesDeAlteracao" class="dataInicioAntesDeAlteracao" value='<s:property value="dataInicioVigenciaAssociacaoPlano" />'  />
                                 <input type="hidden" name="dataFimAntesDeAlteracao" id="dataFimAntesDeAlteracao" class= "dataFimAntesDeAlteracao" value='<s:property value="dataFimVigenciaAssociacaoPlano" />'  />
                      </s:if>

Jquery is like this :

 $('.dataFimVigenciaPlanoVigente').on('change', function(e){
      var $this = $(this);

      var dataFimVigenciaPlanoVigente = $this.parent('td').find('.dataFimVigenciaPlanoVigente').val(); //( $('#dataFimVigenciaPlanoVigente').val();
      var nomeCanalVenda =  $this.parent('td').find('.nomeCanalVenda').val();
      var dataInicioVigenciaPlanoVigente =$this.parent('td').find('#dataInicioVigenciaAssociacaoPlano').val();
      var codigoCanalVenda = $this.parent('td').find('.codigoCanalVenda').val();
      var dataInicioAntesDeAlteracao = $this.parent('td').find('.dataInicioVigenciaAssociacaoPlano').val();
      var dataFimAntesDeAlteracao = $this.parent('td').find('.dataFimAntesDeAlteracao').val();
  • 2

    by the ID? in the iterator probably exists the option of Voce name with a different id, no?

  • 1

    The question seems to be very simple as @Marcelobonifazio has already shown. If there’s something we’re not seeing, post more details on the question. If possible post the code you are working on to help more specifically.

  • I could put a counter to differentiate each input?

  • In the code of your iterator, where is the dataFimVigenciaPlanoVigente to which you are attaching an change ?

  • Ah! Sorry, I didn’t get the important part. I will edit.

2 answers

3


Collect value from own

You’re attaching the event change to the field you refer to as the one you intend to collect the value, so that you can collect the value of itself, just refer to the object this or its representation in jQuery $(this):

$('.dataFimVigenciaPlanoVigente').on('change', function(e){
  var $this    = $(this),
      meuValor = $this.val();
//...

See the reply by @Borachio on your question.

Your line:

var dataFimVigenciaPlanoVigente = $this.parent('td').find('.dataFimVigenciaPlanoVigente').val();

It’s unnecessary 'cause you’re pulling out of the field, climbing up to the parent element td, locate the field itself and then extract its value. You can reduce the line to:

var dataFimVigenciaPlanoVigente = $this.val();

Related subject: What’s the difference between $(this) and $this and this?.

Element cache

For the element with the class dataFimVigenciaPlanoVigente, you are caching your DOM reference, however, to locate your parent element you are constantly performing a search.

Your code could pass to:

$('.dataFimVigenciaPlanoVigente').on('change', function(e){
  var $this = $(this),
      $wrap = $(this).parent('td');
// ...

And then to use:

var nomeCanalVenda =  $wrap.find('.nomeCanalVenda').val();

Twice the same amount

By collecting the values of the various input, There’s one you’re collecting twice for two different variables:

// Aqui por ID ao input dataInicioVigenciaAssociacaoPlano
var dataInicioVigenciaPlanoVigente = $this.parent('td').find('#dataInicioVigenciaAssociacaoPlano').val();

// ...

// Aqui por Class ao input dataInicioVigenciaAssociacaoPlano
var dataInicioAntesDeAlteracao = $this.parent('td').find('.dataInicioVigenciaAssociacaoPlano').val();

Working with "brothers"

Since you’re working with sibling elements, you have no need to locate the parent, you can make use of the method siblings() that returns the elements "brothers":

Where have you:

var nomeCanalVenda =  $this.parent('td').find('.nomeCanalVenda').val();

You would have:

var nomeCanalVenda =  $this.siblings('.nomeCanalVenda').val();

Less code, better understanding.

$('.dataFimVigenciaPlanoVigente').on('change', function(e){

    var $this = $(this);

    var dataFimVigenciaPlanoVigente    = $this.val(),
        nomeCanalVenda                 = $this.siblings('.nomeCanalVenda').val(),
        dataInicioVigenciaPlanoVigente = $this.siblings('.dataInicioVigenciaAssociacaoPlano').val(),
        codigoCanalVenda               = $this.siblings('.codigoCanalVenda').val(),
        dataInicioAntesDeAlteracao     = $this.siblings('.dataInicioAntesDeAlteracao').val(),
        dataFimAntesDeAlteracao        = $this.siblings('.dataFimAntesDeAlteracao').val();

    // Apenas para debug
    $("#valoresObtidos").html("Valores obtidos: " + dataFimVigenciaPlanoVigente +" "+ nomeCanalVenda +" "+ dataInicioVigenciaPlanoVigente +" "+ codigoCanalVenda +" "+ dataInicioAntesDeAlteracao +" "+ dataFimAntesDeAlteracao);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form>
    <table>
        <tr>
            <td>
                <input type="hidden" name="canalVendaVO.codigo" id="codigoCanalVenda" class="codigoCanalVenda" value="1" />
                <input type="hidden" name="canalVendaVO.nome" id="nomeCanalVenda" class="nomeCanalVenda" value="2" />
                <input type="hidden" name="dataInicioVigenciaAssociacaoPlano" id="dataInicioVigenciaAssociacaoPlano" class="dataInicioVigenciaAssociacaoPlano" value="3" />
                &nbsp;&nbsp;&nbsp;&nbsp;At&eacute;&nbsp;&nbsp;&nbsp;&nbsp;
                <input type='text' data-mask="data" data-date-type="default" size='10' maxlength='10' value="4" id="dataFimVigenciaAssociacaoPlano" class="dataFimVigenciaPlanoVigente" />
                <input type="hidden" name="dataInicioAntesDeAlteracao" id="dataInicioAntesDeAlteracao" class="dataInicioAntesDeAlteracao" value="5" />
                <input type="hidden" name="dataFimAntesDeAlteracao" id="dataFimAntesDeAlteracao" class="dataFimAntesDeAlteracao" value="6" />
            </td>
        </tr>
    </table>
</form>
<!-- apenas para debug -->
<div id="valoresObtidos"></div>

Multiple variables

When you want to declare multiple variables in Javascript, you don’t have to write constantly var, can make use of separator , as follows:

var dataFimVigenciaPlanoVigente    = $this.val(),
    nomeCanalVenda                 = $this.siblings('.nomeCanalVenda').val(),
    dataInicioVigenciaPlanoVigente = $this.siblings('.dataInicioVigenciaAssociacaoPlano').val(),
    codigoCanalVenda               = $this.siblings('.codigoCanalVenda').val(),
    dataInicioAntesDeAlteracao     = $this.siblings('.dataInicioAntesDeAlteracao').val(),
    dataFimAntesDeAlteracao        = $this.siblings('.dataFimAntesDeAlteracao').val();

Repeated ids

In your code, the same is applying id to input, but how do you have those input within a cycle, what will happen is that you will end up with the repeated Ids on the page.

According to the rules, one id is a unique selector, being a way of referencing a single object. Already the classes are common selectors the same being a form of multiple references elements at once.

For example, where do you have:

<input type="hidden" name="canalVendaVO.codigo"  id="codigoCanalVenda" class="codigoCanalVenda" value='<s:property value="canalVendaVO.codigo" />' />

You must change to:

<input type="hidden" name="canalVendaVO.codigo" class="codigoCanalVenda" value='<s:property value="canalVendaVO.codigo" />' />

The idea is to remove all id of these fields that will be repeated by the cycle thus avoiding unpredictable results by Javascript.


Optimized code

Your code with the corrections and suggestions above is as shown below:

  • With the use of parent

    $('.dataFimVigenciaPlanoVigente').on('change', function(e){
    
        var $this = $(this),
            $wrap = $this.parent();
    
        var dataFimVigenciaPlanoVigente    = $this.val(),
            nomeCanalVenda                 = $wrap.find('.nomeCanalVenda').val(),
            dataInicioVigenciaPlanoVigente = $wrap.find('.dataInicioVigenciaAssociacaoPlano').val(),
            codigoCanalVenda               = $wrap.find('.codigoCanalVenda').val(),
            dataInicioAntesDeAlteracao     = $wrap.find('.dataInicioAntesDeAlteracao').val(),
            dataFimAntesDeAlteracao        = $wrap.find('.dataFimAntesDeAlteracao').val();
    });
    

    Example in Jsfiddle.

  • With the use of siblings

    $('.dataFimVigenciaPlanoVigente').on('change', function(e){
    
        var $this = $(this);
    
        var dataFimVigenciaPlanoVigente    = $this.val(),
            nomeCanalVenda                 = $this.siblings('.nomeCanalVenda').val(),
            dataInicioVigenciaPlanoVigente = $this.siblings('.dataInicioVigenciaAssociacaoPlano').val(),
            codigoCanalVenda               = $this.siblings('.codigoCanalVenda').val(),
            dataInicioAntesDeAlteracao     = $this.siblings('.dataInicioAntesDeAlteracao').val(),
            dataFimAntesDeAlteracao        = $this.siblings('.dataFimAntesDeAlteracao').val();
    });
    

    Example in Jsfiddle.

  • Thank you very much for the explanation. But it turns out I’m still having this problem of always getting the value of the first input. Right after assigning values in Jquery I put an Alert and the value that appears in it is from the top input, not from what was clicked.

  • Thank you very much for the explanation. But it turns out I’m still having this problem of always getting the value of the first input. Right after assigning values in Jquery I put an Alert and the value that appears in it is from the top input, not from what was clicked.

  • @user5515 Have you corrected your code in the sense that Ids are unique? It’s just that if you have fields with Ids as it is in your question and you have it within a cycle, you’ll get the page full of repeated Ids and the results are unpredictable!

  • That’s right. The Ids were repeated. Deleting it worked! Thank you very much and sorry anything, I’m beginner.

  • @user5515 Always at your service, we are here to help :)

2

use this object. For example:

HTML:

<input type="text" class="button"/>
<input type="text" class="button"/>

jQuery:

$(function(){
  $(".button").click(function(){
    this.value = "novo valor";
  });
});

http://jsfiddle.net/Ljb8bqr8/1/

Browser other questions tagged

You are not signed in. Login or sign up in order to post.