I have a date picker (default one) on which I need to translate the Month column to any other language.
I have not been able to access those fields yet and can't seem to find a proper way of doing so.
Would someone know how I can set that 'picker'choices to the one I want to (ie translated text)?
{
fn: function(element, eOpts)
{
var picker = this.query('pickerslot')[0];
var store = picker.getStore();
for (i in LANG.word.months)
{
store.getAt(i).data.text=LANG.word.months[i];
}
picker.refresh();
},
event: 'painted'
}
Worked Like a charm, got it was hard to find the proper way
Related
I'm convinced I'm overthinking this and ending up in a loop of not being able to solve this issue. The short of it is I have an array which includes dates which I am displaying in a list in my main view. The entries will fire notifications to users based on the time of the date.
I want to be able to remove entries from the Array or View where the date is older than the current date and only show users the up to date entries. Almost everything I've found online doesn't seem to apply to this and I'm going round in circles trying to resolve this.
Theres a lot to unpack with my code so I've condensed it down.
struct EventListView: View {
var body: some View {
NavigationView {
//Loads the array from a CSV - no issues with this, been working with it for
all other functions in the app.
var events = loadCSV(from: "Eventtest")
List(events, id: \.id) { event in
//This function returns a true/false bool which I want to use to remove
from view/array
let eventinpast = dateInPast(value: event.date)
HStack{
VStack(alignment: .leading, spacing: 5){
Text(event.name)
.font(.subheadline)
.foregroundColor(.secondary)
Text(event.event) //confusing but this is correct.
.font(.subheadline)
.foregroundColor(.secondary)
Text(event.date)
Text(event.time)
}.frame(width: 200.0, alignment: .topLeading)
}
}
}
}
}
I've tried to change the List to include a "ForEach" but this doesn't resolve the issue as everything I've found online for this revolves around a user action to delete/remove, but I want the bool to decide if the event item is displayed/deleted or not.
I've removed my attempts for trying to delete/remove items because at this point I'm tripping myself up constantly and I'm not convinced I'm looking at the problem from the right perspective.
Most recent attempt has been following this: https://www.hackingwithswift.com/books/ios-swiftui/building-a-list-we-can-delete-from
But instead of using .onDelete I tried .onAppear but no deals. Sorry if proposing this problem is rambling, I'm quite drained from trying to get what I thought would be really simple functionality working.
Any help would be greatly appreciated! Thank you.
Sometimes it is better to do the model stuff first.
var events = loadCSV(from: "Eventtest")
events = events.filter() { !dateInPast(value: $0.date) }
how about SHOWING only the relevant events:
var events = loadCSV(from: "Eventtest").filter { !dateInPast(value: $0.date) }
or
List(events.filter { !dateInPast(value: $0.date) }, id: \.id) { event in
Thanks so much #dtm & #ChrisR!
I knew I was overthinking what I was trying to do. I've ended up with this.
var events = loadCSV(from: "Eventtest")
var events = events.filter { !dateInPast(value: $0.date) }
There are some other date eval's in scope for the view but that can be moved into the loadCSV function or dateInPast, tidies it up a bit too. Unfortunately I can't upvote since my account is new. Thanks so much though. Cheers!
Qooxdoo experts :
oTable.getPaneScroller(0).getHeader().addListener('click', function(e) { ..... }, this);
I can call some function, but what I really need is to get the column's label or index in which I'm clicking to use it as a parameter. I can't find the proper syntax for the child's label, still a newbie.
Not sure if it's exactly what you need but you may want to try this:
oTable.getPaneScroller(0).getHeader().addListener('click', function(e) {
var pageX = e.getDocumentLeft();
var col = oTable.getPaneScroller(0)._getColumnForPageX(pageX);
var label = oTable.getPaneScroller(0).getHeader().getHeaderWidgetAtColumn(col).getLabel();
alert(label);
});
This is certainly not the "cleanest" solution one could think of, but who cares if it serves your purpose ;-)
My combo uses remote query. When the user types something, the server returns matching results. However, when there are a lot of matching results, then the combo expands, loses focus and highlights the firts record returned by the server. The combo has these properties:
...
queryMode:'remote',
enableKeyEvents:true,
forceSelection:true,
...
The screen of what is going on is here:
So, as you can see, when the user typed the last character, the server returned records and for some (I think stupid) reason highlighted the first record. But what is more important there is no focus any longer and the user has to put cursor on the field again to continue typing. To solve this problem, I tried these events:
'blur':function(){
this.focus();
},
'keydown':function(){
this.focus();
},
'keypress':function(){
this.focus();
},
'keyup':function(){
this.focus();
},
But there is no effect. I also tried to use load event, but it also has no effect.
I had this issue too, for solve it use the afterQuery property in the combo.
Something like this:
afterQuery: function() {
combo.setRawValue(combo.lastQuery);
},
pd: I think this is a Bug, but i'm not sure about it...
I could solve the similar issue with focus be two actions:
Set "selectOnFocus: false"
Update doRawQuery.
doRawQuery: function() {
var me = this;
...
me.inputEl.focus();
}
If you have your overridden version (I believe you should to not change original plugin), you can do it this way to not duplicate the logic:
doRawQuery: function() {
var me = this;
me.callParent(arguments);
me.inputEl.focus();
}
xtype: 'combo',
...
listeners:{
// repair raw value after blur
blur:function() {
var val = this.getRawValue();
this.setRawValue.defer(1, this, [val]);
}
}
Look this example(thanks to Saki)
i have a situation here that i can't seem to figure out. Please if anybody knows how to resolve this i would love to hear suggestions.Thanks
I have a "global view" that is visible on a subnavbar in the app, that is a calendar, this calendar serves as a global calendar throughout the application, so almost all the views use the calendar view & model to set show data according to the date selected.
This calendar view/model should have some way to store in history each time the date is changed, this (i think) is done using a single URL or query string parameters each time the date is changed, something like
webapp/view1?date=20120301
and when the date is changed, so its the query string.
I would like to use query string parameters for this so i don't have to specify on each route the (/:date) optional parameter.
THE THING IS backbone stopped firing a route change or a history event when query strings are changed, they simply ignore query strings on the Backbone.History implementation, this is breaking all my implementation cause i can't track each time the querystring is changed, so the "back" button will not fire a change event and therefore i can't change the date on the model that would change the date on the calendar.
I know a simple solution to this would be just using "pretty URL" and adding that date parameter to each view, but im trying to avoid that.
Any suggestions?
Thanks in advance
UPDATE
I ended up using "pretty URLs" like the Backbone documentation suggests, cause using query strings would bring me a lot of trouble for tracking the URL change and history, also wouldn't work as expected when using hashchange instead of pushState.
So, my code ended up like this:
Attaching somewhere in your router, view, controller, something, to the "route" event of your router, to check the URI for the date and set this date to the calendar picker:
this.listenTo(myRouter, "route", this.routeChanged);
Then, this method would do something like:
checkURIdateParameter: function (route, arr) {
var found = false;
for (var i = 0; i < arr.length ; i++) {
if (arr && arr[i] && arr[i].indexOf("date=") != -1) {
if (app.models.dateControl) {
var dateFromParameter = new Date(arr[i].substring("date=".length).replace(/\$/g, ":"));
dateFromParameter = (isNaN(dateFromParameter.getTime())) ? app.models.dateControl.defaults.date : dateFromParameter;
app.models.dateControl.set("date", dateFromParameter);
found = true;
}
}
}
if (!found) app.models.dateControl.set("date", app.models.dateControl.defaults.date, {changeURI:false});
}
This serves as the function that will read params from the URI and reflect those changes on the dateControl.
There should be another method that will be the one in charge of updating the URI to a new one each time the date is changed (so that the params are in sync with the view) and the link can be copied and pasted with no problems.
Somewhere on your router, view, controller:
this.listenTo(app.models.dateControl, "change:date", this.updateURIdateParameter);
This is a method that is attached to a model that has the current date, this model is updated by the calendar picker (the UI control) or the method that was linked with the route event (routeChanged, look above).
This method should do something like this:
, updateURIdateParameter: function (a, b, c) {
if (c && c.changeURI == false) return; //this is in case i don't want to refresh the URI case the default date is set.
var currentFragment = Backbone.history.fragment;
var newFragment = "";
var dateEncoded = app.models.dateControl.get("date").toJSON().replace(/\:/g, "$");
newFragment = currentFragment.replace(/\/date=([^/]+)/, "") + "/date=" + dateEncoded;
if (newFragment != currentFragment) {
app.router.navigate(newFragment, false);
}
}
This method gets the currentDate selected from the corresponding model, parses it, then takes the URL from the Backbone.history.fragment, execs a nice regexp against it that will replace the old date parameter (if exists) and then appends the new encoded date.
Then navigates to this route in silent mode so that the method that checks the route is not called (this prevents annoying loops).
I hope this helps.
I would suggest using "Pretty URL".
FYI Page URL in the browser bar will blink in this example.
Somewhere inside your Backbone.Router:
this.route('*action', function() {
console.log('404');
});
this.route(/^(.*?)\?date=(\d+)$/, function(route, date) {
// same current route (with ?date)
var fragment = Backbone.history.fragment;
// navigate to main route (to create views etc.)
this.navigate(route, {trigger:true, replace:true});
// silent change hash
this.navigate(fragment);
});
this.route('any', function() {
// need wait for hash change
_.defer(function() {
console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/));
});
});
this.route('route', function() {
// need wait for hash change
_.defer(function() {
console.log('parse date here and do what you want', window.location.hash.match(/^(.*?)\?date=(\d+)$/));
});
});
In Sencha Touch, I often need to have an Ext.DataView panel that contains a small sub-set records or even a single record from the collection in the store.
For example I might have a Model for Car which has thousands of car records in it's app.stores.cars store but I want to show a smaller subset of these items (say; just sports cars) in my listOfSportsCars DataView while also showing the larger complete set of cars in my listOfCars DataView.
My first thought was to use multiple stores. So I'd have one main store for the big list of all cars, and a second store with a filter for my subset of sportscars. However, now updating a model from one store does not automatically update the record in the other store, so this defeats the purpose of using a DataView as the changes are not updated everywhere in the page when updating records.
My second attempt was to overwrite the collectData method on the DataView, which sounded exactly like what I was after:
var card = new Ext.DataView({
store: app.stores.cars,
collectData: function(records, startIndex){
// map over the records and collect just the ones we want
var r = [];
for( var i=0; i<records.length; i++ )
if( records[i].data.is_sports_car )
r.push( this.prepareData(records[i].data, 0, records[i]) );
return r;
},
tpl: new Ext.XTemplate([
'<tpl for=".">',
'<div class="car">{name}</div>',
'</tpl>'
]),
itemSelector: 'div.car'
});
A full example can be found here.
But, although it's documented that I can/should override this method, Sencha Touch really doesn't like it when you mess around with the length of the array returned by collectData so this was a dead-end.
How do others deal with displaying/updating multiple collections of the same records?
UPDATE There was a bug preventing collectData from working as expected. The bug has since been fixed in Sencha Touch 1.1.0.
As written in the comment:
I've used your democode with the last Sencha Touch release and opened all with Google Chrome. In the current version the error is fixed. (Version 1.1)
you could use Filters in order to get a subset of the data asociated to that store.
yourstore.filter('name', 'Joseph');
Also you should define 'root' as a function so it will always return an array. Readers in sencha touch asume you're always going to get an array as response, but it's not true if you are having a JSON with a single entry, try something like this:
root: function(data) {
if (data) {
if (data instanceof Array) {
return data;
} else {
return [data];
}
}
The full code for the store could be like this:
YourApp.ViewName = new Ext.data.Store({
model: 'YourApp.models.something',
proxy: {
type: 'scripttag',
url: 'http://somerandomurl/service/json',
extraParams: {
param1: 'hello'
},
reader: {
type: 'json',
root: function(data) {
if (data) {
if (data instanceof Array) {
return data;
} else {
return [data];
}
}
}
}
},
});
Hope it helps.
I use the "filter" features in the Store. Not modifying the DataView (I use a List).
Here's a snippet where I will fiter out Programs with a catagory that fit's a regex. (I have Programs with a catagory field)
MyApp.stores.Programs.filter(function(object) {
var regex = new RegExp(filterValue, 'i');
return object.data.category.search(regex) >= 0; // found match
});
You can clear the filter like this:
MyApp.stores.Programs.clearFilter(false);
This will update the DataView (I use a List) immediately (it's amazing).
So within your filter you could just filter out sports cars, or cars of a certain price, or whatever.
Hope that helps...
For my understanding of Sencha Touch this is not the best approach.
If it can be still good for performance you shoud use a second "slave" store, with inline data (http://docs.sencha.com/touch/1-1/#!/api/Ext.data.Store) that you can populate automatically from main store with subset of information you want to show when an event occours on the master store, i.e. load event.
If you want to deal with just one store a solution I can imagine is to use an xtemplate with "tpl if" tag in the dataview where you want to show just some information
http://docs.sencha.com/touch/1-1/#!/api/Ext. to write empty records. Maybe, also better solution, could be to use a custom filter function inside xtemplate, in order to put a css with visibility hidden on the items you don't want to see.