In a form consisting of several steps generated in ajax within a single page, I have to use jquery.repeater in an intermediate step.
The form code specific to the repeater is in a dedicated partial
But jquery.repeater does not work, nothing happends when i click on the add or the delete buttons, without even a single javascript error message in the console.
It works if I use this partial directly in a page without the ajax loading.
Note i use the pushing partial updates method in my ajax handler method with
return [
'#myDiv' => $this->renderPartial('mypartial')
];
Welcome for help mates.
here the code i use
and scripts declaration in the bottom of my layout
...
<!-- Scripts -->
<script src="{{ [
'assets/javascript/jquery-3.2.1.min.js',
]|theme }}"></script>
{% framework extra %}
{% scripts %}
</body>
</html>
my partial
<form class="repeater">
<!--
The value given to the data-repeater-list attribute will be used as the
base of rewritten name attributes. In this example, the first
data-repeater-item's name attribute would become group-a[0][text-input],
and the second data-repeater-item would become group-a[1][text-input]
-->
<div data-repeater-list="group-a">
<div data-repeater-item style="display:none;">
<input type="text" name="text-input" />
<input data-repeater-delete type="button" value="Delete" />
</div>
<div data-repeater-item>
<input type="text" name="text-input" />
<input data-repeater-delete type="button" value="Delete" />
</div>
</div>
<input data-repeater-create type="button" value="Add" />
</form>
my page
title = "Ajouter"
url = "/tableau-de-bord/espace/ajouter"
layout = "dashboard"
is_hidden = 0
[formulaireCreation]
==
function onStart()
{
$this->addJs('assets/javascript/node_modules/jquery.repeater/jquery.repeater.js');
$this->addJs('assets/javascript/my-repeater.js');
}
==
<div id='formulaire-creation-component-wrapper'>
{% component 'formulaireCreation' %}
</div>
my-repeater.js
$(document).ready(function () {
$('.repeater').repeater({
// (Optional)
// "show" is called just after an item is added. The item is hidden
// at this point. If a show callback is not given the item will
// have $(this).show() called on it.
show: function () {
$(this).slideDown();
},
// (Optional)
// "hide" is called when a user clicks on a data-repeater-delete
// element. The item is still visible. "hide" is passed a function
// as its first argument which will properly remove the item.
// "hide" allows for a confirmation step, to send a delete request
// to the server, etc. If a hide callback is not given the item
// will be deleted.
hide: function (deleteElement) {
if(confirm('Are you sure you want to delete this element?')) {
$(this).slideUp(deleteElement);
}
},
})
});
And finally, for comparison, the code that works in a basic page
title = "repeater-test"
url = "/repeater-test"
layout = "dashboard"
is_hidden = 0
==
function onStart()
{
$this->addJs('assets/javascript/node_modules/jquery.repeater/jquery.repeater.min.js');
$this->addJs('assets/javascript/my-repeater.js');
}
==
<form class="repeater">
<div data-repeater-list="group-a">
<div data-repeater-item style="display:none;">
<input type="text" name="text-input" />
<input data-repeater-delete type="button" value="Delete" />
</div>
<div data-repeater-item>
<input type="text" name="text-input" />
<input data-repeater-delete type="button" value="Delete" />
</div>
</div>
<input data-repeater-create type="button" value="Add" />
</form>
ok i found a solution, not very elegant but it works
when the partial with the repeater is loaded in ajax, It is as if the page forgot the script declared with
addJS
at the page level, so I declared the script using<script src="/path/to/myscript.js">
at the end of the partial directly and it workstried to inject the script with
{% put scripts %}
but doesn't work