Reevealuate an Unescaped Javascript Expression

Reevealuate an Unescaped Javascript Expression

  

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>"


 



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

Solution

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/




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.

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?

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


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?


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


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;




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

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 :)

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



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>"


 


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!! 


Yes, it is ;)