Count Items in Filtered Repeater Displayed in Text Box

Hello All,

I am trying to add a text box on a page that will simply display the number of items listed within a repeater (when unfiltered as well as filtered).

Can anyone assist with the correct code?

Thanks,

David

Hi David,

It sounds like you are connecting the repeater to a dataset. If so, you can use the getTotalCount() function of the dataset. It will give you the total number of records if unfiltered and the number of filtered records if filtered.

let totalCount = $w("#dataset1").getTotalCount();
$w('#input1').value = totalCount;

Hello Anthony,

Thank you for the quick reply.

I just tried the code you provided, but it doesnā€™t appear to work.

The repeater is connected to a dataset (dataset3), and I have added a text box (text102) onto the page to display the value, and using this code, I receive an error:

export function page1_mouseIn(event) {
let totalCount = $w(ā€œ#dataset3ā€).getTotalCount();
$w(ā€˜#text102ā€™).value = totalCount;

Error: ā€˜valueā€™ does not exist in ā€˜text102ā€™ā€¦ Even if I change ā€˜valueā€™ to ā€˜textā€™, it doesnā€™t work.

Any thoughts?

Text should work, but you will need to fire the code somewhere else other than the mouseIn event of the page. To get the total when the page loads, you have to make sure the dataset is loaded. You use the onReady event for that.

$w.onReady( () => {
$w(ā€œ#myDatasetā€).onReady( () => {
let totalCount = $w(" #dataset3 ").getTotalCount();
$w(ā€™ #text102 ').value = totalCount;
} );
} );

When you filter the data, you would want to put the ā€œcount codeā€ there too.

Iā€™m unsure why youā€™re using the pageā€™s mouseIn, Iā€™d recommend using $w.onReady()

Is it a text or a text box? If itā€™s a textbox, try the .placeholder property instead. If itā€™s a text, it shouldnā€™t be throwing back the same error, is there a different one? It should work using .text but you could try .html = <p>${totalCount}</p>;

Aha!

That appears to work for the total count. Thank you!!

But how do I get the value to change when I apply a filter to the repeater?

David, I did mention this generally above. Are you unsure how to go about coding it?

Morning Anthony,

Thank you again for following up so quickly.

Alas, yes, I am unsure how to insert the count code into my filter code.

Just to briefly clarify on count values - I guess there are 3 different types that can be expressed:

  1. A total count (which you have provided the code for, and in my example, there are 14 records in the dataset)

  2. A filtered count (e.g.: if there are 6 records out of 14 that have me as a Project Manager, by filtering on my name in the Project Manager Filter, it will only show 6 items in the repeater or table; therefore, the count value in the text box should change from 14 to 6)

  3. A specific data field item count (e.g.: if from my 14 records, 10 projects have been allocated a ā€˜Redā€™ status in the Status Field, 3 ā€˜Amberā€™, and 1 ā€˜Greenā€™, I would have 3 text boxes to highlight these numbers)

These count calculations are the kind of thing I usually do in Excel and would very much like to be able to do in my Wix siteā€¦

Going back to no.2 from the list (filter count), a code I have in one of my filters is the below. How would I insert the count code into this?

export function dropdown4_change(event) {
let searchDELOWNER = $w(ā€˜#dropdown4ā€™).value;
$w(ā€˜#dataset3ā€™).setFilter(wixData.filter().contains(ā€œdelOwnerā€, searchDELOWNER));

Any advice would be greatly appreciated!

Thank you in advanceā€¦

David

David, you would add the filtering code in the setFilter function after the filter has been applied:

export function dropdown4_change(event) { 
 let searchDELOWNER = $w('#dropdown4').value; 
    $w('#dataset3').setFilter(wixData.filter()
        .contains("delOwner", searchDELOWNER)
        )
        .then(() => {
           let totalCount = $w("#dataset3").getTotalCount();     
           $w('#text102').value = totalCount;    
        });
}

Regarding #3, it sounds like you would need to run a separate aggregate query to get those counts since apparently you are not filtering on those values.

2 Likes

Hello Anthony,

God bless you! That code worked like a charmā€¦ Itā€™s very satisfying when it does!

Now I have 2 out of 3 counts working, I just need to figure out how to do #3.

Do you know what code I would need to use to run an aggregate query? I need to start with a Boolean field to count the TRUEs in one text box and the FALSEs in anotherā€¦

1 Like

Your Boolean reference is kind of losing me; maybe itā€™s you thinking out loud about how you would have done it in Excel. In your previous post, it sounded like ā€˜Statusā€™ is a text field with one of three values in it: ā€˜Amberā€™, ā€˜Greenā€™, or ā€˜Redā€™. If thatā€™s the case, something like the following would produce the desired result where ā€˜CollectionNameā€™ is the name of the collection, ā€˜Statusā€™ (exact upper-lower case spelling matters, by the way), and three text elements to record the counts.

The aggregate query grouped by ā€˜Statusā€™ produces an array of count totals for the different colors that is then looped through and evaluated with a switch statement. When each of the colors is found, the count value has the toString() function applied to it and then is assigned to the appropriate text element.

export function StatusTotals(){
    wixData.aggregate("CollectionName")
    .group("Status")
    .ascending("_id")
    .count()
    .run()
    .then((results) => {
        let items = results.items; // see below
        for (var i = 0; i < results.length; i++) {
            let item = results.items[i];
            let color = item.count.toString();
            switch (color) {
              case 'Amber':
                $w('#textAmberTotal').text = item.count.toString();
                break;
                
              case 'Green':
                $w('#textGreenTotal').text = item.count.toString();
                break;
                
               case 'Red':
                  $w('#textRedTotal').text = item.count.toString();
                  break;
               }
         }
    })
    .catch((error) => {
        let errorMsg = error.message;
        let code = error.code;
    });
}
2 Likes

Hello Anthony,

Thank you again for the quick replyā€¦ I really appreciate all you help.

Alas, this time, the code didnā€™t seem to work for my ā€˜Statusā€™ field.

Putting this field aside, ideally what I am trying to achieve is to count items within a Boolean field:

  • I have 14 items listed in ā€˜dataset3ā€™ collection
  • One of the fields is simply called ā€˜zā€™ (lowercase) and is a Boolean field
  • In this ā€˜zā€™ field, I have about 10 items checked (TRUE) and 4 items blank (FALSE)
  • I have added 2 text boxes onto the page: textBox2 to capture the TRUEs (10) and textBox3 to capture the number of FALSEs (4).

Can your code above be simplified to do this?

No worries if you canā€™t helpā€¦ I fell like I have taken up more of your time than I already shouldā€™veā€¦

David

1 Like

Hi David,

The code is not any simpler, but it was a simple enough adjustment to make. Notice that Iā€™m lumping the nulls, where the user chose nothing, with the falses. That may or may not be what you want to do. Take a look at the console, so you can see how the array is constructed, and why there is a need to get at the data in a more complicated way. There are other ways to extract the data from the array, but they would all involve the use of other Javascript functions and knowing how to use them.

wixData.aggregate("RetreatRegistration")
  .group("z")
  .ascending("_id")
  .count()
  .run()
  .then( (results) => {
    let items = results.items;        // see below
    console.log(items);
     for (var i = 0; i < results.length; i++) {
       let item = results.items[i];
       if (item._id === true){
            $w('#textBox2').text = item.count.toString();
        }
        if (item._id === false || item._id === null){
            $w('#textBox3').text = item.count.toString();
        }      
     }  
  } )
  .catch( (error) => {
    let errorMsg = error.message;
    let code = error.code;
  } );
1 Like

Hello Anthony,

I hope your dayā€™s going well so far.

Thank you again for the update.

Alas, I canā€™t seem to get this code to workā€¦

Any thoughts?

1 Like

Hi David,

The code does work,; it has been tested. Iā€™m wondering how you are invoking it. Do you see anything in the console window?

I have the collection name that I was testing in there. I was assuming that you would replace it with your collection. In case you werenā€™t sure, you use the actual collection name and not the dataset name.

1 Like

Hello Anthony,

Thank you for following up againā€¦

I just moved the code from the bottom of the code page to the top (so itā€™s the first code in the list), and now it works perfectly!

Thank you so very, very much for all your help! I truly appreciate itā€¦

I hope you enjoy the rest of your day!

David

@tony-brunsman Hey anthony, could you help me with something? I have the same count code you mentioned already working. Im usying it for counting items form a form submission dataset.
This form works via ā€œsubmit buttonā€ seted with an user input basic text. User wirite dawn order and dataset is collecting it. a second dataset then display this order text and displays it in a repeater.

My submition button is already ā€˜codedā€™ to then() refresh the two used datasets afterclick, so the repeater shows the last submission text right away, and this is working well.
However the count number is not refreshing. Since the count code is geting info from the same dataset that display in the repeaters, and the button refreshs it, shouldnā€™t the counter be refreshing too?
Is there a way to force this number to refresh?

Here is the submission button refreshing code I used:

export function button16_click(event) {
    ///refresh the datasets
 return $w("#dataset1").save()
    .then(() => {
 $w("#dataset1").refresh();
 $w("#dataset2").refresh();
      })
      .catch( (err) => {
 let errorMsg = err;
          console.log(errorMsg);
     });
}


Thank you verry much for any help! (and sorry for any mistakes, my english is not all perfect yet)

@lsmbird If Iā€™m understanding you correctly, it sounds like you have a getTotalCount() line somewhere else in your code and that is doing what you want. You will need to include another getTotalCount() line in this click event in the .then area. Your functioning getTotalCount() code is not like a formula in an Excel spreadsheet that dynamically updates input or text values based on changing data. You have to issue the line when you need the count to change based on events happening in your form, like this data saving routine that you have outlined here.

I hope this helps.

@tony-brunsman Edditing this answer: yep, it works, I did lik you said and also kept the original code and both are working. Thank you a lot for helping!!!