Kendo UI javascript : remote bind form - javascript

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.

Related

Knockout JS How to Access a Value from Second View Model / Binding

I am new to Knockout JS and think it is great. The documentation is great but I cannot seem to use it to solve my current problem.
The Summary of my Code
I have two viewmodels represented by two js scripts. They are unified in a parent js file. The save button's event is outside
both foreach binders. I can save all data in the details foreach.
My Problem
I need to be able to include the value from the contacts foreach binder with the values from the details foreach binder.
What I have tried
I have tried accessig the data from both viewmodels from the parent viewmodel and sending the POST request to the controller from there but the observeableArrays show undefined.
Create.CSHTML (Using MVC5 no razor)
<div id="container1" data-bind="foreach: contacts">
<input type="text" data-bind="value: contactname" />
</div>
<div data-bind="foreach: details" class="card-body">
<input type="text" data-bind="value: itemValue" />
</div>
The save is outside of both foreach binders
<div class="card-footer">
<button type="button" data-bind="click: $root.save" class="btn
btn-success">Send Notification</button>
</div>
<script src="~/Scripts/ViewScripts/ParentVM.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel1.js" type="text/javascript"></script>
<script src="~/Scripts/ViewScripts/ViewModel2.js" type="text/javascript"></script>
ViewModel1
var ViewModel1 = function (contacts) {
var self = this;
self.contacts = ko.observableArray(ko.utils.arrayMap(contacts, function (contact) {
return {
contactName: contact.contactName
};
}));
}
ViewModel2
var ViewModel2 = function (details) {
var self = this;
self.details = ko.observableArray(ko.utils.arrayMap(details, function (detail) {
return {
itemNumber: detail.itemValue
};
}));
}
self.save = function () {
$.ajax({
url: baseURI,
type: "POST",
data: ko.toJSON(self.details),
dataType: "json",
contentType: "application/json",
success: function (data) {
console.log(data);
window.location.href = "/Home/Create/";
},
error: function (error) {
console.log(error);
window.location.href = "/Homel/Create/";
}
});
};
ParentViewModel
var VM1;
var VM2;
var initialContactInfo = [
{
contactPhone: ""
}
]
var initialForm = [
{
itemValue: ""
]
}
$(document).ready(function () {
if ($.isEmptyObject(VM1)) {
ArnMasterData = new ViewModel1(initialContactInfo);
ko.applyBindings(VM1, document.getElementById("container1"));
}
if ($.isEmptyObject(VM2)) {
VM2 = new ViewModel2(initialForm);
ko.applyBindings(VM2, document.getElementById("container2"));
}
});

how to remove specific character and text

I have finish autocomplete with a jquery library which is
using jquery-ui-1.12.1.min.js
. I have modified it to make to get the search with username and full name. it will show as below image
when I select the value it will paste the whole text into an input box.
here is my question how do it modify it to show as the image but when I select the value it will only paste the username into input box?
how i only want nonstop00000 paste it into input box when i select the 1st value
here is my javascript
$(document).ready(function () {
$("#id").autocomplete({
source: function(request,response) {
$.ajax({
url: '#Url.Content("~/UserManagement/AutoCompleteUser")/',
type: "POST",
dataType: "json",
data: { term: request.term },
success: function (data) {
response($.map(data, function (item) {
return [{ label: item.Username + " | " + item.FullName, value: item.id }];
}))
}
})
},
messages: {
noResults: "", results: ""
}
});
})
here is my search controller
if (!String.IsNullOrEmpty(searchString))
{
user = user.Where(s => s.Username.Trim().Contains(searchString.Trim())
|| s.FullName.Trim().Contains(searchString.Trim()));
}
here is my autocomplete controller
public JsonResult AutoCompleteUser(string term)
{
var result = (from r in db.UserTables
where ((r.Status == "Active") && (r.Username.ToLower().Contains(term.ToLower()) || (r.FullName.ToLower().Contains(term.ToLower()))))
select new { Username = r.Username, FullName = r.FullName }).Distinct();
return Json(result);
}
here is my view
<div class="col-lg-9 col-md-9 col-sm-9 col-xs-12 search-panel">
#using (Html.BeginForm("Index", "UserManagement", FormMethod.Get))
{
<div class="input-group form-group ui-widget">
#Html.TextBox("id", ViewBag.CurrentFilter as string, new { #class = "form-control autocomplete", #placeholder = "Search for..." })
<span class="input-group-btn">
<input type="submit" value="Search" class="form-control autocomplete " />
</span>
</div>
}
</div>
To achieve this you can use the select event to amend the value to be placed in to the input. Try this:
$("#id").autocomplete({
// your settings...
select: function(e, ui) {
e.preventDefault();
$('#id').val(ui.item.label.split('|')[0].trim());
}
});

Event default not triggering in jQuery module

I'm attempting to write a jQuery script to store an authentication token from a REST API service. I had a block of working code but decided to modularize to make the application more scalable. Now, it seems that the preventDefault portion is no longer working.
<form action="/" id="authorize">
<label for="username">Username:</label><br />
<input type="text" id="username" required /><br />
<label for="password">Password:</label><br />
<input type="password" id="password" required /><br />
<input type="submit" value="Authorize" /><span id="isValid" class="checkContainer"> </span>
</form><hr />
<label for="serviceType" class="fieldDisabled">Method: </label>
<select id="serviceType" disabled>
<option></option>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</select>
The script is saved separately as authorize.js and invoked in the module as follows:
<script src="js/authorize.js"></script>
<script>
$(document).ready(function() {
Authorize.init();
});
</script>
Here's the module itself:
var s;
var Authorize = {
token: null,
settings: {
username: $("#username"),
password: $("#password"),
form: $("#authorize"),
validationIcon: $("#isValid"),
selector: $("#serviceType"),
selectorLabel: $("label[for='serviceType']"),
serviceSelector: $(".methodFieldDisabled"),
url: "redacted"
},
init: function() {
s = Authorize.settings;
this.bindUIActions();
},
bindUIActions: function() {
s.form.submit(function(event) {
event.preventDefault();
data = Authorize.buildJSON(s.username.val(), s.password.val());
Authorize.getToken(json);
});
},
buildJSON: function(username, password) {
var data = {};
data['grant_type'] = password;
data['username'] = username;
data['password'] = password;
return data;
},
getToken: function(data) {
$.ajax({
type: "POST",
url: s.url,
data: data,
success: function(json) {
Authorize.success(json);
},
error: function(json) {
Authorize.error(json);
}
});
},
success: function(json) {
Authorize.token = json.accessToken;
Authorize.revealServiceSelector();
},
error: function(json) {
Authorize.hideServiceSelector();
},
revealServiceSelector: function() {
s.serviceSelector.hide();
if(s.validationIcon.hasClass("invalid")) {
s.validationIcon.removeClass("invalid");
}
selectorLabel.removeClass("fieldDisabled");
selector.prop("disabled", false);
s.validationIcon.addClass("valid");
},
hideServiceSelector: function() {
s.serviceSelector.hide();
if(s.validationIcon.hasClass("valid")) {
s.validationIcon.removeClass("valid");
}
selectorLabel.addClass("fieldDisabled");
selector.prop("disabled", "disabled");
s.validationIcon.addClass("invalid");
}
};
I've been toiling over this for about a day now and can't seem to locate the point of failure. When the form is submitted, it redirects to the root directory of the server instead of executing the script as intended.
Just a few typos which stopped the code in its tracks. The submission was the default behavior as your code failed to complete.
Use a debugger to see the errors at runtime (get to know and love your F12 debugging tools in Chrome etc!):
1) You have the wrong variable (json instead of data) on the line below so you get an error:
bindUIActions: function () {
s.form.submit(function (event) {
event.preventDefault();
data = Authorize.buildJSON(s.username.val(), s.password.val());
Authorize.getToken(data); // <<<<<<<<<<<<<<<<<<<<<<<
});
2) You also failed to put your scope (s) on a couple of variables:
revealServiceSelector: function () {
s.serviceSelector.hide();
if (s.validationIcon.hasClass("invalid")) {
s.validationIcon.removeClass("invalid");
}
s.selectorLabel.removeClass("fieldDisabled");
s.selector.prop("disabled", false);
s.validationIcon.addClass("valid");
},
hideServiceSelector: function () {
s.serviceSelector.hide();
if (s.validationIcon.hasClass("valid")) {
s.validationIcon.removeClass("valid");
}
s.selectorLabel.addClass("fieldDisabled");
s.selector.prop("disabled", "disabled");
s.validationIcon.addClass("invalid");
}
Your from action is pointed to "\" which is the root of your directory. Instead point it to the file that contains the code you want to fire.

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