Ember.js and image uploading - ember.js

I'm having trouble with uploading images in Ember.js
I have a form to create a user :
<div class="container">
<form onsubmit={{action "createUser"}} enctype="multipart/form-data">
<div class="form-group">
<label for="firstName">First name: </label>
{{input type="text" class="form-control" id="firstName" required="true" value=firstName}}
</div>
<div class="form-group">
<label for="lastName">Last name: </label>
{{input type="text" class="form-control" id="lastName" required="true" value=lastName}}
</div>
<div class="form-group">
<label for="age">Age: </label>
{{input type="number" class="form-control" id="age" required="true" value=age}}
</div>
<div class="form-group">
<label for="job">Job: </label>
{{input type="text" class="form-control" id="job" required="true" value=job}}
</div>
<div class="form-group">
<label for="image">Picture: </label>
{{input type="file" class="form-control" id="image" value=image}}
</div>
<button type="submit" class="btn btn-info">Create</button>
</form>
I know I should encode images in base64 but I have no idea how to do that since I've never done it before.
And in the view, this is how I'm trying to get the image (I know this is not what I should do but I don't know how to do it) :
<div class="container">
<h1>{{model.firstName}} {{model.lastName}}</h1>
<p>Age: {{model.age}} years old</p>
<p>Job: {{model.job}}</p>
<img src="{{model.image}}" alt="img" id="image">
</div>
Any ideas, suggestions, help please ?
EDIT :
actions: {
createUser(event) {
event.preventDefault();
let user = this.store.createRecord('user', {
firstName: this.firstName,
lastName: this.lastName,
age: this.age,
job: this.job,
image: this.image
});
user.save().then (() => {
this.transitionToRoute('user', user.id);
});
}
}

Make use of ember-file-upload addon. The addon takes care in encoding them as a Base64 data url. In your case follow the below steps,
hbs form page:
<form onsubmit={{action 'createUser'}}>
<div class="form-group">
<label for="firstName">First name: </label>
{{input type="text" class="form-control" id="firstName" required="true" value=firstName}}
</div>
...
//other input fields
...
{{#file-upload name="avatar"
accept="image/*"
onfileadd=(action 'setAvatar')}}
// preview image before uploading
{{#if avatar}}
<img src={{avatar}}
<a id="upload-avatar">Add a photo</a>
{{else}}
<a id="upload-avatar">Add a photo</a>
{{/if}}
{{/file-upload}}
<button type="submit">Create</button>
</form>
hbs view page:
<div class="container">
<h1>{{model.firstName}} {{model.lastName}}</h1>
<p>Age: {{model.age}} years old</p>
<p>Job: {{model.job}}</p>
<img src={{model.image}} alt="img" id="image">
</div>
js:
import Controller from '#ember/controller';
export default Controller.extend({
avatarFile: null,
actions: {
createUser(event) {
event.preventDefault();
// upload file to backend
let file = this.get('avatarFile');
// make a api call to the url `/upload` (modify the url as you wish)
file.upload('/upload').then((response) => {
// save user model once the image is been uploaded successfully to the server
let user = this.store.createRecord('user', {
firstName: this.firstName,
...
// get the image_url from backend response
image: response.image_url
});
user.save().then((response) => {
// get the user_id in response
this.transitionToRoute('user', response.user_id);
});
});
},
setAvatar(file) {
this.set('avatarFile', file);
// Set the URL so we can see a preview
file.readAsDataURL().then((url) => {
this.set('avatar', url);
});
}
}
});
You can refer to the entire documentation here

Replace
{{input type="file" class="form-control" id="image" value=image}}
with
<input type="file" class="form-control" id="image" onchange={{action "uploadFile"}}/>
<br> Chosen image is <br>
<img src={{image}} />
This will trigger the uploadFile action when the image is chosen.
In your js file, add the action as ,
actions: {
uploadFile: function(event) {
var self = this;
const reader = new FileReader();
const file = event.target.files[0];
let imageData;
reader.onload = function(){
imageData = reader.result;
self.set('image', imageData);
};
if (file) {
reader.readAsDataURL(file);
}
}
}
Source : https://stackoverflow.com/a/40370830/2824131

Related

How to ensure Ember is saving variable state on reload

I'm creating and saving a form using Ember but when I reload the page the toggle keeping track of whether the form has been submitted or not resets to false.
I have a page where the default text is 'You have no account linked'. I then have a button that when pressed displays a form for the user to fill out information . When they click submit and save their information, the form disappears and renders some text about their account. When I reload the page however the text renders to the default 'You have no account linked', and when I click the submit form button, their information is populated in the form fields. How can I ensure that when the page is reloaded the text about the user account is displayed?
This is the controller for the page
export default Controller.extend({
isToggled: false,
emailConnected: false,
actions: {
submitImap(mailbox, toggle, email) {
this.get('ajax').request(`/api/accounts/${this.session.account.id}/mailboxes/imap`, {
method: 'POST',
data: mailbox
})
.then(() => Utils.notify("IMAP settings saved.", 'success'))
.catch(() => Utils.notify("Error saving IMAP account. Try again", 'error'));
this.send('contract', toggle);
this.send('expand', email);
},
disconnectIMAP(mailbox, property, email) {
this.get('ajax').request(`/api/accounts/${this.session.account.id}/mailboxes/imap`, {
method: 'DELETE',
data: {
user_id: mailbox.user_id
}
}).then(() => {
this.set(property, { smtp: {}});
})
.then(() => Utils.notify("IMAP removed. ", 'success'))
.catch(() => Utils.notify("Error removing IMAP account", 'error'));
this.send('contract',email );
},
expand: function(toggle) {
this.set(toggle, true)
},
contract: function(toggle) {
this.set(toggle, false)
}
}
});
This is the template handling the form submission
<h3>IMAP/SMTP</h3>
{{#if emailConnected}}
{{#if isToggled}}
<p> Edit your IMAP settings below </p>
{{else}}
<p>
You currently have IMAP account <strong>{{imapMailbox.username}}</strong>
connected for messaging.
</p>
<button {{action "disconnectIMAP" imapMailbox 'imapMailbox' 'emailConnected' }} class = 'btn btn-danger'>Disconnect</button>
{{/if}}
{{else}}
<p>
You currently do not have an account linked for messaging.
</p>
{{/if}}
{{#if isToggled}}
<form name='imap' class='modern-form full-width' {{action 'submitImap' imapMailbox 'isToggled' 'emailConnected' on="submit" }}>
<div class='row'>
<div class='col-sm-6'>
<h4>IMAP</h4>
<div class='form-group'>
<label>
Host
</label>
{{input type='text' required=true name='address' value=imapMailbox.address class='form-control'}}
</div>
<div class='form-group'>
<label>
Port
</label>
{{input type='text' required=true name='port' value=imapMailbox.port class='form-control'}}
</div>
<div class='form-check'>
{{input type='checkbox' name='ssl' checked=imapMailbox.ssl class='form-check-input'}}
<label for='ssl'>
SSL
</label>
</div>
<div class='form-check'>
{{input type='checkbox' name='starttls' checked=imapMailbox.starttls class='form-check-input'}}
<label>
TLS
</label>
</div>
<div class='form-group'>
<label>
Username
</label>
{{input type='text' required=true name='username' value=imapMailbox.username class='form-control'}}
</div>
<div class='form-group'>
<label>
Password
</label>
{{input type='password' required=true name='password' value=imapMailbox.password class='form-control'}}
</div>
</div>
<div class='col-sm-6'>
<h4>SMTP</h4>
<div class='form-group'>
<label>
Host
</label>
{{input type='text' required=true name='smtp_address' value=imapMailbox.smtp.address class='form-control'}}
</div>
<div class='form-group'>
<label>
Port
</label>
{{input type='text' required=true name='smtp_port' value=imapMailbox.smtp.port class='form-control'}}
</div>
<div class='form-check'>
{{input type='checkbox' name='smtp_ssl' checked=imapMailbox.smtp.ssl class='form-check-input'}}
<label for='ssl'>
SSL
</label>
</div>
<div class='form-check'>
{{input type='checkbox' name='smtp_starttls' checked=imapMailbox.smtp.enable_starttls_auto class='form-check-input'}}
<label>
TLS
</label>
</div>
<div class='form-group'>
<label>
Username
</label>
{{input type='text' required='true' name='smtp_username' value=imapMailbox.smtp.user_name class='form-control'}}
</div>
<div class='form-group'>
<label>
Password
</label>
{{input type='password' required='true' name='smtp_password' value=imapMailbox.smtp.password class='form-control'}}
</div>
</div>
</div>
<button type="submit" class='btn btn-success'>
Save
</button>
<button {{action 'contract' 'isToggled'}} class = 'btn btn-danger'>
Cancel
</button>
</form>
{{else}}
<button {{action 'expand' 'isToggled'}} class= 'btn btn-success'>
Connect email
</button>
{{/if}}
Right now, if I submit the form the behavior is as expected, displaying the current username of the account, but on reload the emailConnected variable resets to false and the default of 'you have no account connected' is present and when I click the form the values are populated.
If you reload the page (or) switch to a different route, the controller's property isToggled will reset to its initial state (i.e) to false in your case.
If you want to maintain the state and make use of the property isToggled at various parts of your application, you can use ember service
But in your case, you want to maintain the property state even after the page reloads. ember service doesn't maintain the state after the page reloads.
Here comes the use of browsers localStorage
So, in your case -
1) store the value of the property isToggled in browsers localStorage
import { computed } from '#ember/object';
export default Controller.extend({
isToggled: computed(function () {
// when the user visits the page for the very first time,
// isToggled value is set to false,
// from next time it gets the value from browsers localStorage.
if (localStorage.isToggled) {
return JSON.parse(localStorage.isToggled);
} else {
return false;
}
}),
...
actions: {
...
expand: function() {
localStorage.setItem('isToggled', JSON.stringify(true));
this.set('isToggled', true);
},
contract: function() {
localStorage.setItem('isToggled', JSON.stringify(false));
this.set('isToggled', false);
}
...
}
});
Now when the page is reloaded the isToggled property state doesn't change to the initial state.
You can find the isToggle browsers localStorage variable in your browsers developer tool: Application -> Local Storage tab
You could also use Ember Local Storage library to achieve this: https://github.com/funkensturm/ember-local-storage

Loading data that isnt on the route?

I have a dropdown setup on a form but how do i set it up if my data isnt in the route? I am trying to load in a list of territories on a new dealer form. I have added ember-power-select add on but I cant figure out how to load the data to the add on to display the available options. Do I need to create a service or controller?
New to ember just trying to work through the basics.
Router.map(function() {
this.route('login');
this.route('admin', function() {
this.route('territory', function() {
this.route('new');
this.route('edit', { path: '/:territory_id/edit'});
this.route('view', { path: '/:territory_id/view'});
});
this.route('dealer', function() {
this.route('view', { path: '/:dealer_id/view'});
this.route('new');
});
});
});
This is my form I am using on creating a new item.
<div class="well">
<form class="form-horizontal">
<fieldset>
<legend>New Dealer</legend>
<div class="form-group">
<label for="inputFirstName" class="col-lg-2 control-label">Name</label>
<div class="col-lg-4">
{{input type="text" value=model.dealerName class="form-control" placeholder="Dealer Name"}}
</div>
</div>
<div class="form-group">
<label for="inputFirstName" class="col-lg-2 control-label">Territory</label>
<div class="col-lg-4">
{{#power-select selected=dealer options=dealer onchange=(action "chooseDestination") as |dealer|}}
{{dealer.dealerName}}
{{/power-select}}
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
{{#link-to 'admin.dealer' class="btn btn-default"}}Cancel{{/link-to}}
<button type="submit" class="btn btn-primary" {{action 'saveDealer' model}}>Submit</button>
</div>
</div>
</fieldset>
</form>
</div>
Just because a route is the new action for a territory or the view action for a dealer, doesn't mean that you can't load other data there.
For example, in the territory/view route, you could load all the dealers.
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return Ember.RSVP.hash({
territory: this.store.find('territory', params.territory_id),
dealers: this.store.findAll('dealer')
})
}
});
Then in your controller and templates, you would have access to model.territory and model.dealers

Ember: Integrating Google Recaptcha with ember-cp-validations

I have a simple contact form, with validation done using ember-cp-validations https://github.com/offirgolan/ember-cp-validations and I now need to integrate the new Google Recaptcha into that.
For the rendering of the recaptcha, I am using this code - https://gist.github.com/cravindra/5beeb0098dda657433ed - which works perfectly.
However, I don't know how to deal with the verification process to allow the form to be submitted/prevented if the challenge is correct/incorrect or not provided
Here is a truncated version of my contact-form component
import Ember from 'ember';
import Validations from './cp-validations/contact-form';
import config from '../config/environment';
export default Ember.Component.extend(Validations,{
data:{},
nameMessage:null,
init() {
this._super(...arguments);
this.set('data',{});
},
actions:{
submitForm() {
this.validate().then(({model,validations}) => {
if (validations.get('isValid')) {
// submit form
}
else {
if(model.get('validations.attrs.data.name.isInvalid')){
this.set('nameMessage',model.get('validations.attrs.data.name.messages'));
}
}
})
}
}
});
Here is the template for the component, which includes the rendering of the recpatcha using the gist above
<form {{action 'submitForm' on='submit'}}>
<div class="row">
<div class="medium-6 columns">
{{input type="text" value=data.name id="name" placeholder="Enter your name"}}
<div class="error-message">
{{nameMessage}}
</div>
</div>
</div>
<div class="row">
<div class="medium-12 columns">
{{google-recaptcha}}
</div>
</div>
<button class="button primary" type="submit">Submit</button>
</form>
The Validations import looks like this
import { validator, buildValidations } from 'ember-cp-validations';
export default buildValidations({
'data.name': {
validators: [
validator('presence',{
presence:true,
message:'Please enter your name'
})
]
},
});
Many thanks for any help!
Register captchaComplete in your google-recaptcha component and mix the answer with your validations
UPDATE
contact-form.hbs
<form {{action 'submitForm' on='submit'}}>
<div class="row">
<div class="medium-6 columns">
{{input type="text" value=data.name id="name" placeholder="Enter your name"}}
<div class="error-message">
{{nameMessage}}
</div>
</div>
</div>
<div class="row">
<div class="medium-12 columns">
{{google-recaptcha captchaComplete=validateRecatcha}}
</div>
</div>
<button class="button primary" type="submit">Submit</button>
</form>
contact-form.js
import Ember from 'ember';
import Validations from './cp-validations/contact-form';
import config from '../config/environment';
export default Ember.Component.extend(Validations,{
data:{},
nameMessage:null,
captchaValidated: false,
init() {
this._super(...arguments);
this.set('data',{});
},
actions:{
validateRecatcha(data){
//if data denotes captcha is verified set captchaValidated to true else false
},
submitForm() {
this.validate().then(({model,validations}) => {
if (validations.get('isValid') && this.get('captchaValidated')) {
// submit form
}
else {
if(model.get('validations.attrs.data.name.isInvalid')){
this.set('nameMessage',model.get('validations.attrs.data.name.messages'));
}
}
})
}
}
});

Binding Ember Model to Radio Fields

I have a simple input radio for toggling between active and inactive. I can not figure out how to get Ember to tie this to the model. My RAW html currently looks like this:
<fieldset class="checkboxes">
<label class="active" for="is_active">
<input type="radio" id="is_active" name="status" value="1" checked="">
<span>Active</span>
<div class="input"></div>
</label>
<label class="sep">/</label>
<label class="inactive" for="inactive">
<input type="radio" id="inactive" value="0" name="status">
<span>Inactive</span>
<div class="input"></div>
</label>
Does anyone have any ideas on how to do this using the Ember form model binding?
make your labels action, that will allow you to play with them in the controller. I hope this help....
<fieldset>
<label class="option-buttons" for="reason1" {{action "setDeclineReason" "Too Expensive" on="mouseDown"}}>
<input name="decline-reason" id="reason1" value="Too Expensive" type="radio">
<span>
<div class="check"></div>
Too expensive
</span>
</label>
<label class="option-buttons" for="reason2" {{action "setDeclineReason" "Lack of Amenities" on="mouseDown"}}>
<input name="decline-reason" id="reason2" value="Lack of Amenities" type="radio">
<span>
<div class="check"></div>
Lack of amenities
</span>
</label>
</fieldset>
App.DeclineController = Ember.Controller.extend({
declineReason: null,
decline: function(){
var update = this.store.update('request', {
id: this.get('model').id,
user_decline_reason: this.get('declineReason')
});
update.save();
actions:{
setDeclineReason: function(declineReason){
this.set('declineReason', declineReason);
}
}
});

Ajax, Django, Jquery Model Form

Built a successful working ModelForm and its fully functional.
My next step was to add Ajax to it and it also worked out pretty well. The Jquery that I used was 1.3.2 version which is pretty old but it worked.
The problem came up when I tried to add bootstrap 2 DATE fields.
Using CHECKIN & CHECKOUT values that I have added to my form and it worked.
It required higher version of jquery so I used the recent one 1.9.1.
But when I used it my form is working except 1 little issues when I submit the form
and there not filled out required fields it will show me those fields but SUBMIT button is
disabled. When I use jquery 1.3.2 all is working 100% except the 2 fields for Bootstrap
DATEPICKER that requires higher jquery version.
Input Fields in the Form: Departure & Return are Date Picker Fields
I didnt include the Bootstrap Scripts they are same from the Bootsrap site.
When I use:
<script src="/media/js/jquery/1.9.1.jquery.min.js" type="text/javascript"></script>
Departure & Return are Date Picker Fields are Working but after submitting it with empty
other fields - it will show you which fields are required but Submit button is disabled.
If I use:
<script src="/media/js/jquery/1.3.2.jquery.min.js" type="text/javascript"></script>
Form is working with ajax 100% but I cant use Departure & Return are Date Picker Fields
(which give me choice to select date - I have to manually type it).
For reference I used this tutorial.
Look at the Category ModelForm Ajax
My question is I can I achieve this form to be working on 1.9.1 Jquery Version with also Date
picker Fields that I can choosed from the calendar.
At the bottom I am including screenshots.
Here is the code:
MODELS.PY
TRIP_TYPES = (
('one way', 'One Way'),
('round trip', 'Round Trip'),
('multi-leg', 'Multi-Leg'),
)
class Request_Quote(models.Model):
trip_type = models.CharField(max_length=10, choices=TRIP_TYPES, default='one way')
company_name = models.CharField(max_length=200)
individual_name = models.CharField(max_length=200)
phone = models.CharField(max_length=200)
email = models.CharField(max_length=200)
from_country = models.CharField(max_length=200)
to_country = models.CharField(max_length=200)
from_city = models.CharField(max_length=200)
to_city = models.CharField(max_length=200)
departure_date = models.CharField(max_length=200)
return_date = models.CharField(max_length=200)
number_of_passengers = models.CharField(max_length=200)
VIEWS.PY
def quote(request):
if request.method == "POST":
form = Request_QuoteForm(request.POST)
## Handle AJAX ##
if request.is_ajax():
if form.is_valid():
form.save()
# Get a list of Categories to return
quotes = Request_Quote.objects.all().order_by('individual_name')
# Create a dictionary for our response data
data = {
'error': False,
'message': 'Request Quote Added Successfully',
# Pass a list of the 'name' attribute from each Category.
# Django model instances are not serializable
'quotes': [q.individual_name for q in quotes],
}
else:
# Form was not valid, get the errors from the form and
# create a dictionary for our error response.
data = {
'error': True,
'message': "Please try again!",
'trip_type_error': str(form.errors.get('trip_type', '')),
'company_name_error': str(form.errors.get('company_name', '')),
'individual_name_error': str(form.errors.get('individual_name', '')),
'phone_error': str(form.errors.get('phone', '')),
'email_error': str(form.errors.get('email', '')),
'from_country_error': str(form.errors.get('from_country', '')),
'to_country_error': str(form.errors.get('to_country', '')),
'from_city_error': str(form.errors.get('from_city', '')),
'to_city_error': str(form.errors.get('to_city', '')),
'departure_date_error': str(form.errors.get('departure_date', '')),
'return_date_error': str(form.errors.get('return_date', '')),
'number_of_passengers_error': str(form.errors.get('number_of_passengers', '')),
}
# encode the data as a json object and return it
return http.HttpResponse(json.dumps(data))
if form.is_valid():
form.save()
return http.HttpResponseRedirect('/request-quote/')
else:
form = Request_QuoteForm()
quotes = Request_Quote.objects.all().order_by('individual_name')
return render_to_response('quote.html', {'title': 'Request Quote', 'form': form, 'quotes': quotes}, context_instance=RequestContext(request))
TEMPLATES:
<script type="text/javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
$("#add_cat").ajaxStart(function() {
// Remove any errors/messages and fade the form.
$(".form_row").removeClass('errors');
$(".form_row_errors").html('');
$("#add_cat").fadeTo('slow', 0.33);
$("#add_cat_btn").attr('disabled', 'disabled');
$("#message").addClass('hide');
});
// Submit the form with ajax.
$("#add_cat").submit(function(){
$.post(
// Grab the action url from the form.
"#add_cat.getAttribute('action')",
// Serialize the form data to send.
$("#add_cat").serialize(),
// Callback function to handle the response from view.
function(resp, testStatus) {
if (resp.error) {
// check for field errors
if (resp.trip_type_error != '') {
$("#trip_type_row").addClass('errors');
$("#trip_type_errors").html(resp.trip_type_error);
}
if (resp.company_name_error != '') {
$("#company_name_row").addClass('errors');
$("#company_name_errors").html(resp.company_name_error);
}
if (resp.individual_name_error != '') {
$("#individual_name_row").addClass('errors');
$("#individual_name_errors").html(resp.individual_name_error);
}
if (resp.phone_error != '') {
$("#phone_row").addClass('errors');
$("#phone_errors").html(resp.phone_error);
}
if (resp.email_error != '') {
$("#email_row").addClass('errors');
$("#email_errors").html(resp.email_error);
}
if (resp.from_country_error != '') {
$("#from_country_row").addClass('errors');
$("#from_country_errors").html(resp.from_country_error);
}
if (resp.to_country_error != '') {
$("#to_country_row").addClass('errors');
$("#to_country_errors").html(resp.to_country_error);
}
if (resp.from_city_error != '') {
$("#from_city_row").addClass('errors');
$("#from_city_errors").html(resp.from_city_error);
}
if (resp.to_city_error != '') {
$("#to_city_row").addClass('errors');
$("#to_city_errors").html(resp.to_city_error);
}
if (resp.departure_date_error != '') {
$("#departure_date_row").addClass('errors');
$("#departure_date_errors").html(resp.departure_date_error);
}
if (resp.return_date_error != '') {
$("#return_date_row").addClass('errors');
$("#return_date_errors").html(resp.return_date_error);
}
if (resp.number_of_passengers_error != '') {
$("#number_of_passengers_row").addClass('errors');
$("#number_of_passengers_errors").html(resp.number_of_passengers_error);
}
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").attr('disabled', false);
} else {
// No errors. Rewrite the category list.
$("#categories").fadeTo('fast', 0);
var text = new String();
for(i=0; i<resp.quotes.length ;i++){
var m = resp.quotes[i]
text += "<li>" + m + "</li>"
}
$("#categories").html(text);
$("#categories").fadeTo('slow', 1);
$("#id_trip_type").attr('value', '');
$("#id_company_name").attr('value', '');
$("#id_individual_name").attr('value', '');
$("#id_phone").attr('value', '');
$("#id_email").attr('value', '');
$("#id_from_country").attr('value', '');
$("#id_to_country").attr('value', '');
$("#id_from_city").attr('value', '');
$("#id_to_city").attr('value', '');
$("#id_departure_date").attr('value', '');
$("#id_return_date").attr('value', '');
$("#id_number_of_passengers").attr('value', '');
}
// Always show the message and re-enable the form.
$("#message").html(resp.message);
$("#message").removeClass('hide');
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").attr('disabled', '');
// Set the Return data type to "json".
}, "json");
return false;
});
});
</script>
<div id="content" class="span9" style="">
<h1>Request Quote</h1>
<div id='message'></div>
<form id='add_cat' method='post' action='.'><input type='hidden' name='csrfmiddlewaretoken' value='KblPqgczzMK7skak162xe4aOL6bLot2A' />
<div class='form_row' id='trip_type_row'>
<div class="span2">
<label for="id_trip_type">Trip type</label>
</div>
<div class="span4">
<select id="id_trip_type" name="trip_type">
<option value="one way" selected="selected">One Way</option>
<option value="round trip">Round Trip</option>
<option value="multi-leg">Multi-Leg</option>
</select>
</div>
<div class="span6">
<p id='trip_type_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='company_name_row'>
<div class="span2">
<label for="id_company_name">Company name</label>
</div>
<div class="span4">
<input id="id_company_name" maxlength="200" name="company_name" type="text" />
</div>
<div class="span6">
<p id='company_name_errors' class="form_row_errors" style="color: red;"></p>
</div>
</div>
<div class='form_row' id='individual_name_row'>
<div class="span2">
<label for="id_individual_name">Individual name</label>
</div>
<div class="span4">
<input id="id_individual_name" maxlength="200" name="individual_name" type="text" />
</div>
<div class="span6">
<p id='individual_name_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='phone_row'>
<div class="span2">
<label for="id_phone">Phone</label>
</div>
<div class="span4">
<input id="id_phone" maxlength="200" name="phone" type="text" />
</div>
<div class="span6">
<p id='phone_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='email_row'>
<div class="span2">
<label for="id_email">Email</label>
</div>
<div class="span4">
<input id="id_email" maxlength="200" name="email" type="text" />
</div>
<div class="span6">
<p id='email_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='from_country_row'>
<div class="span2">
<label for="id_from_country">From country</label>
</div>
<div class="span4">
<input id="id_from_country" maxlength="200" name="from_country" type="text" />
</div>
<div class="span6">
<p id='from_country_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='to_country_row'>
<div class="span2">
<label for="id_to_country">To country</label>
</div>
<div class="span4">
<input id="id_to_country" maxlength="200" name="to_country" type="text" />
</div>
<div class="span6">
<p id='to_country_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='from_city_row'>
<div class="span2">
<label for="id_from_city">From city</label>
</div>
<div class="span4">
<input id="id_from_city" maxlength="200" name="from_city" type="text" />
</div>
<div class="span6">
<p id='from_city_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='to_city_row'>
<div class="span2">
<label for="id_to_city">To city</label>
</div>
<div class="span4">
<input id="id_to_city" maxlength="200" name="to_city" type="text" />
</div>
<div class="span6">
<p id='to_city_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='departure_date_row'>
<div class="span2">
<label for="id_departure_date">Departure date</label>
</div>
<div class="span4">
<input id="id_departure_date" maxlength="200" name="departure_date" type="text" />
</div>
<div class="span6">
<p id='departure_date_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='return_date_row'>
<div class="span2">
<label for="id_return_date">Return date</label>
</div>
<div class="span4">
<input id="id_return_date" maxlength="200" name="return_date" type="text" />
</div>
<div class="span6">
<p id='return_date_errors' class="form_row_errors"></p>
</div>
</div>
<div class='form_row' id='number_of_passengers_row'>
<div class="span2">
<label for="id_number_of_passengers">Number of passengers</label>
</div>
<div class="span4">
<input id="id_number_of_passengers" maxlength="200" name="number_of_passengers" type="text" />
</div>
<div class="span6">
<p id='number_of_passengers_errors' class="form_row_errors"></p>
</div>
</div>
<input id="add_cat_btn" type='submit' value="save">
</form>
</div><!-- End content -->
Screenshots:
These are images with not functional after Submission Form Submit button but Date Picker
Fields are working becasue Jquery 1.9.1 was used:
Screen 1:
Screen 2:
This is an image with not functional Date Picker because Jquery 1.3.2 was used and Submit
Button is enabled after submision:
Thanks for help.
I managed to solve the problem, the problem was with the newest jquery using different variables. Updated the code above with the answer.
Here is the code:
TEMPLATES:
<script type="text/javascript">
// prepare the form when the DOM is ready
$(document).ready(function() {
$("#add_cat").ajaxStart(function() {
// Remove any errors/messages and fade the form.
$(".form_row").removeClass("errors");
$(".form_row_errors").html('');
$("#add_cat").fadeTo('slow', 0.33);
$("#add_cat_btn").attr("disabled", "disabled");
$("#message").addClass('hide');
});
// Submit the form with ajax.
$("#add_cat").submit(function(){
$.post(
// Grab the action url from the form.
"#add_cat.getAttribute('action')",
// Serialize the form data to send.
$("#add_cat").serialize(),
// Callback function to handle the response from view.
function(resp, testStatus) {
$(".form_row").removeClass("errors");
$("#trip_type_errors").html("");
$("#company_name_errors").html("");
$("#individual_name_errors").html("");
$("#phone_errors").html("");
$("#email_errors").html("");
$("#from_country_errors").html("");
$("#to_country_errors").html("");
$("#from_city_errors").html("");
$("#to_city_errors").html("");
$("#departure_date_errors").html("");
$("#return_date_errors").html("");
$("#number_of_passengers_errors").html("");
if (resp.error) {
// check for field errors
if (resp.trip_type_error != '') {
$("#trip_type_row").addClass('errors');
$("#trip_type_errors").html(resp.trip_type_error);
}
if (resp.company_name_error != '') {
$("#company_name_row").addClass('errors');
$("#company_name_errors").html(resp.company_name_error);
}
if (resp.individual_name_error != '') {
$("#individual_name_row").addClass('errors');
$("#individual_name_errors").html(resp.individual_name_error);
}
if (resp.phone_error != '') {
$("#phone_row").addClass('errors');
$("#phone_errors").html(resp.phone_error);
}
if (resp.email_error != '') {
$("#email_row").addClass('errors');
$("#email_errors").html(resp.email_error);
}
if (resp.from_country_error != '') {
$("#from_country_row").addClass('errors');
$("#from_country_errors").html(resp.from_country_error);
}
if (resp.to_country_error != '') {
$("#to_country_row").addClass('errors');
$("#to_country_errors").html(resp.to_country_error);
}
if (resp.from_city_error != '') {
$("#from_city_row").addClass('errors');
$("#from_city_errors").html(resp.from_city_error);
}
if (resp.to_city_error != '') {
$("#to_city_row").addClass('errors');
$("#to_city_errors").html(resp.to_city_error);
}
if (resp.departure_date_error != '') {
$("#departure_date_row").addClass('errors');
$("#departure_date_errors").html(resp.departure_date_error);
}
if (resp.return_date_error != '') {
$("#return_date_row").addClass('errors');
$("#return_date_errors").html(resp.return_date_error);
}
if (resp.number_of_passengers_error != '') {
$("#number_of_passengers_row").addClass('errors');
$("#number_of_passengers_errors").html(resp.number_of_passengers_error);
}
} else {
// No errors. Rewrite the category list.
$("#categories").fadeTo('fast', 0);
var text = new String();
for(i=0; i<resp.quotes.length ;i++){
var m = resp.quotes[i]
text += "<li>" + m + "</li>"
}
$("#categories").html(text);
$("#categories").fadeTo('slow', 1);
$("#id_trip_type").val("");
$("#id_company_name").val("");
$("#id_individual_name").val("");
$("#id_phone").val("");
$("#id_email").val("");
$("#id_from_country").val("");
$("#id_to_country").val("");
$("#id_from_city").val("");
$("#id_to_city").val("");
$("#id_departure_date").val("");
$("#id_return_date").val("");
$("#id_number_of_passengers").val("");
}
// Always show the message and re-enable the form.
$("#message").html(resp.message);
$("#message").removeClass('hide');
$("#add_cat").fadeTo('slow', 1);
$("#add_cat_btn").removeAttr("disabled");//attr('disabled', '');
// Set the Return data type to "json".
}, "json");
return false;
});
});
</script>