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");
        }
    }
chethan
  • 493
  • 1
  • 5
  • 16
  • Where on the DOM is the `input` loaded? – f-CJ Aug 08 '18 at 22:18
  • @f-CJ it's loaded below the Yes/No element. Did I answer your question? – chethan Aug 08 '18 at 22:25
  • You need to run the code that changes the type after you load the elements dynamically. – Barmar Aug 08 '18 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. – Barmar Aug 08 '18 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`? – f-CJ Aug 08 '18 at 22:31
  • @Barmar Unfortunately I am not in a position to change that logic which loads the new element :( – chethan Aug 08 '18 at 22:36
  • @f-CJ No I cannot modify the method that loads input. I have to find a solution with the elements I have posted here. – chethan Aug 08 '18 at 22:37
  • You can use [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to detect changes to the DOM automatically. – Barmar Aug 08 '18 at 22:41
  • @Barmar sure will give it a try and let you know. Thanks – chethan Aug 08 '18 at 22:50
  • @Barmar I have updated what I have tried with MutationObserver please advice further. Thanks. – chethan Aug 09 '18 at 19:41

2 Answers2

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
f-CJ
  • 3,332
  • 1
  • 26
  • 27
  • Could you please point me to any jsbin link or working example you have, for the first suggestion, it would help me understand better – chethan Aug 08 '18 at 22:51
  • @cheresdb not sure if I explained myself clear, any question? – f-CJ Aug 08 '18 at 23:15
  • 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. – chethan Aug 09 '18 at 04:21
  • @cheresdb It gets added as a sibling of `div.btn-group`? – f-CJ Aug 09 '18 at 16:58
  • 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 – chethan Aug 09 '18 at 17:25
  • @cheresdb Yes, with the DOM Mutation Oberserver: https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver – f-CJ Aug 09 '18 at 17:27
  • I have tried something using Mutation Observer and stuck at some point. I will update my question. Please help me out there. Thanks a lot for your valuable suggestions till now. – chethan Aug 09 '18 at 19:27
0

Since I am not sure how to proceed, I have opened a new question on using MutationObeserver in the below link.

Discussion moved here

chethan
  • 493
  • 1
  • 5
  • 16