1
votes

I have a ready input of datepicker in my form which I set as hidden. It will get shown as the radio button change. I also set the .input-datepicker focus by default so that I can still open the datepicker when the input button is clicked.

The problem here is, when I want to submit the form while SET BY DAY radio is active, and all datepicker input set as hidden, my form will throw an error something like below:

An invalid form control with name='start_date[]' is not focusable.

How do I focus the datepicker input only when it is shown?

function toggleDutySetting(type){
    if(type === 'day'){ 
        $('#show_date').hide();
        $('#working_hours_append').html('');
        $('.add-working-days').parent().hide();
    } else if(type === 'date'){
        $('#show_date').show();
        $('.add-working-days').parent().show();
    }
}

function addWorkingHours(){
    $('#working_hours_append').append(`
        <div class="input-group date input-datepicker" style="margin-top: 15px;">
            <input type="text" name="start_date[]" class="form-control pull-left border-radius-0" placeholder="DD-MM-YYYY" required="">
            <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
        </div>
    `);
}

$(document).ready(function(){
    $('body').on('focus',".input-datepicker ", function(){
        $(this).datepicker({ format: 'dd-mm-yyyy' });
    })
})
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" integrity="sha512-mSYUmp1HYZDFaVKK//63EcZq4iFWFjxSL+Z3T/aCt4IO9Cejm03q3NKKYN6pFQzY0SBOr8h+eCIAZHPXcpZaNw==" crossorigin="anonymous" />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js" integrity="sha512-G9dfCJFG3y/Xq8mbbqb5i3FQNVaGl0Fkkw+VPVT3L00gA4k7hyjSGNpAxykwgDw1cfJFlj5tO3XePa+ezjDQyQ==" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js" integrity="sha512-T/tUfKSV1bihCnd+MxKD0Hm1uBBroVYBOYSk1knyvQ9VyZJpc/ALb4P0r6ubwVPSGB2GvjeoMAJJImBG12TiaQ==" crossorigin="anonymous"></script>
</head>
<body>

<div class="form-group">
    <label class="radio-inline">
        <input type="radio" onchange="toggleDutySetting('day')" name="type" value="day" checked>SET BY DAY
    </label>
    <label class="radio-inline">
        <input type="radio" onchange="toggleDutySetting('date')" name="type" value="rotation">SET BY ROTATION
    </label>
</div>

<div class="form-group">
    <div class="checkbox marginless-top">
        <label><input name="weekday[]" type="checkbox" value="MONDAY">Monday</label>
    </div>
    <div class="checkbox marginless-top">
        <label><input name="weekday[]" type="checkbox" value="TUESDAY">Tuesday</label>
    </div>
</div>

<div class="form-group" id="show_date" style="display: none;">
    <div class="input-group date input-datepicker">
        <input type="text" name="start_date[]" class="form-control pull-left border-radius-0" placeholder="DD-MM-YYYY" required="">
        <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
    </div>
</div>

<div class="form-group" id="working_hours_append"></div>

<div class="text-right margin-top" style="display: none;">
    <a href="javascript:;" onclick="addWorkingHours()" class="bold add-working-days"><i class="fa fa-plus"></i>&nbsp; WORKING DAYS</a>
</div>

</body>
</html>
1
Are you wanting to focus on all newly appended input dates or only when the radio button is set to Rotation ? And by focus means you wanted open the date picker after selecting the rotation ? - Always Helping
Focus for all datepicker when radio is set to rotation and Yes for your second question. - Dragon
Focus for all datepicker when radio is set to rotation => this does not make sense. how can you focus on all datepicker when there is only ONE - the others are added after clicking working days - please clarify - Always Helping
Basically I want to call this $('body').on('focus',".input-datepicker ", function(){ $(this).datepicker({ format: 'dd-mm-yyyy' }); }) when the radio is set to rotation and remove this focus when set to day. - Dragon
I can do that when calling the function toggleDutySetting() and have to remove the default input datepicker first. Append it to it's div when rotation is active but the focus cannot be removed once it's called (the focus). - Dragon

1 Answers

1
votes

You need to set the prop required to false when you select day and when its rotation just set it to true to make sure the fields are getting validated.

I have also added focus on all new appended inputs using data-attributes to ensure that you can still use names[] to send data to your backend.

Using find method we can only target the inputs which we need using their data-attributes and a counter for each newly appended inputs. As soon as you click on add Working day the input will be focused itself and you can select the date.

If you select the SET BY DAY your form will submitted normally as required with no errors. If you select SET BY ROTATION all fields will be validated using form-control and required attributes.

Live Working Demo:

//Toggle settings
function toggleDutySetting(type) {
  if (type === 'day') {
    $('#show_date').hide()
    $('#working_hours_append').html('');
    $('.add-working-days').parent().hide();
    $('#show_date').find('input[data-id="0"').prop('required', false).blur() //remove focus
  } else if (type === 'date') {
    $('#show_date').show().prop('required', true)
    $('.add-working-days').parent().show();
    $('#show_date').find('input[data-id="0"').prop('required', true).focus() //set to focus on rotation
  }
}

//Focus counter
var counter = 1

//Add inputs
function addWorkingHours() {
  $('#working_hours_append').append(`
        <div class="input-group date input-datepicker" style="margin-top: 15px;">
            <input type="text" data-id="` + counter + `" name="start_date[]" class="form-control pull-left border-radius-0" placeholder="DD-MM-YYYY" required="">
            <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
        </div>
    `);
  //Focus only after its appended
  $('#working_hours_append').find('input[data-id="' + counter + '"]').focus()
  counter++
}

$(document).ready(function() {
  $('body').on('focus', ".input-datepicker ", function() {
    $(this).datepicker({
      format: 'dd-mm-yyyy',
      autoclose: true
    });
  })
})
<!DOCTYPE html>
<html lang="en">

<head>
  <title>Bootstrap Example</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/css/bootstrap-datepicker.min.css" integrity="sha512-mSYUmp1HYZDFaVKK//63EcZq4iFWFjxSL+Z3T/aCt4IO9Cejm03q3NKKYN6pFQzY0SBOr8h+eCIAZHPXcpZaNw==" crossorigin="anonymous"
  />
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js" integrity="sha512-G9dfCJFG3y/Xq8mbbqb5i3FQNVaGl0Fkkw+VPVT3L00gA4k7hyjSGNpAxykwgDw1cfJFlj5tO3XePa+ezjDQyQ==" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-datepicker/1.9.0/js/bootstrap-datepicker.min.js" integrity="sha512-T/tUfKSV1bihCnd+MxKD0Hm1uBBroVYBOYSk1knyvQ9VyZJpc/ALb4P0r6ubwVPSGB2GvjeoMAJJImBG12TiaQ==" crossorigin="anonymous"></script>
</head>

<body>

  <form>
    <div class="form-group">
      <label class="radio-inline">
            <input type="radio" onchange="toggleDutySetting('day')" name="type" value="day" checked>SET BY DAY
        </label>
      <label class="radio-inline">
            <input type="radio" onchange="toggleDutySetting('date')" name="type" value="rotation">SET BY ROTATION
        </label>
    </div>

    <div class="form-group">
      <div class="checkbox marginless-top">
        <label><input name="weekday[]" type="checkbox" value="MONDAY">Monday</label>
      </div>
      <div class="checkbox marginless-top">
        <label><input name="weekday[]" type="checkbox" value="TUESDAY">Tuesday</label>
      </div>
    </div>

    <div class="form-group" id="show_date" style="display: none;">
      <div class="input-group date input-datepicker">
        <input type="text" data-id="0" name="start_date[]" class="form-control pull-left border-radius-0" placeholder="DD-MM-YYYY">
        <div class="input-group-addon"><i class="fa fa-calendar"></i></div>
      </div>
    </div>

    <div class="form-group" id="working_hours_append"></div>

    <div class="text-right margin-top" style="display: none;">
      <a href="javascript:;" onclick="addWorkingHours()" class="bold add-working-days"><i class="fa fa-plus"></i>&nbsp; WORKING DAYS</a>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
  </form>

</body>

</html>