@belgoros wrote:
As I’m still in the very beginning of Ember learning curve, I wonder what is the best and correct way to implement the following functionality.
- I have to display a shop working hours like in the attached screenshot.
- as you see some day have their hours entered, some do not. I have always display all the 7 week days, no matter if the hours were entered or not, setting the state of the day as Closed and disabling its corresponding hours fields.
- how to save the entered hours:
- by every modified/created day ? (by adding
focus-out
to every opens/closes hours fields, for ex.?)- all the days via the Save button
- saving all the days, no matter if they have hours entered (anyway, every shop will have 7 days with one or another state, - closed, open, divided (i.e. with a break) ?
- how can all the hours values be caught if they don’t have IDs in case of new records ?
Here is how I defined a template:
# templates/working-hours.hbs ... <form {{action "saveHours" on="submit"}}> {{#each weekdays as |weekday|}} {{weekday-row weekday=weekday modelDays=model}} {{/each}} <div class="float-right"> <button type="submit" class="btn btn-success">{{t 'buttons.save'}}</button> </div> </form> ...
Here is the component passed in to the above
for
loop:#templates/components/weekday-row.hbs <div class="form-group row"> <label for="state" class="col-sm-2 col-form-label">{{dayRow.name}}</label> <div class="col-sm-2"> <select class="form-control" onchange={{action "selectState" value="target.value"}}> {{#each states as |state|}} <option value={{state.id}} selected={{eq state.id dayRow.state}}>{{state.name}}</option> {{/each}} </select> </div> <div class="col-sm-2"> {{input type="time" class="form-control" min="06:00" max="22:00" disabled=isClosed pattern="[0-9]{2}:[0-9]{2}" focus-out="alertMessage" value=dayRow.opens }} </div> <label for="closes" class="col-form-label">{{t 'working.hours.labels.to'}}</label> <div class="col-sm-2"> {{input type="time" class="form-control" min="06:00" max="22:00" disabled=isClosed pattern="[0-9]{2}:[0-9]{2}" focus-out="alertMessage" value=dayRow.closes }} </div> </div> {{#if isDivided}} <div class="form-group row"> <div class="col-sm-2 offset-sm-2">{{t 'working.hours.labels.and'}}</div> <div class="col-sm-2"> {{input type="time" class="form-control" min="06:00" max="22:00" disabled=isClosed pattern="[0-9]{2}:[0-9]{2}" value=dayRow.opens }} </div> <label for="closes"class="col-form-label">{{t 'working.hours.labels.to'}}</label> <div class="col-sm-2"> {{input type="time" class="form-control" min="06:00" max="22:00" disabled=isClosed pattern="[0-9]{2}:[0-9]{2}" value=dayRow.closes }} </div> </div> {{/if}}
And finally, the component itself:
# components/weekday-row.js import Component from '@ember/component'; import { inject as service } from '@ember/service'; import { computed } from '@ember/object'; import EmberObject from '@ember/object'; export default Component.extend({ constants: service(), weekday: null, state: null, modelDays: [], weekdays: [], states: [], tagName: '', dayRow: null, init() { this._super(...arguments); this.states = this.get('constants.states'); this.dayRow = this.buildDayRow(); }, buildDayRow() { let dayRow = EmberObject.create({ name: this.get('weekday.name')}); let foundDay = this.get('modelDays').findBy('day', this.get('weekday.day')); if (typeof foundDay != 'undefined') { dayRow.set('state', foundDay.get('state')); dayRow.set('opens', foundDay.get('opens')); dayRow.set('closes', foundDay.get('closes')); } else { let closedState = this.get('states')[1]; dayRow.set('state', closedState.id); } return dayRow; }, isClosed: computed('dayRow.state', function() { return this.get('dayRow').get('state') === 'closed'; }), isDivided: computed('dayRow.state', function() { return this.get('dayRow').get('state') === 'divided'; }), actions: { selectState(state) { this.get('dayRow').set('state', state); this.get('dayRow').set('opens', null); this.get('dayRow').set('closes', null); }, alertMessage(value) { console.log('focus off for: ' + value); } } });
The route handler:
# routes/working-hours.js import Route from '@ember/routing/route'; import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; import { inject as service } from '@ember/service'; export default Route.extend(AuthenticatedRouteMixin, { currentShop: service(), constants: service(), setupController(controller, model) { this._super(controller, model); this.controller.set('weekdays', this.get('constants.days')); }, model() { return this.store.query('working-hour', { shop_id: this.get('currentShop.shop').get('id')}); }, ...
Just in case here is how
weekdays
are defined inconstants.js
service:# services/constants.js import Service from '@ember/service'; import { inject as service } from '@ember/service'; export default Service.extend({ i18n: service('i18n'), init() { this._super(...arguments); this.set('states', [ {id: 'opened', name: this.get('i18n').t('states.open')}, {id: 'closed', name: this.get('i18n').t('states.closed')}, {id: 'divided', name: this.get('i18n').t('states.divided')} ] ); this.set('days', [ {day: 'monday', name: this.get('i18n').t('weekdays.monday')}, {day: 'tuesday', name: this.get('i18n').t('weekdays.tuesday')}, {day: 'wednesday', name: this.get('i18n').t('weekdays.wednesday')}, {day: 'thursday', name: this.get('i18n').t('weekdays.thursday')}, {day: 'friday', name: this.get('i18n').t('weekdays.friday')}, {day: 'saturday', name: this.get('i18n').t('weekdays.saturday')}, {day: 'sunday', name: this.get('i18n').t('weekdays.sunday')} ] ); } });
Thank you!
Posts: 1
Participants: 1