I have a very simple Javascript function that hits a MS SQL server and returns some records back. There is a cell that i want to only display in the top table row when it is unique.
I believe my problem is var hoisting because the variable that i assign within the while loop does not work because the value is not carried from the last records to compare. Here is the code
function searchIndex()
{
var termcounter = "";
flyoutHTML = '<table>';
var adOpenDynamic = 2
var adLockOptimistic = 3
var conn = new ActiveXObject("ADODB.Connection");
var connectionstring = "Provider=SQLOLEDB;Server=XXXXXXXX;INTEGRATED SECURITY=SSPI;DATABASE=YYYYYYYYYY;"
conn.Open(connectionstring)
var rs = new ActiveXObject("ADODB.Recordset")
rs.Open("SELECT field1, field2, field4, field4, field5 FROM dbo.table;", conn)
if (rs.eof)
{
flyoutHTML += '<tr><td align="center">No Records Found!</td></tr>';
}
else
{
while(!rs.eof)
{
if (termcounter != rs(0))
{
var termcounter = rs(0);
flyoutHTML += '<tr>';
flyoutHTML += '<td colspan="3">' + rs(0) + '</td>';
flyoutHTML += '</tr>';
}
flyoutHTML += '<tr>';
flyoutHTML += '<td>' + rs(1) + '</td><td>' + rs(2) + '</td><td>' + rs(3) + '</td>';
flyoutHTML += '</tr>';
rs.movenext
}
rs.close
conn.close
flyoutHTML += '</table>';
}
Take the "var" off the var termcounter = rs(0);
You're probably right about hoisting--JavaScript doesn't have block scope, so both times you declare termcounter it's in the same scope. This is a very common mistake, since JavaScript looks like C-based languages which have block scope.
Declaring a var in a conditional or looping block is equivalent to declaring it at the beginning of the function that block is in, scope-wise.
You'll lose less hair if you always place your var declarations at the top of functions--never in conditional or loop blocks. See Crockford. You can use JSLint to warn you. (Oh, by the way, you're missing a ton of semicolons--JSLint will hurt your feelings.)
So why are you redeclaring it? Drop the second "var" and just do the assignment.
The Microsoft stuff is alien to me, but I find the rs(0) syntax baffling. Is rs an object? Or is there some kind of magic that makes it into a function as well (you never know with JS)? I did some Googling and I wonder if you need to be using rs.fields(0) or rs.fields(0).name or rs.fields(0).value or something.
You have this:
var termcounter = rs(0);
I don't think you want to be redeclaring it here - remove the var:
termcounter = rs(0);
AKA How can one de-reference JavaScript variables when enclosing an outer scope?
Related
I've been watching a javascript tutorial to refresh my knowledge of it.
I just need some guidance on why he decided to use this code "style"
Basically, there's a variable named result with an empty string ("") and I'm not so sure why he used (result += ...) when he can also use (result = ...) where it showed the same output when I tried.
function mySentence(myName, myVerb){
var result = "";
result += myName + " " + myVerb + " towards the tree.";
return result;
}
console.log(mySentence("Dale", "walked"));
vs
function mySentence(myName, myVerb){
var result = "";
result = myName + " " + myVerb + " towards the tree.";
return result;
}
console.log(mySentence("Dale", "walked"));
Link of video: https://youtu.be/PkZNo7MFNFg
36:28:00 : Word Blanks
The only reason I can think of for having it there is that the author wanted to be able to rearrange a series of statements after the initial declaration that all used += without having to worry about which was the first statement originally. E.g.:
var result = "";
result += "something";
result += "another thing";
result += "yet another thing";
...where they may want later to swap things around:
var result = "";
result += "another thing";
result += "something";
result += "yet another thing";
The variable result is set to "", an empty string in the beginning.
When you do result= the variable will be replaced with the new value.
But when you do result+= the variable does not get replaced. It will be added with the value that already exists.
For example, in your code, if the variable is set to some value in the beginning, like result="The answer is: ", then the two styles would yield different results. The result= style will return Dale walked towards the tree.. And the result+= will return The answer is: Dale walked towards the tree.
I have a loop that will declare a new variable each time. I want to write my results to a new window and I would like every string declared to print with breaks.
I did try making combining all vars together with '+' signs (using [i] to get the number of occurrences) but document.write printed it because it was a string.
Does anyone know what I can do? I'm sure there must be a few ways but I've been stuck on this for a while.
window['question'+i] = "some stuff";
var myWindow = window.open("", "Questions", "width=500,height=600");
myWindow.document.write(
question0 + ("<br>") +
question1 + ("<br>") +
question2 + ("<br>") +
question3 + ("<br>")
...
)
I recommend to not use different variables. Array's are made for these kind of things and provide functions to do this a lot easier. See this snippet below how to store the texts from a loop in an array and easy print it splitted by a <br> using the join function.
var values = new Array();
for (var i = 0; i < 10; i++) {
values.push("<span>value " + i + "</span>");
}
document.getElementById('result').innerHTML = values.join("<br>");
//If you really want to use document.write()
//document.write(values.join("<br>"));
<div id="result"></div>
sorry I just started with javascrippt and html and I am having trouble finding out what the unexpected identifier is?
here is my function
function fillSearchPlayer(data){
$('#searchPlayers tbody').html('');
for (var i = data.length - 1; i >= 0; i--) {
var p = data[i]
var item = '<tr><td>'p.firstname + ' ' + p.lastname'</td><td>'p.job'</td><td><button class="cbtn" onclick="requestPlayer("'+ p.identifier + '")">More</button></td></tr>'
$('#searchPlayers tbody').append('item');
}
}
maybe you guys could help me, it's saying its coming from the line that starts with "var item"
'<tr><td>'p.firstname look like you missed a plus sign over there. The other thing is .append('item'); - you probably intented to do .append(item);.
As the guys mentioned in the direct comments above you should try to use some templating engine instead of constructing the strings the way you did it.
I would recommend you to read these pieces:
Handlebars - simple and convenient template engine in JavaScript - give it a try!
Template strings in ES2016 - a cleaner way to do what you did with manual string concatenation
There are several errors. String concatenation works with +, and you're missing a semicolon.
Try:
function fillSearchPlayer(data) {
$('#searchPlayers tbody').html('');
for (var i = data.length - 1; i >= 0; i--) {
var p = data[i];
var item = '<tr><td>' + p.firstname + ' ' + p.lastname + '</td><td>' + p.job + '</td><td><button class="cbtn" onclick="requestPlayer("'+ p.identifier + '")">More</button></td></tr>';
$('#searchPlayers tbody').append('item');
}
}
The var item = ... item mixes variable and literal definitions without the real concatenation going on. Just put a + between each varying element to achieve your goal.
You need to enclose the concatenation operator around the p.job variable.
Your assignment should look like this...
var item = '<tr><td>'+p.firstname + ' ' + p.lastname+'</td><td>'+p.job+'</td><td><button class="cbtn" onclick=requestPlayer('+ p.identifier + ')>More</button></td></tr>'
Is there a way to make a variable using an array value? For ex.
//Define all Notes in Sharps and Flats
var noteSharp = ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"];
var noteFlat = ["A","Bb","B","C","Db","D","Eb","E","F","Gb","G","Ab"];
//Make all Major Scales
for (var x=0; x<12; x++){
var noteSharp[x] + "Sharp" = noteSharp[x] + noteSharp[x+2] + noteSharp[x+4] + noteSharp[x+5] + noteSharp[x+7] + noteSharp[x+9] + noteSharp[x+11];
var noteFlat[x] + "Flat" = noteFlat[x] + noteFlat[x+2] + noteFlat[x+4] + noteFlat[x+5] + noteFlat[x+7] + noteFlat[x+9] + noteFlat[x+11];
}
If I do a console.log(CSharp) it says that CSharp is not defined.
In this example I am trying to define a total of 24 variables. Some variable name examples im expecting to get are ASharp , A#Sharp , BbFlat , DFlat. The CSharp and CFlat variable should both be "CDEFGAB"
If this is not possible is it because variables have to be defined before the javascript file is read by the browser at run-time for memory leak security.
If you want to make a global variable, attach it to window
window[variableNameHere] = itsValue;
In your case:
window[noteSharp[x] + "Sharp"] = noteSharp[x] + ...
But it's not good to pollute the global namespace. How about putting it in another namespace:
var sharps = {};
var flats = {};
sharps[noteSharp[x] + "Sharp"] = noteSharp[x]...
flats[noteFlat[x] + "Sharp"] = noteFlat[x]...
//access them
sharps.ASharp;
I quite can't figure out what your code does, but this solution should point you to the right direction.
try the following code
var noteSharp = ["A","B","C"];
for(i in noteSharp) {
window[noteSharp[i]] = 'value of '+noteSharp[i];
}
alert(A)
alert(B)
alert(C)
This is exactly what you want.
and rewriting it for your code
//Define all Notes in Sharps and Flats
var noteSharp = ["A","A#","B","C","C#","D","D#","E","F","F#","G","G#"];
var noteFlat = ["A","Bb","B","C","Db","D","Eb","E","F","Gb","G","Ab"];
//Make all Major Scales
for (var x=0; x<12; x++){
window[noteSharp[x] + "Sharp"] = noteSharp[x] + noteSharp[x+2] + noteSharp[x+4] + noteSharp[x+5] + noteSharp[x+7] + noteSharp[x+9] + noteSharp[x+11];
window[noteFlat[x] + "Flat"] = noteFlat[x] + noteFlat[x+2] + noteFlat[x+4] + noteFlat[x+5] + noteFlat[x+7] + noteFlat[x+9] + noteFlat[x+11];
}
alert(ASharp);
alert(AFlat);
As per my knowledge, in JavaScript there are 2 ways by which you can create dynamic variables:
eval Function
window object
eval:
var times = 1;
eval("var sum" + times + "=10;");
alert(sum1);
window object:
var times = 1;
window["sum" + times] = 10;
alert(window["sum1"]);
Change the end of your code to look like this:
for (var x=0; x<12; x++){
self[noteSharp[x] + "Sharp"] = noteSharp[x] + noteSharp[x+2] + noteSharp[x+4] + noteSharp[x+5] + noteSharp[x+7] + noteSharp[x+9] + noteSharp[x+11];
self[noteFlat[x] + "Flat"] = noteFlat[x] + noteFlat[x+2] + noteFlat[x+4] + noteFlat[x+5] + noteFlat[x+7] + noteFlat[x+9] + noteFlat[x+11];
}
As a result, you will have global variables with variable names like you want, such as CSharp, which would equal "CDEFGAB"--however, complicated variable names like A#Sharp cannot be written outright as variables, but can still be accessed by using subscript notation, like this self["A#Sharp"] (or window["A#Sharp"] in most cases, although it has traditionally been better style to use self rather than window to refer to the most local window object connected with a script instance).
The other answer looks like it has been finished out by the time I finished typing mine, and it looks good, too.
If this is not possible
It isn't for local variables without the use of eval.
is it because variables have to be defined before the javascript file is read by the browser at run-time for memory leak security.
No. It's not possible because ECMA-262 specifies that the only way to declare a variable is by a variable declaration statement, which is of the form:
var *identifier* [optional initialiser]
where identifier is a valid identifier, which can't be an expression like:
var 'foo' + 'bar';
The rest of the question has been covered in other answers.
I create WordPress ShortCode tab and write this code to collect the shortcode
jQuery('body').on('click', '#tapSubmit',function(){
var shortcode = '[tapWrap]';
jQuery('.tapForm').each(function(){
var title = jQuery('.Title').val(),
content = jQuery('.Content').val(),
shortcode += '[tap ';
if(title){shortcode += 'title="'+title+'"';}
shortcode += ']';
if(content){shortcode += ''+content+'';}
shortcode += '[/tap]';
});
shortcode += '[/tapWrap]';
tinyMCE.activeEditor.execCommand('mceInsertContent', false, shortcode);
});
and i get this error
Uncaught SyntaxError: Unexpected token if
and i try the code in http://jsfiddle.net/ and i got this error in the line which have this code
shortcode += '[tap ';
Expected an assignment or function call and instead saw an expression.
how to fix it ?
When you have
var title = jQuery('.Title').val(),
content = jQuery('.Content').val(),
shortcode += '[tap ';
you are defining new variables in that chain but shortcode is already defined, so you are creating a new variable in this scope. Being a new variable you cannot use +=. Anyway I think you just want to use this:
var title = jQuery('.Title').val(),
content = jQuery('.Content').val(); // changed the last comma with semicolon
shortcode += '[tap ';
To read:
About scope
About var
Problem is coming in here
var title = jQuery('.Title').val(),
content = jQuery('.Content').val(),
shortcode += '[tap ';
shortcode is already a var defined above. You can't use += in a var expression
Just change this to
var title = jQuery('.Title').val(),
content = jQuery('.Content').val(); // note the semicolon here
shortcode += '[tap ';
I think you're also going to run into some nesting issue. Instead of calling jQuery('.Content').val() for each iteration of the loop, I think you're looking for something more like $(this).find('.Content').val() or $('.Content', this). This will find the relevant .Content input in the scope of a given .tapForm.
I'm thinking something like this, but it's just an idea
jQuery('body').on('click', '#tapSubmit', function(){
function title(context) {
var value = jQuery(".Title", context).val();
return value ? 'title="' + value + '"' : '';
}
function content(context) {
var value = jQuery(".Content", context).val();
return value || '';
}
var taps = jQuery('.tapForm').map(function(){
return '[tap ' + title(this) + ']' + content(this) + '[/tap]';
}).join();
tinyMCE.activeEditor.execCommand('mceInsertContent', false, '[tapWrap]' + taps + '[/tapWrap]');
});