Alongside the regular buttons, there should be a Clone button, in this order: Edit | Clone | Delete
Behaviour:
Details:
What about moving the buttons to a seperate class.
Now you mention clone, but I would like to have a 'send password reset' button for the user table?
And that we can add FormActions() to ListActions() and EditActions() so the detail forms can have custom buttons as well (SendSomeEmail, ExportForNewsletter, MoveToSomewhere, etc, etc)
Completely agree about custom buttons. Here are my thoughts about that.
Started working on it in 84f8f103549a3a95631306611ab15160488e7b55, but hit a brick wall: n-n relationships are more difficult to clone than expected.
We either need to
1) specify which n-n relationships need to be duplicated;
(or)
2) go through the create/update fields and duplicate all n-n relationships there;
The problem with (2) is that
The problem with (1) is that:
Right not option (1) seems the way to go, if it's possible. Will investigate and follow-up.
Didn't know about this. I think so, yes. And it's very elegant. It still doesn't clone relationships but we could do that manually, like in the last comment here.
Hello guys,
Any news on this? Using replicate seams the way to go, yet when pressing duplicate it should prompt you with an edit panel right away even before adding the new entry in DB or am I wrong?
Any thoughts on how I can start doing this myself?
Hi @cristianuibar ,
No development on this so far, no. But I do support bringing this feature to CRUD 4.0, so let's reopen this and appropriately tag it.
_In theory_ it shouldn't be to difficult to do for _your project_. You'd have the added benefit of choosing the solution for the dilemma above and just stick with it (whether to clone related entities, or link to them).
In _your project_, you'd need:
Clone; that trait would have a clone() method that does the actual cloning operation, and it could return the operation status (true or false string), similar to how delete() works;/{$id}/clone;resources/views/vendor/backpack/crud/buttons/clone.blade.php very similar to delete.blade.php, but that would call the route above;Then, for each entity you'd like to be clonable, you would:
Hope it makes sense.
I use cloning in a current project by adding a route/button like @tabacitu suggests and this small piece of code using route-model-binding:
public function clone(Task $task)
{
$clonedTask = $task->replicate();
$clonedTask->push();
return redirect()->route('crud.task.edit', [$clonedTask->id]);
}
I don't need any n-n relations to be cloned. 1-n works with this automatically.
I've used something myself, which might be useful to others, or we might even include it one day. Same caveat as @tswonke above - only 1-n relations are cloned, n-n are NOT.
I have two buttons:
Both work the same way: they don't refresh the page when successful, but refresh the ajax data tables. So no redirect. Just like delete and bulk delete.
Route example:
CRUD::resource('monster', 'MonsterCrudController')->with(function() {
Route::post('monster/{id}/clone', 'MonsterCrudController@clone');
});
That leads to a new method inside the CrudController:
public function clone($id)
{
$this->crud->hasAccessOrFail('create');
$clonedEntry = $this->crud->model->findOrFail($id)->replicate();
return (string) $clonedEntry->push();
}
And in the same controller, in setup(), one needs to add the buttons:
$this->crud->addButtonFromView('line', 'clone', 'clone', 'beginning');
$this->crud->addButtonFromView('bottom', 'bulk_clone', 'bulk_clone', 'end');
And here are the actual buttons:
@if ($crud->hasAccess('create'))
<a href="javascript:void(0)" onclick="cloneEntry(this)" data-route="{{ url($crud->route.'/'.$entry->getKey().'/clone') }}" class="btn btn-xs btn-default" data-button-type="clone"><i class="fa fa-clone"></i> Clone</a>
@endif
<script>
if (typeof cloneEntry != 'function') {
$("[data-button-type=clone]").unbind('click');
function cloneEntry(button) {
// ask for confirmation before deleting an item
// e.preventDefault();
var button = $(button);
var route = button.attr('data-route');
$.ajax({
url: route,
type: 'POST',
success: function(result) {
// Show an alert with the result
new PNotify({
title: "Entry cloned",
text: "A new entry has been added, with the same information as this one.",
type: "success"
});
// Hide the modal, if any
$('.modal').modal('hide');
crud.table.ajax.reload();
},
error: function(result) {
// Show an alert with the result
new PNotify({
title: "Cloning failed",
text: "The new entry could not be created. Please try again.",
type: "warning"
});
}
});
}
}
// make it so that the function above is run after each DataTable draw event
// crud.addFunctionToDataTablesDrawEventQueue('cloneEntry');
</script>
@if ($crud->hasAccess('create'))
<a href="javascript:void(0)" onclick="bulkCloneEntries(this)" class="btn btn-default"><i class="fa fa-clone"></i> Clone</a>
@endif
@push('after_scripts')
<script>
if (typeof bulkCloneEntries != 'function') {
function bulkCloneEntries(button) {
if (typeof crud.checkedItems === 'undefined' || crud.checkedItems.length == 0)
{
new PNotify({
title: "{{ trans('backpack::crud.bulk_no_entries_selected_title') }}",
text: "{{ trans('backpack::crud.bulk_no_entries_selected_message') }}",
type: "warning"
});
return;
}
var message = "Are you sure you want to clone these :number entries?";
message = message.replace(":number", crud.checkedItems.length);
// show confirm message
if (confirm(message) == true) {
var ajax_calls = [];
// for each crud.checkedItems
crud.checkedItems.forEach(function(item) {
var clone_route = "{{ url($crud->route) }}/"+item+"/clone";
// submit an AJAX delete call
ajax_calls.push($.ajax({
url: clone_route,
type: 'POST',
success: function(result) {
// Show an alert with the result
new PNotify({
title: "Entry cloned",
text: "A new entry has been added, with the same information as this one.",
type: "success"
});
},
error: function(result) {
// Show an alert with the result
new PNotify({
title: "Cloning failed",
text: "The new entry could not be created. Please try again.",
type: "warning"
});
}
}));
});
$.when.apply(this, ajax_calls).then(function ( ajax_calls ) {
crud.checkedItems = [];
crud.table.ajax.reload();
});
}
}
}
</script>
@endpush
Hope they help someone.
Thank you @tabacitu ! I'll give them a try tonight.
BOOM! PR for it here: https://github.com/Laravel-Backpack/CRUD/pull/1708
Most helpful comment
I've used something myself, which might be useful to others, or we might even include it one day. Same caveat as @tswonke above - only 1-n relations are cloned, n-n are NOT.
I have two buttons:
Both work the same way: they don't refresh the page when successful, but refresh the ajax data tables. So no redirect. Just like delete and bulk delete.
Route example:
That leads to a new method inside the CrudController:
And in the same controller, in
setup(), one needs to add the buttons:And here are the actual buttons:
Hope they help someone.