Hi, so I am trying to output JavaScript statements based on a condition. It works if placed directly in View but fails when placed within
<% section="scripts" %>
Example
<%
IF pcCode
%>
<script type="text/javascript">
var output = "1";
</script>
<%
ELSE
%>
<script type="text/javascript">
console.log('Do something different');
</script>
<%
ENDIF
%>
Is there a way to get round this and nest FoxPro code within sections?
The .prg output (below) translates the condition as string
IF (!wwScriptIsLayout)
wwScriptIsLayout = .T.
wwScriptSections.Add("scripts",[] + CRLF + ;
[] + CRLF +;
[ -%] + CRLF +;
[ if EmptyOrNull(pcCode)] + CRLF +;
[ %-] + CRLF +;
[ <script type="text/javascript">] + CRLF +;
Sections are evaluated not executed as compiled code, so they don't support full structured code.
However you can use simple IF blocks like this:
<% section="scripts" %>
<!-- this works -->
<%= DateTime() %>
<!-- Simple IF blocks work, but not ELSE -->
<%
* plValue = .T. && assume plValue is PRIVATE/PUBLIC
if plValue %>
TRUE
<% endif %>
<% IF !plValue %>
FALSE
<% ENDIF %>
<% endsection %>
IF
blocks are a special use case for evaluation.
As a general rule though, keep 'commands' out of SECTIONs - but you can use expressions. If you need something more complex create a function that you call from the section or use RenderPartial()
to embed a more complex compiled script block.
More info on sections can be found in this topic:
Thanks Rick. Worked like a charm.
Do you have an example of how to call functions within a section?
Use case: Each page in my application requires a JavaScript object with details specific to the page. The general structure is the same except for minor differences (field names & corresponding data). RenderPartial would be ideal if it accepts parameters but in lieu of that, is it possible to use functions to inject code into views?
Just like <%= DateTime() %>
works, you can use any Fox function instead of DateTime(), including your own UDF's. And these UDF's can return anything, including javascript.
Look at the topic I linked - it has examples of most situations.
Calling functions is the same as in the main section of the Content (or Layout) page:
Total: <%= poInvoice.CalculateInvoiceTotal() %>
+++ Rick ---
Thanks Rick.
Minor question: what is the name given to the cursor when you call o.DataSetToCursors(loDs)?
It is not stated in the documentation.
The cursor names are determined by the DataSet and DataTable names in the XML.
+++ Rick ---
I am not specifying DataSet or Table name in my query so the default DataSet name is NewDataSet and default DataTable (Table[0]) name is Table. In this case, what will be the name of the cursor in FoxPro?
<?xml version="1.0"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Table">
<xs:complexType>
<xs:sequence>
<xs:element name="id" type="xs:int" minOccurs="0" />
<xs:element name="name" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
I got the name from the Data Session window. Cursor name is table. Thanks.
The name is determined by whatever your generation code names those tables. It's not always going to be Table - I think that's the default if the data set is created with tables that are not named. It's going to be table
table1
table2
etc if the tables are not named.
This is entirely controlled by the DataSet that creates the XML. You can iterate through the XmlAdapter names if you need to by going to XmlAdapter from Dataset if you need to figure out what the names are, but usually you know what the name is coming into your application.
+++ Rick ---