1

I have a table with an edit and delete button. But now I also want to make a clone button.

The clone button should work as follows: It clones almost all the data (data such as the id he cannot take) from the row that the user has clicked. Then it goes to the edit page and there it fills the data in the input/select values.

But I have no idea how I get this done. I have now a function which output all the data: var cloneJob = angular.extend(job);

Then it goes to the edit page location.href = '#/jobs/add'; But the problem is that he doesn't fill the input/select values. Does AngularJS has a function for this? And am I on the right track or do I need to do something else?

UPDATE Here is a litle bit more code:

This is my the code of my table:

<tr ng-repeat="job in (filtered.rows = (jobs | orderBy: orderByDate:true | filter:filterByActive | filter:filter.query)) | skip:pagination.pageSkip() |limitTo:pagination.perPage" ng-class="{ inactive : !job.active }"  style="cursor: pointer;">
    <td>
        <span ng-bind="job.title"></span>
    </td>
    <td>
        <span ng-bind="job.client.name"></span>
    </td>
    <td> 
        <span ng-bind="job.referenceNumber"><span>
    </td>
    <td> 
        <span ng-bind="job.creationDate"><span>
    </td>
    <td>
        <a ng-href="#/jobs/edit/{{job.id}}/tab/candidates" ng-bind="job.candidates.length"></a>
    </td>
    <td>
        <span class="status" ng-class="job.status.value"></span>
    </td>
    <td>
        <a ng-if="job.active" ng-href="#/jobs/edit/{{job.id}}" class="icon go">
            <span class="tooltip" translate="job_name_details"></span>
        </a>
        <a ng-if="job.active" class="icon close" ng-click="showClosePopup(job)">
            <span class="tooltip" translate="job_close"></span>
        </a>

        <a ng-click="cloneJob(job)" ><span>Clone!</span></a>
        <!-- <button data-ng-click="cloneItem(food)" class="btn inline">Add</button> -->

    </td>
</tr>

Function cloneJob is:

$scope.cloneJob = function (job){
    var cloneJob = angular.extend(job);
    location.href = '#/jobs/add';
}

This outputs a lot of json (all the correct data) and it goes to the add page.

4
  • Can you show your table with values, and how you edit it now? Commented Apr 6, 2016 at 9:26
  • Controller will re-execute on page change, thus your value would get refreshed. What you need is a service/factory, where you would store your state values. And then controller will check if values exists, if yes, populate it. Commented Apr 6, 2016 at 9:29
  • Do I need to put my copy function in the service/factory or does this need to stay in the controller? Commented Apr 6, 2016 at 9:56
  • Edited my answer don't know if it meets your needs 100% Commented Apr 6, 2016 at 10:56

2 Answers 2

1

Try something like

<tr ng-repeat="whatever in whatevers"><button ng-click="duplicateItem(whatever)">duplicate</button></tr>

And on the controller:

$scope.duplicateItem = function(item){
   $scope.duplicatedItem = angular.copy(item); //this will do a copy, not just assign a reference.
   //if you need clean the duplicate item
   delete $scope.somePropertyYouWannaClean;
}

It would better if you provided a working example fiddle or at least more code, so we can give you more accurate answers.

Edit:

A cleaner way would be to make the clone function load the info into a service (or factory, a singleton). Then after loading the route you use that service to get the content back and play with it.

Like:

angular.module('some.namespace.factory', [])
    .factory('CloneJobFactory', function () {
        return {
            job: null,
            loadJob: function (job) {
                var auxJob = angular.copy(job);//if you just need a shallow copy use angular.extend
                this.job =  this.cleanJob(auxJob);
            },
            getClonedJob: function(){
                return this.job;
            },
            cleanJob: function(job) {
                //code that cleans a job object that has been cloned
                delete job.propertyYouDoNotWantToKeep;

                return job;//return the cleaned job
            }
        };
    });

Then the clone function that would be in the controller (that now has to inject the factory we just made) just has to wrap the loadJob method:

$scope.cloneJob = function (job) {
    CloneJobFactory.loadJob(job);
}

The same for the function that would use the cloned data:

$scope.someFunction = function (whateverParams) {
  var clonedJob = CloneJobFactory.getClonedJob();
  //whatever you want
}

This can still be improved.

NOTE: Angular singletons are made to, among other things, share info between controllers, services and so on.

Sign up to request clarification or add additional context in comments.

3 Comments

Are you saying that the function $scope.someFunction can be used to set the data in the input/select fields? And can you use this data still when you change the page/url page?
What I'm saying is that, when you have different controllers, you can share data by using services and injecting them. Angular Services and Factories are not instances, they're just plain objects (singletons) so its content won't change when you change controllers (the same object with the same values will get injected in the different controllers). Plus you keep your controller simple.
Oh okay so you can use that function for another controller to get the data. Thanks! Will try to push the data into the input and select field
0

Make a new 'clone' route, that uses the same controller and view as your 'add' route, but passes in the id of the job that should be cloned:

.when('/jobs/add', { templateUrl: 'jobs/add', controller: 'AddController' })
.when('/jobs/clone/:id', { templateUrl: 'jobs/add', controller: 'AddController' })

Then, in the AddController, check if an id has been passed using $routeParams. If there is an id, fetch the job with the id, and initialize the model by cloning the job. If there's no id, initialize the model with an 'empty' job.

myModule.controller('AddController', function($scope, $routeParams){
    if($routeParams.id) {
        //TODO get existing job using $routeParams.id
        $scope.newJob = angular.copy(job);
    } else {
        $scope.newJob = {};
    }
});

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.