Comments (11)
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.
from crud.
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:
- one to be included per line (like Delete)
- one to be included in the bottom stack (like bulk delete)
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:
- clone.blade.php
@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>
- bulk_clone.blade.php
@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.
from crud.
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)
from crud.
Completely agree about custom buttons. Here are my thoughts about that.
from crud.
Started working on it in 84f8f10, but hit a brick wall: n-n relationships are more difficult to clone than expected.
We either need to
- specify which n-n relationships need to be duplicated;
(or)
- go through the create/update fields and duplicate all n-n relationships there;
The problem with (2) is that
- there could be custom relationship fields, and those don't get duplicated;
- there could be relationships that are added automatically, but are not displayed as fields to the user (ex: auto-assign the groups a user belongs to to a tag);
- what would we use, the create or update fields? because they might be different;
The problem with (1) is that:
- it's uncomfortable to write on the model a $duplicateRelations variable;
- I'm not quite sure we CAN get the relationship table, just from the relationship method name;
Right not option (1) seems the way to go, if it's possible. Will investigate and follow-up.
from crud.
Is this any help? https://laravel.com/api/5.3/Illuminate/Database/Eloquent/Model.html#method_replicate
from crud.
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.
from crud.
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?
from crud.
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:
- a trait that attaches this operation on the EntityCrudController... say...
Clone
; that trait would have aclone()
method that does the actual cloning operation, and it could return the operation status (true or false string), similar to howdelete()
works; - a route for that operation (probably
/{$id}/clone
; - a button type in
resources/views/vendor/backpack/crud/buttons/clone.blade.php
very similar todelete.blade.php
, but that would call the route above;
Then, for each entity you'd like to be clonable, you would:
- add the route
- add the trait
Hope it makes sense.
from crud.
Thank you @tabacitu ! I'll give them a try tonight.
from crud.
BOOM! PR for it here: #1708
from crud.
Related Issues (20)
- [Bug] Attribute of n-n relationship is not set during update (using select2_multiple field) HOT 2
- CRUD field JS Does Not Play Nicely With Repeatable and Date Range HOT 2
- [Bug] [PRO] TinyMCE fields overwrite 'content_css' option HOT 5
- [Bug] Typed property Backpack\CRUD\app\Library\Database\Table::$columns must not be accessed before initialization HOT 2
- [Bug] CRUD field JS Does Not Play Nicely When Sorting Repeatable HOT 2
- [Bug] Method Illuminate\Database\PostgresConnection::getDoctrineColumn does not exist HOT 4
- Image field and HasTraslation trait issue HOT 2
- [WIP] upload vs upload_multiple file display inconsistent behavior.
- [Bug] Call to undefined method Backpack\Basset\BassetManager::echoJs() HOT 5
- [Bug] One crud of many not properly working create/edit/preview pages. HOT 3
- Deploy Backpack for Laravel in production HOT 4
- [Bug] HOT 2
- afterColumn() doesn't work from custom trait.
- Add more db engines to test workflow
- [Bug] HOT 6
- [Bug] When using 'select' type with morphToMany relationship, it errors. HOT 2
- [Bug] Using orderLogic for a column is displaying wrong show/edit links (wrong ids) HOT 2
- [Bug] CRUD Fluent API Does not Support enumFunction HOT 3
- Date field allow nullable save HOT 2
- [Bug] Large increase in amount of executed queries HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from crud.