1

I have a simple post that gets my json objects.

Inside my json I have 2 or more campaigns, campaigns is a array.

within a campaign array I have slots, slots is a array that has 1 or more base_image within.

I display on screen for each campaign.

  • max_slots
  • c_name
  • slots.base_image

so that I can show each campaign name, maximum slots allowed and the images associated within each campaign.

AIM

I am trying to have a upload image and preview image for each campaign so you only see the image preview to the campaign your uploading it to.

PROBLEM

At the moment I upload a image and it shows on the preview for all campaigns, not the individual campaign.

See image bellow:

preview in table

HTML

<body ng-app="myApp">
<div ng-controller="Dashboard">
    <!--FIRST ng-repeat-->
    <div ng-repeat="campaign in campaigns" class="campaign-container">
        <div class="container">
            <h1>{{campaign.c_name}} {{$index}}</h1>
            <strong>This Campaign you are allowed {{campaign.max_slots}} Images</strong>
            <table class="table">
                <thead>
                <tr>
                    <th>Select File</th>
                    <th>Preview Image</th>
                    <th>Add to list</th>
                    <th>Images</th>
                    <!--<th>Remove Image</th>-->
                    <th>Save Campaign</th>
                </tr>
                </thead>
                <tbody>
                <tr>
                    <td> <!--UPLOAD IMAGE-->
                        <div class="upload-new">
                            <input id="fileinput" ng-model="file" type="file" ng-model-instant="" name="file"
                                   accept="image/*"
                                   onchange="angular.element(this).scope().uploadImage(this)">
                        </div>
                        <!--END-->
                    </td>
                    <td>  <!--PREVIEW IMAGE-->
                        <div class="preview">
                            <img style="height: 100px; width: 100px" ng-src="{{preview}}" alt="preview image">
                        </div>
                        <!--END--></td>
                    <td>
                        <button ng-click="addImage()">Add image</button>
                    </td>
                    <td>
                        <div ng-repeat="slot in campaign.slots" class="slot">
                            <img ng-click="addImage()" style="height: 100px; width: 100px" ng-src="{{base_image}}"
                                 alt="slot image">

                            <button ng-click="removeImage(slot)">Remove Image</button>
                        </div>
                    </td>
                    <!--<td>Remove button to be here</td>-->
                    <td>
                        <button ng-click="SaveImage()">Save to API</button>
                    </td>
                </tr>
                </tbody>
            </table>
        </div>
    </div>
    <!--END FIRST ng-repeat-->
</div>
</body>

JavaScript

    .controller('Dashboard', function ($scope, $http, $timeout) {

        $scope.campaigns = [];
        $scope.preview = '';
        // $scope.slots = [];
        $scope.maxSlots = [5];// this dynamic

        $scope.uploadImage = function () {
            // console.log('we are here');
            input = document.getElementById('fileinput');
            file = input.files[0];
            size = file.size;
            if (size < 650000) {
                var fr = new FileReader;
                fr.onload = function (e) {
                    var img = new Image;

                    img.onload = function () {
                        var width = img.width;
                        var height = img.height;
                        if (width == 1920 && height == 1080) {
                            $scope.preview = e.target.result;
                            $scope.perfect = "you added a image";
                            $scope.$apply();

                        } else {
                            $scope.notPerfect = "incorrect definitions";
                        }
                    };
                    img.src = fr.result;
                };

                fr.readAsDataURL(file);
            } else {
                $scope.notPerfect = "to big";
            }
        };

        $scope.addImage = function (index) {

            if ($scope.campaigns[index].slots.length < $scope.campaigns.maxSlots) {
                $scope.campaigns[index].slots.push({
                    "slot_id": $scope.campaigns[index].slots.length + 1,
                    "base_image": $scope.preview,
                    "path_image": ""
                });

            } else {
                window.alert("you have to delete a slot to generate a new one");
            }
        };

$scope.GetData = function () {
            $http({
                url: "http://www.site.co.uk/ccuploader/campaigns/getCampaign",
                method: "POST",
                date: {},
                headers: {'Content-Type': 'application/json'}
            }).then(function (response) {
                // success
                console.log('you have received the data ');
                // console.log(response);
                $scope.campaigns = response.data;
                console.log("logging campaings", $scope.campaigns);
                //$scope.slots = response.data[0].slots;
                //$scope.maxSlots = response.data[0].maxSlots;

            }, function (response) {
                // failed
                console.log('failed getting campaigns goo back to log in page.');
                // console.log(response);
            });
        };

        $scope.GetData();
    })

1 Answer 1

2

You have only one preview variable in your controller, but you need one per campaign. You may want to pass the index of the campaign into your uploadImage function.

I'm not sure if the way you're doing file inputs is correct (haven't done it much myself), but you need something like this:

Template:

<input type="file" onchange="angular.element(this).scope().uploadImage(this, $index)">

<img ng-src="{{campaign.preview}}" alt="preview image">

Controller:

$scope.uploadImage = function (element, index) {
    // Remove this - there are many file inputs with this ID. Use the element or index arguments?
    // input = document.getElementById('fileinput');
    // ...

    if (width == 1920 && height == 1080) {
         $scope.campaigns[index].preview = e.target.result;
    }
}

As mentioned in my comment above, you were also calling input = document.getElementById('fileinput'); to get the file input, but ng-repeat will have created many inputs with that ID. Maybe you should use the input or index that is passed into uploadImage(this, $index). If for some reason you still need to use getElementById instead of using the element you passed in, you could generate unique ID's using the index:

<input id="fileinput-{{ $index }}" 

Edit: The OP used the answer above with a few modifications:

HTML

<input id="fileinput-{{ $index }}" ng-model="file" type="file" ng-model-instant="" name="file" accept="image/*" onchange="angular.element(this).scope().uploadImage(this)">

Controller

    $scope.uploadImage = function (element, index) {
            console.log(element);
            console.log(element.id);
            str = element.id;
            str = str.substr(str.indexOf('-') + 1);
            console.log(str);
            index = str;

            // console.log('we are here');
            input = element;
            file = input.files[0];
            size = file.size;
            if (size < 650000) {
                var fr = new FileReader;
                fr.onload = function (e) {
                    var img = new Image;

                    img.onload = function () {
                        var width = img.width;
                        var height = img.height;
                        if (width == 1920 && height == 1080) {
console.log('we are here');
                            $scope.campaigns[index].preview = e.target.result;
                            // $scope.preview = e.target.result;
                            $scope.perfect = "you added a image";
                            $scope.$apply();

                        } else {
                            $scope.notPerfect = "incorrect definitions";
                        }
                    };
                    img.src = fr.result;
                };

                fr.readAsDataURL(file);
            } else {
                $scope.notPerfect = "to big";
            }
        };
Sign up to request clarification or add additional context in comments.

10 Comments

Thanks for this makes sense. ill get this implemented test and get hopefully accept your answer.
just trying to fix a arror im getting Uncaught ReferenceError: $index is not defined the once its working ill accept answer
Are you naming the function parameter index or $index? In the template it has to be $index, but in the function I named it index
Yes javascrip function its index and html its $index
Is anything getting passed into the function? What if you pass some string just to test?
|

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.