问题
My views will give a dictionary of "build_id", and there is another view responbile generating the details of a given build_id. I.e., the second view "build_details" takes in a parameter "build_id".
Because I have at least one ids from the dictionary, I am going to generate a table.
<table>
<tr>
<td> Number </td>
<td> Actions </td>
</tr>
{% for index, value in build_history.items %}
<tr>
<td> {{index}} </td>
<td>
<select id="action_menu">
<option value=''>-----</option>
<option value="build_{{value.build_id}}">Build Details</option>
</select>
</td>
</tr>
Each row should have a select box. When I select Build Details
I should be redirected to a different page.
My Jquery attempt:
function onSelectChange(){
var select = $("#action_menu option:selected");
if(!(select.val() == ""))
var build_id = select.val().replace('build_','');
window.location.href="{% url build_details build_id %}";
}
</script>
The problem error is:
Caught NoReverseMatch while rendering: Reverse for 'build_details' with arguments '('',)' and keyword arguments '{}' not found.
I believe this mean build_id was not rendered properly... because we are not dynamically building up the build_id on the JS side (browser side..).
What can I do? I know I can use hardcode http://mydomain and concaented build_id - this will work. But can I take advantage of template tags? How can I achieve this?
Thanks.
Final Working Code
Assuming I have a variable contains the length of the dictionary, when we have mutliple <select>
with the same name, server treats it as if it was one entity. Therefore, we can use name a class, and give each <select>
(each row has one) an unique numeric ID.
# Javascript
<script type="text/javascript">
urlMap = {
{% for index, value in build_history.items %}
'{{ value.build_id }}' : '{% url build_details value.build_id %}'{% if not forloop.last %},{% endif %}
{% endfor %}
};
$(function() {
var item_len = parseInt({{dict_len}});
for (var i = 0; i < item_len; i++){
$("#"+i.toString()+".action").change(function() {
if($(this).val() != '')
window.location.href = urlMap[$(this).val()];
}
)
}});
</script>
# HTML (this is a table, each row has one select)
<select class="action" id={{index}}>
<option value=''>-----</option>
<option value="{{ value.build_id }}">Build Details</option>
</select>
回答1:
JavaScript is 100% incompatible with the django template. The django template renders HTML and Javascript, then the javascript runs - at that point, template tags do not even exist.
You'll have to store option value -> URL combinations with django in a javascript array.
### Javascript map
urlMap = {
{% for value in build_history.values %}
{{ value.build_id }}: '{% url build_details value.build_id %}'
{% if not forloop.last %},{% endfor %}
{% endfor %}
};
function onSelectChange(){
var select = $("#action_menu option:selected");
if(!(select.val() == ""))
var build_id = select.val().replace('build_','');
window.location.href=urlMap[build_id];
}
You could use jQuery's data
function to bind data to an element too:
### Jquery data
{% for value in build_history.values %}
$("#action_menu option[value=build_{{ value.build_id }}]")
.data('href', '{% url build_details value.build_id %}');
{% endfor %}
function onSelectChange(){
var select = $("#action_menu option:selected");
if(!(select.val() == ""))
window.location.href=select.data('href');
}
Please copy and pasting this.
<script type="text/javascript">
urlMap = {
{% for index, value in build_history.items %}
'{{ value.build_id }}' : '{% url build_details value.build_id %}'{% if not forloop.last %},{% endif %}
{% endfor %}
};
$(function() {
$("#foo").change(function() {
window.location.href = urlMap[$(this).val()];
});
})
</script>
<select id="foo">
<option value="">---</option>
{% for index, value in build_history.items %}
<option value="{{ value.build_id }}">Build Details</option>
{% endfor %}
</select>
来源:https://stackoverflow.com/questions/9146196/url-and-jquery