0

I'm developing a web application for a company I work at. The user is able to create rows in an HTML table dynamically by setting the number of hours they want to work with. This was achieved with Javascript.

For example, if the user types in the number 5, 5 rows will show in the table.

How do I use my model with dynamic components?

I've tried adding this inside the script:

@Html.EditorFor(model => model.Price, new { htmlAttributes = new { @class = "form-control", id = "priceInput", type = "number" } })

Instead of:

const priceInput = document.createElement('priceInput');

Check the full script below.

<script type="text/javascript">
        function changeRow() {
            const aTable = document.getElementById('hourPriceTable');
            const hourTextBox = document.getElementById('hourInput');
            const rowNumber = parseInt(hourTextBox.value);
            if (rowNumber) {
                const rows = [];

                for (let i = 1; i <= rowNumber; i++) {
                    if (rowNumber < 1 || rowNumber > 24) {
                        document.getElementById('error').innerText = ('O número de horas precisa de ser entre 1 e 24.');
                        document.getElementById('error').style.color = 'red';
                        return false;
                    } else {
                        document.getElementById('error').innerText = '';
                    }
                    const row = document.createElement('tr');
                    const th = document.createElement('th');
                    const td2 = document.createElement('td');
                    th.setAttribute("class", "text-center");
                    td2.setAttribute("class", "text-center");
                    const priceInput = document.createElement('priceInput');
                    priceInput.type = 'number';
                    priceInput.setAttribute("class", "text-center");
                    th.append(i);
                    td2.append(input);
                    row.append(th);
                    row.append(td2);
                    rows.push(row);
                }
                aTable.innerHTML = "";
                rows.forEach(row => aTable.append(row));
            }
        }
    </script>

I'd like the model I'm using to work with the data (storing to database) inserted in these dynamic rows since they have text boxes inside. I've been struggling with adding this functionality as I can't use Html.EditorFor to create the text boxes inside the JavaScript code.

Any help appreciated, I'm sorry if this is confusing.

Cascavel
  • 305
  • 1
  • 3
  • 9
  • 1
    The server page runs (**executing C# methods** like `Html.EditorFor`) and generates the HTML. The client browser renders the HTML and **executes the JavaScript**. Note that there is a *strict separation of execution contexts* and that everything (and only things) that end up on the HTML (or JavaScript resource, eg.) "by some method" can be used on the client. – user2864740 Jan 10 '19 at 23:06
  • Check [This answer](https://stackoverflow.com/questions/14453704/html-helper-in-javascript) – NaDeR Star Jan 10 '19 at 23:10
  • 1
    I think you're asking how to bind the dynamic model on post. Is that right? – Khyron Jan 10 '19 at 23:14
  • I appreciate the replies so far. I had found the answer pointed out by @NaDeRStar but I didn't understand the MyCustomDataAttribute bit. I'm new to programming in general and I'm not completely familiar with the technology I'm using. It's possible that is it Khyron, I'll have a look at that! Thank you. – Cascavel Jan 10 '19 at 23:17
  • @SimãoAmaral We will need to see more of your code. Can you post the model, view and controller (both get and post). Is the dynamic table displaying ok or is that the problem? – Khyron Jan 11 '19 at 01:15

1 Answers1

0

If your javascript is in the view then you could set a variable as the html string:-

<script>
    var input = '@Html.EditorFor(model => model.CertificateCode, new { htmlAttributes = new { @class = "form-control", id = "priceInput", type = "number" } })';
</script>

input will now be the html string of the input element.

you could then create a js element by passing the input string to this:

function createElementFromHTML(htmlString) {
  var div = document.createElement('div');
  div.innerHTML = htmlString.trim();

  // Change this to div.childNodes to support multiple top-level nodes
  return div.firstChild; 
}

or if you have jQuery you can simply use:

<script>
  var input = '@Html.EditorFor(model => model.CertificateCode, new { htmlAttributes = new { @class = "form-control", id = "priceInput", type = "number" } })';
  var element = $(input);
</script>
BenG
  • 14,826
  • 5
  • 45
  • 60
  • I tried the jQuery bit but all I get is HTML text instead of the actual component. Am I doing something wrong? – Cascavel Jan 14 '19 at 00:23