Issues With Pop-Up Blocking (this shouldn't be happening?) - javascript

First to clarify, I am trying to open a pop-up in response to a user event.
I am developing an application on Facebook that involves e-commerce transactions, and for reasons related to my EV SSL certificates, I have to open our billing terminal in a new, fully-secure window. As such, the process goes as follows:
User selects "new card" as payment method and enter's the recipient's shipping address
User clicks "Place Order," which uses an AJAX call to validate the address, and IF valid, syncs it with the database.
IF address is valid (AJAX success: function()), and the user selected "new card," then the secure billing terminal is supposed to open using a window.open call.
As I understand it, most modern browsers including Chrome, Firefox, and Safari are supposed to traverse up the chain to determine if the source event was user-initiated (in this case, it was--a click event), however despite this I cannot seem to prevent this pop-up from getting blocked and my users are having a great deal of trouble figuring out what's going on.
Unfortunately Chrome doesn't make it all that noticeable when a pop-up is blocked, so most users will not notice this and will assume that the app is simply "broken."
Any ideas? We're a week from launch and I'm getting desperate...
[EDIT] Here is the code for reference:
/* -- Step 3: Complete Checkout Click -- */
$('div.finishGroupOrder').live('click', function() {
/* User is Click-Happy? */
if ( $('div#billing-contents div#loader').length ) {
alert('Your order is processing. We know it\'s hard, but please be patient.');
return false;
}
var paymentMethod = $('input[name="method"]:checked').val(); // Payment Method Selected ( Card on File / New / PayPal )
var secureSession = $(this).attr('secure'); // Secure Session ID
var orderData = { addressSelection: $('input[name="address"]:checked').val(),
price: $('div.price').attr('value') };
/* Form Validation */
switch( orderData.addressSelection ) {
case 'new': // User chose to enter address manually
var allInputs = $('div#new-address').find('input:not(#address2), select');
var validInputs = $('div#new-address').find('input[value!=""]:not(#address2), select[value!=""]');
if ( allInputs.length === validInputs.length ) { // All inputs are valid, capture their contents
allInputs.removeClass('bad-value');
var address = { phone: $('input#phone').val(),
address1: $('input#address1').val(),
address2: $('input#address2').val(),
city: $('input#city').val(),
state: $('select#state').val(),
zip: $('input#zipcode').val() };
var validatedAddress = validation.validateAddress(address);
if (validatedAddress) {
address.address1 = validatedAddress.address1;
address.address2 = validatedAddress.address2;
address.city = validatedAddress.city;
address.state = validatedAddress.state;
address.timeOffset = validatedAddress.timeOffset; // Time offset from EST (PST = -3, EST = 0, etc.)
$('input#timezone').val(address.timeOffset);
} else {
allInputs.addClass('bad-value');
return false;
}
} else { // Some inputs are invalid, prompt the user to fix them
allInputs.filter(function() { return ($.inArray( this, validInputs ) > -1) ? false : true; }).addClass('bad-value');
return false;
}
break;
case 'verified': // User chose to ship to verified address
var address = { address1: 'verified' };
break;
default:
alert('Please choose an address where you want the flowers to be delivered.');
return false;
break;
}
/* Sync Order With Updated Address Information */
$.ajax({ type: 'POST',
url: location.protocol + '//' + location.host + '/_ajax/order.ajax.php',
data: 'action=update_order&' + $.param( address ),
success: function() {
/* Load Selected Payment Method */
switch( paymentMethod ) {
//case 'paypal': paypal(); break;
case 'member':
newGroupOrderDialogActions.payAsMember();
break;
case 'newCard':
newGroupOrderDialogActions.payWithCard( secureSession );
//$('div.group-secure-terminal').trigger('click');
break;
}
}
});
And the newGroupOrderActions.payWithCard()...
/* -- Pay With a New Credit Card -- */
payWithCard: function( session ) {
var windowHeight = 769; // Terminal Height
var windowWidth = 638; // Terminal Width
var w = screen.availWidth; // Available Screen (W)
var h = screen.availHeight; // Available Screen (H)
var top = (h-windowHeight)/2; // Center Positioning
var left = (w-windowWidth)/2; // Center Positioning
/* Open Secure Order Terminal */
var secureTerminal = window.open('https://secure.mydomain.ly/contribute?id=' + session, 'myCompany: Secure Checkout', 'menubar=0,toolbar=0,location=1,resizable=0,scrollbars=1,height='+windowHeight+',width='+windowWidth+',top='+top+',left='+left);
/* Check for Secure Order Terminal Close Event */
var onFinish = setInterval(function() {
try {
if (secureTerminal.closed) { // Window has been unloaded, check the order to see if it has been approved
clearTimeout(onFinish);
$.ajax({ type: 'POST',
url: location.protocol + '//' + location.host + '/_ajax/redirect.ajax.php',
data: 'action=group_order_status_redirect',
success: function(redirect) { newGroupOrderDialogActions.publishOrder( redirect ) } // If redirect is not null, order was successful. Redirect to order page
});
}
} catch (e) {}
}, 200);
},

Related

Google Script ui.button calling prompt from other function

I have two separate scripts that are activated by buttons in a sheet. One sends an email (CALemail.js), and the other clears cells (clear.js). Both scripts prompt for confirmation before running. While the first one executes perfectly, my clear.js script first asks the prompt from CALemail and then asks the clear.js prompt before running. How can I separate them?
CALemail.js:
var ehtml =
'<body>' +
'<h2>Calendar Updated</h2>' +
'<p>You can access it by clicking here </p>' +
'</body>'
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',
ui.ButtonSet.YES_NO);
if (response == ui.Button.YES) function CALemail() {
MailApp.sendEmail(
'example#gmail.com', // recipient
' Calendar Updated', // subject
'test', { // body
htmlBody: ehtml // advanced options
} );
} else {
}
clear.js:
function clearRange() {
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?',
ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES)
{
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}
Whether you put them in separate files or in the same file, they need to be separate functions. Unless you want the to run every time you access a function.
function testEmail(){
var ehtml = '<body><h2>Calendar Updated</h2><p>You can access it by clicking here </p></body>';
var ui = SpreadsheetApp.getUi();
var response = ui.alert('You are sending a link to the current version of this calendar. Do you want to continue?',ui.ButtonSet.YES_NO);
if(response == ui.Button.YES) function CALemail() {
MailApp.sendEmail('example#gmail.com',' Calendar Updated','test',{htmlBody: ehtml});
}
}
function clearRange(){
var ui = SpreadsheetApp.getUi();
var response = ui.alert('STOP! You are attempting to clear the Calendar. THIS CANNOT BE UNDONE. Do you want to continue?', ui.ButtonSet.YES_NO);
var sheet = SpreadsheetApp.getActive().getSheetByName('Calendar');
if (response == ui.Button.YES){
sheet.getRange('B4:V10').clearContent();
sheet.getRange('B12:V18').clearContent();
sheet.getRange('B20:V26').clearContent();
sheet.getRange('B28:V34').clearContent();
sheet.getRange('B36:V42').clearContent();
sheet.getRange('B44:C50').clearContent();
sheet.getRange('D3:D43').clearContent();
sheet.getRange('G3:G43').clearContent();
sheet.getRange('J3:J43').clearContent();
sheet.getRange('M3:M43').clearContent();
sheet.getRange('P3:P43').clearContent();
sheet.getRange('S3:S43').clearContent();
sheet.getRange('V3:V43').clearContent();
sheet.getRange('B53:V65').clearContent();
}
}
Note: I didn't test them nor do I care too. That's upto you.

Mousedown still submitting form, when it should not

hello i have a login validation form which uses a mix of jquery and ajax to do validations... if the values are ok the form should submit, if the values are not ok then the form should not submit... however in my case the form is submitting even when the values are incorrect ( i am using the mousedown function ) please see below my code..
<form method="post" name="loginform" action="models/login.php">
<input type="email" class="homepage" name="user_email2" id="user_email2" placeholder="Email" maxlength="50" />
<div class="errormsg" id="errormsg6"></div>
<input type="password" class="homepage" name="user_password2" id="user_password2" placeholder="Password" maxlength="20" />
<div class="errormsg" id="errormsg7"></div>
<input type="submit" name="login" id="login" value="Submit">
<div class="errormsglast" id="errormsg8"></div>
</form>
jquery and ajax
$(document).ready(function()
{
/* ----------------- Login Validations Global Variables ----------------- */
var user_email2 = "";
var user_emailajax2 = "";
var user_password2 = "";
var user_passwordajax2 = "";
var emailformat = new RegExp(/^[+a-zA-Z0-9._-]+#[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/i);
/* ----------------- Define Validate Email */
var validate_email_login = function()
{
var item5 = $("#user_email2").val().toLowerCase();
if (item5.length < 6 || item5.length > 50)
{
$("#errormsg6").html("Email : 6 - 50 Characters");
user_email2 = "";
}
else
{
$("#errormsg6").html("");
user_email2 = item5;
if (!emailformat.test(item5))
{
$("#errormsg6").html("Wrong Email Format");
user_email2 = "";
}
else
{
$("#errormsg6").html("");
user_email2 = item5;
$.ajax(
{
type: 'POST',
url: 'classes/validatelogin.php?f=1',
data: "user_email2=" + item5,
success: function(msg)
{
if (msg == "ok")
{
user_emailajax2 = "";
$("#errormsg6").html("Email Does Not Exist");
}
else if (msg == "exists")
{
user_emailajax2 = item5;
$("#errormsg6").html("");
}
}
});
}
}
}
/* ----------------- Define Validate Password */
var validate_password_login = function()
{
var item5 = $("#user_email2").val().toLowerCase();
var item6 = $("#user_password2").val();
if (item6.length < 8 || item6.length > 20)
{
$("#errormsg7").html("Password : 8-20 Characters");
user_password2 = "";
}
else
{
$("#errormsg7").html("");
user_password2 = item6;
if (user_email2 != "" && user_emailajax2 != "")
{
$.ajax(
{
method: "POST",
url: "classes/validatelogin.php?f=2",
data: "user_email2=" + item5 + "&user_password2=" + item6,
success: function(msg)
{
if (msg == "WrongPw")
{
user_passwordajax2 = "";
$("#errormsg7").html("Wrong Password - See Forgot Password");
}
else if (msg == "CorrectPw")
{
user_passwordajax2 = item6;
$("#errormsg7").html("");
/* window.location.href="manage-properties"; */
}
}
});
}
}
}
/* ----------------- Run Functions */
$("#user_email2").on('focusout', validate_email_login);
$("#user_password2").on('focusout', validate_password_login);
/* ----------------- Stop on Submit */
$( "#login" ).mousedown(function()
{
validate_email_login();
validate_password_login();
if (user_email2 == "" || user_emailajax2 == "" || user_password2 == "" || user_passwordajax2 == "")
{
$("#errormsg8").html("Please Fill All Fields (Correctly)");
console.log("submit false");
return false;
}
else
{
$("#errormsg8").html("");
console.log("submit true");
return true;
}
});
});
Solution Tried - problem is that when user puts the wrong event that is fine, but if user then puts the correct values, the submit returns false on first time, then second time it returns true... it should return true in first go
<input type="button" name="login" id="login" value="Submit">
$( "#login" ).mousedown(function()
{
validate_email_login();
validate_password_login();
if (user_email2 == "" || user_emailajax2 == "" || user_password2 == "" || user_passwordajax2 == "")
{
$("#errormsg8").html("Please Fill All Fields (Correctly)");
console.log("submit false");
return false;
}
else
{
$("#errormsg8").html("");
console.log("submit true");
$('[name=loginform]').submit();
}
});
});
Instead of having a type="submit" button just have a normal button e.g<input type="button" name="login" id="login" value="Submit">. Then when you finished checking the values and happy that it should send then just call:
$('[name=loginform]').submit();
Because what is happening currently is that the form submits when you click on the button, because you are not stopping that event from happening.
If you want to prevent the form from submitting I would suggest either not using that button and initiating the submit yourself like I mentioned above, or alternatively you can use the onsubmit="someFunction()" on the form element way and just return false if it should not submit and return true if it should.
I would say your code suffers from a few issues and some bad practices.
I see you are trying to learn JS so forgive me for not directly solving your issue but to give you some pointers and point you to some best practices.
Logic -
It seems like you are doing a login form. I would say most of this checks should not happen in the client but on the server.
When user signups it might be wise to check user name length on the client as well and prompt the user that he can't use the user name he wants to register with, but during login all the client care is can I login or not.
Security -
You seem to have two serious security issues with your code
You allow to test if an e-mail/user exist or not using 'classes/validatelogin.php?f=1'. in general you should always test the user and password together if they exist and match the user should be able to login, if not the login should fail. you shouldn't notify the user why it fails (if the user name does not exist or if it exist but the password is wrong).
You don't seem to hash passwords in the database. I assume it by limiting the password max length. let the user choose as long password as he wants and hash it using a secure hashing algorithm (I'd suggest bcrypt but google around and find a suitable one). I know you are only learning but this is highly important I think hashing is the first thing you need to learn when handling user logins
Working with the DOM.
You should cache your DOM elements
so instead of calling $('#id') all the time in the main function scope set
var emailInput = $("#user_email2");
function submitForm() {
var email = emailInput.val().toLowerCase();
...
}
You should also probably set the text value of the element and not the html doesn't matter much now but since you are setting text value its good practice and will help you avoid unexpected injections and errors.
Since your using ajax you should not let the form to submit itself even when validation is successful.
Common logic should be packed into functions and reused.
There are many places where your original code can be split into shorter and reusable functions
handle async code better
jQuery supports the Promise API when using ajax requests, I would rather use it. Your original code had a few async calls if you needed to sync between them it would have been painful using plain callbacks (and it is probably what caused you issues in the first place)
Here is a simplified solution using my suggestions -
$(document).ready(function() {
"use strict";
var emailInput = $("#user_email2"),
emailError = $("#errormsg6"),
passwordInput = $("#user_password2"),
passwordError = $("#errormsg7");
function required (value) {
if (value) {
return true;
} else {
return false;
}
//this is just to make the code clear you could use
//`return value ? true : false` or `return !!value`
}
$('form:eq(0)').on('submit', function (e) {
var valid = true,
email = emailInput.val(),
password = passwordInput.val();
e.preventDefault();
if ( !required(email) ) {
emailError.text('Email is required');
valid = false;
}
if ( !required(password) ) {
passwordError.text('Password is required');
valid = false;
}
if ( valid ) {
$.ajax({
method: "POST",
url: "login.php",
data: {
email: email,
password: password
}
}).done(function (data, textStatus, jqXHR) {
//redirect user to main page
}).fail(function (jqXHR, textStatus, errorThrown) {
//show the user the error
})
}
});
});

problems displaying page, deleting contents and repopulating - could this be multiple binding?

I have a mobile app.
It consists of 2 screens. The first is for capturing user
credentials and the 2nd is for displaying data.
The idea is to collect the credentials on screen 1.
Then make an ajax call with the credentials to get data and present it on
screen 2 as a series of links.
Then allow the user to touch a link on screen 2. This will return the link data to the javascript and pass it to the ajax call and get more data - THEN delete all the data on screen 2 and repopulate it with the new data.
First thing I want to find out: is showing a page with mobile.changePage(), populating it, deleting the contents and then repopulating it (without another call to mobile.changePage()) a reasonable thing to do?
I'm having a problem and I think its related to how I'm using onclick in the <a>
Each time I display the most recently received data, I want to display it in an <a>. I write each onclick to call the getData routine passing it information to determine the next ajax AND whatever is being displayed in the <a>. The only way I could figure out to access that was in onclick.
Is there a better way?
I'm able to display the results of the first ajax call just fine. But things get weird with the 2nd, 3rd etc.
Sometimes I'll touch a link and I'll progress thru the screens as I expect.
Sometimes I'll touch an <a> on the 1st result screen, the 2nd result screen will display and then (without me selecting data from the 2nd screen) the 3rd screen will display.
I've looked at the logs and the getData() routine is being executed.
What could be causing this? Am I somehow not destroying all the <a> properly? Am I using onclick in a fashion its not designed for? Should I be using buttons styled to look like links instead of <a>
Here's my code:
"use strict";
var app = {
onDeviceReady: function() {
$('#startButton').click(function(){
app.getDeptsForUser();
});
},
getDeptsForUser: function(){
var parms = new Object();
parms.userName = assignedUser;
app.getData(JSON.stringify(parms),"ENDPOINT1", "Departments");
$.mobile.changePage("#index", { transition: 'slide' });
},
getData: function(paramStr, endpoint, displayHeader){
var paramStrObj = JSON.parse(paramStr);
var serverName = server + ":" + port;
var encoded = Base64().encode(paramStrObj.userName + ':' + pass);
var authType = 'Basic ' + encoded;
var option = endpoint+"?action=start&params=" + paramStr;
var URL = serverName + "/rest/bpm/wle/v1/service/"+option;
$.ajax({
url: URL,
type: "POST",
crossDomain: true,
jsonp: "callback",
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", authType);
},
success: function (result) {
console.log("MobileMockUp getData() ajax success result="+JSON.stringify(result));
if (endpoint === "ENDPOINT1"){
app.displayData(paramStr, endpoint,"Departments", result.data.data.depts.items);
}
else if (endpoint === "ENDPOINT2"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checklists.items);
}
else if (endpoint === "ENDPOINT3"){
app.displayData(paramStr, endpoint,displayHeader, result.data.data.checks.items);
}
},
error: function(jqXHR, textStatus, errorThrown) {
alert('Unable to retrieve '+displayHeader);
},
});
},
displayData: function(currParms,currEndPt, headerText, list){
var nextEndpt;
var nextHeaderText;
var currParmsObj = JSON.parse(currParms);
if (currEndPt === "MD#getDeptsForUser"){
nextEndpt = "MD#getCheckLists";
nextHeaderText = "Check Lists";
}
else if (currEndPt === "MD#getCheckLists"){
nextEndpt = "MD#getChecks";
}
var htmlListString="";
var parmObj;
var newLink;
$('#headerText').text(headerText);
for (var i = 0; i < list.length; i++){
parmObj = new Object();
if (currEndPt === "ENDPOINT1"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=list[i];
}
else if (currEndPt === "ENDPOINT2"){
parmObj.userName=currParmsObj.userName;
parmObj.dept=currParmsObj.dept;
parmObj.checklist=list[i];
}
else if (currEndPt === "ENDPOINT3"){
nextHeaderText = list[i];
}
var str = JSON.stringify(parmObj);
str = str.toString().replace(/"/g, '\\"');
newLink = "<a style='background:#ffffff;padding-top:5%;border-top: thin solid black; display:block;font-size:12px;font-weight:normal;color:#000000;text-decoration: none;' href='#' onclick='app.getData(\""+str+"\",\""+nextEndpt+"\",\""+nextHeaderText+"\")'><pre>" + list[i] + " </pre></a><br>";
htmlListString=htmlListString+newLink;
}
$('#taskListUL').empty();
$('#taskListUL').append(htmlListString);
}
};
Could this be multiple binding?
i figured out it was multiple bindings

How would I make user wait to join until meeting organizer joins first

I am implementing a video conference room in which a user can create a video conference and invite other users.
Now I want to make sure that the user can't join the conference until the meeting organizer opens the room.
I have the following code but it is not working. The meeting organizer can open the room but when users click on "join conference" it doesn't join.
// https://github.com/muaz-khan/RTCMultiConnection
var rmc = new RTCMultiConnection();
rmc.userid = "<?php echo $user->fname . ' ' . $user->lname . ' (' . $user->username . ')' ; ?>";
rmc.session = {
video: true,
audio: true,
data: true
};
var room_status = 0; //room closed
$('#open-room').click(function () {
// http://www.rtcmulticonnection.org/docs/open/
room_status = 1; //room opened
rmc.open();
rmc.streams.mute({video : true});
document.getElementById("on-off-video").style.color= 'red';
});
$('#join-room').click(function () {
if(room_status == 1) {
// http://www.rtcmulticonnection.org/docs/connect/
rmc.connect();
rmc.streams.mute({video: true});
document.getElementById("on-off-video").style.color= 'red';
}
console.log("Waiting for meeting organizer");
});
// display a notification box
window.addEventListener('beforeunload', function () {
return 'Do you want to leave?';
}, false);
// leave here
window.addEventListener('unload', function () {
rmc.leave();
}, false);
rmc.onMediaCaptured = function () {
$('#share-screen').removeAttr('disabled');
$('#open-room').attr('disabled', 'disabled');
$('#join-room').attr('disabled', 'disabled');
};
//chat
rmc.onopen = function (event) {
//alert('Text chat has been opened between you and ' + event.userid);
document.getElementById('input-text-chat').disabled = false;
room_status = 1;
};
//end of chat
$('#disconnect').click(function () {
room_status = 0; //room closed
rmc.leave();
setTimeout("location.href = '../';",2000);
});
//to know the stream type
rmc.onstream = function (e) {
if (e.type == 'local') {
// alert("the stream is local");
}
if (e.type == 'remote') {
// alert("the stream is remote");
}
if (e.isVideo) {
var uibox = document.createElement("div");
uibox.appendChild(document.createTextNode(e.userid));
uibox.className = "userid";
uibox.id = "uibox-" + e.userid.replace(/ |\(|\)/g, '');
document.getElementById('video-container').appendChild(e.mediaElement);
document.getElementById('video-container').appendChild(uibox);
}
else if (e.isAudio) {
document.getElementById('video-container').appendChild(e.mediaElement);
}
else if (e.isScreen) {
$('#cotools-panel iframe').hide();
$('#cotools-panel video').remove();
document.getElementById('cotools-panel').appendChild(e.mediaElement);
}
};
//removes the div containing the userid of the user who is leaving
rmc.onleave = function (e) {
$('#' + "uibox-" + e.userid.replace(/ |\(|\)/g, '')).remove();
};
It seems you have 3 problems here.
1) First, I think you can't use only one RTCMultiConnection object to open and join a room. You have to create 2 separate objects. But, your code is not supposed to run in the same window for opening and joining the room. So It's not a problem if you run it once in a window to open the room and one in another window to join it.
In this case you have a more important problem. Your variable room_status is set to 1 when you open the room in one window. But in the other window, room_status is still equals to 0 so you don't call the code inside the if() in $('#join-room').click function.
It's not a big deal, for now, let's delete the if statement to be sure your code is executed (and read my point 3 for your original goal).
2) I look to the simple example given on https://github.com/muaz-khan/RTCMultiConnection : https://jsfiddle.net/c46de0L8/ and it seems you should use join and not connect. And above all, you should use a Channel ID and a Room Id to be able to connect 2 users.
So I change your code a little and it seems to work well :
var CHANNEL_ID = "MYCHANNEL-" + window.RMCDefaultChannel;
var ROOM_ID = "MYROOM";
var SESSION = {
video: true,
audio: true,
data: true
};
var USERID = "<?php echo $user->fname . ' ' . $user->lname . ' (' . $user->username . ')' ; ?>";
var rmc = undefined;
var room_status = 0; //room closed
$('#open-room').click(function () {
// http://www.rtcmulticonnection.org/docs/open/
room_status = 1; //room opened
rmc = new RTCMultiConnection(CHANNEL_ID);
rmc.userid = USERID;
rmc.session = SESSION;
rmc.open({
dontTransmit: true,
sessionid: ROOM_ID
});
rmc.streams.mute({video : true});
document.getElementById("on-off-video").style.color= 'red';
});
$('#join-room').click(function () {
//if(room_status == 1) {
// http://www.rtcmulticonnection.org/docs/connect/
rmc = new RTCMultiConnection(CHANNEL_ID);
rmc.join({
sessionid: ROOM_ID,
userid: USERID,
session: SESSION
});
rmc.streams.mute({video: true});
document.getElementById("on-off-video").style.color= 'red';
//}
console.log("Waiting for meeting organizer");
});
The rest of the code remains unchanged.
I put a rough working code in a JSFiddle: https://jsfiddle.net/sebdoncker/fjtkvnjq/2/
3) Now you still have the problem : How to be sure that the room is opened before to be able to join it. I think you can use the ROOM ID for this. When one user open a new room you should generate a ROOM ID. Now, you have to send this ROOM ID to your joiner user (by server communication or another way depending of your application architecture). And Since the joiner user doesn't have the ROOM ID, you can disable the join button.
It's just a lead, this depends of your overall application architecture.

Transposh plugin to translate Ajax loaded content

I'm trying to get the transposh plugin to translate everytime the cart is updated dynamically. Currently, the plugin will translate and then woocommerce would update the cart thus the translations disappear.
I found the following code in WooCommerce's checkout.js:
// Event for updating the checkout
$('body').bind('update_checkout', function() {
clearTimeout(updateTimer);
update_checkout();
});
I believe this is the code (I can only find the minified version of it) for how transposh gets the translations going in transposh.js:
(function(c){function D(b,a){if(0!==c.trim(a).length){var d=function(){var b=c(this).attr("id").substr(c(this).attr("id").lastIndexOf("_")+1),a=c("#"+e+"img_"+b);c("#"+e+b).attr("data-source",1);a.removeClass("tr-icon-yellow").removeClass("tr-icon-green").addClass("tr-icon-yellow")};c("*[data-token='"+b+"'][data-hidden!='y']").html(a).each(d);c("*[data-token='"+b+"'][data-hidden='y']").attr("data-trans",a).each(d)}}function E(b,a){clearTimeout(v);h.push(b);r.push(a);D(b,a);v=setTimeout(function(){var b=
{ln0:t_jp.lang,sr0:s,action:"tp_translation",items:h.length},a;for(a=0;a<h.length;a+=1)b["tk"+a]=h[a],b["tr"+a]=r[a],t+=c("*[data-token='"+h[a]+"']").size();c.ajax({type:"POST",url:t_jp.ajaxurl,data:b,success:function(){var b=t/k*100;t_jp.progress&&c("#"+m).progressbar("value",b)}});r=[];h=[]},200)}function l(b,a){E(b,c("<div>"+c.trim(a)+"</div>").text());var d=(k-c("."+e+'[data-source=""]').size())/k*100;t_jp.progress&&c("#"+n).progressbar("value",d)}function w(b,a,d){c.ajax({url:t_jp.ajaxurl,dataType:"json",
type:"GET",data:{action:"tp_gp",tl:d,q:b},success:a})}function x(b,a){w(a,function(a){c(a.results).each(function(a){l(b[a],this)})},t_jp.lang)}function y(b,a,d){c.ajax({url:"https://www.googleapis.com/language/translate/v2",dataType:"jsonp",data:{key:t_jp.google_key,q:b,target:d,source:t_jp.olang},traditional:!0,success:a})}function F(b,a){y(a,function(d){"undefined"!==typeof d.error?x(b,a):c(d.data.translations).each(function(a){l(b[a],this.translatedText)})},t_jp.lang)}function p(b,a,d){if(t_jp.msn_key){var f=
"[";c(b).each(function(a){f+='"'+encodeURIComponent(b[a].replace(/[\\"]/g,"\\$&").replace(/(\r\n|\n|\r)/gm," "))+'",'});f=f.slice(0,-1)+"]";c.ajax({url:"//api.microsofttranslator.com/V2/Ajax.svc/TranslateArray?appId="+t_jp.msn_key+"&to="+d+"&texts="+f,dataType:"jsonp",jsonp:"oncomplete",success:a})}else 1===z?setTimeout(function(){p(b,a,d)},500):(z=1,c.getScript("//www.microsofttranslator.com/ajax/v2/toolkit.ashx?loc=en&toolbar=none",function(){t_jp.msn_key=_mstConfig.appId;p(b,a,d)}))}function G(b,
a){s=2;p(a,function(a){c(a).each(function(a){l(b[a],this.TranslatedText)})},t_jp.binglang)}function A(b,a,d){c.ajax({url:"http://api.apertium.org/json/translate",data:{q:b,langpair:t_jp.olang+"|"+d,markUnknown:"no"},dataType:"jsonp",traditional:!0,success:a})}function H(b,a){s=3;A(a,function(a){200<=a.responseStatus&&300>a.responseStatus&&(void 0!==a.responseData.translatedText?l(b[0],a.responseData.translatedText):c(a.responseData).each(function(a){200===this.responseStatus&&l(b[a],this.responseData.translatedText)}))},
t_jp.lang)}function B(b,a){!t_jp.msn||"2"!==t_jp.preferred&&void 0!==t_jp.google?!t_jp.apertium||"en"!==t_jp.olang&&"es"!==t_jp.olang?t_jp.google_key?F(b,a):x(b,a):H(b,a):G(b,a)}function u(){var b=[],a=0,d=[],f=[];c("."+e+'[data-source=""]').each(function(){var e=c(this).attr("data-token"),g=c(this).attr("data-orig");void 0===g&&(g=c(this).html());1!==b[g]&&(b[g]=1,a+encodeURIComponent(g).length>I&&(B(f,d),a=0,d=[],f=[]),a+=encodeURIComponent(g).length,f.push(e),d.push(g))});B(f,d)}function C(b){"function"===
typeof c.xLazyLoader?b():(t_jp.$=c,c.getScript(t_jp.plugin_url+"/js/lazy.js",b))}function q(b){q.hit?b():(q.hit=!0,C(function(){c.fn.propAttr=c.fn.prop||c.fn.attr;c.xLazyLoader({js:t_jp.jQueryUI+"jquery-ui.min.js",css:t_jp.jQueryUI+"themes/"+t_jp.theme+"/jquery-ui.css",success:b})}))}var I=1024,k,e=t_jp.prefix,n=e+"pbar",m=n+"_s",s=1,t=0,v,h=[],r=[],z=0;t_jp.dgpt=w;t_jp.dgt=y;t_jp.dmt=p;t_jp.dat=A;t_jp.tfl=C;t_jp.tfju=q;t_jp.at=u;c(function(){t_jp.msn&&(t_jp.binglang=t_jp.lang,"zh"===t_jp.binglang?
t_jp.binglang="zh-chs":"zh-tw"===t_jp.binglang?t_jp.binglang="zh-cht":"mw"===t_jp.binglang&&(t_jp.binglang="mww"));c("."+e+"setdeflang").click(function(){c.ajax({url:t_jp.ajaxurl,data:{action:"tp_cookie"},cache:!1});c("."+e+"setdeflang").hide("slow");return!1});k=c("."+e+'[data-source=""]').size();c.ajaxSetup({cache:!0});k&&!t_jp.noauto&&(t_jp.google||t_jp.msn||t_jp.apertium)&&(t_jp.progress?q(function(){c("#"+e+"credit").css({overflow:"auto"}).append('<div style="float: left;width: 90%;height: 10px" id="'+
n+'"/><div style="margin-bottom:10px;float:left;width: 90%;height: 10px" id="'+m+'"/>');c("#"+n).progressbar({value:0});c("#"+m).progressbar({value:0});c("#"+m+" > div").css({background:"#28F828",border:"#08A908 1px solid"});u()}):u());t_jp.edit&&c.getScript(t_jp.plugin_url+"/js/transposhedit.js")})})(jQuery);
What should I add in the checkout.js to fire the translations everytime the cart is updated?
Let me know what other details I should provide.
EDIT: I should note that I was told that the cart is being updated via AJAX. Upon research, the plugin creator of transposh had suggested users to look at the on_init function in transposh.php
This is the on_init function:
/**
* Setup a buffer that will contain the contents of the html page.
* Once processing is completed the buffer will go into the translation process.
*/
function on_init() {
tp_logger('init ' . $_SERVER['REQUEST_URI'], 4);
// the wp_rewrite is not available earlier so we can only set the enable_permalinks here
if (is_object($GLOBALS['wp_rewrite'])) {
if ($GLOBALS['wp_rewrite']->using_permalinks() && $this->options->enable_permalinks) {
tp_logger("enabling permalinks");
$this->enable_permalinks_rewrite = TRUE;
}
}
// this is an ajax special case, currently crafted and tested on buddy press, lets hope this won't make hell break loose.
// it basically sets language based on referred when accessing wp-load.php (which is the way bp does ajax)
tp_logger(substr($_SERVER['SCRIPT_FILENAME'], -11), 5);
if (substr($_SERVER['SCRIPT_FILENAME'], -11) == 'wp-load.php') {
$this->target_language = transposh_utils::get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url);
$this->attempt_json = true;
}
//buddypress old activity
if (#$_POST['action'] == 'activity_get_older_updates') {
$this->target_language = transposh_utils::get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url);
$this->attempt_json = true;
}
tp_logger($_SERVER['REQUEST_URI'], 5);
if (strpos($_SERVER['REQUEST_URI'], '/wpv-ajax-pagination/') === true) {
tp_logger('wpv pagination', 5);
$this->target_language = transposh_utils::get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url);
}
// load translation files for transposh
load_plugin_textdomain(TRANSPOSH_TEXT_DOMAIN, false, dirname(plugin_basename(__FILE__)) . '/langs');
//set the callback for translating the page when it's done
ob_start(array(&$this, "process_page"));
}
Here is the function for update_checkout()
function update_checkout() {
if (xhr) xhr.abort();
if ( $('select#shipping_method').size() > 0 || $('input#shipping_method').size() > 0 )
var method = $('#shipping_method').val();
else
var method = $('input[name=shipping_method]:checked').val();
var payment_method = $('#order_review input[name=payment_method]:checked').val();
var country = $('#billing_country').val();
var state = $('#billing_state').val();
var postcode = $('input#billing_postcode').val();
var city = $('input#billing_city').val();
var address = $('input#billing_address_1').val();
var address_2 = $('input#billing_address_2').val();
if ( $('#shiptobilling input').is(':checked') || $('#shiptobilling input').size() == 0 ) {
var s_country = country;
var s_state = state;
var s_postcode = postcode;
var s_city = city;
var s_address = address;
var s_address_2 = address_2;
} else {
var s_country = $('#shipping_country').val();
var s_state = $('#shipping_state').val();
var s_postcode = $('input#shipping_postcode').val();
var s_city = $('input#shipping_city').val();
var s_address = $('input#shipping_address_1').val();
var s_address_2 = $('input#shipping_address_2').val();
}
$('#order_methods, #order_review').block({message: null, overlayCSS: {background: '#fff url(' + woocommerce_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6}});
var data = {
action: 'woocommerce_update_order_review',
security: woocommerce_params.update_order_review_nonce,
shipping_method: method,
payment_method: payment_method,
country: country,
state: state,
postcode: postcode,
city: city,
address: address,
address_2: address_2,
s_country: s_country,
s_state: s_state,
s_postcode: s_postcode,
s_city: s_city,
s_address: s_address,
s_address_2: s_address_2,
post_data: $('form.checkout').serialize()
};
xhr = $.ajax({
type: 'POST',
url: woocommerce_params.ajax_url,
data: data,
success: function( response ) {
if ( response ) {
var order_output = $(response);
$('#order_review').html(order_output.html());
$('body').trigger('updated_checkout');
}
}
});
}
After a bit of digging , and because im not php expert neither wp expert , but i can tell where the issue is.
First of all you should understand what add_action is , it is well explained here
If you needed to create an AJAX handler for an "add_foobar" request, you would create a hook like this:
add_action( 'wp_ajax_add_foobar', 'prefix_ajax_add_foobar' );
add_action( 'wp_ajax_nopriv_add_foobar', 'prefix_ajax_add_foobar' );
function prefix_ajax_add_foobar() {
// Handle request then generate response using WP_Ajax_Response
}
Using the above example, any time an AJAX request is sent to WordPress, and the request's 'action' property is set to 'add_foobar', this hook will be automatically executed. For example, the following code would execute the above hook.
jQuery.post(
ajaxurl,
{
'action': 'add_foobar',
'data': 'foobarid'
},
function(response){
alert('The server responded: ' + response);
}
);
so now you got how actions works , then you have to get how the transposh.php ajax part works , from the transposh.php file ( i recommend you open the file in a good text editor like sublime text ) , in line 437 :
//buddypress old activity
if (#$_POST['action'] == 'activity_get_older_updates') {
$this->target_language = transposh_utils::get_language_from_url($_SERVER['HTTP_REFERER'], $this->home_url);
$this->attempt_json = true;
}
this simply tells our script to fire translation when this action is called, what you have to do is customizing this line a bit so it fires upon you ajax request (update_checkout()).
if you check update_checkout() function you will find the corresponding action : 'woocommerce_update_order_review'
Solution:
1. Add you wp actions
add_action( 'wp_woocommerce_update_order_review', 'woocommerce_update_order_review' );
//preferably add this to line 207 in transposh.php with other add actions.
2. Instead of adding your own function , just modify the current buddypress example.
if (#$_POST['action'] == 'activity_get_older_updates')
to be
if (#$_POST['action'] == 'activity_get_older_updates' || #$_POST['action'] == 'woocommerce_update_order_review' )
//fire translation if action is equal to buddypress activity get older updates or action is equal to woocommerce update checkout.
3. this guy recommends adding following condition to line 352 in transposh.php
if ($this->is_special_page($_SERVER['REQUEST_URI']))
to be
if ($this->is_special_page($_SERVER['REQUEST_URI'])&& !$this->attempt_json)
found here : http://cl.ly/Shdn/o
I hope i had a link to your page where you are using this , but you could not provide an example , so i hope this solution will work as it was meant to be.

Categories