Announcement

Collapse
No announcement yet.

Any simple examples of ajax use in module?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Any simple examples of ajax use in module?

    Hi,

    I'm going nuts here. All I want to do is update a database entry in the background of a module depending on menu item the user is clicking on.

    Does anyone have a simple example of using ajax (or something) in a module that calls a miva script in the background without changing the user experience?

    I understand how ajax works, I've read a dozen ajax tutorials, but linking json and javascript events is not making any sense. I learn quick, I just need to see something simple in action.

    Thanks for anything that might help. BTW, I have been studying the limited source code but... it's not really making sense to me how all it all fits together when it comes to ajax/json.

    Scot
    M.A.D.* since 1997

    http://www.scotsscripts.com

    *miva application developers

    #2
    Re: Any simple examples of ajax use in module?

    Joining thread.
    Larry
    Larry
    Luce Kanun Web Design
    www.facebook.com/wajake41
    www.plus.google.com/116415026668025242914/posts?hl=en


    Comment


      #3
      Re: Any simple examples of ajax use in module?

      Have you looked at w3schools.com? I always go there when I want a tutorial or intro on something Web-related. Their articles are short but helpful, and have lots of examples.

      I would also just Google "ajax tutorial;" I bet you'll find some good ones. In fact, please let us know what you find out; I've got an AJAX project on my own calendar, and it'll be my first time working with that.

      Good luck :^) --
      Last edited by Kent Multer; 02-01-13, 10:53 AM.
      Kent Multer
      Magic Metal Productions
      http://TheMagicM.com
      * Web developer/designer
      * E-commerce and Miva
      * Author, The Official Miva Web Scripting Book -- available on-line:
      http://www.amazon.com/exec/obidos/IS...icmetalproducA

      Comment


        #4
        Re: Any simple examples of ajax use in module?

        I've totally looked at W3 and Google. I get the gist of ajax. What I don't get is how do I call it from say a system extension module without having to have external files? Can it be done totally internally in the module? Miva merchant source shows various ways they used ajax and json but it's split up in different files.

        Is the json/ajax setup in miva merchant generic enough to utilize in a module or is it specific to whatever it's in there for?

        If a dev from miva merchant could put together a simple ajax/json module example it would help us all out, help make miva merchant a better product (because we could make slicker modules!) and last but not least I would stop pulling what's left of my hair out.

        I've spent way too much time trying to make something work and have basically given up on it which is why I'm here.
        M.A.D.* since 1997

        http://www.scotsscripts.com

        *miva application developers

        Comment


          #5
          Re: Any simple examples of ajax use in module?

          Ditto
          Bill Weiland - Emporium Plus http://www.emporiumplus.com/store.mvc
          Online Documentation http://www.emporiumplus.com/tk3/v3/doc.htm
          Question http://www.emporiumplus.com/mivamodu...vc?Screen=SPTS
          Facebook http://www.facebook.com/EmporiumPlus
          Twitter http://twitter.com/emporiumplus

          Comment


            #6
            Re: Any simple examples of ajax use in module?

            I volunteer to write the module example, and an accompanying article, if MMCorp will provide me the info I need to eliminate all the unnecessary trial-and-error.
            Kent Multer
            Magic Metal Productions
            http://TheMagicM.com
            * Web developer/designer
            * E-commerce and Miva
            * Author, The Official Miva Web Scripting Book -- available on-line:
            http://www.amazon.com/exec/obidos/IS...icmetalproducA

            Comment


              #7
              Re: Any simple examples of ajax use in module?

              That would be cool. It would be cool to include something on how to share data/variables between javascript/json/ajax/miva script so they can all work together.
              M.A.D.* since 1997

              http://www.scotsscripts.com

              *miva application developers

              Comment


                #8
                Re: Any simple examples of ajax use in module?

                I've created a few AJAX-y things, but since nothing is MM specific the best I can do is highlight.

                There are three componants to working AJAX: the page making a call, the JavaScript acting as messenger, and the source of data.

                The page making the call is easy; where do you want this transformation to appear. For example, one of the routines I built was during member registration. When entering a location I want the dropdowns to auto configure based on previous information. So first they would choose a country. Once selected, the Region/State field would populate with only regions within that country. Once a region was selected, then cities would populate the same way. Each dropdown was hooked to have an onChange call.

                Code:
                <span id="divCountrySelect"><select name="{ l.name }" id="{ l.name }" onchange="javascript:RegionLookup();">
                
                <MvWHILE EXPR = "{ l.count LE l.country_count }">
                <MvIF EXPR = "{ l.countries[ l.count ]:country_id EQ l.default }">
                <option value="{ l.countries[ l.count ]:country_id }" selected="true"><MvEVAL EXPR = "{ encodeentities( l.countries[ l.count ]:country ) }"></option>
                <MvELSE>
                <option value="{ l.countries[ l.count ]:country_id }"><MvEVAL EXPR = "{ encodeentities( l.countries[ l.count ]:country ) }"></option>
                </MvIF>
                
                <MvASSIGN NAME = "l.count" VALUE = "{ l.count + 1 }">
                </MvWHILE>
                </select>
                </span>
                The JavaScript element happens in a few places. There is a portion in the head of the document to set up variables, and then a function saved in an external script.

                So in the head, I declare the URL for all my AJAX calls (they all go through the same file), and the id's for each of the dropdowns.
                Code:
                // setup for all ajax calls
                var ajax_url = "<MvEVAL EXPR = "{ g.site_lib_ajax }">";
                
                // setup for looking up locations
                var country_lookup_field = "<MvEVAL EXPR = "{ l.user_field_name $ ':country' }">";
                var region_lookup_field = "<MvEVAL EXPR = "{ l.user_field_name $ ':region' }">";
                var city_lookup_field = "<MvEVAL EXPR = "{ l.user_field_name $ ':city' }">";
                And the external file does a lot of heavy lifting. There are generally three functions, but this can be done however you like. The first thing to have is a function for creating a JavaScript Object with the request. This gets reused for every request. Everyone has their favorite routine, here is the one I'm using:
                Code:
                // AJAX controllers
                function createRequest() {
                    try {
                        request = new XMLHttpRequest();
                    } catch ( tryMS ) {
                        try {
                            request = new ActiveXObject("Msxml2.XMLHTTP");
                        } catch ( otherMS ) {
                            try {
                                request = new ActiveXObject("Microsoft.XMLHTTP");
                            } catch ( failed ) {
                                request = null;
                            }
                        }
                    }
                    return request;
                }
                Now you create a function that gets the Request Object, and if successful, tries to hit the third element, the source of data, and once that information is returned, send it off to another JavaScript for processing. In my case, I have two of these; one for when the Country is selected, and one for when the Region is selected. For me, the process is once a Country is selected, I ping the database for all regions in that country, and then using DOM delete and rewrite the dropdown select for Regions. Same process for when a Region is selected and creating a City dropdown.

                The source of data, 99% of the time will be a database, but it could also be a hardcoded JavaScript array, or even a built-in element like the current time. Once again, for me, all requests go through the same file. So my call looks something like this:
                Code:
                var country_id = document.getElementById(country_lookup_field).value;
                var url= ajax_url + '?security=' + region_security_string + '&data=' + country_id;
                regionRequest.onreadystatechange = GetRegionStatus;
                regionRequest.open("GET", url, true);
                regionRequest.send(null);
                The region_security_string is a base64 encoded string with the session_id, member_id, type of request, an md5 chksum, etc. This lets my AJAX file know what it's going to do. And obviously the country_id is the variable to use in the request.

                Which brings on the last element; the AJAX file or source of data.

                It's an external file that returns JSON for whoever called it. Set the headers so the browser knows it's getting JSON back. Then after decoding the security string, it does a db look up and returns a list of all the regions or cities.

                That's AJAX in a nutshell. I've only made a few functions so far; the previously mentioned location look up, a simple BBCode editor, and a 'fill in the text area with a canned response' based on a dropdown. Trying to do an auto-suggest thingie too, but having trouble with making the keys work right.

                To get this all working in a MM store, use SMT to add the JavaScript to the pages, upload a series of external .js files to do the processing, and a "Module" that will act as your source which just calls MM API functions to get data and send it back. Oh, and the JSON scripts that Kent Multer put on this forum a year or two ago if you can't hook into the MM version.

                Hope that gets everyone started. I'd love to see what you guys come up with.

                Comment


                  #9
                  Re: Any simple examples of ajax use in module?

                  Thanks for all the information, appreciate your efforts.

                  The flow of how things work is what is confusing me.

                  Is this about right?

                  1. The user selects a location from the dropdown. Upon selection, the onChange thing calls a javascript function called RegionLookup()

                  2. The RegionLookup() function reads the vars (such as ajax_url) that you set up in the head of the same document the user is currently interacting with.

                  3. The RegionLoookup() function calls your ajax controller function.

                  4. Your ajax contoller function mysteriously calls a miva script that mysteriously sets data that mysteriously changes the form.

                  Ok, I'm totally lost on how this can interact with mivascript. I can do ajax without using miva script variables.

                  How is the ajax controller file called? And how does it link up with the miva script file that does the work in finding the region information for the user?

                  Sorry, to be obtuse, it's like I'm trying to hold a snowflake here. Something basic I'm missing about how all this links up.
                  M.A.D.* since 1997

                  http://www.scotsscripts.com

                  *miva application developers

                  Comment


                    #10
                    Re: Any simple examples of ajax use in module?

                    Just as a side note, I just found a bunch of PHP examples using ajax out there in the web world that I'm going to study to try to figure out my confusion points.
                    M.A.D.* since 1997

                    http://www.scotsscripts.com

                    *miva application developers

                    Comment


                      #11
                      Re: Any simple examples of ajax use in module?

                      Yes, the MivaScript/JavaScript thing can be a bit of a head-scratcher. You have to remember that Miva Script gets executed first, on the server, and it writes the JS code out to the browser, which runs it later. If you need to get a Miva variable into the page so it's available for JavaScript, you write a mix of both, something like this:

                      Code:
                      var myVariable = <MvEVAL EXPR="{ g.myVariable }">;          -- for straight Miva Script
                      var myVariable = &mvt:global:myVariable;;          -- for page template.  NOTE two semicolons
                      HTH --
                      Last edited by Kent Multer; 02-04-13, 10:11 AM.
                      Kent Multer
                      Magic Metal Productions
                      http://TheMagicM.com
                      * Web developer/designer
                      * E-commerce and Miva
                      * Author, The Official Miva Web Scripting Book -- available on-line:
                      http://www.amazon.com/exec/obidos/IS...icmetalproducA

                      Comment


                        #12
                        Re: Any simple examples of ajax use in module?

                        There are a couple built in functions in the Miva lib. You can even study a working module, albeit quite complex, e.g. the templateorderemails.mv in the LSK. But, like Kent, most of these leave us trying to hold a snowflake. When MM5 was in beta we were give some really simple, commented examples on how render tokens worked. From those simple examples, a whole new world opened in rather short order. I have asked in another thread if Jon had a simple, commented example, like adding a product to the basket or showing the number of items in the basket, that we could study and build on. Perhaps he will chime in and this won't seem so convoluted. I spent hours chasing snowflakes one weekend and decided it would have to wait. Since Scot has brought it up, it appears I am not the only one scratching my head on this.
                        Bill Weiland - Emporium Plus http://www.emporiumplus.com/store.mvc
                        Online Documentation http://www.emporiumplus.com/tk3/v3/doc.htm
                        Question http://www.emporiumplus.com/mivamodu...vc?Screen=SPTS
                        Facebook http://www.facebook.com/EmporiumPlus
                        Twitter http://twitter.com/emporiumplus

                        Comment


                          #13
                          Re: Any simple examples of ajax use in module?

                          Originally posted by Scot - ScotsScripts.com View Post
                          Thanks for all the information, appreciate your efforts.

                          The flow of how things work is what is confusing me.

                          Is this about right?

                          1. The user selects a location from the dropdown. Upon selection, the onChange thing calls a javascript function called RegionLookup()
                          2. The RegionLookup() function reads the vars (such as ajax_url) that you set up in the head of the same document the user is currently interacting with.
                          3. The RegionLoookup() function calls your ajax controller function.
                          4. Your ajax contoller function mysteriously calls a miva script that mysteriously sets data that mysteriously changes the form.

                          Ok, I'm totally lost on how this can interact with mivascript. I can do ajax without using miva script variables.

                          How is the ajax controller file called? And how does it link up with the miva script file that does the work in finding the region information for the user?

                          Sorry, to be obtuse, it's like I'm trying to hold a snowflake here. Something basic I'm missing about how all this links up.
                          Yeah, I've got books, looked through tons of online docs. It gets tricky.

                          You've basically got the right flow. You'll mostly be working with JavaScript variables, up until you reach the "source" step.

                          I'll put a mostly working example in the next post, but here is how things flow.

                          1) Page is drawn with some links. The links include a javascript call to a function called Debug() and each link has a different parameter.

                          2. Click on a link to call Debug().

                          3. First Debug() creates an Object. This is what handles the flow of data from this page to the source of data. In this case it will be what I call the "ajax module".

                          4. After a quick error check it creates the full URL of how to reach the file that is the ajax module. For example, http://localhost/test/ajax.mvc?security=MXxDeWJlcmZ1bmt8dXNlcnxkZWJ1Z3w3MjAzMWMwNjAyZjdlNm NmMjFjMmRmNDJ==&scope=s

                          5. We then tell the Object that if there is a change in readystate, call GetDebugStatus. The readystate will change based on information going back and forth from this page and the ajax module.

                          6. Then open a connection to the URL we made. The parameters sent are a little too out of scope for this example, but you can use "GET" or "POST", and based on that other parameters need to be set.

                          7. At this point, things get turned over to the ajax module. The first step is to change the output level to "" to prevent any extra characters being sent and set the headers so the browser knows what to expect.

                          8. Here you can go to town with calling functions, reading databases, etc. For this example, all I'm doing is using miva_getvarlist() and converting the output to JSON format. I don't even need to do that as I'm just going to display everything raw, but I'm going through the motions.

                          9. The ajax module then outputs it, just like you would output to the screen. But instead, this is outputting a JSON formed response to the call.

                          10. We now go back to the calling script and since readystate has changed, we look at GetDebugStatus().

                          11. I forget what the readyState==4 means, but the status=200 is just like http status where 200 is an ok, and 404 is page not found. All we care about is 4 and 200.

                          12. I then assign what comes back as stringData. There are a few ways for the javascript to 'decode' the response: .responseText is good for straight text and JSON, .responseXML is good for XML replies.

                          13. Finally, I look for div id="debug", and replace its contents with what I sent from the ajax module.

                          This is a really basic example, but you can build from here. Instead of putting a variable list, you could display something useful. Instead of links, use a drop down to send different values.

                          I hope this helps you understand a little about how it all goes together. Obviously I can't share the security string portion, but you can get by without it. Check out the next post for code.
                          Last edited by Scott McCollough; 02-04-13, 04:15 PM.

                          Comment


                            #14
                            Re: Any simple examples of ajax use in module?

                            Here is the main file:
                            Code:
                            <MIVA STANDARDOUTPUTLEVEL=""><MvDO FILE = "./config.mvc">
                            
                            
                            <MIVA STANDARDOUTPUTLEVEL="text, html, compresswhitespace">
                            <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
                            "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
                            <html xmlns="http://www.w3.org/1999/xhtml">
                            
                            
                            <head>
                                <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
                            
                            
                                <title>AJAX Testing</title>
                            
                            
                                <script type="text/javascript">
                                    // setup for all ajax calls
                                    var ajax_url = "<MvEVAL EXPR = "{ g.site_lib_ajax }">";
                            
                            
                                    // AJAX controllers
                                    // Tries different methods because different browsers create the Object differently
                                    function createRequest() {
                                        try {
                                            request = new XMLHttpRequest();
                                        } catch ( tryMS ) {
                                            try {
                                                request = new ActiveXObject("Msxml2.XMLHTTP");
                                            } catch ( otherMS ) {
                                                try {
                                                    request = new ActiveXObject("Microsoft.XMLHTTP");
                                                } catch ( failed ) {
                                                    request = null;
                                                }
                                            }
                                        }
                            
                            
                                        return request;
                                    }
                            
                            
                                    // Two functions for getting debug code on the screen
                                    function Debug(scope) {
                                        // Get the Object
                                        debugRequest = createRequest();
                            
                            
                                        // If it fails, alert us
                                        if (debugRequest == null)
                                            alert("Unable to create request");
                            
                            
                                        else {
                                            // Craft the url of where we are going to get the source of data
                                            var url= ajax_url + '?security=' + debug_security_string + '&scope=' + scope;
                            
                            
                                            // If something happens to the current state (like a drop down or a link press), call "GetDebugStatus()". Cannot included parameters
                                            debugRequest.onreadystatechange = GetDebugStatus;
                            
                            
                                            // Connect to the url we set up. Differences between "GET" and "POST", true and false, and using null are too much to explain here
                                            debugRequest.open("GET", url, true);
                                            debugRequest.send(null);
                                        }
                                    }
                            
                            
                                    // This is called because something happened. Trust me and check for readyState == 4 and status == 200.
                                    function GetDebugStatus() {
                                      if (debugRequest.readyState == 4) {
                            
                            
                                        if (debugRequest.status == 200) {
                                            // we connected and got back informatoin, so process whatever has been sent back
                                            // Assume was we got back is text. JSON or plain text uses .responseText, XML uses .responseXML
                                            var stringData = debugRequest.responseText;
                            
                            
                                            // Find <div id="debug"></div> on the page, and paste in what we got back
                                            document.getElementById('debug').innerHTML = stringData;
                                        }
                                      }
                                    }
                                </script>
                                <link rel="stylesheet" href="css/default.css" />
                            </head>
                            
                            
                            <body>
                                <form method="POST" action="" class="css_class" id="anyform" name="anyform">
                                <h2>Test Debug</h2>
                            
                            
                                <fieldset>
                                    <legend>Debug</legend>
                                    <p><MvEVAL EXPR = "{ Debug() }"></p>
                                </fieldset>
                                </form>
                            </body>
                            </html>
                            <MvEXIT>
                            
                            
                            <MvFUNCTION NAME = "Debug" STANDARDOUTPUTLEVEL = "text, html, compresswhitespace">
                                <MvEVAL EXPR = "{ [ g.site_lib_utils ].Get_Parameters( l.parameters ) }">
                            
                            
                                <MvASSIGN NAME = "l.parameters" MEMBER = "type" VALUE = "{ 'debug' }">
                                <MvASSIGN NAME = "l.string" VALUE = "{ [ g.site_lib_utils ].Encode_Session( l.parameters ) }">
                            
                            
                                <script type="text/javascript">
                                    var debug_security_string = "<MvEVAL EXPR = "{ l.string }">";
                                </script>
                            
                            
                                <p><a href="javascript:Debug('s');">Debug system variables</a></p>
                                <p><a href="javascript:Debug('g');">Debug global variables</a></p>
                                <p><a href="javascript:Debug('d');">Debug database variables</a></p>
                                <p><a href="javascript:Debug('l');">Debug local variables</a></p>
                                <p><a href="javascript:Debug('');">Clear</a></p>
                            
                            
                                <p><div id="debug"></div></p>
                            </MvFUNCTION>
                            And here is the ajax module file:
                            Code:
                            <MIVA STANDARDOUTPUTLEVEL="">
                            <MvDO FILE = "./config.mvc">
                            
                            
                            <MvEVAL EXPR = "{ Send_Headers() }">
                            <MvEVAL EXPR = "{ AJAX_Debug( g.scope ) }">
                            
                            
                            <MvEXIT>
                            
                            
                            <MvFUNCTION NAME = "Send_Headers" STANDARDOUTPUTLEVEL = "">
                                <MvASSIGN NAME = "l.null" VALUE = "{ miva_output_header( 'Expires', 'Mon, 26 Jul 1997 05:00:00 GMT' ) }">
                                <MvASSIGN NAME = "l.null" VALUE = "{ miva_output_header( 'Cache-Control', 'no-cache, must-revalidate' ) }">
                                <MvASSIGN NAME = "l.null" VALUE = "{ miva_output_header( 'Pragma', 'no-cache' ) }">
                                <MvASSIGN NAME = "l.null" VALUE = "{ miva_output_header( 'Content-Type', 'application/json' ) }">
                            </MvFUNCTION>
                            
                            
                            <MvFUNCTION NAME = "AJAX_Debug" PARAMETERS = "scope" STANDARDOUTPUTLEVEL = "">
                                <MvASSIGN NAME = "l.scope" VALUE = "{ tolower( l.scope ) }">
                            
                            
                                <MvIF EXPR = "{ NOT ( l.scope IN 'sgdl' ) }">
                                    <MvASSIGN NAME = "l.scope" VALUE = "s">
                                </MvIF>
                            
                            
                                <MvASSIGN NAME = "l.list" VALUE = "{ miva_getvarlist( l.scope ) }">
                                <MvASSIGN NAME = "l.count" VALUE = "1">
                                <MvASSIGN NAME = "l.debug" VALUE = "">
                                <MvASSIGN NAME = "l.return" VALUE = "">
                            
                            
                            
                            
                                <MvWHILE EXPR = "{ gettoken( l.list, ',', l.count ) }">
                                    <MvASSIGN NAME = "l.token" VALUE = "{ gettoken( l.list, ',', l.count ) }">
                            
                            
                                    <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ '{' }">
                                    <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ '"token":"' $ l.token $ '"' }">
                                    <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ ', ' }">
                                    <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ '"value":"' $ encodeattribute( miva_variable_value( l.scope $ '.' $ l.token ) ) $ '"' }">
                                    <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ '}' }">
                            
                            
                                    <MvASSIGN NAME = "l.count" VALUE = "{ l.count + 1 }">
                            
                            
                                    <MvIF EXPR = "{ gettoken( l.list, ',', l.count ) }">
                                        <MvASSIGN NAME = "l.return" VALUE = "{ l.return $ ', ' }">
                                    </MvIF>
                                </MvWHILE>
                            
                            
                                <MvIF EXPR = "{ len( l.return ) }">
                                    <MvASSIGN NAME = "l.return" VALUE = "{ '[' $ l.return $ ']' }">
                                </MvIF>
                            
                            
                                <MvFUNCTIONRETURN VALUE = "{ l.return }">
                            </MvFUNCTION>
                            Last edited by Scott McCollough; 02-04-13, 01:07 PM.

                            Comment


                              #15
                              Re: Any simple examples of ajax use in module?

                              Hey Scott, that is above and beyond right there. A huge thank you for putting that together. I'll grab that code tomorrow and pour over it and see what I can come up with. But man, this is EXACTLY the kind of thing I need to learn how to do this. My personal learning method is all about taking something apart and putting it back together again... which would explain why I got in so much trouble as a little kid. Anyway, very much appreciated.

                              Is that config.mvc file arbitrary? Just making sure.
                              M.A.D.* since 1997

                              http://www.scotsscripts.com

                              *miva application developers

                              Comment

                              Working...
                              X