---
# System prepended metadata

title: Aplicación TODO

---

# Aplicación TODO

## Codigo Servidor

```javascript=
// el ID de nuestra hoja de cálculo
SSID="";
// probando devolviendo todas las tareas
// crear una funcion que nos devuelva una lista de tareas
function todas(args){
  return   SpreadsheetApp.openById(SSID)
  .getSheetByName("tareas")
  .getDataRange()
  .getValues();
}

function pendientes(args){
  const {categoria} = args;
  sheet= SpreadsheetApp.openById(SSID).getSheetByName("pendientes")
  var valores = sheet.getDataRange().getValues();
  var out = [];
 for (i=1;i< valores.length;i++){
   if( valores[i][2]==categoria){out.push(valores[i])}
 }
 return out
}



function nuevatarea(args){
  const {categoria,prioridad=3,descripcion} = args;
  sheet= SpreadsheetApp.openById(SSID).getSheetByName("tareas")
  ultima= sheet.getLastRow();
  sheet.insertRowAfter(ultima); //inserta nueva fila por si no hubiese suficientes
  nuevoID= 1+sheet.getRange(ultima, 1, 1, 1).getValue();
  sheet.getRange(ultima+1, 1, 1, 5).setValues([[nuevoID,descripcion, categoria, prioridad,"no"]]);
  //return "OK"
  return pendientes({categoria:categoria})
}


function filaDelID(ID,sheetname){
  sheet= SpreadsheetApp.openById(SSID).getSheetByName(sheetname)
  ultima= sheet.getLastRow();
  indices = sheet.getRange(1,1,ultima,1).getValues();
  fila = false;
  for(i=0;i<ultima;i++){
    console.log(i,indices[i][0],sheet.getRange(i+1, 1, 1, 1).getValue())
    if( indices[i][0]==ID){fila = i+1; break}
  }
  return fila
}

/// Obtener registro de un indice (el 4):
// fila = filaDelID(4,"tareas");
// if (fila)  sheet.getRange(fila,1,1,5).getValues()[0]


// PELIGRO insegura, mejor no exponer en la API
function cambiavalor(args){
  const {id,col,valor} = args;
  sheet= SpreadsheetApp.openById(SSID).getSheetByName("tareas");
  fila = filaDelID(id,"tareas");
  if (fila) {
    sheet.getRange(fila,col,1,1).setValue(valor);} // escribe valor  en la columna indicada
  else {
    throw "No se encuentra registro con id: "+id;}
  categoria = sheet.getRange(fila||2,3,1,1).getValue(); // lee columna 3 como categoria 
  return pendientes({categoria:categoria})
}

function marcacompleta(args){
  const {idtarea} = args;
  return cambiavalor({id:idtarea,col:5,valor:"si"})
}

function cambiaprioridad(args){
    const {idtarea,prioridad} = args;
    return cambiavalor({id:idtarea,col:4,valor:prioridad})


}


```



## HTML cliente

```htmlmixed=


<html>
    <head>

    </head>
    <body>
        <h2>Probando API cliente</h2>
        <script>

// Insertar aqui la url del script dev y exe
// dev
GAS=""
// exe
//GAS=""

//llama a una url que responde un objeto JSON en una función callback
// realmente devuelve un código javascript
// esta funcion devuelve una Promesa, que se ejecuta al recibir los datos

const JSONP = (unique => url =>
  new Promise(rs => {
    const script = document.createElement('script');
    const name = `_jsonp_${unique++}`;

    if (url.match(/\?/)) {
      url += `&callback=${name}`;
    } else {
      url += `?callback=${name}`;
    }
    console.log(url);
    script.src = url;
    window[name] = json => {
      rs(json);
      script.remove();
      delete window[name];
    };
    document.body.appendChild(script);
  })
)(0);

// comprueba que no ha habido errores
const checkSuccess = (json =>{
  console.log("checkSuccess: ",json);
    if(json.success) {
     //   console.log("-->  SUCCESS: "+json.message+" serverTimeout: "+json.serverTimeout );
        return Promise.resolve(json.data);}
    else {return  Promise.reject('Se ha producido un error: '+json.err);}
})

// composicion de la url del comando a partir de los argumentos
const cmd_url = ((cmd,arg) =>{
  const gascript_url =GAS;
  var url = gascript_url+"?command="+cmd
  if (typeof(arg) !=="undefined") url = url+'&arg='+JSON.stringify(arg)
  console.log(url);
  return url;
  })

// llamada a la API
function APIcall(cmd,arg){
    return JSONP(cmd_url(cmd,arg)).then(checkSuccess);
}





        </script>


<p>Ejemplo:</p>
<pre>
    APIcall("suma_ab",{a:345,b:5
    })
    .then(function(data){
      console.log( "YA HA RESPONDIDO: ",data)
      console.log( "el valor devuelto es: ",data.resultado)
    })
</pre>


<h3>Algunas Llamadas</h3>
<pre>
  APIcall("pendientes",{categoria:"insti"}) 
  .then(function(data){
    console.log( "YA HA RESPONDIDO: ",data)})

APIcall("nuevatarea",{categoria:"insti",descripcion:"Felices vacaciones"}) 
  .then(function(data){
  console.log( "YA HA RESPONDIDO: ",data)})

APIcall("marcacompleta",{idtarea:6}) 
  .then(function(data){
    console.log( "YA HA RESPONDIDO: ",data)})

APIcall("cambiavalor",{id:7,col:2,valor:"Una nueva descripción para esta tarea"}) 
    .then(function(data){
    console.log( "YA HA RESPONDIDO: ",data)})    
</pre>
    </body>
</html>


```


## Plantilla HTML onsen

```htmlmixed=
<ons-page>
    <ons-toolbar>
      <div class="center">Pendientes</div>
    </ons-toolbar>
    
    <ons-select id="choose-sel" onchange="editSelects(event)">
      <option value="insti">insti</option>
      <option value="casa">casa</option>
    </ons-select>
    
    <ons-list id='listaTareas'>
      
    </ons-list>
    <br />
  
  </ons-page>
```

## Plantilla JS onsen

```javascript=

  // dev
  GAS=""
  // exe
  const JSONP = (unique => url =>
    new Promise(rs => {
      const script = document.createElement('script');
      const name = `_jsonp_${unique++}`;
  
      if (url.match(/\?/)) {
        url += `&callback=${name}`;
      } else {
        url += `?callback=${name}`;
      }
      console.log(url);
      script.src = url;
      window[name] = json => {
        rs(json);
        script.remove();
        delete window[name];
      };
      document.body.appendChild(script);
    })
  )(0);
  
  // comprueba que no ha habido errores
  const checkSuccess = (json =>{
    console.log("checkSuccess: ",json);
      if(json.success) {
       //   console.log("-->  SUCCESS: "+json.message+" serverTimeout: "+json.serverTimeout );
          return Promise.resolve(json.data);}
      else {return  Promise.reject('Se ha producido un error: '+json.err);}
  })
  
  // composicion de la url del comando a partir de los argumentos
  const cmd_url = ((cmd,arg) =>{
    const gascript_url =GAS;
    var url = gascript_url+"?command="+cmd
    if (typeof(arg) !=="undefined") url = url+'&arg='+JSON.stringify(arg)
    console.log(url);
    return url;
    })
  
  // llamada a la API
  function APIcall(cmd,arg){
      return JSONP(cmd_url(cmd,arg)).then(checkSuccess);
  }
  

  function editSelects(event) {
    //console.log("Holazz",event.target.value)
    APIcall("pendientes",{categoria:event.target.value}) 
    .then(function(data){
     // console.log( "YA HA RESPONDIDO: ",data)
    //  console.log(data.length)
      for (i=0;i<data.length;i++){
        console.log(data[i])
        var elemento = document.createElement('ons-list-item');
        elemento.innerHTML='<label class="left"><ons-checkbox input-id="check-1"></ons-checkbox></label>'
        +'<label for="check-1" class="center">'
        + data[i][1]
        +'</label>'
        document.getElementById('listaTareas').appendChild(elemento);
        
      }
    })
  }
  
```


## 3 de mayo

```javascript=


//https://onsen.io/playground/?framework=vanilla&category=reference&module=dialog
//https://onsen.io/v2/guide/#the-first-onsen-ui-app

 
// dev
GAS="https://script.google.com/a/iesvaldebernardo.es/macros/s/AKfycbyTutvXuUqw1PE3Pq4TL9XZnDTEcmKllZryjQXOwX_5/dev"
// exe
//GAS="https://script.google.com/macros/s/AKfycbyAxExQWFjv6-pAbr4KgR4-oxOUHUEYGLqk3AGuq0lycGSgag65/exec"

//llama a una url que responde un objeto JSON en una función callback
// realmente devuelve un código javascript
// esta funcion devuelve una Promesa, que se ejecuta al recibir los datos

const JSONP = (unique => url =>
  new Promise(rs => {
    const script = document.createElement('script');
    const name = `_jsonp_${unique++}`;

    if (url.match(/\?/)) {
      url += `&callback=${name}`;
    } else {
      url += `?callback=${name}`;
    }
    console.log(url);
    script.src = url;
    window[name] = json => {
      rs(json);
      script.remove();
      delete window[name];
    };
    document.body.appendChild(script);
  })
)(0);

// comprueba que no ha habido errores
const checkSuccess = (json =>{
  console.log("checkSuccess: ",json);
    if(json.success) {
     //   console.log("-->  SUCCESS: "+json.message+" serverTimeout: "+json.serverTimeout );
        return Promise.resolve(json.data);}
    else {return  Promise.reject('Se ha producido un error: '+json.err);}
})

// composicion de la url del comando a partir de los argumentos
const cmd_url = ((cmd,arg) =>{
  const gascript_url =GAS;
  var url = gascript_url+"?command="+cmd
  if (typeof(arg) !=="undefined") url = url+'&arg='+JSON.stringify(arg)
  console.log(url);
  return url;
  })

// llamada a la API
function APIcall(cmd,arg){
    return JSONP(cmd_url(cmd,arg)).then(checkSuccess);
}




function editSelects(event) {
  console.log("Holazz",event.target.value)
  APIcall("pendientes",{categoria:event.target.value}) 
  .then(function(data){
    console.log( "YA HA RESPONDIDO: ",data)
    console.log(data.length)
    document.getElementById('listaTareas').innerHTML = "";
    for (i=0;i<data.length;i++){
      console.log(data[i])
      var elemento = document.createElement('ons-list-item');
      elemento.innerHTML='<label class="left"><ons-checkbox input-id="check-'+data[i][0]+'"'
      +' onclick="compruebaCheck('+"'"+data[i][0]+"'"   +')"'
      +'   "></ons-checkbox></label>'
      +'<label for="check-'+data[i][0]+'" class="center">'
      + data[i][1]
      +'</label>'
      document.getElementById('listaTareas').appendChild(elemento);
    }
    
  })
}

function compruebaCheck(ID){
  var checkBox = document.getElementById("check-"+ID);
  console.log("pulsado ", ID);
  if (checkBox.checked == true){
    console.log("activo");
    APIcall("marcacompleta",{idtarea:ID}) 
  .then(function(data){
    console.log( "MARCADO: ",data)
  })
    
    
    
  } else {
    console.log("desactivado");
        APIcall("marcaincompleta",{idtarea:ID}) 
  .then(function(data){
    console.log( "DESMARCADO: ",data)
  })
  }
  
}



```

## Aplicacion basica en VSCodium


```htmlmixed=

<!DOCTYPE html>
<html>
<head>
  <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsenui.css">
  <link rel="stylesheet" href="https://unpkg.com/onsenui/css/onsen-css-components.min.css">
  <script src="https://unpkg.com/onsenui/js/onsenui.min.js"></script>
</head>
<body>
  <!-- <ons-button onclick="alert('Hello World!')">Click Me</ons-button> -->

  <ons-page>
    <ons-toolbar>
      <div class="center">Pendientes</div>
    </ons-toolbar>
    <ons-select id="choose-sel" onchange="editSelects(event)">
        <option value="">--categoría--</option>
        <option value="insti">insti</option>
        <option value="casa">casa</option>
    </ons-select>

    <ons-list id='listaTareas'>
    </ons-list>
  
    <br />
  
    <ons-fab>
      <ons-icon icon="md-plus"></ons-icon>
    </ons-fab>
      
  </ons-page>

<script>
//https://onsen.io/playground/?framework=vanilla&category=reference&module=dialog
//https://onsen.io/v2/guide/#the-first-onsen-ui-app

 
// dev
GAS=""
// exe
//GAS="https://script.google.com/macros/s/AKfycbyAxExQWFjv6-pAbr4KgR4-oxOUHUEYGLqk3AGuq0lycGSgag65/exec"

//llama a una url que responde un objeto JSON en una función callback
// realmente devuelve un código javascript
// esta funcion devuelve una Promesa, que se ejecuta al recibir los datos

const JSONP = (unique => url =>
  new Promise(rs => {
    const script = document.createElement('script');
    const name = `_jsonp_${unique++}`;

    if (url.match(/\?/)) {
      url += `&callback=${name}`;
    } else {
      url += `?callback=${name}`;
    }
    console.log(url);
    script.src = url;
    window[name] = json => {
      rs(json);
      script.remove();
      delete window[name];
    };
    document.body.appendChild(script);
  })
)(0);

// comprueba que no ha habido errores
const checkSuccess = (json =>{
  console.log("checkSuccess: ",json);
    if(json.success) {
     //   console.log("-->  SUCCESS: "+json.message+" serverTimeout: "+json.serverTimeout );
        return Promise.resolve(json.data);}
    else {return  Promise.reject('Se ha producido un error: '+json.err);}
})

// composicion de la url del comando a partir de los argumentos
const cmd_url = ((cmd,arg) =>{
  const gascript_url =GAS;
  var url = gascript_url+"?command="+cmd
  if (typeof(arg) !=="undefined") url = url+'&arg='+JSON.stringify(arg)
  console.log(url);
  return url;
  })

// llamada a la API
function APIcall(cmd,arg){
    return JSONP(cmd_url(cmd,arg)).then(checkSuccess);
}


function editSelects(event) {
  console.log("Holazz",event.target.value)
  if (event.target.value!=""){
    APIcall("pendientes",{categoria:event.target.value}) 
    .then(function(data){
        console.log( "YA HA RESPONDIDO: ",data)
        console.log(data.length)
        document.getElementById('listaTareas').innerHTML = "";
        for (i=0;i<data.length;i++){
        console.log(data[i])
        var elemento = document.createElement('ons-list-item');
        elemento.innerHTML='<label class="left"><ons-checkbox input-id="check-'+data[i][0]+'"'
        +' onclick="compruebaCheck('+"'"+data[i][0]+"'"   +')"'
        +'   "></ons-checkbox></label>'
        +'<label for="check-'+data[i][0]+'" class="center">'
        + data[i][1]
        +'</label>'
        document.getElementById('listaTareas').appendChild(elemento);
        }
        
    })
    }
}

function compruebaCheck(ID){
  var checkBox = document.getElementById("check-"+ID);
  console.log("pulsado ", ID);
  if (checkBox.checked == true){
    console.log("activo");
    APIcall("marcacompleta",{idtarea:ID}) 
      .then(function(data){console.log( "MARCADO: ",data)})
    
  } else {
    console.log("desactivado");
    APIcall("marcaincompleta",{idtarea:ID}) 
      .then(function(data){console.log( "DESMARCADO: ",data)})
  }
  
}



</script>
</body>

</html>
```