1

First of all I will make it clear, that I went through the below link and yet found it difficult to address my issue. Link1, Link2, Link3

Issue:

I have the below loaded on my page:

<div class="btn-group">
 <label class="someClassDifferentForEachLoadedElement btn btn-primary " 
        onclick="$('#someIdDifferentForEvryElement')
        .find('label.active')
        .toggleClass('active', false);
        $(this).toggleClass('active', true);">

  <input class="validated" style="display:none" toggle="true" toggle- 
         checkbox="false" type="radio" value="Y">
  Yes
 </label>     
 <label class="someClassDifferentForEachLoadedElement btn btn-primary"
        onclick="$('#someIdDifferentForEvryElement')
        .find('label.active')
        .toggleClass('active', false);
        $(this).toggleClass('active', true);">  

   <input class="validated" style="display:none" toggle="true" toggle- 
          checkbox="false" type="radio" value="N">
   No
  </label>
 </div>

All the above code (most complex code removed) displays a clickable Yes/No field as in this image

The below element gets loaded dynamically on to DOM when answered YES

 <input class="validated GTnumeric" size="2" type="text" value="">

Approach:

Need to change the type of the loaded input element from text to tel.

I have the below for all elements loaded on to DOM which works great for elements loaded initially:

 $(document).ready(function() {                        
  $(".GTnumeric").not("[type=hidden]").attr("type", "tel");
 });

But I am finding it difficult to make it work for the dynamically loaded elements. I need to address the same issue on numerous [pages and I cannot target on any ID since it changes for every element.

Can anyone please help me solve this with a possible approach using jQuery. Appreciate your help.

UPDATED:

After some suggestion from @barmar and @f-CJ (Thanks to both of you), I have tried below:

I tried below:

 var observer = new MutationObserver(function (mutations)
               {
                 mutations.forEach(function (mutation)
                 {
                   console.log(mutation.type);

                 // here I need get all elements with class "GTnumeric" and 
                 // change its "type" to be "tel" if its not "hidden"

                 // **please help me out here**
                 // code mentioned below 

                 });
                });

 var config = {
 childList: true,
 subtree: true
 };

 // Node, config
var targetNode = document.body;
observer.observe(targetNode, config);

I am not sure how to refer the document again inside the for loop its throwing an error [Uncaught TypeError: t[i].getAttribute is not a function] when I try below:

please help me out here

     var elems = document.getElementsByClassName(".GTnumeric");
    for (var el in elems) {
        if (elems[el].getAttribute("type") != 'hidden') {
            elems[el].setAttribute("type", "tel");
        }
    }
10
  • Where on the DOM is the input loaded? Commented Aug 8, 2018 at 22:18
  • @f-CJ it's loaded below the Yes/No element. Did I answer your question? Commented Aug 8, 2018 at 22:25
  • You need to run the code that changes the type after you load the elements dynamically. Commented Aug 8, 2018 at 22:27
  • None of the code you posted is relevant to this. Post the code that loads the new elements, and we can show you where this goes. Commented Aug 8, 2018 at 22:28
  • If you can modify the method that loads the input, it will be very easy. If you cannot modify the method that loads the input, we can offer different options to get what you want. Can you modify the method that loads the input? Commented Aug 8, 2018 at 22:31

1 Answer 1

0

Ok, so if you cannot modify the method that loads the input file, I see 2 possible solutions:

  1. Add a click event handler and periodically check until the new sibling element has been added -> modify it.

    $('div.btn-group > label').on('click', function(e) {        
        let $this = $(this);
    
        let interv = setInterval(function() {
            let gtNumeric = $this.siblings($(".GTnumeric").not("[type=hidden]")); 
    
            if (gtNumeric.length > 0) {
                gtNumeric.attr("type", "tel");
                clearInterval(interv);
            }
        }, 500);    
    });
    

The idea of the above script is to check siblings of the clicked label and check if there is one with the class .GTnumeric. Once it is found, change the type of the element and clear the interval. I put an interval of half a second (500), you can adapt it to your needs.

  1. Use DOM Mutation Observer, you can check this blog post
Sign up to request clarification or add additional context in comments.

7 Comments

Could you please point me to any jsbin link or working example you have, for the first suggestion, it would help me understand better
@cheresdb not sure if I explained myself clear, any question?
Thanks for the example. There is one problem though, my element is not a sibling. The element gets inserted below the button, but not as a sibling, but as a new row element.
@cheresdb It gets added as a sibling of div.btn-group?
Nope. It gets added as a new div.row element. Is there a way I can refer the whole document when the click event occur to check if an element is added? That should solve the problem
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.