Search Articles


Sort By
  

Article Categories

Authors & MVPs

Kelly Ford

Introducing DNNDev University

The new DNNDev University doesn't have a winning football team. It is built on people - you and I and everyone who uses DotNetNuke and XMod Pro.

XModPro

Using AJAX with XMod Pro Feeds and Templates

XMod Pro is powerfully flexible. It can be extended in many ways and integrated with the rest of your page and site as well. Frequently, this integration is handled via Javascript. While most web developers can pump out Javascript and AJAX calls in their sleep, XMod Pro's ease-of-use attracts many users who may not be so familiar with this or may need an example to kick-start their development efforts.


Taking inspiration from a recent forum post, I wanted to show the basic components of how you can leverage XMod Pro's Feeds, Templates, HTML, and jQuery to create a modern user interface. In this instance we'll be creating a simple drop-down search/filter function. The idea is a simple, but often used UI pattern. You present the user with a list of items to search or filter by. Once the selection is made, the results appear below the list.


To make it easy for you to try out, I'll be using the DNN "Lists" table, which contains a list of countries and their regions (i.e. states in the US).


Here's a look at what we'll end up with. We're deliberately not including any styling as we just want to focus on the mechanics.



This solution is made up of one template and one feed. The template is used to build the drop-down list. The feed is used to generate the data that is displayed below the listbox. These are tied together with a little jQuery AJAX call. Let's get started.


Building Our Listbox


Our template is pretty straightforward.


The first thing we need to do is retrieve our list of countries in the tag. This is achieved by selecting those records from the Lists table that have a ListName of "Country". Notice that we're grabbing the EntryID and the Text columns. The Text column will contain the country name, while the EntryID is the unique identifier for the record. The EntryID is needed so that we can pass it to our Feed later on.


SELECT EntryID, Text FROM Lists WHERE ListName = 'Country' ORDER BY Text

After that, we just need to use XMod Pro's tempting abilities to build our list control like so:


 <HeaderTemplate>
   <label for="ddl-country">Pick a country</label>
   <select size="1" id="ddl-country">
   <option value=""></option>
 </HeaderTemplate>
<ItemTemplate> <option value="[[EntryID]]">[[Text]]</option> </ItemTemplate>
<FooterTemplate> </select> </FooterTemplate>

Here our HeaderTemplate contains a label and the opening HTML <select> tag with a size of 1, which will create the drop down list. I've also added an empty list item (the <option> tag). The ItemTemplate will be repeated for each record retrieved from the database so our ItemTemplate contains an <option> tag with it's value set to the EntryID and the item's display text set to the value of the Text column. This will build our drop-down list items. Finally we close out the HTML select tag with the </select> tag.


So, here's how our template looks thus far:


<xmod:Template UsePaging="False" Ajax="False">
  <ListDataSource CommandText="SELECT EntryID, Text FROM Lists WHERE ListName = 'Country' ORDER BY Text"/>
    <HeaderTemplate>
      <label for="ddl-country">Pick a country</label>
        <select size="1" id="ddl-country">
        <option value=""></option>
    </HeaderTemplate>
<ItemTemplate> <option value="[[EntryID]]">[[Text]]</option> </ItemTemplate>
<FooterTemplate> </select> </FooterTemplate> </xmod:Template>

The astute among you will see the: Ajax="False" property in the <xmod:template> tag and wonder why it's False if this is a post about using AJAX. Good question. The Ajax property sets XMod Pro to do automatic AJAX calls for certain aspects like paging through your list of results. It does all this behind the scenes. Since we're doing our own AJAX and our solution doesn't require paging, we don't need use it. </xmod:template>


Implementing the AJAX


IMPORTANT NOTE: Feeds are, by their nature, public. You generally do not want to make sensitive information available with Feeds. However, if you're using version 4 or later, you have the ability to specify the DNN Roles that are able to access the feed. We will not be implementing that in this example. Refer to the Feeds topic in the help file for more info.


The first thing we need is to add a DIV tag to our template that we can fill with our results. This is a simple matter of adding the HTML. The only item of note is that we're giving it a client-side ID to make it easy for jQuery to find it. We're also setting it to be invisible (display:none;) on first page load. Since the tag is initially empty, that isn't strictly required, though. Plus, we're adding a little padding for a bit better layout.


...
</xmod:Template>
<div id-"regions-list" style="padding:10px; display:none;"></div>

Finally, we use XMod Pro's handing jQueryReady tag to insert our jQuery code.


<xmod:jQueryReady>
$('#ddl-country').change(function(){
var parentId = $(this).val();
$.ajax( {
url: '/test_dnn615/DesktopModules/XModPro/Feed.aspx',
type: 'POST',
dataType: 'html',
data: {
"xfd" : "GetRegions",
"pid" : 0,
"parent" : parentId
},
success: function(data) {
$('#regions-list').html(data).show();
}
})
});
</xmod:jQueryReady>

If you want to know how a jQuery AJAX call is made in more detail and learn about the myriad options that are available, I refer you to the jQuery Docs.


In our code we're hooking up to the drop-down list's "onchange" event (the .change() method in jQuery). When the list value changes we will get the selected value (line 3) and assign it to a variable called "parentId". Remember, this is the EntryID from the database. Then we setup our AJAX call. This will call XMod Pro's Feed page (url), send its data via HTTP POST (type: 'POST'), expect to retrieve results in HTML format (dataType), and pass in three parameters (data): xfd, which is the name of the Feed we're going to create later; pid, which is the Portal's ID; and parent, which is the EntryID of the selected country.


Finally, we define a "success" function. This will execute when the AJAX call successfully retrieves the response from the Feed. The response is passed-in via a variable called "data". Our code then finds the "regions-list" DIV tag we just added, and sets its contents to whatever the Feed returned to us. It then makes the DIV tag visible for the world to see.


Here's how our finished template looks:


<xmod:Template UsePaging="False" Ajax="False">
<ListDataSource CommandText="SELECT EntryID, Text FROM Lists WHERE ListName = 'Country' ORDER BY Text"/> <HeaderTemplate> <label for="ddl-country">Pick a country</label>
<select size="1" id="ddl-country">
<option value=""></option>
</HeaderTemplate>
<ItemTemplate>
<option value="[[EntryID]]">[[Text]]</option>
</ItemTemplate>
<FooterTemplate>
</select>
</FooterTemplate>
</xmod:Template> <div id="regions-list" style="padding: 10px; display: none;"></div>
<xmod:jQueryReady>
$('#ddl-country').change(function(){
var parentId = $(this).val();
$.ajax( {
url: '/test_dnn615/DesktopModules/XModPro/Feed.aspx',
type: 'POST',
dataType: 'html',
data: {
"xfd" : "GetRegions",
"pid" : 0,
"parent" : parentId
},
success: function(data) {
$('#regions-list').html(data).show();
}
});
});
</xmod:jQueryReady>

Creating the Feed


If you're not familiar with XMod Pro's Feeds feature, it's an extremely flexible component that makes it possible to export RSS, CSV, XML, Excel, display printer-friendly pages, inject Javascript and more. If you can output your data in some text-based output, you can probably use feeds to do it. In our case, we're using it to generate some HTML to insert into the page with our template on it.


The great thing about Feeds is that they are a lot like Templates. So, if you can build a Template, you can build a feed. Let's get to it.


Feeds are created on the Manage Feeds page of XMod Pro's Control Panel.



Simple press the "New Feed" button and a dialog will appear. Select the Custom feed type and don't select any other options. We're going to create our feed from scratch.




Well, as you can see, we're not working quite from scratch. XMod Pro has built the skeleton for us to output HTML.


The first step is to name your feed. This is CRITICAL as it is the name we will use to call this feed from our page. Since we already created our AJAX call, we know what to name our Feed: "GetRegions" (without quotes).


Next, remove the tag and replace it with the following tag:


<ListDataSource CommandText="SELECT Value, Text FROM Lists WHERE ParentID = @parent">
<Parameter Name="parent" Value='[[Form:parent]]' DataType="Int32" DefaultValue="-1" />
</ListDataSource>

This retrieves the data for our output. It's job is to get a list of regions for a given country. So, it retrieves the Region's Code (stored in the table's Value column) and the Region's Name (stored in the table's Text column) IF the record's "ParentID" column matches the parent ID we pass-in (@parent). The @parent parameter is defined in the tag. The Parameter's Name is set to "parameter" and it's Value is set to the "parent" parameter being POSTed into the feed (refer back to our AJAX call). To help protect against XSS attacks, we also set the parameter's DataType to only accept a number (Int32). If no parameter is passed, then the DefaultValue for the parameter will be -1, essentially returning an empty result set.


<div id="regions-list" style="padding:10px; display: none;"></div>

The purpose of our Feed is to return a bullet list of regions from the selected country. With that in mind, and with your knowledge of Templates, this next section should be pretty self-explanatory and easily modifiable if you desire:


<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>Name: [[Text]] Code: [[Value]]</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate></pre>

Finally, here's the full Feed:


<xmod:Feed ContentType="text/html">
<ListDataSource CommandText="SELECT Value, Text FROM Lists WHERE ParentID = @parent">
  <Parameter Name="parent" Value='[[Form:parent]]' DataType="Int32" DefaultValue="-1" />
  </ListDataSource>
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>Name: [[Text]] Code: [[Value]]</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</xmod:Feed>

Comments & Ratings

    (Ratings: 0   Avg: )
Rate It!
Share It!