I have got a task to do user editing. I did this. But i cannot pass the value as json object. How can i join two values.
My first object is
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
}
else {
o[this.name] = this.value || '';
}
});
return o;
};
My second object is
var location = function() {
var self = this;
self.country = ko.observable();
self.state = ko.observable();
};
var map = function() {
var self = this;
self.lines = ko.observableArray([new location()]);
self.save = function() {
var dataToSave = $.map(self.lines(), function(line) {
return line.state() ? {
state: line.state().state,
country: line.country().country
} : undefined
});
alert("Could now send this to server: " + JSON.stringify(dataToSave));
};
};
ko.applyBindings(new map());
});
I want to concatenate this. I tried this but i got an error
$.ajax({
url: '/users/<%=#user.id%>',
dataType: 'json',
//async: false,
//contentType: 'application/json',
type: 'PUT',
data: {total_changes: JSON.stringify(dataToSave) + JSON.stringify($("#edit_user_1").serializeObject())},
//data:JSON.stringify(dataToSave),
//data:dataToSave,
success: function(data) {
alert("Successful");
},
failure: function() {
alert("Unsuccessful");
}
});
When i run this it shows an error like this in terminal.
How can i solve this?
If you have json1 and json2 objects you can do:
$.extend(json1, json2);
So in json1 you will get both objects merged.
The problem is JSON.stringify(…) + JSON.stringify(…). This will create a string like "{…}{…}" which obviously is invalid JSON (that's where you get the JSON::ParserError from).
I'm not sure what you are trying to accomplish and which JSON structure your server expects, but you could do something like
…
contentType: 'application/json',
data: JSON.stringify( {
total_changes: dataToSave,
edits: $("#edit_user_1").serializeObject()
}),
…
Related
I have these two functions defined:
function fetchYPosts() {
$http.get("/postsY/")
.then(function(response) {
self.posts = response.data;
}, function(response) {
self.posts = {};
});
};
function fetchXPosts() {
$http.get("/postsX/")
.then(function(response) {
self.posts = response.data;
}, function(response) {
self.posts = {};
});
};
I am passed an id and a string ('X' or 'Y' is what I want the end-user to pass to me) from the front-end. I have this code which handles when the string is passed:
self.handler = function(id, XOrY) {
$http.post("/" + XOrY + "/" + id + "/handle/")
.then(function(response) {
functionToCall = "fetch" + XOrY + "Posts()";
# Here is where I want to call funcitonToCall.
}, function(response) {
self.cerrorMessages = BaseService.accessErrors(response.data);
});
};
With that said, given a variable which holds a string, how do I call the function which has the name of the string variable?
You should select the correct method using something like this:
var fetcher = XOrY == 'x' ? fetchXPosts : fetchYPosts;
which can be used like:
self.handler = function(id, XOrY) {
var fetcher = XOrY == 'x' ? fetchXPosts : fetchYPosts;
$http.post("/" + XOrY + "/" + id + "/handle/")
.then(function(response) {
fetcher();
# Here is where I want to call funcitonToCall.
}, function(response) {
self.cerrorMessages = BaseService.accessErrors(response.data);
});
};
If you have a situation where there's just too many different fetching functions, you can instead define them like this as part of a hash:
var fetch = {
YPosts: function() {
$http.get("/postsY/")
.then(function(response) {
self.posts = response.data;
}, function(response) {
self.posts = {};
});
},
XPosts: function() {
$http.get("/postsX/")
.then(function(response) {
self.posts = response.data;
}, function(response) {
self.posts = {};
});
}
}
and grab the function from fetch[XorY]:
self.handler = function(id, XOrY) {
$http.post("/" + XOrY + "/" + id + "/handle/")
.then(function(response) {
fetch[XorY]();
# Here is where I want to call funcitonToCall.
}, function(response) {
self.cerrorMessages = BaseService.accessErrors(response.data);
});
};
you can encapsule these two function in an object, and call this service in your method like this
var service = {
fetchXPosts: function(){},
fetchYPosts: function(){}
}
self.handler = function(id, XORY) {
service['fetch'+XORY+'posts']();
}
I am a newbie in Knockout JS. i want to apply validations in KO. i have used plugin knockout.validation.min.js . I have implemented it like this but not working
My View Model
$(document).ready(function myfunction() {
ko.applyBindings(new EmployeeKoViewModel());
})
var EmployeeKoViewModel = function () {
var self = this;
self.EmpId = ko.observable()
self.Name = ko.observable("").extend({ required: { message: "please enter employee name " } });
self.City = ko.observable("").extend({ required: { message: "please enter employee city " } });
self.Employees = ko.observableArray();
//GetEmployees();
var EmpData = {
EmpId: self.EmpId,
Name: self.Name,
City: self.City,
};
function GetEmployees() {
$.ajax({
type: "GET",
url: "/Employee/About",
}).done(function (data) {
self.Employees(data);
}).error(function (ex) {
alert("Error");
});
}
self.save = function () {
var EmployeeKoViewModel.errors = ko.validation.group(self);
if (!EmployeeKoViewModel.errors().length <= 0) {
EmployeeKoViewModel.errors.showAllMessages();
return false;
}
$.ajax({
type: "POST",
url: "/Employee/Save",
data: ko.toJSON(EmpData),
contentType: "application/json",
success: function (data) {
self.EmpId(data.EmpId);
GetEmployees();
},
error: function () {
alert("Failed");
}
});
//Ends Here
};
}
I have created a fiddle it is working when i comment GetEmployees() method but not working with it
At this line
var EmployeeKoViewModel.errors = ko.validation.group(self);
you are trying to create a variable, but the syntax is like creating an object with a property which is of course invalid. In order to fix this you can initialize your object first:
var EmployeeKoViewModel = {};
EmployeeKoViewModel.errors = ko.validation.group(self);
if (!EmployeeKoViewModel.errors().length <= 0) {
EmployeeKoViewModel.errors.showAllMessages();
return false;
}
Here is a working jsFiddle
I have an $.ajax function on my page to populate a facility dropdownlist based on a service type selection. If I change my service type selection back and forth between two options, randomly the values in the facility dropdownlist will remain the same and not change. Is there a way to prevent this? Am I doing something wrong?
Javascript
function hydrateFacilityDropDownList() {
var hiddenserviceTypeID = document.getElementById('<%=serviceTypeID.ClientID%>');
var clientContractID = document.getElementById('<%=clientContractID.ClientID%>').value;
var serviceDate = document.getElementById('<%=selectedServiceDate.ClientID%>').value;
var tableName = "resultTable";
$.ajax({
type: 'POST',
beforeSend: function () {
},
url: '<%= ResolveUrl("AddEditService.aspx/HydrateFacilityDropDownList") %>',
data: JSON.stringify({ serviceTypeID: TryParseInt(hiddenserviceTypeID.value, 0), clientContractID: TryParseInt(clientContractID, 0), serviceDate: serviceDate, tableName: tableName }),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) {
a(data);
}
,error: function () {
alert('HydrateFacilityDropDownList error');
}
, complete: function () {
}
});
}
function a(data) {
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
var tableName = "resultTable";
if (facilityDropDownList.value != "") {
selectedFacilityID = facilityDropDownList.value;
}
$(facilityDropDownList).empty();
$(facilityDropDownList).prepend($('<option />', { value: "", text: "", selected: "selected" }));
$(data.d).find(tableName).each(function () {
var OptionValue = $(this).find('OptionValue').text();
var OptionText = $(this).find('OptionText').text();
var option = $("<option>" + OptionText + "</option>");
option.attr("value", OptionValue);
$(facilityDropDownList).append(option);
});
if ($(facilityDropDownList)[0].options.length > 1) {
if ($(facilityDropDownList)[0].options[1].text == "In Home") {
$(facilityDropDownList)[0].selectedIndex = 1;
}
}
if (TryParseInt(selectedFacilityID, 0) > 0) {
$(facilityDropDownList)[0].value = selectedFacilityID;
}
facilityDropDownList_OnChange();
}
Code Behind
[WebMethod]
public static string HydrateFacilityDropDownList(int serviceTypeID, int clientContractID, DateTime serviceDate, string tableName)
{
List<PackageAndServiceItemContent> svcItems = ServiceItemContents;
List<Facility> facilities = Facility.GetAllFacilities().ToList();
if (svcItems != null)
{
// Filter results
if (svcItems.Any(si => si.RequireFacilitySelection))
{
facilities = facilities.Where(f => f.FacilityTypeID > 0).ToList();
}
else
{
facilities = facilities.Where(f => f.FacilityTypeID == 0).ToList();
}
if (serviceTypeID == 0)
{
facilities.Clear();
}
}
return ConvertToXMLForDropDownList(tableName, facilities);
}
public static string ConvertToXMLForDropDownList<T>(string tableName, T genList)
{
// Create dummy table
DataTable dt = new DataTable(tableName);
dt.Columns.Add("OptionValue");
dt.Columns.Add("OptionText");
// Hydrate dummy table with filtered results
if (genList is List<Facility>)
{
foreach (Facility facility in genList as List<Facility>)
{
dt.Rows.Add(Convert.ToString(facility.ID), facility.FacilityName);
}
}
if (genList is List<EmployeeIDAndName>)
{
foreach (EmployeeIDAndName employeeIdAndName in genList as List<EmployeeIDAndName>)
{
dt.Rows.Add(Convert.ToString(employeeIdAndName.EmployeeID), employeeIdAndName.EmployeeName);
}
}
// Convert results to string to be parsed in jquery
string result;
using (StringWriter sw = new StringWriter())
{
dt.WriteXml(sw);
result = sw.ToString();
}
return result;
}
$get return XHR object not the return value of the success call and $get function isn't synchronous so you should wait for success and check data returned from the call
these two lines do something different than what you expect
var facilityDropDownList = $get('<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>');
var selectedFacilityID = $get('<%= selectedFacilityID.ClientID%>').value;
change to something similar to this
var facilityDropDownList;
$.ajax({
url: '<%=servicesFormView.FindControl("facilityDropDownList").ClientID%>',
type: 'get',
dataType: 'html',
async: false,
success: function(data) {
facilityDropDownList= data;
}
});
I'm pretty new to Backbone and I've been trying to create autocomplete functionality with it, fed by an ASMX webservice. The issue I seem to have is whilst my webservice returns in JSON (after a painful battle with it), it wraps the response in a 'd' (dataset). How do I get the view to understand this and get at the correct data?
Here is my code:-
var Airline = Backbone.Model.extend({
initialize: function () {},
defaults: {
name: 'Airline Name',
rating: 50,
icon: '/blank.png'
}
});
var AirlineCollection = Backbone.Collection.extend({
model: Airline,
contentType: "application/json",
url: '/ControlTower/public/runway.asmx/all-airlines',
parse: function (response) {
return response;
}
});
var SelectionView = Backbone.View.extend({
el : $('#airline'),
render: function() {
$(this.el).html("You Selected : " + this.model.get('AirlineName'));
return this;
},
});
var airlines = new AirlineCollection();
airlines.fetch({async: false, contentType: "application/json" });
var airlineNames = airlines.pluck("AirlineName");
$("#airline").autocomplete({
source : airlineNames,
minLength : 1,
select: function(event, ui){
var selectedModel = airlines.where({name: ui.item.value})[0];
var view = new SelectionView({model: selectedModel});
view.render();
}
});
Can anyone see what I'm doing wrong? I've been sitting here for too long now!
Help is appreciated ;)
What about in your AirlineCollection:
parse: function (response) {
return response.d;
}
This works for me
In AirlineCollection
parse: function (response) {
var data = (typeof response.d) == 'string' ? eval('(' + response.d + ')') : response.d;
return data;
}
The following code works great with a hardcoded array (initialData1), however I need to use jquery .ajax (initialData) to initialize the model and when I do the model shows empty:
$(function () {
function wiTemplateInit(winame, description) {
this.WIName = winame
this.WIDescription = description
}
var initialData = new Array;
var initialData1 = [
{ WIName: "WI1", WIDescription: "WIDescription1" },
{ WIName: "WI1", WIDescription: "WIDescription1" },
{ WIName: "WI1", WIDescription: "WIDescription1" },
];
console.log('gridrows:', initialData1);
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{UserKey: '10'}",
url: "WIWeb.asmx/GetTemplates",
success: function (data) {
for (var i = 0; i < data.d.length; i++) {
initialData.push(new wiTemplateInit(data.d[i].WiName,data.d[i].Description));
}
//console.log('gridrows:', initialData);
console.log('gridrows:', initialData);
}
});
var viewModel = function (iData) {
this.wiTemplates = ko.observableArray(iData);
};
ko.applyBindings(new viewModel(initialData));
});
I have been trying to work from the examples on the knockoutjs website, however most all the examples show hardcoded data being passed to the view model.
make sure your "WIWeb.asmx/GetTemplates" returns json array of objects with exact structure {WIName : '',WIDescription :''}
and try using something like this
function wiTemplateInit(winame, description)
{
var self = this;
self.WIName = winame;
self.WIDescription = description;
}
function ViewModel()
{
var self = this;
self.wiTemplates = ko.observableArray();
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
dataType: "json",
data: "{UserKey: '10'}",
url: "WIWeb.asmx/GetTemplates",
success: function (data)
{
var mappedTemplates = $.map(allData, function (item) { return new wiTemplateInit(item.WiName, item.Description) });
self.wiTemplates(mappedTemplates);
}
});
}
var vm = new ViewModel();
ko.applyBindings(vm);
If you show us your browser log we can say more about your problem ( Especially post and response ). I prepared you a simple example to show how you can load data with ajax , bind template , manipulate them with actions and save it.
Hope this'll help to fix your issue : http://jsfiddle.net/gurkavcu/KbrHX/
Summary :
// This is our item model
function Item(id, name) {
this.id = ko.observable(id);
this.name = ko.observable(name);
}
// Initial Data . This will send to server and echo back us again
var data = [new Item(1, 'One'),
new Item(2, 'Two'),
new Item(3, 'Three'),
new Item(4, 'Four'),
new Item(5, 'Five')]
// This is a sub model. You can encapsulate your items in this and write actions in it
var ListModel = function() {
var self = this;
this.items = ko.observableArray();
this.remove = function(data, parent) {
self.items.remove(data);
};
this.add = function() {
self.items.push(new Item(6, "Six"));
};
this.test = function(data, e) {
console.log(data);
console.log(data.name());
};
this.save = function() {
console.log(ko.mapping.toJSON(self.items));
};
}
// Here our viewModel only contains an empty listModel
function ViewModel() {
this.listModel = new ListModel();
};
var viewModel = new ViewModel();
$(function() {
$.post("/echo/json/", {
// Data send to server and echo back
json: $.toJSON(ko.mapping.toJS(data))
}, function(data) {
// Used mapping plugin to bind server result into listModel
// I suspect that your server result may contain JSON string then
// just change your code into this
// viewModel.listModel.items = ko.mapping.fromJSON(data);
viewModel.listModel.items = ko.mapping.fromJS(data);
ko.applyBindings(viewModel);
});
})