So basically, I'm creating variables within the keyUp method of input box that get their data from a smarty loop (this is within the $(document.ready)
Here is the code
{section name=unitEl loop=$allNavies}
$("#attack-navy{$allNavies[unitEl].ID}-number").keyup(function(){
var unit = {$allNavies[unitEl]};
var element = $("#attack-navy" + unit.ID + "-number");
var available_count = {$NAVY_{$allNavies[unitEl].ID}_AVAILABLE_COUNT|default:'0'};
alert(unit.ID);
// Unit max = available count
if(element.val() > available_count)
{
completeUnitValue(element, available_count);
}
// If transport navy: Increase capacity
if({$allNavies[unitEl].ID} == 16 || {$allNavies[unitEl].ID} == 19 || {$allNavies[unitEl].ID} == 20)
{
$("#attack-max-capacity").text(getMaxCapacity());
}
});
{/section}
The problem is, when I alert any of the variables (unit, element, available_count) I receive undefined, but when i use the smarty {$allNavies[unitEl]} instead of variables, everything works fine. I just created variables to make the code more readable.
Anyone know why?
I call what you're doing "smarvascript". I loathe it and beg my coworkers to avoid it. But then, I loathe Smarty altogether, so there ya go.
This line:
var unit = {$allNavies[unitEl]};
assigns some PHP value into a JS var.
This line:
alert(unit.ID);
makes it look like you believe 'unit' is an object with properties. You cannot directly assign a PHP object into a JS object and expect it to work...
I'd need to see some of your PHP code and data structures to explain how you should do it, but it is possible that this might help
var unit = {$allNavies[unitEl]|json_encode};
Or, if $allNavies[unitEl] is an array:
var unit = {$allNavies[unitEl]|#json_encode};
I could probably help most if I knew what the structure of $allNavies was.
Also, I am curious...where are your {literal} markings to keep the JS curly braces from making Smarty freak out?
Edit:
Here is a little trick I like to use when I am forced into injecting Smarty into JS:
//{literal}
( function( allNavies )
{
/*
allNavies is now a JS object and you can work purely with JS in here
*/
}(
//{/literal}
{$allNavies|#json_encode}
//{literal}
) );
//{/literal}
Related
I am running into a problem people have posted before: JavaScript dynamic parameters
But my code uses nodes rather than innerHTML assignments, so the existing SO post doesn't seem to apply to my code.
I want to dynamically generate HTML buttons in a table. For each button, I want to call a function with parameters that depend on the button's index/position in the table. First I tried just using lambda functions with the variable over which I was incrementing. This didn't work, so I also tried dynamically named variables, meaning each button should be passing a differently named variable to deal with lazy-loading effects. But this didn't work either. You can see both versions of what I tried in the code below:
This code I paste below is in a for-loop. In the following, I increase i by 1 each time. offset and jj are unchanged within the loop.
var variableDynamic = i.toString();
window['variableName' + variableDynamic] = i + offset;
upvote.onclick = function() {
upVoteA(i + offset, jj);
//upVoteA(window['variableName' + variableDynamic] , jj);
};
upvote.innerHTML = "Upvote"
Someone told me to look into closures, so following this recommendation: http://www.usepatterns.com/blog/javascript-closures I rewrote the onclick function declaration as:
upvote.onclick = function() {
var a = i + offset;
var b = kk;
function closeIt(){
upVoteA(a,b);
}
closeIt();
};
This still has the same effect that every button calls upVoteA with the same parameter, namely the last/highest value.
I realize I could refactor my code to turn these into .innerHTML set statements and then I'd print the variable and it would be set as a printed statement instead of a lazily-loaded variable. But I'd like not to do that if possible. (apologies that it's not technically lazy loading, the name seems reasonably apt)
Is there a way to make my code work? And why are the closures failing? I thought closures should preserve the environment they were created in, but that is not the case with my code. Which portion of the "environment" are preserved with closures?
This is a very bad answer, but it works
var funcStr = "function dummy() { upVoteA(" + (i + offset) + "," + jj + "); }";
eval(funcStr);
upvote.onclick = dummy;
But if you have something better, please let me know.
I am working on a slider that uses jQuery. Some elements of the slider are working correctly, but there is a problem that I am trying to troubleshoot with some of the code. To test it I would like to be able to display the values of the variables in the statement.
Here is the code block I am working with:
$('.marquee_nav a.marquee_nav_item').click(function(){
$('.marquee_nav a.marquee_nav_item').removeClass('selected');
$(this).addClass('selected');
var navClicked = $(this).index();
var marqueeWidth = $('.marquee_container').width();
var distanceToMove = marqueeWidth * (-1);
var newPhotoPosition = (navClicked * distanceToMove) + 'px';
var newCaption = $('.marquee_panel_caption').get(navClicked);
$(' .marquee_photos').animate({left: newPhotoPosition}, 1000);
});
I added a div called 'test' where I would like to display the values of the variables to make sure they are returning expected results:
<div class="test"><p>The value is: <span></span></p></div>
For example, to test the values, I inserted this into the statement above:
$('.test span').append(marqueeWidth);
However, I don't get any results. What is the correct way to include a test inside that code block to make sure I am getting the expected results?
Thanks.
Just use JavaScript's console functions to log your variables within your browser's console.
var myVar = 123;
console.log(myVar, "Hello, world!");
If you're unsure how to open the console within your browser, see: https://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers
append is used to append either an HTML string, a DOM element, an array of DOM elements, or a jQuery element. Since you are just trying to show a number (marqueeWidth), you probably want to set the text of the span instead:
$('.test span').text(marqueeWidth);
Also, is there a particular reason why you don't just use the console? It may be worth reading over a Debugging JavaScript walkthrough.
you can use the following.
$('.test span').html(marqueeWidth);
However doing a console.log(yourvariable); or alert(yourvariable); is better.
I am customizing some jQuery plugin, and I have an error message I can't understand
var totHistory=0;
var positions = new Array();
$('.someclass').each(function(index){
var tmp = $(this).val();
addHistory({id:tmp});
});
function addHistory(obj)
{
/* Gets called on page load for each comment, and on comment submit */
totHistory++;
positions.push(obj.id);
}
At the very first iteration through .someClass, I get this message
Cannot call method 'push' of undefined
Could someone explain why ?
You should either send positions as a parameter or declare it in a scope accesible for addHistory. You should not declare it without the var keyword as that is considered a bad practice.
Try my first suggestion as that one is the only one I can help you with without knowing the structure of your other js code.
I am trying to use .append() with if statements, I have a lot of them maybe 10. What I'm trying to do is add to a div if something happens. if A is less then 5 I want to add to the div, so on and so on. .append() works good for me if I put all of the things I want to add in one .append(). But if I try to do it separately it will not work for me. I don't know what I will be adding a head of time, it depends on user data so I can't add everything I want in one .append(). My code is long so I have put a fiddle below. I know i may have other issues with this code but, just asking about .append() or a way to add to my div like i want
if(k3a<5) {
msg3="need to work on q3"
var c = $('<p>'+msg3+'</p>')
$('#output1').append(c);
$output1.text(msg3);
}
if(k4a<5) {
msg4="need to work on q4"
var e = $('<p>'+msg4+'</p>')
$('#output1').append(e);
$output1.text(msg4);
}
if(k5a<5) {
msg5="need to work on q5"
var e = $('<p>'+msg5+'</p>')
$('#output1').append(e);
$output1.text(msg5);
}
I know I can do something like below, but I need to add them one by one if the condition is meet, not at once.
if (k1 < 10) {
msg1 = "This will not space like a want.<br/>";
msg2 = "I don know why not.<br/>";
msg3 = "How come.<br/>";
var e = $('<p>'+msg1+'</p>'+'<p>'+msg2+'</p>'+'<p>'+msg3+'</p>');
$('#output1').append(e);
}
http://jsfiddle.net/G24aQ/21/
This looks like you don't understand what the code is doing; (assuming $output1 is $('#output1)) current code is (just one part)
msg4="need to work on q4"; // set global variable `msg4`
var e = $('<p>'+msg4+'</p>'); // set local variable `e`
$('#output1').append(e); // append html to element
$output1.text(msg4); // re-set content of element as text
You most likely want just
var msg4="need to work on q4", // set local variable `msg4`
e = $('<p>'+msg4+'</p>'); // set local variable `e`
$('#output1').append(e); // append html to element
What is $output1? That should be a variable, but you don't assign anything to it. Also, there is no need to use $() to put HTML into just for the sake of assigning it to your c or e variable. $() gets content. You just need to make a String, like:
var c = '<p>'+msg3+'</p>';
although I would have var e, c above all your code, if I was going to reuse it, so you don't have to rewrite var, and I wouldn't store msg3 in a variable at all. My code would contain, something like:
var out1 = $('#output1');
if(k3a<5)out1.append('<p>need to work on q3</p>');
if(k4a<5)out1.append('<p>need to work on q4</p>');
if(k5a<5)out1.append('<p>need to work on q5</p>');
Your code is different on you jsFiddle page. For instance, k3a does not exist. Don't redefine var total in your code, either. There may be more problems with your code, but this should put you on the right path.
you may find it easier to define a small function to output the messages. something like
function showMessage( strMsg, targetID ) {
$('#'+targetID).empty().append("<p>" + strMsg + "</p>");
}
and call it using
showMessage( "message one", "output" );
showMessage( "message two", "output1" );
This way when you decide you want to display them in another fashion, you only have to change it in one place.
I need to pass a jQuery object in to a workaround for an eval. The issue is that i need access to a jQuery object that is out side the eval area but i can't see to pass it in. here is what i have.
var jObj = $(selector);
var myCode = "var jObj="+jObj+"; var i="+i+"; "+shape.mouseover.onEnd.replace("\u0027","'");
var myFucn = new Function(myCode);
myFucn();
the oject I'm getting the string out of is
shape.mouseover.onEnd.replace("\u0027","'");
is working and what I'm passing in that string is
open_info(jObj,i)
Which is what i have to fire. The deal is that the code is run thru YUI compressor so the jObj var becomes something else so i need to pass that in. Right now i get an error where it thinks it should have and ending ] which is not right. I is working it seems, just not the jObj var.
EDIT
there are many way to get where i need to be that are close but not quite like
How to pass parameters in eval in an object form?
shape.mouseover.onEnd = "open_info(jObj,i)";
/*
* this is coming in and must be as it is, don't say it's wrong please
* it's not able to be done anyother way!
*/
//lets process the string and pull in the vars
/* BEOFRE YUI COMPRESSOR CHANGES THINGS and works!!!
var jObj = $(selector);
var i = 1;
var myCode = shape.style.events.mouseover.onEnd.replace("\u0027","'");
var myFucn = new Function(myCode);
myFucn();
*/
// AFTER note it can be random as i change code so it fails cause
// var jObj is now var r and var i is now var e
var r = $(selector);
var e = 1;
var p= shape.style.events.mouseover.onEnd.replace("\u0027","'");
var f= new Function(p);
f();
Now it works before the compression.. After is not due to the change. Hope tha tclears it up some
I might be going down the wrong tracks and be confused here..
But isnt this what your trying to do?
Send myFucn the correct object and what ever i is
myFucn($(selector),10);
function myFucn(jObj,i)
{
shape.mouseover.onEnd.replace("\u0027","'");
}
I still don't understand why this question got 2 down votes, but well it's solved and works great. The trick is to do the same manipulation of the dom state. It's really simple once it is placed out.
//so this is what the object is parsed out to from the json string
//since you can't just pass a function stright that way any how
shape.mouseover.onEnd = "open_info(jObj,i)";
//this is what will take that string and process it
//note jObj is what is in the orgain code but it changes to
// var r or something else that is shorter after going thru YUI compressor
// Which is why we can't just use open_info(jObj,i) and it work..
// ie: it's not an issue with scoope but an issues with var names being shortened
(function(){
//this is the trick on passing them so YUI doesn't get them
//use a string and YUI skips it so we directly create the
//needed oject in the window namespace
window['jObj']=jObj; window['i']=i;
var p= shape.mouseover.onEnd;
var f= new Function(p);
f();
})();
That is it.. I put it in a click or hover event so it's kin to an onClick.
/* EXMAPLE OUTPUT AFTER YUI COMPRESSION
//Note after the YUI compressor get ahold of that
//processing code above it'll look like
*/
function(){window.jObj=n,window.i=t;var u=i.mouseover.onEnd,r=new Function(u);r()}();
So the way that works is, I needed to fix the issue of the var jObj being renamed. So I simply made a sting for the name and let the compressed the var name fill the name of the object I need for the processed code string. Don’t know why I didn’t see it before and I would have saved my rep value :-\ .. oh well. May be a way to shorten this but I'm leaving it for now.
Edit
I recant the edit it was working. :) Very well.. Left wondering what any other ways there would be to make it do the same thing.