TheMathNoob
TheMathNoob

Reputation: 317

passing python data to javascript in web2py

Here is my problem. I have the following function

def index():
    rows=db(db.mylist).select()
    return dict(rows=rows)

so whenever I reload the the front view index I want to retrieve rows from the database and display the data to the user in a list

{{for(r in rows)}}
    li.innerhtml={{=rows.task}}
{{pass}}

Obviously, this is not the right way to do it. I think I have to use json and XML.

This is the table I am using

db.define_table(
   'mylist',
   Field('task', 'string')
)

<div class="col-sm-6">
         <div class="panel panel-default">
             <div class="panel-heading center " style="color: black; font-style: inherit">
                 <form>
                 Task:
                <input name="name" id="task"  />
                     <button type="button" class="btn btn-success btn-sm" onclick=add(),ajax('{{=URL('default','insert_task')}}',['name'])  >add</button>
                     </form>

             </div>

              <div class="panel-body center">
                  <ul id="list" class="list-group">  </ul>
              </div>

         </div>

     </div>
 </div>


var ul = document.getElementById("list");
var lastId=0;
function add()
    {
        if(!isBlank(document.getElementById("task").value)) {


            var iCon = document.createElement('div'); //create a div container
            var dbtMenu=document.createElement('div');
            var li = document.createElement("il");  //create a list-element
            var closeSpan = document.createElement("span"); //create a span for badge attribute
            var ClickListState=0;

            dbtMenu.setAttribute("class","container");
            //dbtMenu.appendChild(dropDownList);
            li.setAttribute('id',lastId); // set an attribute for id
            iCon.className = "glyphicon glyphicon-remove"; // image for remove button
            closeSpan.setAttribute("class", "badge"); //create a new attribute for span
            closeSpan.appendChild(iCon); // put it in the span set
            iCon.addEventListener("click",function(){var element=document.getElementById(li.getAttribute('id'));
                                                    element.parentNode.removeChild(element);}); //functionlity
            li.innerHTML = document.getElementById('task').value;
            var value=document.getElementById('task').value;
            var pass= document.getElementById('task').value;
            li.setAttribute("class", "list-group-item hover-yellow");
            li.addEventListener('click',function() {if(ClickListState==0){li.style.backgroundColor="red"; ClickListState++;}
                                                    else {li.style.backgroundColor="white"; ClickListState--; }});
            li.appendChild(closeSpan);
            lastId++;
            ul.appendChild(li);

        }
    }

function update()
    {
            {{for r in rows:}}
            var iCon = document.createElement('div'); //create a div container
            var dbtMenu = document.createElement('div');
            var li = document.createElement("il");  //create a list-element
            var closeSpan = document.createElement("span"); //create a span for badge attribute
            var ClickListState = 0;

            dbtMenu.setAttribute("class", "container");
            //dbtMenu.appendChild(dropDownList);
            li.setAttribute('id', lastId); // set an attribute for id
            iCon.className = "glyphicon glyphicon-remove"; // image for remove button
            closeSpan.setAttribute("class", "badge"); //create a new attribute for span
            closeSpan.appendChild(iCon); // put it in the span set
            iCon.addEventListener("click", function () {
                var element = document.getElementById(li.getAttribute('id'));
                element.parentNode.removeChild(element);
            });
           // var t ={#{=XML(response.json(r.task))}}
                    li.innerHTML = "t";
            var value = document.getElementById('task').value;
            var pass = document.getElementById('task').value;
            li.setAttribute("class", "list-group-item hover-yellow");
            li.addEventListener('click', function () {
                if (ClickListState == 0) {
                    li.style.backgroundColor = "red";
                    ClickListState++;
                }
                else {
                    li.style.backgroundColor = "white";
                    ClickListState--;
                }
            });
            li.appendChild(closeSpan);
            lastId++;
            ul.appendChild(li);

            {{pass}}

    }
    update();

Upvotes: 0

Views: 1483

Answers (2)

Professor Sarlac Pitt
Professor Sarlac Pitt

Reputation: 11

I came up with this to convert a python list of strings to a javascript array of strings:

{{def print_js_array(left_side, pylist):

  wrap_quotes = map(lambda a: "'{}'".format(a), pylist)

  comma_separated = "" if not pylist else reduce(lambda a,b: "{}, {}".format(a,b), wrap_quotes)

  return "{} = [{}];".format(left_side, comma_separated)
}}

{{=SCRIPT(
  ""
  + print_js_array("var un_pythoned", status_filter_options))
}}

Which given a python list ['', 'Not Started', 'Running', 'Finished', 'Failed'] results in (html):

<script><!--
var un_pythoned = ['', 'Not Started', 'Running', 'Finished', 'Failed'];
//--></script>

Making the array available to subsequent scripts. You could probably write something similar to print a dictionary as json.

Upvotes: 1

Gaurav Vichare
Gaurav Vichare

Reputation: 1183

Read the basic syntax for template language in web2py here

You want this:

<ul>
    {{for row in rows:}}
        <li>{{=row}}</li>
    {{pass}}
</ul>

Other solution can be, build the complete list in controller function using html helpers and pass it to view

def index():
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return dict(task_list=task_list)

And in the view just do:

{{=XML(task_list)}}

XML is an object used to encapsulate text that should not be escaped.

I will suggest you to go through these 2 examples: Image blog and Simple wiki

EDIT:

From your edit, I think you want to add new task using form and wanted to add the list without refreshing the page.

Read Ajax form submission, also related ajax example is given in simple wiki app

<!-- Views/index.html-->
{{extend 'layout.html'}}

<form id="task_form">
     Task:
    <input name="name" id="task"  />
    <input type="submit" class="btn btn-success btn-sm" value="Add" />
</form>

<div id="target"> {{=XML(task_list)}}</div>


<script>
jQuery('#task_form').submit(function() {
  ajax('{{=URL("default", "insert_task")}}',
       ['name'], 'target');
  return false;
});
</script>

--

# Controller

def index():
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return dict(task_list=task_list)

def insert_task():
    """an ajax callback that returns a <ul>"""
    task_name = request.vars.name
    db.mylist.insert(task=task_name)
    rows = db(db.mylist).select()
    my_list = [row.task for row in rows]
    task_list = UL(*my_list)
    return task_list

Upvotes: 1

Related Questions