更改选项时下拉重置 - AngularJS

时间:2017-07-06 14:12:06

标签: javascript jquery html angularjs drop-down-menu

我有两个相互关联的下拉菜单。这些的HTML如下:

<div class=form-group>
    <label for="ab_provider">
        <?php _e( 'Teacher', 'management' ) ?>
    </label>
    <select id="ab_provider" class="field form-control" ng-model="form.staff" ng-options="s.full_name for s in dataSource.data.staff" ng-change="onStaffChange()"></select>
</div>
<div class=form-group>
    <label for="ab_service">
        <?php _e( 'Class Type', 'management' ) ?>
    </label>
    <select id="ab_service" class="field form-control" ng-model="form.service" ng-options="s.title for s in form.staff.services" ng-change="onServiceChange()">
        <option value="">
            <?php _e( '-- Select a class type --', 'bookly' ) ?>
        </option>
    </select>
</div>

这是我的JS,它在添加和编辑时都设置了表单。

module.factory('dataSource', function($q, $rootScope, $filter) {
    var ds = {
        loaded : false,
        data : {
            staff         : [],
            customers     : [],
            start_time    : [],
            end_time      : [],
            time_interval : 900,
            status        : {
                items: [],
                default: null
            }
        },
        form : {
            screen     : null,
            id         : null,
            staff      : null,
            service    : null,
            date       : null,
            repeat     : {
                enabled  : null,
                repeat   : null,
                daily    : { every : null },
                weekly   : { on : null },
                biweekly : { on : null },
                monthly  : { on : null, day : null, weekday : null },
                until    : null
            },
            schedule   : {
                items : [],
                edit  : null,
                page  : null,
                another_time : []
            },
            start_time : null,
            end_time   : null,
            customers  : [],
            notification : null,
            series_id  : null
        },
        loadData : function() {
            var deferred = $q.defer();
            if (!ds.loaded) {
                jQuery.get(
                    ajaxurl,
                    { action : 'bookly_get_data_for_appointment_form' },
                    function(data) {
                        ds.loaded = true;
                        ds.data = data;
                        // Add empty element to beginning of array for single-select customer form
                        ds.data.customers.unshift({name: ''});

                        if (data.staff.length) {
                            ds.form.staff = data.staff[0];
                        }
                        ds.form.start_time = data.start_time[0];
                        ds.form.end_time   = data.end_time[1];
                        deferred.resolve();
                    },
                    'json'
                );
            } else {
                deferred.resolve();
            }

            return deferred.promise;
        },
        findStaff : function(id) {
            var result = null;
            jQuery.each(ds.data.staff, function(key, item) {
                if (item.id == id) {
                    result = item;
                    return false;
                }
            });
            return result;
        },
        findService : function(staff_id, id) {
            var result = null,
                staff  = ds.findStaff(staff_id);

            if (staff !== null) {
                jQuery.each(staff.services, function(key, item) {
                    if (item.id == id) {
                        result = item;
                        return false;
                    }
                });
            }
            return result;
        },
        findTime : function(source, date) {
            var result = null,
                value_to_find = $filter('date')(date, 'HH:mm'),
                time = source == 'start' ? ds.data.start_time : ds.data.end_time;

            jQuery.each(time, function(key, item) {
                if (item.value >= value_to_find) {
                    result = item;
                    return false;
                }
            });
            return result;
        },
        findCustomer : function(id) {
            var result = null;
            jQuery.each(ds.data.customers, function(key, item) {
                if (item.id == id) {
                    result = item;
                    return false;
                }
            });
            return result;
        },
        resetCustomers : function() {
            ds.data.customers.forEach(function(customer) {
                customer.custom_fields     = [];
                customer.extras            = [];
                customer.status            = ds.data.status.default;
                customer.number_of_persons = 1;
                customer.compound_token    = null;
                customer.location_id       = null;
                customer.payment_id        = null;
                customer.payment_type      = null;
                customer.payment_title     = null;
            });
        },
        getDataForEndTime : function() {
            var result = [];
            if (ds.form.start_time) {
                var start_time = ds.form.start_time.value.split(':'),
                    end = (24 + parseInt(start_time[0])) + ':' + start_time[1];
                jQuery.each(ds.data.end_time, function(key, item) {
                    if (item.value > end) {
                        return false;
                    }
                    if (item.value > ds.form.start_time.value) {
                        result.push(item);
                    }
                });
            }
            return result;
        },
        setEndTimeBasedOnService : function() {
            var i = jQuery.inArray(ds.form.start_time, ds.data.start_time),
                d = ds.form.service ? ds.form.service.duration : ds.data.time_interval;
            if (ds.form.service && ds.form.service.duration < 86400) {
                if (i !== -1) {
                    for (; i < ds.data.end_time.length; ++i) {
                        d -= ds.data.time_interval;
                        if (d < 0) {
                            break;
                        }
                    }
                    ds.form.end_time = ds.data.end_time[i];
                }
            }
        },
        getStartAndEndDates : function() {
            var start_date = moment(ds.form.date.getTime()),
                end_date   = moment(ds.form.date.getTime()),
                start_time = [0,0],
                end_time   = [0,0]
                ;
            if (ds.form.service && ds.form.service.duration >= 86400) {
                end_date.add(ds.form.service.duration, 'seconds');
            } else {
                start_time = ds.form.start_time.value.split(':');
                end_time   = ds.form.end_time.value.split(':');
            }
            start_date.hours(start_time[0]);
            start_date.minutes(start_time[1]);
            end_date.hours(end_time[0]);
            end_date.minutes(end_time[1]);

            return {
                start_date : start_date.format('YYYY-MM-DD HH:mm:00'),
                end_date   : end_date.format('YYYY-MM-DD HH:mm:00')
            };
        },
        getTotalNumberOfPersons : function () {
            var result = 0;
            ds.form.customers.forEach(function (item) {
                result += parseInt(item.number_of_persons);
            });

            return result;
        },
        getTotalNumberOfNotCancelledPersons: function () {
            var result = 0;
            ds.form.customers.forEach(function (item) {
                if (item.status != 'cancelled' && item.status != 'rejected') {
                    result += parseInt(item.number_of_persons);
                }
            });

            return result;
        },
        getTotalNumberOfCancelledPersons: function () {
            var result = 0;
            ds.form.customers.forEach(function (item) {
                if (item.status == 'cancelled' || item.status == 'rejected') {
                    result += parseInt(item.number_of_persons);
                }
            });

            return result;
        }
    };

    return ds;
});

/**
 * Controller for 'create/edit appointment' dialog form.
 */
module.controller('appointmentDialogCtrl', function($scope, $element, dataSource, $filter) {
    // Set up initial data.
    $scope.$calendar = null;
    // Set up data source.
    $scope.dataSource = dataSource;
    $scope.form = dataSource.form;  // shortcut
    // Error messages.
    $scope.errors = {};
    // Callback to be called after editing appointment.
    var callback = null;

    /**
     * Prepare the form for new event.
     *
     * @param int staff_id
     * @param moment start_date
     * @param function _callback
     */
    $scope.configureNewForm = function(staff_id, start_date, _callback) {
        var weekday = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'][start_date.format('d')];
        jQuery.extend($scope.form, {
            screen     : 'main',
            id         : null,
            staff      : dataSource.findStaff(staff_id),
            service    : null,
            date       : start_date.clone().local().toDate(),
            start_time : dataSource.findTime('start', start_date.format('HH:mm')),
            end_time   : null,
            repeat     : {
                enabled  : 0,
                repeat   : 'daily',
                daily    : { every: 1 },
                weekly   : { on : [weekday] },
                biweekly : { on : [weekday] },
                monthly  : { on : 'day', day : start_date.format('D'), weekday : weekday },
                until    : start_date.clone().add(1, 'month').format('YYYY-MM-DD')
            },
            schedule   : {
                items : [],
                edit  : 0,
                page  : 0,
                another_time : []
            },
            customers  : [],
            notification  : 'no',
            internal_note : null,
            venue : null,
            term : null,
            inset_days : null,
            min_cost_per_class : null,
            min_no_pupils_per_class : null,
            cost_per_pupil : null,
            max_number_in_class : null,
            teachers_fee : null,
            class_created_by : null
        });
        $scope.errors = {};
        dataSource.setEndTimeBasedOnService();
        callback = _callback;

        $scope.reInitChosen();
        $scope.prepareExtras();
        $scope.prepareCustomFields();
        $scope.dataSource.resetCustomers();
    };

    /**
     * Prepare the form for editing an event.
     */
    $scope.configureEditForm = function(appointment_id, _callback) {
        $scope.loading = true;
        jQuery.post(
            ajaxurl,
            {action: 'bookly_get_data_for_appointment', id: appointment_id},
            function(response) {
                $scope.$apply(function($scope) {
                    if (response.success) {
                        var start_date = moment(response.data.start_date),
                            end_date   = moment(response.data.end_date);
                        jQuery.extend($scope.form, {
                            screen     : 'main',
                            id         : appointment_id,
                            staff      : $scope.dataSource.findStaff(response.data.staff_id),
                            service    : $scope.dataSource.findService(response.data.staff_id, response.data.service_id),
                            date       : start_date.clone().local().toDate(),
                            start_time : $scope.dataSource.findTime('start', start_date.format('HH:mm')),
                            end_time   : start_date.format('YYYY-MM-DD') == end_date.format('YYYY-MM-DD')
                                ? $scope.dataSource.findTime('end', end_date.format('HH:mm'))
                                : $scope.dataSource.findTime('end', (24 + end_date.hour()) + end_date.format(':mm')),
                            repeat     : {
                                enabled  : 0,
                                repeat   : 'daily',
                                daily    : { every: 1 },
                                weekly   : { on : [] },
                                biweekly : { on : [] },
                                monthly  : { on : 'day', day : '1', weekday : 'mon' },
                                until    : start_date.clone().add(1, 'month').format('YYYY-MM-DD')
                            },
                            schedule   : {
                                items : [],
                                edit  : 0,
                                page  : 0,
                                another_time : []
                            },
                            customers  : [],
                            notification : 'no',
                            internal_note : response.data.internal_note,
                            venue : response.data.venue,
                            term : response.data.term,
                            inset_days : response.data.inset_days,
                            min_cost_per_class : response.data.min_cost_per_class,
                            min_no_pupils_per_class : response.data.min_no_pupils_per_class,
                            cost_per_pupil : response.data.cost_per_pupil,
                            max_number_in_class : response.data.max_number_in_class,
                            teachers_fee : response.data.teachers_fee,
                            class_created_by : response.data.class_created_by,
                            series_id  : response.data.series_id
                        });

                        $scope.reInitChosen();
                        $scope.prepareExtras();
                        $scope.prepareCustomFields();
                        $scope.dataSource.resetCustomers();

                        var customers_ids = [];
                        response.data.customers.forEach(function (item, i, arr) {
                            var customer = $scope.dataSource.findCustomer(item.id),
                                clone = {};
                            if (customers_ids.indexOf(item.id) === -1) {
                                customers_ids.push(item.id);
                                clone = customer;
                            } else {
                                // For Error: ngRepeat:dupes & chosen directive
                                angular.copy(customer, clone);
                            }
                            clone.ca_id             = item.ca_id;
                            clone.extras            = item.extras;
                            clone.status            = item.status;
                            clone.custom_fields     = item.custom_fields;
                            clone.number_of_persons = item.number_of_persons;
                            clone.location_id       = item.location_id;
                            clone.payment_id        = item.payment_id;
                            clone.payment_type      = item.payment_type;
                            clone.payment_title     = item.payment_title;
                            clone.compound_token    = item.compound_token;
                            clone.compound_service  = item.compound_service;
                            $scope.form.customers.push(clone);
                        });
                    }
                    $scope.loading = false;
                });
            },
            'json'
        );
        $scope.errors = {};
        callback = _callback;
    };

    var checkTimeInterval = function() {
        var dates = $scope.dataSource.getStartAndEndDates();
        jQuery.post(
            ajaxurl,
            {
                action         : 'bookly_check_appointment_date_selection',
                start_date     : dates.start_date,
                end_date       : dates.end_date,
                appointment_id : $scope.form.id,
                staff_id       : $scope.form.staff ? $scope.form.staff.id : null,
                service_id     : $scope.form.service ? $scope.form.service.id : null
            },
            function (response) {
                $scope.$apply(function ($scope) {
                    $scope.errors = response;
                });
            },
            'json'
        );
    };

    $scope.onServiceChange = function() {
        $scope.dataSource.setEndTimeBasedOnService();
        $scope.reInitChosen();
        $scope.prepareExtras();
        $scope.prepareCustomFields();
        checkTimeInterval();
    };

    $scope.onStaffChange = function() {
        $scope.form.service = null;
    };

    $scope.onStartTimeChange = function() {
        $scope.dataSource.setEndTimeBasedOnService();
        checkTimeInterval();
    };

    $scope.onEndTimeChange = function() {
        checkTimeInterval();
    };

    $scope.onDateChange = function() {
        checkTimeInterval();
    };

    $scope.processForm = function() {
        $scope.loading = true;

        var dates     = $scope.dataSource.getStartAndEndDates(),
            schedule  = [],
            customers = []
        ;

        angular.forEach($scope.form.schedule.items, function (item) {
            if (!item.deleted) {
                schedule.push(item.slots);
            }
        });

        $scope.form.customers.forEach(function (item, i, arr) {
            var customer_extras = {};
            if ($scope.form.service) {
                jQuery('#bookly-extras .service_' + $scope.form.service.id + ' input.extras-count').each(function () {
                    var extra_id = jQuery(this).data('id');
                    if (item.extras[extra_id] !== undefined) {
                        customer_extras[extra_id] = item.extras[extra_id];
                    }
                });
            }
            customers.push({
                id                : item.id,
                ca_id             : item.ca_id,
                custom_fields     : item.custom_fields,
                extras            : customer_extras,
                location_id       : item.location_id,
                number_of_persons : item.number_of_persons,
                status            : item.status
            });
        });

        jQuery.post(
            ajaxurl,
            {
                action        : 'bookly_save_appointment_form',
                id            : $scope.form.id,
                staff_id      : $scope.form.staff ? $scope.form.staff.id : null,
                service_id    : $scope.form.service ? $scope.form.service.id : null,
                start_date    : dates.start_date,
                end_date      : dates.end_date,
                repeat        : JSON.stringify($scope.form.repeat),
                schedule      : schedule,
                customers     : JSON.stringify(customers),
                notification  : $scope.form.notification,
                internal_note : $scope.form.internal_note,
                venue : $scope.form.venue,
                term : $scope.form.term,
                inset_days : $scope.form.inset_days,
                min_cost_per_class : $scope.form.min_cost_per_class,
                min_no_pupils_per_class : $scope.form.min_no_pupils_per_class,
                cost_per_pupil : $scope.form.cost_per_pupil,
                max_number_in_class : $scope.form.max_number_in_class,
                teachers_fee : $scope.form.teachers_fee,
                class_created_by : $scope.form.class_created_by
            },
            function (response) {
                $scope.$apply(function($scope) {
                    if (response.success) {
                        if (callback) {
                            // Call callback.
                            callback(response.data);
                        }
                        // Close the dialog.
                        $element.children().modal('hide');
                    } else {
                        $scope.errors = response.errors;
                    }
                    $scope.loading = false;
                });
            },
            'json'
        );
    };

    // On 'Cancel' button click.
    $scope.closeDialog = function () {
        // Close the dialog.
        $element.children().modal('hide');
    };

    $scope.reInitChosen = function () {
        jQuery('#bookly-chosen')
            .chosen('destroy')
            .chosen({
                search_contains     : true,
                width               : '100%',
                max_selected_options: dataSource.form.service ? dataSource.form.service.capacity + dataSource.getTotalNumberOfCancelledPersons() : 0
            });
    };

    $scope.statusToString = function (status) {
        return dataSource.data.status.items[status];
    };

两个下拉列表的选项来自两个与每个表有关系的不同表,第二个下拉列表中作为选项列出的服务将根据第一个下拉列表中选择的工作人员重新加载。但是,即使在第一个下拉列表中选择的工作人员可以提供相同的服务,第二个下拉列表中的服务也将重置。有没有办法可以将第二个下拉菜单的行为更改为不重置,除非实际需要?

谢谢!

0 个答案:

没有答案