skip to Main Content

I am using jquery.timepicker to make a field a time picker. The default functionality it to append the drop down to the window.

I do not like the width of the dropdown and do not wish to set a fixed width, because the widget is being applied to multiple fields that get resized by responsiveness.

I need the widget (dropdown) to be the same width as the input it applies to. My first thought is to append the widget to the same parent and the input.

My question is there a way to get the id of the element that has triggered the event and add to the function options?

$(document).ready(function () {
  $('.time').timepicker({
    step: 30,
    appendTo: (e) => {
      console.log(e[0].id,`#${e[0].id}-tp`);
      return `#${e[0].id}-tp`;
    },
  });
  $('#form2').timepicker({
    step: 30,
    appendTo: '#form2-tp'
  });
});
*, *::before, *::after {
    box-sizing: border-box;
}
.input-group {
  display: flex;
  flex-wrap: wrap;
  align-items: stretch;
  width: 200px;
  position: relative;
  margin-bottom: 10px; 
}
input, .tp {
  width: 100%;
}
.tp .ui-timepicker-wrapper {
  padding: 0 10px;
  width: 100%;
}
<!DOCTYPE html>
<html lang="en-US" class="h-100">
  <head>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.14.1/jquery.timepicker.min.css" rel="stylesheet">
  </head>
  <body>
    <div class="input-group">
      <label for="form1">Field 1 (error)</label>
      <input type="text" id="form1" class="time">
      <div id="form1-tp" class="tp"></div>
    </div>
    <div class="input-group">
      <label for="form2">Field 2 (works)</label>
      <input type="text" id="form2">
      <div id="form2-tp" class="tp"></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.14.1/jquery.timepicker.min.js"></script>
  </body>
</html>

I have tried to add a function:

$('.time').timepicker({
  step: 30,
  appendTo: (e) => {
    console.log(e[0].id);
  },
});

and the browser console shows the correct element id (along with appendTo errors)

So I thought I could just return the value that I need:

$('.time').timepicker({
  step: 30,
  appendTo: (e) => {
    return `${e[0].id}-timepicker`;
  },
});

but appendTo is viewed as a function.

Short of using and id manually when calling the function i.e. $('#time-element').timepicker({...});, is it possible achieve a string output?

2

Answers


  1. The appendTo option of jQuery Timepicker cannot be a function that returns a dynamic selector directly, but there is a simple solution to append the widget to the same parent as the input while dynamically adjusting the width.

    Solution
    Use the appendTo option to dynamically specify where the widget should be added.
    Use the ID or class of the trigger element to calculate the width of the dropdown and adjust it accordingly.
    You can listen to the showTimepicker event to get the trigger element, and then adjust the dropdown after it is displayed.

    Try this:

    $('.time').timepicker({
      step: 30,
      appendTo: 'body', //You can leave it on body or set a generic parent
      beforeShow: function(input, inst) {
        //Retrieve the trigger element (the input field)
        var $input = $(input);
        var inputWidth = $input.outerWidth();
    
        //Adjust the dropdown to the same width as the input
        setTimeout(function() {
          $(inst.dpDiv).css({
            width: inputWidth + 'px'
          });
        }, 10); //Delay to ensure the dropdown is rendered before adjusting the width
      }
    });
    
    Login or Signup to reply.
  2. In the appendTo parameter, the argument is the current input, so push away from it:

    $('.time').timepicker({
      step: 30,
      appendTo: e => e.closest('.input-group').find('.tp'),
    });
    *, *::before, *::after {
        box-sizing: border-box;
    }
    .input-group {
      display: flex;
      flex-wrap: wrap;
      align-items: stretch;
      width: 200px;
      position: relative;
      margin-bottom: 10px; 
    }
    input, .tp {
      width: 100%;
    }
    .tp .ui-timepicker-wrapper {
      padding: 0 10px;
      width: 100%;
    }
    <link href="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.14.1/jquery.timepicker.min.css" rel="stylesheet">
    <div class="input-group">
      <label for="form1">Field 1 (error)</label>
      <input type="text" id="form1" class="time">
      <div class="tp"></div>
    </div>
    <div class="input-group">
      <label for="form2">Field 2 (works)</label>
      <input type="text" id="form2" class="time">
      <div class="tp"></div>
    </div>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-timepicker/1.14.1/jquery.timepicker.min.js"></script>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search