简体   繁体   中英

Bring inline javascript code in a js script

I have this code:

{% for user in users %}

        <form name="form_user_{{ user.id }}" method="post" action="/networks/{{ net.id }}/sensors/{{ sens.id }}/rights">
          <tr>
            <td>
              <div>
                {{ escape(user.name) }}
                <input type='hidden' name="id" value='{{ user.id }}'>
              </div>
            </td>
            <td>

              <label class="radio inline" onclick="document.forms['form_user_{{ user.id }}'].submit();">
                <input type="radio" name="perms" id="perms_{{user.id}}_0" value="0">
                None
              </label>
              <label class="radio inline" onclick="document.forms['form_user_{{ user.id }}'].submit();">
                <input type="radio" name="perms" id="perms_{{user.id}}_1" value="1">
                Read
              </label>
              <label class="radio inline" onclick="document.forms['form_user_{{ user.id }}'].submit();">
                <input type="radio" name="perms" id="perms_{{user.id}}_4" value="4">
                Read + Commands
              </label>

              {{ xsrf_form_html() }}
            </td>

          </tr>
        </form>

and I would bring this code in a function script at the bottom of the html page and associate the function to a onClick event.

I'm trying to write the function but it doesn't work.

Where is the error in this function?

function createFormAndSubmit(){

{% for user in users %}

 var submitForm = document.createElement("form_user_{{ user.id }}");
 document.body.appendChild(submitForm);
 submitForm.method = "POST";

 var newElement = document.createElement("<input type='hidden' name='id' value='{{ user.id }}'>");
 inputForm.appendChild(newElement);

 var newElement = document.createElement("<input type='radio' name='perms' id='perms_{{user.id}}_0' value='0'>");
 inputForm.appendChild(newElement);

 submitForm.action= "/networks/{{ net.id }}/sensors/{{ sens.id }}/rights";
 document.forms['form_user_{{ user.id }}'].submit();
 submitForm.submit();

{% end %}

}

I'm trying to build the form attaching every element in a tree structure.

You are doing it wrong: Do not try to generate Javascript code in any template language.

The recommended approach to pass data form server-side to client-side Javascript code

  • Create your JavaScript code as a separate .js file

  • Embed related data to HTML code using data-attributes as JSON when you generate HTML from a page template

http://html5doctor.com/html5-custom-data-attributes/

  • When the page executes in the browser, on the client-side DOM ready event read this data if you are on a page where you need to perform the magic task. You can do this by calling jQuery to find out necessary elements which carry the data attribute $("div.my-marker-css-class").size() > 0

http://api.jquery.com/ready/

  • Read the data-attribute payload using JSON.parse($("div.my-marker-css-class").data())

  • ... and fill-in or generate necessary client-side DOM (HTML) elements using jQuery or client side templating

DOM tree based JavaScript template engines

This way

  • You do not need to have generate JavaScript code

  • It's more maintainable (you get syntax highlighting to .js files and so on). You can use Firebug etc. to debug your JavaScript code and error line numbers make sense.

  • It's more cache friendly and places less payload to HTML page

This approach is technically superior and once mastered, is easier to maintain and less bug prone. However, it also means that you must understand the full software stack what goes from the server into your browser and this means more learning for newcomer developers.

Mikko is 100% correct. You will need to pass the raw data from the server and parse it with javascript.

Thankfully, there are plugins that can make this easier. http://daffl.github.com/2011/01/06/jquery-dform.html is one.

Here is a python encoder/decoder: http://docs.python.org/2/library/json.html

And to get the JSON from the server you would use: http://api.jquery.com/jQuery.getJSON/

I don't know python well enough to give a complete example, but these are the basic steps you can take to achieve your goal.

EDIT: I will take a stab at an example, but be prepared to debug it :) EDIT 2: change to make the javascript in its own file as requested by OP.

Your HTML will look like this:

<html>
<head>
<script src='path to jquery'></script>
<script src='path to dForm plugin'></script>
<script src='myjs.js'></script> <!-- use relative path -->
</head>
<body>
<form id="myform"></form>

</body>
</html>

Your myjs.js file will look like this:

    $(function(){
        if($("#myform).length > 0) // only run if #myform exists
        $("#myform").buildForm("http://example.com/myform.json");
    });

The myform.json python file will have something like the following code:

import json
json.dumps({'success': True, 'data': users.values()})

See format python output to json for more information regarding python and JSON formatting.

To do this with inline python, try the following:

<html>
<head>
<script src='path to jquery'></script>
<script src='path to dForm plugin'></script>
</head>
<body>
<script>
var dataArray = [
{% for user in users %}
   {
    "action" : "/networks/{{ net.id }}/sensors/{{ sens.id }}/rights",
    "method" : "post", // or get
    "elements" :
    [
        { "type" : "hidden",
          "name" : "id",
          "value" : "{{ user.id }}"
        },
        {
            "name" : "perms",
            "id"   : "perms_{{user.id}}_0",
            "type" : "radio",
            "value": "0"
        },
        {
            "name" : "perms",
            "id"   : "perms_{{user.id}}_0",
            "type" : "radio",
            "value": "0"
        },
        {
            "type" : "submit",
            "value" : "Submit"
        }
        ]
   },
{% end %}
];

for(var i =0; i<dataArray.length; i++){
   $("body").append("<form id='form"+ i +"'></form>");
   $("#form" + 1).dForm(dataArray[i]);
}
</script>
</body>
</html>

I wouldn't personally recommend the inline method, but, its an option. You will also need to account for the extra comma due to the loop. It may add an empty array item depending on the browser. IE may choke altogether.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM