Search a Sencha TreePicker - javascript

I am using TreePicker from ExtJS 6.0.2. I would like to know how can I perform a search or query on the Picker data similar to this example - Fiddle. It has this property which is an built-in feature from combo-box:
queryMode: 'local'
I have made the TextField editable and I want to know if there is any inbuilt way to perform a search or do I have to write code to do it manually. For the manual way I tried to capture the change event of the TextField by writing the code for it in the config property of the TreePicker but failed to get the event to be fired. What am I missing here, please guide.

it seems this component has a very simple implementation and doesn't support any search functionality.
You could start to implement your need studying the Ext.form.field.ComboBox source code in order to "copy" only the behaviours you want.
For example you will see there's a picker's method to override to handle the change event. A very very simple "search on change" extension can be added with the following override:
...
onFieldMutation: function(e) {
var me = this,
store = me.getStore(),
rawValue = me.inputEl.dom.value;
store.filter('text', rawValue);
},
...
Fiddle

Related

Custom Unobtrusive Validation Method Not Firing as Per Documentation

I've been attempting to implement a ASP.NET MVC custom validation method. Tutorials I've used such as codeproject explain that you add data-val-customname to the element. Then jQuery.validate.unobtrusive.js then uses the third segment of the attribute
data-val-<customname>
as the name of the rule, as shown below.
$.validator.addMethod('customname', function(value, element, param) {
//... return true or false
});
However I just can't get the customname method to fire. By playing around I have been able to get the below code to work, but according to all the sources I've read Unobtrusive validation should not work like this.
$.validator.addMethod('data-val-customname', function(value, element, param) {
//... return true or false
});
I've posted an example of both methods
jsfiddle example
Any help would be much appreciated
I've updated my question hopefully to make clearer.
I have finally found got there in the end, but still feels like too much hard work and therefore I've probably got something wrong. Initial I was scuppered by a bug in Chrome Canary 62 which refused to allow the adding of a custom method.
My next issue was having to load jQuery, jQuery.validate and jQuery.validate.unobtrusive in the markup and then isolate javascript implementation in a ES6 class. I didn't want to add my adaptors before $().ready() because of my class structure and loading of the app file independent of jQuery. So I had to force $.validator.unobtrusive.parse(document);.
Despite this I was still having issues and finally debugged the source code and found that an existing validator information that is attached to the form was not merging with the updated parsed rules, and essentially ignoring any new adaptors added.
My final work around and admit feels like I've done too much, was to destroy the initial validation information before my forced re-parse.
Here is the working jsfiddle demo
Here is some simplified code
onJQueryReady() {
let formValidator = $.data(document.querySelector('form'), "validator" );
formValidator.destroy();
$.validator.unobtrusive.adapters.add("telephone", [], function (options) {
options.rules['telephone'] = {};
options.messages['telephone'] = options.message;
});
$.validator.unobtrusive.parse(document);
$.validator.addMethod("telephone", this.handleValidateTelephoneNumber);
}

Validate function works on ValidationTextBox but not on FilteringSelect. Why?

I'm having a rather strange behaviour and don't know if it's because something I'm not doing right.
I trying to customize a Dojo FilteringSelect in my application to show invalid messages at my will. Looking at the API, I found a way to do it. This way works fine for ValidationTextBox.
Code to switch validation state:
var originalValidator = textBox.validator;
textBox.validator = function() {return false;}
textBox.validate();
textBox.validator = originalValidator;
Here's a fiddle so you can take a look:
http://jsfiddle.net/phusick/HGBnq/
If I change the ValidationTextBox to a FilteringSelect, it should work the same. But for some reason, it doesn't!
Here's the fiddle:
http://jsfiddle.net/nachoargentina/HGBnq/421/
Any suggestions are greatly appreciated!
dijit/form/FilteringSelect does indeed inherit from dijit/form/ValidationTextBox, but it overrides isValid (source). isValid is what calls the validator function in ValidationTexBox.
You could compose your own FilteringSelect that uses the same method that ValidationTextBox uses for isValid, or whatever you wanted or needed to use.

How to access ZK components from JavaScript

I want to set value of a zk datebox from javascript. Actually I can set the value but when I want to access its value, it is throwing a null pointer exception. More generally, some abilities of the zk components can be manupulated but others not. For example I can fire a button onclick event but I can not set an attribute of that button by javascript.
For example these two work :
zk.Widget.$('$startDateProxy').setValue(start); zk.Widget.$('$addEventBtn').fire('onClick');
But these two not:
zk.Widget.$('$startDateProxy').setAttribute("startDate",start) -> cutting the operation
alert(startDateProxy.getValue().toString()) -> null pointer
Thanks
PS: I am trying to use FULLCALENDAR (arshaw.com/fullcalendar)
Thank you for your answer. startDateProxy component is Datebox, not Calendar. Sorry for missing information. I solved the problem by using AuService. I defined a hidden button. Fired its onClick with the parameters. Sample usage:
Client Side:
zk.Widget.$('$eventBtn').fire('onClick',{start : start ,end : end});
Server Side:
public void service(AuRequest request, boolean everError) {
if (Events.ON_CLICK.equals(request.getCommand())) {
Map data = request.getData(); // can be read start,end parameters from here
//dosomething here
}
Try it instead
alert(this.$f('addEventBtn').getLabel());
The Class Calendar does not have a setAttribute method (see the docs).

query on jquery autocomplete module

I am using the Jquery based autocomplete module .I have a small doubt in its functionality. My autocomplete data is available in a local JavaScript variable. The autocomplete works fine, but whenever I update this local javascript variable it still uses the old data. Does this module cache the data? How can we go about fixing this.
The jQuery UI autocomplete does not have caching built in however it does make an internal copy of the source for the lookup values. In order to update this internal source you need to call the setter on the source parameter like so:
var source = [
"dog",
"cat"
];
var myAutocomplete = $("#myid").autocomplete({
source: availableTags
});
//Add new items after autocomplete init
source.push("mouse");
//Update the autocomplete with the modified source
myAutocomplete.autocomplete("option", "source", source);
Here is a jsfiddle with it working:
http://jsfiddle.net/enXYS/
Your browser is probably caching the JS file. Ctrl f5 to force clean the browsers cache.
Try smth like: $('input#necessary_input').flushCache();.
Updated (according to the comments below):
Ok. What about simple recreating of autocomplete (firstly remove it, then create with autocomplete function and new data)?

Event handling in Dojo

Taking Jeff Atwood's advice, I decided to use a JavaScript library for the very basic to-do list application I'm writing. I picked the Dojo toolkit, version 1.1.1. At first, all was fine: the drag-and-drop code I wrote worked first time, you can drag tasks on-screen to change their order of precedence, and each drag-and-drop operation calls an event handler that sends an AJAX call to the server to let it know that order has been changed.
Then I went to add in the email tracking functionality. Standard stuff: new incoming emails have a unique ID number attached to their subject line, all subsequent emails about that problem can be tracked by simply leaving that ID number in the subject when you reply. So, we have a list of open tasks, each with their own ID number, and each of those tasks has a time-ordered list of associated emails. I wanted the text of those emails to be available to the user as they were looking at their list of tasks, so I made each task box a Dijit "Tree" control - top level contains the task description, branches contain email dates, and a single "leaf" off of each of those branches contains the email text.
First problem: I wanted the tree view to be fully-collapsed by default. After searching Google quite extensively, I found a number of solutions, all of which seemed to be valid for previous versions of Dojo but not the one I was using. I eventually figured out that the best solution would seem to be to have a event handler called when the Tree control had loaded that simply collapsed each branch/leaf. Unfortunately, even though the Tree control had been instantiated and its "startup" event handler called, the branches and leaves still hadn't loaded (the data was still being loaded via an AJAX call). So, I modified the system so that all email text and Tree structure is added server-side. This means the whole fully-populated Tree control is available when its startup event handler is called.
So, the startup event handler fully collapses the tree. Next, I couldn't find a "proper" way to have nice formatted text for the email leaves. I can put the email text in the leaf just fine, but any HTML gets escaped out and shows up in the web page. Cue more rummaging around Dojo's documentation (tends to be out of date, with code and examples for pre-1.0 versions) and Google. I eventually came up with the solution of getting JavaScript to go and read the SPAN element that's inside each leaf node and un-escape the escaped HTML code in it's innerHTML. I figured I'd put code to do this in with the fully-collapse-the-tree code, in the Tree control's startup event handler.
However... it turns out that the SPAN element isn't actually created until the user clicks on the expando (the little "+" symbol in a tree view you click to expand a node). Okay, fair enough - I'll add the re-formatting code to the onExpand() event handler, or whatever it's called. Which doesn't seem to exist. I've searched to documentation, I've searched Google... I'm quite possibly mis-understanding Dojo's "publish/subscribe" event handling system, but I think that mainly because there doesn't seem to be any comprehensive documentation for it anywhere (like, where do I find out what events I can subscribe to?).
So, in the end, the best solution I can come up with is to add an onClick event handler (not a "Dojo" event, but a plain JavaScript event that Dojo knows nothing about) to the expando node of each Tree branch that re-formats the HTML inside the SPAN element of each leaf. Except... when that is called, the SPAN element still doesn't exist (sometimes - other times it's been cached, just to further confuse you). Therefore, I have the event handler set up a timer that periodically calls a function that checks to see if the relevant SPAN element has turned up yet before then re-formatting it.
// An event handler called whenever a "email title" tree node is expanded.
function formatTreeNode(nodeID) {
if (dijit.byId(nodeID).getChildren().length != 0) {
clearInterval(nodeUpdateIntervalID);
messageBody = dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML
if (messageBody.indexOf("<b>Message text:</b>") == -1) {
messageBody = messageBody.replace(/>/g, ">");
messageBody = messageBody.replace(/</g, "<");
messageBody = messageBody.replace(/&/g, "&");
dijit.byId(nodeID).getChildren()[0].labelNode.innerHTML = "<b>Message text:</b><div style=\"font-family:courier\">"+messageBody+"</div>";
}
}
}
// An event handler called when a tree node has been set up - we changed the default fully-expanded to fully-collapsed.
function setupTree(theTree) {
dijit.byId("tree-"+theTree).rootNode.collapse();
messageNode = dijit.byId("tree-"+theTree).rootNode.getChildren();
for (pl = 0; pl < messageNode.length; pl++) {
messageNode[pl].collapse();
messageNode[pl].expandoNode.onclick = eval("nodeUpdateIntervalID = setInterval(\"formatTreeNode('"+messageNode[pl].id+"')\",200); formatTreeNode('"+messageNode[pl].id+"');");
}
}
The above has the feel of a truly horrible hack, and I feel sure I must have taken a wrong turn somewhere early on in my thought process. Can someone please tell me:
The correct way to go about putting nicely-formatted text inside a Dojo/Dijit Tree control.
The correct way to handle Dojo events, like where I can figure out what events are available for me to subscribe to.
A better JavaScript library to use (can I do what I want to with JQuery and avoid the all-around-the-houses approach seen above?).
PS: If you're naming a software project, give thought to its name's uniqueness in Google - I'm sure searching for "Dojo" documentation in Google would be easier without all the martial arts results getting in the way.
PPS: Firefox spellchecker knows how to spell "Atwood", correcting me when I put two 'T's instead of one. Is Jeff just that famous now?
I assume that you followed the dijit.Tree and dojo.data in Dojo 1.1 tutorial which directed you to pass the data to the tree control using a data store. That had me banging my head of a brick wall for a while.
Its not really a great approach and the alternative is not really well documented. You need to create a use model instead. I have included an example below of a tree model that I created for displaying the structure of an LDAP directory.
You will find the default implementation of the model in your dojo distribution at ./dijit/_tree/model.js. The comments should help you understand the functions supported by the model.
The IDirectoryService class the code below are stubs for server-side Java POJOs generated by Direct Web Remoting (DWR). I highly recommend DWR if you going to be doing a lot of client-server interaction.
dojo.declare("LDAPDirectoryTreeModel", [ dijit.tree.model ], {
getRoot : function(onItem) {
IDirectoryService.getRoots( function(roots) {
onItem(roots[0])
});
},
mayHaveChildren : function(item) {
return true;
},
getChildren : function(parentItem, onComplete) {
IDirectoryService.getChildrenImpl(parentItem, onComplete);
},
getIdentity : function(item) {
return item.dn;
},
getLabel : function(item) {
return item.rdn;
}
});
And here is an extract from the my JSP page where I created the model and used it to populate the tree control.
<div
dojoType="LDAPDirectoryTreeModel"
jsid="treeModel"
id="treeModel">
</div>
<div
jsid="tree"
id="tree"
dojoType="dijit.Tree" model="treeModel"
labelAttr="name"
label="${directory.host}:${directory.port}">
</div>

Categories

Resources