My problem is when I click in my tr, I display a choicefield with {{formFacture.description_article}} but it doesn't work.
When I do td.innerHTML = "test" it does work.
Here is my html code:
<tbody class="table-article-tbody" id="table_article_tbody">
{% for ligne in liste_article %}
<tr id="{{ ligne.ref_article }}">
<td>{{ ligne.descripton_article }}</td>
<td>{{ ligne.compte_article }}</td>
</tr>
{% endfor %}
<tr>
<td>{{ formFacture.description_article }}</td>
<td>{{ formFacture.compte_article }}</td>
</tr>
</tbody>
And here is my javascript code:
<script>
$('#table_article tr').on('click', function(event){
event.preventDefault();
if($(this).attr('id') != undefined){
var $this = $(this);
$.ajax({
type: 'GET',
url : "{% url 'updateligneFacture_tem' %}",
data: $("#form_facture").serialize(),
success : function(data){
$('#contenue_fact').html(data);
$('#table_article tr:last').remove();
var row = $this.attr('id');
var tr = document.getElementById(row);
var td = tr.insertCell(0);
td.innerHTML = "{{ formFacture.description_article }}";
alert(tr);
$('.selectpicker').selectpicker();
},
error : function(){
alert("Erreur update !!");
}
});
}
});
</script>
You are trying set the click event to a table as:
$("#table_article tr").on("click", ...), but you should assign the event to the tr directly
$("#table_article tbody tr").on("click", ...)
or
$("#table_article_tbody tr").on("click", ...)
It's the main reason, you don't set the event to the tr of table correctly.
Also, you can escape the django objects with the filters: safe and scapejs
{{ object|safe }}
{{ object|escapejs }}
Related
I'm new at python, but no at programing. I'm using Django to create a webapp and in some part, I have to create products. A product has a name, brand and type, but this product can have many "inventories". For example: The product Iphone has a brand Apple, type Phone and since I have 3 in my stock, there is another table that saves 3 individual codes for them (and the price and state as well).
For this solution I have used formsets, and it was working fine without the JS. What I mean is that the process is ok, but when I want to dinamically add a new row to add a new Inventory, is added visually but then when I tried to save it, it just saves the last row. I have looked into the debug console of chrome and it seems that the problem is that the name and ID, of the new row, remains the same as the original one (the prefix I believe), but I don't know how to change it. Here is my code: Note in this image that the prefix of the second row is 0
views.py:
class ProductoInline(InlineFormSetFactory):
model= Inventario
fields = ['codigo', 'Producto', 'Precio', 'Estado']
factory_kwargs = {'extra':1 , 'max_num': 10,
'can_order': False, 'can_delete': False}
class InventarioCreateView(LoginRequiredMixin, CreateWithInlinesView):
model = Producto
inlines = [ProductoInline]
fields = '__all__'
factory_kwargs = {'extra': 3, 'max_num': 10,'can_order': False,
'can_delete': False}
template_name = 'ventas/inventario_form.html'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
inventario_form.html:
{%extends "ventas/base.html" %}
{% load staticfiles %}
{% load crispy_forms_tags %}
{%block content %}
<section class="card">
<header class="card-header">Crea/actualiza producto</header>
<div class="card-body">
<form method="POST">
{% csrf_token %}
{{ form|crispy }}
{% for formset in inlines %}
<table class="table table-bordered table-responsive-md table-striped text-center">
<tr>
<th class="text-center">Código</th>
<th class="text-center">Precio</th>
<th class="text-center">Estado</th>
<th class="text-center">Eliminar</th>
</tr>
{{formset.management_form}}
<tbody>
{% for form2 in formset %}
<tr id="{{ form2.prefix }}-row" class="dynamic-form">
<td>{{ form2.codigo }}</td>
<td>{{ form2.Precio }}</td>
<td>{{ form2.Estado }}</td>
<td><a id="remove-{{ form2.prefix }}-row" href="javascript:void(0)" class="delete-row">Eliminar</a></td>
</tr>
{% endfor %}
<tr>
<td colspan="4">Añadir producto</td>
</tr>
</tbody>
</table>
{% endfor %}
<button type="submit">Crear producto</button>
</form>
</div>
{%endblock content %}
formset.js:
function updateElementIndex(el, prefix, ndx) {
var id_regex = new RegExp('(' + prefix + '-\\d+)');
var replacement = prefix + '-' + ndx;
if ($(el).attr("for")) $(el).attr("for",
$(el).attr("for").replace(id_regex, replacement));
if (el.id) el.id = el.id.replace(id_regex, replacement);
if (el.name) el.name = el.name.replace(id_regex, replacement);
}
function addForm(btn, prefix) {
var formCount = parseInt($('#id_' + prefix + '-TOTAL_FORMS').val());
var row = $('.dynamic-form:first').clone(true).get(0);
$(row).removeAttr('id').insertAfter($('.dynamic-form:last')).children('.hidden').removeClass('hidden');
$(row).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, formCount);
$(this).val('');
});
$(row).find('.delete-row').click(function() {
deleteForm(this, prefix);
});
$('#id_' + prefix + '-TOTAL_FORMS').val(formCount + 1);
return false;
}
function deleteForm(btn, prefix) {
$(btn).parents('.dynamic-form').remove();
var forms = $('.dynamic-form');
$('#id_' + prefix + '-TOTAL_FORMS').val(forms.length);
for (var i=0, formCount=forms.length; i<formCount; i++) {
$(forms.get(i)).children().not(':last').children().each(function() {
updateElementIndex(this, prefix, i);
});
}
return false;
}
first of all, even if i want to display a message after click on the table, nothing happened. i didn't understand what is missing for this first step.
At the end, i want to confirm the delete after click on the button delete.
There is my code for each files html.twig and js
main.js:
var produits = document.getElementById('produits');
if (produits) {
produits.addEventListener('click', e => {
// if (e.target.className === 'btn btn-danger') {
// if (confirm('Are you sure?')) {
// const id = e.target.getAttribute('data-id');
//
// fetch(`/Delete/${id}`, {
//
// }).then(res => window.location.reload());
//}
// }
alert(2);
});
}
Affiche.html.twig:
<table class="table table-striped table-bordered" id="produits">
<tr>
<th>Nom</th>
<th>Desctiption</th>
<th>Image</th>
<th>Operation</th>
<th>Actions</th>
</tr>
{% for produit in produits %}
<tr>
<td>{{ produit.nomProduit }}</td>
<td>{{ produit.descriptionProduit }}</td>
<td><img alt="" src="{{ asset('uploads/images/'~produit.imageProduit) }}"></td>
<td>{{ produit.operationProduit }}</td>
<td>
Show
Edit
Delete
</td>
</tr>
{% endfor %}
</table>
An ID is by definition unique, here it seems you can have more than one product so you should set a class to target them all. And moreover you set a "data-id" and not an id. I used "produits-alerte" in my example.
Select products by class and loop over them to add an onClick event, so you can both trigger dialog and get the specific id of the product clicked.
So it leads to :
for (var i = 0, len = produits_alerte.length; i < len; i++) {
produits_alerte[i].onclick = function() {
if (confirm("Are you sure?")) {
console.log('Product ID Clicked : ' + this.getAttribute("data-id"));
//delete product with id above
} else {
//or don't
}
}
}
Here is a working solution using only vanilla JavaScript.
create a function:
<script>
function getvalue() {
alert("Hi");
return;
}
</script>
Link it to the button with 'onClick':
Delete
I read that using onclick is deprecated and bad practice.
I have this do_something function that will proccess the data inside of onclick. How I can convert this to javascript:
{% for user in all_user %}
<tr>
<td>{{ user.code }}</td>
<td>
<button type="button" onclick="do_something('{{ user.name }}', '{{ user.age }}', 1, '{{ user.desc }}');">small</h6></button>
</td>
</tr>
{% endfor %}
Set a class selector on the buttons so you can apply the event listener to it via Javascript.
Your function requires parameters that are unique per user, so you'll need to set those parameters as data attributes on each button.
{% for user in all_user %}
<tr>
<td>
<button class="user-action-btn" type="button"
data-name="{{ user.name }}"
data-age="{{ user.age }}"
data-desc="{{ user.desc }}">small</button>
</td>
</tr>
{% endfor %}
In Javascript, get the elements by class name and set the event handler for each.
Here's an example of the code in Javascript
(function() {
var classname = document.getElementsByClassName("user-action-btn");
var myFunction = function(e) {
e.preventDefault();
var name = this.getAttribute("data-name");
var age = this.getAttribute("data-age");
var desc = this.getAttribute("data-desc");
do_something(name, age, 1, desc)
};
for (var i = 0; i < classname.length; i++) {
classname[i].addEventListener('click', myFunction, false);
}
})();
And here's the JQuery equivalent
$( document ).ready(function() {
$('.user-action-btn').on('click', function(e){
e.preventDefault();
var name = $(this).data('name');
var age = $(this).data('age');
var desc = $(this).data('desc');
do_something(name, age, 1, desc);
});
I'm trying out Django for the first time as a web framework.
My views.py function looks as follow:
def display(request):
find_duplicate()
return render_to_response('index.html', {'obj': my_model.objects.order_by('id')})
def get_dict():
d={}
for e in my_model.objects.all():
col2 = e.col2
col3 = e.col3
col2 = unicode(col2).encode('UTF8')
col3 = unicode(col3).encode('UTF8')
d.setdefault(col2, [])
d[col2].append(col3)
del d['']
return d
def find_duplicate():
#print(d)
d = get_dict()
for k,v in d.items():
if len(v) > 1:
name=[]
id=[]
#print(k)
for i in v:
#print(i)
reg1 = i.split("(")[0]
name.append(reg1)
reg2 = re.search(r'[A-Z0-9]*', i.split("_")[1])
id.append(reg2.group())
#print(name)
#print(id)
And my index.html is as follows:
<body>
<div class="container">
<table align="center">
<tr>
<th bgcolor="#f0a00c">Col1</th>
<th bgcolor="#f0a00c">Col2</th>
<th bgcolor="#f0a00c">Col3</th>
<th bgcolor="#f0a00c">Col4</th>
<th bgcolor="#f0a00c">Col5</th>
</tr>
{% for b in obj %}
<tr>
<td>{{ b.col1 }}</td>
<td>{{ b.col2 }}</td>
<td>{{ b.col3 }}</td>
<td>{{ b.col4 }}</td>
<td>{{ b.col5 }}</td>
</tr>
{% endfor %}
</table>
</div> <!-- /container -->
<script>
var col21 = [], col31 =[];
{% for b in obj %}
col21.push("{{b.col2 }}");
col31.push("{{b.col3 }}");
{% endfor %}
console.log(col21);
console.log(col31);
</script>
</body>
My urls.py:
urlpatterns = patterns(
'',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', 'myapp.views.display'),
)
So, right now the index.html displays the database from mysql ordered by col2 like this:
Col2 | Col3 | Col4
1 | Name1(something_1234) | Some_date
1 | Name1(something_3456) | Some_date
2 | Name3(something_7890) | Some_date
2 | Name4(something_0988) | Some_date
Now, the get_dict() function in views.py returns the dictionary d which looks as follows:
{'1': ['Name1(something_1234)', 'Name1(something_3456)'], '2': 'Name3(something_7890)', 'Name4(something_0988)']}
And the find_duplicate() function parses the name and the id part from each element of Col3. So print(name) in that function will give names and ids for each key (num) i.e., ['Name1', 'Name1'] & ['1234', '3456'] for key 1.
Now, based on this I want to display red boxes on the table elements as follows:
So, for all values in Col2, if any 2 value is same then a box should be displayed around them, and then for that Col2 value check the name part and the id part and then display boxes around them accordingly.
Right now I'm just able to display the table but how do I display the table along with the boxes around the table elements?
I am trying to make a table row a link by using jQuery and this:
jQuery(document).ready(function() {
$(".clickable-row").click(function() {
window.location.href = $(this).data('href');
});
});
In my html file i have this:
<tr class='clickable-row' data-href='my-page.com/user/123'>
<td><span class="glyphicon glyphicon-user"></span></td>
<td>{{ member.getFornamn }} {{ member.getEfternamn }}</td>
<td>{{ member.getEmail }}</td>
<td>{{ member.getTel1 }}</td>
<td>{{ member.getPostadress }}</td>
<td>{{ member.getPostnr }}</td>
</tr>
Nothing is happening.
If i change to this: window.location.href = 'www.google.com'; it's working so I know WERE the problem is...
What am I missing?
Edit:
Plunker: http://plnkr.co/edit/0MBucaxR1fDpYZjZRLHc?p=preview
For some reason above doesn't work for me. If I use this it works:
jQuery(document).ready(function() {
$(".clickable-row").click(function() {
window.location.href = '**any link at all**';
});
});
But when i change to this my console log don't even recognize my click...??
jQuery(document).ready(function() {
$(".clickable-row").click(function() {
window.location.href = $(this).data('href');
});
});
I did this:
jQuery(document).ready(function() {
$(".clickable-row").click(function() {
thisdata = $(this).attr('data-href');
console.log(thisdata);
window.location.href = thisdata;
});
});
And the console gave me the correct answer.
I noticed that my actual table looked like this:
<tr class='clickable-row' data-href='URL://my-page.com/user/123'>
So by removing the URL:// it works now.
Thand you for your help!