This question is for using javascript in Caspio Cloud's platform, so a few things might look different than normal. But basically, I need to put an 'if' statement that references a variable 'above' a change function that runs some other code and I can't figure it out.
The problem is that in Caspio's form the Virtual9 field will 'change' on the form's load, and so it runs the change js. I need to not run the change js onload and also only if the variable 'item' is null.
<script>
var item = document.getElementsByName("InsertRecordItemID")[0].value;
<!-- right here I need an if (item !== null) to then run the change function but that if it's not null to not run the change function{ -->
$("[name='cbParamVirtual9']").change(function(){
var itid = document.getElementsByName("cbParamVirtual9")[0].value;
document.getElementsByName("InsertRecordItemID")[0].value = itid;
}
);
</script>
I've tested the variables using alert windows and they are gotten correctly. I just need to make sure the change function doesn't run if the variable 'item' is null.
EDIT: To clarify, when the form loads the ItemID field may or may not be null (based on parameters that pass over).
If it is not null then the Virtual9 field (where the user makes a selection) will be hidden- because the ItemID already had a value and needs to not change.
However, if ItemID is null then Virtual9 will be visible and the user can make a change, thereby updating the ItemID field. The user may update Virtual9 multiple times (looking for the right record) so it needs to keep updating ItemID (even after it is no longer null in this case).
That's why I think the best solution is to disable the code ONLY for onload, if possible. So that the code runs on change of Virtual9 but not onload.
Related
I have setup a Custom JavaScript variable that works intermittently. The function is simply designed to return true or false if a text is contained on the page.
The below code works fine when the page is loaded directly from the URL bar and when executed in the developer tools console. When running the function in the console, the function indeed turns true. When the code is executed within debug mode in GTM, the value returns false when a history change event occurs.
function() {
var content = document.body.innerText;
var query = "text to search";
if (content.search(query) > -1 ) {
return true;
} else {
return false;
}
}
Any assistance/insight is very much appreciated!
To me this seems like expected behavior. Since you are talking about history changes, you are probably working with a single page application, or some other page where the DOM is changed after the initial page load.
Custom Javscript variables evaluate a function and return the result each time you reference it. How I imagine the flow of operations goes is this.
Page Loads (target text is in the page body) -> Custom JS evaluates on page view and returns true -> User presses some button -> DOM is modified to display new content (target text is removed and no longer present -> History change occurs -> Custom JS evaluates again, the text is no longer present so returns false.
If the target text is still present after the history change, then I can understand why we have some unexpected behavior. The history change trigger is based off of the push state api so what could be happening is that the pushState() function is called before the DOM is finished being modified. In this case, the text isn't present at time of the history change event even though it is shortly afterwards.
You could change the page so pushState() is only called after the DOM is done being modified, use a custom event as a trigger instead (again, pushing it after the DOM is done being modified), or use a different trigger like the element visibility trigger that will only fire after the new DOM elements you want to target appear on-screen.
I have created the following tag in GTM (Google Tag Manager):
(function(window) {
if (typeof(dataLayer[dataLayer.length-1].count) !== "undefined"){
dataLayer.push({'count':dataLayer[dataLayer.length-1].count+1});
} else {
dataLayer.push({'count':1});
}
})(window);
Initially, when there is no "count" pushed to the dataLayer, the if statement returns false and { "count" : 1} is pushed. After that the value of count should be incremented with each push. My aim is just to count the number of clicks on certain button.
However, it seems "if" statement is never validated, thus every button click results in pushing "0"-s to the dataLayer. I know this is not the best solution, but still I can't find out why this is not working. Btw it's working when I run this code in browser console.
I had to use dataLayer.length-2 instead of dataLayer.length-1 to access count. This was caused by the fact that GTM pushes gtm.click to dataLayer after each click event
Very simply, I have a custom ASP.NET control that in addition to rendering a textbox also outputs a javascript function and a call to that function. The key to the problem here is that variables in the javascript may be different on each postback.
So I have the control inside of an UpdatePanel and below is an example of what the output javascript looks like. Some of the variables passed to someStaticFunction are dynamic based on properties of the custom control (e.g. Visible).
$(function() {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(myFunction);
myFunction();
});
function myFunction(sender, args) {
someStaticFunction('false'); \\ "false" is written dynamically by the control's server side code
}
When the UpdatePanel posts back, depending on what the user chose, the page may now set the control's property to true. While the javascript does get written out correctly (same as above except 'false' is 'true', false is still passed to someStaticFunction.
So the control is rendering the correct javascript after the postback however the page is running the javascript from the original post.
I hope that's clear and someone can offer a suggestion. Thanks in advance.
Have you tried evaluating the properties of the control in the pageLoad() function that gets called on every postback and calling someStaticFunction with that value instead of what gets generated server side?
A simple code example:
function pageLoad(){
var value = $('#controlID').val();
someStaticFunction(value);
}
I wanna get the value of some checkboxes that is in my page, but the problem it is that this checkboxes are created by ajax, and how the javascript is executed before the my ajax mount my checkboxes, the function that gets the value of this element is null.
The code is like this:
function salvar()
{
//here is the problem, because this inputs is not here,
//I have a ajax function that creates this inputs
var checkBoxes = $('input[name=checkbox]');
var idsTelas;
var i = 0;
$.each(checkBoxes, function()
{
if ($(this).attr('checked'))
{
idsTelas[i] = $(this).val();
i++;
}
});
}
I suspect you are going about this the wrong way:
I wanna get the value of some checkboxes that is in my page, but the problem it is that this checkboxes are created by ajax, and how the javascript is executed before the my ajax mount my checkboxes
If I understand you correctly, your Javascript is executing before the checkboxes are created/inserted into the page.
So - when the Javascript runs, you want to get the value of things that don't exist yet? That is quite simply not going to be possible, regardless of any clever tricks.
The only way to resolve this is to change the relative timings. You'll need to run your salvar() function after the checkboxes have been created by AJAX. Or alternatively, if you can't push back execution of the function for some reason, you'll need to bring the AJAX creation step forwards. Either way, there has to be a dependency between creating the checkboxes and then invoking salvar().
I have a problem with my code, some code does not work when I call recursive call of same function inside it. It has to be something with myGalleria = Galleria.get(0);, but I have no idea how to make it all work.
Document Ready (just to show when I call function for the first time, everything works fine for first time)
$(document).ready(function(){
$.getJSON('getImages.php', {
cat: "123"
}, function(imgData){
createGallery(imgData);
});
});
Now function itself, note that when I click on .galleria-menuButtons span that calls same function nothing is working, well galleria itself is creating, but nothing else.
function createGallery(imgData){
$("#gallery").galleria({
image_margin: 30,
clicknext: true,
transition: "fade",
dataSource: imgData
});
myGalleria = Galleria.get(0); // I don't think this works after recursive call
// Adding menu and menu buttons
myGalleria.addElement("menu").appendChild("container", "menu");
myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");
$.ajax({
url: "menuButtons.php",
success: function(data){
myGalleria.$("menuButtons").html(data);
}
});
// Menu button click events
$('.galleria-menuButtons span').live('click', function(){
alert(this.id);
// Getting jSon data
$.getJSON('getImages.php', {
cat: this.id
}, function(imgData) {
alert(imgData);
createGallery(imgData); // <- Recursive call
});
});
}
I have similar function on window.resize and it also does not work after recursive call.
$(window).resize(function(){
$(".galleria-container").css("width", $(window).width());
$(".galleria-container").css("height", $(window).height());
galleriaRescale = Galleria.get(0);
galleriaRescale.rescale(); // <- this is not working either
//sizeBG();
});
FYI - this isn't actually recursion in the traditional sense because you're calling createGallery from a click handler which launches a JSON request which then calls createGallery when that succeeds, both of which will occur after the previous call to createGallery finishes.
But you do have surviving function closures which could be confusing things or causing problems. One guess is that you may want to make sure that things you expect to be local variables (like myGalleria have a var in front of them so they really are local variables and not variables that might be scoped to a higher level and be influenced by a previous incarnation of this call or be influencing an earlier call that hasn't yet completed.
var myGalleria = Galleria.get(0);
Then, assuming imgData is some sort of data structure like an array or object, you have to make sure that there's either only one global version of that data structure that never changes or that each call of createGallery has the appropriate separate copy of that data structure. If it's getting changed along the way, then subsequent calls to createGallery may not be getting the data they want. If it's a read-only data structure (you don't change it), then you're probably OK on that one.
OK, let's talk through the pseudo code for what this does.
On page ready, you get some JSON image data.
When that succeeds, you call createGallery with that image data.
The createGallery call does some sort of operation in the DOM (perhaps an animation)
It then calls: myGalleria = Galleria.get(0); Because there is no var in front of myGalleria, this is a global variable declaration (bad news for recursion and closures)
You then use the myGalleria data structure to make some changes to the DOM (adding menus and menu items).
You then add a .live click handler on a pretty generic set of CSS classes (it's possible you have added this click handler more than once here).
You then fetch some JSON image data again.
When that image data is fetched, you start the whole process over again by called createGallery.
Summary
The two potential problems I see are that myGalleria is not a local variable and probably should be and you may be adding duplicate click handlers.
If neither of these fully solve the issue, then we probably need more information about what Galleria.get(0) is doing.
FYI, the resize clickHandler looks like it may have the same issue with not using var to make your variable declaration a local variable.
Round 2
OK, here are some more observations.
When you add the menu and menu buttons with this block of code, you aren't providing any unique identifiers to either the addElement or appendChild functions (you're providing "menu" and "menuButtons" to both). As such, I don't know how you can uniquely hook up to them in the subsequent click event. As far as your code looks, all the menu items look identical and none have unique state. I don't know the Galleria code, but I assume somebody has to make unique identifiers for these new items so that you can uniquely identify them in your subsequent click handler.
// Adding menu and menu buttons
myGalleria.addElement("menu").appendChild("container", "menu");
myGalleria.addElement("menuButtons").appendChild("menu", "menuButtons");
When you set up a click handler to presumably handle the clicks for just these menu items, you are using the exact same CSS selector every time so there's no way that this click handler is going to be uniquely assigned to just the newly create menu items (which is what I assume you want). I don't know the Galleria code, but I assume that you should create some sort of unique ID that you pass into addElement and appendChild for the newly created menu items and then reference that unique identifier when you install the click handler. Likewise, this function needs to uniquely target just the menu buttons you created by using unique identifiers myGalleria.$("menuButtons").html(data);
Lastly, I'd suggest you change the name of one of your variables just to avoid confusion. In your click handler, change the three occurrences of imgData to just data so there can be no confusion about closures and the value of imgData.
Round 3
Ultimately one of the fixes was this (embedded in the comments):
I think it might work if you just only install the .live click handler once outside the createGallery function rather than call it each time. Since it's .live it will automatically work for all future buttons you create so you should only call it once. I'd suggest putting it in the $(document).ready function block.