Ext JS 4 TextArea - how to set the insertion point? - extjs

Is it possible / how do you set the insertion point for an ExtJS 4 Textarea?
I want to insert some text (which I have working), then I want to set the insertion point at a specific length from the beginning of the field:
I am getting the current contents, inserting some text in front. Now I want to move the insertion point to right after the "-":
//field = my ExtJS text area
var ins = "some text I inserted - \r";
var value = ins + field.getValue();
field.setValue(value);

There's no out-of-the-box method that allows this.
Javascript security doesn't allow you to fire a keypress event, so you can't focus the textarea and then fire the "CTRL+END" key combo, or even the "END" key, for example.
I played around with the focus() and select() methods on the <textarea> element, with no success being able to get the cursor to appear at the end.
So my answer is that you shouldn't attempt this until it's officially supported, because even if you get a hack to work, it might only function properly in some browsers.

qaScriptForm is a normal form
Script is a normal TextArea
var insertIndex = qaScriptForm.Script.selectionStart;
var value = qaScriptForm.Script.value;
value=value.substr(0,insertIndex)+ " DATEADD(DAY,-7,GETDATE()) "+value.substr(insertIndex);
qaScriptForm.Script.value=value;

Related

Codename One - Correct use of the Picker

I'm trying to do a clear question about the use of the Picker, because my previous one in not enough clear: Codename One - addActionListener of a Picker
The purpose of the Picker is to select one element from a set, such as a string of a set of strings, is it right? So, I want to give the user the opportunity to select a string from a set of strings, each of one corresponds to a language.
The problem is that the use of an ActionListener added to the Picker is not correct for this purpose, because it's triggered by both "Ok" and "Cancel" buttons.
I need to execute some code (to change the language) only and only if the user press "Ok", because executing that code if the user press "Cancel" should be considered an unexpected behavior and a bug (from the point of view of the user).
So my question is how to use correctly the Picker in this use case.
From the CN1 documentation, one way to do this would be :
String [] list = {"one" , "two" , "three"};
Picker picker = new Picker ();
picker.setType(Display.PICKER_TYPE_STRINGS);
picker.setStrings(list);
picker.setSelectedString("test");
picker.addActionListener(l -> System.out.println(picker.getSelectedString()));
Oddly, and as Francesco has pointed out in a prior moment, when you run the application IN THE SIMULATOR, and press the Cancel-Button inside the picker, it prints out the selected string. Same when you press the OK-Button. (Is this intended?)
On installed devices, the results seem to be mixed, as to on some devices the cancel operation does not incur in any action.
I had to do this to avoid triggering another listener on the string (I was using a Property with a change listener) if Cancel was pressed, and I did this by checking the current picker string against the previous selected string to see if it changed. I only updated the field or local variable (Property in my case) if the value changed. Modifying the previous answer's code:
...
private String currentSelection;
...
String [] list = {"one" , "two" , "three"};
Picker picker = new Picker ();
picker.setType(Display.PICKER_TYPE_STRINGS);
picker.setStrings(list);
picker.setSelectedString("test");
picker.addActionListener(l -> {
if (!picker.getSelectedString.equals(currentSelection) {
currentSelection = picker.getSelectedString;
System.out.println(currentSelection);
}
});

Extjs 6.0 - ItemSelector: how to programmatically focus/highlight an element?

I have a ItemSelector component inside a Window. I have implemented a search functionality that dynamically finds the matching entry based on user's keyboard input.
Now I just want to highlight/focus such item inside the ItemSelector.
I'm looking for something like:
// when the search returned a result and got the related index in the store
function onSearchPerformed(index) {
var cmp = this;
cmp.itemSelector.setSelected(index); // here I'd be highlighting the entry
}
Example
Imagine a simple ItemSelector like this one taken from the web.
User types 'Delaw' and my search function detects that there is an entry with name Delaware and it's at position 3 in the store.
All I want to do is to programmatically highlight the row/entry 'Delaware' just as if you clicked on it.
This ux component uses a boundList, or better 2 of them.
A from and a toList.
You need to get a reference to the right boundlist.
More on that you will find here: http://docs.sencha.com/extjs/6.0.1/classic/src/ItemSelector.js.html
Basically you can do something like this:
https://fiddle.sencha.com/#view/editor&fiddle/24ec
afterrender: function(cmp){
Ext.defer(function(){
var boundlist = cmp.down('boundlist');
item = boundlist.all.item(1);
boundlist.highlightItem(item);
},300);
}
After you have a ref to the correct boundlist, you can simply highlight the item using:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-highlightItem
Take care that you may need to call following function before:
http://docs.sencha.com/extjs/6.0.1/classic/Ext.view.BoundList.html#method-clearHighlight
To find the correct item should't be too hard.
There are two ways to solve the issue
One is by following #devbnz answer, marked as correct. This is preferable, if you just want to graphically highlight the entry without triggering any event.
However, by hovering on other entries, you will lose the highlight on your current entry.
The second one, as suggested by #guilherme-lopes in the comments, may be preferable in cases in which you want the selection to act as if you actually clicked on an entry, which will trigger the selectionchange event and similar...
Depending on the situation, I ended up using either.

Enable/disable buffered rendering at runtime

I have a grid that is using a buffered renderer.
For printing, I copy the grid DOM into a new window, and send it to printer. For this to work, the DOM has to be rendered completely, but with a buffered renderer, it isn't.
If I have to, I will disable buffered renderer completely, but since only a few users use the printing feature, I would prefer not to.
Is there a possibility to switch bufferedRenderer off temporarily before fetching the DOM, and to switch it back on afterwards?
I am not sure how it helps you , but I have done this similar sort by increasing the view size at runtime.
Lets suppose you have buffered renderer with this config:
ptype : 'bufferedrenderer',
trailingBufferZone : 20,
leadingBufferZone : 50
So dynamically , you can set the viewsize at runtime by getting the reference of plugin and using setViewSize(newSize) method.
eg:
var dd=Ext.ComponentQuery.query("#ExampleTreePanel")[0];
var bufferedRendererPlugin = dd.plugins[0];
bufferedRendererPlugin.setViewSize(100000);
This large size is just a big number we can assume so that the DOM will be completely loaded and you can give it to print.Its a workaround. Again you can resize the view by setting it to small number.
bufferedRendererPlugin.setViewSize(115);
I have adapted the good answer by Saloo to work around some things that are different between ExtJS 6 and ExtJS 4:
// Set view size to match store content:
this.bufferedRenderer.setViewSize(this.getStore().getCount());
// Refresh view, so that everything is rendered:
this.bufferedRenderer.refreshView(0);
// refreshView does not revert the node container's "translate" setting after the viewSize was changed to be equal or greater than the store count, so we have to enforce it manually:
this.getView().getEl().down(this.getView().getNodeContainerSelector()).translate(0,0,0);

ExtJS 4.2 Accessing Array Elements returned from store

I am unable to access the store elements returned from my store. When I console.log(me.proxy.read(operation)) and expand/navigate in the console I see all of my elements. There are 1000 rows. I am using the same store for a grid and have the pageSize set to 50. Even though I can see 1000 rows when i do a console.log(me.proxy.read(operation.resultSet.records[51])) i get an undefined message. So, it appears that for some reason the number of elements I can access is only 50 as that is what my pageSize is set to.
Long story short, I am using the same store for two scenarios. I want to have paging in my grid that will show 50 rows on each page. However, I want to loop through the entire store and load an array of all 1000 rows. The reason why I want an array of all 1000 is becasue I am going to use a date field in the rows to populate my date picker from an array. I am going to disable the dates in my grid and have the datepicker display only the dates that are in my grid.
I tried to include a screen shot but I am not allowed because i am only a 3 on the reputation system.
var operation = new Ext.data.Operation({action: 'read', start: 0, limit: 1000});
var proxy = new Ext.data.proxy.Ajax({ url: 'http://192.168.0.103/testit/dao_2.cfc?method=getContent'});
me.proxy.read(operation);
console.log(me.proxy.read(operation));
HERE IS UPDATED CODE:
I have this in my controller:
ondatesStoreLoad: function(me,records,success)
{
var s = this.getStore('dates');
for (i = 0; i < s.getCount(); i++) {
MESSAGE_ID = s.getAt(i).get('message_id');
RECIP_EMAIL = s.getAt(i).get('recip_email');
UNIX_TIME_STAMP = s.getAt(i).get('unix_time_stamp')
console.log(i,MESSAGE_ID, RECIP_EMAIL, UNIX_TIME_STAMP);
};}
This puts out all 1,000 of my records to the console but I am not sure how to put them in an array that I can use in my datepicker component. When ever i try to get the store in the datepicker it is always undefined. I suppose it is becasue the store hasn't loaded yet so there is nothing there. Not sure how to get around that. Perhaps a callback handler?
HERE IS ANOTHER UPDATE:
I added a callback in my store.load:
var store = Ext.getStore('dates');
store.load({callback: function(){
console.log(store.data.items[999].data.recip_email);
console.log(store.data.items[999].data.unix_time_stamp);}
})
That took forever to figure out but now I can access all my records and have a smaller problem to work on. At the moment i just have one element hardcoded to do a quick test.
Where do I need to put the code to get it into my date picker disableDates config? I need to put the dates into an array but for quick testing I used minDate: just to see if i could see something work but it shows up as undefined. Now i have the code in a beforrender listener but that seemingly needs to be in some other place or maybe some handler for my date picker....? is there an onload for the datepicker or something i shoudl use for this??
Why not just change the datepicker directly from that ondatesStoreLoad function? Before the loop, disable all dates in the datepicker. Then during the loop, instead of the console.log call, enable the date that was found in that record.
In theory, that should work. However, looking at the docs for Ext, I don't see a way to disable all dates, or to enable a date. You can only set which dates are disabled. But the general idea of updating the datepicker in that ondatesStoreLoad call is still what you should do.
You might need to extend the datepicker class, and add some custom methods to it to be able to enable a specific day.

angularjs mask override characters

I have a mask setup on a date field using the angular-ui masks module like so:
<input type="text"
id="date"
ng-model="transaction.date"
ui-mask="99/99/9999" />
If I have 30/05/2013 in the field and want to change that to 10/05/2013 by simply putting a '1' at the start it pushes all the characters over so it becomes 13/00/5201.
Is there way to force ui-mask to overwrite the character insted of inserting it? (This would save someone from hitting 'delete' then the character.
Example: http://jsfiddle.net/5NbD7/
If you type '30' at the front of my example you will end up with 30/01/0120 I would rather it override the characters and produce 30/01/2010
I don't know it there is an easier way, but you try the following :
You will need to download mask.js, unminified, from source and link it in your html, if you haven't already done so.
https://rawgithub.com/angular-ui/ui-utils/master/modules/mask/mask.js
Then you will need to modify the source code of mask.js like this (seach for the comment //Update Values and put this code below) :
...
// Update values
if (oldValueUnmasked !== "" && oldValueUnmasked!==valUnmasked && !isDeletion) {
var charIndex = maskCaretMap.indexOf(caretPos);
if (charIndex === -1) {
charIndex = maskCaretMap.indexOf(caretPos+1);
}
valUnmasked=valUnmasked.substr(0,charIndex).concat(oldValueUnmasked.substr(charIndex,valUnmasked.length));
}
...
Now, before updating the value, mask will do a concatenation of the characters in the old value and those in the new value, depending on the position of the cursor (caret).
It's by no means an ironproof solution, but it should give you an idea of where to look if you want to customise the input more or check that this change does not break anything else.
Fiddle:
http://jsfiddle.net/CALvj/
I think that the way typed characters are inserted or overwrite input text depends on the keyboard current insert mode. Users can simply change the default pressing the Ins key.
The only way to change it from code would be forcing an Ins key press but this isn't allowed in Javascript.

Resources