divendres, 19 de febrer del 2010

Mini AJAX Framework

Aquesta llibreria, ens permet realitzar peticions XMLHttpRequest de dues formes diferents. També ens permet inserir la resposta HTML en el document de dues formes diferents


Realitzar peticions


Amb la funció "get" realitzem una petició url definida: get(url);
Per exemple:
<a href="#" onclick="get('/index/prova?id=2')">link</a>


Amb la funció "formget" realitzem la petició afegint a la url els camps d'un formularI: formget('url','form_id');
Per exemple:
<form id="form1" action="javascript:formget('/index/prova','form1')">


Mostrar la resposta HTML al document:


Els elements de la resposta HTML han de tenir un identificador (pot anar precedit d'un símbol '+'); i aquest mateix identificador l'ha de tenir també algun element del document.
  1. Si l'identificador de l'element resposta conicideix amb algun element del document, aquest es reemplaça per la resposta. Exemple:

    document:             resposta:           document resultant:
    <html>                <div id="msg">      <html>
      <div id="msg">        <p>Resposta</p>     <div id="msg">
        <p>Document</p>   </div>                  <p>Resposta</p>
      </div>                                    </div>
    </html>                                   </html>

  2. Si l'identificador de l'element resposta comença pel signe '+' seguit d'un identificador, la resposta s'afegeix a l'element del document que tingui el mateix identificador. Exemple:

    document:             resposta:           document resultant:
    <html>                <div id="+msg">     <html>
      <div id="msg">        <p>Resposta</p>     <div id="msg">
        <p>Document</p>   </div>                  <p>Document</p>
      </div>                                      <p>Resposta</p>
    </html>                                     </div>
                                              </html>


# Fitxer: Ajax.js



function get(url){
  req = new XMLHttpRequest();
  if (req){
    req.open("GET",url,true);
    req.send(null);
  }
  req.onreadystatechange = function(){
    if(req.readyState == 4){
      var div = document.createElement('div');
      div.innerHTML = req.responseText;
      for(var i=0; i<div.childNodes.length; i++){
        var respChild = div.childNodes.item(i);
        if(respChild.nodeType == 1){
          var respChildId = respChild.getAttribute("id");
          if (respChildId){
            var docReplace = document.getElementById(respChildId);
            if (docReplace){
              docReplace.parentNode.replaceChild(respChild,docReplace);
            }else if (respChildId.indexOf('+') == 0){
              var docAdd = document.getElementById(respChildId.substring(1));
              if (docAdd){
                for (var j=0; j<respChild.childNodes.length; j++){
                  docAdd.appendChild(respChild.childNodes.item(j));
                }
              }
            }
          }
        }
      }
    }
  }
}


function formget(url,form_id){
  var getstr = "?";
  var form = document.getElementById(form_id);
  for (i=0; i<form.getElementsByTagName("input").length; i++){
    if (form.getElementsByTagName("input")[i].type == "text"){
      getstr += form.getElementsByTagName("input")[i].name + "=" + 
                form.getElementsByTagName("input")[i].value + "&";
    }
    if (form.getElementsByTagName("input")[i].type == "checkbox"){
      if (form.getElementsByTagName("input")[i].checked){
        getstr += form.getElementsByTagName("input")[i].name + "=" + 
                  form.getElementsByTagName("input")[i].value + "&";
      }else{
        getstr += form.getElementsByTagName("input")[i].name + "=&";
      }
    }
    if (form.getElementsByTagName("input")[i].type == "radio"){
      if (form.getElementsByTagName("input")[i].checked){
        getstr += form.getElementsByTagName("input")[i].name + "=" + 
                  form.getElementsByTagName("input")[i].value + "&";
      }
    }  
  }
  for (i=0; i<form.getElementsByTagName("select").length; i++){
    var sel = form.getElementsByTagName("select")[i];
    getstr += sel.name + "=" + sel.options[sel.selectedIndex].value + "&";
  }
  for (i=0; i<form.getElementsByTagName("textarea").length; i++){
    getstr += form.getElementsByTagName("textarea")[i].name + "=" + 
              form.getElementsByTagName("textarea")[i].value + "&";        
  }
  get(url+getstr); 
}









Exemple d'ús amb mod_python:

# Fitxer: Index.py


# -*- coding: utf-8 -*-
from datetime import datetime

def index(req,itxt="null",**kwargs):
  if itxt=="null":
    return """
<html>
<head>
  <link rel="stylesheet" href="/style.css"></style>
  <script src="/ajax.js"></script>
</head>
<body>
  <div class="section">
    <div>
      <span id="menu_index">
<a href="#" onmouseover="get('/index/menu')">Veure el menu</a>
</span>
    </div>
  </div>
  <div class="section">
    <div>
        <span id="msg"></span>
        <form action="javascript:formget('','myform')" id="myform">
          <label for="itxt">input type text</label>
          <input type="text" name="itxt" /><br />
           
          <label for="ipass">input type password</label>
          <input type="text" name="ipass" /><br />
          
          <label for="txta">textarea</label>
          <textarea name="txta"></textarea><br /><br />
          
          <input type="submit" value="Enviar" />
        </form>
    </div>
  </div>
  <div class="section">
    <div>
      <h1>Historial</h1>
      <table id="historial">
      </table>
    </div>
  </div>
</html>  
  """
  elif itxt=="":
    return """
    <p id="msg" class="error">No has introduit el "input type text"!</p>
    <table id="+historial"><tr><td>no text</td><td>%s</td></tr></table>
    """ % (datetime.now(),)
  else:
    resp="""
    <div id="msg">
    <p class="exit">S'ha introduit "input type text": %s<br />
    """ % (itxt,)
    for k in kwargs:
        resp += """%s: %s <br />""" % (k,kwargs[k])
    resp+="""
    </p></div>
    <table id="+historial"><tr><td>%s</td><td>%s</td></tr></table>
    """ % (itxt,datetime.now())
    
    return resp
    
def menu(req):
    return """
    <nav id="menu_index">
        <ul>
            <li><a href="#">Link1</a></li>
            <li><a href="#">Link2</a></li>
            <li><a href="#">Link3</a></li>
            <li><a href="#">Link4</a></li>
        </ul>
    </nav>
    """