DNN Community Blog

The Community Blog is a personal opinion of community members and by no means the official standpoint of DNN Corp or DNN Platform. This is a place to express personal thoughts about DNNPlatform, the community and its ecosystem. Do you have useful information that you would like to share with the DNN Community in a featured article or blog? If so, please contact .

The use of the Community Blog is covered by our Community Blog Guidelines - please read before commenting or posting.


Using jQuery and AJAX

We’ve come a long way thus far and in our last blog we were able to get our Tasks table data returned as a JSON object via our web service. In this blog we’re going to return to our view control and update it so that we can get these tasks surfaced in our view control. In order to do this we’ll use jQuery, a popular JavaScript library, to help us do some dynamic manipulating of both the layout and data in our view. If you’re not familiar with jQuery I’ve provided some links at the bottom of this blog entry that will be helpful. 

Sidenote: As I just mentioned we will use jQuery in this tutorial, but you could definitely use other JavaScript libraries such as Angular if you like. Just whatever floats your boat!

Updating the code in our View
Now it’s time to get into some code and get these tasks to show in our module already! One important thing to note is that DNN loads and uses jQuery by default. Thus, we don’t need to register any scripts or make calls to CDN’s because jQuery is already in the house and being used. 

Open up the View.ascx file in Visual Studio and go into the “Code view”.  We’ve previously coded and styled this to give us the two grey boxes in our view. The DIV on the left is for adding tasks and the DIV on the right is for listing out the tasks as we add them. Currently we’ve got some placeholder information in the Task List DIV on the right. All we have to do is to write some jQuery to get these tasks showing up.

Beneath the last closing </DIV> tag start a script block. For any of you front-end developers this will be something you’re used to, but for anyone who is new it may not be. For that reason we’re going to be as thorough as possible. To start a script block just include this code 

<script type =”text/javascript”>

</script>

Now with our script block started we need to include some jQuery code to go out and fetch our JSON that is awaiting us. JQuery has a short-hand AJAX (asynchronous JavaScript and XML) method for fetching JSON and we will make use of it. You can find out more about this $.getJSON function on the jQuery page and on the w3Schools page

Update your script block to read:

<script type="text/javascript">
    $.getJSON(
        "/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=416",
       function (result) {
           var parsedTaskJSONObject = jQuery.parseJSON(result);
          console.log(parsedTaskJSONObject);            
        });
</script>

Now let’s discuss this code here to gain more understanding. The first line we see is the $.getJSON and that is jQuery’s shorthand method for grabbing JSON via AJAX. On the next line you see a URL and this URL just happens to be the URL that points to our web service where our JSON object is awaiting us. After the URL we see “function(result)” and what this represents is that we are about to create a function based on the resulting data of our JSON call. 

Next we create a variable, in this case named, “parsedTaskJSONObject” which is set equal to the result of our “result” object being parsed by jQuery’s parseJSON method. This variable name is probably too long for most, but I'm going to name it that just for clarity's sake. Then we instantly turn around and put in a “console.log(parsedTaskJSONObject);”. This “console.log” will log whatever we pass into it into the console, which makes it easy for us to check as to whether or not we’re really getting any data back. You may wonder where the console resides. Most browsers have F12 tools with a console in them. I’m using Google Chrome and when using Chrome just click F12 and you’ll see the toolbar pop up. Then just click on the last option which is the console. If you’ve done everything correctly then you should be seeing some objects returned there. Expand those nodes and you should see our dummy data task object information there. It should look similar to this:

Logging objects in the console

If you see those objects then congrats, you’re making progress and we’re almost there. As a side note I frequently use the console.log method in order to check what’s going on within my JavaScript. If you ever wonder what is happening just console.log the information.  Now that we’re cooking with gas let’s keep right on trucking. 

Time to Loop Through Some Objects
We are successfully getting our data back as objects and now we need to do something with them. Update your code to read as the following and click save: 

<script type="text/javascript">
    $.getJSON(
        "/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=416",
        function(result) {
            var parsedTaskJSONObject = jQuery.parseJSON(result);
            console.log(parsedTaskJSONObject);
            $.each(parsedTaskJSONObject, function () {
                console.log(this.isComplete + this.TaskName + this.TaskDescription);
            });
             });
</script>

Once you click save and reload the website look in the console and see what’s there. You should see something that looks similar to this: 

Logging objects in a loop in the console

The reason we see all the information for each object on a row is because we just put in a loop and logged it all. If you look back up at the code just after the console.log(parsedTaskJSONObject) you see the jQuery syntax of $.each(parsedTaskJSONObject, function(){…}. This tells our code to loop through each JSON object and execute a function on that object. In our case, at least at the moment, our function that happens on each object is to simply logging the information of each object. Pay attention to the “this” syntax. When we say “this” we are referring to “this” object … in other words… the current object that we are looping through. After the “this” we tag the isComplete, TaskName, & TaskDescription properties of our objects. 

This confirms that we can successfully loop through our objects and grab each individual object. Now we need to take these objects and insert them into our TaskList on the right hand side of the screen. Next update your script to the following, save it, then reload the page:

<script type="text/javascript">
    $.getJSON(
        "/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=416",
       function (result) {
           var parsedTaskJSONObject = jQuery.parseJSON(result);
            $.each(parsedTaskJSONObject, function () {
                if (this.isComplete == true) {
                    $('.ListItems').append(
                        '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox" checked/></div>' +
                            '<div class="ListTaskName">' + this.TaskName + '</div>' +
                            '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');
                }
                else {
                    $('.ListItems').append(
                        '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox"/></div>' +
                        '<div class="ListTaskName">' + this.TaskName + '</div>' +
                        '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');
                }
            });
        });
</script>

Did you now get some data back in the module? If so, congrats… you’re moving right along! Let’s talk about this updated script. In this updated script we simply add in some new logic in the loop where we previously logged the items. We first run a check to see if the “isComplete” property is true for the current item we’re looping through. If it is true then we use jQuery to append some text to the “ListItems” DIV. You may wonder why we are doing it this way. Well I also am wondering why kind of… The whole reason we’re doing this is because we want the checkbox to be checked if the isComplete value is true and not checked is the value of isComplete is false. After doing some research it seems the only way we can get this to render correctly is to either include the “checked” syntax or not. There is no way to set it to true or false directly in the html that I can figure out. If you can figure a way to do this then please let us know in the comments below this blog entry. 

Looking specifically at the loop we see:

                    $('.ListItems').append(
                        '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox" checked/></div>' +
                            '<div class="ListTaskName">' + this.TaskName + '</div>' +
                            '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');
                     }

and on each line we are adding in a div with the checkbox syntax either present or not and then we’re adding in the + symbols because that’s how we concatenate in JavaScript. So whenever we hit a point where we want to add in a value from our object we then use the “this.TaskName” syntax. This is how we iterate through each item and log it to the screen. Fun stuff huh?


* UPDATE
The Shaun Walker has submitted a way to fix the checkbox "checked" scenario, which is really straight forward & simple (slapping myself here for not thinking about it previously). In order to not have to repeat the DIV items simply use the below code... and thanks Shaun!:

var checked = '';
if (this.isComplete == true) {
  checked = ' checked';
}
$('.ListItems').append(
  '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox"' + checked + '/></div>' +
  '<div class="ListTaskName">' + this.TaskName + '</div>' +
  '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');


Did you notice that the placeholders are still there? Let’s take them out so that only the real data is showing now. To remove the placeholder data just go back up to the “ListItems” DIV and delete the 3 child DIVS and you should be good to go.

While you might think we’re through we still have one bit of business to take care of at the moment. Again we have hard coded the URL into the script. And you’re probably already saying it here before you read it, but we can’t hard code the moduleId because that value will change dynamically. So how can we account for this? It’s not too bad to pull off actually. Update your script to read as follows, click save, then reload:

<script type="text/javascript">
var moduleId = <%= ModuleId %>;
    $.getJSON(
        "/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=" + moduleId,
       function (result) {
           var parsedTaskJSONObject = jQuery.parseJSON(result);
            $.each(parsedTaskJSONObject, function () {
                if (this.isComplete == true) {
                    $('.ListItems').append(
                        '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox" checked/></div>' +
                            '<div class="ListTaskName">' + this.TaskName + '</div>' +
                            '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');
                }
                else {
                    $('.ListItems').append(
                        '<div class="checkbox"><input class="cbxListIsComplete" type="checkbox"/></div>' +
                        '<div class="ListTaskName">' + this.TaskName + '</div>' +
                        '<div class="ListTaskDescription">' + this.TaskDescription + '</div>');
                }
            });
        });
</script>

Your module still should have worked. Did you see what we did? We created a variable called “moduleID” then concatenated it to the string of the URL. We actually surfaced a server-side value and exposed it as a string and set it to a variable. When you see the “ var moduleID = <%= ModuleId %>; those percentage signs are letting us know that it’s server code. If you want to, feel free to console.log that variable to ensure it’s coming through. Once we get that variable we then update the URL that we’re referencing and concatenate the moduleId to the end of the string and that’s all it takes.

That wasn’t much code, but it did make for a long blog. Though, I wanted to elaborate on it in a step by step method in hopes of making it easier to understand because I’m more concerned with you learning than simply being able to click and refresh. Hopefully it’s helpful.

Did you just successfully get your tasks returned to the view control? If so, tweet to me and let me know!

The below video walks through the concepts covered in this blog


Summary

In this blog entry we made use of jQuery to not only fetch the JSON data that we previously created, but to also loop through our objects and update the view. We have indeed come a long way and we’re just about there. Now that we’re at a decent stopping point in the next blog I want to take a second and reflect on our journey thus far so that we can mentally tie all the strings together. Yes, it will be somewhat repetitive, but then again repetition is the mother of learning. Hope to see you there!

Helpful JQuery links:

Go to the Next Blog Entry: "Mentally Mapping the Pieces Together"

Comments

Patrick Fischer
When I updated the code to query the ModuleId using var moduleId = <%= ModuleId %>; my test page with the test module on it returned no tasks.

To fix this I had to inspect the module element on the test page to find the ModuleId for my test module on the page and then update the tasks table and set the ModuleId for the tasks to this Id rather than the default 416 I had been using.

Maybe this was necessary because I did missed something....
Patrick Fischer Tuesday, January 27, 2015 7:37 AM (link)
Yogs M
Hi Clinton,

I am having problem.

When i use "/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=416" it dispalys all the records /rows for moduleId = 416

however......

When i tried displaying all the rows as below nothing displays
. It's blank module with just column headings.

var moduleId = <%= ModuleId %>;
$.getJSON(
"/DesktopModules/MyFirstModule/API/ModuleTask/GetTasks?moduleId=" + moduleId,


Where is <%= ModuleId%>coming from it is from "CBP_GetTasks" procedure or it is Form Table "CBP_Tasks"? i guess form Procedure.

Any thought on this?


Thanks,
Yogs
Yogs M Monday, April 27, 2015 9:51 AM (link)
Clinton Patterson
Yogs, the ModuleID is coming from DNN. We set a server side value for this javascript variable. Try to console.log the Module ID just to see if you are getting it back from DNN.
Clinton Patterson Thursday, April 30, 2015 9:05 AM (link)
James Brown
Link to the series introduction
http://www.dnnsoftware.com/community-blog/cid/155064/module-development-for-non-developers-skinners-dnn-beginners--blog-series-intro

Link to the previous Blog Entry:http://www.dnnsoftware.com/community-blog/cid/155084/creating-the-web-service-class
James Brown Monday, June 15, 2015 11:44 AM (link)
James Brown
I had a lot of trouble getting the checkboxes to work correctly with your code, so re-wrote the script as follows:
(My folder tree is a bit different than yours, otherwise this is it:


James Brown Monday, June 15, 2015 3:43 PM (link)
James Brown
I had dome problems with the check box so modified the script to shorten it. My folder setup is a little different than the example in the video.


James Brown Monday, June 15, 2015 9:58 PM (link)
James Brown
Trying this again without the enclosing script tags. It seems that the system ate the code that I posted previously:

var moduleId = <%= ModuleId %>;
$.getJSON(
"/DesktopModules/TaskManager/API/ModuleTasks/getTasks?moduleid=" + moduleId,
function (result) {
var parsedTaskJSONObject = jQuery.parseJSON(result);
$.each(parsedTaskJSONObject, function(){
if(this.IsComplete == true)
{ var xcheck = 'checked' }
else
{var xcheck =''}

$('.ListItems').append(
'
' +
'
' + this.TaskName + '
' +
'
' + this.TaskDescription +'
');

});
});
James Brown Thursday, June 18, 2015 11:03 AM (link)
Mark Buelsing
Still following along and learning a lot. See you in the next blog entry Clint.
Mark Buelsing Wednesday, March 16, 2016 2:27 PM (link)
Don DeVeux
Everything has been working up until this point. I've added the js block. I've recompiled and ensured the latest version (by date and size) is in the both the DNN/DesktopModules/bin (where my compiler puts it) and DNN/bin (where I copy it) folders. However, when I run it, the js block is not there.

I added some bogus text to the site and followed the previous steps and that isn't showing up either. What would prevent my changes from being in the compiled version. I have done the following:

1) Rebuild ALL in VS
2) Changed the Version Number of the build and rebuilt it.
3) Ensured the DLL is the correct version
4) Restarted the site

None of it seems to update my Module in DNN. What step am I missing?
Don DeVeux Monday, November 21, 2016 5:45 PM (link)

Comment Form

Only registered users may post comments.

NewsArchives


Aderson Oliveira (15)
Alec Whittington (11)
Alex Shirley (10)
Andrew Nurse (30)
Andy Tryba (1)
Anthony Glenwright (5)
Antonio Chagoury (28)
Ash Prasad (32)
Ben Schmidt (1)
Benjamin Hermann (25)
Benoit Sarton (9)
Beth Firebaugh (12)
Bill Walker (36)
Bob Kruger (5)
Bogdan Litescu (1)
Brian Dukes (2)
Brice Snow (1)
Bruce Chapman (20)
Bryan Andrews (1)
cathal connolly (55)
Charles Nurse (163)
Chris Hammond (209)
Chris Paterra (55)
Clinton Patterson (41)
Cuong Dang (21)
Daniel Bartholomew (2)
Daniel Mettler (154)
Dave Buckner (2)
David Poindexter (4)
David Rodriguez (3)
Dennis Shiao (1)
Doug Howell (11)
Erik van Ballegoij (30)
Ernst Peter Tamminga (74)
Geoff Barlow (10)
George Alatrash (6)
Gifford Watkins (3)
Gilles Le Pigocher (3)
Ian Robinson (7)
Israel Martinez (17)
Jan Blomquist (2)
Jan Jonas (3)
Jaspreet Bhatia (1)
Jenni Merrifield (6)
Joe Brinkman (274)
John Mitchell (1)
Jon Henning (14)
Jonathan Sheely (4)
Jordan Coopersmith (1)
Joseph Craig (2)
Kan Ma (1)
Keivan Beigi (3)
Ken Grierson (10)
Kevin Schreiner (6)
Leigh Pointer (31)
Lorraine Young (60)
Malik Khan (1)
Matthias Schlomann (15)
Mauricio Márquez (5)
Michael Doxsey (7)
Michael Tobisch (3)
Michael Washington (202)
Miguel Gatmaytan (3)
Mike Horton (19)
Mitchel Sellers (28)
Nathan Rover (3)
Navin V Nagiah (14)
Néstor Sánchez (31)
Nik Kalyani (14)
Peter Donker (54)
Philip Beadle (135)
Philipp Becker (4)
Richard Dumas (22)
Robert J Collins (5)
Roger Selwyn (8)
Ruben Lopez (1)
Ryan Martinez (1)
Salar Golestanian (4)
Sanjay Mehrotra (9)
Scott McCulloch (1)
Scott S (11)
Scott Wilkinson (3)
Scott Willhite (97)
Sebastian Leupold (80)
Shaun Walker (237)
Shawn Mehaffie (17)
Stefan Cullmann (12)
Stefan Kamphuis (12)
Steve Fabian (31)
Timo Breumelhof (24)
Tony Henrich (3)
Torsten Weggen (2)
Vicenç Masanas (27)
Vincent Nguyen (3)
Vitaly Kozadayev (6)
Will Morgenweck (40)
Will Strohl (165)
William Severance (5)

Content Layout

Subscribe to DNN Digest

Subscribe to DNN Digest

DNN Digest is our monthly email newsletter. It highlights news and content from around the DNN ecosystem, such as new modules and themes, messages from leadership, blog posts and notable tweets. Keep your finger on the pulse of the ecosystem by subscribing.  


Copyright 2017 by DNN Corp Terms of Use Privacy
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out