I am receiving a JavaScript error due to the ASP.net bundle functionality, the JS code works fine before it gets minified but not after.
The issue Is have a isSelected variable that contains a boolean. But when the code gets minified it shortens this variable name to i. But in the $.each method I create an inline function with two parameters one being i.
It seems the minification logic failed to realize that renaming the variable to i would conflict with the code in my inline function.
Is this a bug with the ASP.net bundling system? If not how am I recommended to solve this, I am concerned that although I could just rename the parameter name that this bug could crop up in other parts of my web application.
Original JS code
function ItemManagerUpdateUi(instance) {
var selectedValue = instance.ItemCombo.GetValue();
var selectedItem = ItemManagerGetSelectedItem(instance);
var isSelected = selectedValue != null;
var isNewSelected = selectedValue == -1;
var applyText = isNewSelected ? "Add" : "Apply";
var text = isNewSelected ? "" : instance.ItemCombo.GetText();
var highestSortOrder = 0;
$.each(instance.Items, function (i, e) {
if (e.SortOrder > highestSortOrder)
highestSortOrder = e.SortOrder;
});
var sortOrder = isNewSelected || !isSelected ? highestSortOrder + 1 : selectedItem.SortOrder;
$('#' + instance.EditPanelId).toggle(isSelected);
$('#' + instance.ApplyButtonId).val(applyText);
$('#' + instance.DeleteButtonId).toggle(!isNewSelected);
var labelWidth = $(instance.ItemCombo.GetMainElement()).closest('.rbox-clearfix').find('.labelStyle').width() + 15;
$('#' + instance.ButtonPanelId).css('margin-left', labelWidth + 'px');
instance.TextControl.SetText(text);
instance.SortOrderControl.SetNumber(sortOrder);
$.each(instance.CustomFields, function (i, e) {
var value = isNewSelected || !isSelected ? null : selectedItem[e.DataName];
var dxControl = eval(e.ControlName);
dxControl.SetValue(value);
dxControl.SetIsValid(true);
});
if (!isNewSelected)
$(instance.ItemCombo.GetMainElement()).find('.dms-combo-main-input').removeClass('newActivityItem');
instance.TextControl.SetIsValid(true);
}
JS code after minification
function ItemManagerUpdateUi(n) {
var u = n.ItemCombo.GetValue(),
f = ItemManagerGetSelectedItem(n),
i = u != null,
t = u == -1,
s = t ? "Add" : "Apply",
h = t ? "" : n.ItemCombo.GetText(),
r = 0,
e,
o;
$.each(n.Items, function(n, t) {
t.SortOrder > r && (r = t.SortOrder)
});
e = t || !i ? r + 1 : f.SortOrder;
$("#" + n.EditPanelId).toggle(i);
$("#" + n.ApplyButtonId).val(s);
$("#" + n.DeleteButtonId).toggle(!t);
o = $(n.ItemCombo.GetMainElement()).closest(".rbox-clearfix").find(".labelStyle").width() + 15;
$("#" + n.ButtonPanelId).css("margin-left", o + "px");
n.TextControl.SetText(h);
n.SortOrderControl.SetNumber(e);
console.log(i);
$.each(n.CustomFields, function(i, e) {
console.log(i);
var value = t || !i ? null : f[e.DataName]
, dxControl = eval(e.ControlName);
dxControl.SetValue(value);
dxControl.SetIsValid(!0)
});
t || $(n.ItemCombo.GetMainElement()).find(".dms-combo-main-input").removeClass("newActivityItem");
n.TextControl.SetIsValid(!0)
}
EDIT
After more research it seems removing the eval line of code fixes the issue. For the time being I changed my code to not use eval although this still seems like a bug in the bundle process, for some reason you have these strange behaviour when using eval
Related
Can someone give me a hand and tell me what does this "+e+" do in the following script (taken from
https://tracking.crealytics.com/lib/multi_conversion.min.js
)? I highlighted it in black:
(function(){var
t,e,n;this.__multi_conversion_tracking=function(e,n){var i,c,r;return
i=document.getElementsByTagName("body")[0],c=document.createElement("div"),c.id="multi_conversion_tracking",c.style.display="none",r=document.createElement("iframe"),r.src=t(e,n,1),c.appendChild(r),i.appendChild(c)},n=function(){return"https:"===location.protocol.toLowerCase()?"https":"http"},t=function(t,e,i){return
null==i&&(i=1),""+n()+"://tracking.crealytics.com/"+t+"/multi_check.php
?data="+e+" &random="+(new Date).getTime()+"
&frame="+i},e=function(t,e){return-1!==t.indexOf(e,t.length-e.length)}}).call(this);
I am trying to figure out why this script is not parsing correctly the following tag:
<script
src="https://tracking.crealytics.com/lib/multi_conversion.min.js"></script>
<script type="text/javascript"> var transactionString =
{{CrealyticsProductsInfo}};__multi_conversion_tracking(70,
"transactionString"); </script> <noscript> <div style="display:inline;"> <img
src="https://tracking.crealytics.com/70/multi_check.php?data=transactionString">
</div> </noscript>
this is the assignation I give the variable in my tracking code:
var divElement = document.createElement("Div");
divElement.id = "transactionString";
divElement.setAttribute('data-transaction-string', products_info);
It is supposed to mimic the following div element:
<div id='transactionString' data-transaction-string='DATA'></div>
multi_conversion_tracking function takes two parameters, e and n. the value of the first parameter (e) will be appended to the data parameter in that query string being composed using + e +
e it's just argument of function t. It concatenating e argument with another parts of url.
__multi_conversion_tracking call t function r.src = t(e, n, 1)
(function() {
var t, e, n;
this.__multi_conversion_tracking = function(e, n) {
var i, c, r;
return i = document.getElementsByTagName("body")[0],
c = document.createElement("div"),
c.id = "multi_conversion_tracking",
c.style.display = "none",
r = document.createElement("iframe"),
r.src = t(e, n, 1),
c.appendChild(r),
i.appendChild(c)
}, n = function() {
return "https:" === location.protocol.toLowerCase() ? "https" : "http"
}, t = function(t, e, i) {
return null == i && (i = 1), "" + n() + "://tracking.crealytics.com/" + t + "/multi_check.php ?data=" + e + " &random=" + (new Date).getTime() + " &frame=" + i
}, e = function(t, e) {
return -1 !== t.indexOf(e, t.length - e.length)
}
}).call(this)
You concat a string with a variable, or multiple variables, with this.
For example
var e = "johan855";
var string = "Hello " + e + ".";
console.log(string);
And / or
var e = "johan855";
var a = "Hello ";
var dot = ".";
var string = a + e + dot;
console.log(string);
will output
Hello johan855.
The "+e+" part in this javascript code is just a concatenation of the var e with other elements to create a string.
I'm trying to use jQuery on a Joomla site, and Joomla loads jQuery in noConflict mode. I'm trying to wrap my code in (function($){ ... })(jQuery);.
This works:
function calculate()
{
var de = document.calculator.de.value;
var para = document.calculator.para.value;
var quantia = document.calculator.quantia.value;
var pais = jQuery("#para option:selected").text();
var curr = (pais == "Brazil" ? "Reais" : "Euro");
var tax = (pais == "Brazil" ? 0 : 3)
result = Math.round(quantia * para) + ' ' + curr;
jQuery('#result').text(result);
e.preventDefault();
return false;
}
This doesn't work (Uncaught ReferenceError: calculate is not defined):
(function($){
function calculate()
{
var de = document.calculator.de.value;
var para = document.calculator.para.value;
var quantia = document.calculator.quantia.value;
var pais = $("#para option:selected").text();
var curr = (pais == "Brazil" ? "Reais" : "Euro");
var tax = (pais == "Brazil" ? 0 : 3)
result = Math.round(quantia * para) + ' ' + curr;
$('#result').text(result);
e.preventDefault();
return false;
}
})(jQuery);
I'm probably missing a small detail, but where am I going wrong?
The function calculate is local to the closure. The best solution would be putting all of your code into the closure. In case this is not possible you can assign the function to window via:
window.calculate = calculate;
You can also return it from the closure and then assign it to the calculate variable:
calculate = (function($) {
...
return calculate;
})(jQuery);
I am trying to display JSON data on a list but my javascript code gets stuck in the middle of wlCommonInit() function.
function wlCommonInit(){
WL.Logger.debug("inside the wlcommoninit");
busyIndicator = new WL.BusyIndicator('AppBody');
var $list = $("ul#myList");
$list.append('<li> ' + "resrere" +
'</li>');
getData();
$list.append('<li> ' + "resrere" +
'</li>');
}
function getData() {
$.mobile.showPageLoadingMsg();
WL.App.overrideBackButton (function(){WL.App.close();});
var invocationData = {
adapter : 'StudentInfo',
procedure : 'getStudentInfos'
};
WL.Client.invokeProcedure(invocationData,{
onSuccess : loadFeedsSuccess,
onFailure : getDataFailure,
});
}
function loadFeedsSuccess(result){
if (!result || !result.invocationResult || !result.invocationResult.items || result.invocationResult.items.length == 0)
alert("Could not retrieve feeds");
feeds = result.invocationResult.items;
$("ul#myList").empty();
for (var i=0; i<feeds.length; i++){
var dataItem = feeds[i];
var listItem = $("<li>" + dataItem.question + "</li>");
$("ul#myList").append(listItem);
}
}
In this code, it sticks at getData(); it displays the first "resrere" but it does not display second "resrere". I can not find the problem, so I can not create any solution. Thanks for your help.
items should be resultSet.
Tested locally and verified to work after the below changes.
Change this:
if (!result || !result.invocationResult ||
!result.invocationResult.items || result.invocationResult.items.length
== 0)
To This:
if (!result || !result.invocationResult ||
!result.invocationResult.resultSet ||
result.invocationResult.resultSet.length == 0)
And this:
feeds = result.invocationResult.items;
To this:
feeds = result.invocationResult.resultSet;
Added tinyMCE as inline editor. Have a next probllem : first time this is work good - show with custom style (as I setup), works correctly but when I click cancel and then start edit again I have empty editor - without text in edit area. so this is a code:
UPD : cm.Node - wrapper for docuement.createElement and el.setAttribute, cm.getByAttr('attr', 'attr_val', el) - get elemnt by attr from el. req - wrapper for AJAX, cm.merge - like array_merge in PHP
var EditBlock = function(){
var my = this;
var o = cm.merge({
'id' : '',
'act' : '',
'val' : '',
'nobr' : false,
'text' : false,
'onSaved' : function(){},
'onSave' : function(){},
'params' : {'iconsPath' : 'interface/common/images/stdc/nicEditorIcons.gif'}
}, arguments[0]);
var prefix = 'tinyMCE_' + Math.random() + '_';
var node = cm.getEl(o.id);
var txtArea = cm.addClass(cm.Node('textarea', {'id' : prefix + o.id, 'style': ('width:' + node.offsetWidth + 'px')}), prefix + o.id);
var saveBtn = cm.Node('input', {'type':'button', 'value':'Save'});
var cancelBtn = cm.Node('input', {'type':'button', 'value':'Cancel'});
var container = cm.Node('div', txtArea, cm.Node('div', saveBtn, cancelBtn));
var plainText = function(node){
var str = '';
var childs = node.childNodes;
for(var i = 0, ln = childs.length; i < ln; i++){
if(childs[i].nodeType == 3)
str += childs[i].nodeValue;
else if(childs[i].childNodes.length)
str += plainText(childs[i]);
}
return str;
}
var init = function(){
node.onclick = my.edit;
cancelBtn.onclick = my.close;
saveBtn.onclick = function(){
my.save();
my.close();
}
}
my.save = function(){
var tmp = cm.Node('div', tinyMCE.get(prefix + o.id).getContent());
var content = o.text? plainText(tmp) : tmp.innerHTML;
o.onSave(content);
node.innerHTML = content;
req({
'act' : o.act,
'data' : 'data[content]=' + escape(content) + (o.val? '&data[val]=' + o.val : ''), 'handler' : function(){o.onSaved(content)}
});
}
my.close = function(){
tinyMCE.init({
'editor_deselector' : prefix + o.id
});
container.parentNode.removeChild(container);
node.style.display = 'block';
}
my.edit = function(){
txtArea.value = node.innerHTML;
node.style.display = 'none';
node.parentNode.insertBefore(container, node);
var styles = '';
var styleRef = cm.getByAttr('rel', 'stylesheet');
for(var i = 0, ln = styleRef.length; i < ln; i++){
styles += (i > 0? ',' : '') + styleRef[i].href;
}
tinyMCE.init({
'height' : '100%',
'content_css' : styles + ',/sdtc-new/nc/interface/common/css/mce-editor.css',
'mode' : "specific_textareas",
'editor_selector' : prefix + o.id
});
}
init();
}
use this like :
new EditBlock({'onSave' : function(content){
page.content = content;
viewDepartment(page);
}, 'id':'depContent', 'act' : '/departments/setContent/', 'val' : page.id, 'params' : {buttonList : ['fontSize','bold','italic','underline','strikeThrough','html']}});
So ... again about problem. When first time start to edit that all works fine when click save - all works too (still exists some bugs but after saving I can click and start edit again) but when click cancel that editor is hide but when I click to edit again I have a empty edit area. I see to console and find that after canceling when I start editing again then I create new edit but old not destroy - only hidden.
I try to usetynyMCE.Editor class methods like hide and show and setContent and was a some result - after canceling I could edit egain but edit area was without styles and buttons.
Please help. If would be quaestion by code - I pleasure to answer.
Thanks.
Don't use hide() and show() here. You should shut down tinymce correctly in order to be able to reinitialize a tinymce editor with the same id as the first one.
To shut down an edtor instance use:
tinymce.execCommand('mceRemoveControl',true,'editor_id');
To reinitialize use
tinymce.execCommand('mceAddControl',true,'editor_id');
Please note!
These have since changed, you may have better luck with (for newer versions, 4+ I think):
try mceRemoveEditor and mceAddEditor instead...as in:
tinymce.execCommand('mceRemoveEditor',true,'editor_id');
tinymce.execCommand('mceAddEditor',true,'editor_id');
Ok, feeling stupid here, but wondering what the problem is here exactly.
Although the function works as it should, I get this JS Error in Opera. Not sure about other browsers...
Uncaught exception: TypeError: Cannot
convert
'document.getElementById("shoutbox_area"
+ moduleId)' to object
oElement = document.getElementById("shoutbox_area"
+ moduleId).childNodes;
Here is the relevant code:
function appendShout(XMLDoc)
{
var shoutData = XMLDoc.getElementsByTagName("item");
var oElement = [];
if (shoutData.length > 0)
{
var moduleId = shoutData[0].getAttribute("moduleid");
if (shoutData[shoutData.length - 1].getAttribute("lastshout") != "undefined")
{
for (var i = 0; i < shoutData.length; i++)
if (shoutData[i].firstChild.nodeValue != 0)
document.getElementById("shoutbox_area" + moduleId).innerHTML += shoutData[i].firstChild.nodeValue;
oElement = document.getElementById("shoutbox_area" + moduleId).childNodes;
var i = oElement.length;
while (i--)
{
if (i % 2 == 0)
oElement[i].className = "windowbg2";
else
oElement[i].className = "windowbg";
}
oElement[oElement.length - 2].style.borderBottom = "1px black dashed";
}
}
}
Can someone please help me to understand why it is giving me an error here:
oElement = document.getElementById("shoutbox_area" + moduleId).childNodes;
Can I not assign an array to the childNodes?
EDIT:
This JS Error occurs when I try and delete a shout. The JS function for deleting a shout is this:
function removeShout(shout, moduleID)
{
var shoutContainer = shout.parentNode.parentNode;
var send_data = "id_shout=" + shout.id;
var url = smf_prepareScriptUrl(smf_scripturl) + "action=dream;sa=shoutbox;xml;" + "delete_shout;" + "canmod=" + canMod[moduleID] + ";" + sessVar + "=" + sessId;
sendXMLDocument(url, send_data);
var shoutID = 0;
while (shoutID !== null)
{
var shoutID = document.getElementById(shout.parentNode.id);
var moduleID = shoutID.parentNode.getAttribute("moduleid");
if (shoutID.parentNode.lastChild)
{
var url = smf_prepareScriptUrl(smf_scripturl) + "action=dream;sa=shoutbox;xml;get_shouts=" + (shoutID.parentNode.lastChild.id.replace("shout_", "") - 1) + ";membercolor=" + memberColor[moduleID] + ";maxcount=" + maxCount[moduleID] + ";shoutboxid=" + shoutboxID[moduleID] + ";textsize=" + textSize[moduleID] + ";parsebbc=" + parseBBC[moduleID] + ";moduleid=" + moduleID + ";maxcount=" + maxCount[moduleID] + ";canmod=" + canMod[moduleID] + ";" + sessVar + "=" + sessId;
getXMLDocument(url, appendShout);
}
element = shoutID.parentNode.childNodes;
var i = element.length;
while (i--)
{
if (i % 2 == 0)
element[i].className = "windowbg2";
else
element[i].className = "windowbg";
}
shoutID.parentNode.removeChild(shoutID);
}
}
Am using the following functions for the sending and getting the XMLHttpRequest as you may have noticed already in the removeShout function above:
// Load an XML document using XMLHttpRequest.
function getXMLDocument(sUrl, funcCallback)
{
if (!window.XMLHttpRequest)
return null;
var oMyDoc = new XMLHttpRequest();
var bAsync = typeof(funcCallback) != 'undefined';
var oCaller = this;
if (bAsync)
{
oMyDoc.onreadystatechange = function () {
if (oMyDoc.readyState != 4)
return;
if (oMyDoc.responseXML != null && oMyDoc.status == 200)
{
if (funcCallback.call)
{
funcCallback.call(oCaller, oMyDoc.responseXML);
}
// A primitive substitute for the call method to support IE 5.0.
else
{
oCaller.tmpMethod = funcCallback;
oCaller.tmpMethod(oMyDoc.responseXML);
delete oCaller.tmpMethod;
}
}
};
}
oMyDoc.open('GET', sUrl, bAsync);
oMyDoc.send(null);
return oMyDoc;
}
// Send a post form to the server using XMLHttpRequest.
function sendXMLDocument(sUrl, sContent, funcCallback)
{
if (!window.XMLHttpRequest)
return false;
var oSendDoc = new window.XMLHttpRequest();
var oCaller = this;
if (typeof(funcCallback) != 'undefined')
{
oSendDoc.onreadystatechange = function () {
if (oSendDoc.readyState != 4)
return;
if (oSendDoc.responseXML != null && oSendDoc.status == 200)
funcCallback.call(oCaller, oSendDoc.responseXML);
else
funcCallback.call(oCaller, false);
};
}
oSendDoc.open('POST', sUrl, true);
if ('setRequestHeader' in oSendDoc)
oSendDoc.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
oSendDoc.send(sContent);
return true;
}
Hopefully this is good enough, you can do a view source on it to see the actual HTML, but there are attributes that get added to the Shoutbox tags at runtime so as to be XHTML compliant, etc..
Please let me know if there is anything else you need?
Thanks :)
The code is breaking because shoutID is null in the second of these two lines, the second time through the loop:
var shoutID = document.getElementById(shout.parentNode.id);
var moduleID = shoutID.parentNode.getAttribute("moduleid");
The first of those lines is strange. Why not just use var shoutID = shout.parentNode;?
Also, the moduleId attribute seems to be nowhere around.
What are you trying to achieve with the while loop?