Transposh plugin to translate Ajax loaded content - javascript

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.

Related

Why is my AJAX JQUERY trying to pass multiple variable values to php server side always returning an error?

I am trying to send multiple values from the client side to the server side through JavaScript. Here is my JavaScript JQUERY function below:
// This function addToRentalCart(car) adds the requested
// car to a user's rental cart. It does this through the use
// of an AJAX call to the server with the required data.
// Since the required car data is already on the associated
// html webpage (index.html) all this function does is read it
// from there and send it to the server side process.
// Server side processing will then take care of the rest
// of the operation.
function addToRentalCart (car)
{
var carPosition = 'carRow' + car;
var carAvailabilityCol = 'Col10';
var carAvailableElement = carPosition + carAvailabilityCol;
var carAvailable = document.getElementById(carAvailableElement);
if (carAvailable.innerHTML === 'N')
{ //If the car is not available
alert("Sorry, the car is not available now. Please try other cars.");
}
else
{ //If the car is available
//var carPictureFileCol = 'Col0'; //Set the column numbers of each desired variable
var carMakeCol = 'Col1';
var carModelCol = 'Col2';
var carYearCol = 'Col3';
var carPricePerDayCol = 'Col8';
var carMakeElement = carPosition + carMakeCol;
var carMake = document.getElementById(carMakeElement).innerHTML; //Get the car make or brand
var carModelElement = carPosition + carModelCol;
var carModel = document.getElementById(carModelElement).innerHTML; //Get the car model
var carPictureFile = carModel + '.jpg'; //Get the car picture file
var carYearElement = carPosition + carYearCol;
var carYear = document.getElementById(carYearElement).innerHTML; //Get the car year
var carPricePerDayElement = carPosition + carPricePerDayCol;
var carPricePerDay = document.getElementById(carPricePerDayElement).innerHTML;
carPricePerDay = carPricePerDay.substring(1); //Get the price per day without the dollar sign
$.ajax({
type: "GET",
url: "rentalCarsCart.php",
data: {"carPicFile": carPictureFile, "carBrand": carMake, "carMod": carModel,
"carYearMan": carYear, "carPPD": carPricePerDay},
dataType: "json",
success: function()
{
alert("You have successfully added this car to your rental cart");
},
error: function()
{
alert("error in Ajax call to cart url");
},
});
}
}
All values seem fine even according to the Apache Netbeans IDE output but it bombs out and displays the error alert always. I have even debugged it inside Chrome developer tools using a breakpoint and step through method and all values are fine. It is bombing out inside JQUERY.JS itself and not sending the GET request to the PHP backend. Does anyone have any ideas why? I can't seem to find anything wrong with my code. If you can help me I would be grateful.
My server side code is as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Rental Car Shopping Cart</title>
<style>
h1 {text-align: center;}
button:hover{cursor: pointer;}
</style>
<h1>Car Reservation</h1>
</head>
<body>
<?php
header("Access-Control-Allow-Origin: *");
$carPicture = $_GET['carPicFile']; // get car picture filename
$carMake = $_GET['carBrand']; // get the make of the car
$carModel = $_GET['carMod']; // get the car model
$carYear = $_GET['carYearMan']; // Get the car year of manufacture
$carPricePerDay = $_GET['carPPD']; // Get the car price per day
echo ('<div>');
echo ($carPricePerDay);
echo ('</div>');
?>
</body>
</html>
Phil was right in the comment above that you don't need a dataType response from the PHP server side coding, so I removed it. I also found out the other problem on the PHP backend although not shown in the above PHP code which was very basic originally but got more complicated later:
Instead of if (($carPicture!=0) && ($carMake!=0) && ($carModel!=0) && ($carYear!=0) &&
($carPricePerDay!=0))
{
session_start(); //etc
Try:
if (isset($carPicture) && isset($carMake) && isset($carModel) && isset($carYear) && isset($carPricePerDay))
{
session_start(); //etc
The reason being that when the variables are undefined they are also equal to zero or I am not sure why it decided to work with the bottom version. Positive logic seems to be better than negative logic for PHP. Thanks guys.

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

asynchronous HTTP (ajax) request works in script tag but not in js file

I have this ajax call here in a script tag at the bottom of my page. Everything works fine! I can set a breakpoint inside the 'updatestatus' action method in my controller. My server gets posted too and the method gets called great! But when I put the javascript inside a js file the ajax call doesn't hit my server. All other code inside runs though, just not the ajax post call to the studentcontroller updatestatus method.
<script>
$(document).ready(function () {
console.log("ready!");
alert("entered student profile page");
});
var statusdropdown = document.getElementById("enumstatus");
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById("enumstatus");
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
</script>
Now I put this at the bottom of my page now.
#section Scripts {
#Scripts.Render("~/bundles/studentprofile")
}
and inside my bundle.config file it looks like this
bundles.Add(new ScriptBundle("~/bundles/studentprofile").Include(
"~/Scripts/submitstatus.js"));
and submitstatus.js looks like this. I know it enters and runs this code because it I see the alert message and the background color changes. So the code is running. Its just not posting back to my server.
$(document).ready(function () {
console.log("ready!");
alert("submit status entered");
var statusdropdown = document.getElementById('enumstatus');
statusdropdown.addEventListener("change", function (event) {
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
// do something with the returned value e.g. display a message?
// for example - if(data) { // OK } else { // Oops }
});
var e = document.getElementById('enumstatus');
if (e.selectedIndex == 0) {
document.getElementById("statusbubble").style.backgroundColor = "#3fb34f";
} else {
document.getElementById("statusbubble").style.backgroundColor = "#b23f42";
}
}, false);
});
In the console window I'm getting this error message.
POST https://localhost:44301/Student/#Url.Action(%22UpdateStatus%22,%20%22Student%22) 404 (Not Found)
Razor code is not parsed in external files so using var id = "#Model.StudentId"; in the main view will result in (say) var id = 236;, in the external script file it will result in var id = '#Model.StudentId'; (the value is not parsed)
You can either declare the variables in the main view
var id = "#Model.StudentId";
var url = '#Url.Action("UpdateStatus", "Student")';
and the external file will be able to access the values (remove the above 2 lines fro the external script file), or add them as data- attributes of the element, for example (I'm assuming enumstatus is a dropdownlist?)
#Html.DropDownListFor(m => m.enumStatus, yourSelectList, "Please select", new { data_id = Model.StudentId, data_url = Url.Action("UpdateStatus", "Student") })
which will render something like
<select id="enumStatus" name="enumStatus" data-id="236" data-url="/Student/UpdateStatus">
Then in the external file script you can access the values
var statusbubble = $('#statusbubble'); // cache this element
$('#enumStatus').change(function() {
var id = $(this).data('id');
var url = $(this).data('url');
var status = $(this).val();
$.post(url, { ID: id, Status: status }, function (data) {
....
});
// suggest you add/remove class names instead, but if you want inline styles then
if (status == someValue) { // the value of the first option?
statusbubble.css('backgroundColor', '#3fb34f');
} else {
statusbubble.css('backgroundColor', '#b23f42');
};
});

Ajax.Updater POST params not transmitted by Firefox

I am debugging code written by someone else - I am also a newbie at Ajax and JS. The code shown below uses Ajax (Prototype JavaScript framework, version 1.6.0.1) to submit a simple contact form and update the page with the response. It works perfectly with IE8 and fails with Firefox. I have traced the failure to the post parameters. The target file, mail.php, is not receiving any POST parameters when Firefox is the browser. Not just the values are missing - the params are not defined in the post. The URL is valid. The form, the Ajax JS files and the mail.php script are all on the same domain.
I have tried variations on defining var params as shown in several other Stack Overflow posts (inline, different assignment methods, etc). All produced the same results as the code below.
Any clue what is wrong?
FF results
Please try again. responseText='', url='http://domain.com/builder/mail.php',
form_name='dom', form_message='testing', form_email='dom#domain.com',
form_to='info#domain.com'
IE8 results
Message Sent!
JS function
function sendForm(F)
{
$("contact_form").hide();
$("ajax-loader").show();
var url = site_url+'mail.php';
var form_message = escape($("message").value);
var form_name = escape($("name").value);
var form_address = escape($("address").value);
var form_phone = escape($("phone").value);
var form_email = escape($("email").value);
var form_how_learn = escape($("how_learn").value);
var form_to = escape($("to").value);
var params = {message: form_message,
name: form_name,
address: form_address,
phone: form_phone,
email: form_email,
how_learn: form_how_learn,
to: form_to};
var ajax = new Ajax.Updater(
'contact_form',
url,
{
method: 'post',
parameters: params,
onComplete: function (response)
{
$("ajax-loader").hide();
if (response.responseText == "ok")
{
$("contact_form").innerHTML = "<p style=\"color:green;\">Message Sent!</p>";
$("contact_form").show();
}
else
{
// Debug code added
$("contact_form").innerHTML = "<p style=\"color:red;\">Please try again."+
" responseText='"+response.responseText+"',"+
" url='"+url+"',"+
" form_name='"+form_name+"',"+
" form_message='"+form_message+"',"+
" form_email='"+form_email+"',"+
" form_to='"+form_to+"'"+
"</p>";
$("contact_form").show();
}
},
onFailure: function ()
{
$("ajax-loader").hide();
$("contact_form").innerHTML = "<p style=\"color:red;\">Please try again.</p>";
$("contact_form").show();
}
}
);
return false;
}

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

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);
},

Categories