Not sure how to title this question appropriately, but here is what I am looking for:
I have a repeater on my site that collects data based on user input. The data is sorted based on one of the data inputs and I have a “ranking/placing” text box that will automatically add what rank/place they are in based on all the other user input data. That works well.
Here is where I need a little extra help. I have a few filters on my page where the user can narrow down what they want to see based on other data inputs. The rank/place needs to update with the filtered data.
Example:
Name 1 - California, Male, 4:15, Rank 1
Name 2 - California, Male, 4:20, Rank 2
Name 3 - Oregon, Male, 4:30, Rank 3
Name 4 - Oregon, Male, 5:00, Rank 4
The data is currently sorted by Time and the appropriate rank number is applied. Now if the user wants to filter data to just show Oregon and Male, Name 1 and Name 2 disappear and Name 3 and Name 4 stay visible. But now, Name 3 and Name 4 need to have a new ranking/placing as Rank 1 and Rank 2.
Then when I reset my filters on my page, the ranking/placing goes back to the original rank/place with no filters.
Current code is:
$w.onReady( function () {
$w( “#repeater1” ).onItemReady(($item, itemData, index) => {
$item( “#text25” ).text = “#” + (index + 1 ).toString()
})
})
Here’s a way that you could do it:
-
Get the length of the text element
-
Create a new string with the end character chopped off
-
Add the index to the end of the string
$w.onReady(function () {
$w("#repeater1").onItemReady(($item, itemData, index) => {
let prevText = $item("#text25").text;
let newText = prevText.substr(0,prevText.length - 1) + (index + 1).toString();
$item("#text25").text = newText;
})
})
Thanks for your response. Not the end result I’m looking for.
In my example above all Names are in the repeater with no filtering applied. I need to be able to apply a filter, when I apply the filter to “hide” some of the data, the new data should display with an updated Rank.
Here it is with no filter:
Name 1 - California, Male, 4:15, Rank 1
Name 2 - California, Male, 4:20, Rank 2
Name 3 - Oregon, Male, 4:30, Rank 3
Name 4 - Oregon, Male, 5:00, Rank 4
Apply a filter of “Oregon”, then it will display the following:
Name 3 - Oregon, Male, 4:30, Rank 3
Name 4 - Oregon, Male, 5:00, Rank 4
But I need it to display:
Name 3 - Oregon, Male, 4:30, Rank 1
Name 4 - Oregon, Male, 5:00, Rank 2
Then when I clear my filters on the same page, all the data is back to being displayed and the Rank is back to the original.
@alan33921 I don’t think that I’m misunderstanding what you’re trying to do. The above code should achieve the end result you are looking for as it would always update the rank based on what is currently in the repeater.
How are you populating the repeater: wixData.query or a dataset? If #text25 is tied to a dataset field, that could be undoing what the onItemReady is trying to do. Just speculating …
@tony-brunsman Thanks again. I will try it again in a little bit.
My repeater is being populated by a dataset from user input. #text25 is not tied to a dataset field. It is simply a number that starts at 1 and increments by 1 down the line until the last one. Would that make a difference if it is not tied to anything?
Looks like it works. I added that code to my existing code and now it works, previously I was replacing the code. The very first time I change a filter, it keeps the original numbers, but then I change it to something else and it fixes itself for all the remaining filters. Is there something we can put in the code to make sure it updates on the first filter without having to change it?
Also any place that is #10 or above is defaulting to 110 and 111, 112 and so forth. So it is adding 1 at the beginning.
@alan33921 Right, you will need a way to remove the numbers, however many, at the end of the string and then re-apply the number appropriate for the new filter in effect.
$w.onReady(function () {
$w("#repeater1").onItemReady(($item, itemData, index) => {
let prev = $item("#text25").text;
// now loop through characters of name string
// and find the first number after the word "Rank"
let start = prev.indexOf("Rank");
for (var c = start; c < prev.length; c++) {
if (isNaN(prev.substr(c,1)) === false){
// found first number at end of string, now exit loop.
break;
}
}
let new = prev.substr(0,c) + " " + (index + 1).toString();
$item("#text25").text = new;
})
})
@tony-brunsman Thanks again. This code works. The only problem remaining is when I select a filter, the ranking does not change at first. When I change the filter and change it back, then the numbers update correctly.
@alan33921 The onItemReady runs when a new repeated item is created. To ensure that it runs every time on every displayed repeater item, you could put the code in a separate method that uses forEachItem and explicitly call that method in the filtering code.
export function ApplyRank(){
$w("#repeater1").forEachItem(($item, itemData, index) => {
let prev = $item("#text25").text;
// now loop through characters of name string
// and find the first number after the word "Rank"
let start = prev.indexOf("Rank");
for (var c = start; c < prev.length; c++) {
if (isNaN(prev.substr(c,1)) === false){
// found first number at end of string, now exit loop.
break;
}
}
let new = prev.substr(0,c) + " " + (index + 1).toString();
$item("#text25").text = new;
})
}