-2

I had a little complex task to do which I have already completed almost, but only stuck at one place

What I am doing

  • i have 3 input fields on my UI followed by a HTML table, the Input field is simple input field where user is going to input something
  • In my HTML table I have several input field to get input from user,initially there is only one row the first column is autocomplete from which user is selecting some data and according to that I am populating the next columns of that rows
  • When there is last Input field in my case it is Disc% so when user focusout from this I am creating new row with same functionality and the focus should shift to that new row's first column which is itemName

What my issue is

  • When I am loading the page the focus is automatically on itemName which is inside the table which I don't want

  • when page loads the focus should b on input field out side the table first, then if it is last input field outside the tble after focusout it should go in table's input field

  • In my code I think setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100); this line is causing issue because when user focusout from the last input field of HTML table I am creating new row and focus shifts on new row's first column

  • I have commented the line where I think issue is

"use strict";
console.clear()


const data = [ //data to populate Item Name search input field
  {
    "ItemName": "Butter"
  },
  {
    "ItemName": "Rice"
  },
  {
    "ItemName": "Milk"
  },
  {
    "ItemName": "Ice Cream"
  },
  {
    "ItemName": "Curd"
  }
]

const data1 = { // this data will be dynamic but for now to test i am using this single data
  butter: {
    "ItemName": "Butter",
    "ItemCode": 400564,
    "PurRate": 8,
    "DiscAmt": 6,
    "gstPercentage": 35,
    "gstAmt": 5
  },
  rice: {
    "ItemName": "Rice",
    "ItemCode": 400565,
    "PurRate": 3,
    "DiscAmt": 2,
    "gstPercentage": 20,
    "gstAmt": 8
  },
  milk: {
    "ItemName": "Milk",
    "ItemCode": 200569,
    "PurRate": 1,
    "DiscAmt": 1,
    "gstPercentage": 50,
    "gstAmt": 2
  },
  'ice cream': {
    "ItemName": "Ice cream",
    "ItemCode": 800002,
    "PurRate": 16,
    "DiscAmt": 2,
    "gstPercentage": 15,
    "gstAmt": 2
  },
  curd: {
    "ItemName": "Curd",
    "ItemCode": 100289,
    "PurRate": 9,
    "DiscAmt": 1,
    "gstPercentage": 12,
    "gstAmt": 4
  },
}

var totalAmount = "";
var unitQuantity = "";

$("#supplierInput").on('input', function() {
  myCode();
});

function myCode() {
  function rowappend(tbody) { // this one is appending row{

    const markup =
      `<tr>
  <td>
    <input type="text" class="form-control commantd" name="itemNametd">
  </td>
  <td name="itemCodetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="unitQtytd">
  </td>
  <td name="purRatetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="discPercentagetd">
  </td>
  <td name="discAmttd" class="commantd"></td> 
  <td name="gstPercentagetd" class="commantd"></td>
  <td name="gstAmttd" class="commantd"></td>
  <td name="totalAmttd" class="commantd"></td>
  
</tr>`

    $(tbody).append(markup);
    setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

    const itemName = data.map(value => { //using autocomplete to for searching input field
      return value.ItemName;
    });
    $("[name=itemNametd]", tbody).last().autocomplete({
      source: itemName
    });
  }
  rowappend($('tbody', '#tableInvoice'))


  function getValues(row) {
    const search = ($('[name=itemNametd]', row).val()).toString()
    const value = data1[search.toLowerCase()];
    if (value) {
      $(row).find("[name=itemCodetd]").text(value.ItemCode);
      $(row).find("[name=purRatetd]").text(value.PurRate);
      $(row).find("[name=discAmttd]").text(value.DiscAmt);
      $(row).find("[name=gstPercentahgetd]").text(value.gstPercentage);
      $(row).find("[name=gstAmttd]").text(value.gstAmt);
    }
  }



  function calc(row) {
    const unitQuantity = $(row).find("[name=unitQtytd]").val();
    const purchaseRate = $(row).find("[name=purRatetd]").text();
    const totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));

    $(row).find("[name=totalAmttd]").text(totalAmount);

  }

  $(document).on('focusout', (e) => {
    const row = e.target.parentElement.parentElement
    if (e.target.matches('[name=discPercentagetd]')) {
      if ($(row).parent().find('tr').length - $(row).index() === 1) { // only last row
        rowappend(e.target.parentElement.parentElement.parentElement)
      }
    }

    if (e.target.matches('[name=unitQtytd]')) {
      calc(e.target.parentElement.parentElement)
    }

    if (e.target.matches("[name=itemNametd]")) {
      getValues(e.target.parentElement.parentElement)
    }

  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />

<div class="container commonDivInvoice">
  <div class="form-row">
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="dcNoInput">DC No</label> <input type="text" class="form-control" name="dcNoInput" id="dcNoInput">
    </div>
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="supplierInput">Supplier</label> <input list="supplierInputList" id="supplierInput" class="form-control custom-select ">
      <datalist id="supplierInputList">
  <option>1</option>
  <option>2</option>
      </datalist>
    </div>
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="dcInput">DC Input</label> <input type="text" class="form-control" name="dcInput" id="dcInput">
    </div>




  </div>
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>
        </tr>
      </thead>
      <tbody>

      </tbody>

    </table>

  </div>
</div>

Edit / Update

  • I have edited my code with correct data I have a datalist tag so on change of that I am creating the table row so when i change the datalist the focus shifts on the first column of the table row
  • In my actual I have structure like this after datalist I have so many input fields to fill up then want to go to table
manish thakur
  • 760
  • 9
  • 35
  • 76

2 Answers2

1

Just use $("#dcNoInput").focus(), 100); to focus on that textbox.

What I have done is got that textbox element with its id and used .focus().

"use strict";
console.clear()
$("#dcNoInput").focus();

const data = [ //data to populate Item Name search input field
  {
    "ItemName": "Butter"
  },
  {
    "ItemName": "Rice"
  },
  {
    "ItemName": "Milk"
  },
  {
    "ItemName": "Ice Cream"
  },
  {
    "ItemName": "Curd"
  }
]

const data1 = { // this data will be dynamic but for now to test i am using this single data
  butter: {
    "ItemName": "Butter",
    "ItemCode": 400564,
    "PurRate": 8,
    "DiscAmt": 6,
    "gstPercentage": 35,
    "gstAmt": 5
  },
  rice: {
    "ItemName": "Rice",
    "ItemCode": 400565,
    "PurRate": 3,
    "DiscAmt": 2,
    "gstPercentage": 20,
    "gstAmt": 8
  },
  milk: {
    "ItemName": "Milk",
    "ItemCode": 200569,
    "PurRate": 1,
    "DiscAmt": 1,
    "gstPercentage": 50,
    "gstAmt": 2
  },
  'ice cream': {
    "ItemName": "Ice cream",
    "ItemCode": 800002,
    "PurRate": 16,
    "DiscAmt": 2,
    "gstPercentage": 15,
    "gstAmt": 2
  },
  curd: {
    "ItemName": "Curd",
    "ItemCode": 100289,
    "PurRate": 9,
    "DiscAmt": 1,
    "gstPercentage": 12,
    "gstAmt": 4
  },
}

var totalAmount = "";
var unitQuantity = "";

$("#supplierInput").on('input', function() {
  var dcInput = $("#dcInput").val();

    myCode();
  if(!dcInput){
    setTimeout(() => $("#dcInput").focus(), 110);
  }
});

function myCode() {
  function rowappend(tbody) { // this one is appending row{

    const markup =
      `<tr>
  <td>
    <input type="text" class="form-control commantd" name="itemNametd">
  </td>
  <td name="itemCodetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="unitQtytd">
  </td>
  <td name="purRatetd" class="commantd"></td>
  <td>
    <input type="text" class="form-control commantd" name="discPercentagetd">
  </td>
  <td name="discAmttd" class="commantd"></td> 
  <td name="gstPercentagetd" class="commantd"></td>
  <td name="gstAmttd" class="commantd"></td>
  <td name="totalAmttd" class="commantd"></td>
  
</tr>`

    $(tbody).append(markup);
    setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);

    const itemName = data.map(value => { //using autocomplete to for searching input field
      return value.ItemName;
    });
    $("[name=itemNametd]", tbody).last().autocomplete({
      source: itemName
    });
  }
  rowappend($('tbody', '#tableInvoice'))


  function getValues(row) {
    const search = ($('[name=itemNametd]', row).val()).toString()
    const value = data1[search.toLowerCase()];
    if (value) {
      $(row).find("[name=itemCodetd]").text(value.ItemCode);
      $(row).find("[name=purRatetd]").text(value.PurRate);
      $(row).find("[name=discAmttd]").text(value.DiscAmt);
      $(row).find("[name=gstPercentahgetd]").text(value.gstPercentage);
      $(row).find("[name=gstAmttd]").text(value.gstAmt);
    }
  }



  function calc(row) {
    const unitQuantity = $(row).find("[name=unitQtytd]").val();
    const purchaseRate = $(row).find("[name=purRatetd]").text();
    const totalAmount = (parseInt(unitQuantity) * parseInt(purchaseRate));

    $(row).find("[name=totalAmttd]").text(totalAmount);

  }

  $(document).on('focusout', (e) => {
    const row = e.target.parentElement.parentElement
    if (e.target.matches('[name=discPercentagetd]')) {
      if ($(row).parent().find('tr').length - $(row).index() === 1) { // only last row
        rowappend(e.target.parentElement.parentElement.parentElement)
      }
    }

    if (e.target.matches('[name=unitQtytd]')) {
      calc(e.target.parentElement.parentElement)
    }

    if (e.target.matches("[name=itemNametd]")) {
      getValues(e.target.parentElement.parentElement)
    }

  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.2/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css" rel="stylesheet" />

<div class="container commonDivInvoice">
  <div class="form-row">
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="dcNoInput">DC No</label> <input type="text" class="form-control" name="dcNoInput" id="dcNoInput">
    </div>
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="supplierInput">Supplier</label> <input list="supplierInputList" id="supplierInput" class="form-control custom-select ">
      <datalist id="supplierInputList">
  <option>1</option>
  <option>2</option>
      </datalist>
    </div>
    <div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-2">
      <label for="dcInput">DC Input</label> <input type="text" class="form-control" name="dcInput" id="dcInput">
    </div>




  </div>
  <div class="row tableInvoice" id="commonDvScroll">
    <table class="table table-bordered" id="tableInvoice">
      <thead>
        <tr>
          <th id="itemNameth" class="commanth">Item Name</th>
          <th id="itemCodeth" class="commanth">Item Code</th>
          <th id="unitQtyth" class="commanth">Unit Qty</th>
          <th id="purRateth" class="commanth">Pur.Rate</th>
          <th id="discPercentageth" class="commanth">Disc%</th>
          <th id="discAmtth" class="commanth">Disc Amt</th>
          <th id="gstPercentageth" class="commanth">Gst%</th>
          <th id="gstAmtth" class="commanth">Gst Amt</th>
          <th id="totalAmtth" class="commanth">Total Amount</th>
        </tr>
      </thead>
      <tbody>

      </tbody>

    </table>

  </div>
</div>
Syed mohamed aladeen
  • 6,507
  • 4
  • 32
  • 59
  • No that will not work as when I will focus out from `Disc%` it will again focus on `DC No` which is not correct, Initially when page loads it should focus on `DC No` the when I `focusout` `Disc%` of table it should focus on new row which is created – manish thakur Jun 20 '19 at 05:44
  • You need to focus on the `DC No` textbox. an when the row is added in the table it should focus on the first textbox of that row. is that right? if so the updated code is working fine – Syed mohamed aladeen Jun 20 '19 at 06:15
  • no when I select any option from `datalist` it should focus on next textbox here i.e `DC Input` and after that it should go to tabels first row, if i change `setTimeout(() => $("[name=itemNametd]", tbody).last().focus(), 100);` to focus on `Dc Input` then while appending new row in table it will focus on `DC Input` which will not correct – manish thakur Jun 20 '19 at 06:19
  • hey can you please help me out on this https://stackoverflow.com/questions/56831552/how-to-auto-select-the-dropdown – manish thakur Jul 01 '19 at 09:27
0

Very simple.Write this line of code inside document.ready() and let me know.

$("#YourFormId").find('input[type="text"]').first().focus();
Dilip Oganiya
  • 1,504
  • 12
  • 20