i have 2 regions , in 2 regions there are 2 cities. i have to output the count and name of cities. how can i get it - pymongo

{'_id': ObjectId('619f4e58b1a936e640635e97'), 'OrderDate': '01-01-2020', 'Region': 'East', 'City': 'Boston', 'Category': 'Bars', 'Product': 'Carrot', 'Quantity': '33', 'UnitPrice': '1.77', 'TotalPrice': 58.0, '': 'Sum of TotalPrice'}
{'_id': ObjectId('619f4e58b1a936e640635e98'), 'OrderDate': '04-01-2020', 'Region': 'East', 'City': 'Boston', 'Category': 'Crackers', 'Product': 'Whole Wheat', 'Quantity': '87', 'UnitPrice': '3.49', 'TotalPrice': 303.0, '': '17988.66'}
{'_id': ObjectId('619f4e58b1a936e640635e99'), 'OrderDate': '07-01-2020', 'Region': 'West', 'City': 'Los Angeles', 'Category': 'Cookies', 'Product': 'Chocolate Chip', 'Quantity': '58', 'UnitPrice': '1.87', 'TotalPrice': 108.46, '': '15336.92'}
{'_id': ObjectId('619f4e58b1a936e640635e9a'), 'OrderDate': '10-01-2020', 'Region': 'East', 'City': 'New York', 'Category': 'Cookies', 'Product': 'Chocolate Chip', 'Quantity': '82', 'UnitPrice': '1.87', 'TotalPrice': 153.34, '': '33325.58'}
{'_id': ObjectId('619f4e58b1a936e640635e9b'), 'OrderDate': '13-01-2020', 'Region': 'East', 'City': 'Boston', 'Category': 'Cookies', 'Product': 'Arrowroot', 'Quantity': '38', 'UnitPrice': '2.18', 'TotalPrice': 82.84}
{'_id': ObjectId('619f4e58b1a936e640635e9c'), 'OrderDate': '16-01-2020', 'Region': 'East', 'City': 'Boston', 'Category': 'Bars', 'Product': 'Carrot', 'Quantity': '54', 'UnitPrice': '1.77', 'TotalPrice': 95.58}
{'_id': ObjectId('619f4e58b1a936e640635e9d'), 'OrderDate': '19-01-2020', 'Region': 'East', 'City': 'Boston', 'Category': 'Crackers', 'Product': 'Whole Wheat', 'Quantity': '149', 'UnitPrice': '3.49', 'TotalPrice': 520.01}
{'_id': ObjectId('619f4e58b1a936e640635e9e'), 'OrderDate': '22-01-2020', 'Region': 'West', 'City': 'Los Angeles', 'Category': 'Bars', 'Product': 'Carrot', 'Quantity': '51', 'UnitPrice': '1.77', 'TotalPrice': 90.27}
w=db.sales.count_documents({"Region":"West"})
e=db.sales.count_documents({"Region":"East"})
print("Total count of orders in East region and West region are",w,"and",e)
a=db.sales.aggregate([{"$project":{"Region":1,"City":1}}])
for i in a:
print(i)

Try this instead, Refer https://mongoplayground.net/p/d4L-QQXh1Id
db.collection.aggregate([
{
"$group": {
"_id": {
"Region": "$Region",
"City": "$City"
},
"Total Amount": {
"$sum": "$TotalPrice"
},
"count": {
"$sum": 1
}
},
},
{
"$project": {
"_id": 0,
"Cities": "$_id.City",
"Total Count": "$count",
"Total Amount": "$Total Amount"
}
}
])

Related

Calculate diff of values in a column under condition

I Have a DF with columns ['Region', 'Country', 'Year', 'Yearly_rank'].
I need to group by region and country and calculate for each country the change in 'Yearly_rank' between years 2016-2019
df = pd.DataFrame([{'Region': 'west europe', 'Country': 'Finland', 'Year': 2019, 'Yearly_rank': 1}, {'Region': 'west europe', 'Country': 'Denmark', 'Year': 2019, 'Yearly_rank': 2}, {'Region': 'west europe', 'Country': 'Norway', 'Year': 2019, 'Yearly_rank': 3}, {'Region': 'west europe', 'Country': 'Iceland', 'Year': 2019, 'Yearly_rank': 4}, {'Region': 'west europe',
'Country': 'Netherlands', 'Year': 2019, 'Yearly_rank': 5}, {'Region': 'west europe', 'Country': 'Switzerland', 'Year': 2019, 'Yearly_rank': 6}, {'Region': 'west europe', 'Country': 'Sweden',
'Year': 2019, 'Yearly_rank': 7}, {'Region': 'australia and new zealand', 'Country': 'New Zealand', 'Year': 2019, 'Yearly_rank': 8}, {'Region': 'north america', 'Country': 'Canada',
'Year': 2019, 'Yearly_rank': 9}, {'Region': 'west europe', 'Country': 'Austria', 'Year': 2019,
'Yearly_rank': 10}]
Try this:
cond = df["Year"].isin([2016, 2019])
change = df[cond].sort_values("Year").groupby(["Region", "Country"])["Yearly_rank"].diff()
df.assign(change=change).sort_values("change").groupby("Region").head(1)

How to check if a value is followed by another value with variable length of sequence

I have a data frame with a series of events like below:
import numpy as np
import pandas as pd
ex2 = pd.DataFrame.from_dict({'order': {266: 0, 267: 1, 268: 2, 269: 3, 270: 4, 271: 5, 739: 6, 740: 7, 741: 8, 742: 9, 743: 10, 744: 11, 1657: 12, 1658: 13, 1659: 14, 1660: 15, 1661: 16, 1662: 17, 1680: 18, 1681: 19, 1682: 20, 1683: 21, 1684: 22, 1685: 23, 1739: 24, 1740: 25, 1741: 26, 1742: 27, 1743: 28, 1744: 29, 2144: 30, 2145: 31, 2146: 32, 2147: 33, 2148: 34, 2149: 35, 2232: 36, 2233: 37, 2234: 38, 2235: 39, 2236: 40, 2237: 41, 2277: 42, 2278: 43, 2279: 44, 2280: 45, 2281: 46, 2282: 47, 2403: 48, 2404: 49, 2405: 50, 2406: 51, 2407: 52, 2408: 53, 2409: 54, 2410: 55, 2411: 56, 2412: 57, 2413: 58, 2414: 59, 2552: 60, 2553: 61, 2554: 62, 2555: 63, 2556: 64, 2557: 65, 2788: 66, 2789: 67, 2790: 68, 2791: 69, 2792: 70, 2793: 71}, 'group': {266: '0', 267: '0', 268: '0', 269: '0', 270: '0', 271: '0', 739: '0', 740: '0', 741: '0', 742: '0', 743: '0', 744: '0', 1657: '1', 1658: '1', 1659: '1', 1660: '1', 1661: '1', 1662: '1', 1680: '1', 1681: '1', 1682: '1', 1683: '1', 1684: '1', 1685: '1', 1739: '1', 1740: '1', 1741: '1', 1742: '1', 1743: '1', 1744: '1', 2144: '1', 2145: '1', 2146: '1', 2147: '1', 2148: '1', 2149: '1', 2232: '1', 2233: '1', 2234: '1', 2235: '1', 2236: '1', 2237: '1', 2277: '1', 2278: '1', 2279: '1', 2280: '1', 2281: '1', 2282: '1', 2403: '1', 2404: '1', 2405: '1', 2406: '1', 2407: '1', 2408: '1', 2409: '1', 2410: '1', 2411: '1', 2412: '1', 2413: '1', 2414: '1', 2552: '1', 2553: '1', 2554: '1', 2555: '1', 2556: '1', 2557: '1', 2788: '1', 2789: '1', 2790: '1', 2791: '1', 2792: '1', 2793: '1'}, 'id': {266: 301.0, 267: 301.0, 268: 302.0, 269: 302.0, 270: 302.0, 271: 303.0, 739: 304.0, 740: 304.0, 741: 304.0, 742: 305.0, 743: 306.0, 744: 306.0, 1657: 307.0, 1658: 301.0, 1659: 308.0, 1660: 308.0, 1661: np.nan, 1662: np.nan, 1680: 310.0, 1681: 301.0, 1682: 311.0, 1683: 311.0, 1684: 311.0, 1685: 312.0, 1739: 313.0, 1740: 313.0, 1741: 313.0, 1742: 313.0, 1743: 305.0, 1744: 305.0, 2144: 301.0, 2145: 301.0, 2146: 314.0, 2147: 305.0, 2148: 305.0, 2149: 305.0, 2232: 303.0, 2233: 303.0, 2234: 315.0, 2235: np.nan, 2236: np.nan, 2237: 316.0, 2277: 301.0, 2278: 301.0, 2279: 301.0, 2280: 305.0, 2281: 305.0, 2282: 317.0, 2403: 316.0, 2404: 316.0, 2405: 304.0, 2406: 304.0, 2407: 305.0, 2408: 310.0, 2409: 308.0, 2410: 318.0, 2411: 318.0, 2412: 305.0, 2413: 305.0, 2414: 319.0, 2552: 319.0, 2553: 320.0, 2554: 320.0, 2555: 320.0, 2556: np.nan, 2557: 310.0, 2788: 302.0, 2789: 321.0, 2790: 302.0, 2791: 302.0, 2792: 315.0, 2793: 322.0}, 'type': {266: 'A', 267: 'B', 268: 'C', 269: 'D', 270: 'E', 271: 'F', 739: 'A', 740: 'A', 741: 'C', 742: 'G', 743: 'A', 744: 'H', 1657: 'I', 1658: 'J', 1659: 'C', 1660: 'D', 1661: 'K', 1662: 'F', 1680: 'L', 1681: 'B', 1682: 'C', 1683: 'D', 1684: 'E', 1685: 'F', 1739: 'A', 1740: 'A', 1741: 'C', 1742: 'D', 1743: 'K', 1744: 'F', 2144: 'A', 2145: 'F', 2146: 'C', 2147: 'M', 2148: 'N', 2149: 'F', 2232: 'A', 2233: 'I', 2234: 'C', 2235: 'K', 2236: 'F', 2237: 'O', 2277: 'O', 2278: 'A', 2279: 'C', 2280: 'P', 2281: 'F', 2282: 'O', 2403: 'O', 2404: 'I', 2405: 'C', 2406: 'D', 2407: 'P', 2408: 'Q', 2409: 'R', 2410: 'O', 2411: 'C', 2412: 'P', 2413: 'F', 2414: 'F', 2552: 'R', 2553: 'O', 2554: 'C', 2555: 'D', 2556: 'S', 2557: 'L', 2788: 'C', 2789: 'B', 2790: 'C', 2791: 'E', 2792: 'F', 2793: 'O'}, 'is_active': {266: True, 267: True, 268: True, 269: False, 270: False, 271: True, 739: True, 740: True, 741: True, 742: True, 743: True, 744: True, 1657: True, 1658: True, 1659: True, 1660: False, 1661: True, 1662: True, 1680: False, 1681: True, 1682: True, 1683: False, 1684: False, 1685: True, 1739: True, 1740: True, 1741: True, 1742: False, 1743: True, 1744: True, 2144: True, 2145: True, 2146: True, 2147: True, 2148: True, 2149: True, 2232: True, 2233: True, 2234: True, 2235: True, 2236: True, 2237: True, 2277: True, 2278: True, 2279: True, 2280: True, 2281: True, 2282: True, 2403: True, 2404: True, 2405: True, 2406: False, 2407: True, 2408: False, 2409: True, 2410: True, 2411: True, 2412: True, 2413: True, 2414: True, 2552: True, 2553: True, 2554: True, 2555: False, 2556: True, 2557: False, 2788: True, 2789: True, 2790: True, 2791: False, 2792: True, 2793: True}, 'prev_event_type': {266: np.nan, 267: 'A', 268: np.nan, 269: 'C', 270: 'C', 271: np.nan, 739: np.nan, 740: 'A', 741: 'A', 742: np.nan, 743: np.nan, 744: 'A', 1657: np.nan, 1658: np.nan, 1659: np.nan, 1660: 'C', 1661: np.nan, 1662: np.nan, 1680: np.nan, 1681: 'J', 1682: np.nan, 1683: 'C', 1684: 'C', 1685: np.nan, 1739: np.nan, 1740: 'A', 1741: 'A', 1742: 'C', 1743: np.nan, 1744: 'K', 2144: 'B', 2145: 'A', 2146: np.nan, 2147: 'F', 2148: 'M', 2149: 'N', 2232: np.nan, 2233: 'A', 2234: np.nan, 2235: np.nan, 2236: np.nan, 2237: np.nan, 2277: 'F', 2278: 'O', 2279: 'A', 2280: 'F', 2281: 'P', 2282: np.nan, 2403: 'O', 2404: 'O', 2405: np.nan, 2406: 'C', 2407: 'F', 2408: np.nan, 2409: 'C', 2410: np.nan, 2411: 'O', 2412: 'P', 2413: 'P', 2414: np.nan, 2552: 'F', 2553: np.nan, 2554: 'O', 2555: 'C', 2556: np.nan, 2557: np.nan, 2788: 'C', 2789: np.nan, 2790: np.nan, 2791: 'C', 2792: 'C', 2793: np.nan}, 'is_of_interest': {266: False, 267: False, 268: False, 269: False, 270: True, 271: False, 739: False, 740: False, 741: False, 742: False, 743: False, 744: False, 1657: False, 1658: False, 1659: False, 1660: False, 1661: False, 1662: False, 1680: False, 1681: False, 1682: False, 1683: False, 1684: True, 1685: False, 1739: False, 1740: False, 1741: False, 1742: False, 1743: False, 1744: False, 2144: False, 2145: False, 2146: False, 2147: False, 2148: False, 2149: False, 2232: False, 2233: False, 2234: False, 2235: False, 2236: False, 2237: False, 2277: False, 2278: False, 2279: False, 2280: False, 2281: False, 2282: False, 2403: False, 2404: False, 2405: False, 2406: False, 2407: False, 2408: False, 2409: False, 2410: False, 2411: False, 2412: False, 2413: False, 2414: False, 2552: False, 2553: False, 2554: False, 2555: False, 2556: False, 2557: False, 2788: False, 2789: False, 2790: False, 2791: True, 2792: False, 2793: False}})
I need to define if an event of type == 'C' results in an event of type == 'E' for particular group and id combination (so all operations will pe performed on ex2.groupby(['group', 'id']). I know that event of type == 'C' results in event of type == 'E' if there is no active (is_active == 1) event between C and E. I currently have a backward information about previous active event type contained in prev_active_type column. So for example:
for 5th row (order == 4), which is of type E I know that prev_active_type == 'C' - therefore, C led to E.
on the other hand, for 9th row (order == 8), C doesn't result in E.
What I need to obtain is a column that would tell me if event of type == 'C' resulted in event of type E (new_column == True) or not (new_column == False). I think creating an is_of_interest column which indicates if type == E is a good start, but I can't figure out how to achieve my goal from that. THe issue is that there is a variable number of events between C and E - sometimes there is none, sometimes there is one, two or event three...
The expected output is:
ex2['expected_output2'] = {266: False, 267: False, 268: True, 269: False, 270: False, 271: False, 739: False, 740: False, 741: False, 742: False, 743: False, 744: False, 1657: False, 1658: False, 1659: False, 1660: False, 1661: False, 1662: False, 1680: False, 1681: False, 1682: True, 1683: False, 1684: False, 1685: False, 1739: False, 1740: False, 1741: False, 1742: False, 1743: False, 1744: False, 2144: False, 2145: False, 2146: False, 2147: False, 2148: False, 2149: False, 2232: False, 2233: False, 2234: False, 2235: False, 2236: False, 2237: False, 2277: False, 2278: False, 2279: False, 2280: False, 2281: False, 2282: False, 2403: False, 2404: False, 2405: False, 2406: False, 2407: False, 2408: False, 2409: False, 2410: False, 2411: False, 2412: False, 2413: False, 2414: False, 2552: False, 2553: False, 2554: False, 2555: False, 2556: False, 2557: False, 2788: False, 2789: False, 2790: True, 2791: False, 2792: False, 2793: False}.values()
I try to give a small overview of the general idea first, below you find a working code example. I assume that your data is in correct order.
The following happens:
Give every entry a 'connection number', where a new connection starts at every occurance of a C row as well as after each E row.
Then, for each of these connections, check if the following conditions apply:
The connection must have one row with a C and one row with an E, because of how the connections are created in the first step, C and E rows will only happen in the first and last row respectively.
All rows between the first and last row must have 'is_active' == False
Here a working example:
# I removed your rows as they are not needed
ex2.drop(['prev_event_type', 'is_of_interest'], axis=1, inplace=True)
def is_valid_connection(connection):
is_valid = (
(connection['type'] == 'C').any() and
(connection['type'] == 'E').any() and
(~connection.iloc[1:-1]['is_active']).all()
)
return pd.Series({'result': is_valid})
ex2['connection_number'] = ((ex2['type'] == 'C') | (ex2['type'] == 'E').shift(1, fill_value=False)).cumsum()
valid_connection_ids = ex2.groupby(['group', 'id', 'connection_number']).apply(is_valid_connection)
ex2 = ex2.merge(valid_connection_ids, left_on=['group', 'id', 'connection_number'], right_index=True)
ex2.loc[ex2['type'] != 'C', 'result'] = False
ex2 = ex2.drop('connection_number', axis=1)
Here's my interpretation for the solution to the problem above:
Sort Dataframe (by order or group,id)
ex2.sort_values(by=['group', 'id'], inplace=True)
Group Dataframe by previous event type:
grouped_df = ex2.groupby(['group', 'id', 'prev_event_type']).aggregate({
'group': 'first',
'id': 'first',
'prev_event_type': 'first',
'type': lambda x: list(x),
'is_active': lambda x: list(x)
})
Iterate through zipped values to find the sequence of E (can be improved):
def check_next(nexts, actives):
check = False
for n, a in zip(nexts, actives):
if n != 'E':
check = a
else:
return not check
return False
grouped_df['output'] = grouped_df.apply(lambda x: check_next(x['type'], x['is_active']) if x['prev_event_type'] == 'C' else False, axis=1)
And now you have every group, id pair labelled where an E event occurred before C, such that there are no active-events in between.
Let me know if this helps!

Difference between AFNetworking and Postman response with JSON request

Does anyone have any idea why I'm getting this when I POST with AFNetworking (wrong):
[ '0',
'1',
'7',
'0',
'2',
'94',
'0',
'3',
'41',
'0',
'4',
'5',
'0',
'5',
'51',
'0',
'6',
'3',
'0',
'7',
'40',
'0',
'8',
'18',
'0',
'9',
'12',
'0',
'10',
'10',
'1',
'11',
'9',
'2',
'12',
'4',
'2',
'13',
'17',
'2',
'14',
'25',
'2',
'15',
'16',
'2',
'16',
'15',
'2',
'17',
'21',
'2',
'18',
'35',
'2',
'19',
'37',
'2',
'20',
'34',
'2',
'21',
'32',
'3',
'22',
'96' ]
but I get this when I POST with postman (correct)?
[ { riderId: 7, placeId: 1, eventCategoryId: 0 },
{ riderId: 94, placeId: 2, eventCategoryId: 0 },
{ riderId: 41, placeId: 3, eventCategoryId: 0 },
{ riderId: 5, placeId: 4, eventCategoryId: 0 },
{ riderId: 51, placeId: 5, eventCategoryId: 0 },
{ riderId: 3, placeId: 6, eventCategoryId: 0 },
{ riderId: 40, placeId: 7, eventCategoryId: 0 },
{ riderId: 18, placeId: 8, eventCategoryId: 0 },
{ riderId: 12, placeId: 9, eventCategoryId: 0 },
{ riderId: 10, placeId: 10, eventCategoryId: 0 },
{ riderId: 9, placeId: 11, eventCategoryId: 1 },
{ riderId: 4, placeId: 12, eventCategoryId: 2 },
{ riderId: 17, placeId: 13, eventCategoryId: 2 },
{ riderId: 25, placeId: 14, eventCategoryId: 2 },
{ riderId: 16, placeId: 15, eventCategoryId: 2 },
{ riderId: 15, placeId: 16, eventCategoryId: 2 },
{ riderId: 21, placeId: 17, eventCategoryId: 2 },
{ riderId: 35, placeId: 18, eventCategoryId: 2 },
{ riderId: 37, placeId: 19, eventCategoryId: 2 },
{ riderId: 34, placeId: 20, eventCategoryId: 2 },
{ riderId: 32, placeId: 21, eventCategoryId: 2 },
{ riderId: 96, placeId: 22, eventCategoryId: 3 } ]
That's a node.js response btw. Same endpoint and json data being posted on both.
Thoughts?
It's just a simple NSMutableDictionary that I'm passing. Here is my AFNetworking submission code:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:#"http://192.168.20.230:3000/api/v1/test" parameters:submission success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
Figured it out. Apparently I needed to set the requestSerializer.
manager.requestSerializer = [AFJSONRequestSerializer serializer];
I thought that json was AFNetworking's default so setting that would be redundant. Ah well.
Full working code:
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.requestSerializer = [AFJSONRequestSerializer serializer];
[manager POST:#"http://192.168.20.230:3000/api/v1/test" parameters:submission success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"responseObject: %#", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];

Sencha Touch 2 pie chart has no labels

I am attempting to follow this example for creating a pie chart but my chart does not display labels for the sections. I copied and used the exact code from the example linked above.
The chart display complete with color sections but there are no labels like in the example.
My code is pasted below:
Ext.define('RevivalTimes.view.Chart', {
extend: 'Ext.chart.PolarChart',
xtype: 'chart',
requires: [
'Ext.chart.series.Pie',
'Ext.chart.interactions.Rotate'
],
config: {
title: 'Statistics',
iconCls: 'settings',
layout: 'fit',
animate: true,
interactions: ['rotate'],
colors: ['#115fa6', '#94ae0a', '#a61120', '#ff8809', '#ffd13e'],
store: {
fields: ['name', 'data1', 'data2', 'data3', 'data4', 'data5'],
data: [
{name: 'metric one', data1: 10, data2: 12, data3: 14, data4: 8, data5: 13},
{name: 'metric two', data1: 7, data2: 8, data3: 16, data4: 10, data5: 3},
{name: 'metric three', data1: 5, data2: 2, data3: 14, data4: 12, data5: 7},
{name: 'metric four', data1: 2, data2: 14, data3: 6, data4: 1, data5: 23},
{name: 'metric five', data1: 27, data2: 38, data3: 36, data4: 13, data5: 33}
]
},
series: [{
type: 'pie',
label: {
field: 'name',
display: 'rotate'
},
xField: 'data3',
donut: 30
}]
} //config
});
The labels show with the inclusion of labelField as shown in the code below:
series: [{
type: 'pie',
label: {
field: 'name',
display: 'rotate'
},
xField: 'data1',
donut: 30,
labelField: 'name',
showInLegend: true,
}],

How do I get two list panels to resize properly (dynamic)

I am using Sencha Touch 1.1 and have run into an aggravating little bug in my UI for which I've not been able to find the correct way to address in Sencha.
The symptom is that in my search panel containing two lists, it seems that the second list is folding directly under the first list, so in my example case the first list being one row is covering up the first row of the second list.
This is a fairly long code snippet, sorry if I got a little out of control. I just wanted to provide my exact test case (minus the sencha base code).
I've watered the app down to provide this example.
If you take the time to load it you will find that if you go into the "Job Export Search" option and enter 2 into the job order field and click "Check It!" the results will show.
I am putting a little job order info in the first list that returns one row. the second list containing many rows has export history details. Pull down on that second list and you see the first row has been tucked behind the first list.
moving doLayout() around the app has done nothing and the layout "fit" config option seems work fine except for the ui relationship between these two lists. I am assuming the ui just doesn't know the first list is taking up any space at render, but am unsure.
I'll just go ahead and say thanks for your time here at the top, you might not make it to the bottom.
rich
My Models:
Ext.regModel('JobModel', {
idProperty: 'id'
,fields: [
{type: 'int', name: 'id', field: 'id'}
,{type: 'string', name: 'market', field: 'market'}
,{type: 'string', name: 'client', field: 'client'}
,{type: 'string', name: 'title', field: 'title'}
,{type: 'string', name: 'owner', field: 'owner'}
]
});
Ext.regModel('ExportHistoryModel', {
idProperty: 'id'
,fields: [
{type: 'int', name: 'id', field: 'id'}
,{type: 'string', name: 'date_exported', field: 'date_exported'}
,{type: 'int', name: 'rank', field: 'rank'}
,{type: 'string', name: 'careersite', field: 'careersite'}
,{type: 'int', name: 'job_id', field: 'job_id'}
]
});
Ext.regModel('MenuModel', {
idProperty: 'id',
fields: [
{ name: 'id', type: 'int' }
,{ name: 'title', type: 'string' }
,{ name: 'target', type: 'string' }
]
});
My Stores:
Ext.regStore('JobStore', {
model: 'JobModel'
,sorters: [{
property: 'id',
direction: 'ASC'
}]
,proxy: {
type: 'localstorage',
id: 'adsel-app-jobstore'
}
,data: [
{id: 1, market: 'Boston', client: 'Creme Co.', title: 'Baker', owner: 'rwheadon'}
,{id: 2, market: 'Miami', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
,{id: 3, market: 'Dallas', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
,{id: 4, market: 'Chicago', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
,{id: 6, market: 'Fargo', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
,{id: 10, market: 'Boise', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
,{id: 21, market: 'Miami2', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
,{id: 31, market: 'Dallas2', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
,{id: 41, market: 'Chicago2', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
,{id: 61, market: 'Fargo2', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
,{id: 101, market: 'Boise2', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
,{id: 22, market: 'Miami3', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
,{id: 32, market: 'Dallas3', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
,{id: 42, market: 'Chicago3', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
,{id: 62, market: 'Fargo3', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
,{id: 102, market: 'Boise3', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
,{id: 23, market: 'Miami4', client: 'Vice Inc.', title: 'Administrative Asst.', owner: 'rwheadon'}
,{id: 33, market: 'Dallas4', client: 'Cowboy LLC', title: 'Customer Service', owner: 'rwheadon'}
,{id: 43, market: 'Chicago4', client: 'Family Care DDM', title: 'Hygenist', owner: 'rwheadon'}
,{id: 63, market: 'Fargo4', client: 'Brokers Ltd.', title: 'Sales Associate', owner: 'rwheadon'}
,{id: 103, market: 'Boise4', client: 'Tate R. Well Co.', title: 'Customer Service Representative', owner: 'rwheadon'}
]
});
Ext.regStore('ExportHistoryStore', {
model: 'ExportHistoryModel'
,sorters: [{
property: 'rank',
direction: 'ASC'
},
{property: 'job_id', direction: 'ASC'}
,{property: 'id', direction:'ASC'}]
,proxy: {
type: 'localstorage',
id: 'adsel-app-exporthistorystore'
}
,data: [
{id: 1, date_exported: '2012-03-26 08:53:00', rank: 1, careersite: 'Monster', job_id: 1}
,{id: 2, date_exported: '2012-03-26 08:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 3, date_exported: '2012-03-26 08:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 4, date_exported: '2012-03-26 08:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 5, date_exported: '2012-03-26 08:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 6, date_exported: '2012-03-26 08:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 7, date_exported: '2012-03-26 08:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 8, date_exported: '2012-03-26 08:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 9, date_exported: '2012-03-26 08:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 10, date_exported: '2012-03-26 08:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 21, date_exported: '2012-03-26 08:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 31, date_exported: '2012-03-26 09:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 41, date_exported: '2012-03-26 09:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 51, date_exported: '2012-03-26 09:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 61, date_exported: '2012-03-26 09:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 71, date_exported: '2012-03-26 09:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 81, date_exported: '2012-03-26 09:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 91, date_exported: '2012-03-26 09:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 101, date_exported: '2012-03-26 09:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 22, date_exported: '2012-03-26 09:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 32, date_exported: '2012-03-26 11:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 42, date_exported: '2012-03-26 11:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 52, date_exported: '2012-03-26 11:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 62, date_exported: '2012-03-26 11:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 72, date_exported: '2012-03-26 11:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 82, date_exported: '2012-03-26 11:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 92, date_exported: '2012-03-26 11:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 102, date_exported: '2012-03-26 11:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 23, date_exported: '2012-03-26 11:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 33, date_exported: '2012-03-26 13:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 43, date_exported: '2012-03-26 13:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 53, date_exported: '2012-03-26 13:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 63, date_exported: '2012-03-26 13:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 73, date_exported: '2012-03-26 13:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 83, date_exported: '2012-03-26 13:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 93, date_exported: '2012-03-26 13:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 103, date_exported: '2012-03-26 13:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 24, date_exported: '2012-03-26 13:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 34, date_exported: '2012-03-26 15:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 44, date_exported: '2012-03-26 15:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 54, date_exported: '2012-03-26 15:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 64, date_exported: '2012-03-26 15:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 74, date_exported: '2012-03-26 15:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 84, date_exported: '2012-03-26 15:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 94, date_exported: '2012-03-26 15:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 104, date_exported: '2012-03-26 15:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 25, date_exported: '2012-03-26 15:53:00', rank: 2, careersite: 'Monster', job_id: 2}
,{id: 35, date_exported: '2012-03-26 20:53:00', rank: 3, careersite: 'Dice', job_id: 1}
,{id: 45, date_exported: '2012-03-26 20:53:00', rank: 4, careersite: 'Dice', job_id: 2}
,{id: 55, date_exported: '2012-03-26 20:53:00', rank: 5, careersite: 'Dice', job_id: 3}
,{id: 65, date_exported: '2012-03-26 20:53:00', rank: 6, careersite: 'Dice', job_id: 4}
,{id: 75, date_exported: '2012-03-26 20:53:00', rank: 7, careersite: 'Monster', job_id: 3}
,{id: 85, date_exported: '2012-03-26 20:53:00', rank: 8, careersite: 'Monster', job_id: 4}
,{id: 95, date_exported: '2012-03-26 20:53:00', rank: 9, careersite: 'Monster', job_id: 5}
,{id: 106, date_exported: '2012-03-26 20:53:00', rank: 10, careersite: 'Monster', job_id: 10}
,{id: 1116, date_exported: '2012-03-26 08:53:00', rank: 11, careersite: 'Craigslist', job_id: 10}
,{id: 1216, date_exported: '2012-03-26 08:53:00', rank: 12, careersite: 'Craigslist', job_id: 6}
,{id: 1316, date_exported: '2012-03-26 08:53:00', rank: 13, careersite: 'Craigslist', job_id: 3}
,{id: 1416, date_exported: '2012-03-26 08:53:00', rank: 14, careersite: 'Craigslist', job_id: 1}
,{id: 1516, date_exported: '2012-03-26 08:53:00', rank: 15, careersite: 'Craigslist', job_id: 4}
,{id: 1616, date_exported: '2012-03-26 08:53:00', rank: 16, careersite: 'Monster', job_id: 6}
]
});
Ext.regStore('HomeMenuStore', {
model: 'MenuModel'
,sorters: [{
property: 'title',
direction: 'ASC'
}]
,proxy: {
type: 'localstorage',
id: 'adsel-app-homemenustore'
}
,data: [
// {id: 1, title: 'Status', targetMenu: 'statusList'}
{id:2, title:'Jobs', target: 'jobListPanel'}
,{id:3, title:'Export History', target: 'exportListPanel'}
,{id:4, title: 'Job Export Search', target: 'jobExportSearchPanel'}
]
});
overlappingListProblem.js (intitializers)
var App;
// new Ext.Application({
new Ext.Application({
name : 'AdSel',
useLoadMask : true,
launch: function (){
App = this;
//initialization
AdSel.views.homeMenuPanel = new Ext.Panel({
id: 'homeMenuPanel'
,layout: 'fit'
,dockedItems: [
AdSel.views.consoleBar
]
,items: [
AdSel.views.consoleList
]
});
AdSel.views.jobListPanel = new Ext.Panel({
id: 'jobListPanel'
,layout: 'fit'
,dockedItems: [
AdSel.views.jobsToolbar
]
,items: [
AdSel.views.jobList
]
});
AdSel.views.exportListPanel = new Ext.Panel({
id: 'exportListPanel'
,layout: 'fit'
,dockedItems: [
AdSel.views.exporthistoryToolbar
]
,items: [
AdSel.views.exporthistoryList
]
});
AdSel.views.jobExportSearchPanel = new Ext.Panel({
id: 'jobExportSearchPanel'
,layout: 'fit'
,dockedItems: [
AdSel.views.jobHistoryCheckerToolbar
,AdSel.views.joborderHistoryCheckForm
,AdSel.views.joborderPostingHistoryHeaderInfo
]
,items: [
AdSel.views.joborderPostingHistoryResultList
]
});
//render
AdSel.views.viewport = new Ext.Panel({
fullscreen : true
,layout : 'card'
,cardAnimation : 'slide'
,items: [
AdSel.views.homeMenuPanel
,AdSel.views.jobListPanel
,AdSel.views.exportListPanel
,AdSel.views.jobExportSearchPanel
]
})
}
});
hardwiredmenu-screens.js:
//MAIN SCREEN (HOME)
AdSel.views.consoleBar = new Ext.Toolbar({
id: 'consoleBar',
title: 'Job Management Console'
});
AdSel.views.consoleList = new Ext.List({
id: 'consoleList'
,store: 'HomeMenuStore'
,disableSelection: true
,itemTpl: '<div class="list-item-title">{title}</div>'
,onItemDisclosure: function (record) {
var selectedNote=record;
var theTarget = selectedNote.data.target;
if( theTarget == 'jobExportSearchPanel') {
Ext.getStore('JobStore').filter({property:'id', value: 0, exactMatch: true});
Ext.getStore('ExportHistoryStore').filter({property:'job_id', value: 0, exactMatch: true});
AdSel.views.viewport.setActiveItem(theTarget, {type: 'slide', direction: 'left'})
} else {
AdSel.views.viewport.setActiveItem(theTarget, {type: 'slide', direction: 'left'});
}
}
});
job-screens.js
//JOBS SCREEN
AdSel.views.jobsToolbar = new Ext.Toolbar({
id: 'jobsToolbar'
,ui: 'light'
,defaults: {
iconMask: true
,ui: 'plain'
}
,title: 'Jobs'
,items: [
{
iconCls: 'home',
handler: function () {
AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
}
}
]
});
AdSel.views.jobList = new Ext.List({
id: 'jobList'
,store: 'JobStore'
,disableSelection: true
,itemTpl: '<div class="list-item-title">{title} ({client}) in {market} entered by {owner}</div>'
});
//JOB EXPORTHISTORY SEARCH SCREEN
/*
* *********************************************** *
* *********************************************** *
* *********************************************** *
* JOB HISTORY *
* *********************************************** *
* *********************************************** *
* *********************************************** *
*/
AdSel.views.jobHistoryCheckerToolbar = new Ext.Toolbar({
id: 'jobHistoryCheckerToolbar'
,ui: 'light'
,dock: 'top'
,defaults: {
iconMask: true
,ui: 'plain'
}
// ,title: 'Job Posting History'
,title: 'Job Export History'
,items: [
{
iconCls: 'home'
,id: 'jobhistorycheckerHomeBtn'
,handler: function(){
AdSel.views.joborderHistoryCheckForm.reset();
Ext.getStore('JobStore').clearFilter();
Ext.getStore('ExportHistoryStore').clearFilter();
AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
}
}
,{xtype: 'spacer'}
,{
text: 'Check it!'
,ui: 'action'
,handler: function () {
var ovrEditor = AdSel.views.joborderHistoryCheckForm;
var filterid = ovrEditor.getValues().joborderid;
var theHeaderStore = Ext.getStore('JobStore');
theHeaderStore.clearFilter();
theHeaderStore.filter({property:'id', value: filterid, exactMatch: true});
var theHistoryStore = Ext.getStore('ExportHistoryStore');
theHistoryStore.clearFilter();
theHistoryStore.filter({property:'job_id', value: filterid, exactMatch: true});
var theHeaderList = AdSel.views.joborderPostingHistoryHeaderInfo;
theHeaderList.refresh();
var theHistoryList = AdSel.views.joborderPostingHistoryResultList;
theHistoryList.refresh();
AdSel.views.jobExportSearchPanel.doLayout();
}
}
]
});
AdSel.views.joborderHistoryCheckForm = new Ext.form.FormPanel({
id: 'joborderHistoryCheckForm'
,standardSubmit: false
,submitOnAction: false
,items: [
{
xtype: 'textfield'
,id: 'joborderhistorycheckform-joborderid'
,name: 'joborderid'
,label: 'JO Number'
}
]
});
AdSel.views.joborderPostingHistoryHeaderInfo = new Ext.List({
id: 'joborderPostingHistoryHeaderInfo'
// ,layout: 'fit'
,store: 'JobStore'
,disableSelection: true
,itemTpl: '<div class="list-item-title-dark"><b>Job Order: </b>{id}<br/>' +
'<b>Title: </b>{title}<br/><b>Client: </b>{client}</div>'
});
AdSel.views.joborderPostingHistoryResultList = new Ext.List({
id: 'joborderPostingHistoryResultList'
// ,layout: 'fit'
,store: 'ExportHistoryStore'
,disableSelection: true
,itemTpl: '<div class="list-item-title">Runtime: {date_exported}<br/>' +
'Career Site: {careersite}<br/>Rank: {rank}</div>'
});
exporthistory-screens.js
//EXPORTS SCREEN
AdSel.views.exporthistoryToolbar = new Ext.Toolbar({
id: 'jobsToolbar'
,ui: 'light'
,defaults: {
iconMask: true
,ui: 'plain'
}
,title: 'Export History'
,items: [
{
iconCls: 'home',
handler: function () {
AdSel.views.viewport.setActiveItem('homeMenuPanel', {type: 'slide', direction: 'right'});
}
}
]
});
AdSel.views.exporthistoryList = new Ext.List({
id: 'exporthistoryList'
,store: 'ExportHistoryStore'
,disableSelection: true
,itemTpl: '<div class="list-item-title">{date_exported} exported job# {job_id} to {careersite} (ranked {rank})</div>'
});
I am assuming most won't need the index.html, but I might as well burn a few more bytes:
<html>
<head>
<link rel="stylesheet" type="text/css" href="touch/1.1.1/resources/css/sencha-touch.css"/>
<script type="text/javascript" src="touch/1.1.1/sencha-touch.js"></script>
<script type="text/javascript" src="app/overlappingListProblem.js"></script>
<script type="text/javascript" src="app/models/models.js"></script>
<script type="text/javascript" src="app/models/stores.js"></script>
<script type="text/javascript" src="app/viewers/exporthistory-screens.js"></script>
<script type="text/javascript" src="app/viewers/hardwiredmenu-screens.js"></script>
<script type="text/javascript" src="app/viewers/job-screens.js"></script>
</head>
<body>
</body>
</html>
Posting my alternative approach where I use a form instead of stacking the two dynamic lists together in a panel:
The Form Panel
AdSel.views.joborderPostingHistoryHeaderInfoForm = new Ext.form.FormPanel({
id: 'joborderPostingHistoryHeaderInfoForm'
,standardSubmit: false
,submitOnAction: false
,items: [
{
xtype: 'textfield'
,id: 'joborderPostingHistoryHeaderInfoForm-adTitle'
,name: 'adTitle'
,label: 'Job Title'
,listeners: {
afterrender: function(ele) {
ele.fieldEl.dom.readOnly = true;
}
}
}
,{
xtype: 'textfield'
,id: 'joborderPostingHistoryHeaderInfoForm-clientName'
,name: 'clientName'
,label: 'Client'
,listeners: {
afterrender: function(ele) {
ele.fieldEl.dom.readOnly = true;
}
}
}
]
});
And then load the desired record into that form adding a little code to the Check It! button:
theHeaderStore = Ext.getStore('exactMatchJobStore');
theHeaderStore.removeAll();
theHeaderStore.load({
params:{id: filterid}
});
theHeaderStore.on('datachanged', function(){
var selectedNote = this.first();
AdSel.views.joborderPostingHistoryHeaderInfoForm.loadRecord(selectedNote);
});