Scroll text method, works with arrays, not with string - javascript

Basic javascript function to scroll the text in the title bar, I'm calling it via a setInterval("rotateTitle()", 1000); call after onload.
This function, which takes text from an array, works perfectly.
var counter = 0;
function rotateTitle() {
var baseTitle = "www.mydomain.com - now with JavaScript";
var titleArray = new Array("a","b","c","d","e","f","g");
var titleString = "abcdefg";
var scrollText = getNextScroll(titleArray);
window.document.title=baseTitle.concat(scrollText);
}
function getNextScroll(inValue) {
var str = " ";
for (var i = 0; i<inValue.length; i++) {
var index = i+counter;
if (i+counter >= inValue.length) {
index -= inValue.length;
}
str += inValue[index];
}
counter++;
if (counter > inValue.length) {
counter = 0;
}
return str;
}
Edited here for clarity:
Now if I rewrite the function to scroll a string (not an array), I change the line
str += inValue[index];
to
str.concat(inValue.charAt(index));
and change getNextScroll(titleArray) to getNextScroll(titleString), the script seems to execute, but only the baseTitle is shown.
Why is this wrong?

You have to assign the result of str.concat back to str; otherwise you'll miss the concat operation. Instead of charAt you must use inValue[index].
Do like this:
str = str.concat(inValue[index]);
Here's a JS Bin: http://jsbin.com/aCEBAju/2/
In your original code you have this:
str.concat(inValue.charAt(index));
debugging in Chrome it barks: array has no method charAt.

The solution to the problem is that str.concat(inValue.charAt(index)); must change to str = str.concat(inValue.charAt(index)); or str += inValue.charAt(index);. Str must be assigned the new value. This is the entire working function:
var counter = 0;
function rotateTitle() {
var baseTitle = "www.berrmal.com - now with JavaScript";
var titleArray = new Array("b","e","r","r","m","a","l"); //no longer necessary
var titleString = "berrmal: bigger, longer, uncut";
var scrollText = getNextScroll(titleString);
window.document.title=baseTitle.concat(scrollText);
}
function getNextScroll(inString) {
var str = " ";
for (var i = 0; i<inString.length; i++) {
var index = i+counter;
if (i+counter >= inString.length) {
index -= inString.length;
}
str += inString.charAt(index);
}
counter++;
if (counter > inString.length) {
counter = 0;
}
return str;
}
I figured out the answer to the problem based on Leniel Macaferi's answer, though his posted code is not correct. This method runs successfully in Firefox 23.0 with no error in the console.

Related

Javascript: How do I prevent reappending a string to multiple queries?

In this case, lets take YouTube as an example:
The below code, I believe, is scripted to append a string to search_query=, but it gets appended to &page= as well.
if (oSession.uriContains("www.youtube.com/results?search_query="))
{
var str = oSession.fullUrl;
var sAppend = "+test1+test2+test3";
if (oSession.fullUrl.indexOf(sAppend, str.length - sAppend.length) < 0)
{
oSession.fullUrl = str + sAppend;
}
}
Thank you in advance.
You can try this code:
if (oSession.uriContains("www.youtube.com/results?search_query="))
{
var str = oSession.fullUrl;
var sAppend = "+test1+test2+test3";
if (!oSession.uriContains(sAppend))
{
oSession.fullUrl = str + sAppend;
}
}

Why does the second loop execute before the first loop?

so this might be a repost, but I don't really know how to explain my second problem.
I have this code:
var paragraphsArray = new Array();
function setParagraphs(offSet)
{
offSet = offSet * 12;
for (var i = 1; i < 13; i++)
{
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph)
{
//clear paragraph1 div
document.getElementById("paragraph1").innerHTML = "";
//create p elements
var pElem = document.createElement("p");
pElem.setAttribute("id", "pEntry"+i);
document.getElementById("paragraph1").appendChild(pElem);
$("pEntry"+i).text(paragraph);
});
}
}
edited: I removed the second loop because it was unnecessary, for some reason the p element creation starts on i==13, which is the extra one that shouldn't even do.
for some reason the second loop executes first, so the paragraphArray is printed out as undefined. I managed to "fix" the order with the setTimeout() function, BUT I still get the undefined message, instead of the value. In the first loop the value is printed out fine, but if I try and put it in a $("p").text(paragraph); I also get undefined. So although I was right about the execution order, the problem is still there!
Because first is in ajax call, declare paragraphsArray in global space and use a callback function, try this:
*Updated
var paragraphsArray = [];
function setParagraphs(offSet) {
offSet = offSet * 12;
var request = 0;
for (var i = 1; i < 13; i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', {idd: parX}).done(function(paragraph) {
request++;
paragraphsArray[request] = paragraph;
console.log(paragraphsArray[request]);
if (request === 12) {
alert('first');
callback();
}
});
}
}
function callback() {
for (var i = 1; i < 13; i++) {
console.log(paragraphsArray[i]);
}
alert('second');
}
Run the second loop inside of the first loop.
function setParagraphs (offSet) {
//paragraphs
var testing = 0;
var paragraphsArray = new Array();
offSet = offSet * 12;
for (var i=1;i<13;i++) {
var parX = i + offSet;
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
for (var i=1;i<13;i++) {
console.log(paragraphsArray[i]);
alert('second');
}
});
}
}
$.get is async function. 1st cycle will just send requests and wouldn't wait for response, so 2nd cycle will start right after first, without getting response of $.get function. Thats why console.log(paragraphsArray[i]); in 2nd cycle shows undefined.
You only can handle response in first cylce.
You can use $("p").text(paragraph); only like in this example:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
});
You can't use variables, which are assigned in function
function(paragraph) {
paragraphsArray[i] = paragraph;
console.log(paragraphsArray[i]);
alert('first');
$("p").text(paragraph);
}
outside of this function.
To achieve what you want you have to use another approach.
HTML will be:
<div id='paragraphs'>
</div>
JS code:
var testASd = $.get('php/entryParagraphs.php', { idd: parX }).done(function(paragraph) {
$("#results").append("<p>"+paragraph+"</p>")
});
You should use ~ this code. I just show you approach.

Merging arrays in JavaScript not working

When I try var a = ar_url2.concat(ar_desc2); to join my arrays into one it returns null. I'm sure it's trivial but I spent a few hours stuck on this now and an explanation as why this is happening would be great. In my code bellow I tried while(ar_url2.length)a.push(ar_url2.shift()); and it returns same null...
function agregar() {
var i = 0,
textarea;
var ar_desc = [];
while (textarea = document.getElementsByTagName('textarea')[i++]) {
if (textarea.id.match(/^desc_([0-9]+)$/)) {
ar_desc.push(textarea.id);
}
}
var desc_count_demo = document.getElementById('desc_count').value;
var desc_count = desc_count_demo - 1;
i = 0;
var ar_desc2 = [];
var campo = null;
while (i <= desc_count) {
campo = document.getElementById(ar_desc[i]).value;
ar_desc2[ar_desc[i]] = campo;
i++;
}
i = 0;
var input;
var ar_url = [];
while (input = document.getElementsByTagName('input')[i++]) {
if (input.id.match(/^url_([0-9]+)$/)) {
ar_url.push(input.id);
}
}
var url_count_demo2 = document.getElementById('url_count').value;
var url_count2 = url_count_demo2 - 1;
i = 0;
var ar_url2 = [];
while (i <= url_count2) {
campo = document.getElementById(ar_url[i]).value;
ar_url2[ar_url[i]] = campo;
i++;
}
// var a = Array.prototype.concat.call(ar_url2, ar_desc2);
while (ar_url2.length) a.push(ar_url2.shift());
function url(data) {
var ret = [];
for (var d in data)
ret.push(encodeURIComponent(d) + "=" + encodeURIComponent(data[d]));
return ret.join("&");
}
window.open('alta1.php?'+url(a));
}
EDIT: If I pass to function url(ar_url2) or url(ar_desc2) the returned values in the URL are
http://localhost/proj1/alta1.php?url_0=inpit&url_1=input
and
http://localhost/proj1/alta1.php?desc_0=input&desc_1=input
But still cannot merge both into one...
One thing I see is your ar_url Array is filled by:
while(input=document.getElementsByTagName('input')[i++]){
if(input.id.match(/^url_([0-9]+)$/)){
ar_url.push(input.id);
}
}
Since you the putting the whole id in the array, it will be filled with things like: 'url_0', 'url_1', 'url_2', etc...
Later you do:
ar_url2[ar_url[i]] = campo;
When you index into ar_url, you get out the 'url_XXX' strings. That means you are setting the 'url_XXX' properties on ar_url2 instead of filling in the elements of the array.
Try changing your second loop to:
while(input=document.getElementsByTagName('input')[i++]){
var result;
if(result = input.id.match(/^url_([0-9]+)$/)){
ar_url.push(+result[1]);
}
}
To use the value captured in the ([0-9]+) portion of the RegExp instead of the entire 'url_XXX' string.

Javascript array results returning undefined

I have been working on a simple math game and am having problems getting the overall answer results to return after the end of the game.
Here is what my return function looks like
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
Here is the full script
Pretty much need debugging help. I new to this so I'm guessing there is a ton that's off, but as long as I can get the results fed back I should be fine.
You are not passing the value of x in many placess
$(document).ready(function () {
//declare arrays and variables for use below
var pNum1 = [];
var pNum2 = [];
var pNumAns = [];
var pNumGuess = [];
var pNumStore = [];
var pNumCarry = 0;
var pNumTrack = 0;
var pNumMessageRight = ['Awesome Job!', 'Correct!', 'Great Job!'];
var pNumMessageWrong = ['Oh No! That Was Wrong!', 'Incorrect!', 'That\'s Wrong'];
$(".Play").click(function () {
$("#popup").attr("class", "on");
pNumTrack = 0;
pNumGen(pNumTrack);
});
$(".pNumSubmit").click(function () {
pNumCalc(pNumTrack-1);
});
$(".pNumNext").click(function () {
pNumGen(pNumTrack);
});
function pNumGen(x) {
pNum1[x] = (Math.round(Math.random() * 51));
pNum2[x] = (Math.round(Math.random() * 51));
pNumAns[x] = pNum1[x] + pNum2[x];
$(".pNum1").html(pNum1[x]);
$(".pNum2").html(pNum2[x]);
$(".pNumGuess").val("");
$(".pNum1").html(pNumTrack[x]);
if (pNumTrack == 2) {
$(".pNumNext").html("");
$(".pNumSubmit").html("Close");
pShowResults();
}
pNumTrack++;
}
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
function pShowResults() {
var pNumResults = document.getElementById("results");
for (var i = 0; i < pNumGuess.length; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
});
Demo: Fiddle
There is a function called pNumCalc in your code which you have set to take in an argument, but you never pass one in. You use the argument to store the results in the pNumGuess array, but since the argument is never passed in, the guesses are never stored, and you end up with undefined as the answers the user gave.
Updated fiddle: http://jsfiddle.net/dwdX9/2/. Not sure how close this is to what you actually want though, but hopefully it gets you on the right track.
Because StackOverflow wants code to to be included when JSFiddle is...:
pNumCalc(pNumTrack)
You forget to define array before use it.
function pShowResults() {
var pNumStore = new Array();
var pNumResults = document.getElementById("results");
for (var i = 0; i <= 10; i++) {
pNumStore.push(pNumGuess[i]);
var pNumTable = document.createElement("div");
pNumTable.innerHTML = (pNumGuess[i]);
pNumResults.appendChild(pNumTable);
}
}
I must suggest you should use jquery instead.
After visiting your Fiddle seems like there are many problems with the code. and also your question is unclear.
for e.g.
$(".pNumSubmit").click(function () {
//why x value not passed?
pNumCalc();
});
function pNumCalc(x) {
pNumGuess[x] = $(".pNumGuess").val();
if (pNumGuess[x] == pNumAns[x]) {
$(".message").html(pNumMessageRight[Math.floor(Math.random() * pNumMessageRight.length)]);
$(".pNumNext").html("Next Question >")
} else {
$(".message").html(pNumMessageWrong[Math.floor(Math.random() * pNumMessageWrong.length)]);
$(".pNumNext").html("Maybe The Next Question >")
}
}
Please clear which array is returning undefined so that others can help you.

Overriding javascript built in to 3rd party control (infragistics UltraWebGrid)

I am using an old version of UltraWebGrid by Infragistics and need to replace some of the built in javascript. The compiled js looks like its adding a bunch of functions to an object type as an api of sorts. formatted like:
var igtbl_ptsBand = ["functionname1",function(){...},"functionname2",function(){...},...
and so on. How would I override this?
Basically the control is adding html to the page in a way that is not compatible with newer browsers and the javascript code that does this just needs a little tweak. I found the code... I just need to change it.
The code can be found here
I added an answer to dump code examples in and whatnot. I will not select this answer
Similar SO question
The array you mentioned seems to be a function table of sorts:
var igtbl_ptsBand = ["func1", function() { }, "func2", function() { } ]
I would recommend using chaining instead of just an override. With chaining you can inject your own code, but still call the original function. Let's say you want to replace "func2" and chain. You could do something like this:
var origFunc, findex, ix;
if (igtbl_ptsBand.indexOf) {
// indexOf is supported, use it
findex = igtbl_ptsBand.indexOf("func2") + 1;
} else {
// Crippled browser such as IE, no indexOf, use loop
findex = -1;
for (ix = 0; ix < igtbl_ptsBand.length; ix += 2) {
if (igtbl_ptsBand[ix] === "func2") {
findex = ix + 1;
break;
}
}
}
if (findex >= 0) {
// Found it, chain
origFunc = igtbl_ptsBand[findex];
igtbl_ptsBand[findex] = function() {
// Your new pre-code here
// Call original func (chain)
origFunc();
// Your new post-code here
};
}
origFunc may have arguments, of course, and you may want to use the JavaScript call() function to set the "this pointer" to something specific, e.g.:
origFunc.call(customThis, arg1, arg2...);
If the arguments are in an array, you can use apply() instead of call().
I would not recommend doing this. You should always try to work with a third party library, not against it. That being said, this should work:
igtbl_ptsBand[igtbl_ptsBand.indexOf("functionYouWantToOverwrite") + 1] = function () {
// your new stuff...
};
Ok here is what I am doing. I will update this with my progress.
This fixes my problem. It turns out I had to apply the functionarray to all child objects of the parent "rows". To do this I added the code in my "Fix Rows" function. I split it up because i am running accross other browser JS error which I am fixing in this js file.
Here is the js file that I added to my .net page like so...
</form>
<script type="text/javascript" src="../../scripts/BrowserCompat.js"></script>
</body>
</html>
.
Brows_FixUltraWebGrid();
function Brows_FixUltraWebGrid() {
FixRows();
}
function FixRows() {
FixGridRows_render();
for (var i = 0; i < igtbl_ptsRows.length; i += 2)
igtbl_Rows.prototype[igtbl_ptsRows[i]] = igtbl_ptsRows[i + 1];
}
function FixGridRows_render() {
var origFunc, findex, ix;
if (igtbl_ptsRows.indexOf) {
// indexOf is supported, use it
findex = igtbl_ptsRows.indexOf("render") + 1;
} else {
// Crippled browser such as IE, no indexOf, use loop
findex = -1;
for (ix = 0; ix < igtbl_ptsRows.length; ix += 2) {
if (igtbl_ptsRows[ix] === "render") {
findex = ix + 1;
break;
}
}
}
if (findex >= 0) {
// Found it, chain
origFunc = igtbl_ptsRows[findex];
igtbl_ptsRows[findex] = function() {
// Your new pre-code here
// Call original func (chain)
//origFunc();
// Your new post-code here
var strTransform = this.applyXslToNode(this.Node);
if (strTransform) {
var anId = (this.AddNewRow ? this.AddNewRow.Id : null);
//new logic to include tbody if it is not there
var tadd1 = '';
var tadd2 = '';
if (!(/\<tbody\>/.test(strTransform))) {
tadd1 = '<tbody>';
tadd2 = '</tbody>';
}
this.Grid._innerObj.innerHTML =
"<table style=\"table-layout:fixed;\">" + tadd1 + strTransform + tadd2 + "</table>";
//old line
//this.Grid._innerObj.innerHTML = "<table style=\"table-layout:fixed;\">" + strTransform + "</table>";
var tbl = this.Element.parentNode;
igtbl_replaceChild(tbl, this.Grid._innerObj.firstChild.firstChild, this.Element);
igtbl_fixDOEXml();
var _b = this.Band;
var headerDiv = igtbl_getElementById(this.Grid.Id + "_hdiv");
var footerDiv = igtbl_getElementById(this.Grid.Id + "_fdiv");
if (this.AddNewRow) {
if (_b.Index > 0 || _b.AddNewRowView == 1 && !headerDiv || _b.AddNewRowView == 2 && !footerDiv) {
var anr = this.AddNewRow.Element;
anr.parentNode.removeChild(anr);
if (_b.AddNewRowView == 1 && tbl.tBodies[0].rows.length > 0)
tbl.tBodies[0].insertBefore(anr, tbl.tBodies[0].rows[0]);
else
tbl.tBodies[0].appendChild(anr);
}
this.AddNewRow.Element = igtbl_getElementById(anId);
this.AddNewRow.Element.Object = this.AddNewRow;
}
this.Element = tbl.tBodies[0];
this.Element.Object = this;
this._setupFilterRow();
for (var i = 0; i < this.Band.Columns.length; i++) {
var column = this.Band.Columns[i];
if (column.Selected && column.hasCells()) {
var col = this.getColumn(i);
if (col)
igtbl_selColRI(this.Grid.Id, col, this.Band.Index, i);
}
}
if (this.ParentRow) {
this.ParentRow.ChildRowsCount = this.length;
this.ParentRow.VisChildRowsCount = this.length;
}
}
console.log('overridden row render function executed');
};
}
}

Categories