<commit_before>/* global google */

angular.module('skjutsgruppen.controllers', [])

    .controller('AppCtrl', function ($scope, $ionicModal, $timeout, $state) {

        // With the new view caching in Ionic, Controllers are only called
        // when they are recreated or on app start, instead of every page change.
        // To listen for when this page is active (for example, to refresh data),
        // listen for the $ionicView.enter event:
        //$scope.$on('$ionicView.enter', function(e) {
        //});

        // Form data for the login modal
        $scope.loginData = {};

        // Create the login modal that we will use later
        $ionicModal.fromTemplateUrl('templates/login.html', {
            scope: $scope
        }).then(function (modal) {
            $scope.modal = modal;
        });

        // Triggered in the login modal to close it
        $scope.closeLogin = function () {
            $scope.modal.hide();
        };

        // Open the login modal
        $scope.login = function () {
            $scope.modal.show();
        };

        // Perform the login action when the user submits the login form
        $scope.doLogin = function () {
            console.log('Doing login', $scope.loginData);

            // Simulate a login delay. Remove this and replace with your login
            // code if using a login system
            $timeout(function () {
                $scope.closeLogin();
            }, 1000);
        };

        $scope.goHome = function () {
            $state.go('app.startpage');
        };

        $scope.browseSofthouseWebsite = function () {
            var url = 'http://www.softhouse.se';
            window.open(url, '_system', 'location=no');
            return false;
        };
    })

    .controller('registerTripDriverCtrl', function ($scope, $state) {
        $scope.myForm = {};
        var listOfViaLocations = [];

        $scope.addTripDriver = function (form) {

            window.localStorage.result = JSON.stringify($scope.myForm);
            window.localStorage.listOfViaLocations = JSON.stringify(listOfViaLocations);

            $state.go('app.summary');
        };

        $scope.addLocation = function () {
            listOfViaLocations.push($scope.myForm.viaLocation);
        };
    })

    .controller('StartpageCtrl', function ($scope) {
    })

    .controller('ResultCtrl', function ($scope, $ionicPopup, $state) {
        //var result = JSON.parse(window.localStorage.resultForResult || '{}');

        $scope.matches = [
            { who: "Anna Svensson", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-18 07:00", secondTime: "2016-02-18 12:00", availableSeats: "1" },
            { who: "Pelle Jönsson", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-17 12:00", secondTime: "2016-02-18 13:00", availableSeats: "4" },
            { who: "Niklas Smith", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-18 11:00", secondTime: "2016-02-18 12:00", availableSeats: "3" }
        ];

         $scope.showConfirm = function(match) {
           var confirmPopup = $ionicPopup.confirm({
             title: 'Kolla in profil för ' + match.who,
             template: 'Vill du gå vidare och kolla in profilen för ' + match.who + '?'
             //templatUrl: 'templates/popupTemplate.html'
           });

           confirmPopup.then(function(res) {
             if(res) {
               console.log('Gå vidare till profil');
               $state.go('app.popupTemplate');
             } else {
               console.log('Stanna kvar');
             }
           });
         };

        $scope.onMatchClick = function(match) {
          var matchAccepted;
          var messageString = "Info om föraren \nNamn: " + match.who + "\nSamt annan info om resan";

          if(confirm(messageString) == true){
              matchAccepted = true;
          }
          else{
              matchAccepted = false;
          }

          if(matchAccepted == true){
            alert("Vi kommer nu att matcha ihop dig med " + match.who);
          }
        };

    })

    .controller('PushCtrl', function ($scope) {
    })

    .controller('SummaryCtrl', function ($scope) {

        var result = JSON.parse(window.localStorage.result || '{}');
        var listOfViaLocations = JSON.parse(window.localStorage.listOfViaLocations || '{}');

        $scope.listHasLocations = false;
        $scope.item =
        { from: result.from, to: result.to, firstTime: result.firstTime, secondTime: result.secondTime, availableSeats: result.availableSeats, viaLocation: listOfViaLocations };

        if (listOfViaLocations.length > 1) {
            $scope.listHasLocations = true;
        }
        else {
            $scope.listHasLocations = false;
        }
    })

    .controller('AchievementsCtrl', function ($scope, AchievementsFactory) {
        AchievementsFactory.getAchievements().all().then(function (data) {
            $scope.achievements = data;
        });
    })

    .controller('MapCtrl', function ($scope, $state, $cordovaGeolocation, MapFactory) {
        var options = { timeout: 10000, enableHighAccuracy: true };

        $cordovaGeolocation.getCurrentPosition(options).then(function (position) {

            var currentLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

            var mapOptions = {
                center: currentLatLng,
                mapTypeId: google.maps.MapTypeId.HYBRID
            };

            $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

            google.maps.event.addListenerOnce($scope.map, 'idle', function () {

                var markerIcon = {
                    url: 'img/map/me.png',
                    // This marker is 20 pixels wide by 32 pixels high.
                    size: new google.maps.Size(32, 50),
                    // The origin for this image is (0, 0).
                    origin: new google.maps.Point(0, 0),
                    // The anchor for this image is the base of the flagpole at (0, 32).
                    anchor: new google.maps.Point(15, 50)
                };

                var marker = new google.maps.Marker({
                    map: $scope.map,
                    animation: google.maps.Animation.NONE,
                    icon: markerIcon,
                    position: currentLatLng
                });

                //var infoWindow = new google.maps.InfoWindow();
                //var infoWindowContent;

                google.maps.event.addListener(marker, 'click', function () {
                    // infoWindowContent =
                    // '
' +
                    // '
Här är du!
' +
                    // '
';
                    // infoWindow.setContent(infoWindowContent);
                    //infoWindow.open($scope.map, marker);
                });
            });

            MapFactory.getCoordinates().all().then(function (data) {
                $scope.mapCoordinates = data;

                console.log(data);

                if (data !== undefined && data.length > 0) {
                    var bounds = new google.maps.LatLngBounds();
                    var infoWindow = new google.maps.InfoWindow(), marker, i;
                    var markerIcon, coordinateLatLng, infoWindowContent, bonusWindowContent;

                    for (i = 0; i < data.length; i++) {
                        console.log(data[i].username);

                        if (data[i].ETA !== undefined) {
                            $scope.ETA = data[i].ETA;
                        }

                        markerIcon = {
                            url: 'img/map/' + data[i].marker + '.png',
                            // This marker is 20 pixels wide by 32 pixels high.
                            size: new google.maps.Size(32, 50),
                            // The origin for this image is (0, 0).
                            origin: new google.maps.Point(0, 0),
                            // The anchor for this image is the base of the flagpole at (0, 32).
                            anchor: new google.maps.Point(15, 50)
                        };

                        console.log(markerIcon.url);

                        coordinateLatLng = new google.maps.LatLng(data[i].longitud, data[i].latitud);
                        bounds.extend(coordinateLatLng);
                        marker = new google.maps.Marker({
                            title: data[i].username,
                            map: $scope.map,
                            animation: google.maps.Animation.DROP,
                            icon: markerIcon,
                            position: new google.maps.LatLng(data[i].longitud, data[i].latitud)
                        });

                        google.maps.event.addListener(marker, 'click', (function (marker, i) {
                            return function () {
                                if (data[i].marker === 'accepted') {
                                    bonusWindowContent = '
' + data[i].username + ' är påväg till dig och ankomer om ca. ' + data[i].ETA.substr(3, 2) + ' minuter och ' + data[i].ETA.substr(6, 2) + ' sekunder.
'
                                }
                                else {
                                    bonusWindowContent = "";
                                }
                                infoWindowContent =
                                '
' +
                                '
Här är ' + data[i].username + '!
' +
                                bonusWindowContent
                                '
';
                                infoWindow.setContent(infoWindowContent);
                                infoWindow.open($scope.map, marker);
                            }
                        })(marker, i));

                        $scope.map.fitBounds(bounds);
                    }

                    var boundsListener = google.maps.event.addListener(($scope.map), 'bounds_changed', function (event) {
                        this.setZoom(15);
                        google.maps.event.removeListener(boundsListener);
                    });
                }
                else {
                    console.log("Coordinates data is empty or undefined!")
                }
            });

        }, function (error) {
            console.log("Could not get location");
        })
    })

    .controller('StatisticsCtrl', function($scope, StatisticsFactory) {

      StatisticsFactory.getStatistics().all().then(function(data) {
        $scope.statistics = data;
      });

    })

    .controller('SettingsCtrl', function ($scope, SettingsFactory) {

        SettingsFactory.getSettings().all().then(function (data) {
            $scope.settings = data;
        });

        $scope.toggleSetting = function (settingId, newValue) {
            SettingsFactory.updateSetting(settingId, newValue);
        };
    })

    .controller('registerTripPassengerCtrl', function ($scope, $state, $filter) {
        $scope.myForm = {};

        var weekDaysList = ['S', 'M', 'T', 'O', 'T', 'F', 'L'];
        var monthList = ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'];
        var dateFormat = 'yyyy-MM-dd';

        function timePickerCallback(model, parameter) {
            function prependZero(param) {
                if (String(param).length < 2) {
                    return "0" + String(param);
                }

                return param;
            }

            function epochParser(val) {
                if (!val) {
                    return "00:00";
                } else {
                    var hours = parseInt(val / 3600);
                    var minutes = (val / 60) % 60;

                    return prependZero(hours) + ":" + prependZero(minutes);
                }
            }

            return function (value) {
                model[parameter] = epochParser(value);
            };
        }

        function datepickerCallback(model, parameter, dateFormat) {
            return function (value) {
                model[parameter] = $filter('date')(value, dateFormat);
            };
        }

        $scope.datepickerObject = {
            titleLabel: 'Välj datum',
            todayLabel: 'Idag',
            closeLabel: 'Stäng',
            setLabel: 'Ok',
            mondayFirst: true,
            inputDate: new Date(),
            weekDaysList: weekDaysList,
            monthList: monthList,
            templateType: 'popup',
            showTodayButton: 'true',
            callback: datepickerCallback($scope.myForm, 'firstDate', dateFormat),
            dateFormat: dateFormat,
            closeOnSelect: false,
        };

        $scope.timePickerObject = {
            inputEpochTime: (11 * 60 + 30) * 60, // 11:30
            titleLabel: 'Välj klockslag',
            setLabel: 'Ok',
            closeLabel: 'Stäng',
            callback: timePickerCallback($scope.myForm, 'firstTime')
        };

        $scope.datepickerObjectArrival = angular.extend({}, $scope.datepickerObject);
        $scope.datepickerObjectArrival.callback = datepickerCallback($scope.myForm, 'arrivalDate', dateFormat);

        $scope.timePickerObjectArrival = angular.extend({}, $scope.timePickerObject);
        $scope.timePickerObjectArrival.callback = timePickerCallback($scope.myForm, 'arrivalTime');

        $scope.addTripPassanger = function (form) {
            window.localStorage.resultForResult = JSON.stringify($scope.myForm);
            $state.go('app.result');
        };
    })

    .controller('ProfileCtrl', function ($scope) {
        $scope.recurringTrips = [
          {
            title: 'Malmö - Göteborg (ToR)'
          },
          {
            title: 'Hem - Jobbet (ToR)'
          }
        ];

        $scope.storedAddresses = [
          {
              name: 'Hem'
          },
          {
              name: 'Jobbet'
          },
          {
              name: 'Maxi'
          }
        ];
    })

    .controller('popupTemplateCtrl', function($scope) {
        $scope.recurringTrips = [
          {
              title: 'Stockholm - Göteborg (ToR)'
          },
          {
              title: 'Hem - Jobbet (ToR)'
          }
        ];

        $scope.storedAddresses = [
          {
              name: 'Hem'
          },
          {
              name: 'Jobbet'
          },
          {
              name: 'IKEA'
          },
          {
              name: 'Maxi'
          }
        ];
    });
<commit_msg>Fix jshint warnings and some formatting<commit_after>/* global google */

angular.module('skjutsgruppen.controllers', [])

    .controller('AppCtrl', function ($scope, $ionicModal, $timeout, $state) {

        // With the new view caching in Ionic, Controllers are only called
        // when they are recreated or on app start, instead of every page change.
        // To listen for when this page is active (for example, to refresh data),
        // listen for the $ionicView.enter event:
        //$scope.$on('$ionicView.enter', function(e) {
        //});

        // Form data for the login modal
        $scope.loginData = {};

        // Create the login modal that we will use later
        $ionicModal.fromTemplateUrl('templates/login.html', {
            scope: $scope
        }).then(function (modal) {
            $scope.modal = modal;
        });

        // Triggered in the login modal to close it
        $scope.closeLogin = function () {
            $scope.modal.hide();
        };

        // Open the login modal
        $scope.login = function () {
            $scope.modal.show();
        };

        // Perform the login action when the user submits the login form
        $scope.doLogin = function () {
            console.log('Doing login', $scope.loginData);

            // Simulate a login delay. Remove this and replace with your login
            // code if using a login system
            $timeout(function () {
                $scope.closeLogin();
            }, 1000);
        };

        $scope.goHome = function () {
            $state.go('app.startpage');
        };

        $scope.browseSofthouseWebsite = function () {
            var url = 'http://www.softhouse.se';
            window.open(url, '_system', 'location=no');
            return false;
        };
    })

    .controller('registerTripDriverCtrl', function ($scope, $state) {
        $scope.myForm = {};
        var listOfViaLocations = [];

        $scope.addTripDriver = function (form) {

            window.localStorage.result = JSON.stringify($scope.myForm);
            window.localStorage.listOfViaLocations = JSON.stringify(listOfViaLocations);

            $state.go('app.summary');
        };

        $scope.addLocation = function () {
            listOfViaLocations.push($scope.myForm.viaLocation);
        };
    })

    .controller('StartpageCtrl', function ($scope) {
    })

    .controller('ResultCtrl', function ($scope, $ionicPopup, $state) {
        //var result = JSON.parse(window.localStorage.resultForResult || '{}');

        $scope.matches = [
            { who: "Anna Svensson", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-18 07:00", secondTime: "2016-02-18 12:00", availableSeats: "1" },
            { who: "Pelle Jönsson", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-17 12:00", secondTime: "2016-02-18 13:00", availableSeats: "4" },
            { who: "Niklas Smith", from: "Göteborg", to: "Stockholm", firstTime: "2016-02-18 11:00", secondTime: "2016-02-18 12:00", availableSeats: "3" }
        ];

         $scope.showConfirm = function(match) {
           var confirmPopup = $ionicPopup.confirm({
             title: 'Kolla in profil för ' + match.who,
             template: 'Vill du gå vidare och kolla in profilen för ' + match.who + '?'
             //templatUrl: 'templates/popupTemplate.html'
           });

           confirmPopup.then(function(res) {
             if(res) {
               console.log('Gå vidare till profil');
               $state.go('app.popupTemplate');
             } else {
               console.log('Stanna kvar');
             }
           });
         };

        $scope.onMatchClick = function(match) {
          var matchAccepted;
          var messageString = "Info om föraren \nNamn: " + match.who + "\nSamt annan info om resan";

          if(confirm(messageString) == true){
              matchAccepted = true;
          }
          else{
              matchAccepted = false;
          }

          if(matchAccepted == true){
            alert("Vi kommer nu att matcha ihop dig med " + match.who);
          }
        };

    })

    .controller('PushCtrl', function ($scope) {
    })

    .controller('SummaryCtrl', function ($scope) {

        var result = JSON.parse(window.localStorage.result || '{}');
        var listOfViaLocations = JSON.parse(window.localStorage.listOfViaLocations || '{}');

        $scope.listHasLocations = false;
        $scope.item =
        { from: result.from, to: result.to, firstTime: result.firstTime, secondTime: result.secondTime, availableSeats: result.availableSeats, viaLocation: listOfViaLocations };

        if (listOfViaLocations.length > 1) {
            $scope.listHasLocations = true;
        }
        else {
            $scope.listHasLocations = false;
        }
    })

    .controller('AchievementsCtrl', function ($scope, AchievementsFactory) {
        AchievementsFactory.getAchievements().all().then(function (data) {
            $scope.achievements = data;
        });
    })

    .controller('MapCtrl', function ($scope, $state, $cordovaGeolocation, MapFactory) {
        var options = { timeout: 10000, enableHighAccuracy: true };

        $cordovaGeolocation.getCurrentPosition(options).then(function (position) {

            var currentLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

            var mapOptions = {
                center: currentLatLng,
                mapTypeId: google.maps.MapTypeId.HYBRID
            };

            $scope.map = new google.maps.Map(document.getElementById("map"), mapOptions);

            google.maps.event.addListenerOnce($scope.map, 'idle', function () {

                var markerIcon = {
                    url: 'img/map/me.png',
                    // This marker is 20 pixels wide by 32 pixels high.
                    size: new google.maps.Size(32, 50),
                    // The origin for this image is (0, 0).
                    origin: new google.maps.Point(0, 0),
                    // The anchor for this image is the base of the flagpole at (0, 32).
                    anchor: new google.maps.Point(15, 50)
                };

                var marker = new google.maps.Marker({
                    map: $scope.map,
                    animation: google.maps.Animation.NONE,
                    icon: markerIcon,
                    position: currentLatLng
                });

                //var infoWindow = new google.maps.InfoWindow();
                //var infoWindowContent;

                google.maps.event.addListener(marker, 'click', function () {
                    // infoWindowContent =
                    // '
' +
                    // '
Här är du!
' +
                    // '
';
                    // infoWindow.setContent(infoWindowContent);
                    //infoWindow.open($scope.map, marker);
                });
            });

            MapFactory.getCoordinates().all().then(function (data) {
                $scope.mapCoordinates = data;

                console.log(data);

                if (data !== undefined && data.length > 0) {
                    var bounds = new google.maps.LatLngBounds();
                    var infoWindow = new google.maps.InfoWindow(), marker, i;
                    var markerIcon, coordinateLatLng, infoWindowContent, bonusWindowContent;

                    for (i = 0; i < data.length; i++) {
                        console.log(data[i].username);

                        if (data[i].ETA !== undefined) {
                            $scope.ETA = data[i].ETA;
                        }

                        markerIcon = {
                            url: 'img/map/' + data[i].marker + '.png',
                            // This marker is 20 pixels wide by 32 pixels high.
                            size: new google.maps.Size(32, 50),
                            // The origin for this image is (0, 0).
                            origin: new google.maps.Point(0, 0),
                            // The anchor for this image is the base of the flagpole at (0, 32).
                            anchor: new google.maps.Point(15, 50)
                        };

                        console.log(markerIcon.url);

                        coordinateLatLng = new google.maps.LatLng(data[i].longitud, data[i].latitud);
                        bounds.extend(coordinateLatLng);
                        marker = new google.maps.Marker({
                            title: data[i].username,
                            map: $scope.map,
                            animation: google.maps.Animation.DROP,
                            icon: markerIcon,
                            position: new google.maps.LatLng(data[i].longitud, data[i].latitud)
                        });

                        google.maps.event.addListener(marker, 'click', (function (marker, i) {
                            return function () {
                                if (data[i].marker === 'accepted') {
                                    bonusWindowContent = '
' + data[i].username + ' är påväg till dig och ankomer om ca. ' + data[i].ETA.substr(3, 2) + ' minuter och ' + data[i].ETA.substr(6, 2) + ' sekunder.
';
                                } else {
                                    bonusWindowContent = "";
                                }
                                infoWindowContent =
                                '
' +
                                '
Här är ' + data[i].username + '!
' +
                                bonusWindowContent +
                                '
';
                                infoWindow.setContent(infoWindowContent);
                                infoWindow.open($scope.map, marker);
                            };
                        })(marker, i));

                        $scope.map.fitBounds(bounds);
                    }

                    var boundsListener = google.maps.event.addListener(($scope.map), 'bounds_changed', function (event) {
                        this.setZoom(15);
                        google.maps.event.removeListener(boundsListener);
                    });
                } else {
                    console.log("Coordinates data is empty or undefined!");
                }
            });

        }, function (error) {
            console.log("Could not get location");
        });
    })

    .controller('StatisticsCtrl', function($scope, StatisticsFactory) {

      StatisticsFactory.getStatistics().all().then(function(data) {
        $scope.statistics = data;
      });

    })

    .controller('SettingsCtrl', function ($scope, SettingsFactory) {

        SettingsFactory.getSettings().all().then(function (data) {
            $scope.settings = data;
        });

        $scope.toggleSetting = function (settingId, newValue) {
            SettingsFactory.updateSetting(settingId, newValue);
        };
    })

    .controller('registerTripPassengerCtrl', function ($scope, $state, $filter) {
        $scope.myForm = {};

        var weekDaysList = ['S', 'M', 'T', 'O', 'T', 'F', 'L'];
        var monthList = ['Jan', 'Feb', 'Mar', 'Apr', 'Maj', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'];
        var dateFormat = 'yyyy-MM-dd';

        function timePickerCallback(model, parameter) {
            function prependZero(param) {
                if (String(param).length < 2) {
                    return "0" + String(param);
                }

                return param;
            }

            function epochParser(val) {
                if (!val) {
                    return "00:00";
                } else {
                    var hours = parseInt(val / 3600);
                    var minutes = (val / 60) % 60;

                    return prependZero(hours) + ":" + prependZero(minutes);
                }
            }

            return function (value) {
                model[parameter] = epochParser(value);
            };
        }

        function datepickerCallback(model, parameter, dateFormat) {
            return function (value) {
                model[parameter] = $filter('date')(value, dateFormat);
            };
        }

        $scope.datepickerObject = {
            titleLabel: 'Välj datum',
            todayLabel: 'Idag',
            closeLabel: 'Stäng',
            setLabel: 'Ok',
            mondayFirst: true,
            inputDate: new Date(),
            weekDaysList: weekDaysList,
            monthList: monthList,
            templateType: 'popup',
            showTodayButton: 'true',
            callback: datepickerCallback($scope.myForm, 'firstDate', dateFormat),
            dateFormat: dateFormat,
            closeOnSelect: false,
        };

        $scope.timePickerObject = {
            inputEpochTime: (11 * 60 + 30) * 60, // 11:30
            titleLabel: 'Välj klockslag',
            setLabel: 'Ok',
            closeLabel: 'Stäng',
            callback: timePickerCallback($scope.myForm, 'firstTime')
        };

        $scope.datepickerObjectArrival = angular.extend({}, $scope.datepickerObject);
        $scope.datepickerObjectArrival.callback = datepickerCallback($scope.myForm, 'arrivalDate', dateFormat);

        $scope.timePickerObjectArrival = angular.extend({}, $scope.timePickerObject);
        $scope.timePickerObjectArrival.callback = timePickerCallback($scope.myForm, 'arrivalTime');

        $scope.addTripPassanger = function (form) {
            window.localStorage.resultForResult = JSON.stringify($scope.myForm);
            $state.go('app.result');
        };
    })

    .controller('ProfileCtrl', function ($scope) {
        $scope.recurringTrips = [
          {
            title: 'Malmö - Göteborg (ToR)'
          },
          {
            title: 'Hem - Jobbet (ToR)'
          }
        ];

        $scope.storedAddresses = [
          {
              name: 'Hem'
          },
          {
              name: 'Jobbet'
          },
          {
              name: 'Maxi'
          }
        ];
    })

    .controller('popupTemplateCtrl', function($scope) {
        $scope.recurringTrips = [
          {
              title: 'Stockholm - Göteborg (ToR)'
          },
          {
              title: 'Hem - Jobbet (ToR)'
          }
        ];

        $scope.storedAddresses = [
          {
              name: 'Hem'
          },
          {
              name: 'Jobbet'
          },
          {
              name: 'IKEA'
          },
          {
              name: 'Maxi'
          }
        ];
    });
<|endoftext|>


<commit_before>angular.module('app.controllers', ['app.services'])

.controller('sideMenuCtrl', function($scope, $ionicPopup, Material, AccessControl, OAuth, DoorClient) {
   $scope.logout = function() {
      $ionicPopup.show({
         title: 'Log out?',
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  OAuth.logout();
                  AccessControl.initialize();
               }
            }
         ]
      });
      Material.de();
   };
   DoorClient.getWhoAmI(function(user) {
      $scope.user = user;
   });
})

.controller('entitiesCtrl', function($scope, $ionicPopup, Material, DoorClient) {
   $scope.showAuthToken = function(entity) {
      DoorClient.postAuthToken(entity.id, function(data) {
         $ionicPopup.show({
            title: 'Your code is...',
            template: data.token,
            scope: $scope,
            buttons: [
               {
                  text: 'OK',
                  type: 'button-positive'
               }
            ]
         })
         Material.de();
      });
   };
   $scope.open = function(entity) {
      $ionicPopup.show({
         title: `Open ${entity.name}?`,
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  $scope.showAuthToken(entity);
               }
            }
         ],
      });
      Material.de();
   };
   DoorClient.getUserEntities(function(data) {
      $scope.entities = data.content;
      Material.rede();
   });
})

.controller('usersCtrl', function($scope, $rootScope, $state, $ionicListDelegate, $ionicPopup, Material, DoorClient) {
   $scope.edit = function(user) {
      $rootScope.editUser = user;
      $ionicListDelegate.closeOptionButtons();
      $state.go('^.editUser');
   };
   $scope.remove = function(index) {
      $ionicPopup.show({
         title: `Remove ${$scope.users[index].description}?`,
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  DoorClient.deleteUser($scope.users[index].id);
                  $scope.users.splice(index, 1);
               }
            }
         ]
      });
      $ionicListDelegate.closeOptionButtons();
   };
   $rootScope.showUsers = function(){
      DoorClient.getUsers(function(data) {
         $scope.users = data.content;
         Material.rede();
      });
   };
   $rootScope.showUsers();
})

.controller('createUserCtrl', function($scope, $rootScope, Material, DoorClient) {
   $scope.newUser = {};
   $scope.createUser = function(user) {
      DoorClient.postUser(user, function() {
         $rootScope.showUsers();
      });
   };
   Material.de();
})

.controller('editUserCtrl', function($scope, $rootScope, Material, DoorClient) {
   $scope.editUser = $rootScope.editUser;
   $scope.save = function(user) {
      DoorClient.putUser(user, function() {
         $rootScope.showUsers();
      });
   };
   Material.de();
});
<commit_msg>Fix user binding<commit_after>angular.module('app.controllers', ['app.services'])

.controller('sideMenuCtrl', function($scope, $ionicPopup, Material, AccessControl, OAuth, DoorClient) {
   $scope.logout = function() {
      $ionicPopup.show({
         title: 'Log out?',
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  OAuth.logout();
                  AccessControl.initialize();
               }
            }
         ]
      });
      Material.de();
   };
   DoorClient.getWhoAmI(function(user) {
      $scope.user = user;
   });
})

.controller('entitiesCtrl', function($scope, $ionicPopup, Material, DoorClient) {
   $scope.showAuthToken = function(entity) {
      DoorClient.postAuthToken(entity.id, function(data) {
         $ionicPopup.show({
            title: 'Your code is...',
            template: data.token,
            scope: $scope,
            buttons: [
               {
                  text: 'OK',
                  type: 'button-positive'
               }
            ]
         })
         Material.de();
      });
   };
   $scope.open = function(entity) {
      $ionicPopup.show({
         title: `Open ${entity.name}?`,
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  $scope.showAuthToken(entity);
               }
            }
         ],
      });
      Material.de();
   };
   DoorClient.getUserEntities(function(data) {
      $scope.entities = data.content;
      Material.rede();
   });
})

.controller('usersCtrl', function($scope, $rootScope, $state, $ionicListDelegate, $ionicPopup, Material, DoorClient) {
   $scope.edit = function(user) {
      $rootScope.editUser = angular.copy(user);
      $ionicListDelegate.closeOptionButtons();
      $state.go('^.editUser');
   };
   $scope.remove = function(index) {
      $ionicPopup.show({
         title: `Remove ${$scope.users[index].description}?`,
         scope: $scope,
         buttons: [
            {text: 'No'},
            {
               text: 'Yes',
               type: 'button-positive',
               onTap: function(e) {
                  DoorClient.deleteUser($scope.users[index].id);
                  $scope.users.splice(index, 1);
               }
            }
         ]
      });
      $ionicListDelegate.closeOptionButtons();
   };
   $rootScope.showUsers = function(){
      DoorClient.getUsers(function(data) {
         $scope.users = data.content;
         Material.rede();
      });
   };
   $rootScope.showUsers();
})

.controller('createUserCtrl', function($scope, $rootScope, Material, DoorClient) {
   $scope.newUser = {};
   $scope.createUser = function(user) {
      DoorClient.postUser(user, function() {
         $rootScope.showUsers();
      });
   };
   Material.de();
})

.controller('editUserCtrl', function($scope, $rootScope, Material, DoorClient) {
   $scope.editUser = $rootScope.editUser;
   $scope.save = function(user) {
      DoorClient.putUser(user, function() {
         $rootScope.showUsers();
      });
   };
   Material.de();
});
<|endoftext|>


<commit_before>// -------------------------------------------------------------------------- \\
// File: ScrollView.js                                                        \\
// Module: ContainerViews                                                     \\
// Requires: Core, Foundation, View                                           \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var ScrollAnimation = NS.Class({

    Extends: NS.Animation,

    duration: 250,

    prepare: function ( coordinates ) {
        var object = this.object,
            startX = this.startX = object.get( 'scrollLeft' ),
            startY = this.startY = object.get( 'scrollTop' ),
            endX = this.endX = coordinates.x || 0,
            endY = this.endY = coordinates.y || 0,
            deltaX = this.deltaX = endX - startX,
            deltaY = this.deltaY = endY - startY;

        return !!( deltaX || deltaY );
    },

    drawFrame: function ( position ) {
        var x = position < 1 ?
                this.startX + ( position * this.deltaX ) : this.endX,
            y = position < 1 ?
                this.startY + ( position * this.deltaY ) : this.endY;
        this.object._scrollTo( x, y );
    }
});

/**
    Class: O.ScrollView

    Extends: O.View

    An O.ScrollView instance is a fixed size container, which can be scrolled if
    its contents overflows the bounds of the view. By default, a scrollbar will
    only be shown for vertical overflow. Set the <O.ScrollView#showScrollbarX>
    property to `true` to show a scrollbar on horizontal overflow as well.
*/
var ScrollView = NS.Class({

    Extends: NS.View,

    /**
        Property: O.ScrollView#showScrollbarX
        Type: Boolean
        Default: false

        Show a scrollbar if the content horizontally overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarX: false,

    /**
        Property: O.ScrollView#showScrollbarY
        Type: Boolean
        Default: true

        Show a scrollbar if the content vertically overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarY: true,

    /**
        Property: O.ScrollView#positioning
        Type: String
        Default: 'absolute'

        Overrides default in <O.View#positioning>.
   */
    positioning: 'absolute',

    /**
        Property: O.ScrollView#layout
        Type: Object
        Default:
                {
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%'
                }

        Overrides default in <O.View#layout>.
    */
    layout: NS.View.LAYOUT_FILL_PARENT,

    /**
        Property: O.ScrollView#layerStyles
        Type: Object

        Sets the overflow styles to show the scrollbars.
    */
    layerStyles: function () {
        var styles = NS.View.prototype.layerStyles.call( this );
        styles.overflowX = this.get( 'showScrollbarX' ) ? 'auto' : 'hidden';
        styles.overflowY = this.get( 'showScrollbarY' ) ? 'auto' : 'hidden';
        styles.WebkitOverflowScrolling = 'touch';
        return styles;
    }.property( 'layout', 'allowTextSelection', 'positioning',
        'showScrollbarX', 'showScrollbarY' ),

    /**
        Property: O.ScrollView#keys
        Type: Object
        Default: {}

        Keyboard shortcuts to scroll the view. A map of keyboard shortcut to the
        method name to call on the O.ScrollView instance. These shortcuts will
        automatically be activated/deactivated when the view is added/removed
        to/from the document.

        For example, on the main scroll view for you content, you might set:

            {
                'pagedown': 'scrollPage',
                'pageup': 'reverseScrollPage',
                'space': 'scrollPage',
                'shift-space': 'reverseScrollPage',
                'down': 'scrollLine',
                'up': 'reverseScrollLine'
            }
    */
    keys: {},

    didCreateLayer: function ( layer ) {
        this.scrollLayer = layer;
    },

    didEnterDocument: function () {
        this.get( 'scrollLayer' ).addEventListener( 'scroll', this, false );

        // Add keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.register( key, this, keys[ key ] );
        }

        return ScrollView.parent.didEnterDocument.call( this );
    },

    willLeaveDocument: function () {
        // Remove keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.deregister( key, this, keys[ key ] );
        }

        this.get( 'scrollLayer' ).removeEventListener( 'scroll', this, false );

        return ScrollView.parent.willLeaveDocument.call( this );
    },

    _restoreScroll: function () {
        // Scroll is reset to 0 in some browsers whenever it is removed from the
        // DOM, so we need to set it to what it should be.
        if ( this.get( 'isInDocument' ) ) {
            var layer = this.get( 'scrollLayer' );
            layer.scrollLeft = this.get( 'scrollLeft' );
            layer.scrollTop = this.get( 'scrollTop' );
        }
    }.queue( 'render' ).observes( 'isInDocument' ),

    /**
        Property: O.ScrollView#scrollAnimation
        Type: O.Animation

        An <O.Animation> object to animate scrolling on this object. Normally
        you will not need to interact with this directly, but just set the
        `withAnimation` argument to `true` when you call O.ScrollView#scrollTo.
        However, if you wish to change the duration or easing method, you can do
        so by setting it on this object.
    */
    scrollAnimation: function ( ) {
        return new ScrollAnimation({
            object: this
        });
    }.property(),

    /**
        Property: O.ScrollView#isAnimating
        Type: Boolean

        Is the scroll currently animating?
    */
    isAnimating: false,

    willAnimate: function () {
        this.set( 'isAnimating', true );
    },

    didAnimate: function () {
        this.set( 'isAnimating', false );
    },

    /**
        Method: O.ScrollView#scrollToTop

        Scrolls the view to the top
    */
    scrollToTop: function () {
        return this.scrollTo( 0, 0, true );
    },

    /**
        Method: O.ScrollView#scrollToBottom

        Scrolls the view to the bottom
    */
    scrollToBottom: function () {
        return this.scrollTo( 0,
            this.get( 'scrollLayer' ).scrollHeight - this.get( 'pxHeight' ),
            true
        );
    },

    /**
        Method: O.ScrollView#scrollPage

        Scrolls the view down by the view height - 50px.
    */
    scrollPage: function () {
        return this.scrollBy( 0, this.get( 'pxHeight' ) - 50, true );
    },

    /**
        Method: O.ScrollView#reverseScrollPage

        Scrolls the view up by the view height - 50px.
    */
    reverseScrollPage: function () {
        return this.scrollBy( 0, 50 - this.get( 'pxHeight' ), true );
    },

    /**
        Method: O.ScrollView#scrollLine

        Scrolls the view down by 40px.
    */
    scrollLine: function () {
        return this.scrollBy( 0, 40 );
    },

    /**
        Method: O.ScrollView#reverseScrollLine

        Scrolls the view up by 40px.
    */
    reverseScrollLine: function () {
        return this.scrollBy( 0, -40 );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view by the given number of pixels (use negative values to
        scroll up/left).

        Parameters:
            x             - {Number} The number of pixels to scroll right.
            y             - {Number} The number of pixels to scroll down.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {Boolean} Did the view actually scroll (false if already at end)?
    */
    scrollBy: function ( x, y, withAnimation ) {
        var left = this.get( 'scrollLeft' ),
            top = this.get( 'scrollTop' );
        x += left;
        y += top;

        this.scrollTo( x, y, withAnimation );

        return top !== this.get( 'scrollTop' ) ||
            left !== this.get( 'scrollLeft' );
    },

    /**
        Method: O.ScrollView#scrollToView

        Scroll the view to show a sub-view in the top left of the view.

        Parameters:
            view          - {View} The sub-view to scroll to.
            offset        - {Object} (optional) If supplied, must contain
                            numerical `x` and `y` properties which give the
                            number of pixels to offset the subview from the top
                            left of the scroll view.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollToView: function ( view, offset, withAnimation ) {
        var position = view.getPositionRelativeTo( this );
        return this.scrollTo(
            position.left + ( offset && offset.x || 0 ),
            position.top + ( offset && offset.y || 0 ),
            withAnimation
        );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view to a given position, where (0,0) represents the scroll
        view fully .

        Parameters:
            x             - {Number} The number of pixels to set the horizontal
                            scroll-position to.
            y             - {Number} The number of pixels to set the vertical
                            scroll-position to.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollTo: function ( x, y, withAnimation ) {
        // Can't have negative scroll values.
        if ( x < 0 ) { x = 0; }
        if ( y < 0 ) { y = 0; }

        var scrollAnimation = this.get( 'scrollAnimation' );
        scrollAnimation.stop();

        if ( withAnimation && this.get( 'isInDocument' ) ) {
            scrollAnimation.animate({
                x: x,
                y: y
            });
        } else {
            this.beginPropertyChanges()
                .set( 'scrollLeft', x )
                .set( 'scrollTop', y )
                .propertyNeedsRedraw( this, 'scroll' )
            .endPropertyChanges();
        }
        return this;
    },

    /**
        Method (private): O.ScrollView#_scrollTo

        Set the new values and immediately redraw. Fast path for animation.
    */
    _scrollTo: function ( x, y ) {
        this.set( 'scrollLeft', x )
            .set( 'scrollTop', y );
        this.redrawScroll();
    },

    /**
        Method: O.ScrollView#redrawScroll

        Redraws the scroll position in the layer to match the view's state.
    */
    redrawScroll: function () {
        var layer = this.get( 'scrollLayer' ),
            x = this.get( 'scrollLeft' ),
            y = this.get( 'scrollTop' );
        layer.scrollLeft = x;
        layer.scrollTop = y;
        // In case we've gone past the end.
        if ( x || y ) {
            NS.RunLoop.queueFn( 'after', this.syncBackScroll, this );
        }
    },

    /**
        Method: O.ScrollView#syncBackScroll

        Parameters:
            event - {Event} (optional) The scroll event object.

        Updates the view properties when the layer scrolls.
    */
    syncBackScroll: function ( event ) {
        if ( this._needsRedraw ) {
            return;
        }
        var layer = this.get( 'scrollLayer' ),
            x = layer.scrollLeft,
            y = layer.scrollTop;
        this.beginPropertyChanges()
            .set( 'scrollLeft', x )
            .set( 'scrollTop', y )
            .endPropertyChanges();
        if ( event ) {
            event.stopPropagation();
            // Don't interpret tap to stop scroll as a real tap.
            if ( NS.Tap ) {
                NS.Tap.cancel();
            }
        }
    }.on( 'scroll' )
});

if ( NS.UA.isIOS ) {
    ScrollView.implement({
        isFixedDimensions: function () {
            var positioning = this.get( 'positioning' );
            return positioning === 'absolute' || positioning === 'fixed';
        }.property( 'positioning' ),

        draw: function ( layer, Element, el ) {
            var isFixedDimensions = this.get( 'isFixedDimensions' ),
                scrollFixerHeight = 1,
                wrapper = null,
                safariVersion = NS.UA.safari,
                children;

            // Render the children.
            children = ScrollView.parent.draw.call( this, layer, Element, el );

            // Trick 1: The dual overflow:scroll view.
            // By default, iOS Safari will scroll the containing scroll view
            // if you are at the top/bottom of an overflow:scroll view. This
            // means it scrolls the window instead of bouncing your scroll view.
            // The dual overflow:scroll fixes this in iOS < 8. You only need
            // this in Safari: if in a UIWebView you can disable the natural
            // scrolling of the window.
            if ( 0 < safariVersion && safariVersion < 8 ) {
                wrapper = this.scrollLayer = el( 'div', {
                    style: 'position:relative;height:100%;' +
                        '-webkit-overflow-scrolling:touch;' +
                        'overflow-x:' +
                            ( this.get( 'showScrollbarX' ) ?
                                'auto;' : 'hidden;' ) +
                        'overflow-y:' +
                            ( this.get( 'showScrollbarY' ) ?
                                'auto;' : 'hidden;' )
                });
                layer.appendChild( wrapper );
                layer = wrapper;
            }

            // Trick 2: Never leave the scroll view at the ends.
            // As Trick 1 doesn't work in Safari on iOS8, or any other WKWebView
            // based browser. We have to use a more crude method: ensure the
            // scrollHeight is at least pxHeight + 2, then make sure scrollTop
            // is never at the absolute end, so there is always room to scroll
            // in both directions. We add a 1px tall empty div at the top of
            // the content so at scrollTop=1px, it looks like it should.
            if ( NS.UA.isWKWebView ) {
                scrollFixerHeight = 2;
                layer.appendChild(
                    el( 'div', { style: 'height:1px' } )
                );
                this.on( 'scroll', this, '_setNotAtEnd' )
                    .addObserverForKey( 'isInDocument', this, '_setNotAtEnd' );
            }

            // Append the actual children of the scroll view.
            Element.appendChildren( layer, children );

            // Trick 3: Ensuring the view scrolls.
            // Following platform conventions, we assume a fixed height
            // ScrollView should always scroll, regardless of whether the
            // content is taller than the view, whereas a variable height
            // ScrollView just needs to scroll if the content requires it.
            // Therefore, if it's a fixed height view, we add an extra
            // invisible div permanently 1px below the height, so it always
            // has scrollable content.
            if ( isFixedDimensions ) {
                layer.appendChild(
                    el( 'div', {
                        style: 'position:absolute;top:100%;left:0px;' +
                            'width:1px;height:' + scrollFixerHeight + 'px;'
                    })
                );
            }
        },

        _setNotAtEnd: function () {
            if ( this.get( 'isInDocument' ) ) {
                var scrollTop = this.get( 'scrollTop' ),
                    scrollLeft = this.get( 'scrollLeft' );
                if ( !scrollTop ) {
                    this.scrollTo( scrollLeft, 1 );
                } else if ( scrollTop + this.get( 'pxHeight' ) ===
                        this.get( 'layer' ).scrollHeight ) {
                    this.scrollTo( scrollLeft, scrollTop - 1 );
                }
            }
        }.queue( 'after' ),

        preventRootScroll: function ( event ) {
            if ( !this.get( 'isFixedDimensions' ) ) {
                var layer = this.get( 'layer' );
                if ( layer.scrollHeight <= layer.offsetHeight ) {
                    event.preventDefault();
                }
            }
        }.on( 'touchmove' ),

        insertView: function ( view, relativeTo, where ) {
            if ( !relativeTo && this.get( 'isRendered' ) ) {
                relativeTo = this.scrollLayer;
                if ( where === 'top' ) {
                    if ( NS.UA.safari >= 8 ) {
                        relativeTo = relativeTo.firstChild;
                        where = 'after';
                    }
                } else if ( !where || where === 'bottom' ) {
                    if ( this.get( 'isFixedDimensions' ) ) {
                        relativeTo = relativeTo.lastChild;
                        where = 'before';
                    }
                }
            }
            return ScrollView.parent.insertView.call(
                this, view, relativeTo, where );
        }
    });
}

NS.ScrollView = ScrollView;

}( O ) );
<commit_msg>Round scroll positions<commit_after>// -------------------------------------------------------------------------- \\
// File: ScrollView.js                                                        \\
// Module: ContainerViews                                                     \\
// Requires: Core, Foundation, View                                           \\
// Author: Neil Jenkins                                                       \\
// License: © 2010-2015 FastMail Pty Ltd. MIT Licensed.                       \\
// -------------------------------------------------------------------------- \\

"use strict";

( function ( NS ) {

var ScrollAnimation = NS.Class({

    Extends: NS.Animation,

    duration: 250,

    prepare: function ( coordinates ) {
        var object = this.object,
            startX = this.startX = object.get( 'scrollLeft' ),
            startY = this.startY = object.get( 'scrollTop' ),
            endX = this.endX = coordinates.x || 0,
            endY = this.endY = coordinates.y || 0,
            deltaX = this.deltaX = endX - startX,
            deltaY = this.deltaY = endY - startY;

        return !!( deltaX || deltaY );
    },

    drawFrame: function ( position ) {
        var x = position < 1 ?
                this.startX + ( position * this.deltaX ) : this.endX,
            y = position < 1 ?
                this.startY + ( position * this.deltaY ) : this.endY;
        this.object._scrollTo( x, y );
    }
});

/**
    Class: O.ScrollView

    Extends: O.View

    An O.ScrollView instance is a fixed size container, which can be scrolled if
    its contents overflows the bounds of the view. By default, a scrollbar will
    only be shown for vertical overflow. Set the <O.ScrollView#showScrollbarX>
    property to `true` to show a scrollbar on horizontal overflow as well.
*/
var ScrollView = NS.Class({

    Extends: NS.View,

    /**
        Property: O.ScrollView#showScrollbarX
        Type: Boolean
        Default: false

        Show a scrollbar if the content horizontally overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarX: false,

    /**
        Property: O.ScrollView#showScrollbarY
        Type: Boolean
        Default: true

        Show a scrollbar if the content vertically overflows the bounds of the
        DOM element representing this view?
    */
    showScrollbarY: true,

    /**
        Property: O.ScrollView#positioning
        Type: String
        Default: 'absolute'

        Overrides default in <O.View#positioning>.
   */
    positioning: 'absolute',

    /**
        Property: O.ScrollView#layout
        Type: Object
        Default:
                {
                    top: 0,
                    left: 0,
                    width: '100%',
                    height: '100%'
                }

        Overrides default in <O.View#layout>.
    */
    layout: NS.View.LAYOUT_FILL_PARENT,

    /**
        Property: O.ScrollView#layerStyles
        Type: Object

        Sets the overflow styles to show the scrollbars.
    */
    layerStyles: function () {
        var styles = NS.View.prototype.layerStyles.call( this );
        styles.overflowX = this.get( 'showScrollbarX' ) ? 'auto' : 'hidden';
        styles.overflowY = this.get( 'showScrollbarY' ) ? 'auto' : 'hidden';
        styles.WebkitOverflowScrolling = 'touch';
        return styles;
    }.property( 'layout', 'allowTextSelection', 'positioning',
        'showScrollbarX', 'showScrollbarY' ),

    /**
        Property: O.ScrollView#keys
        Type: Object
        Default: {}

        Keyboard shortcuts to scroll the view. A map of keyboard shortcut to the
        method name to call on the O.ScrollView instance. These shortcuts will
        automatically be activated/deactivated when the view is added/removed
        to/from the document.

        For example, on the main scroll view for you content, you might set:

            {
                'pagedown': 'scrollPage',
                'pageup': 'reverseScrollPage',
                'space': 'scrollPage',
                'shift-space': 'reverseScrollPage',
                'down': 'scrollLine',
                'up': 'reverseScrollLine'
            }
    */
    keys: {},

    didCreateLayer: function ( layer ) {
        this.scrollLayer = layer;
    },

    didEnterDocument: function () {
        this.get( 'scrollLayer' ).addEventListener( 'scroll', this, false );

        // Add keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.register( key, this, keys[ key ] );
        }

        return ScrollView.parent.didEnterDocument.call( this );
    },

    willLeaveDocument: function () {
        // Remove keyboard shortcuts:
        var keys = this.get( 'keys' ),
            shortcuts = NS.ViewEventsController.kbShortcuts,
            key;
        for ( key in keys ) {
            shortcuts.deregister( key, this, keys[ key ] );
        }

        this.get( 'scrollLayer' ).removeEventListener( 'scroll', this, false );

        return ScrollView.parent.willLeaveDocument.call( this );
    },

    _restoreScroll: function () {
        // Scroll is reset to 0 in some browsers whenever it is removed from the
        // DOM, so we need to set it to what it should be.
        if ( this.get( 'isInDocument' ) ) {
            var layer = this.get( 'scrollLayer' );
            layer.scrollLeft = this.get( 'scrollLeft' );
            layer.scrollTop = this.get( 'scrollTop' );
        }
    }.queue( 'render' ).observes( 'isInDocument' ),

    /**
        Property: O.ScrollView#scrollAnimation
        Type: O.Animation

        An <O.Animation> object to animate scrolling on this object. Normally
        you will not need to interact with this directly, but just set the
        `withAnimation` argument to `true` when you call O.ScrollView#scrollTo.
        However, if you wish to change the duration or easing method, you can do
        so by setting it on this object.
    */
    scrollAnimation: function ( ) {
        return new ScrollAnimation({
            object: this
        });
    }.property(),

    /**
        Property: O.ScrollView#isAnimating
        Type: Boolean

        Is the scroll currently animating?
    */
    isAnimating: false,

    willAnimate: function () {
        this.set( 'isAnimating', true );
    },

    didAnimate: function () {
        this.set( 'isAnimating', false );
    },

    /**
        Method: O.ScrollView#scrollToTop

        Scrolls the view to the top
    */
    scrollToTop: function () {
        return this.scrollTo( 0, 0, true );
    },

    /**
        Method: O.ScrollView#scrollToBottom

        Scrolls the view to the bottom
    */
    scrollToBottom: function () {
        return this.scrollTo( 0,
            this.get( 'scrollLayer' ).scrollHeight - this.get( 'pxHeight' ),
            true
        );
    },

    /**
        Method: O.ScrollView#scrollPage

        Scrolls the view down by the view height - 50px.
    */
    scrollPage: function () {
        return this.scrollBy( 0, this.get( 'pxHeight' ) - 50, true );
    },

    /**
        Method: O.ScrollView#reverseScrollPage

        Scrolls the view up by the view height - 50px.
    */
    reverseScrollPage: function () {
        return this.scrollBy( 0, 50 - this.get( 'pxHeight' ), true );
    },

    /**
        Method: O.ScrollView#scrollLine

        Scrolls the view down by 40px.
    */
    scrollLine: function () {
        return this.scrollBy( 0, 40 );
    },

    /**
        Method: O.ScrollView#reverseScrollLine

        Scrolls the view up by 40px.
    */
    reverseScrollLine: function () {
        return this.scrollBy( 0, -40 );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view by the given number of pixels (use negative values to
        scroll up/left).

        Parameters:
            x             - {Number} The number of pixels to scroll right.
            y             - {Number} The number of pixels to scroll down.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {Boolean} Did the view actually scroll (false if already at end)?
    */
    scrollBy: function ( x, y, withAnimation ) {
        var left = this.get( 'scrollLeft' ),
            top = this.get( 'scrollTop' );
        x += left;
        y += top;

        this.scrollTo( x, y, withAnimation );

        return top !== this.get( 'scrollTop' ) ||
            left !== this.get( 'scrollLeft' );
    },

    /**
        Method: O.ScrollView#scrollToView

        Scroll the view to show a sub-view in the top left of the view.

        Parameters:
            view          - {View} The sub-view to scroll to.
            offset        - {Object} (optional) If supplied, must contain
                            numerical `x` and `y` properties which give the
                            number of pixels to offset the subview from the top
                            left of the scroll view.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollToView: function ( view, offset, withAnimation ) {
        var position = view.getPositionRelativeTo( this );
        return this.scrollTo(
            position.left + ( offset && offset.x || 0 ),
            position.top + ( offset && offset.y || 0 ),
            withAnimation
        );
    },

    /**
        Method: O.ScrollView#scrollBy

        Scroll the view to a given position, where (0,0) represents the scroll
        view fully .

        Parameters:
            x             - {Number} The number of pixels to set the horizontal
                            scroll-position to.
            y             - {Number} The number of pixels to set the vertical
                            scroll-position to.
            withAnimation - {Boolean} (optional) If true, animate the scroll.

        Returns:
            {O.ScrollView} Returns self.
    */
    scrollTo: function ( x, y, withAnimation ) {
        // Can't have negative scroll values.
        // Can't scroll to fractional positions
        x = x < 0 ? 0 : Math.round( x );
        y = y < 0 ? 0 : Math.round( y );

        var scrollAnimation = this.get( 'scrollAnimation' );
        scrollAnimation.stop();

        if ( withAnimation && this.get( 'isInDocument' ) ) {
            scrollAnimation.animate({
                x: x,
                y: y
            });
        } else {
            this.beginPropertyChanges()
                .set( 'scrollLeft', x )
                .set( 'scrollTop', y )
                .propertyNeedsRedraw( this, 'scroll' )
            .endPropertyChanges();
        }
        return this;
    },

    /**
        Method (private): O.ScrollView#_scrollTo

        Set the new values and immediately redraw. Fast path for animation.
    */
    _scrollTo: function ( x, y ) {
        this.set( 'scrollLeft', x )
            .set( 'scrollTop', y );
        this.redrawScroll();
    },

    /**
        Method: O.ScrollView#redrawScroll

        Redraws the scroll position in the layer to match the view's state.
    */
    redrawScroll: function () {
        var layer = this.get( 'scrollLayer' ),
            x = this.get( 'scrollLeft' ),
            y = this.get( 'scrollTop' );
        layer.scrollLeft = x;
        layer.scrollTop = y;
        // In case we've gone past the end.
        if ( x || y ) {
            NS.RunLoop.queueFn( 'after', this.syncBackScroll, this );
        }
    },

    /**
        Method: O.ScrollView#syncBackScroll

        Parameters:
            event - {Event} (optional) The scroll event object.

        Updates the view properties when the layer scrolls.
    */
    syncBackScroll: function ( event ) {
        if ( this._needsRedraw ) {
            return;
        }
        var layer = this.get( 'scrollLayer' ),
            x = layer.scrollLeft,
            y = layer.scrollTop;
        this.beginPropertyChanges()
            .set( 'scrollLeft', x )
            .set( 'scrollTop', y )
            .endPropertyChanges();
        if ( event ) {
            event.stopPropagation();
            // Don't interpret tap to stop scroll as a real tap.
            if ( NS.Tap ) {
                NS.Tap.cancel();
            }
        }
    }.on( 'scroll' )
});

if ( NS.UA.isIOS ) {
    ScrollView.implement({
        isFixedDimensions: function () {
            var positioning = this.get( 'positioning' );
            return positioning === 'absolute' || positioning === 'fixed';
        }.property( 'positioning' ),

        draw: function ( layer, Element, el ) {
            var isFixedDimensions = this.get( 'isFixedDimensions' ),
                scrollFixerHeight = 1,
                wrapper = null,
                safariVersion = NS.UA.safari,
                children;

            // Render the children.
            children = ScrollView.parent.draw.call( this, layer, Element, el );

            // Trick 1: The dual overflow:scroll view.
            // By default, iOS Safari will scroll the containing scroll view
            // if you are at the top/bottom of an overflow:scroll view. This
            // means it scrolls the window instead of bouncing your scroll view.
            // The dual overflow:scroll fixes this in iOS < 8. You only need
            // this in Safari: if in a UIWebView you can disable the natural
            // scrolling of the window.
            if ( 0 < safariVersion && safariVersion < 8 ) {
                wrapper = this.scrollLayer = el( 'div', {
                    style: 'position:relative;height:100%;' +
                        '-webkit-overflow-scrolling:touch;' +
                        'overflow-x:' +
                            ( this.get( 'showScrollbarX' ) ?
                                'auto;' : 'hidden;' ) +
                        'overflow-y:' +
                            ( this.get( 'showScrollbarY' ) ?
                                'auto;' : 'hidden;' )
                });
                layer.appendChild( wrapper );
                layer = wrapper;
            }

            // Trick 2: Never leave the scroll view at the ends.
            // As Trick 1 doesn't work in Safari on iOS8, or any other WKWebView
            // based browser. We have to use a more crude method: ensure the
            // scrollHeight is at least pxHeight + 2, then make sure scrollTop
            // is never at the absolute end, so there is always room to scroll
            // in both directions. We add a 1px tall empty div at the top of
            // the content so at scrollTop=1px, it looks like it should.
            if ( NS.UA.isWKWebView ) {
                scrollFixerHeight = 2;
                layer.appendChild(
                    el( 'div', { style: 'height:1px' } )
                );
                this.on( 'scroll', this, '_setNotAtEnd' )
                    .addObserverForKey( 'isInDocument', this, '_setNotAtEnd' );
            }

            // Append the actual children of the scroll view.
            Element.appendChildren( layer, children );

            // Trick 3: Ensuring the view scrolls.
            // Following platform conventions, we assume a fixed height
            // ScrollView should always scroll, regardless of whether the
            // content is taller than the view, whereas a variable height
            // ScrollView just needs to scroll if the content requires it.
            // Therefore, if it's a fixed height view, we add an extra
            // invisible div permanently 1px below the height, so it always
            // has scrollable content.
            if ( isFixedDimensions ) {
                layer.appendChild(
                    el( 'div', {
                        style: 'position:absolute;top:100%;left:0px;' +
                            'width:1px;height:' + scrollFixerHeight + 'px;'
                    })
                );
            }
        },

        _setNotAtEnd: function () {
            if ( this.get( 'isInDocument' ) ) {
                var scrollTop = this.get( 'scrollTop' ),
                    scrollLeft = this.get( 'scrollLeft' );
                if ( !scrollTop ) {
                    this.scrollTo( scrollLeft, 1 );
                } else if ( scrollTop + this.get( 'pxHeight' ) ===
                        this.get( 'layer' ).scrollHeight ) {
                    this.scrollTo( scrollLeft, scrollTop - 1 );
                }
            }
        }.queue( 'after' ),

        preventRootScroll: function ( event ) {
            if ( !this.get( 'isFixedDimensions' ) ) {
                var layer = this.get( 'layer' );
                if ( layer.scrollHeight <= layer.offsetHeight ) {
                    event.preventDefault();
                }
            }
        }.on( 'touchmove' ),

        insertView: function ( view, relativeTo, where ) {
            if ( !relativeTo && this.get( 'isRendered' ) ) {
                relativeTo = this.scrollLayer;
                if ( where === 'top' ) {
                    if ( NS.UA.safari >= 8 ) {
                        relativeTo = relativeTo.firstChild;
                        where = 'after';
                    }
                } else if ( !where || where === 'bottom' ) {
                    if ( this.get( 'isFixedDimensions' ) ) {
                        relativeTo = relativeTo.lastChild;
                        where = 'before';
                    }
                }
            }
            return ScrollView.parent.insertView.call(
                this, view, relativeTo, where );
        }
    });
}

NS.ScrollView = ScrollView;

}( O ) );
<|endoftext|>


<commit_before>/**
 * Created by Evgenii on 16.01.2017.
 */
Vue.config.debug = true;
Vue.http.headers.common['X-CSRF-TOKEN'] = document.getElementById('token').getAttribute('value');

var productVue = new Vue({

    el: "#productVue",

    data: {
        token: document.getElementById('token').getAttribute('value'),
        translate:  {},
        filterEvent: true,
        xapactEvent: true,
        paramEvent: true,
        fileEvent: true,
        product:{
            id: document.getElementById("form-data").id.value,
            images: [],
            meta_description: null,
            meta_title: null,
            title: null,
            slug: null
        },
        productsList:{
            products:{},
            pagination:{
                currentPage: {},
                lastPage: {},
                pageToGet: 1
            }
        },
        relOptions:{
            category:0,
            paginate: 20,
            search: '',
            selected: []
        },
        relatedProducts: null,
        selectedProductsIds: [],
        countryList: null
    },

    created: function () {
        this.$http.get('/dashboard/products/' + this.product.id + '/edit').then(function (response) {
            this.product = response.body;});
        this.$http.get('/dashboard/helpers/translate').then(function (response) {
            this.translate = response;});
        this.getRelatedProducts();
    },

    computed: {
        stringImagesIds: function(){
            var images = [];
            for(var i = 0, len = this.product.images.length; i < len; i++ ){
                images[i] = this.product.images[i].id;
            }
            return images.join(',');
        },

        coountTitle: function () {
            return this.product.meta_title.length
        },

        coountDescription: function () {
            return this.product.meta_description.length
        },
    },

    methods: {

        makeSlug: function () {
            this.product.slug = this.prepareSlug()
        },

        prepareSlug: function () {
            var answer = '',
                title = this.product.title,
                translate = this.translate;

            for (var i in title) {
                if (translate.hasOwnProperty(title[i])) {
                    if (translate[title[i]] !== undefined) {
                        answer += translate[title[i]];
                    }
                } else {
                    answer += title[i];
                }
            }

            return answer.toLocaleLowerCase()
                .replace(/[^a-z0-9-]/, '-')
                .replace(/-{2,}/g, '-')
                .replace(/^[\s\uFEFF\xA0-]+|[\s\uFEFF\xA0-]+$/g, '')
                .replace(/\s/ig, '-');
        },

        getFields: function(){
            var vue = this;
            if(vue.filterEvent){
                vue.filterEvent = false;
                $("#filters").addClass('loading');
                this.$http.get('/dashboard/filters/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                    .then(function (response) {
                        $("#filters .inner").html(response.body);
                        $("#filters").removeClass('loading');
                        $('.selectize').selectize({
                            create: true,
                            createOnBlur: true,
                            sortField: 'text'
                        });
                    }, function (error) {
                        $("#filters .inner").html(error.body);
                        $("#filters").removeClass('loading');
                });
            }
        },

        getFieldsClik: function(){
            var vue = this;
            $("#filters").addClass('loading');
            this.$http.get('/dashboard/filters/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                .then(function (response) {
                    $("#filters .inner").html(response.body);
                    $("#filters").removeClass('loading');
                    $('.selectize').selectize({
                        create: true,
                        createOnBlur: true,
                        sortField: 'text'
                    });
                }, function (error) {
                    $("#filters .inner").html(error.body);
                    $("#filters").removeClass('loading');
                });
        },

        getXapacts: function () {
            var vue = this;
            if(vue.xapactEvent){
                vue.xapactEvent = false;
                $("#characters").addClass('loading');
                this.$http.get('/dashboard/characteristics/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                    .then(function (response) {
                        $("#characters .inner").html(response.body);
                        $("#characters").removeClass('loading');
                        $('.selectize_x').selectize({
                            create: true,
                            createOnBlur: true,
                            sortField: 'text'
                        });
                    }, function (error) {
                        $("#characters .inner").html(error.body);
                        $("#characters").removeClass('loading');
                    });
             }
        },

        getXapactsClik: function(){
            var vue = this;
            $("#characters").addClass('loading');
            this.$http.get('/dashboard/characteristics/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                .then(function (response) {
                    $("#characters .inner").html(response.body);
                    $("#characters").removeClass('loading');
                    $('.selectize_x').selectize({
                        create: true,
                        createOnBlur: true,
                        sortField: 'text'
                    });
                }, function (error) {
                    $("#characters .inner").html(error.body);
                    $("#characters").removeClass('loading');
                });
        },

        getParam: function () {
            var vue = this;
            if (vue.paramEvent) {
                vue.paramEvent = false;
                $("#params").addClass('loading');
                this.$http.get('/dashboard/parameters/list?id='+ vue.product.id )
                    .then(function (response) {
                        $("#params .inner").html(response.body);
                        $("#params").removeClass('loading');
                    }, function (error) {
                        $("#params .inner").html(error.body);
                        $("#params").removeClass('loading');
                    });

            }
        },

        getParamClik: function () {
            var vue = this;
            $("#params").addClass('loading');
            this.$http.get('/dashboard/parameters/list?id='+ vue.product.id )
                .then(function (response) {
                    $("#params .inner").html(response.body);
                    $("#params").removeClass('loading');
                }, function (error) {
                    $("#params .inner").html(error.body);
                    $("#params").removeClass('loading');
                });
        },

        setAsThumbnail: function(image) {
            var vue = this;
            for(var img in vue.product.images){
                vue.product.images[img].is_thumb = false;
            }
            vue.product.images[vue.product.images.indexOf(image)].is_thumb = true;

            this.$http.post('/dashboard/set-thumbnail/' + image.id, {_token: vue.token, productId : vue.product.id} )
                .then(function (response) {});
        },

        removeImage: function (image) {
            var vue = this;
            this.$http.post('/dashboard/remove-image/' + image.id, {_token: vue.token} )
                .then(function (response) {
                    var index = vue.product.images.indexOf(image);
                    if (index > -1)
                        vue.product.images.splice(index, 1);
                });
        },

        loadImage: function (event) {
            var vue = this;
            var uploadInput = event.target;
            for(var property in uploadInput.files) {
                if(!isNaN(property)){
                    var data = new FormData();
                    //console.log(uploadInput[0].files[property]);
                    data.append('file', uploadInput.files[property]);
                    data.append('product_id', this.product.id);
                    data.append('is_certificate', event.target.id == 'cerf' ? 1 : 0);
                    this.$http.post('/dashboard/upload-image', data )
                        .then(function (image) {
                            vue.product.images.push(image.body);
                            if(vue.product.images.length == 1){
                                vue.setAsThumbnail(image);
                            }
                        });
                }
            }
            uploadInput.value = null;
        },

        loadVideo: function(){
            var vue = this;
            bootbox.prompt("Введите HTML код видео", function(result) {
                if (result ) {
                    vue.product.video = result;
                }
            });

        },

        removeVideo: function(){
            this.product.video = null;
        },

        getPdfList: function(){
            var vue = this;
            if(vue.fileEvent){
                vue.fileEvent = false;
                this.$http.get('/dashboard/pdf?id=' + vue.product.id )
                    .then(function (response) {
                        $("#filesup").html(response.body);
                    });
            }
        },

        updatePdfList: function(){
            var vue = this;
            this.$http.get('/dashboard/pdf?id=' + vue.product.id )
                .then(function (response) {
                    $("#filesup").html(response.body);
                });
        },

        loadPDF: function(event){
            var vue = this;
            var uploadInput = event.target;
            for(var property in uploadInput.files) {
                if(!isNaN(property)){
                    var data = new FormData();
                    data.append('file', uploadInput.files[property]);
                    data.append('productID', vue.product.id);
                    data.append('categoryID', vue.product.category_id);
                    data.append('brandID', vue.product.brand_id);

                    this.$http.post('/dashboard/upload-pdf', data )
                        .then(function () {
                            vue.updatePdfList();
                        });
                }
            }
        },

        getProducts: function () {
            var vue = this;
            var options = {
                params: {
                    categoryId: vue.relOptions.category,
                    paginate: vue.relOptions.search,
                    search: vue.relOptions.search,
                    selected: vue.getSelectedProductsIds(),
                    page: vue.productsList.pagination.pageToGet,
                    _: Date.now()
                }
            };
            this.$http.get('/dashboard/product-actions/getProducts', options)
                .then(function (response) {
                    vue.productsList.products = response.body.data;
                    vue.productsList.pagination.currentPage = response.body.current_page;
                    vue.productsList.pagination.lastPage = response.body.last_page;
                    if(vue.productsList.pagination.lastPage < vue.productsList.pagination.pageToGet) {
                        vue.productsList.pagination.pageToGet = vue.productsList.pagination.lastPage;
                        vue.getProducts()
                    }
                });
        },

        getRelatedProducts: function(){
            var vue = this;
            this.$http.post('/dashboard/product-actions/getRelatedProducts', {productId: this.product.id})
                .then(function (response) {
                    vue.relOptions.selected = response.body;
                    vue.selectedProductsIds = this.getSelectedProductsIds();
                });
        },

        syncProducts: function(){
            this.selectedProductsIds = this.getSelectedProductsIds();
            var body = {
                ids: this.getSelectedProductsIds(),
                productId: this.product.id
            };
            this.$http.post('/dashboard/product-actions/syncRelated', body)
        },

        getSelectedProductsIds: function(){
            var productsIds = [];
            this.relOptions.selected.forEach(function(product){
                productsIds.push(product.id);
            });
            return productsIds;
        },

        addProduct: function(relProduct, index){
            this.productsList.products.splice(index, 1);
            this.relOptions.selected.push(relProduct);
            this.syncProducts();
            this.getProducts();
        },

        removeProduct: function(relProduct, index){
            this.relOptions.selected.splice(index, 1);
            this.productsList.products.push(relProduct);
            this.syncProducts();
            this.getProducts();
        },

        nextPage: function(){
            if(this.productsList.pagination.currentPage != this.productsList.pagination.lastPage){
                this.productsList.pagination.pageToGet = this.productsList.pagination.currentPage + 1;
                this.getProducts();
            }
        },

        prevPage: function(){
            if(this.productsList.pagination.currentPage != 1) {
                this.productsList.pagination.pageToGet = this.productsList.pagination.currentPage - 1;
                this.getProducts();
            }
        },

        updateCountry: function () {
            this.$http.post('/dashboard/country/get')
                .then(function (response) {
                    this.countryList = response.body;
                });
        }

    }

});<commit_msg>17.02.17.1<commit_after>/**
 * Created by Evgenii on 16.01.2017.
 */
Vue.config.debug = true;
Vue.http.headers.common['X-CSRF-TOKEN'] = document.getElementById('token').getAttribute('value');

var productVue = new Vue({

    el: "#productVue",

    data: {
        token: document.getElementById('token').getAttribute('value'),
        translate:  {},
        filterEvent: true,
        xapactEvent: true,
        paramEvent: true,
        fileEvent: true,
        product:{
            id: document.getElementById("form-data").id.value,
            images: [],
            meta_description: null,
            meta_title: null,
            title: null,
            slug: null
        },
        productsList:{
            products:{},
            pagination:{
                currentPage: {},
                lastPage: {},
                pageToGet: 1
            }
        },
        relOptions:{
            category:0,
            paginate: 20,
            search: '',
            selected: []
        },
        relatedProducts: null,
        selectedProductsIds: [],
        countryList: null
    },

    created: function () {
        if(this.product.id){
            this.$http.get('/dashboard/products/' + this.product.id + '/edit').then(function (response) {
                this.product = response.body;});
        }

        this.$http.get('/dashboard/helpers/translate').then(function (response) {
            this.translate = response;});
        this.getRelatedProducts();
    },

    computed: {
        stringImagesIds: function(){
            var images = [];
            for(var i = 0, len = this.product.images.length; i < len; i++ ){
                images[i] = this.product.images[i].id;
            }
            return images.join(',');
        },

        coountTitle: function () {
            if(this.product.id){
                return this.product.meta_title.length
            }else{
                return 0;
            }
        },

        coountDescription: function () {
            if(this.product.id){
                return this.product.meta_description.length
            }else{
                return 0;
            }
        },
    },

    methods: {

        makeSlug: function () {
            this.product.slug = this.prepareSlug()
        },

        prepareSlug: function () {
            var answer = '',
                title = this.product.title,
                translate = this.translate;

            for (var i in title) {
                if (translate.hasOwnProperty(title[i])) {
                    if (translate[title[i]] !== undefined) {
                        answer += translate[title[i]];
                    }
                } else {
                    answer += title[i];
                }
            }

            return answer.toLocaleLowerCase()
                .replace(/[^a-z0-9-]/, '-')
                .replace(/-{2,}/g, '-')
                .replace(/^[\s\uFEFF\xA0-]+|[\s\uFEFF\xA0-]+$/g, '')
                .replace(/\s/ig, '-');
        },

        getFields: function(){
            var vue = this;
            if(vue.filterEvent){
                vue.filterEvent = false;
                $("#filters").addClass('loading');
                this.$http.get('/dashboard/filters/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                    .then(function (response) {
                        $("#filters .inner").html(response.body);
                        $("#filters").removeClass('loading');
                        $('.selectize').selectize({
                            create: true,
                            createOnBlur: true,
                            sortField: 'text'
                        });
                    }, function (error) {
                        $("#filters .inner").html(error.body);
                        $("#filters").removeClass('loading');
                });
            }
        },

        getFieldsClik: function(){
            var vue = this;
            $("#filters").addClass('loading');
            this.$http.get('/dashboard/filters/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                .then(function (response) {
                    $("#filters .inner").html(response.body);
                    $("#filters").removeClass('loading');
                    $('.selectize').selectize({
                        create: true,
                        createOnBlur: true,
                        sortField: 'text'
                    });
                }, function (error) {
                    $("#filters .inner").html(error.body);
                    $("#filters").removeClass('loading');
                });
        },

        getXapacts: function () {
            var vue = this;
            if(vue.xapactEvent){
                vue.xapactEvent = false;
                $("#characters").addClass('loading');
                this.$http.get('/dashboard/characteristics/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                    .then(function (response) {
                        $("#characters .inner").html(response.body);
                        $("#characters").removeClass('loading');
                        $('.selectize_x').selectize({
                            create: true,
                            createOnBlur: true,
                            sortField: 'text'
                        });
                    }, function (error) {
                        $("#characters .inner").html(error.body);
                        $("#characters").removeClass('loading');
                    });
             }
        },

        getXapactsClik: function(){
            var vue = this;
            $("#characters").addClass('loading');
            this.$http.get('/dashboard/characteristics/'+ vue.product.id + '?category_id=' + vue.product.category_id )
                .then(function (response) {
                    $("#characters .inner").html(response.body);
                    $("#characters").removeClass('loading');
                    $('.selectize_x').selectize({
                        create: true,
                        createOnBlur: true,
                        sortField: 'text'
                    });
                }, function (error) {
                    $("#characters .inner").html(error.body);
                    $("#characters").removeClass('loading');
                });
        },

        getParam: function () {
            var vue = this;
            if (vue.paramEvent) {
                vue.paramEvent = false;
                $("#params").addClass('loading');
                this.$http.get('/dashboard/parameters/list?id='+ vue.product.id )
                    .then(function (response) {
                        $("#params .inner").html(response.body);
                        $("#params").removeClass('loading');
                    }, function (error) {
                        $("#params .inner").html(error.body);
                        $("#params").removeClass('loading');
                    });

            }
        },

        getParamClik: function () {
            var vue = this;
            $("#params").addClass('loading');
            this.$http.get('/dashboard/parameters/list?id='+ vue.product.id )
                .then(function (response) {
                    $("#params .inner").html(response.body);
                    $("#params").removeClass('loading');
                }, function (error) {
                    $("#params .inner").html(error.body);
                    $("#params").removeClass('loading');
                });
        },

        setAsThumbnail: function(image) {
            var vue = this;
            for(var img in vue.product.images){
                vue.product.images[img].is_thumb = false;
            }
            vue.product.images[vue.product.images.indexOf(image)].is_thumb = true;

            this.$http.post('/dashboard/set-thumbnail/' + image.id, {_token: vue.token, productId : vue.product.id} )
                .then(function (response) {});
        },

        removeImage: function (image) {
            var vue = this;
            this.$http.post('/dashboard/remove-image/' + image.id, {_token: vue.token} )
                .then(function (response) {
                    var index = vue.product.images.indexOf(image);
                    if (index > -1)
                        vue.product.images.splice(index, 1);
                });
        },

        loadImage: function (event) {
            var vue = this;
            var uploadInput = event.target;
            for(var property in uploadInput.files) {
                if(!isNaN(property)){
                    var data = new FormData();
                    //console.log(uploadInput[0].files[property]);
                    data.append('file', uploadInput.files[property]);
                    data.append('product_id', this.product.id);
                    data.append('is_certificate', event.target.id == 'cerf' ? 1 : 0);
                    this.$http.post('/dashboard/upload-image', data )
                        .then(function (image) {
                            vue.product.images.push(image.body);
                            if(vue.product.images.length == 1){
                                vue.setAsThumbnail(image);
                            }
                        });
                }
            }
            uploadInput.value = null;
        },

        loadVideo: function(){
            var vue = this;
            bootbox.prompt("Введите HTML код видео", function(result) {
                if (result ) {
                    vue.product.video = result;
                }
            });

        },

        removeVideo: function(){
            this.product.video = null;
        },

        getPdfList: function(){
            var vue = this;
            if(vue.fileEvent){
                vue.fileEvent = false;
                this.$http.get('/dashboard/pdf?id=' + vue.product.id )
                    .then(function (response) {
                        $("#filesup").html(response.body);
                    });
            }
        },

        updatePdfList: function(){
            var vue = this;
            this.$http.get('/dashboard/pdf?id=' + vue.product.id )
                .then(function (response) {
                    $("#filesup").html(response.body);
                });
        },

        loadPDF: function(event){
            var vue = this;
            var uploadInput = event.target;
            for(var property in uploadInput.files) {
                if(!isNaN(property)){
                    var data = new FormData();
                    data.append('file', uploadInput.files[property]);
                    data.append('productID', vue.product.id);
                    data.append('categoryID', vue.product.category_id);
                    data.append('brandID', vue.product.brand_id);

                    this.$http.post('/dashboard/upload-pdf', data )
                        .then(function () {
                            vue.updatePdfList();
                        });
                }
            }
        },

        getProducts: function () {
            var vue = this;
            var options = {
                params: {
                    categoryId: vue.relOptions.category,
                    paginate: vue.relOptions.search,
                    search: vue.relOptions.search,
                    selected: vue.getSelectedProductsIds(),
                    page: vue.productsList.pagination.pageToGet,
                    _: Date.now()
                }
            };
            this.$http.get('/dashboard/product-actions/getProducts', options)
                .then(function (response) {
                    vue.productsList.products = response.body.data;
                    vue.productsList.pagination.currentPage = response.body.current_page;
                    vue.productsList.pagination.lastPage = response.body.last_page;
                    if(vue.productsList.pagination.lastPage < vue.productsList.pagination.pageToGet) {
                        vue.productsList.pagination.pageToGet = vue.productsList.pagination.lastPage;
                        vue.getProducts()
                    }
                });
        },

        getRelatedProducts: function(){
            var vue = this;
            this.$http.post('/dashboard/product-actions/getRelatedProducts', {productId: this.product.id})
                .then(function (response) {
                    vue.relOptions.selected = response.body;
                    vue.selectedProductsIds = this.getSelectedProductsIds();
                });
        },

        syncProducts: function(){
            this.selectedProductsIds = this.getSelectedProductsIds();
            var body = {
                ids: this.getSelectedProductsIds(),
                productId: this.product.id
            };
            this.$http.post('/dashboard/product-actions/syncRelated', body)
        },

        getSelectedProductsIds: function(){
            var productsIds = [];
            this.relOptions.selected.forEach(function(product){
                productsIds.push(product.id);
            });
            return productsIds;
        },

        addProduct: function(relProduct, index){
            this.productsList.products.splice(index, 1);
            this.relOptions.selected.push(relProduct);
            this.syncProducts();
            this.getProducts();
        },

        removeProduct: function(relProduct, index){
            this.relOptions.selected.splice(index, 1);
            this.productsList.products.push(relProduct);
            this.syncProducts();
            this.getProducts();
        },

        nextPage: function(){
            if(this.productsList.pagination.currentPage != this.productsList.pagination.lastPage){
                this.productsList.pagination.pageToGet = this.productsList.pagination.currentPage + 1;
                this.getProducts();
            }
        },

        prevPage: function(){
            if(this.productsList.pagination.currentPage != 1) {
                this.productsList.pagination.pageToGet = this.productsList.pagination.currentPage - 1;
                this.getProducts();
            }
        },

        updateCountry: function () {
            this.$http.post('/dashboard/country/get')
                .then(function (response) {
                    this.countryList = response.body;
                });
        }

    }

});<|endoftext|>