Advanced DataGrid SUM

Hi All,
I'm trying to SUM columns and display the total column at the end of each group using:
<mx:GroupingCollection id="groupedData" source="{acData}" >
                            <mx:Grouping>
                                <mx:GroupingField name="SERIES" >
                                    <mx:summaries>
                                        <mx:SummaryRow summaryPlacement="last group">
                                            <mx:fields>
                                                <mx:SummaryField dataField="Field01" operation="SUM" />
                                                <mx:SummaryField dataField="Field03" operation="SUM" />
                                            </mx:fields>
                                        </mx:SummaryRow>
                                    </mx:summaries>
                                </mx:GroupingField>
                            </mx:Grouping>
                        </mx:GroupingCollection>
with summaryPlacement="group"  shows at the top.
with summaryPlacement="last group" It shows the top and the last.
with summaryPlacement="last" Doesn't show anything. How can I fix this? It's a way to change this total ROW color as RED and display the word TOTAL.
Thanks !
Johnny

I got the solution:
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
            import mx.controls.advancedDataGridClasses.AdvancedDataGridColumn;
            import mx.collections.IViewCursor;    
            import mx.collections.SummaryObject;
            [Bindable]
            private var dpFlat:ArrayCollection = new ArrayCollection([
                {Territory:"Arizona", Territory_Rep:"Barbara Jennings", Actual:38865, Estimate:40000},
                {Territory:"Arizona", Territory_Rep:"Dana Binn", Actual:29885, Estimate:30000}, 
                {Territory:"Central California", Territory_Rep:"Joe Smith", Actual:29134, Estimate:30000}, 
                {Territory:"Nevada", Territory_Rep:"Bethany Pittman", Actual:52888, Estimate:45000}, 
                {Territory:"Northern California", Territory_Rep:"Lauren Ipsum", Actual:38805, Estimate:40000},
                {Territory:"Northern California", Territory_Rep:"T.R. Smith", Actual:55498, Estimate:40000}, 
                {Territory:"Southern California", Territory_Rep:"Alice Treu", Actual:44985, Estimate:45000},
                {Territory:"Southern California", Territory_Rep:"Jane Grove", Actual:44913, Estimate:45000}
            // Callback function to create
            // the SummaryObject used to hold the summary data.
            private function summObjFunc():SummaryObject {
                // Define the object containing the summary data.
                var obj:SummaryObject = new SummaryObject();
                // Add a field containing a value for the Territory_Rep column.
                obj.Territory_Rep = "Total:";
                return obj;
            // Callback function to summarizes
            // every other row of the Actual sales revenue for the territory.
            private function summFunc(cursor:IViewCursor, dataField:String, operation:String):Number {
                var sumRows:Number = 0;
                while (!cursor.afterLast)
                    if (dataField == "Actual")
                        sumRows += Number(cursor.current["Actual"]);
                    cursor.moveNext();
                return sumRows;
            private function formatSummary(data:Object, col:AdvancedDataGridColumn):Object{
                if ( data["Territory_Rep"] == "Total:") 
                    return { color:0xFF0000, fontWeight:"bold"}
                return {};
        ]]>
    </mx:Script>
    <mx:AdvancedDataGrid id="myADG" editable="true" width="100%" height="100%"
                         initialize="gc.refresh();" styleFunction="formatSummary">       
        <mx:dataProvider>
            <mx:GroupingCollection id="gc" source="{dpFlat}">
                <mx:Grouping>
                    <mx:GroupingField name="Territory">
                        <mx:summaries>
                            <mx:SummaryRow summaryObjectFunction="summObjFunc" summaryPlacement="last">
                                <mx:fields>
                                    <mx:SummaryField dataField="Actual" summaryFunction="summFunc"/>
                                </mx:fields>
                            </mx:SummaryRow>
                        </mx:summaries>
                    </mx:GroupingField>
                </mx:Grouping>
            </mx:GroupingCollection>
        </mx:dataProvider>       
        <mx:columns>
            <mx:AdvancedDataGridColumn dataField="Territory" editable="false"/>
            <mx:AdvancedDataGridColumn dataField="Territory_Rep" headerText="Territory Rep" editable="false"/>
            <mx:AdvancedDataGridColumn dataField="Actual" editable="true"/>
            <mx:AdvancedDataGridColumn dataField="Estimate" editable="true"/>
        </mx:columns>
    </mx:AdvancedDataGrid>
</mx:Application>

Similar Messages

  • Drag and Drop in DataGrid/Advanced DataGrid

    Hi All,
    Here is the scenario, assume that i have some 10 records in
    DataGrid/Advanced DataGrid .I have selected 4th record and when i
    try to drag the selected item to
    down, i should be able to drag all the records one step down
    from the selected record( from 4 th record to 10th record)
    i.e, re-arranging the items
    If i drag the selected item(assume that some 6th record) to
    top, say to 2nd row then from the second row all the rows
    has to come down.
    And How do we
    add the rows at middle and at the specified position?
    Any help will be appricated and Thanks in Advance.

    Hi All,
    myself got the solution for re-arranging the datagrid items
    by using the pre-defined properties of DataGrid.
    I can also get the index number of Items while start dragging
    but the problem is how do i get the index number where the Items
    dropped.
    Here is the code..............
    <?xml version="1.0" encoding="utf-8"?>
    <mx:Application xmlns:mx="
    http://www.adobe.com/2006/mxml"
    layout="horizontal">
    <mx:Script>
    <![CDATA[
    import mx.controls.Alert;
    import mx.collections.ArrayCollection;
    [Bindable]
    private var datagridData:ArrayCollection = new
    ArrayCollection([
    {task:"testing drag and
    drop",category:"Office",priority:"Medium"},
    {task:"testing datagrid
    DND",category:"personal",priority:"High"},
    {task:"testing services for
    todo",category:"office",priority:"Medium"},
    {task:"meet ravi on
    sunday",category:"personal",priority:"Low"},
    {task:"buy a book",category:"friends",priority:"Medium"},
    {task:"play cricket",category:"friends",priority:"Low"}]);
    private function onDragStart():void
    Alert.show("selected Indices"+dataGrid.selectedIndices);
    private function onDragComplete():void
    Alert.show("selected Indices"+dataGrid.selectedIndices);
    ]]>
    </mx:Script>
    <mx:DataGrid id="dataGrid" dataProvider="{datagridData}"
    dragEnabled="true" dragMoveEnabled="true"
    dropEnabled="true" allowDragSelection="true"
    allowMultipleSelection="true" rowCount="10"
    dragStart="onDragStart()"
    dragComplete="onDragComplete()">
    <!--dragStart="onDragStart()"-->
    <mx:columns>
    <mx:DataGridColumn dataField="task" headerText="Task"
    width="200"/>
    <mx:DataGridColumn dataField="category"
    headerText="Category"/>
    <mx:DataGridColumn dataField="priority"
    headerText="Priority"/>
    </mx:columns>
    </mx:DataGrid>
    </mx:Application>

  • Grouping of Data in Advanced Datagrid

    Hii,
    I need to group the data in advanced datagrid. I used the Grouping collection class, but it it not working.
    My advanced datagrid has column groups...so will this have any impact on grouping.
    Thanks!!
    Vikas

    Assuming that the table (say WALK_IN_PER_LOG) that you have has atleast the following two columns
    walk_in_date DATE -- holds date time stamp
    dob DATE -- holds date of birth
    SELECT TO_CHAR(walk_in_date,'WW')&#0124; &#0124;'-'&#0124; &#0124;TO_CHAR(walk_in_date,'DAY') "Week#-Day"
    ,TO_CHAR(TRUNC(TO_CHAR(walk_in_date,'HH24')/02),'09')&#0124; &#0124;'-'&#0124; &#0124;
    TO_CHAR(TRUNC(TO_CHAR(walk_in_date,'HH24')/02)+2,'09')
    ,COUNT(*)
    FROM walk_in_per_log
    WHERE MONTHS_BETWEEN(SYSDATE,dob) > 18*12
    GROUP BY TO_CHAR(walk_in_date,'WW')&#0124; &#0124;'-'&#0124; &#0124;TO_CHAR(walk_in_date,'DAY')
    ,TO_CHAR(TRUNC(TO_CHAR(walk_in_date,'HH24')/02),'09')&#0124; &#0124;'-'&#0124; &#0124;
    TO_CHAR(TRUNC(TO_CHAR(walk_in_date,'HH24')/02)+2,'09')
    PS I might have complicated the query a little in trying to get the formatting as you had requested but the principle is simple
    First group by the day, so that all events of one day can be compared together, then extract the hour portion of each of those dates and divide by 2 and use the quotient of the division as a grouping factor.
    eg
    from hours
    00-02 the quotient is 0 (2 is taken as 1:59:59)
    02-04 the quotient is 1 (4 is taken as 3:59:59)
    and so on
    hope this helps....

  • Grouping issue on Advanced DataGrid

    Hello,
    I've got an advanced datagrid with 5 columns, The number_Group column has data like this...
    1-10
    1-10
    11-20
    11-20
    11-20
    21-30
    21-30
    21-30
    41-50
    101-110
    When I apply Grouping, it works as expected but the 101-110 group is displayed before the 11-20 group.
    I've tried to set groupingField.numeric = true but that screws it up even more... because 11-20 isn't a number I'm guessing.
    Does anyone know a way around this? I could change the number_Group column to this...
    1
    1
    11
    11
    21
    41
    101
    and groupingField.numeric = true should work but I need the Grouping display to show 1-10, 11-20. Perhaps I can intercept this and modify it?
    Anyone got any ideas?
    Thanks,
    Nick

    Hi, Nicky
    u can solve this problem by grouping function.
    u create ur dataprovider like
    private var myData:ArrayCollection = new  ArrayCollection([{data1:1, data2:10,......},
                                                                                         {data1:1, data2:21, ....}]);
    u declare the grouping function in following manner
    private function myGroupLabelFunction(item:Object, column:AdvancedDataGridColumn):String
    // here u write ur logice to formatting ur dispalying data in advance grid.
    //suppose ur labelfield of datagrid are data1,data2, data3 respectively.
    return item.data1+"-"+item.data2;
    if u do in this way i think it will work.
    if u sucess then give me mark.
    Thanks
    Niranjan

  • PLEASE HELP!! Need some way to read header text in advanced datagrid using QTP

    I am writing a function to read column names in advanced data
    grid. There is no operation for that and any of the properties that
    I can use to read the column names.
    Please suggest any way that I can get the names of columns in
    the advanced data grid.
    Thanks

    I hope to hear something from adobe folks...I am providing
    more info.....
    I am using QTP 9.2 and Flex 3 add-in available from Adobe.
    My application has flex Advanced datagrid object and I am
    trying to read column names for the datagrid.
    I have contacted developers and they told me that column
    names for flex advanced datagrid are stored in "Header Text"
    I have tried reading "Header Text" using
    GetROProperty("HeaderText") but it doesn't return anything.
    I have tried the following code:
    x =
    Browser("app").FlexApplication("flexapp").FlexCanvas("Canvas").FlexAdvancedDatagrid("esti mategridid").GetROProperty("Header
    Text")
    msgbox x
    I have also tried getting value for column names using other
    available properties for webtables like outerhtml, outertext, alt
    etc. but I don't get any data.
    Part of the problem may be because none of the above
    mentioned properties are supported by Flex Advanced datagrid.
    I have also tried getting child objects but I always get the
    data in datagrid as values but not the column names.
    My primary reason for getting column names is to write a
    function to update cell in datagrid independent of application. So,
    I want to pass column name as a parameter to the function and get
    the corresponding columnIndex in the function by comparing the
    parameter value against column names.
    Thanks to all for you help...

  • Does compiling an advanced datagrid using flex ant task require additional config other than the license property?

    Hi,
        I am trying to build my Flex app which uses the Advanced Data Grid in a couple of locations. Originally, when I built the app using the flex ant tasks, I noticed the Visualization Trial watermark show up on the screen. I then added the license tag with the serial number to my flex-config.xml and re-ran my ant build. The watermark goes away, but then when I look at the advanced datagrid, the datagrid shows up with the hierarchy, but the data does not display in the grid (only the group by nodes are visible, not the data for the leaf elements). This works fine when I build the app using my Flex Builder. Is there something I am missing or need to add to my flex ant task to make this work?
    Any help or guidance is much appreciated.
    The following is the ant task to build the module that uses the ADG:
        <target name="compile-modules" depends="compile-shared">
            <!-- Module 1 -->
            <echo>Compiling module 1...</echo>
            <mxmlc file="${modulesrc.dir}\ui\modules\mod1\Module1.mxml"
                    output="${dist.dir}\modules\mod1\Module1.swf"
                    actionscript-file-encoding="UTF-8"
                    incremental="true"
                    default-background-color="0xFFFFFF"
                    use-network="false"
                    load-externs="${extern-report-xml}">
                <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml" />
                <source-path path-element="${FLEX_HOME}/frameworks"/>
                <!-- source paths -->
                <compiler.source-path path-element="${modulesrc.dir}"/>
                <!-- add external libraries -->
                <compiler.library-path dir="${main.dir}" append="true">
                    <include name="${lib.dir}"/>
                </compiler.library-path>
                <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                    <include name="libs" />
                    <include name="locale/{locale}" />
                </compiler.library-path>
                <compiler.debug>true</compiler.debug>
            </mxmlc>
        </target>
    And here is the ant task for the main application:
        <target name="compile-ui" depends="compile-modules">
            <mxmlc file="${src.dir}/MainApp.mxml" output="${dist.dir}/MainApp.swf"
                    actionscript-file-encoding="UTF-8" keep-generated-actionscript="false"
                    fork="true" maxmemory="1024m">
                <jvmarg value="-XX:MaxPermSize=256m"/>
                <load-config filename="${FLEX_HOME}/frameworks/flex-config.xml"/>
                <source-path path-element="${FLEX_HOME}/frameworks"/>
                <source-path path-element="${src.dir}"/>
                <source-path path-element="${main.dir}/locale/{locale}"/>
                <!-- List of SWC files or directories that contain SWC files. -->
                <!--<compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                    <include name="libs" />
                    <include name="locale/{locale}" />
                </compiler.library-path>-->
                <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true">
                    <include name="libs/datavisualization.swc" />
                    <include name="libs/flex.swc" />
                    <include name="libs/framework.swc" />
                    <include name="libs/rpc.swc" />
                    <include name="libs/utilities.swc" />
                    <include name="locale/{locale}" />
                </compiler.library-path>
                <compiler.library-path dir="${main.dir}" append="true">
                    <include name="${lib.dir}"/>
                </compiler.library-path>
                <runtime-shared-library-path path-element="${FLEX_FRAMEWORK}/framework.swc">
                    <url rsl-url="framework_3.2.0.3958.swf"/>
                    <url rsl-url="framework_3.2.0.3958.swz"/>
                </runtime-shared-library-path>
                <compiler.debug>true</compiler.debug>
            </mxmlc>
        </target>
    Regards,
    Purush

    to remove watermark i have added license key in WEB-INF\flex\license.properties file as key = value

  • HP QTP10 cannot read Automation values of Advanced DataGrid

    Hi everyone,
    We're an Automation functional testing team, testing a flex application with HP QTP v10. So far we've successfully automated many parts of the application. Now, we're struck at a serious issue.
    The issue is QTP cannot read automation values specified for an Advanced Datagrid (ADG).
    While trying to read row data of the ADG, the automation name of QTP shows like,
    "lblData | someGroup |  | ** |  |  |  |  |  |  |  |  |  | lblData"
    The screenshot of Object Spy while spying ADG is also attached.
    Other than the Automation Index, we are not able to populate any automation values of a row data.
    The ADG is a custom one. Our development team has customized it in some way, and we dont have access to the code. They are using an External renderer or Custom renderer to render values into the column.
    As there is no possiblity for value-based recording, we tried to access the ADG with index-based recording. Then, we 're able to perform operations like Click, but cannot read contents of the row/cell.
    We're using:
    HP Quick TestProfessional v10.0
    Flex plugin 4.5
    Internet Explorer 7
    Flash Player v10
    Our Questions are:
    How to get automation values for these custom ADG?
    Is there any other possible ways to access the custom ADG components other than these automation values?
    Do we need any patches/plugin upgradation to perform this?
    Is there any other tools in market that can recognize and access these custom ADGs?
    Without these automation values we're unable to proceed further work. Any replies/comments/help are welcome.
    Thank you!

    A sortCompareFunction would look something like:
    Function sortWithNullAtEnd(a:Object, b:Object, field:Array = null):int
        if (a.fieldName == null && b.fieldName == null) return 0;
        if (a.fieldName == null) return 1;
        if (b.fieldName == null) return –1;
        if (a.fieldName < b.fieldName)
            return –1;
        if (a.fieldName > b.fieldName)
            return 1;
        return 0;
    Note that this sort would be unstable so you might be better off using a second field to get stability.

  • (Advanced)DataGrid with selectable columns

    Hello -
    I'm trying to make a Flex (Advanced)DataGrid component with some mechanism where the user can toggle the visibility of the columns.  I've crudely implemented this by reading in the columns into the right-click menu, and when a column name is selected here, the visibility is toggled.  It works, but it's not the most elegant solution.
    Specifically, I'm trying to emulate the "datagrid" that Mozilla Thunderbird uses to display emails.  Here is an image:
    In the upper right, there is an icon over the scroll bar.  If there is no scrollbar, the icon remains in the same place.  When clicking the icon, it opens up a menu that shows all the possible columns, with the visible ones having a check mark next to them, like this:
    Also, the scroll bar always appears under this button, never "pushing" it over into it's own column.
    I'd like to re-create this in Flex.  I believe the menu part and creating a column with a button headerRendered is easy enough.  But I can't figure out how (if at all possible) to do this with the scrollbar, because the scrollbar always seems to be "its own column".  Any ideas or help would be appreciated.  Thank you.
      - Ian

    This blog post seems to answer your question:
    http://blog.flexgeek.in/2007/06/tips-tricks-adding-a-combobox-to-a-datagrid-header-as-head errenderer/
    http://omalraj.com/2009/06/flex-datagrid-header-with-a-combobox-filter/
    http://franto.com/custom-header-in-datagrid-part-2/
    http://blogs.adobe.com/aharui/2007/03/thinking_about_item_renderers_1.html
    If this post answers your question or helps, please mark it as such. Thanks!
    http://www.stardustsystems.com
    Adobe Flex Development and Support Services

  • Advanced datagrid dropline

    I have used dragStart and dragDrop event in advanced datagrid for drag and drop row. While draging drop line show above the drop row. I need it will be below the drop row.
    Can any one help me?

    My answer to your other question is also applicable here. The dataField property can be accessed via the listData property of your renderer if your renderer implements the  IDropInListItemRenderer interface. You'll need to cast listData to AdvancedDataGridListData.

  • SortcompareFunction is not working properly for more than 1 column in advanced datagrid

    Hi Guys,
    I am using an advanced datagrid with groupingCollection.
    I have more than 1 grouped column. How ever I am using 2 sort compare function to sort date and time.
    The problem is when I am trying to sort date its workinf properly then when I jump to time column its not working and sorting few rows only inside the  column but not the entire column. samething happen when I sort time first and the date is not sorting.
    any help will be really appriciable .
    Thanks in advance.

    In our application we tend to use views to return appropriate values for a particular user.
    For example (we do building inspections) the publication item sql is like
    select * from inspection_sites where id in (select site_id from v_pda_bi_sites where bi_id=:bi_id)
    The view acts like a dynamic parameter table (in this cases looks at experience level, status of sites, and responsibility allocations). Once the driving views are tuned this works quite efficiently, and as the dependant tables for the publication item automatically includes all of the tables in the driving view, the object gets refreshed if there is any change to any of them, even if the site details themselves have not changed

  • Get an item at a particluar position in Advanced Datagrid

    I want to access some property of an item lying at nth position in an advanced datagrid. I was not able to find any method which can return me this result. getChildAt method returns display objects of the adv DG and not the items in it. Also numChildren poperty returns number of display objects and not the number of rows.

    You MUST get it from the dataProvider.  That is the only place the data exists.  You can use the DataGrid events to return the row and column indexes into the dataProvider item.
    Or you can get a reference to the renderer, and then get to the dataprovider item through the data property. Or through your own property if it is a custom renderer.
    But one way or another, you must get to the dataProvider item.
    I do not recall the syntax, look into the dataGrid events in the docs.
    Tracy

  • Tree structure in advanced datagrid

    Hi
    I'm using advanced datagrid to mainly display heirarchical data.
    There are five columns in my datagrid and name column is heirarchical one.
    Problem I am facing is tree symbols are getting displayed in some other columns. Please help.

    Hi PAgrawal,
    Advanced DG has treeColumn property that you can assign to your name column
    This will display tree icons on required column
    Thanks and Best regards,
    Abhishek
    Abhishek Chaudhary | [email protected]
    Off: +91 712 224 5867 Ext:8358 ,  Mob: +91 992 358 8703

  • Pagination in Advanced Datagrid ..

    I need to use pagination for Flex advanced datagrid...how should i get the length of the groupingcollection for calculating my page size....
    For the Flex datagrid i have it working as I have the length of dataprovider which will be my page size....
    Any ideas...or can anyone post an example of advanced datagrid with pagination...Will be of great help...
    Thanks

    have a look @ this http://www.adobe.com/devnet/flex/articles/flashbuilder4_datapaging_php.html

  • Iconfunction in Advanced Datagrid

    I'm specifying an 'iconfunction' in my advanced datagrid - works but
    not quite as desired.
    I have two flavors of data in the grid: (a) Directory and (b) Database
    For the Directory icon I can easily specify a folder icon. There does
    not appear to me, to be a way to change this icon to an open folder
    vs. closed folder on a click. The icon is what's specified in the
    icon function.
    I've tried itemopen, itemclose with no success.
    Specifying a set of default icons works except that an empty
    directory shows up as a leaf and picks up the database icon.
    That is not what I want.
    Is there a way to have the best of both worlds?
    TIA, Chris

    I got this work after a couple of tries.
    The combination of the iconfunction and the
    item listeners did the trick.
    The AdvancedDatagrid tracks open items so
    by default the rest are closed.
    I found it easier to just maintain the state
    separately. My grid will be pretty small so
    this did the trick.
    Thanks.

  • Filtering of Grouped data in Advanced DataGrid

    I want to display the Hierarchical Data (groped data) in
    Advance DataGrid and at the same time I want the filtering
    functionality as well. The problem is if I want grouped view then I
    have to provide GroupingCollection to the dataprovider ( that has
    no filterFunction type functionality ).
    Is there any way to solve this issue?

    You have to call adg.validateNow() after assigning the
    GroupingCollection as dataProvider to the AdvancedDataGrid and
    before applying the filterFunction.
    It should be like -
    adg.dataProvider = gc;
    adg.validateNow();
    IHierarchicalCollectionView(adg.dataProvider).filterFunction
    = filterFunc;
    IHierarchicalCollectionView(adg.dataProvider).refresh();
    Note: The filter function will be applied to group rows
    also.

Maybe you are looking for

  • Re: [iPlanet-JATO] Re: Retrieving all Values from a Tiled View

    Todd, Let me try to explain you this time. I have a text field in a TiledViewBean. When I display the page, the text field html tag is created with the name="PageDetail.rDetail[0].tbFieldName" say five times/rows with same name. The html tags look li

  • Conditionally Hiding Summary Fields

    <p>Hello.</p><p>I am trying to recreate a report originally written in Foxfire to Crystal Reports. The data is coming from two linked tables, a "header" table and a "details" table. For each account from the "header" table, there may be one or more "

  • Fine grained auditing on table, but I don't want it on view

    I have a table which contains sensitive information, and I want to audit all queries on it except the web account 'EJBUSER', so I created the below policy: begin dbms_fga.add_policy( policy_name => 'STAFF_LOGON_QRY_POLICY'', object_schema => 'CPY', o

  • Editing in IPhoto11 and in Photoshop Elements 9 - help!!

    Hi, I am so confused - need help: 1.I uploaded RAW photos from Nikon D90 directly to Iphoto. I see them as NEF (raw). 2. I click on the photo to edit it FIRST in IPHOTO. I made some changes. It stays in NEF. Then, on the same photo, I choose from the

  • Legibility issue iTunes 11.2

    Some windows in iTunes 11.2 are for me now illegible in upgrade to 11.2 I'm on OS X 10.75, intel Core 2 Duo processor. Here follows two examples: Eg. 1  podcasts, where icons ar barely visible, and title invisible unless highlighted. Example 2: iPhon