1

I have a simple contact form on my website which is created using online builder (so I can't change the html code and add id't to elements). Here is the example of my form:

https://jsfiddle.net/kerm131/w6oa7uhe/30/

        $("[data-type='phone'] .input .form-control").intlTelInput({

          allowDropdown: true,
          autoPlaceholder: "aggressive",
          initialCountry: "auto",
          geoIpLookup: function(success, failure) {
            $.get("https://ipinfo.io", function() {}, "jsonp").always(function(resp) {
              var countryCode = (resp && resp.country) ? resp.country : "";
              success(countryCode);
            });
          },
        });
        let country = document.querySelector('selected-flag[title]');
        $("[data-type='hidden'] .input .form-control").val($(country));
        
.field {
  padding: 10px 0;
}

.form-control {
  padding: 10px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/css/intlTelInput.css">
<div class="fields">
  <div class="field" data-type="name" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="Wie sollen wir Sie ansprechen?" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="phone" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="email" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="E-Mail Adresse *" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="hidden" style="width: 247px;">
    <div class="input"><input class="form-control" type="text" style="border-radius: 15px;" value="hidden content"></div>
  </div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/intlTelInput-jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/utils.js"></script>

There is int-tel-input jQuery plugin in the field for telephone number that sets country dial code using user ip. I want duplicate this information to the hiddden field. Or to be more exact, take data from attribute "title" of element with class .selected-flag and fill in this information "hidden" field.

Unfortunately, I have very poor skills in JS and jQuery, so I can't figure out how to make it works. You can see my attempts in the JS code field.

Please, give me a hint or solution to solve my problem.

Anton
  • 45
  • 7

3 Answers3

3

Because I completely forgot that the DOMSubtreeModified event has been deprecated – and because, as Smollet777 accurately commented, the DOMSubtreeModified approaches didn't work on changing the flag – the following approach is recommended instead of the versions:

// caching the elements ('target' and 'recipient') for later use:
let target = document.querySelector('.selected-flag'),
    recipient = document.querySelector('[data-type=hidden] input.form-control'),

// setting the options for the MutationObserver, these are the
// mutation-types we're looking for:
    options = {
      'attributes' : true
    },

// the MutationObserver callback function:
    observationHandler = function(mutations, observer){

      // for each mutation of the list of mutations:
      for (let mutation of mutations) {

        // we update the value property of the recipient Node,
        // setting that value to the 'title' property-value
        // from the 'target' Node:
        recipient.value = target.title;
      }
    },

 // initialising a new MutationObserver, passing in the
 // callback function:
    observer = new MutationObserver(observationHandler);

 // using the observer.observe() method to observe the
 // 'target' Node using the options defined earlier:
    observer.observe(target, options);

$("[data-type='phone'] .input .form-control").intlTelInput({

  allowDropdown: true,
  autoPlaceholder: "aggressive",
  initialCountry: "auto",
  geoIpLookup: function(success, failure) {
    $.get("https://ipinfo.io", function() {}, "jsonp").always(function(resp) {
      var countryCode = (resp && resp.country) ? resp.country : "";
      success(countryCode);
    });
  },
});

let target = document.querySelector('.selected-flag'),
  recipient = document.querySelector('[data-type=hidden] input.form-control'),
  options = {
    'attributes': true
  },
  observationHandler = function(mutations, observer) {
    for (let mutation of mutations) {
      recipient.value = target.title;
    }
  },
  observer = new MutationObserver(observationHandler);

observer.observe(target, options);
.field {
  padding: 10px 0;
}

.form-control {
  padding: 10px;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/css/intlTelInput.css">
<div class="fields">
  <div class="field" data-type="name" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="Wie sollen wir Sie ansprechen?" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="phone" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="email" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="E-Mail Adresse *" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="hidden" style="width: 247px;">
    <div class="input"><input class="form-control" type="text" style="border-radius: 15px;" value="hidden content"></div>
  </div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/intlTelInput-jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/utils.js"></script>

JS Fiddle demo.

With regard to the issues raised in the comments, that this solution only works with the first of multiple similar forms on the page, the following is amended to work with multiple similar forms:

// cache all relevant elements, using document.querySelectorAll():
let targets = document.querySelectorAll('.selected-flag'),
  options = {
    'attributes': true
  },
  observationHandler = function(mutations, observer) {
    for (let mutation of mutations) {

      // here we cache the current target (the element to which
      // the observationHandler is bound):
      let target = mutation.target,

      // we find the 'recipient' node, the element you wish
      // to update; here we navigate from the 'target' to the
      // closest ancestor element matching the supplied CSS
      // selector, and from there we look for the first (if any)
      // nodes matching the CSS selector passed to
      // document.querySelector():
            recipient = target.closest('div.fields').querySelector('[data-type="hidden"] input');

      // here we update the value of the 'recipient' node:
          recipient.value = target.title;
    }
  },
  observer = new MutationObserver(observationHandler);

  // iterating over the NodeList of elements:
  targets.forEach(

    // here we bind the mutation observer to each
    // of the matching elements from the NodeList:
    (target) => observer.observe(target, options)
  );

JS Fiddle demo.

Unfortunately, due to the character limits of Stack Overflow answers – and the length of the supplied demo – I'm unable to post the working Snippet here, but the linked JS Fiddle demo does contain full working code.

References:

David Thomas
  • 249,100
  • 51
  • 377
  • 410
  • 2
    First two snippets are not working when country is changed. – Smollet777 Dec 02 '18 at 17:56
  • 1
    Thanks! I honestly thought I'd checked that they worked. I can't believe I let that slip through (in two separate snippets)... – David Thomas Dec 02 '18 at 18:02
  • @DavidThomas did you check main form on the top of the page? (it has no problem). Issues that I described reveals in forms which are in modal windows which are called clicking on "Besichtigungstermin vereinbaren" and "Preise anfragen" buttons (green buttons on the middle and the end of the page) – Anton Dec 03 '18 at 11:20
  • @DavidThomas Thank you! Here is an example - https://jsfiddle.net/kerm131/at5sL2jc/ You can see, that auto-selection works well in all 3 form, but manual selection work only in the first one. – Anton Dec 03 '18 at 11:51
  • 1
    I've updated the answer, it should work as required now. – David Thomas Dec 03 '18 at 14:23
  • @DavidThomas Thank you very much! It works perfectly! – Anton Dec 04 '18 at 06:18
  • @DavidThomas Hello! I'm sorry to disturb you. Could you look at this question [link](https://stackoverflow.com/questions/53646154/jquery-script-doesnt-work-properly-in-ie?noredirect=1#comment94150889_53646154) that conncted with current topic? – Anton Dec 06 '18 at 07:45
0

You can do it like this

var title = $('.selected-flag').attr('title'); // get title of the element with class `selected-flag`
$("[data-type='hidden'] .input .form-control").val(title); // set value of the input

Update

As I said in the comments below, you need to listen the changes of the flag menu. I'm not sure if intlTelInput has events for that (It should) but you can handle it with this not quite good code:

$(document).ready(function() {
  $('#country-listbox > li').click(function() {
    setTimeout(function() {
      var title = $('.selected-flag').attr('title');
      $("[data-type='hidden'] .input .form-control").val(title);
    });
  });
});
Vahid
  • 6,639
  • 5
  • 37
  • 61
  • Unfortunately, it doesn't work https://jsfiddle.net/kerm131/w6oa7uhe/30/ – Anton Dec 02 '18 at 16:46
  • @Anton It actually works but what you need is to listen the changes of that flag menu. – Vahid Dec 02 '18 at 16:51
  • I'm sorry, but I did't get it. After I run this code, the "hidden" field is still empty and in the inspect tool it still has value "hidden content" with no changes. – Anton Dec 02 '18 at 16:57
  • @Anton I updated my answer. you can also see it here: https://jsfiddle.net/w6oa7uhe/31/ – Vahid Dec 02 '18 at 16:58
  • Sorry, I check your update it works! But it works only if I change the country in the dropdown list. But I need that value changed not only if I change country, but in the moment when the page is loaded up, because the country detects by IP – Anton Dec 02 '18 at 17:01
  • 1
    @Anton So then you really need to listen to intl-tel-input events (See this link: https://github.com/jackocnr/intl-tel-input#events) But just to make it work: https://jsfiddle.net/w6oa7uhe/32/ (I really don't recommend this code though) – Vahid Dec 02 '18 at 17:09
0

Do it like below:

Value of selected flag changes in async manner so there has to be some function that can listen to the attribute change (here it is title)

check() function listens for title change every 0.5 sec

        $("[data-type='phone'] .input .form-control").intlTelInput({

          allowDropdown: true,
          autoPlaceholder: "aggressive",
          initialCountry: "auto",
          geoIpLookup: function(success, failure) {
            $.get("https://ipinfo.io", function() {}, "jsonp").always(function(resp) {
              var countryCode = (resp && resp.country) ? resp.country : "";
              success(countryCode);
            });
          },
        });
        
        function check() { //this function is important
         if (!$('.selected-flag').attr('title')) {
          return setTimeout(check, 500);
        }

       let country = $('.selected-flag').attr('title');
       $("[data-type='hidden'] .input .form-control").val(country);
}

check();
        
        
.field {
  padding: 10px 0;
}

.form-control {
  padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/css/intlTelInput.css">
<div class="fields">
  <div class="field" data-type="name" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="Wie sollen wir Sie ansprechen?" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="phone" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="email" style="width: 247px;">
    <div class="input"><input class="form-control text" type="text" data-placeholder="true" value="E-Mail Adresse *" style="border-radius: 15px;"></div>
  </div>
  <div class="field" data-type="hidden" style="width: 247px;">
    <div class="input"><input class="form-control" type="text" style="border-radius: 15px;" value="hidden content"></div>
  </div>
</div>
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/intlTelInput-jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/intl-tel-input/14.0.6/js/utils.js"></script>
Ambrish Pathak
  • 3,813
  • 2
  • 15
  • 30