Can i pass a javascript object back to an atk4 page? - javascript

From an ATK4 page, i can call jqplot using a javascript helper file like this
on the page
$chart = $p->add('jqplot', null, 'chart1');
$chart->setSeries(array(10,20,15));
define a jqplot.php like this
class jqplot extends View {
function render()
{
$plot=$this->js(true)->univ()->jqplot($this->series, $this->opts);
parent::render();
return $this;
}
}
and in a js helper file, link the php call to the javascript
$.each({
jqplot: function(series, opts){
console.log('jqplot series',series);
console.log('jqplot options',opts);
$plot=$.jqplot(this.jquery.attr("id"), series, opts);
return $plot;
}
}
If i have one chart on a page and reload it with an ajaxec call, it works fine but if i have several charts next to each other, only the first one is ok and the one next to it completely disappears if i call reload.
What i really want to do is call the jqplot replot function on the chart and pass it new data from the page but how can i do this ? The $plot object in the jshelper holds a javascript object and i need this object to call replot on it.
I am thinking maybe i can store the object when first created in a javascript associative array and then when i call replot, lookup the id and if found, call replot on the object but not sure what this code looks like or whether i have the right approach so any help appreciated.
Thanks in advance for you assistance.

It probably would be quite difficult to achieve this. First you need to properly handle destruction of jqPlot. You'll need a proper jQuery UI widget capable of restoring everything through a de-constructor. Then you might get it to work.
As far as Agile Toolkit is concern, it destroys the element containing your jqPlot using JavaScript, re-loads HTML and re-executes JavaScript.

Related

How to Use Jquery Smart Wizard with some ajax pages

I am having difficulty in understanding how to use the jQuery smart wizard.
I have managed to get it going with static html for my first three tabs but I now want to add another tab which uses an ajax call to get the data based on the data I have collected in the previous tabs.
I know there are callback functions for leaving and entering steps but the documentation is unclear on how to use them (or it maybe I don't understand enough jQuery/JavaScript to correctly interpret the documentation)
The way I read it is I would use
$("#smartwizard").on("stepContent", function(e, anchorObject, stepIndex, stepDirection) {
// if this is the correct step index then
// do my ajax call using a promise
// (Which I do not understand fully how to do.
// I have never used a promise before.)
// and return my html. (Where is the html going to be put? is it the 'tabpanel'?)
return myHTMLfromtheajaxcall;
// else do nothing
// How do I stop it overriding the existing content?
// Do I return '' or false or what?
});
What and where do the parameters for the function come from. What is 'e'? What is 'anchorObject'? The other parameters are self explanatory.
I hope somebody can explain things in simple terms with some examples.
Thank you in advance.

PHP logic to Javascript front into html tags

I am currently trying to convert a lot of backend code to front end (to lighten the load on a small system).
The code at the moment calls a PHP function to return specific information. (e.g. image locations, strings, styling)
I am converting this code to its js equivalent, the content from Mysql was converted to JSON and stored in a read only file and I am accessing that file using this code:
<script>
function jsread(tag) {
$.getJSON("/strings.json", function(result){
document.write(result[tag]['value']);
});
}
</script>
I want the function to "print" where ever it is invoked. document write writes the value to the page but stops all other loading and write only the value.
Let me be very clear on this: I DO NOT want to use anything that needs extra calls or references out side of this function, that will take months of work so no getting elements by their IDs I have already view many questions on this subject and none are what I can work with. I need something that can be applied to every situation. Other wise I will just have to read the JSON using PHP as a middle compromise.
The problem here is, document.write()'s behaviour is crazy across all the browsers, because, it directly modifies the document object and messes up with the events attached. So it is always better to avoid this function as each browser defines it differently and has a different effect on the same code, with different browsers.
Is there a way to use them without a direct reference?
Solution
The wise thing is, as I said in the comments, it is better to use one of the jQuery functions safely, which create a textNode and insert it the right way, without affecting the others:
<script>
function jsread(tag) {
$.getJSON("/strings.json", function(result){
$("body").append(result[tag]['value']);
});
}
</script>
In case, if you wanna do something like having a placeholder and doing stuff, then you can try giving something like this:
$(function () {
var data = "Dummy Data, that would probably get returned from the getJSON";
// Inside the Success function, do this:
$("span.placeholder-of-the-json").replaceWith(data);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="placeholder-of-the-json">This gets replaced</span>

Trouble with calling javascript function within another using D3

I'm learning to use D3.js for some visualization ideas I have and I'm running into something that is probably quite easy and perhaps solely a javascript thing.
I want to call a function from within another function. I have created a basic scatter plot and want to reload it with new data points. Here is the JSFiddle. I'm really quite stumped!
I think in it's simplest form it looks like this:
function firstFunction() {
var something;
}
function secondFunction() {
firstFunction();
}
But it seems to sometimes works sometimes not and can't figure out why.
What's happening is that, in jsfiddle, the default is to encapsulate everything in a function that runs on window load. The code looks like this: window.onload=function(){your stuff}
When you try to set the onload, the code structure is then structured like this:
function firstFunction(){
function secondFunction(){
do stuff
}
}
onload = secondFunction;
The issue is that secondFunction is not accessible outside the scope of firstFunction. This is called variable scoping, and coding would suck without it.
The way to solve this issue is to move your onload assignment to the javascript block. I'd recommend the built in d3 way of doing this: d3.select('button').on('click',newScatter); here I'm selecting the button and adding a click event handler. This works because there is only one button, but it would be better to give the button a class or id and use that in d3.select().
If you do that, your code will still not work, but that's because you delete the SVG element that's supposed to contain the scatter plot in newScatter() (this line: elem.parentNode.removeChild(elem);). The button, however, will successfully do what you told it to do and delete your scatter plot.
I've created a working version of your fiddle here.

Assigning json to variable

Ok, some explanation. Even though I don't think it has anything to do with the problem itself. I have a small django project that maps some data using leaflet. On a mouseover some ajax functionality is added, using the dajax(which is a "lightweight library to implement AJAX inside django projects") framework. The call itself looks like this:
dajax.add_data(simplejson.dumps(series), 'my_test_flot')
My js function receives json data which looks like this (using alert)
[{"color": "#dddd00",
"data": [[-0.5, -20.5]],
"label": "Tweede Zandlaag"}]
The object has more data to it but the problem is not with the object. When I copy/paste the data directly into the function var series = [] the behaviour is as aspected. As aspected means, the graph I'm drawing with flot is actually being drawn. Otherwise the graph remains empty.
function my_test_flot(dat) {
function MyFormatter(v, xaxis) {
return " ";
}
$(function () {
alert(dat)
var series = dat; // here lies the problem, but why?
...
Can anyone help?
Ok, problem solved. Apparently you have to use JSON.parse(). How it's done is explained here.
This does not copy the data - it just makes series a reference to the same object as dat. Therefore, if you later modify the object, all users retaining references to it see the changes. This is probably what causes your trouble.

Export dynamically created table from javascript to Excel

I am working on a project that dynamically creates an html table with javascript. Once this table is created I need to be able to export it to excel through a button click. I have tried a few things already, but they haven't worked for me.
I tried doing a simple export from javascript by creating the Active X object, but that setting is locked down in IE so our browsers will not work with Active X.
I tried exporting to excel from a code behind function using the HttpContext class but since the table is created dynamically, the server doesn't see it.
My final method, and I was sure that this was going to work, was I used AJAX via a pagemethod to export the table to excel. I was going to create an array of the table in javascript and pass it to the pagemethod. But before I got to this step, I created a pagemethod that exported a simpe "Test" file to excel. It worked as a method called from a button click, so I figured it would from a pagemethod as well. It didn't :( It runs and completes the pagemethod, but doesn't open excel or export anything. No errors and the success function is executed.
Here is the code:
<System.Web.Service.WebMethod()>
Public Shared Function exportTable(ByVal title As String) As String
HttpContext.Current.Response.ClearContext()
HttpContext.Current.Response.AddHeader("content-disposition", "attachment; filename="TEST.xls")
HttpContext.Current.Response.ContentType = "application/vnd.ms-excel"
HttpContext.Current.Response.Write("<?xml version='1.0'?>")
HttpContext.Current.Response.Write("<ss:Workbook xmlns:ss='urn:schemas-microsoft-com:office:spreadsheet'>")
HttpContext.Current.Response.Write("<ss:Worksheet ss:Name='sheet1'>")
HttpContext.Current.Response.Write("<ss:Table>")
HttpContext.Current.Response.Write("<ss:Row>")
HttpContext.Current.Response.Write("<ss:Cell><ss:Data ss:Type='String'>TEST</ss:Data></ss:Cell>")
HttpContext.Current.Response.Write("</ss:Row>")
HttpContext.Current.Response.Write("</ss:Table>")
HttpContext.Current.Response.Write("</ss:Worksheet>")
HttpContext.Current.Response.Write("</ss:Workbook>")
HttpContext.Current.ApplicationInstance.CompleteRequest()
Return 0
End Function
My page method call is:
function exportToExcel(title) {
PageMethods.exportTable(title, exportSuccess, exportFailure)
}
The exportSuccess function is a simple alert, which is firing. I take that to mean that the pageMethod is executing without errors, but that it can't open excel or ... something.
I eventually want to pass in an array and loop through it to add the rows and data. I've done this with a non dynamic table and it works. I'm also going to use the title to define the filename, but for testing reasons, I've named it TEST.xls.
I copied and pasted the HttpContext code into a button click event and it worked fine with a static table, so I don't think there are any problems with that. But I have been known to be wrong.
I guess my question is can a PageMethod export to excel or use the HttpContext class? Is there a better/easier way to do this?
Please keep in mind that I cannot use ActiveX objects and all customers are required to use IE.
Thanks for your help, and I'm sorry if this has already been covered. I searched but didn't find anything. If it has, could you please point me to the post?
If you send out the Excel MIME header, followed by an HTML table, EXCEL should load it as it it were a spreadsheet.
Well, I've buckled under pressure and decided to do it a different way. I think that ajax does not play well with response.write.
I created an asp:hiddenfield control. Then when the ajax was called to generate the table, I populated it's value with a pipe delimeted string representing the rows and columns of the table. So cell1|cell2||cell1|cell2||cell1|cell2.
Then I created an on_click method for a button and was able to use the same code from the function above. To populate the table I just replace the "TEST" by parsing the hiddenfield value.
I decided to post this just in case anyone else was having an issue with it.

Categories