I am making multi-lang index page and I'm making lang change area, when I click each language text it changes.
When I click my language links(AZ, EN, RU) it changes language but after the page reload it doesn't change language.
Mainly I want caching onclick functions after a page reload.
Also I want to use pure JavaScript.
Here is my code:
var voc = [
{
"AZ":"Log in2",
"EN":"Log in",
"RU":"Log in3"
}
];
function translate(ele,lng){
for(var i=0;i<voc.length;i++){
for(var k in voc[i]){
if(voc[i][k] == ele.innerText.trim()){
ele.innerText = voc[i][lng];
break;
}
}
}
}
function translateTo(lng){
var trc = document.getElementsByClassName("trans");
for(var i=0;i<trc.length;i++){
translate(trc[i],lng);
}
}
//add this function to any event button.click,select.change or on load
//translateTo("AR");
function under1(){
document.getElementsByClassName("lang")[0].style = "text-decoration:underline;";
document.getElementsByClassName("lang")[1].style = "text-decoration:none";
document.getElementsByClassName("lang")[2].style = "text-decoration:none";
}
function under2(){
document.getElementsByClassName("lang")[0].style = "text-decoration:none;";
document.getElementsByClassName("lang")[1].style = "text-decoration:underline";
document.getElementsByClassName("lang")[2].style = "text-decoration:none";
}
function under3(){
document.getElementsByClassName("lang")[0].style = "text-decoration:none;";
document.getElementsByClassName("lang")[1].style = "text-decoration:none";
document.getElementsByClassName("lang")[2].style = "text-decoration:underline";
}
.langselect a{
text-decoration:none;
}
.langselect a:nth-child(2){
text-decoration:underline;
}
<p>
<span class='trans'>Log in</span>
</p>
<p class="langselect">
<a href="" class="lang" onclick='translateTo("AZ"); under1(); return false;'>AZ</a>
<a href="" class="lang" onclick='translateTo("EN"); under2(); return false;'>EN</a>
<a href="" class="lang" onclick='translateTo("RU"); under3(); return false;'>RU</a>
</p>
The answer would be using a cookie:
window.onbeforeunload = function() {
document.cookie = "lang=AU"; //For example. You can choose to add the language whichever way you want.
}
And then when the page loads:
window.onload = function() {
window.getCookie = function(name) {
var match = document.cookie.match(new RegExp('(^| )' + name + '=([^;]+)'));
if (match) {
return match[2]
};
}
Courtesy of #JonathanCamenisch for the second part of the answer.
Related
I have this keyboard site launcher script, which I copied from some place years ago and it works fine as is. I want to enhance it by adding a cascading keypress launch for some of the keys. Here is my code:
<html><head>
<script language="JavaScript">
<!-- Begin
var key = new Array();
key['a'] = "https://www.arstechnica.com";
key['g'] = "https://www.google.com";
key['s'] = "https://slashdot.org";
key['y'] = "http://www.yahoo.com";
function getKey(keyStroke) {
isNetscape=(document.layers);
eventChooser = (isNetscape) ? keyStroke.which : event.keyCode;
which = String.fromCharCode(eventChooser).toLowerCase();
// alert('['+which+'] key \n has been stroke');
runUrl(which);
}
function runUrl(which) {
for (var i in key)
if (which == i) {window.location = key[i];}
}
document.onkeypress = getKey;
// End -->
</script></head>
<body>
Make a selection<br>
<br>
key['a'] = "https://www.arstechnica.com";
key['g'] = "https://www.google.com";
key['s'] = "https://slashdot.org";
key['y'] = "http://www.yahoo.com";
<br>
<br>
<!-- I solemnly swear this page is coded with vi or notepad.exe depending on the OS being used -->
</body>
</html>
Now, I want to modify the action for pressing the letter "s" to launch a submenu of sorts and ask me to select if I want to go to "Slashdot" or Spotify" for instance. like if I press an "s" second time, it goes to slashdot and if I press "f" for instance, it goes to spotify.
My problem is, I have never programmed in Javascript other than copying and pasting code and changing string values in the code, like here, changing the pressed keys and site URLs.
Any pointers, regarding how to start modifying this code, are greatly appreciated.
to be honest, the code provided is a bit outdated but I keep it so you can see the necessary changes that I made for the menu to be added and to implement the feature it's just a sketch but I will do the job I think from here you can expand, hope this puts you in the right direction
let isopenMenu = true;
const menu = document.getElementById("menu");
function toggleMenu() {
isopenMenu = !isopenMenu;
menu.style.display = isopenMenu ? "block" : "none";
}
var key = new Array();
key["a"] = "https://www.arstechnica.com";
key["g"] = "https://www.google.com";
key["s"] = "https://slashdot.org";
key["y"] = "http://www.yahoo.com";
key["b"] = "http://www.stackoverflow.com";
key["c"] = "http://www.test.com";
const menuSite = ["b", "c", "s"];
function getKey(keyStroke) {
isNetscape = document.layers;
eventChooser = isNetscape ? keyStroke.which : event.keyCode;
which = String.fromCharCode(eventChooser).toLowerCase();
runUrl(which);
}
function runUrl(which) {
for (var i in key)
if (which == i) {
if (which === "s") {
return toggleMenu();
}
if (!isopenMenu && menuSite.includes(which)) {
return;
}
window.location = key[i];
}
}
document.onkeypress = getKey;
window.addEventListener("load", toggleMenu);
<html><head>
<script language="JavaScript">
</script></head>
<body>
Make a selection<br>
<br>
key['a'] = "https://www.arstechnica.com";
key['g'] = "https://www.google.com";
key['s'] = "to toggel menu
key['y'] = "http://www.yahoo.com";
<br>
<br>
<ul id="menu">
<li>key['b'] = "http://www.stackoverflow.com";</li>
<li>key['c'] = "http://www.test.com</li>
</ul>
</body>
</html>
Indeed the code you've provided seems a bit dusted. There's some stuff that isn't done in that way nowadays. Notepad is an editor I still occassionally use though.
Since you've mentioned that you never really used JavaScript it's a bit hard to give you advice. You can do things way more elegant and even improve the look - but I'd say this would just confuse you even more. So let's work on something based on your code.
At the moment the keys and the corresponding targets are stored in an object (yeah, it's an object not an array). We can use a second object - let' say subKey - to store the additional targets upon pressing s.
var key = {};
key.a = "https://www.arstechnica.com";
key.g = "https://www.google.com";
key.s = "subMenu";
key.y = "http://www.yahoo.com";
var subKey = {};
subKey.a = "https://www.stackoverflow.com";
subKey.g = "https://www.startpage.com";
subKey.s = "goBack";
As you can see I've reserved the key s to go to the sub menu and inside the sub menu this button is used to go back to the main menu.
Now instead of hardcoding what the user gets to see on screen, we can iterate over those objects and use the information from there. To do this we need to reserve a html element - I've chosen an empty <div> which acts as some sort of container. As we iterate over the object we construct a string with the keys and it's associated targets and ultimately assign this this to the div's .innerHTML property.
let container = document.getElementById("container");
container.innerHTML = "Make a selection<br><br>";
for (var i in obj) {
container.innerHTML += "key['" + i + "'] = " + obj[i] + "<br>";
}
As the procedure is the same for both objects we just need to wrap it inside a function and pass it a reference to the desired object.
Your runUrl function needs to be modified a bit to take care of the additional options. This is best done with a simple if-else construct. So in pseudo-code:
if choice is subMenu open sub menu
if choice is goBack open main menu
if it's none of the above open a link
If we put everything together, your example looks a little bit like this:
(Just click on 'Run code snippet' and make sure to click somewhere inside the window so it'll have key focus)
<html>
<head>
</head>
<body>
<div id="container">
</div>
</body>
<script type="text/javascript">
var key = {};
key.a = "https://www.arstechnica.com";
key.g = "https://www.google.com";
key.s = "subMenu";
key.y = "http://www.yahoo.com";
var subKey = {};
subKey.a = "https://www.stackoverflow.com";
subKey.g = "https://www.startpage.com";
subKey.s = "goBack";
var currentObj = key;
function getKey(event) {
let which = String.fromCharCode(event.keyCode).toLowerCase();
runUrl(which)
}
function runUrl(which) {
for (var i in currentObj) {
if (which == i) {
if (currentObj[i] != "subMenu") {
if (currentObj[i] != "goBack") {
window.location = currentObj[i];
} else {
populateMenu(key);
}
} else {
populateMenu(subKey);
}
}
}
}
function populateMenu(obj) {
currentObj = obj;
let container = document.getElementById("container");
container.innerHTML = "Make a selection<br><br>";
for (var i in obj) {
container.innerHTML += "key['" + i + "'] = " + obj[i] + "<br>";
}
}
populateMenu(key);
document.onkeypress = getKey;
</script>
</html>
It looks like could achieve this with arbitrary list of sites. If so, you could handle this a little more generically by providing a list of sites and filtering the sites based on keystrokes.
If so, you can achieve it with the following:
const sites = [
'https://www.arstechnica.com',
'https://www.google.com',
'https://mail.google.com',
'https://slashdot.org',
'https://spotify.com',
'http://www.yahoo.com',
];
let matches = sites;
document.getElementById('keys').addEventListener('keyup', event => {
const keys = event.target.value.toLowerCase().split('');
matches = sites
.map(site => ({ site, stripped: site.replace(/^https?:\/\/(www\.)?/i, '')})) // strip out https://wwww. prefix
.filter(site => isMatch(site.stripped, keys))
.map(site => site.site);
if (event.keyCode === 13) {
if (matches.length === 0) {
alert('No matches');
} else if (matches.length === 1) {
alert(`launching ${matches[0]}`);
} else {
alert('More than one match found');
}
matches = sites;
}
document.getElementById('matches').textContent = matches.join(', ');
});
// find sites matching keys
function isMatch(site, keys) {
if (keys.length === 0) return true;
if (site.indexOf(keys[0]) !== 0) return false;
let startIndex = 1;
for (let i = 1; i < keys.length; i++) {
let index = site.indexOf(keys[i], startIndex);
if (index === -1) return false;
startIndex = index + 1;
}
return true;
}
document.getElementById('matches').textContent = matches.join(', ');
<div>Keys: <input type="text" id="keys" autocomplete="off" /> press Enter to launch.</div>
<p>Matches: <span id="matches" /></p>
The key parts to this are:
Define a list of sites you want to handle
Ignore the the https://wwww prefixes which is achieved with site.replace(/^https?:\/\/(www\.)?/i, '')
Implement filter logic (in this case it is the isMatch method) which tries to match multiple keystrokes
For demonstration purposes, I've wired keyup to an input field instead of document so that you can see it in action, and the action is triggered with the enter/return key.
I have this piece of HTML code
<html>
<head></head>
<body>
<div ng-init="controller.onInit()" style="divContainer">
<div class="divLoading" style="vertical-align:middle" ng-show="controller.noOfLoadingInProgress > 0">
<span class="text"> Loading ...</span> <img src="../../Styles/Images/loading.gif" />
</div>
<br />
<h1>
Test</h1>
<div ui-view="wizardContent">
</div>
<!--<div class="clear">
</div>-->
<div>
<a class="buttonprev" id="btnPrevious" href="#" ng-show="controller.wizard.wizardIndex > 1"
ng-click="controller.wizard.previous()"><span>Previous </span></a>
<a class="buttonCancel"
id="btnCancel" href="#" ng-click="controller.wizard.cancel()"><span>Cancel </span>
</a>
<a class="buttonnext" id="btnNext" ng-disabled="controller.wizard.isNextInProgress"
href="#" ng-show="controller.termsAndCondition.isTermAndConditionAccepted && (controller.wizard.wizardIndex < controller.wizard.wizardItems.length-1)"
ng-click="controller.wizard.next()"><span>Next</span> </a>
<a class="buttonnext" id="btnFinish" href="#" ng-show="controller.termsAndCondition.isTermAndConditionAccepted && (controller.wizard.wizardIndex == controller.wizard.wizardItems.length-1)"
ng-click="controller.wizard.finish()" ng-disabled ="controller.wizard.isFinished == 1"><span>Finish</span> </a>
</div>
</div>
</body>
</html>
And this piece of javascript code.
var WizardItem = function (manager, uiState) {
this.manager = manager;
this.uiState = uiState;
}
var Wizard = function ($state, onFinishCallback, wizardItems) {
var self = this;
self.onFinishCallback = onFinishCallback;
self.wizardItems = wizardItems;
self.wizardIndex = 0;
self.isNextInProgress = false;
self.isFinished = 0;
self.refresh = function () {
$state.go(wizardItems[self.wizardIndex].uiState);
};
self.next = function () {
if ((self.wizardIndex < wizardItems.length - 1) && wizardItems[self.wizardIndex].manager.validate()) {
if (wizardItems[self.wizardIndex].manager.overrideNext == null) {
self.wizardIndex++;
$state.go(wizardItems[self.wizardIndex].uiState);
}
else {
self.isNextInProgress = true;
wizardItems[self.wizardIndex].manager.overrideNext(onFinishCallBack);
}
}
function onFinishCallBack(success) {
self.isNextInProgress = false;
if (success) {
self.wizardIndex++;
$state.go(wizardItems[self.wizardIndex].uiState);
self.isFinished = 1;
}
}
}
self.refreshWizardFrom = function (newWizardItems) {
self.wizardItems.splice(0);
for (var c = 0; c < newWizardItems.length; c++) {
self.wizardItems.push(newWizardItems[c]);
}
}
self.previous = function () {
if (self.wizardIndex > 1) {
self.wizardIndex--;
console.log($state.go(wizardItems[self.wizardIndex].uiState));
$state.go(wizardItems[self.wizardIndex].uiState);
}
};
self.cancel = function () {
if (confirm('Are you sure you want to cancel!')) {
$state.go('Home');
}
};
self.finish = function () {
self.isFinished = 1;
if ((self.wizardIndex == wizardItems.length - 1) && wizardItems[self.wizardIndex].manager.validate()) {
//Ajmal Bug 410 - Variable flag isFinished set to 1 and being called on finish button click to disable it
self.isFinished = 1;
self.onFinishCallback();
self.isFinished = 1;
// alert('finish');
}
};
self.validateCurrentWizardItem = function () {
return wizardItems[self.wizardIndex].manager.validate();
};
self.initAllWizardItems = function () {
for (var c = 0; c < wizardItems.length; c++) {
wizardItems[c].manager.onInit();
}
}
self.registerValidations = function () {
for (var c = 0; c < wizardItems.length; c++) {
wizardItems[c].manager.registerValidations();
}
};
};
I would like to disable the finish button after clicking it once.
I've tried something like that, but it still doesn't work
in the javascript file, use a flag
self.isFinished = 0;
then set it to 1 in the finish function
self.isFinished = 1
then use ng-disabled in the html part of the code
ng-disabled = "controller.wizard.isFinished == 1"
Can someone figure out where may be the issue ?
Thanks
Try do self.wizadr.isFinished = 1; instead of self.isFinished = 1;
You cannot disable tag. Use ng-disabled on button. Also add ng-app directive on body
Indeed, disabling a tag did not make any sense, hence I decided to remove all the links from all the tags with this function.
In the self.finish function, added a call to a function (in bold )
self.finish = function () {
if ((self.wizardIndex == wizardItems.length - 1) && wizardItems[self.wizardIndex].manager.validate()) {
self.onFinishCallback();
ConvertAnchorToSpan();
// alert('finish');
}
};
Outside of the Wizard, used that function in the same javascript file.
function ConvertAnchorToSpan() {
var $link = $('a');
var $span = $('<span>');
$link.after($span.html($link.html())).remove();
}
It now works and prevents multiple submissions. I removed all the isFinished flags in the javascript file as well as the ng-disabled in the html.
As there is no disable property for anchor tag so you can use custom code for that.
I used ng-class in place of ng-disabled It will add a class to your anchor tag and in css code is written for make this class elements disable.
<style>
.disabledOn {
cursor: not-allowed;
pointer-events: none;
color: grey;
}
</style>
HTML
<a class="buttonnext" id="btnFinish" href="#" ng-show="controller.termsAndCondition.isTermAndConditionAccepted && (controller.wizard.wizardIndex == controller.wizard.wizardItems.length-1)"
ng-click="controller.wizard.finish()" ng-class="{disabledOn : controller.wizard.isFinished == 1}"><span>Finish</span> </a>
Best of luck :)
ng-disabled can't be used for a tag. you can use this
HTML
<a ng-click="disabled()" class="btn" ng-class="{'disabled':disable}">Click Me</a>
JS
app.controller('MainCtrl', function($scope) {
var count=0;
$scope.disable=false;
$scope.disabled = function() {
if(count>0) { return false;}else{
alert("do someting else");
$scope.disable=true;
count++;
}
}
});
CSS
.disabled { cursor: default; opacity: .5; }
You can prevent click event by using this code after a first click.
For reference click this link
Hope it will be useful for you.
I'm looking for a filter to replace "href" in a TextEntity of an API. The "text" can contains 3 different kind of URLs. After the replacement I want to open the corrected URLs in a new separate window.
I receive from the textvalue the following information:
1. link - this is an example for a all kind of external links. Can be mysite.com/mypage.html or any other valid url. Like everything with a http://, https://, ftp:// in the startof the url.
2. internal page - Can includes all other files. like mypdf.pdf or mydoc.doc or other stuff, but without http://mydomain.tdl
3. mymail#domain.tdl
I tried something but it doesn't work.
.filter('parseText', function ($sce, $sanitize) {
var mydomain = 'http://www.mydomain.tdl';
return function (text) {
var newStringUrlReplace = $sanitize(text).replace('href="','href="'+mydomain);
var regex = /href="([\S]+)"/g;
var newString = newStringUrlReplace.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");
return $sce.trustAsHtml(newString);
}
});
I need this output the "text" ran went through the filter:
1. link
2. internal page
3. mymail#domain.tdl
To make it easier to understand:
I need a function which turns this types of URLs.
URL TO A EXTERNAL PAGE
internal page of the CMS
into
URL TO A EXTERNAL PAGE
internal page
Here's a version working based on your original code:
(function() {
angular
.module('app', ['ngSanitize'])
.controller('MainCtrl', MainCtrl)
.filter('parseText', parseText);
function MainCtrl($scope) {
$scope.array = [
'link',
'internal page',
'mymail#domain.tdl',
'URL TO A EXTERNAL PAGE',
'internal page of the CMS'
];
}
function parseText($sce) {
var myDomain = 'http://www.mydomain.tdl/';
var externalRegex = /([http|https|ftp]+:\/\/[^"]*)/g;
var internalRegex = /(href=)"([^"]*)/g;
return function(input) {
if (!input) return;
if (input.indexOf('mailto: ') !== -1) return input;
var url = '';
if (externalRegex.test(input)) {
url = input.replace(externalRegex, '$1" class="externalURL" onClick="cordova.InAppBrowser.open(\'$1\', \'_blank\', \'location=yes\')');
} else {
url = input.replace(internalRegex, '$1 ' + myDomain + '$2' + ' class="externalURL" onClick="cordova.InAppBrowser.open(\'' + myDomain + '$2' + '\', \'_blank\', \'location=yes\')');
}
return $sce.trustAsHtml(url);
}
}
})();
<!DOCTYPE html>
<html ng-app="app" >
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular-sanitize.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<p ng-repeat="url in array track by $index">
<span ng-bind-html="url | parseText"></span>
</p>
</body>
</html>
Hm,
well i have a solution now...
.filter('parseText', function ($sce, $sanitize) {
return function ( text ) {
var mydomain = 'http://www.mydomain.tdl';
text = $sanitize(text);
var source,sear,repl;
var newString;
var regex = /href="([\S]+)"/g;
var extMatch = /http|https|\/\//g;
var mtMatch = /mailto:/g;
var div = document.createElement("div");
div.innerHTML = text;
var aList = div.getElementsByTagName("a");
var aListNew = new Array();
var href,t;
if(aList.length>0){
for(var i = 0; i<aList.length; i++ ){
href = aList[i].getAttribute("href");
t = aList[i].outerHTML;
t = $sanitize(t);
if(href.match(extMatch)!=null){
newString = t.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('$1', '_blank', 'location=yes')\"");
} else if(href.match(mtMatch)!=null){
newString = t;
} else{
newString = t.replace(regex, "class=\"externalURL\" onClick=\"cordova.InAppBrowser.open('"+mydomain+"$1', '_blank', 'location=yes')\"");
}
source = text;
sear = t;
repl = newString;
text = text.replace(t,newString);
}
}
return $sce.trustAsHtml(text);
};
});
I have a site to allow someone to place food orders. Images of potential ingredients (determined by a MySQL query) can be clicked to add or remove them, and the image will toggle on each click.
The problem I'm having is for each new item I am having to duplicate the function and just change the variable names for each new function. I'm sure there must be a way to simplify to dynamically apply to all of the ingredients without all of the redundant code.
Here is the code just for two. There are dozens. Any suggestions would be appreciated.
window.onload = function () {
var ProductElement = document.getElementById('Ketchup');
if (ProductElement != null) {
Ketchupobj = document.getElementById('Ketchup')
document.getElementById('Ketchuptogg').onclick = function () {
Ketchuptoggle();
}
}
var ProductElement = document.getElementById('Mustard');
if (ProductElement != null) {
Mustardobj = document.getElementById('Mustard')
document.getElementById('Mustardtogg').onclick = function () {
Mustardtoggle();
}
}
}
function Ketchuptoggle() {
if (Ketchuptggle == 'on') {
Ketchupobj.src = "Ketchup.jpg";
Ketchuptggle = 'off';
} else {
Ketchupobj.src = "noKetchup.jpg";
Ketchuptggle = 'on';
}
}
function Mustardtoggle() {
if (Mustardtggle == 'on') {
Mustardobj.src = "Mustard.jpg";
Mustardtggle = 'off';
} else {
Mustardobj.src = "noMustard.jpg";
Mustardtggle = 'on';
}
}
<table class="ing">
<tr>
<?php
for ($x=0; $x<5 AND $row = mysql_fetch_row($result);$x++ ) {
$caps=$row[1];
$caps=strtoupper($caps);
echo <<<image
<td><b>$caps</b><br>
<a id="$row[0]" class="toggle" href="#"><img id="$row[0]img" class="toggimg"
src="$row[0].jpg" style="border-style: none" alt=""/></a>
</td>
image;
}
echo"</tr></table>";
Implicit this is your friend:
var toggles = document.getElementsByClassName('toggle');
for (var i=0; i<toggles.length; i++) {
toggles[i].isOn = true;
toggles[i].onclick = function(ev){
var condiment = this.id;
this.isOn = !this.isOn;
document.getElementById(condiment+'img').src=(this.isOn?'':'no')+condiment+'.png';
};
}
With html you have the ability to add your property for an element, so you could do:
<button class="btnProduct" data-type="mostard"> Mostard</button>
<button class="btnProduct" data-type="ketchup"> Ketchup</button>
<button class="btnProduct" data-type="barbecue"> Barbecue</button>
Then with a help of jquery you can do:
$('btnProduct').click(function(){
//So, here you could use a switch or some logic
// to do different things for data-type
console.log($(this).attr('data-type'))
}
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;
}