ani_css
ani_css

Reputation: 2126

Focus on the next form element with datepicker

I have some form elements (4) and when I fill or select current element it must focus next element but I'm using some jquery plugin jquery pikaday and jquery flexdatalist my first input has datalist, second and third element has datepicker and fourth element has select list and my question how can I auto focus next element them when they fill or selected ?

$(document).ready(function() {
  
  $('.flexdatalist').flexdatalist({
       minLength: 0,
       searchContain:true,
  });

  $(document).on('focus', '.checkin, .checkout', function() {
    return new Pikaday({
      numberOfMonths: 2,
      field: this,
      format: "DD.MM.YYYY",
      minDate: new Date(),
      firstDay: 1,
      maxDate: new Date(2020, 12, 31),
      onSelect: function() {
        e = this.getDate();
      }
    });
  });
});
body {
  padding: 30px;
}
input,
select {
  width: 100%;
  padding: 10px;
  border: 1px solid #ccc;
}
<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.5.1/css/pikaday.min.css" />
  <link rel="stylesheet" href="http://cdn.anitur.com.tr/example/flexdatalist/flexdatalist.css" />
</head>

<body>


  <div class="container">


    <div class="row">

      <div class="col-lg-3 col-md-3 col-sm-3">
        <input type="text" name="" class='flexdatalist' data-min-length='1' list='languages' name='language' />
        <datalist id="languages">
          <option value="PHP">PHP</option>
          <option value="JavaScript">JavaScript</option>
          <option value="Cobol">Cobol</option>
          <option value="C#">C#</option>
          <option value="C++">C++</option>
          <option value="Java">Java</option>
          <option value="Pascal">Pascal</option>
          <option value="FORTRAN">FORTRAN</option>
          <option value="Lisp">Lisp</option>
          <option value="Swift">Swift</option>
          <option value="ActionScript">ActionScript</option>
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">
        <input type="text" class="checkin" />
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">

        <input type="text" class="checkout" />
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">

        <select name="select" id="select">
          <option value="0">Choose</option>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
          <option value="4">4</option>
          <option value="5">5</option>
          <option value="6">6</option>
          <option value="7">7</option>
        </select>
      </div>

    </div>


  </div>



  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.5.1/pikaday.min.js"></script>

  <script src="http://cdn.anitur.com.tr/example/flexdatalist/flexdatalist.js"></script>

  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</body>

</html>

like trivago

Upvotes: 1

Views: 1553

Answers (1)

Lesotto
Lesotto

Reputation: 84

I reformatted your code a bit, since crucial JS the scripts were at the bottom. This is only for pikadate boxes on focus, I didn't go into detail for flexdatalist. Anyway, the problem you were having is that on each focus of datepickers you were assigning new ones, and thus you would get a Maximum call stack size exceeded. ('StackOverflow' :) isn't it ironic). So in this example on document ready, each plugin is assigned to the proper box separately. Additionally, for the main problem, while assigning a plugin, an additional function is passed as a function which will say how to select the next box after this one is closed. This is achieved by using onClose property while assigning the plugin. Also if you don't pass a parameter here, it will not create a problem since it is handled.

You can now use the similar method for flexdatalist, just gotta find the proper attribute within the plugin documentation (like onClose is used on pikadate).

<html lang="en">

<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.5.1/css/pikaday.min.css" />
  <link rel="stylesheet" href="http://cdn.anitur.com.tr/example/flexdatalist/flexdatalist.css" />
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/pikaday/1.5.1/pikaday.min.js"></script>

  <script src="http://cdn.anitur.com.tr/example/flexdatalist/flexdatalist.js"></script>

    <script type="text/javascript">
        $(document).ready(function() {

            $('.flexdatalist').flexdatalist({
                minLength: 0,
                searchContain:true,
                select: function () {
                    $('#checkin').focus();
                }
            });

            var assignPicker = function (id, whenClosed) {
                if (typeof whenClosed !== 'function') {
                    whenClosed = null;
                }

                return new Pikaday({
                    numberOfMonths: 2,
                    field: document.getElementById(id),
                    format: "DD.MM.YYYY",
                    minDate: new Date(),
                    firstDay: 1,
                    maxDate: new Date(2020, 12, 31),
                    onSelect: function() {
                        e = this.getDate();
                    },
                    onClose: whenClosed
                });
            }

            assignPicker('checkin', function() {
                $('#checkout').focus();
            });
            assignPicker('checkout', function() {
                $('#select').focus();
            });

        });
    </script>

    <style>
        body {
            padding: 30px;
        }
        input,
        select {
            width: 100%;
            padding: 10px;
            border: 1px solid #ccc;
        }
    </style>

</head>

<body>


  <div class="container">


    <div class="row">

      <div class="col-lg-3 col-md-3 col-sm-3">
        <input type="text" name="" class='flexdatalist' data-min-length='1' list='languages' name='language' />
        <datalist id="languages">
          <option value="PHP">PHP</option>
          <option value="JavaScript">JavaScript</option>
          <option value="Cobol">Cobol</option>
          <option value="C#">C#</option>
          <option value="C++">C++</option>
          <option value="Java">Java</option>
          <option value="Pascal">Pascal</option>
          <option value="FORTRAN">FORTRAN</option>
          <option value="Lisp">Lisp</option>
          <option value="Swift">Swift</option>
          <option value="ActionScript">ActionScript</option>
        </datalist>
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">
          <input type="text" class="checkin" id="checkin" />
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">

          <input type="text" class="checkout" id="checkout" />
      </div>
      <div class="col-lg-3 col-md-3 col-sm-3">

        <select name="select" id="select">
          <option value="0">Choose</option>
          <option value="1">1</option>
          <option value="2">2</option>
          <option value="3">3</option>
          <option value="4">4</option>
          <option value="5">5</option>
          <option value="6">6</option>
          <option value="7">7</option>
        </select>
      </div>

    </div>


  </div>




  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</body>

</html>

Edit: Here's a little update for the flexdatalist box. They have some events in the official documentation, but not sure that any of them will fit the situation.

For example, you may use change:flexdatalist like so:

$('.flexdatalist').flexdatalist({
    minLength: 0,
    searchContain:true,
}).on('change:flexdatalist', function() {
    $('#checkin').focus();
});

But the issue here, as with any other event that may suit you, is that the propagation of closing of the plugin is done only after these events. And then you would get a chained closing command on all plugins as they close one after another in a series of events. Which is what happens here, and what also happens on pikadate plugin if you try to put a focus functionality in onSelect handler. To solve this problem, I would rather recommend using another plugin which has a on-close handler which propagates only after the plugin has finished everything (at least like pikadate has). The other option would be to extend the plugin which can be a bit more work.

Upvotes: 2

Related Questions