Question:
I’m learning how to code and have run into an issue with a repeater that I would love some help with.
Product:
Wix Studio Editor
What are you trying to achieve:
I am trying to create an order form that features a repeater with various text input fields that expands items in the repeater with an add button and removes them (except for the first item) with a remove button. Essentially creating line items for the order and submitting each line item as its own separate entry into the associated database collection.
What have you already tried:
I have tried utilizing the resources available through WIX dev, Google, and ChatGPT and have what I believe is working code, but the repeater does not visually update or refresh either in the editor preview or on the published site. I have included a debug counter in my code which shows the refreshing and adding new items, but that is not reflected visually.
None of the elements within the repeater, or the repeater itself, is connected to a dataset, as I believe the code is handling those connections.
Additional information:
Here is the current code I am working with:
import wixData from ‘wix-data’;
let lineItems = ;
$w.onReady(() => {
console.log(“[onReady] Page is ready”);
// Initialize with one blank item
lineItems = [createEmptyItem()];
console.log(“[onReady] Initialized lineItems with one item:”, lineItems);
refreshRepeater();
// Add new line item
$w(‘#addLineBtn’).onClick(() => {
console.log(“[addLineBtn] Add Line button clicked”);
lineItems.push(createEmptyItem());
console.log(“[addLineBtn] New item added. Total items:”, lineItems.length);
refreshRepeater();
});
// Submit all items to collection
$w(‘#submitBtn’).onClick(() => {
console.log(“[submitBtn] Submit button clicked”);
console.log(“[submitBtn] Submitting items:”, lineItems);
submitLineItems();
});
// Handle each item when the repeater renders
$w(‘#lineItemRepeater’).onItemReady(($item, itemData, index) => {
console.log([onItemReady] Rendering line item ${index}
, itemData);
// Set initial values
$item('#graphicNameInput').value = itemData.graphicName;
$item('#qtyInput').value = itemData.qty;
$item('#widthInput').value = itemData.width;
$item('#heightInput').value = itemData.height;
$item('#tileTypeInput').value = itemData.tileType;
$item('#tileColorInput').value = itemData.tileColor;
$item('#pmsCodesInput').value = itemData.pmsCodes;
// Track input updates
$item('#graphicNameInput').onInput((e) => {
console.log(`[onInput] graphicName changed on item ${index}:`, e.target.value);
lineItems[index].graphicName = e.target.value;
});
$item('#qtyInput').onInput((e) => {
console.log(`[onInput] qty changed on item ${index}:`, e.target.value);
lineItems[index].qty = e.target.value;
});
$item('#widthInput').onInput((e) => {
console.log(`[onInput] width changed on item ${index}:`, e.target.value);
lineItems[index].width = e.target.value;
});
$item('#heightInput').onInput((e) => {
console.log(`[onInput] height changed on item ${index}:`, e.target.value);
lineItems[index].height = e.target.value;
});
$item('#tileTypeInput').onInput((e) => {
console.log(`[onInput] tileType changed on item ${index}:`, e.target.value);
lineItems[index].tileType = e.target.value;
});
$item('#tileColorInput').onInput((e) => {
console.log(`[onInput] tileColor changed on item ${index}:`, e.target.value);
lineItems[index].tileColor = e.target.value;
});
$item('#pmsCodesInput').onInput((e) => {
console.log(`[onInput] pmsCodes changed on item ${index}:`, e.target.value);
lineItems[index].pmsCodes = e.target.value;
});
// Remove line item
$item('#removeLineBtn').onClick(() => {
if (index > 0) {
console.log(`[removeLineBtn] Remove clicked on item ${index}`);
lineItems.splice(index, 1);
console.log("[removeLineBtn] Item removed. New length:", lineItems.length);
refreshRepeater();
} else {
console.log("[removeLineBtn] First item cannot be removed.");
}
});
});
});
function createEmptyItem() {
const blank = {
graphicName: ‘’,
qty: ‘’,
width: ‘’,
height: ‘’,
tileType: ‘’,
tileColor: ‘’,
pmsCodes: ‘’
};
console.log(“[createEmptyItem] Created new empty item:”, blank);
return blank;
}
function refreshRepeater() {
console.log(“[refreshRepeater] Refreshing repeater with items:”, lineItems.length);
const freshCopy = JSON.parse(JSON.stringify(lineItems));
$w(‘#lineItemRepeater’).data = freshCopy;
// Update debug counter text
$w(‘#debugCounter’).text = Total Items: ${lineItems.length}
;
}
function submitLineItems() {
console.log(“[submitLineItems] Submitting line items:”, lineItems);
const insertions = lineItems.map(item => {
console.log(“[submitLineItems] Inserting item:”, item);
return wixData.insert(“Graphics”, item);
});
Promise.all(insertions)
.then(() => {
console.log(“[submitLineItems] All items successfully inserted.”);
lineItems = [createEmptyItem()];
refreshRepeater();
})
.catch(err => {
console.error(“[submitLineItems] Error submitting items:”, err);
});
}
And here is a link to the order form on the published site: https://www.gomhf.com/orderform