I know there are lots of other questions that address calling rails controller methods using AJAX, but I don't see any that call a rails controller method that requires a parameter, in my case, "def sum_graph(date)"
I am using the Chart.js bar graph and I get the values of the bars using this rails method. Upon updating the values that are used by the sum_graph(date) method via best_in_place, I would like to be able to call that method using the new values to update the chart without refreshing the page.
My code so far looks like this (I'm only updating one bar in the graph since I'm just trying to get it to work):
$(document).ready(function() {
$('.best_in_place').bind("ajax:success", function() {
myBar.datasets[0].bars[0].value = <%= sum_graph(Date.current - 24.months) %>;
myBar.update();
});
});
If I replace the sum_graph(date) method in this code with a random number generator, it indeed updates the bar with the random value every time I change a value using best_in_place so I think I'm headed in the right direction. So is my code indeed re-calling this method each time I change a value, just without the new values? Either way, any help here to resolve this problem would be much appreciated.
Thanks so much in advance.
Related
So, I'm trying to figure out what is the exact order/timing of functions being called in my controller in Yii. Right now, I have code like this
public function actionIndex()
{
$userId = Login::model()->getUserId();
// update all of the account balances upon viewing
// Account::model()->updateAccountBalance($userId);
// limits the data provided to only those accounts that are of the same userId
$dataProvider= new CActiveDataProvider('Account', array('criteria'=>array(
'condition'=>'user_id="'.$userId.'"')));
$this->render('index',array(
'dataProvider'=>$dataProvider,
));
// an attempt to update my account after the view has rendered.
// nope this is super super slow.
Account::model()->updateAccountBalance($userId);
}
Which I would like to update my account balance in the database after everything in the view has been rendered. (In my view I have a couple of calls using Ajax to external servers.). Now, this seems to be working well - and it seems to be going as fast as it was using javascript initially. But, I'm still a bit confused on the order. Is my function
Account::model()->updateAccountBalance($userId);
being called after the view has entirely rendered (i.e. made ajax calls)? I know that there are specific functions like afterRender and filters - but does this function get called after rendering anyways?
Watching your Codes its 100% for sure, Account::model()->updateAccountBalance($userId); is not called. $this->render(); will exit after your view was rendered successful. You can also check the Documentation about render(); here: http://www.yiiframework.com/doc/api/1.1/CController#render-detail
By adding, true as return param to $this->render(); you will be able to provide your application to "exit" after the view is rendered. But in that way, you will be get your "delay" again.
$viewData = $this->render('index',array(
'dataProvider'=>$dataProvider,
), true);
// an attempt to update my account after the view has rendered.
// nope this is super super slow.
Account::model()->updateAccountBalance($userId);
echo $viewData;
You should run Account::model()->updateAccountBalance($userId); in an own thread triggered by AJAX (clientside) or CRON (Backend) to make that async process work fine without any "delays".
I hope this will help you out.
This is really tricky to get my head around as I'm not used to this style of programming/data management.
All I'm trying to do at the moment is pass a json object returned via breeze into a dynatree or fancytree.
The examples that exist online all assume that the tree will do the ajax call via "initajax" or that some weirdly convoluted custom binding handler is needed into which various objects are passed:
ko.bindingHandlers.dynatree = {
update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
setTimeout(function () {
$(element).dynatree({
noLink: true, // noLink is required to 'unlock' the checkboxes
minExpandLevel: 2
})
// the timeout value shows the correct knockout bindings BEFORE dynatree kicks in.
}, 1000);
}
}
This all seems too complicated to me, surely? I already have the json object, I know that's working. If I use knockout to "foreach" bind it to some plain html then all data is displayed just fine. In my mind all I need to do is initialize the tree div and pass it the json object... It's just that I have no idea how to do that!
I've tried using the jsfiddle here: http://jsfiddle.net/Ebram/UhA3m/5/ but chrome developer tools complain about the element having no "dynatree" method when the custom binding handler fires. It's passing in a "ul" element and that could be the problem - surely it should be passing in the tree div, not the ul element?
Anyhow, if anyone could point me in the right direction I'd hugely appreciate it. As I'm using John Papa's SPA methodology, I'm also unsure as to where I would put any separate js initialization code as the underlying viewmodel isn't the right place for me to be doing a $(#tree).dynatree initialization type call, is it? I must admit I've not got my head around this yet.
I suppose all I'm looking for is something along the lines of "once the viewmodel for this view has finished loading and the knockout binding is being done, initialize the dynatree div and pass this json object to the tree" if that makes sense in pseudocode?
I can hopefully point you in the approximate right direction.
It seems dynatree can also take JSON from a file as well as an AJAX request. In this example Lazy Loading, if you look in the source code, there's:
// In real life we would call a URL on the server like this:
...
// .. but here we use a local file instead:
Storing your data in a file to get it in seems awfully wasteful. Now that we know it's a little flexible in what it gets, let's see where it uses the data and maybe we can get it to use a local variable instead. let see where it loads it
Looking in the dynatree source, there's a function associated with appendAjax. (line 1774 in my source.) A little short on time at the moment, but I'd find where it gets the JSON and what it does with it. Perhaps you can do the same thing outside or mod the handling of ajaxOptions to take a variable with the JSON.
I'm struggling with this even after reading the MSDN documentation and the following online guides:
Codefoster
Stephen Walter
I think my problem is easy to fix and that I just am thinking about something in the wrong way. Basically I am querying my web service and on success running the following method. I am then trying to bind the result to my listview. For now I am using a hardcoded value publicMembers.itemlistwhich has been declared at the top of the document just to make sure I can actually bind to the list before doing it with my query results. Ignore line 2 for now.
Success Method:
_lookUpSuccess: function xhrSucceed(Result) {
var response = JSON.parse(Result.responseText);
listView = document.querySelector("#termTest");
ui.setOptions(listView, {
itemDataSource: publicMembers.itemList,
itemTemplate: document.querySelector(".itemtemplate"),
})
},
Now, instead of using document.querySelector, I have also tried with WinJS.Utilities.id and WinJS.Utilities.query, neither of which worked either. This doesn't break my code and introduce an error but it doesn't bind to the listview either so I think I have an issue in querying the right DOM element. However exactly the same code does work if I add it to the top of the script, it is only when I place it in this method that it stops working.
EDIT: Also to clarify, when I debug publicMembers.itemList is storing the values I expect them to be.
Please point out if I have explained things poorly and I will try and improve my question.
Thanks.
I haven't used WinJS.UI.setOptions, but rather this other way of setting the data source. Can you see if it works?
_lookUpSuccess: function xhrSucceed(result) {
var response = JSON.parse(result.responseText);
listView = document.querySelector("#termTest");
listView.winControl.itemDataSource = publicMembers.itemList;
},
This would assume you're defining the itemTemplate as part of the data-win-options attribute of your ListView's HTML element. You could also probably just do listView.winControl.itemTemplate = document.querySelector(".itemtemplate") if you prefer to set it programmatically.
I've been going at this for a solid hour, and I have a feeling it might be something simple. I'm doing a basic model fetch with backbone.js with the code below.
var Document = Backbone.Model.extend({
urlRoot: "/Package/Documents/GetDocumentById/"
});
mydocument = new Document({id: "3978204"});
mydocument.fetch()
I would expect the above code to make a call to the following url
localhost:3000/Package/Documents/GetDocumentById/3978204
But instead it is adding an extra parameter to the query which is blowing up my method.
localhost:3000/Package/Documents/GetDocumentById/3978204?_=1318548585841
I have no idea how ?_=1318548585841 get rid of the extra parameter.
Any help would be apperciated.
Take a look at this related question. This is a cache-buster added by jQuery.ajax(), which Backbone uses in the background.
I believe you can remove this by passing cache:true as an option to fetch() (which gets passed to $.ajax()):
mydocument.fetch({ cache: true });
If that works but you don't want to do it every time, you could set it globally with jQuery.ajaxSetup().
I know it's easily possible to execute javascript through a controller, but is it possible to do it the other way around?
Use case scenario:
I have a list of products on the left side of a page. When I click one of these products, I have a CSS highlight appearing. I'd then like the javascript to rerender my search results function, "showtheresults".
It would allow users to drill down the product whose data they are searching through. The only way I can think of doing it is through javascript. Other suggestions welcome.
You can try using the Ajax toolkit. In JavaScript:
// Include Ajax toolkit
{!REQUIRESCRIPT("/soap/ajax/22.0/connection.js")}
{!REQUIRESCRIPT("/soap/ajax/22.0/apex.js")}
// Get selected Lead Ids
var leadIds = {!GETRECORDIDS($ObjectType.Lead)};
// Call your class method
var result = sforce.apex.execute('CalledFromJavaScript', 'theMethod', {arg: leadIds});
Then in Apex:
// Make your class global and method a webservice:
global class CalledFromJavaScript
{
webService static Integer theMethod(List<Id> sObjectIds)
{
...
}
}
You can do this with an output panel that you rendered selectively based on a boolean in your controller. In this example set 'renderScriptPanel' when you'd like the showResults function to run. If you're doing a partial page refresh make sure to refresh the id of the output panel.
<apex:outputPanel id="scriptPanel" rendered="{!renderScriptPanel}">
<script type="text/javascript">
showTheResults();
</script>
</apex:outputPanel>
You may want to look at JavaScript Remoting for Apex Controllers