mde / ejs

Embedded JavaScript templates -- http://ejs.co
Apache License 2.0
7.7k stars 841 forks source link

Template literals #680

Closed CaedenPH closed 2 years ago

CaedenPH commented 2 years ago

I am trying to render a form-like template as shown below. image

This method below works fine, however it is very manual which is not ideal for the form that I will be creating which will have many more text inputs.

document.getElementById("name").value = "<%= name; %>";
document.getElementById("margin").value = "<%= margin; %>";
document.getElementById("mileage").value = "<%= mileage; %>";

I have tried 2 methods to automate my problem:

<% for (var i = 1; i < Object.keys(info).length; i++) { %>
            <% let x = Object.keys(info)[i]; %>
            <label for=<% x %>><%= x %></label>
            <input type="text" id="<= x %>" value="<% info[x] %>" ><br>
        <% } %>

This works except for the fact that when I reload the page the local state is preserved and the value of the text input does not return back to info[x].

My other method was to loop through through each text input and apply the value as such;

const elementsList = document.querySelectorAll("#id, #name, #margin, #mileage, #max_price, #min_price");
        const elementsArray = [...elementsList];

        elementsArray.forEach((i) => {
            document.getElementById(i).value = `<% info[${i}] %>`
        });

However the problem with this is that <% info[${i}] %> does not format the i into the template literal, but instead raises SyntaxError: Unexpected token '{'.

I have read multiple issues similiar to this however none of them seemed to help. Does anyone have any ideas how I might be able to achieve an automated text input with value of the ejs variables without manually writing out each value?

mde commented 2 years ago

I can't quite understand what you're trying to do here. Are you running EJS on your server, or in the browser?

CaedenPH commented 2 years ago

I can't quite understand what you're trying to do here. Are you running EJS on your server, or in the browser?

I am running express on the node server and rendering ejs files. The code shown is inside the ejs rendered files. Apologies for the miscommunication

mde commented 2 years ago

If you're running EJS on your server, there's no need to be using any client-side JS like document.getElementById. Just render HTML using EJS — that's what it's for. Looks like that's what you're doing in your first example. (Although the Object.keys seems redundant. You could just use for (k in info) { to iterate over the keys. (As long as you don't don't do weird shit like delete/reinsert, or use numeric keys, it's deterministic.)

I'm not sure what you mean about local state being preserved. Are you doing a hard refresh?

CaedenPH commented 2 years ago

If you're running EJS on your server, there's no need to be using any client-side JS like document.getElementById. Just render HTML using EJS — that's what it's for. Looks like that's what you're doing in your first example. (Although the Object.keys seems redundant. You could just use for (k in info) { to iterate over the keys. (As long as you don't don't do weird shit like delete/reinsert, or use numeric keys, it's deterministic.)

I'm not sure what you mean about local state being preserved. Are you doing a hard refresh?

I mean that when I reload the text input value does not return to <% info[i] %>. This is a html thing where if you edit the value it stays there even through a page reload. However, I need to make it so that on a reload the text input value will return to the value specified.

https://jsfiddle.net/ozfapyw1/ Here is an example of what I mean when I say the original value is lost. If you change the value to "e" and reload, the value does not return to "". Hope this makes sense

CaedenPH commented 2 years ago

I have found a solution which is probably not the most ideal but it works.

<% for (var i = 1; i < Object.keys(info).length; i++) { %>
            <% let x = Object.keys(info)[i]; %>
            <label for=<% x %>><%= x %></label>
            <input type="text" id="<%= x %>" value="<%= info[x] %>"><br>
        <% } %>

This renders the inputs and the values on the input, and in the javascript of that page I added

document.getElementById("form").reset();

This means that the form is reset to the values passed into the html.

Thank you

mde commented 2 years ago

Given that the persistence of client-side state is a browser issue, and not an EJS issue, it seems like your solution is actually the optimal one.