Skip to content

Instantly share code, notes, and snippets.

@NouranMahmoud
Last active May 10, 2021 02:37
Show Gist options
  • Save NouranMahmoud/9b8a41c5059a894303219899e3f1e2c0 to your computer and use it in GitHub Desktop.
Save NouranMahmoud/9b8a41c5059a894303219899e3f1e2c0 to your computer and use it in GitHub Desktop.
multi-step-form
import Ember from 'ember';
export default Ember.Component.extend({
});
import Ember from 'ember';
export default Ember.Controller.extend({
appName: 'Multi step form',
});
import Ember from 'ember';
export default Ember.Controller.extend({
currentStepNumber: 1, // step counter
posts: Ember.computed(function(){
return this.get('store').peekAll('post');
}),
onInit: Ember.observer('model', function(){
this.get('model.posts').createRecord();
}),
firstStep: Ember.computed('currentStepNumber', function() {
const stepNumber = this.get('currentStepNumber');
return stepNumber === 1;
}),
secondStep: Ember.computed('currentStepNumber', function() {
const stepNumber = this.get('currentStepNumber');
return stepNumber === 2;
}),
lastStep: Ember.computed('currentStepNumber', function() {
const stepNumber = this.get('currentStepNumber');
return stepNumber === 3;
}),
actions: {
goNext: function() {
// validation occurs here
this.get('model').validate().then( ({validations}) => {
const pageErrors = validations.get('errors');
// check which step you are in and validate its fields only
switch(this.get('currentStepNumber')) {
case 1:
// here we need to validate against first step fields only
// which is "title"
// so, I filter the errors
const firstStepErrors = pageErrors.filter( (error) => {
return (error.attribute === 'title');
});
// but length will be always be 1, because even if page.title is valid, there is another "post.title" which will not be valid so this step will not pass.
// ==> is there a way to know, this "title" belongs to which model?
console.log(firstStepErrors); // check console.
if (firstStepErrors.length === 0) {
var nextStep = this.get('currentStepNumber') + 1;
this.set('currentStepNumber', nextStep);
}
break;
case 2:
const secondStepErrors = pageErrors.filter( (error) => {
return (error.attribute === 'title');
});
if (secondStepErrors.length === 0) {
var nextStep = this.get('currentStepNumber') + 1;
this.set('currentStepNumber', nextStep);
}
break;
case 3:
break
default:
break;
}
});
},
goPrevious: function() {
var prevStep = this.get('currentStepNumber') - 1;
this.set('currentStepNumber', prevStep);
return;
},
addNewPost: function() {
this.get('store').createRecord('post', {
page: this.get('model')
});
}
}
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
import { validator, buildValidations } from 'ember-cp-validations';
const Validations = buildValidations({
title: [
validator('presence', true),
validator('length', {min: 2, max: 30})
],
posts: validator('has-many'),
});
export default Model.extend(Validations, {
title: attr('string'),
posts: hasMany('posts')
});
import Model from "ember-data/model";
import attr from "ember-data/attr";
import { belongsTo, hasMany } from "ember-data/relationships";
import { validator, buildValidations } from 'ember-cp-validations';
const Validations = buildValidations({
title: [
validator('presence', true),
validator('length', {min: 2, max: 30})
],
page: validator('belongs-to'),
});
export default Model.extend(Validations, {
title: attr('string'),
content: attr('string'),
author: attr('string'),
page: belongsTo('page')
});
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: 'none',
rootURL: config.rootURL
});
Router.map(function() {
this.route('multi-step-form');
});
export default Router;
import Ember from 'ember';
export default Ember.Route.extend({
model() {
return this.get('store').createRecord('page');
}
});
<h1>Welcome to {{appName}}</h1>
<br>
Go to {{#link-to 'multi-step-form'}}multi step form {{/link-to}}
<br>
{{outlet}}
<br>
<br>
<p>New Post:</p>
Title: {{input
value=post.title
placeholder="Enter your post title"
required=true
focus-out=(action (mut showTitleError) true)
}}
<br/>
Content: {{input
value=post.content
placeholder="Enter your post content"
required=true
focus-out=(action (mut showTitleError) true)
}}
<br/>
Author: {{input
value=post.author
placeholder="Enter author name"
required=true
focus-out=(action (mut showTitleError) true)
}}
<br/>
<br/>
<br/>
{{#if firstStep}}
<h2>first step</h2>
Page Name: {{input
value=model.title
placeholder="Enter your page name"
required=true
focus-out=(action (mut showTitleError) true)
}}
{{else if secondStep}}
<h2>second step</h2>
{{#each posts as |post|}}
{{my-post post=post}}
{{/each}}
<a href="#" {{action 'addNewPost' preventDefault=true}}>+ new post</a>
{{else if lastStep}}
<br/>
<p>Page Title: {{model.title}}</p>
{{#each posts as |post|}}
<p>Post Title: {{post.title}}</p>
<p>Post Content: {{post.content}}</p>
<p>Post Author: {{post.author}}</p>
<br/>
<br/>
{{/each}}
<button {{action "submit"}}>Submit</button>
{{/if}}
<p>
<button {{action "goPrevious" preventDefault=true}}>Previous</button>
<button {{action "goNext" preventDefault=true}}>Next</button>
</p>
{
"version": "0.12.1",
"EmberENV": {
"FEATURES": {}
},
"options": {
"use_pods": false,
"enable-testing": false
},
"dependencies": {
"jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
"ember": "2.12.0",
"ember-template-compiler": "2.12.0",
"ember-testing": "2.12.0"
},
"addons": {
"ember-data": "2.12.1",
"ember-cp-validations": "3.3.2"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment