Creating a reusable jQuery function - javascript

Instead of re-writing a massive block of code each time, I'm trying to incorporate functions into my work but I'm having trouble making it work.
Basically, I've got a selection of radio buttons and I'm performing some stuff each time a radio button is clicked. (I'm actually loading an iFrame). However, I need to make the iFrame SRC different for each radio button so how would I cater for this within the function?
The function:
jQuery.fn.switchPreview = function () {
$('.liveDemoFrame').remove();
$('.liveDemoHand').append('<iframe class="liveDemoFrame" src="themes/src/' + themeName + '/" width="100%" height="300" scrolling="no"><p>Your browser does not support iframes.</p></iframe>');
$('.liveDemoHand').append('<div class="switchPreview"><div class="loadingPreview"></div></div>');
$('.liveDemoFrame').load(function() {
$('.switchPreview').fadeOut();
$('.switchPreview').remove();
$('.liveDemoFrame').fadeIn();
});
return this;
}
Within the iFrame SRC I have a variable called themeName. I need this to somehow change for each radio button. You can see within the code that calls the function I've tried to declare the variable each time but this still gives me an undefined error.
The code that calls it:
$('#cTheme1').click(function () {
$('input:radio[name=mgChooseTheme]:nth(1)').attr('checked',true);
var themeName = 'theme1';
$('.liveDemoFrame').switchPreview();
});
$('#cTheme2').click(function () {
$('input:radio[name=mgChooseTheme]:nth(2)').attr('checked',true);
var themeName = 'theme2';
$('.liveDemoFrame').switchPreview();
});
$('#cTheme3').click(function () {
$('input:radio[name=mgChooseTheme]:nth(3)').attr('checked',true);
var themeName = 'theme3';
$('.liveDemoFrame').switchPreview();
});
I'm sure this is something very simple but I'm still learning so little things always throw me off!

Pass in the themeName as an argument of the switchPreview function.
-Change the first line of the function to:
jQuery.fn.switchPreview = function (themeName) {
-For each of the three times you are calling the function, make sure you are passing in the argument, i.e:
$('.liveDemoFrame').switchPreview(themeName);

Why not just update the src tag of the iframe ...
$('#cTheme1').click(function () {
$('input:radio[name=mgChooseTheme]:nth(1)').attr('checked',true);
$('#liveDemoFrame').attr('src', <the new url>);
});
Then your iframe would already need to be part of the page :
<iframe id='liveDemoFrame' src='<default page>'></iframe>
i notice your using a CLASS attribute on your iFrame and accessing it using that - you really need to think about using the ID attribute if you are just wanting to refer to a single object. (as in my example above)

Related

How to have JavaScript functions work across different HTML pages?

I am building a website with several HTML pages, and going to fill up info on different pages through an API. I have added onclick listeners to HTML elements like this:
// ASSIGNING ELEMENTS AS VARIABLES
const EPL = document.getElementById('epl');
const bundesliga = document.getElementById('bundesliga');
const laliga = document.getElementById('laliga');
// ONCLICKS
EPL.onclick = function() {
getStandings('2021');
location.replace('standings.html');
}
bundesliga.onclick = function() {
getStandings('2088');
location.replace('standings.html');
}
laliga.onclick = function() {
getStandings('2224');
location.replace('standings.html');
}
When one of these is clicked, I call a function (getStandings) with its unique argument to fetch some data from the API. I also want to move to another HTML page, for which I used location.replace.
I'm caught in a dilemma: if I use the same JS file for every HTML page, when I get to the new HTML page, I get errors as the new HTML page does not have every element:
main.js:41 Uncaught TypeError: Cannot set property 'onclick' of null
But if I use different JS files, maybe one JS file for each HTML file, I cannot carry forward the bits of information I need. How can I get to the new HTML page, with its own JS file, without stopping and losing everything in the function I'm in currently, under the JS file of the old page? For example, the argument '2021' or '2088' are to be passed into the getStandings() function which will populate the new HTML page with data from an API. If I jump to a new HTML page with a new JS file, this is lost.
Is there a better way to organise my files? 😐😐😐😐😐
You can set your event listeners on the condition that the elements are not null e.g.
const EPL = document.getElementById('epl');
const bundesliga = document.getElementById('bundesliga');
const laliga = document.getElementById('laliga');
if(EPL){
EPL.onclick = function() {
getStandings('2021');
location.replace('standings.html');
}
}
etc...
Solved! As amn said, I can add URL parameters to the end of the URL of the new HTML page, then get the variables from its own URL once I'm on the new HTML page.
I think I would rather use classes instead of IDs to define the listener, and maybe IDs for dedicated action.

jQuery trigger function from code loaded by append

Is there anyway to call a function or trigger an event from html loaded from an append() call? I have a tag It is filled when a user licks on a list of things like this. in my index.html I have something like this:
function doThis(someData) {
$.get("/url/"+someData, function(htmlFromServer) {
$("#something").append(htmlFromServer);
});
}
function doSomething(moreData) {
alert(moreData);
}
I want to be able to do something like this in the returned html
<div>
<p>This is an important message</p>
<script>
doSomething("this message is different for each page");
</script>
</div>
I want to be able to call one function, but depending on what is returned, I alert a different message. I want the front end to call one endpoint, but what happens next is dynamic. I don't want to do a huge if block in my doThis(), or worse, a function for each possibility that "someData" may have.
You could pass a function to doThis. You also probably meant to concatenate the someData.
function doThis(someData, cb) {
$.get("/url/" + someData, function(htmlFromServer) {
$("#something").append(htmlFromServer);
cb()
});
}
doThis('somepath', () => console.log('append successful'));
I got this to work by defining all my functions in a javascript file and import like usual.
I then make a decision on the back end that all of the possible html that is returned by the jQuery get() call, has a hidden form field with the id of "x" and the value being the function name I want to call after the .append(htmlFromServer) is done.
So i have this function in a .js file defined int the head as usual. I then do this:
$.get("/url/"+someData, function(htmlFromServer) {
$("#myDiv").append(htmlFromServer).append(function() {
var functionToCall = $("#x").val(); // x is the id of the element
window[functionToCall]();
});
}
And I now have a generic way of handling different data depending on the server response without a big if block.

JQuery - using previously declared variables for a click function

Have searched high an low for an answer without luck.
I am trying to pass a variable between two functions. The first function runs when the page loads, pulling settings from a google script file. I don't have any issues with this part. I am however, struggling with the second function which runs 'on click' and requires some variables from the first function.
Any guidance is appreciated.
<script>
$(function() {
google.script.run
.withSuccessHandler(loadSettings)
.withFailureHandler(showStatus)
.withUserObject($('#button-bar').get())
.getSettings();
function loadSettings(settings) {
$("select").data("option",settings.userInput1);
};
$('#add1').click(function(){
var option0 = $("select").data("option");}
...etc.
})
</script>
I assume settings.userInput1 is a string. Try the below
<script>
var userInput ="";
$(function() {
google.script.run
.withSuccessHandler(loadSettings)
.withFailureHandler(showStatus)
.withUserObject($('#button-bar').get())
.getSettings();
function loadSettings(settings) {
userInput = settings.userInput1;
$("select").data("option",settings.userInput1);
};
$('#add1').click(function(){
//you can now use userInput in this function
var option0 = $("select").data("option");}
...etc.
})
if other solutions are not working then you should go this way -
Make a hidden field
store that variables value in that hidden field
in the next function get the value from that field
$("#hiddenfield_id").val();

TestComplete different tabs not accessing information within each other in same script

So I have a function that looks like this, and ultimately I'm trying to store the button's location information in a different tab inside the same script as the tab the function is in. So for instance in one tab, let's call it GeneralTab, I have all my operations I want to do declared. This is what it looks like.
function MyFunction
{
ThePage.Button.click();
}
Pretty simple so far. What I am trying to do is store its location in a different tab within the script. Let's call this tab LocationTab. LocationTab looks like this:
var page = LaunchInternetExplorer(url);
function MyPage()
{
this.Button = page.SomeLocation;
}
ThePage = new MyPage();
Here is what is intresting, when I run MyFunction inside of the same tab this works fine. That would look like the following:
var page = LaunchInternetExplorer(url);
function MyPage()
{
this.Button = page.SomeLocation;
}
ThePage = new MyPage();
function MyFunction
{
ThePage.Button.click();
}
But if I try to have them be two different tabs in the same script, I get an error when I try and run MyFunction(). It says
"ThePage is undefined".
What is going on here.
You need to add //USEUNIT LocationTab at the top of your GeneralTab script. Check the docs for details: Calling Routines and Variables Declared in Another Unit.

Need to change the function name in JS, trying to keep it from breaking

I'm no javascript guru, I'm having to call an external JS file twice in one page. The JS file includes a function. Having this function called twice (once in each JS include) breaks the functionality. So I thought I'd modify the 2nd instance to a different function name. This works to allow the first instance to work correctly but breaks the 2nd one (The one with the function changed).
The function name is address and I'm trying to work just exactly what else needs to be modified in this script to reflect the name change. I fear there are other mentions of "address" that is legitimate and not associated with the function name. I'm at my wits end and am just not sure. Anyone care to look at this JS and help me find which instances of the word address need to be changed to correctly reflect the one function and var name?
/**
* execute part
*/
$(document).ready(function(){
address.bindZipcodeFind();
});
var address = {
bindZipcodeFind: function(){
$('.zipcode-searcha').click(function(){
$('.zipcode-search-resulta').text("로딩ė¤‘...");
$.get('http://www.nuvonoir.com/postalcode2/zipsearch-action.php',{
query: $('#dongNamea').val()
},function(data){
$('.zipcode-search-resulta').html(data);
address.bindPutAddress();
})
});
},
bindPutAddress: function(){
$('.zipcode-search-resulta a').click(function(){
$('[id=zipcode1a]').val($(this).parent().parent().find('.postcd1').text());
$('[id=zipcode2a]').val($(this).parent().parent().find('.postcd2').text());
$('[id=OrdAddra]').val(address.remove_useless_addr($(this).parent().parent().find('.address').text()));
address.hideZipcodeFinder();
$('[name=addr]').focus();
return false;
});
},
remove_useless_addr: function(address){
if(address.indexOf('~') != -1){
address = address.split(' ').slice(0,-1).join(' ');
}
return address;
},
hideZipcodeFinder: function(){
$('.zipcode-findera').slideUp();
}
}
If you have no way to mitigate including code twice, then there's the only option: write that function was called elsewhere:
global variable
invisible element with certain id
or even more magic things:
field in document object or document root node (html/body)
location hash (URL part after #)
cookie/sessionStorage based on document.lastModified (it is equal to page generating time on server) or anything remaining stable within one page load.
Example using global variable:
function once() {
if (window.myOnceFuncIsCalled) return;
// do the main work
window.myOnceFuncIsCalled = true;
}

Categories