Reputation: 2126
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
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