Running multiple AJAX functions through onclick event - javascript

I feel as if this issue is pretty simple, so I may be overlooking something pretty straightforward, but I can't seem to find the solution on Facebook. Basically I have two AJAX functions that interface with PHP scripts through the onClick event. Here is how I am laying out the HTML:
onClick = "previousMonth(this.id); monthDisplay_previous(this.id)"
Currently, it is displaying the output from previousMonth(this.id). But if I reverse the function calls and set it up as:
onClick = "monthDisplay_previous(this.id); previousMonth(this.id)"
then it only displays the output from monthDisplay_previous(this.id) -- it just won't run them both. In addition, they both interface with different PHP scripts. I feel like this is enough information to go off of, but if you want me to post more code I will, reluctantly. Any ideas?

If they can run in parallel, you might try somethign like this
var someFunction = function(that_id) {
previousMonth(that_id);
monthDisplay_previous(that_id);
}
onClick = "someFunction(this.id);"

Try wrapping both of your functions into another one.
onClick = function(){ previousMonth(this.id); monthDisplay_previous(this.id); }

Related

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>

How to avoid duplicated code in JavaScript / jQuery?

First, a little disclaimer: I'm no master at working with javaScript / jQuery, although I have handled it quite a few times. Recently, I have sometimes found myself being forced to make redundant code, i.e. repeat line(s) of code regarding diferent events, because I don't know how to do it in a more efficient way. A small example would be enabling a button after checking if any checkbox in a page is selected. This is done either upon page loading or after any checkbox is selected:
var checkboxes = $("input[type='checkbox']");
$('#nextfl').attr("disabled", !checkboxes.is(":checked"));
checkboxes.click(function()
{
$('#nextfl').attr("disabled", !checkboxes.is(":checked"));
});
I don't think this could be solved using the bind or on functions, for instance, since it refers to events not related to the same element. I believe it must exist a straightforward solution to this though, but as I said before, I have little experience in JS / jQ, and there are some similar situations where I have repeated dozens of lines of code, which is of course at least a bad practice.
You can always split redundant code into functions with javascript:
function doCheckboxLogic () {
$('#nextfl').attr("disabled", !checkboxes.is(":checked"));
// and any other logic that needs to be done
}
You then call that function in place of the redundant code block:
checkboxes.click(function()
{
doCheckboxLogic();
});
There's not much gained here since it's one line of code anyway, but this really helps with encapsulating more complicated blocks of logic
Best practice in this case is to extract common logic to its own function which can be called as required. Try this:
$(function() {
var $checkboxes = $("input[type='checkbox']");
function checkState() {
$('#nextfl').attr("disabled", !$checkboxes.is(":checked"));
}
$checkboxes.click(checkState); // run the function on click of a checkbox
checkState(); // run it on load of the page
});

Iterate over DOM elements in DalekJS

Does anyone know a simple way to iterate over, and operate on, all elements matching a query using the API?
My simplest use case is something like this - not real code, but hopefully you know what im looking for.
test.query('textarea').each(function(v, i){
this.type(v.id, 'test' + i);
});
I can do it with arbitrary JS exec, jQuery etc. I just figure it's something that Dalek probably does that I've missed
Thanks!
EDIT
Turns out my JS exec backup doesn't work...
test
.execute(function(){
var textareaIds = [];
(function($){
$('textarea').each(function(){
textareaIds.push($(this).attr('id'));
});
})(window.jQuery);
this.data('textareaIds', textareaIds);
});
But possibly due to the nature of how the code is queued then executed you can't use the array in a for loop afterwards. Have I missed something?
We are going to improve the API session in the upcoming version of DalekJS, so iterating over DOM elements & interaction between JavaScript executed on the client side & JavaScript executed on the server as part of the tests will be a lot smother.
Regarding your not working execute example. You can not just use the data passed via this.data in your Node code afterwards, you need to add it to the chain. As this is an very experimental feature, we did not really implement an API that can work with the data later.
One thing you can do, is abusing the log.message method like this:
.execute(// your code)
.log.message(function () {
// get the data
var myArray = test.data('textareaIds');
// do something with it
require('fs').writeFileSync('myFile.txt', JSON.stringify(myArray));
})
I suppose that this is not exactly what you want/need, but reusing that data for further tests and assertions is not yet possible. But we are working on it.

How to overwrite implementation of the function or intercept call to it?

I angularjs when modal window from bootstrap is opened it provides two functions, $dismis and $close, on modal window $scope. I need an event to be fired just before either one of these is called. Currently code in controller looks like this
$scope.$emit("ModalClosing");
$scope.$close(payload);
What I would like is to eliminate need to call $emit manually, I want to be able to do
$scope.$close(payload), so that the implementation of $close function does steps above. How would one achieve that? It probably needs something like what mocking framework use. I basically need to intercept call to the function and call my code, and then call original function.
Update: After I posted the question I thought why not just replace it with my implementation. I cannot believe that it is so simple. Is this right? Is there a better way?
var closeModal = $scope.$close;
$scope.$close = function (payload) {
$scope.$emit("ModalClosing");
closeModal(payload);
};
After I posted the question I thought why not just replace it with my implementation. I cannot believe that it is so simple. Is this right? Is there a better way?
var closeModal = $scope.$close;
$scope.$close = function (payload) {
$scope.$emit("ModalClosing");
closeModal(payload);
};

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.

Categories