I have a datatable that I need to add rows dynamically throught t.row.add(), the table is composed by 4 columns, one of them has buttons inside, those buttons are Show & Edit, and they need the {{ row.id }} so the can be shown or edit, the problem is that I don't know how get the twig variable works. Here is my table code:
<table class="table table-striped table-bordered table-hover" id="sample_2">
<thead>
<tr>
<th class="table-checkbox noprint" style="text-align:center;">
<input type="checkbox" class="group-checkable" data-set="#sample_2 .checkboxes" disabled/>
</th>
<th width="40%" style="text-align:center;">
Valoraciones
</th>
<th width="20%" style="text-align:center;">
Estado
</th>
<th width="20%" style="text-align:center;" class="noprint">
Acciones
</th>
</tr>
</thead>
<tbody>
{% for valoracion in valoracion %}
<tr class="odd gradeX" id="fila{{ valoracion.id }}">
<td class="noprint">
<input type="checkbox" class="checkboxes" disabled/>
</td>
<td style="text-align:center;" id="valoracion">
{{ valoracion.descripcion }}
</td>
{% if valoracion.enabled == 1 %}
<td style="text-align:center;" id="estadoValEnable">Activo</td>
{% else %}
<td style="text-align:center;" id="estadoValEnable">Inactivo</td>
{% endif %}
<td style="text-align:center;" class="noprint">
<a class="btn btn-sm default" data-toggle="modal" onclick="showMantenimientoValoracion({{valoracion.id}})">Ver</a>
<a class="btn btn-sm blue" data-toggle="modal" onclick="editMantenimientoValoracionDetails({{valoracion.id}})">Editar</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
and here is the action to create a new row (the create action is in a modal view):
function sendDataCreateValoracionDetails() {
if ($('#CrearValoracionMantenimiento').val() == "") {
Notificacion("error", "La descripión de la competencia no puede estar vacía");
$('#CrearValoracionMantenimiento').focus();
} else {
$.blockUI({
baseZ: 20000,
message: '<h4><img src="{{ asset('
assets / global / plugins / cubeportfolio / cubeportfolio / img / cbp - loading.gif ') }}" /> Guardando datos, por favor espere...</h4>'
});
var form = document.getElementById("formCreateMantenimientoValoracionDetails");
var formData = new FormData(form);
$.ajax({
url: '{{ path('
createValoracionMantenimiento ') }}',
type: 'POST',
data: formData,
cache: false,
contentType: false,
processData: false,
success: function(returndata) {
if (returndata.success == true) {
$.unblockUI();
$('#crearValoracion').modal('hide');
Notificacion("success", "Valoración RP", "Los datos se han guardado correctamente.");
if ($('#EstadoValoracion').attr('checked')) {
var status = "Activo";
} else {
var status = "Inactivo";
}
$(document).ready(function() {
var t = $('#sample_2').addClass('centro').DataTable();
$("#sample_2").each(function() {
t.row.add([
'<tr>' +
'<td><input type="checkbox" class="checkboxes" disabled/></td>',
'<td>' + ($("#CrearValoracionMantenimiento").val()) + '</td>',
'<td>' + status + '</td>',
'<td ><a class="btn btn-sm default" data-toggle="modal" onclick="showMantenimientoValoracion(' {
{
valoracion.id
}
}
')">Ver</a><a class="btn btn-sm blue" data-toggle="modal" onclick="editMantenimientoValoracionDetails(' {
{
valoracion.id
}
}
')">Editar</a></td></tr>',
]).draw(false);
});
});
} else {
if (returndata.success == false) {
$.unblockUI();
Notificacion("error", "Valoración RP", "Existe una valoración igual.");
}
}
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
Notificacion("error", "Valoración RP", "Ha existido un problema y no se ha podido crear la valoración.");
$.unblockUI();
}
});
}
}
These are my buttons:
<a class="btn btn-sm default" data-toggle="modal" onclick="showMantenimientoValoracion('{{ valoracion.id }}')">Ver</a>
<a class="btn btn-sm blue" data-toggle="modal" onclick="editMantenimientoValoracionDetails('{{ valoracion.id }} ')">Editar</a>
and these are the twig parameters I need to pas inside the functions:
onclick="showMantenimientoValoracion('{{ valoracion.id }}') ///
onclick="editMantenimientoValoracionDetails('{{ valoracion.id }} ')`
here is the function code:
if ($('#EstadoValoracion').attr('checked')) {
var status = "Activo";
} else {
var status = "Inactivo";
}
$(document).ready(function() {
var t = $('#sample_2').addClass('centro').DataTable();
$("#sample_2").each(function() {
t.row.add([
'<tr>' +
'<td><input type="checkbox" class="checkboxes" disabled/></td>',
'<td>' + ($("#CrearValoracionMantenimiento").val()) + '</td>',
'<td>' + status + '</td>',
'<td ><a class="btn btn-sm default" data-toggle="modal" onclick="showMantenimientoValoracion(' {
{
valoracion.id
}
}
')">Ver</a><a class="btn btn-sm blue" data-toggle="modal" onclick="editMantenimientoValoracionDetails(' {
{
valoracion.id
}
}
')">Editar</a></td></tr>',
]).draw(false);
});
});
Thanks everyone :)
A twig variable can be readed by using .twig extension to the file name ends , When I need to use a variable twig inside javascript function, I create it inside file twig. There is not another way.
Just remove the quotes from the twig variable -
onclick="showMantenimientoValoracion('{{ valoracion.id }}')
should be
onclick="showMantenimientoValoracion({{ valoracion.id }})
And in your javascript function add the parameter -
function sendDataCreateValoracionDetails(valoracion_id) {
console.log(valoracion_id)
// Your code goes here
}
This should do it.
Related
i'm trying to go update page . my models.py
class MainGroup(models.Model):
admin = models.ForeignKey(User,on_delete=models.CASCADE)
main_type = models.CharField(max_length=40,unique=True)
date = models.DateTimeField(auto_now_add=True)
my views.py
#login_required
def list_maingroup(request):
lists = MainGroup.objects.all().order_by('-pk')
data = []
for i in lists:
item = {
'id':i.id,
'admin':i.admin.username,
'main_type':i.main_type,
'date':i.date
}
data.append(item)
return JsonResponse({'data':data})
and this is my template
$.ajax({
type:'GET',
url:'/list-main-group',
success:function(data){
data = data.data
spinnerBox.classList.add('non-visible')
var k = '<tbody>'
for(i = 0;i < data.length; i++){
const date = new Date(data[i]["date"]).toLocaleString();
const id = parseInt(data[i]['id'])
// const url = '{% url "products:update_maingroup" %}'
// const my_url = url + "/"+id
k+= '<tr>';
k+= '<td>' + data[i]['id'] + '</td>';
k+= '<td>' + data[i]["admin"] + '</td>';
k+= '<td>' + data[i]["main_type"] + '</td>';
k+= '<td>' + date + '</td>';
k+= '<td align="center">'+
'<button class="btn btn-info bg-info" id="update" data-url='+{% url "products:update_maingroup" id %}+ '><i class="far fa-edit"></i></button>'+
' <button class="btn btn-danger btn-del bg-danger" data-did='+parseInt(data[i]["id"])+"><i class='far fa-trash'></i></button>"+
'</td>';
k+= '</tr>'
}
k+='</tbody>'
tableBody.innerHTML = k
$('#maingroupid').dataTable({
"order": [[ 0, "desc" ]]
});
},
// error:function(error){
// console.log(error)
// }
});
<div class="card-body table-responsive" >
<div id="spinner-box" class="spinner-border text-primary text-center" role="status">
</div>
<table id="maingroupid" class="table table-bordered table-striped text-center">
<thead>
<tr>
<th>#</th>
<th>{% trans "admin" %}</th>
<th>{% trans "name" %}</th>
<th>{% trans "date" %}</th>
<th>{% trans "options" %}</th>
</tr>
</thead>
<tbody id="tableData">
</tbody>
</tfoot>
</table>
</div>
i've tried several ways to achieve that but still none of them worked , and this my views.py to update
#login_required
def update_maingroup(request,id):
obj = get_object_or_404(MainGroup,id=id)
form = MainGroupForm(instance=obj)
if request.is_ajax() and request.method == 'POST' and request.user.is_superuser:
if form.is_valid():
form = MainGroupForm(request.POST,instance=object)
form.save()
return JsonResponse({'success':'success'})
else:
return JsonResponse({'success':False,'error_msg':form.errors,'error_code':'invalid'})
context = {'form':form,'obj':obj}
return render(request,'update_maingroup.html',context)
and my update_maingroup.html
<form id="main-form" role="form" method="POST" action="{% url 'products:update_maingroup' id=obj.id %}">{% csrf_token %}
<div class="card-body">
<div class="form-group row">
<label for="mainGroup" class="col-sm-2 control-label">{% trans "name " %}</label>
<div class="col-sm-10">
{{form.main_type | attr:'id:mainGroup'}}
<p id="main_error" class="alert alert-danger" aria-disabled="true" hidden></p>
</div>
</div>
</div>
<!-- /.card-body -->
<div class="card-footer">
<button type="submit" class="btn btn-success">{% trans "save" %}</button>
</div>
</form>
my urls.py to update
path('maingroup/update/<int:id>',update_maingroup,name='update_maingroup'),
path('list-main-group',list_maingroup,name='list-maingroup'),
but it raise this error :
Reverse for 'update_maingroup' with no arguments not found. 1 pattern(s) tried: ['maingroup/update/(?P[0-9]+)$']
is there something i have to change or add please ? thank you for helping ..
You are mixing Django template tags with JavaScript in your template:
{% url "products:update_maingroup" id %}
This does not work because the template tag only gets evaluate once when the template is rendered, not when the JavaScript get executed.
You have to generate the URL in your view:
#login_required
def list_maingroup(request):
lists = MainGroup.objects.all().order_by('-pk')
data = []
for i in lists:
item = {
'id':i.id,
'admin':i.admin.username,
'main_type':i.main_type,
'date':i.date,
'url': reverse("products:update_maingroup", kwargs={"id": i.id})
}
data.append(item)
return JsonResponse({'data':data})
In your template:
...
'<button class="btn btn-info bg-info" id="update" data-url='+data[i]["url"] + '><i class="far fa-edit"></i></button>'+
...
There are a bunch of alternatives:
you can create a "template URL" with a dummy values and replace those
var urlTemplate = "{% url "products:update_maingroup" 9999 %};
var url = urlTemplate.replace("9999", id);
you can use a third-party library that provides URL reversal in JavaScript, e.g. django-js-reverse
I load my table first, then I dynamically append tags asynchronously.
As soon as those tags are appended, the table row height seems to shift up. How can I prevent that ?
I've tried
.portfolio-table tr {
height: 80px;
}
Table
<table class="table portfolio-table">
<thead class="thin-border-bottom">
<th width="2%">#</th>
<th width="28%">Name</th>
<th width="60%" class="text-left">Tags</th>
<th width="5%">Edit</th>
<th width="5%">Delete</th>
</thead>
<tbody>
<tr>
#foreach ($portfolios as $portfolio)
<td title="{{ $portfolio->id }}">{{ $portfolio->id }} </td>
<td>
<a href="/portfolio/{{ $portfolio->id ?? '' }}/">
{{ $portfolio->name }}
</a>
</td>
<td class="text-right" >
<img src="/assets/fe/img/svg/default.svg" alt="Loading" width="30px">
<p class="portfolioSkillTags text-left" id="{{ $portfolio->id ?? '' }}"></p>
</td>
<td>
<a href="/portfolio/{{ $portfolio->id ?? '' }}/edit" type="button" class="btn btn-info btn-sm">
Edit
</a>
</td>
<td>
<a data-toggle="modal" data-target="#delete_portfolio_{{ $portfolio->id ?? '' }}" type="button" class="btn btn-danger btn-sm">
Delete
</a>
</td>
</tr>
#endforeach
</tbody>
</table>
ajax
$("tbody").each(function(){
$($(this)).find('tr').each(function(){
var selector = $(this);
var id = $(this).find('td:nth-child(1) ').attr('title');
// console.log('%c id = ' + id, "color: green;");
// return false;
var data = {};
data.id = id;
$.ajax({
method: 'POST',
url: '/api/portfolio/' + id + '/skills',
crossDomain: true,
contentType: false,
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('value'),
"Accept": "application/json",
"Content-Type": "application/x-www-form-urlencoded",
"Cache-Control": "no-cache"
},
data: data,
success: function(response){
console.log(id, response);
$('p.portfolioSkillTags#'+ id).prev('img').fadeOut();
for (i = 0; i < response.length; i++) {
// console.log(response[i],id);
var name = response[i]['name'];
var color = response[i]['color'];
$('p.portfolioSkillTags#'+id).prepend('<span class="badge" style="background-color:' + hexToRgb(color,.2) + ';border:' + hexToRgb(color,.7) + ' 2px solid;">' + name + '</span>').fadeIn('slow');
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log(JSON.stringify(jqXHR));
console.log("AJAX error: " + textStatus + ' : ' + errorThrown);
}
});
});
});
It seems the loading spinner image causes the glitch since it makes the text oveerflow. You can try fix it with some css style like float right so it wont make the paragraph wrap.
<img src="/assets/fe/img/svg/default.svg" style="float: right;" alt="Loading" width="30px">
The issue is with the height of the spinner (svg element). When you loads the data asynchronously, it brings the spinner with larger height. As soon as your API call resolves successfully, the spinner element (which has larger height goes away). Then your other data that can be retained in less height shrinks and produces this issue.
You can fix it with many ways, the simplest one is, keep the height(including paddings) of spinner (svg) element smaller than height of td element. For example:
<img src="/assets/fe/img/svg/default.svg" alt="Loading" width="30px" height="30px">
.portfolio-table tr td {
height: 50px;
}
UODATE
Please rectify the HTML as well, you might want to start the foreach loop outside the start tag of tr HTML element.
#foreach ($portfolios as $portfolio)
<tr>
<td title="{{ $portfolio->id }}">{{ $portfolio->id }} </td>
<td>
<a href="/portfolio/{{ $portfolio->id ?? '' }}/">
{{ $portfolio->name }}
</a>
</td>
<td class="text-right" >
<img src="/assets/fe/img/svg/default.svg" alt="Loading" width="30px">
<p class="portfolioSkillTags text-left" id="{{ $portfolio->id ?? '' }}"></p>
</td>
<td>
<a href="/portfolio/{{ $portfolio->id ?? '' }}/edit" type="button" class="btn btn-info btn-sm">
Edit
</a>
</td>
<td>
<a data-toggle="modal" data-target="#delete_portfolio_{{ $portfolio->id ?? '' }}" type="button" class="btn btn-danger btn-sm">
Delete
</a>
</td>
</tr>
#endforeach
$('p.portfolioSkillTags#'+ id).prev('img').fadeOut();
make this to
$('p.portfolioSkillTags#'+ id).prev('img').hide();
and Please rectify the HTML as well, you might want to start the foreach loop outside the start tag of tr HTML element as mentioned by Prince
I think the problem is a css animation. Try something to globally enforce to disable them to see if the behavior disappear.
* {
animation: none !important;
}
If that is the case disable the animation with the right css selector when you are loading your data.
I tried to send information via ajax about user_question and language input fields, but how to write correctly this element inside ajax javascript to save the table element value in database.
thank you.
the script element.
<table id="myTable" class="table table-sm table-hover order-list">
<thead>
<tr>
<td>User Question</td>
<td>Language</td>
</tr>
</thead>
<tbody>
<tr>
<td class="col-md-9">' . HTML::inputField('user_question', null, 'placeholder="Write a short answer"'). '</td>
<td class="col-md-2">' . HTML::inputField('language', null, 'placeholder="Language"') . '</td>
<td class="col-sm-1"><a id="delete_row" class="deleteRow"></a></td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="5">
<input type="button" class="btn btn-lg btn-block " id="addrow" value="Add Row" />
</td>
</tr>
<tr></tr>
</tfoot>
</table>
<script>
$(document).ready(function () {
var counter = 0;
$("#addrow").on("click", function () {
var newRow = $("<tr>");
var cols = "";
cols += '<td><input type="text" class="form-control" name="user_question' + counter + '"/></td>';
cols += '<td><input type="text" class="form-control" name="language' + counter + '"/></td>';
cols += '<td><input type="button" class="ibtnDel btn btn-md btn-danger " value="Delete"></td>';
newRow.append(cols);
$("table.order-list").append(newRow);
counter++;
// element pb
// var data = $("#new_product").serialize(); // form id or table id ?
var dataString = 'user_question='+user_question+'language='+language;
$.ajax({
type: 'POST',
url: '{$ajax_url}',
data : dataString,
success: function(data) {
alert(data);
$("p").text(data);
}
});
$("table.order-list").on("click", ".ibtnDel", function (event) {
$(this).closest("tr").remove();
counter -= 1
});
});
</script>
Use like this to get php variables value inside javascript in .php page
url: "<?php echo $ajax_url; ?>",
Also use & and symbol to add two or more param in your dataString
Im loading row detail information in a bootstrap table via an Ajax call with the id as parameters .
This details show within a collapsible row using a glyph icon button.
However,clicking back on the button to collapse the row end up in distorting the display.
I've been struggling to find a fix to it although the code seems correct.
May you find the jsFiddle here
var parentsData = {
"success": true,
"parents": [{
"id": 1531,
"Firstname": "Austin",
"Surname": "Ana\u00eblle",
"schoolId": "046039",
"schoolName": "ARCAMBAL",
"commune": "ARCAMBAL"
}, {
"id": 2032,
"Firstname": "Ramos",
"Surname": "L\u00e8i",
"schoolId": "046043",
"schoolName": "J CALVET",
"commune": "CAHORS"
}, {
"id": 3036,
"Firstname": "Baker",
"Surname": "Salom\u00e9",
"schoolId": "046043",
"schoolName": "Z LAFAGE",
"commune": "CAHORS"
}, {
"id": 1724,
"Firstname": "Berry",
"Surname": "Marl\u00e8ne",
"schoolId": "046044",
"schoolName": "J CALVET",
"commune": "CAHORS"
}]
};
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
if (!$(this).closest('tr').next('tr').hasClass('expand-child')) {
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
$(".expand-child").slideUp();
var $this = $(this).closest('tr');
var rowId = $(this).data('id');
var newRow = '<tr class="expand-child">' + '<td colspan="12" id="collapse' + rowId +
'">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th >FirstName</th>' +
'<th >School Id</th>' +
'<th >School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function(parentsData) {
if (parentsData.parents) {
var parents = parentsData.parents;
$.each(parents, function(i, parent) {
newRow = newRow + '<tr scope="row">' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune +
'</td>' +
'</tr>';
});
newRow = newRow + '</tbody></table></td></tr>';
}
$(newRow).insertAfter($this);
}
});
} else {
$(this).closest('tr').slideToggle();
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
$detailRow.style.visibility.toggle('table-row collapse');
$(e.target).toggleClass('glyphicon-eye-close glyphicon-eye-open');
}
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script>
<container>
<table class="table table-striped table-hover js-table">
<thead>
<tr>
<th>Training</th>
<th>Title</th>
<th>Date</th>
<th>End date</th>
<th>Description</th>
<th>nb of Applicants</th>
<th>Actions</th>
</tr>
</thead>
<tr data-toggle="collapse" data-target="#collapse4039" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 16/10/2016</td>
<td>16/oct./2016</td>
<td>13/oct./2016</td>
<td>Sequelae of viral hepatitis</td>
<td>15</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/edsa-AgrementEPS/app_dev.php/formation/4039/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse4095" class="clickable">
<td>Activités nautiques</td>
<td> Activités nautiques - 24/10/2016</td>
<td>24/oct./2016</td>
<td>21/oct./2016</td>
<td>Severe pre-eclampsia, third trimester</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group hidden" role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4095 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon " aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Valider les candidats">
<a href="/valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group hidden" role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 24/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
<tr data-toggle="collapse" data-target="#collapse3188" class="clickable">
<td>Activités nautiques</td>
<td>Activités nautiques - 29/10/2016</td>
<td>29/oct./2016</td>
<td>26/oct./2016</td>
<td>Other secondary chronic gout</td>
<td>0</td>
<td>
<div class="btn-group btn-group-sm" role="group" aria-label="...">
<div class="btn-group " role="group" aria-label="Voir le detail">
<a href="#" class="parents js-view-parents" data-href="formation_json_parents" data-id=4039 data-toggle="tooltip" data-placement="top" alt="Voir les details" title="Voir les inscrits">
<span class="glyphicon glyphicon-eye-close" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Valider les candidats">
<a href="valider" data-href='' alt="Valider les candidats" data-toggle="tooltip" data-placement="right" title="Valider les candidats">
<span class="glyphicon glyphicon-check" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
<div class="btn-group " role="group" aria-label="Imprimer la liste d'emargement pour cette formation">
<a href="/liste?print=pdf" data-href="" alt="Download PDF list of applicants" data-toggle="tooltip" data-placement="right" name="Activités nautiques - 16/10/2016" title="Download PDF list of applicants">
<span class="glyphicon glyphicon-download-alt" aria-hidden="true" style="color:black; margin: 5px;"></span>
</a>
</div>
</div>
</td>
</tr>
</table>
</container>
The main problem is that you attached the ID for collapsing on the wrong element. It should be attached to the tr.expand-child element and not the .expand-child td element.
I would build the .expand-child row in its entirety only once you have an AJAX response.
And it's a good habit to cache elements that you will be re-using.
Here's how I would revise your code:
var $table = $('.js-table');
$table.find('.js-view-parents').on('click', function(e) {
e.preventDefault();
// cache elements
var $btn = $(e.target), $row = $btn.closest('tr'),
// find next immediate .expand-child
$nextRow = $row.next('tr.expand-child');
// toggle button
$btn.toggleClass('glyphicon-eye-close glyphicon-eye-open');
// if .expand-child row exist already, toggle
if ($nextRow.length) {
// show or hide .expand-child row if eye button is open or not, respectively
$nextRow.toggle($btn.hasClass('glyphicon-eye-open'));
// if not, create .expand-child row
} else {
$.ajax({
url: '/echo/json/',
dataType: "json",
data: parentsData,
success: function (parentsData) {
var newRow = '<tr class="expand-child" id="collapse' + $btn.data('id') + '">' +
'<td colspan="12">' +
'<table class="table table-condensed table-bordered" width=100% >' +
'<thead>' +
'<tr>' +
'<th>Surname</th>' +
'<th>FirstName</th>' +
'<th>School Id</th>' +
'<th>School name</th>' +
'</tr>' +
'</thead>' +
'<tbody>';
if (parentsData.parents) {
$.each(parentsData.parents, function(i, parent) {
newRow += '<tr>' +
'<td>' + parent.Firstname + '</td>' +
'<td>' + parent.Surname + '</td>' +
'<td>' + parent.schoolId + '</td>' +
'<td>' + parent.schoolName + ' ' + parent.commune + '</td>' +
'</tr>';
});
}
newRow += '</tbody></table></td></tr>';
$row.after(newRow);
}
});
}
});
Demo
For demo purposes, I have commented out the AJAX call.
There are several things wrong in your else block. First of all,
$(this).closest('tr').slideToggle();
is going to slide up your parent row, which is not what you want - you want to hide the child row.
var $detailRow = $(this).closest('tr').next('tr').hasClass('expand-child');
hasClass() will return a boolean, you cannot use it to filter a jQuery collection. What you are trying to do is select the next <tr> that has the class .expand-child, like this:
var $detailRow = $(this).closest('tr').next('tr.expand-child');
The next line makes absolutely no sense.
$detailRow.style.visibility.toggle('table-row collapse');
I guess you want to toggle the classes of that row instead:
$detailRow.toggleClass('table-row collapse');
These changes will make the first showing/hiding work. But then there's a problem in your if block as well:
$(".expand-child").slideUp();
This will select all elements with the class .expand-child in the DOM. But you'll probably want to only select the child row of the current parent row.
I am, however, not going to debug this whole code for you. I think, I have made some of the main issues clear (see this updated fiddle: https://jsfiddle.net/r7sgL7vy/2/) and you'll hopefully be able to go on from here yourself.
One more tipp: For performance, store jQuery collections that you use more than once in variables instead of querying them every time you need them. You already do this with $detailRow for example, and with $this = ... - but it's not used consequently. Why not select and declare all the needed dom elements at the start of the click event handler and then use them everywhere? Besides the performance factor, it also makes your code much cleaner, easier to understand (for you and for others) and easer to spot any mistakes in your logic.
I'm trying to pass a variable to a function, I know there are many topics about this, and I've nearly tried all suggestions, but still can't get it to work, these are my attempts:
edit: without the onclick, everything is working fine
var filename = file.name;
<button class="btn btn-danger delete" onclick="deleteImage(\''+filename+'\');">
results in: Uncaught SyntaxError: Unexpected token ILLEGAL
<button class="btn btn-danger delete" onclick="deleteImage("'+type+'");">
results in (alert): 'filename'
<button class="btn btn-danger delete" onclick="deleteImage('" + filename + "');">
results in: Uncaught SyntaxError: Unexpected token ILLEGAL
<button class="btn btn-danger delete" onclick="deleteImage(" + filename + ");">
result in: Uncaught SyntaxError: Unexpected token }
this is the full code (modified, blueimp fileuploader)
<script id="template-download" type="text/x-tmpl">
{% for (var i=0, file; file=o.files[i]; i++) { %}
<tr class="template-download fade">
{% if (file.error) { %}
<td></td>
<td class="name"><span>{%=file.name%}</span></td>
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
<td class="error" colspan="2"><span class="label label-important">Error</span> {%=file.error%}</td>
{% } else {
// add the image urls to the file inputbox
var filename = file.name;
var prev = $("#mFile").val();
$("#mFile").val(prev + file.name + ",");
%}
<td class="preview">{% if (file.thumbnail_url) { %}
<img src="modules/mod_stern_form_prijsopgave/upload/server/php/files/thumbnail/{%=file.name%}">
{% } %}</td>
<td class="name">
{%=file.name%}
</td>
<td class="size"><span>{%=o.formatFileSize(file.size)%}</span></td>
<td colspan="2"></td>
{% } %}
<td>
<button class="btn btn-danger delete" onclick="deleteImage('" + filename + "');" data-type="{%=file.delete_type%}" data-url="{%=file.delete_url%}"{% if (file.delete_with_credentials) { %} data-xhr-fields='{"withCredentials":true}'{% } %}>
<i class="icon-trash icon-white"></i>
<span>Verwijderen</span>
</button>
</td>
</tr>
{% } %}
</script>
and testing like this:
function deleteImage(filename) {
alert(filename);
}
what am I doing wrong? Thanks for your advice
try the template format for onclick value:
onclick="deleteImage('{%=filename%}');"
try file.name as well
onclick="deleteImage('{%=file.name%}');"
<button id="deleteOnClick" class="btn btn-danger delete">...</button>
and in javascript:
document.getElementById("deleteOnClick").onclick = function(){deleteImage(filename);}
edit:
if you want to delete the file specified only by the original filename value:
var deleteByFile = (function (filename){
return function(){deleteImage(filename);};
}(filename));
document.getElementById("deleteOnClick").onclick = deleteByFile
You can't access JS variables from your HTML. You must do something like this:
var filename = 'testing';
document.getElementById('testdiv')
.setAttribute('onclick', "alert('" + filename + "')");
filename = 'more testing';
Here is a fiddle.
try to use onclick="deleteImage(" + filename + ");"
You can set a varaiable like var counter = 1;
Wherever it is required, you can update it like
onclick="updateCount('+counter+')"