649
Views
14
Comments
Solved
Reevealuate an Unescaped Javascript Expression
Question

Hi.

I'm using the Resize Cols Widget from the Forge. to resize a table with 2 Columns. The left column has a List Records in it. When I make that smaller, it squishes it up and looks a bit hard to read. I've played about with CSS height and word wrap which has made an effect.

I did use the Outsystems Actions to work out the percentage of the first column against the total width and I used this percentage to calculate how many letters of each column to show. (Some columns have a Lot of information in). This worked, but it called the server each time, which is not ideal.

I replicated it in JavaScript in an Unescaped Expression- see below.

However, this doesn't reexecute when I resize it. Even if I put this JavaScript in the OnNotify Action. It only recalculates if I refresh the page. Is there anyway I can get this JavaScript to re-evaluate when the Session Variable changes?


"<script>


var str = """+EncodeJavaScript(ListRecords1.List.Current.DateTimeReceived)+""";


var columnString="""+EncodeJavaScript(Session.ResponsiveTables)+"""


var columnSizes = columnString.split(';');


var paneOne=columnSizes[0];


var paneTwo = columnSizes[1];


var tableSize = columnSizes[2];


var percentages = paneOne/tableSize; 


var subString = percentages*16;


var res= """";


if(subString<16)


{


res = str.substring(0, subString)+""..."";


}


 


else


 


{


res = str.substring(0,19);


}


document.getElementById('"+EncodeJavaScript(DTR.Id)+"').innerHTML = res;


</script>"


 



2020-02-28 09-46-54
Eduardo Jauch
Solution

Hi Edward,

Put your JavaScript inside a function:

"<script>

function f(DateTimeReceived, ResponsiveTables, id) {

  var str = ""DateTimeReceived"";   var columnString=""ResponsiveTables""   var columnSizes = columnString.split(';');   var paneOne=columnSizes[0];   var paneTwo = columnSizes[1];   var tableSize = columnSizes[2];   var percentages = paneOne/tableSize;    var subString = percentages*16;   var res= """";   if(subString<16) {     res = str.substring(0, subString)+""..."";   } else {     res = str.substring(0,19);   }   document.getElementById('"Id"').innerHTML = res; } </script>"

Then, in the Preparation and in the OnNotify, you execute an action called RunJavaScript (it is in the HttpRequestHandler extensin), with the javascript:

"f(" + EncodeJavaScript(ListRecords1.List.Current.DateTimeReceived) + "," + EncodeJavaScript(Session.ResponsiveTables) + "," + EncodeJavaScript(Session.ResponsiveTables) + ");"

I think this way it will work :)

Cheers,
Eduardo Jauch

2016-04-21 20-09-55
J.
 
MVP

Hi,


I wonder why you are not using text-overflow: ellipsis ?

see more info on https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/




2020-02-28 09-46-54
Eduardo Jauch

J. wrote:

Hi,


I wonder why you are not using text-overflow: ellipsis ?

see more info on https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

I didn't even noticed that this was what the code was doing... xD

Edward, if it is just a matter of using ellipses, you can use it without the JavaScript (CSS can take care of it for you)

About the code, the explanation on why it will work only the first time, is that it will be evaluated only the first time, and will have the values of the first time. Using a function and executing it when needed (directly or through events) will give you the "dynamic" behavior that you are looking for.

2019-09-24 18-41-25
Jorge Martins
 
MVP

J. wrote:

Hi,


I wonder why you are not using text-overflow: ellipsis ?

see more info on https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

This would indeed be the best way to do it I think, but answering the question you asked (and ignoring the reason behind it) you should be able to use an Ajax Refresh to refresh the Expression where you have your JavaScript code... this would trigger the browser to re-evaluate the JavaScript. Have you tried it?

UserImage.jpg
Edward S

Eduardo Jauch wrote:

J. wrote:

Hi,


I wonder why you are not using text-overflow: ellipsis ?

see more info on https://css-tricks.com/snippets/css/truncate-string-with-ellipsis/

I didn't even noticed that this was what the code was doing... xD

Edward, if it is just a matter of using ellipses, you can use it without the JavaScript (CSS can take care of it for you)

About the code, the explanation on why it will work only the first time, is that it will be evaluated only the first time, and will have the values of the first time. Using a function and executing it when needed (directly or through events) will give you the "dynamic" behavior that you are looking for.

I completely missed the fact you need overflow:hidden; and white-space:nowrap for CSS And now it works wonderfully. Quicker than the JavaScript I wrote! CSS really is quite powerful!! 


UserImage.jpg
Edward S

Hi.


Thanks you all for your help. I am trying to implement them now. I've not got them to work. Chrome doesn't suggest any errors, so I imagine I've mis-interpreted something. I'm not a natural at this!!

As for the CSS, I think the reason we don't do it is because some of our data looks like this

EmailOne,

EmailTwo. Either that, or I am putting the CSS in the wrong area.

I'l get there eventually I am sure. Thanks everyone :)


Edward


UserImage.jpg
Edward S

Hi,

I am a little stuck with the JavaScript. Essentially, if I do alert(res) instead of
 document.getElementById('"Id"').innerHTML = res;


The alert, alerts the correct value. Am I missing something obvious? Or should that work?


2016-04-21 20-09-55
J.
 
MVP

Is it the real id you are passing (noticing a bug in Eduardo's code I think)


2020-02-28 09-46-54
Eduardo Jauch

J. wrote:

Is it the real id you are passing (noticing a bug in Eduardo's code I think)

Yes, the code is not perfect. I just tried to pass the idea of using a function :)
The id, in special, should be only 

document.getElementById(Id).innerHTML = res;

As it would be an input parameter in the function.

As well as the other two variables:

  var str = DateTimeReceived;  
  var columnString=ResponsiveTables

In fact, there was no need to the str and columnString variables at all... 

Aaaaaand... I didn't tested this :)

UserImage.jpg
Edward S

I am passing the ID of the Widget into document.getElementById, not the one you'd get if you viewed the Source Code?


e.g.

document.getElementById('"+EncodeJavaScript(DTR.Id)+"').innerHTML = res;




2016-04-21 20-09-55
J.
 
MVP

Dunno why should encode an id (that could be an issue), but yes. Furthermore, if it's just text, it's better to use .textContent

UserImage.jpg
Edward S

Hi,

The Encode JavaScript was stopping the date displaying. :) 

Because I was hardcoding the ID from the HTML, I guess I need to pass the ID in as a function like Eduardo says in order to get the value for each record in the list, or run the JavaScript in a loop


Edward_Theme_wt134:wtMainContent:wtListRecords1:0:wtDTR



UserImage.jpg
Edward S

Hi 

Thanks to you both so much for your help!!

I got it to work. I removed the Encode JavaScript and made the variable a function and I called the JavaScript in a Loop 

I added this to my JavaScript in order to account for the changing IDs in the List. And I call the JavaScript in a loop.

Now I just have to wait and see whether the business want this functionality!! :)


Thanks again :)


Edward



var id = """";


var prefix = ""Edward_Theme_wt134:wtMainContent:wtListRecords1:"";


id+=prefix;


id+=index;


var suffix = "":wtDTR""


id+=suffix;


 


document.getElementById(id).innerHTML = res;


return res;


}


</script>"


 


2020-02-28 09-46-54
Eduardo Jauch

Yes, it is ;)

Community GuidelinesBe kind and respectful, give credit to the original source of content, and search for duplicates before posting.