我有两个相互关联的下拉菜单。这些的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];
};
两个下拉列表的选项来自两个与每个表有关系的不同表,第二个下拉列表中作为选项列出的服务将根据第一个下拉列表中选择的工作人员重新加载。但是,即使在第一个下拉列表中选择的工作人员可以提供相同的服务,第二个下拉列表中的服务也将重置。有没有办法可以将第二个下拉菜单的行为更改为不重置,除非实际需要?
谢谢!