I have a repeater to take in user input data in a form like this:
And now if the user wanted to delete an element they would check the "Delete Selected" box and then click a delete button at the bottom of the page. This is the code for this:
export async function btnDelete_click(event, $w) {
childrenAdded--;
$w("#repeater1").forEachItem(async ($item, itemData, index) => {
if ($item("#checkbox").checked === true) {
var data = $w("#repeater1").data;
data.splice(index, 1);
$w("#repeater1").data = data;
}
});
// console.log("before update: ");
// console.log($w("#repeater1").data);
updateIndexes();
// console.log($w("#repeater1").data);
}
function updateIndexes() {
var count = $w("#repeater1").data.length;
var data = [];
for (var i=0; i< count; i++) {
data.push({
"_id": i.toString()
})
}
$w("#repeater1").data = data;
}
With the way repeaters work, you have to replace the data property to update the items but everytime this is done the newly updated repeater with the forms only deletes the last item. For example, the repeater is left like this after deleting 2:
I have a feeling this is just inheritently how repeaters work but I was curious if anyone had an easy way to only delete the element selected when the repeater is not connected to a dataset?
#repeater #remove #properly #input #form
Hi omarleopaz!
I was interested in the issue of connecting the repeater to the data. This method can be used to pre-enter a large amount of information and after verification - record once. I wrote code for your repeater with the following differences: 1) you can add (addButton) and delete (delButton) any number of repeater entries; 2) in case of accidental deletion, it is possible to restore deleted records once (cancelButton); 3) each record has a unique "Id" - the time of its creation, assigned automatically. In the example, I display it in the repeater, but it can be hidden; 4) after preparation, when you press the (submitButton) , the contents of the prepared data array are displayed on the console, in real programs it can be transferred for further processing; 5) I refused to use DatePicker for entering the date of birth due to the fact that the Wix developers did not allow him to go outside the container, which leads to irrational construction and, following the example of other programmers, introduced 3 drop-down lists (date, month, year) with control of the correctness of the correct date.
Example description.
Repeater in the editor:
Full code
$w.onReady(function () { $w("#myRepeater").data = []; let tempData = [], cancelData = []; // function adding template: Items of $w("#myRepeater").data function addtemp() { const templateItem = [{ "_id": new Date().getTime().toString(), "name": "", "date_of_birth": new Date(), "D": "", "M": "", "Y": "", "age": "", "coatch": "", "team": "", "address": "", "allergies": "" }]; tempData = $w("#myRepeater").data; $w("#myRepeater").data = tempData.concat(templateItem); // add to "#myRepeater".data } // function validate date function datedmy(d, m, y) { Number.m var m2 = (m - 1).toString(); //console.log(m2) var d2 = d.toString(); var y2 = y.toString(); var x = new Date(y2, m2, d2); let xx = x.valueOf(); var dd = x.getDate(); if ((d - dd) > 0) { return false } else { return true } } // $w("#repeatedId").readOnly = true; //$w("#repeatedId").hide(); // for hide Id $w("#dropdownY").required = true; $w("#invalidDay").text = "Wrong date!"; $w("#invalidDay").hide() //placeholders $w("#dropdownD").placeholder = "D"; $w("#dropdownM").placeholder = "M"; $w("#dropdownY").placeholder = "Y"; $w("#rpeatedName").placeholder = "Name ?"; $w("#input1").placeholder = "Age ?"; $w("#input2").placeholder = "Coatch(s) ?"; $w("#input3").placeholder = "Team ?"; $w("#input4").placeholder = "Address ?"; $w("#input5").placeholder = "Does your child have any allergies?"; // Options for Date of birth: Days let opd = []; let iv, is; for (var i = 0; i < 31; i++) { iv = i + 1, is = iv.toString(), opd[i] = { "label": is, "value": is } } $w("#dropdownD").options = opd; //Monthes let opm = []; for (var im = 0; im < 12; im++) { iv = im + 1, is = iv.toString(), opm[im] = { "label": is, "value": is } } $w("#dropdownM").options = opm; //Years let opy = []; let iye = new Date().getFullYear(); for (var iy = 0; iy < 30; iy++) { iv = iye - iy, is = iv.toString(), opy[iy] = { "label": is, "value": is } } $w("#dropdownY").options = opy; // $w.onReady(function () { addtemp(); // first add to "#myRepeater".data // connect ("#repeated...").text to "#myRepeater" $w("#myRepeater").onItemReady(($item, itemData, index) => { $w("#dropdownD").placeholder = "D"; $w("#dropdownM").placeholder = "M"; $w("#dropdownY").placeholder = "Y"; $item("#repeatedId").value = itemData._id.toString(); $item("#rpeatedName").value = itemData.name; //"Name ?" $item("#input1").value = itemData.age //"Age ?" $item("#input2").value = itemData.coatch; //"Coatch(s) ?" $item("#input3").value = itemData.team; //"Team ?" $item("#input4").value = itemData.address; //"Address ?" $item("#input5").value = itemData.allergies; //"Does your child have any allergies?"; $item("#dropdownD").value = itemData.D; //Date $item("#dropdownM").value = itemData.M; //Month $item("#dropdownY").value = itemData.Y; //Year // event for registration "date_of_birth" $item("#dropdownY").onMouseOut((event) => { let d = $item("#dropdownD").value; let m = $item("#dropdownM").value; let y = $item("#dropdownY").value; if (datedmy(d, m, y)) { //validate date $item("#invalidDay").hide("fade"); Number.m var m2 = (m - 1).toString(); itemData.date_of_birth = new Date(y, m2, d) // reistration "date_of_birth" } else { $item("#invalidDay").show(); $item("#dropdownY").value = "Y?"; itemData.date_of_birth = 0; } }); // below you can add connection other "#repeated ..." elements }); // function saving $w("#myRepeater").data whith inputing values; function save() { tempData = $w("#myRepeater").data; $w("#myRepeater").forEachItem(($item, itemData, index) => { tempData[index].name = $item("#rpeatedText").value; //"Name ?" tempData[index].age = $item("#input1").value; //"Age ?" tempData[index].coatch = $item("#input2").value; //"Coatch(s) ?" tempData[index].team = $item("#input3").value; //"Team ?" tempData[index].address = $item("#input4").value; //"Address ?" tempData[index].allergies = $item("#input5").value; //"Does your child have any allergies?"; tempData[index].D = $item("#dropdownD").value; tempData[index].M = $item("#dropdownM").value; tempData[index].Y = $item("#dropdownY").value; // "date_of_birth" let d = $item("#dropdownD").value; let y = $item("#dropdownY").value; let m = $item("#dropdownM").value; Number.m var m2 = (m - 1).toString(); tempData[index].date_of_birth = new Date(y, m2, d) //"date_of_birth" }); $w("#myRepeater").data = tempData; // reset repeater data } //// Events // "#addButton" $w("#addButton").onClick((event, $w) => { addtemp(); }); // "#delButton" $w("#delButton").onClick((event, $w) => { save(); cancelData = $w("#myRepeater").data; // memory for cancel tempData = []; $w("#myRepeater").forEachItem(($item, itemData, index) => { if ($item('#checkbox1').checked === false) { tempData.push($item("#myRepeater").data[index]); } }); $w("#myRepeater").data = tempData; }); //"#cancelButton" $w("#cancelButton").onClick((event, $w) => { if (cancelData.length > 0) { $w("#myRepeater").data = cancelData; cancelData = []; } }); //"#submitButton" $w("#submitButton").onClick((event, $w) => { save(); console.log("#myRepeater :final", $w("#myRepeater").data); console.log("cancelData :final", cancelData); cancelData = []; }); }); }) // For full API documentation, including code examples, visit http://wix.to/94BuAAs
Example with the addition of 2 entries
Date of birth is entered after selecting the year from the drop-down list.
You can see how it works https://211026a.wixsite.com/mysite-15
Best wishes to you!
Hi omarleopaz! I found some useful articles on using repeaters connected to data. https://www.wix.com/corvid/forum/news-announcements/new-articles-on-repeaters-and-corvid
This article is very useful for understanding: https://support.wix.com/en/article/corvid-the-lifecycle-of-repeated-items .
I reproduced this example on my site and it works well, but there are no input elements in this example.
Have a look at this example which you can open in your own Wix Editor with all the code and elements all setup.
https://www.wix.com/corvid/forum/tips-tutorials-examples/example-input-repeaters
Note that the [age gives you the two options, one for inline actions which are for inside the repeater itself and for global actions which are for outside the repeater.
Examples of code for removal are here
https://www.wix.com/corvid/reference/$w.Repeater.html#data "... example defines event handlers to handle the creation of new items and the removal of existing items. Then it sets a repeater's data. Lastly, it adds an event handler to a "removeButton" that is not part of the repeater. Clicking the button resets the repeater's data, removing one of the items."
For example, it is proposed to remove data
// handle removal of new repeated items $w("#myRepeater").onItemRemoved( (itemData) => { console.log(`Removed: ${JSON.stringify(itemData)}`); } ); // set the repeater data to be the first part of the static data, // triggering the creation of new items $w("#myRepeater").data = bikeData; // add a handler for the "remove" button that resets the repeater data // with the middle object removed, triggering the removal of the middle // repeated item $w("#removeButton").onClick( () => { let tempData = $w("#myRepeater").data; tempData.splice(1,1); $w("#myRepeater").data = tempData; } );
Good luck!
Don´t know if I have the solution, but I see you do this 2 times:
$w("#repeater1").data = data;
once inside btnDelete_click once once in
updateIndexes() {
The first one looks superfluous. Also, you have to reset the repeater data array first to nothing before updating it with new data, like so:
$w("#repeater1").data =[]; $w("#repeater1").data = data;
Hope this helps.