Dynatree init from external data not working - treeview

First time on Stack Overflow :-). I have been using the Leo Outliner mainly to organize my task and writings and works pretty well to let me clarify my mind on complex subjects, but I cant not share my clarities easily with others because they don't use Leo. I have made a small exportation script from Leo to Dynatree just as a test and it works pretty well, so I thought that is was time create a web outliner, using web2py + dynatree. The problem is that dynatree works only for static data that is inside the script, but trying to use code like this:
<script type="text/javascript">
$(function(){
$("#tree").dynatree({
// In real life we would call a URL on the server like this:
// initAjax: {
// url: "/getTopLevelNodesAsJson",
// data: { mode: "funnyMode" }
// },
// .. but here we use a local file instead:
initAjax: {
url: "sample-data1.json"
data: { mode: "all" }
},
onActivate: function(node) {
$("#echoActive").text(node.data.title);
},
onDeactivate: function(node) {
$("#echoActive").text("-");
}
});
});
The part that loads sample-data1.json is not working, no matter that the file exists and it has the proper permissions. I have searched here:
How to Load Dynatree via Ajax using MVC
https://groups.google.com/forum/?fromgroups=#!msg/dynatree/kZqIO1zCTSU/HYTFe9O2docJ
and others places on the web but I cant find how to enable this loading from external data. I have even thought in change my library for YUI or ExtJS. I now that there is a support for trees on web2py using jstree, but, in contrast with dynatree, YUI or ExtJS, JsTree documentation is not very newbie friendly.
Any pointer to a solution would be appreciated.

Where is the file located?
The best is to put the file under static folder
web2py/applications/yourapp/static/sample-data1.json
So you need to tell your Javascript to load this from static folder.
initAjax: {
url: "yourapp/static/sample-data1.json",
data: { mode: "all" }}
Or you can create the url dynamically
<script>
var url_to_sample_data = "{{=URL('static', 'sample-data1.json')}}";
.....
initAjax: {
url: url_to_sample_data,
data: { mode: "all" }
}
.....
</script>

Related

I can't seem to generate content for dynamic content load

I am using wordpress and php along with ajax to create a random loading of customer reviews on our main page
function loadContent() {
$.ajax({
type: "GET",
url: 'http://skillsetsonline.ssosv.com/contentLoader.php',
data: {
company: 1
},
success: function(data) {
alert(data);
var currReview = document.getElementById('reviewRand');
currReview.innerHTML = data;
}
});
}
setTimeout(loadContent, 10000); // milliseconds, so 10 seconds = 10000ms
<div id="reviewRand" class="elementToFadeInAndOut" style="font-color:#FFF;">Hi how are you</div>
I pasted the ajax command in from a stackoverflow posting that was an accepted answer but may not have it exactly right this does not include the fading CSS code I use but that is working I just need to change the content.
Currently "Hi how are you" fades in every 10 seconds. One thing I have not learned about yet with this ajax command is the
data:{company:1}
I know it simply passes &company=1 to the GET URL but in my case I do not need to send anything and since it should not break anything if it is sent I left it alone not sure if
data:{}
would work and be cleaner
I have verified that the url used does get a random review
formatted like this
I love this program.blah blah.<br>
A USER<br>
A location<br>
June 2016<br>
Each line is formatted in CSS via a class tag
Any ideas would be greatly appreciated
Since the domain you're making the AJAX request to is on a different domain/origin, what you're running in to is a CORS issue. By default, the client will not allow you to update the page with data from an AJAX request that is served on a different origin than the site where the request originated. You can read about making CORS changes here https://enable-cors.org/
A common way around this is to serve the response via JSONP. You can do this in your script at http://skillsetsonline.ssosv.com/contentLoader.php if you have access to change that file. There are also third-party sites that will request that URL for you and create a proxy that serves the response via JSONP, then you can use it on your website.
Here's an example utilizing a JSONP proxy on https://crossorigin.me
function loadContent() {
$.ajax({
type: "GET",
url: 'https://crossorigin.me/http://skillsetsonline.ssosv.com/contentLoader.php',
success: function(data) {
var currReview = document.getElementById('reviewRand');
currReview.classList.add('ready');
currReview.innerHTML = data;
}
});
}
setTimeout(loadContent, 0); /* changed this for the demo */
#reviewRand:not(.ready) {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="reviewRand"><img src="http://thinkfuture.com/wp-content/uploads/2013/10/loading_spinner.gif"></div>

AJAX explained in detail

I found allot of examples of AJAX and I think I can get some code with it to work on my own. If only I knew what the use of all the terms of the AJAX code where.
I think in general it lacks the availability of these guides or special pages where constructed code is explained in detail for new programmers.
This would help enormously because of the misunderstanding of the syntax in many cases. Me for example spend 8 hours a day on my internship to learn PHP, Jquery, HTML from scratch and there is allot of information out there but its not structured and in most cases to technical. Any tips on that maby ? :)
$.ajax({
type: 'POST',
url: 'http://kyleschaeffer.com/feed/',
data: { postVar1: 'theValue1', postVar2: 'theValue2' },
beforeSend:function(){
// this is where we append a loading image
$('#ajax-panel').html('<div class="loading"><img src="/images/loading.gif" alt="Loading..." /></div>');
},
success:function(data){
// successful request; do something with the data
$('#ajax-panel').empty();
$(data).find('item').each(function(i){
$('#ajax-panel').append('<h4>' + $(this).find('title').text() + '</h4><p>' + $(this).find('link').text() + '</p>');
});
},
error:function(){
// failed request; give feedback to user
$('#ajax-panel').html('<p class="error"><strong>Oops!</strong> Try that again in a few moments.</p>');
}
});
Ajax is asynchronous, which mean you can use it to get new informations from the server without reloading the whole page.
Here's an explanation of your code :
$.ajax({
$ is the JQuery object, on which you're calling the ajax function
type: 'POST',
You're gonna send your data by post, which mean that you'll have to get them in php with $_POST['variable_name']. You could also put GET instead
url: 'http://kyleschaeffer.com/feed/',
the url you want to reach
data: { postVar1: 'theValue1', postVar2: 'theValue2' },
as you're sending your request with POST, you cannot pass data directly from the URL.
So you have to pass them like that. { nameVar: 'value', .... }
If you were sending with GET, you could directly write them into url like : "http://my_url.php?var1=val1&var2=val2 etc ...
beforeSend:function()
You can define an action before sending your ajax request
$('#ajax-panel').html('<div class="loading"><img src="/images/loading.gif" alt="Loading..." /></div>');
Here, inside your div "ajax-panel" you want to write some content. (a div "loading" and a picture inside "loading").
success:function(data)
If your request is successful, you can do something. By successful it means if server answer 200 i guess, anyway ... If you have a response from server... ;)
$('#ajax-panel').empty();
You delete content into ajax-panel
$(data).find('item').each(function(i){
$('#ajax-panel').append('<h4>' + $(this).find('title').text() + '</h4><p>' + $(this).find('link').text() + '</p>');
});
You're adding some html AFTER (append) the ajax-panel div
error:function()
Not sure you were looking for that, hope that help you ;)
AJAX is an acronym standing for Asynchronous JavaScript and XML and this technology help us to load data from the server without a browser page refresh.
If you are new with AJAX, I would recommend you go through our Ajax Tutorial before proceeding further.
JQuery is a great tool which provides a rich set of AJAX methods to develope next generation web application
Take a took at this
$.ajax({
type : varType, //GET or POST or PUT or DELETE verb
url : varUrl, // Location of the service
data : varData, //Data sent to server
contentType : varContentType, // content type sent to server
dataType : varDataType, //Expected data format from server
processdata : varProcessData, //True or False
success : function(msg) {//On Successfull service call
},
error : function() {// When Service call fails
}
});

Extjs 4 (with a code for 3.4 below) downloading a file returned from a post request

I have seen questions slightly related to this, but none that answer my problem. I have set up an Ext.Ajax.request as follows:
var paramsStringVar = 'param1=1&param2=two&param3=something&param4=etc';
Ext.Ajax.request({
url: '/cgi-bin/url.pl',
method:'POST',
params:paramsStringVar,
timeout:120000,
success: function(response, opts){
var objhtml = response.responseText; //content returned from server side
console.log(objhtml);
}
});
This request retrieves the appropriate content from the backend. One parameter is outputType, which can take values {html, excel, csv}. When returning html to display I am able to handle and display it correctly. Now on to the problem...
When I set the outputType parameter to csv or excel, I get back the appropriate content as csv or tsv(excel) as requested. BUT, I don't want the content, I want a prompt to download the file(csv or excel). How can I have the browser auto prompt the user to download the file instead of just retrieving the text content within extjs?
Version 4.07 so I can't use any 4.1 only features
There seems to be no bulletproof solution but there are several approaches I would try:
1) Use an iframe instead of real XHR to POST data to the server, e.g. <form action="/something" target="myiframe"> where myiframe is the name of your hidden iframe. That way your form would use the iframe (not your main window) to submit data to the configured URL. Your server should set response header as application/octet-stream (or some ither MIME type for binary data) so the browser triggers download. Otherwise (if html returned in your case) you can just retrieve iframe's body innerHTML and display it to the user in UI. While using an iframe (or a new window) instead of XHR doesn't sound like the best idea, this solution seems to be the most reliable so far (and with best browser support).
Here is a slightly modified example from Ext.form.Basic docs page:
Ext.create('Ext.form.Panel', {
title: 'Basic Form',
renderTo: Ext.getBody(),
width: 350,
// Any configuration items here will be automatically passed along to
// the Ext.form.Basic instance when it gets created.
// *THIS* makes the form use a standard submit mechanism, not XHR
/**/standardSubmit: true,
// URL to submit to
url: 'save-form.php',
items: [{
fieldLabel: 'Field',
xtype: 'textfield',
name: 'theField'
}],
buttons: [{
text: 'Submit',
handler: function() {
// The getForm() method returns the Ext.form.Basic instance:
var form = this.up('form').getForm();
if (form.isValid()) {
// Submit the Ajax request and handle the response
form.submit({
success: function(form, action) {
Ext.Msg.alert('Success', action.result.msg);
},
failure: function(form, action) {
Ext.Msg.alert('Failed', action.result.msg);
},
// You can put the name of your iframe here instead of _blank
// this parameter makes its way to Ext.form.Basic.doAction()
// and further leads to creation of StandardSubmit action instance
/**/ target: '_blank'
});
}
}
}]
});
There are two key parameters here (lines marked with /**/):
standardSubmit: true config that you pass to your form will make it do a standard submit instead of XHR.
Passing a target parameter to the form's submit action. This feature is not documented but you can see it being used in Ext.form.action.Submit source code (all options that you pass to Ext.form.Basic.submit() method end up as parameters of Ext.form.action.* instance.
In the example code I put target: '_blank' to demonstrate that it works right away (will create a new browser window). You can replace it with the name of your iframe later but I suggest that you first test how your form submits data to a regular new window and then develop logic that creates and processes an iframe. You will have to process the result inside iframe yourself, thought. It's not that difficult, see Ext.data.Connection.upload() implementation as an example of iframe processing.
ExtJS actually already uses the iframe technique for file uploads. See Ext.data.Connection and Ext.form.field.Field.isFileUpload() for an idea of how it can work.
2) Suggested here: Using HTML5/Javascript to generate and save a file.
If you don't want to go the iframe way, you can try generate data URI from response data and navigate to that URI triggering download:
content = "Hello world!";
uriContent = "data:application/octet-stream," + encodeURIComponent(content);
window.location.href = uriContent;
Again, mimetype is essential here. This worked for me, you should note, however, that browsers impose a size limit to data URIs (256Kb is a safe bet).
3) Another answer in the mentioned thread links to FileSaver.js library the implements the (abandoned?) w3 spec. Usage and demo here. It uses [BlobBuilder] to generate a blob of binary data that is further used to initialize downloads using one of several methods. While this solution seems to work, it uses deprecated APIs and may not be future-proof.
Below is my solution. This is how I have it currently working. The response generates a download/open prompt, based on a response type of text/csv. Note that no iFrame or reference to an iframe are needed. I spent a lot of time hung up on the need for an iFrame, which actually broke my solution. An iFrame is not needed to generate a download prompt. What is needed is a request(submittal) similar to this one, along with a backend generating the appropriate csv with text/csv response header.
var hiddenForm = Ext.create('Ext.form.Panel', {
title:'hiddenForm',
standardSubmit: true,
url: /cgi-bin/url.pl
timeout: 120000,
height:0,
width: 0,
hidden:true,
items:[
{xtype:'hiddenField', name:'field1', value:'field1Value'},
// additional fields
]
})
hiddenForm.getForm().submit()
The standardSubmit line is vital
You don't need to create a form panel and make it hidden in your extjs file. We can add a html form and on click of button in extjs file we can submit the form using the url. This will work both in IE as well as chrome browsers. Below is my code i tried and its working fine,
<form action="<%=fullURL%>/DownloadServlet.do" method="get" id="downloadForm" name="downloadForm" target="_self">
</form>
click:
{
fn: function()
{
document.getElementById('downloadForm').submit();
}
}
To get it working on ExtJS 3.4:
var hiddenForm = new Ext.FormPanel({
id:'hiddenForm',
region: 'south',
method: 'POST',
url: "/cgi/test.wsgi",
height: 0,
standardSubmit: true,
hidden:true,
items:[
{xtype:'hidden', name:'p', value:p},
{xtype:'hidden', name:'g', value:g},
// ...
],
});
linkThis = new Ext.Button({
text: 'Download this CSV',
handler: function() {
hiddenForm.getForm().submit();
},
maxHeight: 30,
});
Remember that in order to make it working, you should put the hiddenForm in any container (i.e. in the same Ext.Window of the button), for example:
risultatiWindow = new Ext.Window({
title: 'CSV Export',
height: 400,
width: 500,
....
items: [...., hiddenForm]
});

request.html in local file gets status = 0

I'm making a functional mockup using mootools,and in this prototype I have to load an html file via request.HTML, but as soon as I run the script, the call never reaches the onSuccess due to the state = 0.
The blame could be that the request is treated as a violation of the crossdomain.
So I was wondering if is out there a way to work it around?
this is the code I use for performing the request
req = new Request.HTML({
url: "detail.html",
onFailure: function(a) { console.log("iFailed: " + a); },
onSuccess: function(r3, rEls, rHTML, rJS) {
console.log("It worked!!");
},
onComplete: function() { console.log('completed'); }
}).send();
as I run this it always goes into the onFailure and in the onComplete without hitting the onSuccess.
I need this to work with safari, because the mock shall work on an iphone/ipad/ipod.
thx a ton
in the end I managed it bu injecting an iframe via js, instead of populating the div via ajax.
it's kind of lame and it sucks a lot, but at least it work and it's good for prototyping purposes.

Ajax prototype to load page then update hash

I have 3 page with different concept/layout/animation.
I'm using prototype & script.aculo.us
I have this in my navigation:
<ul>
<li>PAGE1</li>
<li>PAGE2</li>
</ul>
and this is in my js:
windows.location.hash: 'web';
function showPage() {
startloading();
var url: '/localhost/page2'+web;
new Ajax.Updater('maincontent', 'page2', { method: 'get' });
finishloading();
}
the question & problem is:
Why in windows location hash is still: /localhost/page1/#page2 with or without if I use var url?
All the animation in page 2 doesn't work, because I didn't put the header, but if put I it, I got double header and still the animation won't work either.
Can anybody give me the solution?
Thank you very much.
In your code
var url: '/localhost/page2'+web;
line throws error so hash cannot be changed. Fix it to
var url = '/localhost/page2'+web;
then it should work.
The correct way to update your hash is:
window.location.hash = '#'+yourValue;
Hard to tell what exactly you're trying to do with your function but there's a few things that are clearly a bit wrong.
function showPage(var) {
startloading();
var url: '/localhost/page'+var;
new Ajax.Updater('maincontent', url, { method: 'get' });
finishloading();
}
depending on what you're actually doing its fairly likely you would probably want something more like this:
function showPage(var) {
var url = '/localhost/page'+var;
new Ajax.Updater('maincontent', url, { method: 'get' ,
onCreate: function(){
startloading();
},
onComplete: function(){
finishloading();
}
});
}
Thats complete guesswork though, if you can provide more detail i can help more.

Resources