Backbone js button click event not firing - javascript

I have an ajax function on the initialize of the main router that seems to hinder the event of my signin button in signin.js. When I click the signin button, it doesn't perform its function, instead the browser places the inputs on the URL, (i.e. username and password).
But when I remove the ajax function on the initialize, I can successfully log in.
I've included some of the codes I'm working on. Thanks
main.js
initialize: function(){
$.ajax({
type: "GET",
url: "something here",
contentType: "application/json",
headers: {
'someVar': something here
},
statusCode: {
404: function() {
console.log('404: logged out');
if (!this.loginView) {
this.loginView = new LoginView();
}
$('.pagewrap').html(this.loginView.el);
},
200: function() {
console.log('200');
if (!this.homeView) {
this.homeView = new HomeView();
}
$('.pagewrap').html(this.homeView.el);
}
}
});
// return false;
},
signin.js
var SigninView = Backbone.View.extend ({
el: '#signin-container',
events: {
"click #btn-signin" : "submit"
},
submit: function () {
console.log('signin');
$.ajax({ ... });
return false;
}
});
var toSignin = new SigninView();
window.anotherSigninView = Backbone.View.extend({
initialize: function() {},
render: function() {}
});
home.js
window.HomeView = Backbone.View.extend ({
initialize: function() {
this.render();
},
render: function() {
$(this.el).html( this.template() );
return this;
}
});
some html
<form id="signin-container">
<table id="tbl-signin">
<tr>
<td><div class="input-box"><input class="input-text" type="text" name="username" placeholder="Username"></div></td>
<td><div class="input-box"><input class="input-text" type="password" name="password" placeholder="Password"></div></td>
<td><input id="btn-signin" class="button" value="Sign In"></td>
</tr>
<tr>
<td class="opt"><input class="checkbox" type="checkbox" name="rememberMe" value="true"><label class="opt-signin">Remember Me?</label></td>
<td class="opt"><a class="opt-signin" href="#">Forgot Password?</a></td>
<td></td>
</tr>
</table>
</form>

You need to prevent the default behaviour of the submit button in your click handler. You can do this like so:
var SigninView = Backbone.View.extend ({
el: '#signin-container',
events: {
"click #btn-signin" : "submit"
},
submit: function (event) {
event.preventDefault();
console.log('signin');
$.ajax({ ... });
}
});
Alternatively, you might consider using the html button element which won't attempt to submit the form it's associated with.

Ok, I figured out what's your problem :)
Here is an example that resumes your code jsfiddle.net/26xf4/6. The problem is that you don't call new SigninView(); (instantiate the view) hence its events are never bound.
So, in this example try to uncomment the ligne 43 and your code will work as expected, because when you instantiate a View (new SigninView()) its constructor calls the delegateEvents() function (you don't see this in your code, it's in the backbone.js) enabling the events you declare in your view :
events: {
"click #btn-signin" : "submit"
},

I don't know about your HTML mockup, my best guess is that you are catching the incorrect event here. If you are submitting a form, you should catch submit form event not click #some-button. Because even if you catch click event of button inside a form and return false, the form will be still submitted because those are 2 different events

Related

Kendo UI javascript : remote bind form

I'm having trouble getting started with binding a Form to a remote Datasource in Kendo UI for javascript
I have verified that the ajax call returns the correct JSONP payload, e.g:
jQuery31006691693527470279_1519697653511([{"employee_id":1,"username":"Chai"}])
Below is the code:
<script type="text/javascript">
$(document).ready(function() {
var viewModel = kendo.observable({
employeeSource: new kendo.data.DataSource({
transport: {
read: {
url: baseUrl + "/temp1",
dataType: "jsonp"
},
parameterMap: function(options, operation) {
if (operation !== "read" && options.models) {
return {
models: kendo.stringify(options.models)
};
}
return options;
}
},
batch: true,
schema: {
model: {
id: "employee_id",
fields:{
employee_id: { type: "number" },
username: { type: "string" }
}
}
}
}),
hasChanges: false,
save: function() {
this.employeeSource.sync();
this.set("hasChanges", false);
},
change: function() {
this.set("hasChanges", true);
}
});
kendo.bind($("#item-container"), viewModel);
viewModel.employeeSource.read();
});
</script>
<div id="item-container">
<div class="row">
<div class="col-xs-6 form-group">
<label>Username</label>
<input class="form-control k-textbox" type="text" id="username" data-bind="value: username, events: { change: change }" />
</div>
</div>
<button data-bind="click: save, enabled: hasChanges" class="k-button k-primary">Submit All Changes</button>
</div>
No errors are thrown, but I was expecting my username text form field to be populated with the value 'Chai', and so on.. but it doesn't
Your textbox is bound to a username property but this doesn't exist on your view-model, nor is it being populated anywhere. Assuming your datasource correctly holds an employee after your call to read(), you will need to extract it and set it into your viewmodel using something like this:
change: function(e) {
var data = this.data();
if (data.length && data.length === 1) {
this.set("employee", data[0]);
this.set("hasChanges", true);
}
}
And modify the binding(s) like this:
<input class="form-control k-textbox" type="text" id="username"
data-bind="value: employee.username, events: { change: change }" />
You should also be aware that the change event is raised in other situations, so if you start using the datasource to make updates for example, you'll need to adapt that code to take account of the type of request. See the event documentation for more info. Hope this helps.

Backbone View showing then disappearing

I have a view created with Backbone.js and inserted into a div element - it shows for about a second and then disappears.
Here is my code for the view:
var addPlayerView = Backbone.View.extend({
tagName: "div",
model: Player,
id: 'addPlayerDiv',
initialize: function() {
console.log('addPlayerView has been created');
},
render: function (){
this.$el.html('<p>show this puppy</p>');
return this;
}
});
here is the model:
var Player = Backbone.Model.extend({
defaults: {
ID: "",
firstName: '',
lastName: ''
},
idAttribute: "ID"
});
and here is the HTML:
<form onsubmit="addNewPlayer();">
<input type="submit" value="Add New Player New"/>
</form>
<p>
<div id="addPlayerDiv"></div>
</p>
<script>
function addNewPlayer() {
var player = new Player({});
var newPlayerView = new addPlayerView({el: $("#addPlayerDiv"), model: player});
newPlayerView.render();
};
</script>
The addNewPlayer() function is being called correctly and the newPlayerView is rendering on the page, but only for a second, then it disappears on the page.
No idea what to do. Anyone have this problem before?
You need cancel the default action (in our case onsubmit tries send data to server)
<form onsubmit="addNewPlayer(); return false;">
or
<form onsubmit="addNewPlayer(event);">
function addNewPlayer(e) {
e.preventDefault();
.....
}
Example

Backbone JS: Issue related to click event and POST request

I am new to Backbone and just finished a simple get request. Trying to implement a simple POST request.
Use case:
When user clicks on Transfer button input field values will be sent to a REST API as a JSON object.
<div id="transfer">
<input type="text" placeholder="From Address" id="fromAddress" />
<input type="text" placeholder="To Address" id="toAddress" />
<input type="text" placeholder="Amount" id="dollars" />
<input type="button" id="button" value="Transfer"/>
</div>
Issue 1
First problem is that what will go into the Backbone View.
My Backbone View:
var TransferView = Backbone.View.extend({
events: {
"click #button": "sendMoney"
},
sendMoney: function() {
alert();
console.log($("#fromAddress").val());
//this.model.transferMoney($("#fromAddress").val(),
$("#toAddress").val(), $("#dollars").val());
}
});
var transferView = new TransferView();
transferView.render();
When I click on button nothing happens. What is the issue here?
Issue 2
Backbone Model looks like this.
var Money = Backbone.Model.extend({
url: 'http://localhost:3000/sendMoney',
defaults: {
fromAddress: "",
toAddress: "",
amount: ""
},
transferMoney: function(request, response) {
//get field values?
this.save();
}
});
var transferMoney = new Money();
Flow didn't reach the model yet, but I am not sure how would I fetch fromAddress, toAddress and amount values from req? How would I pass the request parameters in JSON format to REST service?
Note: Can not use form here. It is more like a ajax request.
The issues with your view are :
you're missing a template
you have a syntax error in $("#toAddress").val(), $("#dollars").val());
Since the view doesn't have a template, nothing gets displayed and therefore there is no "#button" to attach events to. Also, don't forget you'll typicallly need to provide a Money model instance to the view, so that you can then set attributes on it.
To pass value from the form, just use the val() method.
And to send data to the API, you just need to save: Backbone does the rest.
Basically, what you probably want to have is something like
var TransferView = Backbone.View.extend({
events: {
"click #button": "sendMoney"
},
sendMoney: function() {
this.model.save({
fromAddress: $("#fromAddress").val(),
toAddress: $("#toAddress").val(),
amount: $("#dollars").val(),
});
}
});
And to instanciate the view:
var money = new Money();
var transferView = new TransferView({ model: money });
It would probably be a good investment of your time to read a few Backbone tutorials, such as http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/
To delegate saving to a model method, do something like:
var Money = Backbone.Model.extend({
url: 'http://localhost:3000/sendMoney',
defaults: {
fromAddress: "",
toAddress: "",
amount: ""
},
transferMoney: function(attributes) {
this.save(attributes);
}
});
var TransferView = Backbone.View.extend({
events: {
"click #button": "sendMoney"
},
sendMoney: function() {
this.model.transferMoney({
fromAddress: $("#fromAddress").val(),
toAddress: $("#toAddress").val(),
amount: $("#dollars").val(),
});
}
});

call service rest on click with Backbone

I want to call a rest service (post) when I press on the button login but it doesn't launch any service it just add a "?" at the end of the url of my application.
here is my js :
(function ($) {
var authentication = Backbone.Model.extend({
defaults: {
Username: "",
Password: ""
},
url:'../../rest/login'
});
var LoginView = Backbone.View.extend({
model: new authentication(),
el: $("#login-form"),
events: {
"click button#login": "login"
},
login: function(){
alert("ici");
this.model.save({username: this.$el.find("#inUser")}, {
password: this.$el.find("#inPswd")}, {
success: function() {
/* update the view now */
},
error: function() {
/* handle the error code here */
}
});
}
})
})
(jQuery);
And here is my form :
<form class="form-inline">
<div class="form-group">
<input type="text" class="form-control" placeholder="Username" id="inUser"></input>
<input type="password" class="form-control" placeholder="Password" id="inPswd"></input>
<button id="login">Login</button>
</div>
</form>
You have a problem with your .save() method call because you send username and password in two different objects.
Also to stop adding question mark ? sign (stop submitting your form) you need to add event.preventDefault(); and/or return false; to your button click handler.
Here is a fix:
login: function(event) {
event.preventDefault();
alert("ici");
this.model.save({
username: this.$el.find("#inUser"),
password: this.$el.find("#inPswd")
}, {
success: function() {
/* update the view now */
},
error: function() {
/* handle the error code here */
}
});
return false;
}

How to enable/disable save button of backbone form-view when user changes form content

I have form which gets data from backbone model. When the form is shown, they have initially value set to backbone model. Now, if any field is edited, i want to enable "save" button immediately as soon as any changes is made to field. However, if you change field value and again change it to original, it should again disable the "save" button that allows to save model.I want to achieve as one shown in this jsfiddle :http://jsfiddle.net/qaf4M/2/
I am using backbone.js and backbone.stick (http://nytimes.github.io/backbone.stickit/) to bind model to template.
I create view as follows with model as parameter
RegionManager.show(new app.myView({
model : new app.myModel(
{id: 1})
}));
MY model value is something like this:
{
"id":1, "name:"a" , "age":21
}
The view is as follows:
myView = Backbone.View.extend({
template: _.template( $("#template").html() ),
events: {
"click #save" : "update",
},
bindings: {
'#id': 'id',
'#name': 'name',
'#age': 'age'
},
initialize: function () {
if(this.model){
this.model.fetch();
},
render: function () {
this.$el.html( this.template );
this.stickit(); //used library http://nytimes.github.io/backbone.stickit/
Backbone.Validation.bind(this);
},
update: function() {
this.model.save (
{success: this.success_callback, error: this.error_callback});
},
success_callback: function (model, response) {
},
error_callback: function (model, response) {
alert('error.');
}
});
My template look like
<script type="text/template" id="template">
<form id="myForm " >
<fieldset>
<label>Name</label>
<input type="text" id="name" name="name" />
<label>Age</label>
<input type="text" id="age" name="age" />
<input type="hidden" id="id" name="id"/>
</fieldset>
<a id="save" disabled >Save Changes</a>
</form>
I am confused where should i bind event and how or what is proper way to know the user has chagne some value and accordingly disable button when there is no cahnge in form and enable when change has been made.
A simple solution would be to make your view listen to your model's changes:
initialize: function () {
if(this.model){
this.model.fetch({
success: function(model, resp) {
this.model._attributes = resp; // create a copy of the original attributes
this.listenTo(this.model, 'change', function() {
// when the model changes
// maybe write some function to compare both
if(_.isEqual(this.model._attributes, this.model.toJSON())) {
// disable
}
else {
// able
}
});
}
});
}
So, when the data comes back from the server, you create a copy, and then listen to your model's changes. If the new attributes equal the original, disable the button.

Categories