$tree.tree is not a function - javascript

I am generating a tree in plone using an add-on product called collective.virtualtreecategories . However, I keep getting a weird javascript error and the tree cannot be displayed.
On my browser's error console, I get the following:
$tree.tree is not a function
Here is the part of code that produces the error:
$tree.tree({
data: {
type: "json",
url: "##vtc-categories-tree.json",
async: false
},
lang: {
new_node: "New category"
},
rules: {
deletable: ["folder"],
renameable: ["folder"],
draggable: "none",
droppable: "none",
},
callback: {
beforechange: function(node, tree_obj) {
return before_change_node()
},
onselect: function(node, tree_obj) {
node_selected(node)
},
oncreate: function(node) {
jq(node).attr('rel', 'folder')
},
onrename: function(node, lang, tree_obj, rb) {
old_id = node.id // may be undefined (new node)
new_name = jq(node).children("a:visible").text();
// shared code. Server determines if creating/renaming by the old_name value
jq.ajax({
type: 'POST',
url: "vtc-category-added-renamed",
data: {
'category_path': selected_category(node),
'old_id': old_id,
'new_name': new_name
},
success: function(data) {
jq.jGrowl(data.msg, {
life: 1500
});
// set/change node id
if (data.result) {
node.id = data.new_id
}
},
dataType: 'json',
traditional: true
})
},
beforedelete: function(node, tree_obj) {
jq.ajax({
type: 'POST',
url: "vtc-category-removed",
data: {
'category_path': selected_category(node)
},
success: function(data) {
jq.jGrowl(data.msg, {
life: 3000
});
},
dataType: 'json',
traditional: true
});
return true;
}
}
});​
The complete code listing can be found HERE
Can someone help me fix this?
UPDATE:
I should perhaps add that, this was working before in a different setting. Now, I just recreated the project and thats when I got this error.

As far as I can tell from your code $tree isn't a function, its an element
on line 89 var $tree = jq('ul#VTCTree');
therefore I assume .tree() is a JQuery widget and isn't working as expected?
Just seen some of the comments and the updates. Have you checked the path/file inclusion of the tree plugin/widget?

On my browser's error console, I get the following:
if your browser is Internet Explorer, the extra comma that you have here
droppable: "none",
is a widely known problem.
Not a problem for Firefox, but will give unexpected results, like 3 elements in the following array. but length = 4
myArr = [1,2,3,,]
also, check this https://stackoverflow.com/a/5139232/982924

I had the same issue, even though I had jquery loaded and the jquery.filetree.min plugin loaded. I was missing the jquery UI js which is also required.

Related

Select2: Creating tags with ajax

I am using the select2 library.
My select2 element can search the database for each tag via the ajax and that works fine.
My issue is, I want the user to also be able to create a new tag. Looking at their documentation I should use the createTag option; however, this fires as soon as I click into the element and on each key press.
Can anyone offer any guidance on how I can achieve my goal?
here is my code thus far
I am using ajax top search for tags but I would also like to create new tags to the database. I have tried doing this via createTag but this seems to be firing as soon as I click in the HTML element and on each key press.
Here is my code:
$('.tags').select2({
tags: true,
placeholder: "These tags will apply to all lines",
tokenSeparators: [','],
ajax: {
url: '/api/tags/find',
dataType: 'json',
data: function (params) {
return {
q: $.trim(params.term)
};
},
processResults: function (data) {
return {
results: data
}
},
cache: true,
},
createTag: function(params) {
alert('tag created') // This is were I would put my ajax POST.
}
});
After reading the documentation again, I can see I should have been using the events https://select2.org/programmatic-control/events
I used the createTag option to assign newTag: true to newly created tags and used the select2:selected event which checked if a new tag had been selected and, if it was, sent an ajax request to the server to create that tag.
$('.tags').select2({
tags: true,
placeholder: "These tags will apply to all lines",
minimumInputLength: 3,
tokenSeparators: [','],
ajax: {
url: '/api/tags/find',
dataType: 'json',
data: function (params) {
return {
q: $.trim(params.term)
};
},
processResults: function (data) {
return {
results: data
}
},
// cache: true,
},
createTag: function(params) {
let term = $.trim(params.term);
if (term.length < 3)
{
return null
}
return {
id: term,
text: term,
newTag: true,
}
},
});
$('.tags').on('select2:select', function (e) {
let tag = e.params.data;
if (tag.newTag === true)
{
axios.post('/api/newtag', {
name: tag.text,
type: 'default',
})
}
});

select2 programmatically without knowing results in advance

I am trying to write a test for a Javascript select2 control and I would like to automatically select the first item. Since it's using ajax I do not know what the first item is. All the examples I have seen create <option> however they assume knowledge of the value. How can I select the first item without knowledge? (Note this example only runs the ajax command after 3 items are entered).
var $selector = $("#foo");
$selector.show().select2({
allowClear: true,
placeholder: "--------",
minimumInputLength: 3,
ajax: {
url: "...",
type: 'GET',
dataType: 'json',
delay: 250,
data: function(term, page) {
return {
number__icontains: term
};
},
results: function(data) {
return {
results: $.map(data.objects, function(option) {
return {
'id': option.id,
'text': option.desc
};
})
};
},
cache: false
},
initSelection: function(element, callback) {
...
}
});

Typeahead format source

I'm trying to use Typeahead. I'm using AJAX to get my source :
$(document).ready(function() {
$('input.typeahead').typeahead(
{
hint: true,
highlight: true,
minLength: 1
},
{
source: function(query, process) {
jQuery.ajax({
url: 'suggestion.php',
dataType: "json",
data: {
type: 'abc'
},
success: function(data) {
suggestion = [];
for(var i in data)
{
suggestion.push(data[i]);
}
console.log(data);
}
});
process(suggestion);
return suggestion;
}
});
});
But there is the result :
But when I see the logs :
I've an array with strings !
There the console message :
I can see an error appear at the first char typed but only the first time. All the time, I've "undefined" x 5 proposed.
What's the matter ? I guess the format, but I've tried mainly things from stacks, without results (only errors). My Php code return ("echo") an json_encode($array) ! It's my first time using Ajax and Typeahead..
Sorry for my english.
I think that suggestion must be this kind of array :
[{ "value": "CBOXXX" }, { "value": "CBAXXX" }]

JQuery popup not working after continuous call

I'm using MVC 4 for my project and im trying to edit or display my data on popup.
When I call my open popup code 6 or 7 times I take javascript errors.
my controller is
public ActionResult OpenEditForm(string objectParam, string formStatus)
{
BranchNotesDetailViewModel viewModel = new BranchNotesDetailViewModel();
//..................
return PartialView("Edit", viewModel);
}
and my javascript code is
myDialog = $("<div> </div>");
function CreateDialog(name) {
myDialog.dialog({
autoOpen: false,
title: name,
resizable: false,
position: 'center',
stack: true,
height: 'auto',
width: 'auto',
modal: true,
close: function (event, ui) {
// remove div with all data and events
myDialog.remove();
//myDialog.dialog('close')
}
});
}
$('#brancNotesList .grid-row').click(function () {
var json = $(this).children('td:eq(1)').text().trim();
$.ajax({
contentType: 'application/html',
url: '#Url.Action("OpenEditForm", "BranchNotes")',
dataType: 'html',
type: 'GET',
data: {
objectParam: json,
formStatus: "1"
}
}).done(function (result) {
CreateDialog('Detail');
myDialog.html(result).dialog('open');
});
});
$(function () {
$(document).ajaxComplete(function (event, request, settings) {
//re-parse the DOM after Ajax to enable client validation for any new form fields that have it enabled
$.validator.unobtrusive.parse(document);
});
});
function openFormCreate() {
$.ajax({
contentType: 'application/html',
url: '#Url.Action("OpenEditForm", "BranchNotes")',
dataType: 'html',
type: 'GET',
data: {
formStatus: '2'
}
}).done(function (result) {
CreateDialog('Detail');
myDialog.html(result).dialog().dialog('open');
});
}
When i open dialogs one or two times it works but after fifth or sixth time it crashes with exception
JavaScript runtime error: Could not complete the operation due to error 80020101
I tried to find a memory problem or something after ajax call but i cant find where or what. Is there any way to handle that? I read about that problem some forums they say comments fields cause that but it not works for me.
I found my error. I have two layouts, one for main page one for edit page and i noticed some Jquery script files rendered in both pages. I cleaned the edit layout from jquery scripts then everything works fine.

Cannot refresh TreeStore in EXTjs

I'm trying to create a web-page in EXTJs that has two major components:
A Form (Ext.form.Panel)
A Panel (Ext.tree.Panel)
The form is supposed to get some values, which should populate tree in second panel. In the button handler of the first panel I have access to the updated JSON object, but I cannot figure out a way to refresh the TreeStore that will update the display in tree.Panel.
This is what I have so far :
Ext.define('TreeServiceData',{
config:{
data : ''
},print : function() {
console.log("Printing data: ")
console.log(this.data.children[0])
}
});
var dataObject = Ext.create('TreeServiceData');
dataObject.setData({'expanded':false,'children':[{'text':'Master','expanded':true,'leaf':false,'children':[{'text':'Child 1','expanded':true,'leaf':false,'children':[{'text':'Child 2','expanded':true,'leaf':false,'children':[{'text':'Child 3','expanded':false,'leaf':false}]}]}]}]})
Ext.define('TreeStoreData',{
extend: 'Ext.data.TreeStore',
model: 'TaskModel',
autoLoad: true,
autoSync: true,
proxy: {
type:'memory',
reader: {
type:'json'
}
},
root:dataObject.getData()
});
var treeStore = Ext.create('TreeStoreData');
Now I'm trying to update and display the value of this treestore on a button call which looks like this :
buttons:[
{
text:'Get CCP/Product',
handler:function (btn, evt) {
dataObject.print();
treeStore.removeAll();
dataObject.setData({'expanded':false,'children':[{'text':'Master11','expanded':true,'leaf':false,'children':[{'text':'Child 12','expanded':true,'leaf':false,'children':[{'text':'Child 23','expanded':true,'leaf':false,'children':[{'text':'Child 34','expanded':false,'leaf':false}]}]}]}]})
dataObject.print();
}
}
]
But on this button handler I'm always getting a "Uncaught TypeError: Cannot call method 'indexOf' of undefined " on treeStore.removeAll() method, where treestore is clearly defined in this context.
Question 1) What is the correct way to refresh a TreeStore ?
Answer 1)
Instead of:
treeStore.removeAll();
dataObject.setData( ... );
You should do:
dataObject.setData( ... ); // This won't affect the store
treeStore.setRootNode(dataObject.getData()); // Actually update the store
Note that changing dataObject's data won't affect the store automatically like you seem to think...
this code works for me (ExtJS 4.2.1)
Total tree panel nodes refresh example:
var responseDictObjects = $.ajax({
data: { Id: this.idDictionary },
dataType: "json",
type: "POST",
cache: false,
url: 'http://' + config.domain + '/' + 'api/Dictionaries/GetDictTreeData',
async: false
}).responseText;
responseDictObjects = jQuery.parseJSON(responseDictObjects);
while (this.storeDict.getRootNode().firstChild) {
this.storeDict.getRootNode().removeChild(this.storeDict.getRootNode().firstChild);
}
this.storeDict.getRootNode().appendChild(responseDictObjects.Data);
Replace this.storeDict with your store reference.
In my case:
JSON.stringify(responseDictObjects.Data)
returns
"[{"id":8,"text":"kkk","leaf":false,"expanded":true,"children":null},{"id":17,"text":"ttttt","leaf":false,"expanded":true,"children":null},{"id":22,"text":"gggg","leaf":false,"expanded":true,"children":null},{"id":23,"text":"qqq","leaf":false,"expanded":true,"children":null},{"id":24,"text":"fff","leaf":false,"expanded":true,"children":null},{"id":27,"text":"fff","leaf":false,"expanded":true,"children":null},{"id":28,"text":"ggggggggggggggggggg","leaf":false,"expanded":true,"children":null},{"id":31,"text":"ttttttttttt666666666","leaf":false,"expanded":true,"children":null},{"id":32,"text":"ffffffffffffffffffff","leaf":false,"expanded":true,"children":null},{"id":33,"text":"kkkkkkkkkkkkk","leaf":false,"expanded":true,"children":null},{"id":35,"text":"7777777777","leaf":false,"expanded":true,"children":null},{"id":36,"text":"999999999999","leaf":false,"expanded":true,"children":null},{"id":37,"text":"iii","leaf":false,"expanded":true,"children":null}]"
I found another bug with TreePanel, previosly removed nodes appears after executing appendChild. So i started to use jquery tree plugin (dynatree). All you need is to create empty panel. And after render a panel, embed tree, in my case:
Create empty panel:
that.treePanel = Ext.create('Ext.panel.Panel', {
title: 'Records',
width: 350,
height: 400
});
After rendering panel you can refresh nodes whenever you want:
var that = this;
var responseDictObjects = $.ajax({
data: { Id: this.idDictionary },
dataType: "json",
type: "POST",
cache: false,
url: 'http://' + config.domain + '/' + 'api/Dictionaries/GetDictTreeData',
async: false
}).responseText;
responseDictObjects = jQuery.parseJSON(responseDictObjects);
var el = this.treePanel.getId();
if (this.treeDict == null) {
this.treeDict = $('#' + el).dynatree({
onActivate: function (node) {
that.treeDict.lastSelectedId = node.data.index;
},
children: []
});
}
this.treeDict.dynatree("getRoot").removeChildren(true);
this.treeDict.dynatree("getRoot").addChild(responseDictObjects.Data);

Categories

Resources