I have a form control in some directive. I am resetting object data to its original state but it is not working in the $scope.on event. If I use it outside in some function it works.
$scope.$on('edit_view_changed', function (event, parameters) {
if (parameters.viewName === "" && parameters.editIndex === -1) {
vm.resetData();
// this reset data is not working
}
});
function resetData() {
vm.rowData = angular.copy(vm.data);
}
// works properly on cancel button click
function cancelEdit() {
vm.resetData();
$timeout(function () {
vm.editCancelProspect();
});
}
// RowData is bind to a form in a html view.
<form class="col-md-12" name="editForm" novalidate>
<div class="col-md-10">
<div class="form-group col-md-3">
<label class="col-sm-3 control-label">{{'customers.columns.companyName'|translate}}</label>
<input type="text" name="name" class="form-control" ng-model="vm.rowData.name"></input>
</div>
<div class="form-group col-md-4">
<label class="col-sm-3 control-label">{{'customers.columns.address'|translate}}</label>
<input type="text" name="adresse" class="form-control" ng-model="vm.rowData.adresse"></input>
</div>
<div class="form-group col-md-3">
<label class="col-sm-3 control-label">{{'customers.columns.contactPerson'|translate}}</label>
<input type="text" name="kontakt" class="form-control" ng-model="vm.rowData.companyContact"></input>
</div>
<div class="form-group col-md-2 ">
<label class="col-sm-3 control-label">{{'customers.columns.phone'|translate}}</label>
<input type="text" name="phone" class="form-control" ng-model="vm.rowData.phone" ng-pattern="/^\d+$/"></input>
<span ng-show="editForm.phone.$error.pattern" class="error">{{'customers.inValidPhone' | translate}}</span>
</div>
</div>
<button type="button" class="btn cancel-button" title="{{'prospects.cancelEdit'|translate}}" ng-click="vm.cancelEdit()">
{{'prospects.cancelEdit'|translate}}</button>
</form>
Related
I'm trying to create multiple form under tabs with previous tab data been used in the next tab and each form has a save button which saves the data for the next tab using angularjs. Everything is working fine with code. All of the form data is added to single field in the model which is a JSONField. Except I have a form which has a file field usually images I am stuck with the upload of these images to the json field.
var app = angular.module('app', []);
app.controller('enviromentController', function ($scope, $http) {
$scope.saveEnvironment = function () {
$http({
method: 'PUT',
"url": "{% url 'core:api:edit-environement' env_id=env_id %}",
"data": angular.copy($scope.env),
"headers": {
"accept": "application/json",
"content-type": "application/json",
"Authorization": "Token " + localStorage.getItem('token')
}
}).then(function () {
inform("Saved", "Published data");
});
this is my form
<div class="tab-content" id="myTabContent" style="min-height:375px">
<div class="tab-pane active" id="environment" role="tabpanel" aria-labelledby="environment-tab">
<div class="form-group col-lg-5">
<label class="form-control-label">Title </label>
<input type="text" class="form-control" ng-model="env.title" required />
</div>
<div class="form-group col-lg-5">
<label class="form-control-label">Department</label>
<select class="form-control" ng-model="env.department"
ng-options="c.id as c.name for c in departments" required>
</select>
</div>
<div class="form-group col-lg-5">
<label class="form-control-label" for="appname">App Name</label>
<select class="form-control" ng-model="env.app_name"
ng-options="c.id as c.name for c in app_name" required>
</select>
</div>
</div>
<div class="tab-pane" id="room" role="tabpanel" aria-labelledby="room-tab">
<div class="row">
<div class="form-group col-lg-4">
<label class="form-control-label">Name</label>
<input type="text" class="form-control" ng-model="env.json_data1.room.name" />
</div>
<div class="form-group col-lg-4">
<label class="form-control-label">Height </label>
<input type="text" class="form-control" ng-model="env.json_data1.room.height" />
</div>
<div class="form-group col-lg-4">
<label class="form-control-label">Width </label>
<input type="text" class="form-control" ng-model="env.json_data1.room.width" />
</div>
<div class="form-group col-lg-5">
<label class="form-control-label">Length </label>
<input type="text" class="form-control" ng-model="env.json_data1.room.length" />
</div>
<div class="form-group col-lg-5">
<label class="form-control-label">Texture </label>
<input type="text" class="form-control" ng-model="env.json_data1.room.texture" />
</div>
<div class="form-group col-lg-5">
<label class="form-control-label">Room Image </label>
<input type="file" class="dropify"
file-model="env.json_data1.room.room_floorplan" accept="image/*" />
</div>
<div class="form-group col-lg-5">
<label class="form-control-label">Floorplan </label>
<input type="file" class="dropify"
accept="image/*" />
</div>
<div class="form-group col-lg-2 p-4">
<label class="form-control-label"> </label>
<button type="button" ng-click="addRoom(env.json_data1.room)"
class="btn btn-primary">{{env.json_data1.room.stage||'Add'}}</button>
</div>
<table class="table">
<tr>
<th>Name</th>
<th>Texture</th>
<th>Size</th>
<th>Actions</th>
</tr>
<tr ng-repeat="room in env.json_data1.rooms">
<td>{{room.name}}</td>
<td>{{room.texture}}</td>
<td>{{room.height}} x {{room.width}} x {{room.length}}</td>
<th><button type="button" ng-click="editRoom(room)">Edit</button></th>
</tr>
</table>
</div>
</div>
$scope.addRoom = function (rec) {
if (!rec.stage) {
rec.stage = 'Update';
$scope.env.json_data1.rooms.push(rec);
}
$scope.env.json_data1.room = {};
}
I'm getting set of data by calling a GET method in angularjs.
controller
$scope.edit = function (id) {
var edit_url = 'http://localhost/AwtCW2012002/api/restApiController/editQuestion.json?question_id=' + id;
$http.get(edit_url)
.success(function (data) {
console.log(data);
})
.error(function () {
})
};
Data from the GET method is like follows
How can I pass the data into respective fields in my view (into placeholders, as this view is used to edit existing data)
view
<div class="container" ng-controller="questionEditCtrl">
<form class="form-horizontal" role="form" name='quizAdd' ng-submit="submit(data)">
<div class="form-group">
<label class="control-label col-sm-2" for="question">Question:</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="question" ng-model="data.question" placeholder="Enter Question">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer1">Answer 1:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer1" ng-model="data.ans1" id="answer1" placeholder="Enter Answer 1">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer2">Answer 2:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer2" ng-model="data.ans2" id="answer2" placeholder="Enter Answer 2">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer3">Answer 3:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer3" ng-model="data.ans3" id="answer4" placeholder="Enter Answer 3">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer4">Answer 4:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer4" id="answer4" ng-model="data.ans4" placeholder="Enter Answer 4">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="answer5">Answer 5:</label>
<div class="col-sm-10">
<input type="text" class="form-control" name="answer5" id="answer5" ng-model="data.ans5" placeholder="Enter Answer 5">
</div>
</div>
<div class="form-group">
<label class="control-label col-sm-2" for="sel1">Select Correct Answer:</label>
<div class="col-sm-10">
<select class="form-control" ng-model="data.correct_ans" id="sel1">
<option>{{data.ans1}}</option>
<option>{{data.ans2}}</option>
<option>{{data.ans3}}</option>
<option>{{data.ans4}}</option>
<option>{{data.ans5}}</option>
</select>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
</div>
You are getting the response in array. Use ng-repeat to render you fields. What you perform ng-repeat, you can add placeholder like,
placeholder="Write Answer {{$index}}"
Firstly, populate a $scope variable with the data from the api for it to be available for binding in the template:
$http.get(edit_url)
.success(function (data) {
$scope.data = data; //populate a scope variable
})
.error(function () {
});
Then, you can use one time expressions :: for your placeholders as follows:
placeholder="{{::data.ans1}}"
This will ensure only the default value of data.ans1 which was fetched from the api will be used as the placeholder. All subsequent changes to data.ans1 will change the value, but the placeholder will remain the same.
I am trying to submit a simple contact form. The form is inside a bootstrap modal (don't think that makes any difference) but the controller is in a directive.
The html for the form is as followed:
<form name="contactForm" ng-submit="contactForm()" novalidate>
<div class="form-group">
<div class="col-lg-6 col-md-6 col-sm-6">
<input type="text" placeholder="Full name" name="name" ng-minlength="3" max="20"
ng-model="name" id="name" class="form-control">
</div>
<div class="col-lg-6 col-md-6 col-sm-6">
<input type="email" ng-minlength="4" placeholder="Email address" name="contactEmail"
ng-model="email" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-lg-12 col-md-12 col-sm-12">
<input type="text" ng-model="subject" name="subject" ng-minlength="10" id=""
placeholder="Subject" class="form-control">
</div>
</div>
<div class="form-group">
<div class="col-lg-12 col-md-12 col-sm-12">
<textarea class="form-control" ng-model="message" name="message" ng-minlength="10"
placeholder="Your message"></textarea>
</div>
</div>
<div class="modal-footer">
<div class="col-lg-12 col-md-12 col-sm-12">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<input type="submit" class="btn btn-primary" value="Submit" />
</div>
</div>
</form>
Which i think is all good. The body of my controller looks like this
$rootScope.contactForm = contactForm();
function contactForm() {
console.log('triggered!');
var contactFormVars = {
name: $rootScope.name,
contactEmail: $rootScope.contactEmail,
subject: $rootScope.subject,
message: $rootScope.message
}
// With Promise
Stamplay.Object('contactform')
.save(contactFormVars)
.then(function(res) {
console.log('yes!');
}, function(err) {
console.log('No!');
})
}
return directive;
};
EDIT: Controller now looks like this:
function contactForm($rootScope,$stamplay,$q) {
$rootScope.data = {}
$rootScope.data = {
name: $rootScope.data.name,
contactemail: $rootScope.data.contactemail,
subject: $rootScope.data.subject,
message: $rootScope.data.message
}
Stamplay.Object("contactform")
.save($rootScope.data, function (err, res) {
console.log(res);
console.log(err);
// res is the new car object
});
}
When i click the submit button I get the following error which i've been Googling
Error: v2.contactForm is not a function. (In 'v2.contactForm()', 'v2.contactForm' is an instance of FormController)
fn
Any help with this is appreciated.
EDIT
Ok so now i've moved the js from a directive and placed it in to the main controller. At the moment its not making any difference, only that the error has changed very slightly:
angular.js:12722Error: v4.contactForm is not a function. (In 'v4.contactForm(ensureSafeObject(v5,text))', 'v4.contactForm' is an instance of FormController)
fn
Not sure what the difference between v2 and v4 is.
Any advice to get past this blocker is appreciated.
Trying to learn Angular ... and
I'm missing something really obvious here, I'm sure of it. However, all of the examples, fiddles or plunkers I'm finding deal with validating create forms, not update forms.
My application is creating a modal form to add/edit client data. If a valid clientId is passed in, the form is opened as an edit and the data is loaded into the form.
When I load the values, I'm only assigning the value to the modal's property. Since its only a value, it doesn't have an $invalid function or any of the other nice form methods. Without that, the validation doesn't work. What's the proper way to load data into a form in Angular so that it can be validated? Thanks!
angular.module('app').controller("clientController",
function ($scope, $modalInstance, dataService, clientId) {
$scope.clientForm = {}
$scope.clientForm.clientId = clientId;
$modalInstance.opened.then(function () {
if (clientId > 0) {
dataService.getClient(clientId).then(function (clientData) {
$scope.clientForm.name = clientData.Name;
$scope.clientForm.address1 = clientData.Address1;
$scope.clientForm.address2 = clientData.Address2;
$scope.clientForm.city = clientData.City;
$scope.clientForm.stateId = clientData.StateId;
$scope.clientForm.zip = clientData.Zip;
$scope.clientForm.email = clientData.Email;
});
};
});
$scope.ok = function () {
$scope.clientForm.$submitted = true;
if ($scope.clientForm.$valid) {
$modalInstance.close($scope.clientForm);
}
};
$scope.cancel = function () {
$modalInstance.dismiss('cancel');
};
}
)
And for the form:
<script type="text/ng-template" id="ClientEdit.html">
<div class="modal-header">
<h3 class="modal-title"><span>Client</span></h3>
</div>
<div class="modal-body col-md-12">
<form name="clientForm" novalidate>
<div class="form-group col-md-12">
<label class="col-md-2 control-label text-right" for="txtclientName">Name: </label>
<div class="col-md-6"><input class="form-control input-sm" id="txtclientName" type="text" ng-model="clientForm.name" required /></div>
<p ng-show="clientForm.name.$invalid">Name is required.</p>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label text-right" for="txtAddressLine1">Address 1: </label>
<div class="col-md-6"><input class="form-control input-sm" id="txtAddressLine1" type="text" ng-model="clientForm.address1" /></div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label text-right" for="txtAddressLine2">Address 2: </label>
<div class="col-md-6"><input class="form-control input-sm" id="txtAddressLine2" type="text" ng-model="clientForm.address2" /></div>.
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label text-right" for="txtCity">City: </label>
<div class="col-md-2"><input class="form-control input-sm" id="txtCity" type="text" ng-model="clientForm.city" /></div>
<label class="col-md-1 control-label text-right" for="txtZip">Zip: </label>
<div class="col-md-2"><input class="form-control input-sm" id="txtZip" type="text" ng-model="clientForm.zip" /></div>
</div>
<div class="form-group col-md-12">
<label class="col-md-2 control-label text-right" for="txtEmail">Email: </label>
<div class="col-md-6"><input class="form-control input-sm" id="txtEmail" type="email" ng-model="clientForm.email" /></div>
</div>
</form>
</div>
<div class="modal-footer">
<button class="btn btn-primary" ng-click="ok()" ng-disabled="clientForm.$invalid">Save</button>
<button class="btn btn-warning" ng-click="cancel()">Cancel</button>
</div>
</script>
Maybe I'm using model binder incorrectly or maybe marionette interferes, but my view and model don't seem to be communicating and therefore not pre-filling my template fields
View
define([
'marionette',
'underscore',
'text!app/views/templates/user/form.html',
'app/models/user'
],
function (Marionette, _, Template, Model) {
"use strict"
return Marionette.ItemView.extend({
events: {
'submit .edit-user-form': 'onClickSave'
},
initialize: function(options) {
/* initiate model binder */
Backbone.ModelBinder.bind(Model, this.$el)
/* create empty model in case its a create request */
this.model = new Model()
/* if the options.id is passed then lets load an instance of the model */
if (options && options.id) {
this.model = new Model({id: options.id})
this.model.set('id', options.id)
/* set that to this so its acceptable inside the fetch */
var that = this
this.model.fetch({
/* fetch request successful */
success: function (response) {
/* set the model instance trigger a re-render */
that.model = response
that.render()
},
/* we couldn't load the model so we go back to the users list */
error: function () {
alert('User could not be loaded, redirecting you to the users list')
window.location.hash = 'users'
}
})
}
},
/* save button triggered so prevent default and trigger the model to save */
onClickSave: function (ev) {
ev.preventDefault()
this.model.save({}, {
success: function (response) {
console.log(response, 'response')
}
})
},
/* render the form */
render: function () {
var html = _.template($(Template).html(), this.model.toJSON())
this.$el.html(html)
return this
}
})
}
)
Template
<script type="text/template" id="userFormTemplate">
<div id="userForm">
<h2><img src="/img/icons/32/update.png" /> Update User</h2>
<h2><img src="/img/icons/32/create.png" /> Create New User</h2>
<form class="edit-user-form">
<fieldset name="personal" class="halfWidth left">
<legend>Personal Details:</legend>
<div class="control-group">
<label class="control-label">First name:</label>
<div class="controls">
<input type="text" name="first_name" id="first_name">
</div>
</div>
<div class="control-group">
<label class="control-label">Last name:</label>
<div class="controls">
<input type="text" name="last_name" id="last_name">
</div>
</div>
<div class="control-group">
<label class="control-label">Birthdate:</label>
<div class="controls">
<input type="date" name="birthdate" id="birthdate">
</div>
</div>
</fieldset>
<fieldset name="job" class="halfWidth right">
<legend>Job Details:</legend>
<div class="control-group">
<label class="control-label">Job Title</label>
<div class="controls">
<input type="text" name="job_title" id="job_title">
</div>
</div>
<div class="control-group">
<label class="control-label">Start Date:</label>
<div class="controls">
<input type="date" name="job_start_date" id="job_start_date">
</div>
</div>
<div class="control-group">
<label class="control-label">Probation Ends:</label>
<div class="controls">
<input type="date" name="job_probation_ends" id="job_probation_ends">
</div>
</div>
</fieldset>
<div class="clearfix"></div>
<br />
<fieldset name="personal" class="halfWidth left">
<legend>Work Details:</legend>
<div class="control-group">
<label class="control-label">Work Email</label>
<div class="controls">
<input type="email" name="work_email" id="work_email">
</div>
</div>
<div class="control-group">
<label class="control-label">Work Address:</label>
<div class="controls">
<input type="text" name="work_address" id="work_address">
</div>
</div>
<div class="control-group">
<label class="control-label">Work Phone Number:</label>
<div class="controls">
<input type="text" name="work_phone_number" id="work_phone_number">
</div>
</div>
</fieldset>
<fieldset name="personal" class="halfWidth right">
<legend>Personal Details:</legend>
<div class="control-group">
<label class="control-label">Personal Email</label>
<div class="controls">
<input type="email" name="personal_email" id="personal_email">
</div>
</div>
<div class="control-group">
<label class="control-label">Home Address:</label>
<div class="controls">
<input type="text" name="personal_address" id="personal_address">
</div>
</div>
<div class="control-group">
<label class="control-label">Home Phone Number:</label>
<div class="controls">
<input type="text" name="personal_phone_number" id="personal_phone_number">
</div>
</div>
</fieldset>
<div class="clearfix"></div>
<br />
<div class="control-group button">
<button class="btn save-form btn-success" type="submit">Create User</button>
</div>
</form>
</div>
</script>
You have to define the bindings, its not automatic.
var bindings = {
first_name: '#first_name',
last_name: '#last_name',
birthdate: '#birthdate',
job_title: '#job_title',
job_start_date: '#job_start_date',
job_probation_ends: '#job_probation_ends',
work_email: '#work_email',
work_address: '#work_address',
work_phone_number: '#work_phone_number',
personal_email: '#personal_email',
personal_address: '#personal_address',
personal_phone_number: '#personal_phone_number'
}