0

I have a code in Laravel-5.8 using JQuery Datepicker. The application is Dynamic input form that when you click add(+) button, it adds array of controls.

<table class="table table-bordered">
 <thead>
   <tr>
     <th scope="col">Start Date<span style="color:red;">*</span></th>
     <th scope="col">End Date<span style="color:red;">*</span></th>
     <th scope="col" width="8%"><a class="btn btn-info addRow"><i class="fa fa-plus"></i></a></th>
   </tr>
 </thead>

 <tbody>
    <td>
       <input id="startDate" type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="start_date[]" class="form-control">
    </td>
    <td>
       <input id="endDate" type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="end_date[]" class="form-control">
    </td>
 </tbody>
 </thead>
</table>


<script src="{{ asset('theme/adminlte3/plugins/jquery/jquery.js') }}"></script>
<!-- jQuery UI 1.11.4 -->
<script src="{{ asset('theme/adminlte3/plugins/jquery-ui/jquery-ui.js') }}"></script>

<script type="text/javascript">
        $(function () {
            $( "#startDate" ).datepicker({
                dateFormat: 'dd-mm-yy',
                changeMonth: true,
                changeYear: true,     
                showAnim: 'slideDown',
                duration: 'fast',                    
                yearRange: new Date().getFullYear() + ':' + new Date().getFullYear(),

            });
            
            $( "#endDate" ).datepicker({
                dateFormat: 'dd-mm-yy',
                changeMonth: true,
                changeYear: true,     
                showAnim: 'slideDown',
                duration: 'fast',                    
                yearRange: new Date().getFullYear() + ':' + new Date().getFullYear(),
            });                
     });
</script>       

   <script type="text/javascript">
    $(document).ready(function(){
        $('.addRow').on('click', function () {
   var isHod = {{ Auth::user()->is_hod == 0 ? 0 : 1 }};
    var numRows = $('.activity').length

    if (numRows<4) {
        addRow();
    }
        });

        function addRow() {
            var addRow = '<tr>\n' +
' <td><div class="input-group"><div class="input-group-prepend"><span class="input-group-text"><i class="far fa-calendar-alt"></i></span></div><input id="startDate" type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="start_date[]" class="form-control"></div></td>\n' +
' <td><div class="input-group"><div class="input-group-prepend"><span class="input-group-text"><i class="far fa-calendar-alt"></i></span></div><input id="endDate" type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="end_date[]" class="form-control"></div></td>\n' +
' <td><a   class="btn btn-danger remove"> <i class="fa fa-times"></i></a></td>\n' +
' </tr>';
            $('tbody').append(addRow);
            addRemoveListener();
        };
    addRemoveListener();
});

function addRemoveListener() {
$('.remove').on('click', function () {
        var l =$('tbody tr').length;
        if(l==1){
            alert('you cant delete last one')
        }else{

            $(this).parent().parent().remove();

        }

    });
 }

</script>

The default JQuery datepicker works fine. But when I clicked on the Add new (+) to add new ones on array. When I click on the start_date and end_date, no date was coming.

How do I resolve this?

mikefolu
  • 1,203
  • 6
  • 24
  • 57

1 Answers1

0

The problem is the way you initialize your datepicker.

You are using an anonymous function to register the datepicker

$(function () {
        $( "#startDate" ).datepicker({
            dateFormat: 'dd-mm-yy',
            changeMonth: true,
            changeYear: true,     
            showAnim: 'slideDown',
            duration: 'fast',                    
            yearRange: new Date().getFullYear() + ':' + new Date().getFullYear(),

        });
        
        // ...            
 });

which works for elements that aleady exist on the page when the function runs, but you are dynamically adding elements to the page after initialization, so the datepicker won't be registered there .

You can lookup how to register datepicker to dynamically added elements in this SO answer: https://stackoverflow.com/a/10433307/6813537

-- EDIT

In your case, the first thing you'd need to do is removing the ids start_date and end_date and instead adding something like data tags, since adding the same id multiple times to the same page is not allowed.

So you could change the code to add new lines to (notice the data-datepicker" on the inputs):

    function addRow() {
            var addRow = '<tr>\n' +
' <td><div class="input-group"><div class="input-group-prepend"><span class="input-group-text"><i class="far fa-calendar-alt"></i></span></div><input  type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="start_date[]" class="form-control" data-datepicker></div></td>\n' +
' <td><div class="input-group"><div class="input-group-prepend"><span class="input-group-text"><i class="far fa-calendar-alt"></i></span></div><input  type="text" placeholder="dd/mm/yyyy" readonly autocomplete="off" name="end_date[]" class="form-control" data-datepicker></div></td>\n' +
' <td><a   class="btn btn-danger remove"> <i class="fa fa-times"></i></a></td>\n' +
' </tr>';
            $('tbody').append(addRow);
            addRemoveListener();
        };

You should also change the id= part in your html to data-datepicker.

Now you have a way to universally target the components that should trigger your datepicker, so you could change your initialization function to

$(function () {
        $('body').on('focus',"[data-datepicker]", function(){
                 $(this).datepicker({
                         dateFormat: 'dd-mm-yy',
                         changeMonth: true,
                         changeYear: true,     
                         showAnim: 'slideDown',
                         duration: 'fast',                    
                         yearRange: new Date().getFullYear() + ':' + new Date().getFullYear(),
                 });
        });​           
 });

Explanation:

We are now registering a global event listener on the body object, that listens to the focus event, that's triggered when you enter something like a text input. The second parameter of the on function allows us to filter for only the elements we are interested in. In your case, elements with an attribute data-datepicker. We then initialize the datepicker on that object.

You can read all about the on function in the jQuery documentation https://api.jquery.com/on/

Fabian Bettag
  • 799
  • 12
  • 22