I've worked on this for days and made little progress because I suck at javascript.
Goal: Create a wp plugin that allows choosing an alternate chat department for each web page, or use the default chat dept for the domain. I can do all of this with php in my plugin, BUT... all of my Wordpress websites are using Zoho SalesIQ plugin. I cannot disable this plugin, so instead I must edit the chat widget javascript that's in the plugin settings, so NO PHP. Yuck.
Much research lead me to a potential solution - I've inserted custom meta tags into the head that will hold the correct data to insert into the javascript. But that's where I get lost - how do I replace these two values in the zoho javascript with the content from the custom meta tags?
<meta name='my_zoho_widgetcode' content='123456789' />
<meta name='my_zoho_deptcode' content='deptA' />
<script id="zsiqchat">
var $zoho=$zoho || {};
$zoho.salesiq = $zoho.salesiq || {
widgetcode: "GET-WIDGETCODE-FROM-META-TAG",
values:{},
ready:function(){}
};
var d=document;
s=d.createElement("script");
s.type="text/javascript";
s.id="zsiqscript";
s.defer=true;
s.src="https://salesiq.zoho.com/widget?plugin_source=wordpress";
t=d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s,t);
$zoho.salesiq.ready=function() {
$zoho.salesiq.chat.department("GET-DEPT-FROM-META-TAG");
};
</script>
I managed to get it to work this way, but it's going to require a lot of IF conditions (shortened here), so I'm looking for a cleaner solution.
<script type="text/javascript" id="zsiqchat">
var zoho_meta_widgetcode = document.querySelector('meta[name="zoho_widgetcode"]').content;
var zoho_meta_deptcode = document.querySelector('meta[name="zoho_deptcode"]').content;
var $zoho=$zoho || {};
if (zoho_meta_widgetcode === '123456789') {
$zoho.salesiq = $zoho.salesiq || {
widgetcode:"123456789",
values:{},ready:function(){}
};
}
if (zoho_meta_widgetcode === '') {
$zoho.salesiq = $zoho.salesiq || {
widgetcode:"000000000",
values:{},ready:function(){}
};
}
var d=document;
s=d.createElement("script");
s.type="text/javascript";
s.id="zsiqscript";
s.defer=true;
s.src="https://salesiq.zoho.com/widget?plugin_source=wordpress";
t=d.getElementsByTagName("script")[0];
t.parentNode.insertBefore(s,t);
$zoho.salesiq.ready=function()
{
if (zoho_meta_deptcode === 'deptA') {
$zoho.salesiq.chat.department(["deptA"]);
}
if (zoho_meta_deptcode === '') {
$zoho.salesiq.chat.department(["Default"]);
}
};
</script>
UPDATE: I've learned that the SalesIQ WP plugin will allow me to make some changes to the code but not other changes. This caused me so much grief I ended up disabling that plugin and inserting my own code via my plugin.
Related
First things first, I'm brand new to Javascript and Regex. I've only been dipping my toes in this past month. I've been trying to put together away to paste a url into a text input then automatically trim it down to just the host name and validate it before I'm able to push the button.
I've gotten it working a few different times but I keep running into the same issue: After a certain period of time, it simply stops working.
I've reformatted and cleaned up the code a few times (though, I'm sure it's still very sloppy because I'm new at this) and I can get it working again. But after an hour or so of working, it stops working. Reloading the page doesn't make a difference. Even restarting my computer doesn't make a difference. It simply stops working.
My only guess is that there must be something about the way I'm going about this which is causing it crash or stall out. Perhaps a formatting issue, perhaps the methodology altogether is flawed. I just don't know enough to be able to diagnose it yet.
Hopefully, some of you nice people would be able to point out my flaws or point me in the right direction of how to fix this. I've searched and I couldn't find anyone who was trying to do the things I'm doing all in one build (preparing to myself to be proved wrong here).
Here's the code:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>Untitled Document</title>
</head>
<body>
<input id="notesUrlInput" type="text" placeholder="URL Goes here" pattern="^(?!www\.)[a-zA-Z0-9\-]+\.[a-zA-Z0-9]+$" autocomplete="off">
<button id="notesExecuteButton" disabled>Execute</button>
<span id="notesUrlOutput"></span>
<!------------------------------------------------------------------------------->
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script>
(function () {
var timeout = null;
var notesUrlOutput = document.getElementById("notesUrlOutput");
var notesExecuteButton = document.getElementById("notesExecuteButton");
document.getElementById('notesUrlInput').addEventListener('keyup',
function (e) {
clearTimeout(timeout);
timeout = setTimeout(
function () {
rawInput = $('#notesUrlInput').val();
cleanInput = rawInput.replace('www.', '');
cleanInput = cleanInput.replace('http://', '');
cleanInput = cleanInput.replace('https://', '');
cleanInput = cleanInput.replace(/\/.*/,'');
$('#notesUrlInput').val(cleanInput);
if (cleanInput.value == "") {
notesUrlOutput.innerHTML = "";
notesExecuteButton.disabled = true; return false;
} else if(!notesUrlInput.checkValidity()) {
notesUrlOutput.innerHTML = "Invalid URL: Please provide a valid URL";
notesExecuteButton.disabled = true; return false;
} else {
notesUrlOutput.innerHTML = "Input OK";
notesExecuteButton.disabled = false; return false;
}
}, 400);
});
})();
</script>
</body>
</html>
Frustratingly, when I pasted this code in here and ran it, it worked. As soon as I opened the file I copied this from in my browser. It stopped working. I just don't understand it.
From your code it looks like you want to extract just the domain name from the input field.
You mix JavaScript DOM calls and jQuery, which is fine. It is usually easier to interact with the DOM using just jQuery. Here is your code rewritten in jQuery:
const cleanRegex = /^https?:\/\/(?:www\.)?(.*)\/.*$/;
const validRegex = /^[\w\-]+(\.[\w]+)+$/;
(function () {
$('#notesExecuteButton').prop('disabled', true);
$('#notesUrlInput').on('input', function(event) {
let val = $(this).val();
let cleaned = val.replace(cleanRegex, '$1');
$(this).val(cleaned);
if(!cleaned) {
$('#notesUrlOutput').text('');
$('#notesExecuteButton').prop('disabled', true);
} else if(!cleaned.match(validRegex)) {
$('#notesUrlOutput').text('Invalid URL: Please provide a valid URL');
$('#notesExecuteButton').prop('disabled', true);
} else {
$('#notesUrlOutput').text('Input OK');
$('#notesExecuteButton').prop('disabled', false);
}
});
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script>
<input id="notesUrlInput" />
<button id="notesExecuteButton" style="disabled: disabled;">Go</button>
<div id="notesUrlOutput"></div>
Explanation:
.on('input') - fires every time something changes in the input field- val.replace(cleanRegex, '$1') - clean up: strip protocol and www prefix, and URL path (any text after domain
cleaned.match(validRegex) - check validity of domain
.prop('disabled', true/false) - add/remove disable property
I have added the Google Translate plugin to my web page. How can I get a callback to my JavaScript function whenever the user selects a language from the drop down menu that the plugin adds to my web page? The Google Translate API documentation does not seem to have any information on this. I have read through the JavaScript code of the Google Translate plugin and I cannot see anything that is helpful.
It will also be fine if I get a callback to my function just before the translation of my web page begins or just after the translation of my web page ends or just before or after the translation of any specific element in my web page.
Here is the HTML for a simplified version of my web page:
<html>
<head>
</head>
<body>
<!-- Google Website Translator plugin -->
<div id="google_translate_element"></div><script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'es', layout: google.translate.TranslateElement.InlineLayout.SIMPLE}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<div>
<p>This part can be translated using the Google Translator plugin.</p>
</div>
<script type="text/javascript">
function translationCallback() {
// This function needs to be called when Google translates this web page.
alert("A language was selected from the Google Translator plugin dropdown");
}
</script>
</body>
</html>
Thanks for the responses. Based on the answers and comments in the SO questions referenced in the above responses, I cobbled together the code below which works for me.
I added a hidden div and a listener for its DOMSubtreeModified event. The listener gets called when Google translates the contents of the hidden div. However the listener gets called multiple times for each time a language is selected from the plugin drop down menu. Google seems to be making multiple passes. The original value of the innerHTML seems to be retained as a substring in all the passes except the last. So I check for the original innerHTML substring in the event handler to avoid executing the code multiple times.
Select an initial value for the innerHTML that is distinct for each language in the drop down menu. 'English' works in my case.
<html>
<head>
</head>
<body>
<!-- Google Website Translator plugin -->
<div id="google_translate_element"></div><script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({pageLanguage: 'en', includedLanguages: 'es', layout: google.translate.TranslateElement.InlineLayout.SIMPLE}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="//translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
<div>
<p>This part can be translated using the Google Translator plugin.</p>
</div>
<div id="translationDetector" style="display:none;">English</div>
<script type="text/javascript">
var origValue = document.getElementById("translationDetector").innerHTML;
document.getElementById("translationDetector").addEventListener("DOMSubtreeModified", translationCallback, false);
function translationCallback() {
// This function needs to be called when Google translates this web page.
var currentValue = document.getElementById("translationDetector").innerHTML;
if (currentValue && currentValue.indexOf(origValue) < 0) {
origValue = currentValue;
alert("There is a disturbance in the force: " + currentValue);
}
}
</script>
</body>
</html>
Google translate js uses a cookie to keep track of the current language selection. You could set up a timeout to watch for changes to the cookie.
Here's how I implemented this for Drupal, adaptable to any javascript framework:
Drupal.exampleLanguageChanged = function() {
if (Drupal.exampleGetCookie('googtrans') != cookieValue) {
cookieValue = Drupal.exampleGetCookie('googtrans');
console.log('cookie changed ' + cookieValue);
}
setTimeout(Drupal.exampleLanguageChanged, 500);
};
Drupal.exampleGetCookie = function(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length >= 2) {
return parts.pop().split(";").shift();
}
return '';
};
Drupal.behaviors.exampleSimpleTranslation = {
attach: function(context) {
cookieValue = Drupal.exampleGetCookie('googtrans');
console.log('cookie value ' + cookieValue);
setTimeout(Drupal.exampleLanguageChanged, 500);
}
};
From this SO question, this code apears to work:
var $textfield = find("#google-translate");
var $popup = find("#google_translate_element");
var $select = $popup.find("select");
$textfield.click(function () {
$popup.fadeIn("fast");
return false;
});
$select.bind("change", function () {
$popup.fadeOut("fast");
});
Here's one solution, but I'm not sure if I like it that much. Essentially you check to see if the text or page has changed then when it does you act on that.
Google Translate Widget - Translation complete callback
what I need
I need to hide js code in view source
js code
function unloadJS(scriptName) {
var head = document.getElementsByTagName('head').item(0);
var js = document.getElementById(scriptName);
js.parentNode.removeChild(js);
}
function unloadAllJS() {
var jsArray = new Array();
jsArray = document.getElementsByTagName('script');
for (i = 0; i < jsArray.length; i++){
if (jsArray[i].id){
unloadJS(jsArray[i].id)
}else{
jsArray[i].parentNode.removeChild(jsArray[i]);
}
}
}
var page_count = {{count()}};
if (page_count == 4)
{
dataLayer.push({'event':'mobilePromo-android'});
}
$(document).ready(function()
{
var page_count = {{count()}};
var height= $(window).height();
if (page_count == 4 )
{
$.ajax({
type: "GET",
url: "http://times.com/mobilepopuptracker?from=android",
});
$('body').html('<div class="row flush aligncenter popbx" style="height:'+height+'px"><div class="12u">');
}
else
{
}
});
function redirect()
{
var a=$(location).attr('href');
window.location.href=a;
}
</script>
Problem
I Need to hide js code in view source.
Debug
i have reffred the link find solution on http://www.sitepoint.com/hide-jquery-source-code/.
though code is still viewed.
any suggestion are most welcome.
though we know we cannot stop viewing of js in view source but still there must be some trick.
Use the online Google Closure Compiler service, it will make your code almost unreadable by doing things like renaming variables and function names. For example:
Raw JS
function toggleDisplay(el){
if (!el) return;
el.style.display = (el.style.display==='none') ? 'block' : 'none';
}
Closure Compiled
function toggleDisplay(a){a&&(a.style.display="none"===a.style.display?"block":"none")};
JavaScript Beautified
function toggleDisplay(a){
a&&(a.style.display="none"===a.style.display?"block":"none")
};
In doing so it also reduces the size of your script, helping to boost the loading time of your webpage.
You can still read the script, but its harder to understand and can get really complex when using things like JavaScript Closures.
You can't truly hide your js code. You can obfuscate it (i.e. make it difficult to read), but unlike PHP or Perl - which is processed on the server side - JS runs in the client's browser itself. Therefore, the client always has a copy of it, and can view that source at any time.
I'm a newbie with JavaScript and I asked a question earlier and got answers which helped me, but I thought I could incorporate it into the larger form I was working with and now I'm stuck again.
I have a large form with one select option. When the form is filled out, a new window opens and incorporates the values submitted into an invitation type page.
Everything else is working except for this select option. The problem I am having is depending on the selection, I want different text to be written into the new window (as part of the overall new window invitation page).
I'm really close, mostly b/c of help I received earlier today -- I can either get the new window to show just my named option value or I can get a whole new window with the different text (that is not part of the invitation page). I just can't combine the two.
I wrote up a smaller page in case someone wants to take a look at it. Thanks in advance.
<!doctype html>
<html>
<head>
<title>JavaScript Forms</title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="mystyle.css">
<script type="text/JavaScript">
function newWindow() {
allInfo = open("", "displayWindow");
allInfo.document.open();
allInfo.document.write('<!doctype html><html><head><link rel="stylesheet" type="text/css" href="mystyle_invite.css"><title>Resume</title><meta charset="utf-8"> </head><body>');
allInfo.document.write(document.getElementById ('firstname').value);
allInfo.document.write('</body></html>');
allInfo.document.close();
}
function showName() {
var doIt=document.getElementById('firstname').value;
if ( doIt == "Michael" ) {
allInfo.document.write("Mr. " + doIt); //only "Mikey" is written out
}
else if ( doIt == "Sam" ) {
allInfo.document.write("Mrs. " + doIt);
}
else {
allInfo.document.write("Sir " + doIt);
}
}
</script>
</head>
<body>
<script type="text/JavaScript">
</script>
<form id="infoForm" method="post" name="infoForm">
<p>First Name:</p>
<p><select id="firstname" onChange="showName()" >
<option value="Mikey">nickname1</option>
<option value="Sammy">nickname2</option>
<option value="Sir Doug">nickname3</option>
</select></p>
<p> <input type="button" value="Submit Information" onClick="newWindow()"></p>
</form>
</body>
</html>
There are somethings that can help a lot here. First opening a second window can be a painful experience both for the user and the programmer. Unless you have an absolute need I would recommend manipulating the current window's DOM to display a popup instead.
Next if you can use DOM methods to change the page contents. document.write comes with a lot of problems which in your case are not apparent. Mainly it can erase you current DOM. You don't notice this in your example because the new window is blank so rewriting it is incidental.
Finally your use of allInfo is a quirky way to reference a global variable. It is not easily understood that this is happening from the style of code. In fact any linter will throw an error for your use of the global and will case an error if you declare "use strict" in your functions. Best to learn the good coding practises way.
Since we will want to interact with a variable (allInfo) in your case we should encapsulate the value in an object. This object can hold the state of that reference and offer some abstracted interactions with it. By doing so you avoid polluting the global name space and allow you to swap out your implementation without having to rewrite the parts of your program that depend on it.
// Our welcome window object
function WelcomeWindow() {
// save a reference to the content of your new window
// to be printed when ready. (Lazy execution)
this.innerHTML = '';
}
WelcomeWindow.prototype.open = function() {
this.win = window.open("", "displayWindow");
return this;
};
WelcomeWindow.prototype.close = function() {
this.win.close();
return this;
};
WelcomeWindow.prototype.write = function(html) {
this.innerHTML += '' + html;
return this;
};
WelcomeWindow.prototype.render = function() {
if (!this.win) { throw new Error("window has not been opened yet."); }
this.win.open();
this.win.write('<!doctype html><html><head><link rel="stylesheet" type="text/css" href="mystyle_invite.css"><title>Resume</title><meta charset="utf-8"> </head><body>');
this.win.write(this.innerHTML);
this.win.write('</body></html>');
this.win.close();
return this;
};
This allows us to declaratively manipulate the window before it is opened. For example if we want to add the name to the window:
function NameField(id) {
this.element = document.getElementById(id);
}
NameField.prototype.toString = function() {
var name = this.element.value;
switch (name) {
case 'Michael': return 'Mr. Michael';
case 'Sam': return 'Mrs. Sam';
default: return 'Sir ' + name;
}
};
NameField.prototype.toHtml = function() {
return '<strong>' + this.toString() + '</strong>';
};
Linking it together using code instead because adding events into the DOM only confuses the separation of markup and code.
window.onload = function() {
var form = document.getElementById('infoForm');
form.onsubmit = function(e) {
e.preventDefault();
var name = new NameField('firstName');
new WelcomWindow()
.write(name.toHtml())
.open()
.render();
return false;
};
};
I was just wondering if there are any methods of creating nice, smooth transition effects when navigating between pages? Things like blind effects, sliding effects, etc. I guess I'm looking for something like what jQuery can do with images - but for actual web pages. I know there are fade effects and all that, but I was just wondering if there was something more 'modern' out there. While I realize Flash would be a good fit for this, it is not an option.
You can do some pretty cool effects if you use jQuery UI. They will go much smoother if you load everything in using AJAX... but, here's an example to get it working with full page loads.
First you need to additionally include jQuery UI (I just built my own and only grabbed the effects I needed):
<script type="text/javascript" src="jquery-ui-1.7.1.custom.min.js"></script>
And here's the javascript you'll need to make it work.
$(function() {
$('body').hide();
$('a').bind('click', function() {
var newPage = $(this).attr('href');
$('body').hide('blind',{},500, function() {
newPageParts = newPage.split('?');
newPageURL = newPageParts[0];
newPageParams = newPageParts[1];
newPage = newPageURL+"?transition=true"+(newPageParams != undefined ? "&"+newPageParams : '');
window.location=newPage;
});
return false;
});
if(getURLParam('transition') != '') {
$('body').show('blind',{},500,null);
}
});
function getURLParam(strParamName){
var strReturn = "";
var strHref = window.location.href;
if ( strHref.indexOf("?") > -1 ){
var strQueryString = strHref.substr(strHref.indexOf("?")).toLowerCase();
var aQueryString = strQueryString.split("&");
for ( var iParam = 0; iParam < aQueryString.length; iParam++ ){
if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ){
var aParam = aQueryString[iParam].split("=");
strReturn = aParam[1];
break;
}
}
}
return strReturn;
}
Of course, fading in is only going to work on pages that have this script on it...
Just a note: I did just kinda make this in a few minutes so it might be really ghetto. But, it does work... so... yeah...
IE has a very simple implementation of page transition effects, but I don't think they will work on other browsers like Mozilla and Safari.