Javascript text file reader doesnt work the first time - javascript

I got a webpage with some homemade search engine which is supposed to look for some data in a server-side text file. I use JS to parse this file, it works well except for the very 1st time I use it... The culprit seems to be my fetchText() function which doesnt return anything the first time. Note that if I add a alert() inside the fetchText() it works correctly (see note in JS source code). I guess the IFRAME is not fully loaded or something. What can I do ?
Webpage code
<form style="margin-top:15px; margin-left:15px;width:200px;">
<input type="text" value="NGR_" id="srcTxtInput" style="margin-top:0px;margin-left:0px;width:100px;"/>
<input type="button" value="Go" onclick="SearchString('./Coordinates.txt')" />
</form>
<div id="searchResults" style="vertical-align:right;margin-top:25px;">
<select size="4" id="select_list" onchange="Selec_change();" ondblclick="Selec_change();" style="visibility: hidden; width:250px;margin-left:8px;" ></select>
<img id="closeImg" src="./close.png" height="15px" width="15px" style="opacity:0.5;visibility:hidden; margin-left:235px;margin-bottom:5px;margin-top:5px;vertical-align:top;" alt="Close results" title="Close results" onclick="HideSearch();" onmouseover="this.style.cursor='pointer';"/>
</div>
JS code
function SearchString(txtFile){
var slist = document.getElementById('select_list');
var str = trim(document.getElementById('srcTxtInput').value.toUpperCase());
if(str == "" ){
slist.options.length = 0; //empty list
HideSearch();
exit;
}
var txt = fetchText(txtFile);
//DO SOMETHING
}
function fetchText(txtFile) {
var d = document;
var txtFrame = d.getElementById('textReader');
txtFrame.src = txtFile;
**//Note that if I add *alert(txtFrame.src)* here the function works the 1st time**
var text = '';
if (txtFrame.contentDocument) {
var d = txtFrame.contentDocument;
text = d.getElementsByTagName( 'BODY')[ 0].innerHTML;
}
else if (txtFrame.contentWindow) {
var w = txtFrame.contentWindow;
text = w.document.body.innerHTML;
}
return text;
}

Since loading page content like that is an asynchronous operation, you can't expect the contents to be there immediately after setting the "src" attribute of your <iframe>. You'll have to put the code that searches through the text in a "load" event handler on the frame document.
That means you'll write something like:
fetchText(textFile, function(theText) {
// DO SOMETHING
});
and modify "fetchText()" to be more like this:
function fetchText(txtFile, whenLoaded) {
var d = document;
var txtFrame = d.getElementById('textReader');
txtFrame.onload = function() {
var text = '';
if (txtFrame.contentDocument) {
var d = txtFrame.contentDocument;
text = d.getElementsByTagName( 'BODY')[ 0].innerHTML;
}
else if (txtFrame.contentWindow) {
var w = txtFrame.contentWindow;
text = w.document.body.innerHTML;
}
whenLoaded(text);
};
txtFrame.src = txtFile;
}

Related

jQuery insert/remove text at specific position in input field/textarea

I am trying to do similar thing as YouTube has when you are embeding a video and you want to get a code. You can click on checkboxes or select size and it dynamically changes the value of input field.
Does somebody have idea how to do it?
I managed to write a code that is replacing the width correctly, but I dont know how to make a code that would add &scheme=XXX at the end of the link or remove it if user selects no color scheme.
This is the code for width,I dont think its best one, but works:
$("#width").on("change keyup", function(){
var width = $(this).val();
if (width){
$("#embed-text").val($("#embed-text").val().replace(/ (width\s*=\s*["'])[0-9]+(["'])/ig, ' width=\''+width+'\''));
}
});
Here is textarea which I am trying to change and inputs I'm using for it:
The ID is taken from PHP, in actual textarea that jQuery sees the ".$id." is actual number
<textarea class='clean' id='embed-text'><iframe src='http://my.url/embed/?r=".$id."' width='600' height='".$height."' frameborder='0' marginwidth='0' marginheight='0' allowtransparency='true'></iframe></textarea>
<div style='padding-right: 10px; display: inline-block;'>
Color scheme:
<select id='schemes' class='clean'>
<option value='-'>None</option>
<option value='xxx'>Xxx</option>
</select>
</div>
<div style='padding-right: 10px; display: inline-block;'>
Width: <input type='number' min='250' max='725' value='600' id='width' class='clean'>
</div>
When user does not select any scheme (or changes from XXX to None), I want link in textarea (iframes src) to be like this:
http://my.url/embed/?r=X
But when he selects any scheme, i would like it to look like this:
http://my.url/embed/?r=X&scheme=XXX
I actually have no idea how to do this. Tried googling for more than hour, but I don't know what the ID will be (to identify position where to add the string), thats PHP value and I cant pass it to external script file, so I tried to find if I can insert something at specific position (ie.: 15th character from start) with JS, but could not find anything.
Thanks.
I separate some functions in order to keep the code clean check this I think that is what you were looking for JsFiddle
var generateUrl = function(id,colorScheme) {
var baseUrl = "http://my.url/embed/?";
var url = baseUrl.concat("r="+id);
if (colorScheme != null && colorScheme != '')
url = url.concat("&scheme="+colorScheme);
return url;
};
var changeUrl = function(id, colorScheme) {
var url = generateUrl(id, colorScheme);
var srcPattern = "src='(.*?)'";
var embedText = $("#embed-text").val();
var newEmbedText = embedText.replace(new RegExp(srcPattern),"src='"+url+"'");
$("#embed-text").val(newEmbedText);
};
var changeWidth = function(newWidth) {
var widthPattern = "width='([0-9]*)'";
var embedText = $("#embed-text").val();
var newEmbedText = embedText.replace(new RegExp(widthPattern),"width='"+newWidth+"'");
$("#embed-text").val(newEmbedText);
};
var getURLParameter = function(url,parameterName) {
return decodeURIComponent((new RegExp('[?|&]' + parameterName + '=' + '([^&;]+?)(&|#|;|$)').exec(url)||[,""])[1].replace(/\+/g, '%20'))||null
};
var getId = function() {
var urlPattern = "src='(.*?)'";
var embedText = $("#embed-text").val();
var url = embedText.match(new RegExp(urlPattern))[1];
var id = getURLParameter(url, 'r');
return id;
};
$("#width").on("change keyup", function(){
var width = $(this).val();
var colorScheme = $(schemes).val();
changeWidth(width);
changeUrl(getId(),colorScheme);
});
And i removed the value '-' for the first option just leave it in blank.

Undefined function in javascript

I'm encountering an error that doesn't seem to make sense.
Chrome's console is saying Uncaught ReferenceError: clicked_server is not defined
I tried almost everything to fix it but the error itself doesn't make much sense
<script>
var selected_char = 'X';
function draw_list () {
// lets draw an x in all server in the array
var server_id = 0;
var draw_servers = new Array();
draw_servers = document.getElementById("server_arr").value.split(";");
foreach(draw_servers as server_id) {
document.getElementById("server("+server_id+")").innerHTML = selected_char;
}
// Update the counter and servers array
server_count_field.innerHTML = "Buy Server("+servers_array.length+")";
}
function clicked_server(server_id) {
var clicked = document.getElementById("server("+server_id+")").innerHTML;
if (clicked == selected_char) remove_server(server_id);
else add_server(server_id);
}
window.onload = draw_list();
function add_server(server_id) {
// select a server for purchase
var servers_array = document.getElementById("server_arr").value;
if(servers_array.length > 0) servers_array = servers_array + ";" + server;
else servers_array = server;
document.getElementById("server_arr").value = servers_array;
}
</script>
My HTML is working perfectly. Here it is
<form action="dobuyserver.php" method="POST">
<input type="hidden" name="server" id="server_arr"/>
<input type="submit" value="Buy Server(0)" id="server_count"/>
</form>
<td style="background-color:##000000;" onclick="clicked_server(9)"><font color="#FFFFFF">
<strong>
<span id="server(9)">
</span>
</strong>
</font></td>
As per my understanding you need to use
window.onload = draw_list;
instead of
window.onload = draw_list();
The reason for the stated error is that your javascript fails before getting to your function.
foreach(draw_servers as server_id) {
This line is invalid, so the js blows up and never goes beyond that line.
Replace window.onload = draw_list(); with window.onload = draw_list;
window.onload
Use window.onload = draw_list; instead of window.onload = draw_list();

Javascript no jquery - How do I add this function to existing javascript that is triggered by onload / onpaste?

This is an add-on to my previously answered question.
question 8423472
I have tried to implement a validate function to this wonderful code to no avail.
Looks like I need more hand holding here.
This script is a slightly modified version of the quite excellent answer I received from #Martin Jespersen.
The script takes a single column list of emails and breaks it up into textareas containing single row comma delimited lists of no more than 150 addresses. Nice.
Below works great but, I need to add a basic validation function.
<html>
<head>
<script language=javascript type='text/javascript'>
function onpaste(e) {
var t = this;
var cnt='0';
setTimeout(function(){
var list = document.getElementById('t');
var emails= t.value.split(/\s+/), ta;
while(emails.length) {
cnt++;
ta = document.createElement('textarea');
ta.value = emails.splice(0,150).join(',').replace(/,\s*$/,'');
document.body.appendChild(ta);
}
document.getElementById('button1').value=cnt;
},1);
}
window.onload = function() {
document.getElementById('t').onpaste = onpaste;
}
</script>
</head>
<BODY>
<p><textarea id="t" rows="10" cols="50" class="textarea"></textarea><br /></p><br />
There are <input type="button" id="button1" value="0"> textareas
<pre id="p" class="pre"></pre>
</body>
</html>
HOWEVER, the guy I made it for (actually #Martin made it) is not real meticulous about what he pastes into the textarea.
So, I am trying to implement a function that will reduce invalid emails / bad input.
I tried several ways including changing the onload event to a button in the page with onclick event.
I thought I was learning here but, I just can't wrap my brain around what I am doing wrong.
So, how can I insert this function, or just its' "validation" routine into one of the above functions?
function findEmailAddresses(StrObj) {
var separateEmailsBy = '\n';
var email = "<none>"; // if no match, use this
var emailsArray = StrObj.match(/([a-zA-Z0-9._-]+#[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi); // yeah could be better
if (emailsArray) {
email = "";
for (var i = 0; i < emailsArray.length; i++) {
if (i != 0) email += separateEmailsBy;
email += emailsArray[i];
}
}
return email;
}
Useage of findEmailAddresses function:
<textarea name=t rows=10 cols=50 onBlur="this.form.email.value=findEmailAddresses(this.value);"></textarea>
I tried calling the function individually in the functions above and even tried removing the function just inserting the code using "emails" instead of "this.value" in both cases. I even tried a two page approach. For some reason, I just can't implement this code into the working splitter. My results are either no effect or I break the thing.
Basically I tried many variations of inserting. Like below:
<html>
<head>
<script language=javascript type='text/javascript'>
function onpaste(e) {
var t = this;
var cnt='0';
setTimeout(function(){
var list = document.getElementById('t');
var emails= t.value.split(/\s+/), ta;
//
findEmailAddresses(emails);
// also tried inserting code from function. ///
while(emails.length) {
cnt++;
ta = document.createElement('textarea');
ta.value = emails.splice(0,150).join(',').replace(/,\s*$/,'');
document.body.appendChild(ta);
}
document.getElementById('button1').value=cnt;
},1);
}
window.onload = function() {
// tried to trigger it here as well and even added a new split //
document.getElementById('t').onpaste = onpaste;
}
/////
function findEmailAddresses(StrObj) {
var separateEmailsBy = '\n';
var email = "<none>"; // if no match, use this
var emailsArray = StrObj.match(/([a-zA-Z0-9._-]+#[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+)/gi); // yeah could be better
if (emailsArray) {
email = "";
for (var i = 0; i < emailsArray.length; i++) {
if (i != 0) email += separateEmailsBy;
email += emailsArray[i];
}
}
return email;
}
////////
</script>
</head>
<BODY>
<p><textarea id="t" rows="10" cols="50" class="textarea"></textarea><br /></p><br />
There are <input type="button" id="button1" value="0"> textareas
<pre id="p" class="pre"></pre>
</body>
</html>
Much thanks to anyone who can assist.
Try putting return true; after your inline javascript.

Why "Microsoft JScript runtime error: Object expected"?

I'm about 1 day old in using jquery, and is currently having a nightmare with it. I alreadt spent half of my day trying to get rid of this error.
I did some reading after “googling” the error (sorry, Bing!) and discovered that most of these errors result from the jquery file not being properly loaded. Okay…that started to point me in the right direction but I still couldn’t figure out why it wasn’t pathing properly. I mean, I was doing as people said – I would drag the .js file into my designer and it would print out the proper path, but still the error shows.
Here's my exact code in my editor template (with the error):
#model bool
#{
string status = "Active";
string buttonValue = "Deactivate";
string hiddenValue = "true";
if (!ViewData.Model)
{
status = "Inactive";
buttonValue = "Activate";
hiddenValue = "false";
}
}
<div style="width:100px; float:left;">
<img id = "AD_Img" src = "/Content/themes/base/images/icon_#(status).png" alt = #(status) />
<label for = "AD_Img" id = "AD_Label" >#(status)</label>
</div>
<div style="width:100px; float:left;">
<input type="button" id = "AD_Button" value = #(buttonValue) style = "width:100px" onclick = "ChangeStatus()" />
<input id = "AcntStatus" type = "hidden" name = "AcntStatus" value = #(hiddenValue) />
</div>
and in the same cshtml file, the script goes this way:
<script type="text/javascript" src="/Scripts/jquery-1.5.1.min.js">
function ChangeStatus()
{
var ButtonVal = $("#AD_Button").val();
alert(ButtonVal);
if (ButtonVal == "Deactivate")
{
var stat = "Inactive";
var buttonVal = "Activate";
var HiddenValue = "false";
}
else if (ButtonVal == "Activate")
{
stat = "Active";
buttonVal = "Deactivate";
HiddenValue = "true";
}
$("#AD_Img").attr({src: "/Content/themes/base/images/icon_"+stat+".png", alt: stat});
$("#AD_Label").html(stat);
$("#AD_Button").val(buttonVal);
$("#AcntStatus").val(HiddenValue);
}
</script>
The debugger stops on the ChangeStatus function of the input element on the following line:
<input type="button" id = "AD_Button" value = #(buttonValue) style = "width:100px" onclick = "ChangeStatus()" />
i tried to debug it by using this in my function code:
function ChangeStatus()
{
var ButtonVal = document.getElementById("AD_Button").value;
alert(ButtonVal);
}
And it works properly, it returns the exact string that I'm looking for without that error, but why? What's wrong with my codes?
Please help me figure this out.
This:
$("#AD_Img").attr(src: "../../../Content/themes/base/images/icon_"+stat+".png", alt: stat);
forces an Syntax-error. It has to be:
$("#AD_Img").attr({src: "../../../Content/themes/base/images/icon_"+stat+".png", alt: stat});
Edit:
Also take a look at your <script>, you can't mix external JS and internal JS.
This:
<script type="text/javascript" src="../../../Scripts/jquery-1.5.1.min.js">
//your code
</script>
Has to be splitted into
<script type="text/javascript" src="../../../Scripts/jquery-1.5.1.min.js"></script>
<script type="text/javascript">
//your code
</script>

Replacing DIV content based on variable sent from another HTML file

I'm trying to get this JavaScript working:
I have an HTML email which links to this page which contains a variable in the link (index.html?content=email1). The JavaScript should replace the DIV content depending on what the variable for 'content' is.
<!-- ORIGINAL DIV -->
<div id="Email">
</div>
<!-- DIV replacement function -->
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}
</script>
<!-- Email 1 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 1 content</div>';
ReplaceContentInContainer('Email1',content);
}
</script>
<!-- Email 2 Content -->
<script ="text/javascript">
var content = '<div class="test">Email 2 content</div>';
ReplaceContentInContainer('Email2',content);
}
</script>
Any ideas what I've done wrong that is causing it not to work?
Rather than inserting the element as text into innerHTML create a DOM element, and append it manually like so:
var obj = document.createElement("div");
obj.innerText = "Email 2 content";
obj.className = "test"
document.getElementById("email").appendChild(obj);
See this working here: http://jsfiddle.net/BE8Xa/1/
EDIT
Interesting reading to help you decide if you want to use innerHTML or appendChild:
"innerHTML += ..." vs "appendChild(txtNode)"
The ReplaceContentInContainer calls specify ID's which are not present, the only ID is Email and also, how are the two scripts called, if they are in the same apge like in the example the second (with a corrected ID) would always overwrite the first and also you declare the content variable twice which is not permitted, multiple script blocks in a page share the same global namespace so any global variables has to be named uniquely.
David's on the money as to why your DOM script isn't working: there's only an 'Email' id out there, but you're referencing 'Email1' and 'Email2'.
As for grabbing the content parameter from the query string:
var content = (location.search.split(/&*content=/)[1] || '').split(/&/)[0];
I noticed you are putting a closing "}" after you call "ReplaceContentInContainer". I don't know if that is your complete problem but it would definitely cause the javascript not to parse correctly. Remove the closing "}".
With the closing "}", you are closing a block of code you never opened.
First of all, parse the query string data to find the desired content to show. To achieve this, add this function to your page:
<script type="text/javascript">
function ParseQueryString() {
var result = new Array();
var strQS = window.location.href;
var index = strQS.indexOf("?");
if (index > 0) {
var temp = strQS.split("?");
var arrData = temp[1].split("&");
for (var i = 0; i < arrData.length; i++) {
temp = arrData[i].split("=");
var key = temp[0];
var value = temp.length > 0 ? temp[1] : "";
result[key] = value;
}
}
return result;
}
</script>
Second step, have all possible DIV elements in the page, initially hidden using display: none; CSS, like this:
<div id="Email1" style="display: none;">Email 1 Content</div>
<div id="Email2" style="display: none;">Email 2 Content</div>
...
Third and final step, in the page load (after all DIV elements are loaded including the placeholder) read the query string, and if content is given, put the contents of the desired DIV into the "main" div.. here is the required code:
window.onload = function WindowLoad() {
var QS = ParseQueryString();
var contentId = QS["content"];
if (contentId) {
var source = document.getElementById(contentId);
if (source) {
var target = document.getElementById("Email");
target.innerHTML = source.innerHTML;
}
}
}
How about this? Hacky but works...
<!-- ORIGINAL DIV -->
<div id="Email"></div>
<script type="text/javascript">
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
var txt = document.createTextNode(content);
container.appendChild(txt);
}
window.onload = function() {
var args = document.location.search.substr(1, document.location.search.length).split('&');
var key_value = args[0].split('=');
ReplaceContentInContainer('Email', key_value[1]);
}
</script>

Categories