Asked By: Anonymous
I want my text input the clear when I click it and start typing, similar to an Excel cell, and for my number input to clear if a non-number is entered, or to change to the last typed number if the value is above 24. The number part is working, where if I type 25, the value changes to 5 in the cell.
Because of the tabular nature of the data, I’d like to keep my data in arrays.
Basically, how do I bind e.target.value
in my changeInput
function to the variable the is bound with bind:value={x}
?
Below is my complete code of how I’ve been trying it, but it’s not working as I would hope.
let jobNames = ['Job1', 'Job2', 'Job3']
let jobHours = Array.from(Array(3), () => Array.from(Array(2)));
let cell = Array.from(Array(3), () => Array.from(Array(3)));
let newText = true
function changeInput(e) {
let value = e.target.value;
let input = value.slice(-1);
if (newText) {
newText = false;
e.target.value = input;
}
if (e.target.type === 'number') {
if (!Number(input) && Number(input) !== 0) {
e.target.value = '';
}
if (Number(value) > 24) {
e.target.value = input;
}
}
}
</script>
<style>
container {
display: grid;
grid-template-columns: 2fr 1fr 1fr;
border-top: solid black 1px;
border-left: solid black 1px;
}
input {
width: 100%;
height: 100%;
border: none;
background-color: rgba(255, 255, 255, 0);
border-bottom: solid black 1px;
border-right: solid black 1px;
min-width: 50px;
}
</style>
<container>
{#each jobNames as name, i}
<input
type="text"
data-cell={`${i}-0`}
bind:this={cell[i][0]}
bind:value={name}
on:input={changeInput}
on:click={e => {newText = true; console.log(newText)}}
/>
{#each jobHours[i] as hour, j}
<input
class="text-center"
type="number"
data-cell={`${i}-${j+1}`}
bind:this={cell[i][j+1]}
bind:value={hour}
on:input={changeInput}
on:click={e => newText = true}
/>
{/each}
{/each}
</container>
Solution
Answered By: Anonymous
You need to pass the index from the template when the user types so we can access the bound element within the arrays jobNames
and jobHours
.
Here’s how your code will now look
<script>
// Declare variables here
function changeInput(e, i, j) {
const value = e.target.value;
const input = e.data;
if (newText) {
newText = false;
jobNames[i] = input;
}
if (!Number(input) && Number(input) !== 0) {
console.log('entered');
jobHours[i][j] = '';
}
if (Number(e.target.value) > 24) {
jobHours[i][j] = input;
}
}
</script>
{#each jobNames as name, i}
<input
type="text"
data-cell={`${i}-0`}
bind:this={cell[i][0]}
bind:value={name}
on:input={e => changeInput(e, i)}
on:click={e => {newText = true}}
/>
{#each jobHours[i] as hour, j}
<input
class="text-center"
type="text"
data-cell={`${i}-${j+1}`}
bind:this={cell[i][j+1]}
bind:value={hour}
on:input={e => changeInput(e, i, j)}
/>
{/each}
{/each}
Here is a working example on REPL.