Knockout.js Observable Array with onlick event - javascript

Hi I have a web application, I'm very new to KnockOut.js
I have my JS COde
ko.applyBindings(new LOBViewModel());
//COMMENTED SECTION BINDS THE DATA TO HTML, BUT DOES NOT TRIGGER ONLICK EVENT
//function LOBViewModel() {
// var self = this;
// self.vm = {
// LOBModel: ko.observableArray()
// };
// GetLOB();
//
// self.DeleteRecord = function (lobmodel) {
// $.ajax({
// type: "POST",
// url: '/Admin/DeleteLOB',
// data : {LOB_ID : lobmodel.LOB_ID},
// success: function (data)
// {
// alert("Record Deleted Successfully");
// GetLOB();//Refresh the Table
// },
// error: function (error)
// {
// }
// });
// };
// function GetLOB() {
// $.ajax({
// url: '/Admin/GetLOB',
// type: "POST",
// dataType: "json",
// success: function (returndata) {
// self.vm.LOBModel = returndata;
// ko.applyBindings(self.vm);
// alert("Hello");
// },
// error: function () {
// }
// });
// };
//}
//UNCOMMENTED SECTION DOES NOT BIND THE DATA TO HTML
function LOBViewModel() {
var self = this;
self.LOBModel = ko.observableArray([]);
GetLOB();
self.DeleteRecord = function (lobmodel) {
$.ajax({
type: "POST",
url: '/Admin/DeleteLOB',
data: { LOB_ID: lobmodel.LOB_ID },
success: function (data) {
alert("Record Deleted Successfully");
GetLOB();//Refresh the Table
},
error: function (error) {
}
});
};
function GetLOB() {
$.ajax({
url: '/Admin/GetLOB',
type: "POST",
dataType: "json",
success: function (returndata) {
self.LOBModel = returndata;
alert(self.LOBModel.length);
},
error: function () {
alert("eRROR GET LOB");
}
});
};
}
Details
My Json is in the following format
[0] = > { LOB_ID : 0 , LOB_Name : "data" LOB_description : "data" }
[1] => and so on
HTML File
<tbody data-bind="foreach: LOBModel">
<tr>
<td data-bind="text:LOB_ID"></td>
<td data-bind="text: LOB_Name"></td>
<td data-bind="text: LOB_Description"></td>
<td><button data-bind="click: $root.DeleteRec">Delete</button></td>
</tr>
</tbody>
My Question is
why is that
i have to use vm to bind the json into LOADModel so that it works, when i use self.LOBModel = ko.observableArray([]); the binding does not happen. i.e, my table does not load the data.
my Onlick does not get triggered in both the version of the code, I've tried self.DeleteRec, $root.DeleteRec and just DeleteRec as well. Though seems very obvious it just doesnot work.
Would the DeleteRec know which record i'm deleting. is lobmodel.LOB_ID correct way to use ?

To answer point by point:
(1) Your problem is in the GetLOB function, on this line:
self.LOBModel = returndata;
By doing that, you overwrite the self.LOBModel = ko.observableArray([]). What you should do instead is this:
self.LOBModel(returndata);
Then you should see the data in your table (if you have no other errors). The thing to remember here, is that if you make a variable observable, you always need to use the ()-syntax to read or write the underlying value. If you use = instead, you erase the observable functionality.
(2) the approach with '$root.DeleteRecord' is correct. 'self.DeleteRecord' would not work, and neither would just DeleteRecord. What would also work is '$parent.DeleteRecord'. The problem seems to be that you do 'DeleteRec' instead of 'DeleteRecord'.
(3) your approach is the right one. Deleted my others comments on this point, since Richard Dalton below me made a correct comment that invalidates what I typed here.
Edit: working Fiddle
http://jsfiddle.net/LFgUu/4/

Related

Why does my jquery plugin cannot access or utilize a data or vaiable from my script?

I have this custom made jQuery plugin, whenever I called it in my script, the option parameter row cannot access the variable or data defined on my script.
JQuery Plugin:
{
$.fn.dbGrid = function (options) {
var settings= $.extend({
read: function () { },
row:""
}, options)
settings.read.call(this)
//console.log(settings.row)
//It ouputs nothing
}
Usage on my Script:
var rows;
function onSuccess(data) {
rows = data;
}
function populateTable() {
$("#container").dbGrid({
read: function () {
$.ajax({
url: "some url",
success: onSuccess,
dataType: "json",
async: false,
type: "GET"
});
},
row:rows
//here the option `row` can not access my `rows` defined in my script, thats why it cannot yield result in my plugin whenever I do console.log
})
//console.log("Row in Base script" + rows);
//Here it outputs the result I want which is data from the function onSuccess
}
populateTable();
}

Ajax POST don't work after button click

My problem is lack of action after pressing the button. Under the button hook AJAX function.
Please a hint where I have a bug // errors.
My code:
Controller:
[HttpPost]
public ActionResult InsertCodesToDB(string name)
{
cl.InsertCodesToDB(name);
fl.MoveCodeFileToAccept(name);
string response = "Test";
return Content(response, "application/json");
}
View / Button:
<input type="button" class="btn btn-success sendCodesToDB" value="Umieść kody w bazie" data-value="#item.Name"/>
View / Script:
<script>
$('.sendCodesToDB').on('click', function () {
var name = $(this).data("value");
$.ajax({
url: '/ActualCodes/InsertCodesToDB',
type: 'POST',
dataType: 'json',
cache: false,
data: JSON.stringify({ 'name': 'name' }),
success: function (response) {
#(ViewBag.MessageOK) = response;
},
error: function () {
onBegin;
}
});
});
function onBegin() {
$('#files').hide();
$('#insertFiles').hide();
$('#loading').show();
$('#lblSelectedProductName').text('Trwa umieszczanie kodów w bazie danych. Proszę czekać ...');
$('#ttt').show();
}
</script>
Thank you in advance for your help.
You seem to not be adding the on ready function for jQuery. Try adding it before your click action and closing it before your onBegin() function, like so:
<script>
// open here
$( document ).ready(function() {
$('.sendCodesToDB').on('click', function () {
var name = $(this).data("value");
$.ajax({
url: '/ActualCodes/InsertCodesToDB',
type: 'POST',
dataType: 'json',
cache: false,
data: JSON.stringify({ 'name': 'name' }),
success: function (response) {
#(ViewBag.MessageOK) = response;
},
error: function () {
// function call missing "()"
onBegin();
}
});
});
// and close here
});
function onBegin() {
$('#files').hide();
$('#insertFiles').hide();
$('#loading').show();
$('#lblSelectedProductName').text('Trwa umieszczanie kodów w bazie danych. Proszę czekać ...');
$('#ttt').show();
}
</script>
The code in Ajax must be JavaScript. You cannot use C# code there (except to print some values). What is #(ViewBag.MessageOK) doing here:
success: function (response) {
#(ViewBag.MessageOK) = response;
},
If you want to display the response in a message box, try something like:
success: function (response) {
$("#your_message_id").html(response);
},
Notes: aside from that, you have several errors in your code as others pointed out in the comments.
1- Remove the quotes from the data like this:
data: JSON.stringify({ name: name }),
2- Change the error to this:
error: function () {
onBegin(); // You need "()" here
}
Or better this:
error: onBegin // You don't need "()" here
I guess you are sending data inside the AJAX call in the wrong way.
Try it like this
data: JSON.stringify({ name: name })
Hope this will help you.

jQuery.when() doesn't seem to be waiting

I need to make a server side call when a user does something in the DOM (click a checkbox, select a dropdown, etc. This is the series of events:
User clicks a checkbox (or something)
A spinner fades in and the UI becomes unavailable
The server side call is made, and gets back some JSON
A label in the UI is updated with a value from the JSON
The spinner fades out and the UI becomes available again
The problem I'm having is that 4 and 5 often get reversed, and the spinner fades out sometimes 2 or 3 seconds before the label is updated.
I'm trying to use .when() to make sure this isn't happening, but I don't seem to be doing it right. I've been looking at this thread, and this one, and jquery's own documentation.
Here's where I'm at right now...
function UpdateCampaign() {
$('#overlay').fadeIn();
$.when(SaveCampaign()).done(function () {
$('#overlay').fadeOut();
});
}
function SaveCampaign() {
var formData =
.... // get some data
$.ajax({
url: '/xxxx/xxxx/SaveCampaign',
type: 'GET',
dataType: 'json',
data: { FormData: formData },
success: function (data) {
var obj = $.parseJSON(data);
.... // update a label, set some hidden inputs, etc.
},
error: function (e) {
console.log(e)
}
});
}
Everything works correctly. The server side method is executed, the correct JSON is returned and parsed, and the label is updated as expected.
I just need that dang spinner to wait and fade out until AFTER the label is updated.
The issue is because you're not giving $.when() a promise. In fact you're giving it nullso it executes immediately. You can solve this by returning the promise that $.ajax provides from your SaveCampaign() function like this:
function SaveCampaign() {
var formData = // get some data
return $.ajax({ // < note the 'return' here
url: '/xxxx/xxxx/SaveCampaign',
type: 'GET',
dataType: 'json',
data: { FormData: formData },
success: function (data) {
var obj = $.parseJSON(data);
// update a label, set some hidden inputs, etc.
},
error: function (e) {
console.log(e)
}
});
}
I know its answered by Rory already. But here's mine promise method, it works fine always and instead of using success and error uses done and fail
var jqXhr = $.ajax({
url: "/someurl",
method: "GET",
data: {
a: "a"
});
//Promise method can be used to bind multiple callbacks
if (someConditionIstrue) {
jqXhr
.done(function(data) {
console.log('when condition is true', data);
})
.fail(function(xhr) {
console.log('error callback for true condition', xhr);
});
} else {
jqXhr.done(function(data){
console.log('when condition is false', data);
})
.fail(function(xhr) {
console.log('error callback for false condition', xhr);
});
}
Or if I want a common callback other than conditional ones, can bind directly on jqXhr variable outside the if-else block.
var jqXhr = $.ajax({
url: "/someurl",
method: "GET",
data: {
a: "a"
});
jqXhr
.done(function(data) {
console.log('common callback', data);
})
.fail(function(xhr) {
console.log('error common back', xhr);
});

jquery ajax store variable and then retrieve later on

Hi i am using jquery and ajax to retrieve the user id of the logged in user, Im saving this into a variable as I want to be able to do some logic with it later on. however I am having trouble accessing it. My code is below:
$(document).ready(function () {
var taskBoard = {
fetch: function (url, data) {
$('.loading-icon').fadeIn();
$('.task_board').addClass('loading');
$.ajax({
url: url,
async: true,
dataType: 'json',
data: data,
type: 'POST',
success: function (json) {
$('.loading-icon').fadeOut();
$('#task_board').html($(json.data.taskBoard));
$('.task_board').removeClass('loading');
$('.update-results').hide();
} // end success
}); //end ajax
}, //end fetch function
authUser: function (url, data) {
$.ajax({
url: url,
async: true,
dataType: 'json',
data: data,
type: 'POST',
success: function (json) {
$.each($(json), function (index, item) {
taskBoard.storeUser(item.id);
});
} // end success
}); //end ajax
}, //end authUser function
storeUser: function (param) {
var authUserId = param;
return param;
// if I do an alert here the correct user id is returned.
},
} //end var taskBoard
//However if I do an alert here outside of the var taskBoard I get an undefined.
alert(taskBoard.storeUser());
});
Any ideas how I can get this globally assigned variable outside of this function?
change this
storeUser: function (param) {
var authUserId = param;
return param;
// if I do an alert here the correct user id is returned.
},
change to this:
authUserId : null,
storeUser: function (param) {
if (param)
{
this.authUserId = param;
}
return this.authUserId;
},
Now the var authUserId will be stored as a property in the taskBoard object.
When param is undefined it will return the value unupdated if not it will update it first and then returns it.
A more elegant solution would be to use Object.defineProperty here.
Delete the storeUser property and after the declaration of the taskBoard object add this:
Object.defineProperty(taskBoard, "storeUser", {
get : function(){ return this.StoreUserVar; },
set : function(value){ this.StoreUserVar = value; }
});
Now you can assign the userid with:
taskBoard.storeUser = item.id;
//-------- taskBoard object
success: function (json) {
$.each($(json), function (index, item) {
taskBoard.storeUser = item.id;
doOtherFunction();
});
//--------
function doOtherFunction()
{
//the callback function fired from the success.
alert(taskBoard.storeUser); //this will alert with the value set.
}
Well if you need a global variable then declare that variable before the document.ready, since variables defined in this function are only valid in this function
Javascript Scope Examples

Extending jQuery ajax success globally

I'm trying to create a global handler that gets called before the ajax success callback. I do a lot of ajax calls with my app, and if it is an error I return a specific structure, so I need to something to run before success runs to check the response data to see if it contains an error code bit like 1/0
Sample response
{"code": "0", "message": "your code is broken"}
or
{"code": "1", "data": "return some data"}
I can't find a way to do this in jQuery out of the box, looked at prefilters, ajaxSetup and other available methods, but they don't quite pull it off, the bets I could come up with is hacking the ajax method itself a little bit:
var oFn = $.ajax;
$.ajax = function(options, a, b, c)
{
if(options.success)
{
var oFn2 = options.success;
options.success = function(response)
{
//check the response code and do some processing
ajaxPostProcess(response);
//if no error run the success function otherwise don't bother
if(response.code > 0) oFn2(response);
}
}
oFn(options, a, b, c);
};
I've been using this for a while and it works fine, but was wondering if there is a better way to do it, or something I missed in the jQuery docs.
You can build your own AJAX handler instead of using the default ajax:
var ns = {};
ns.ajax = function(options,callback){
var defaults = { //set the defaults
success: function(data){ //hijack the success handler
if(check(data)){ //checks
callback(data); //if pass, call the callback
}
}
};
$.extend(options,defaults); //merge passed options to defaults
return $.ajax(options); //send request
}
so your call, instead of $.ajax, you now use;
ns.ajax({options},function(data){
//do whatever you want with the success data
});
This solution transparently adds a custom success handler to every $.ajax() call using the duck punching technique
(function() {
var _oldAjax = $.ajax;
$.ajax = function(options) {
$.extend(options, {
success: function() {
// do your stuff
}
});
return _oldAjax(options);
};
})();
Here's a couple suggestions:
var MADE_UP_JSON_RESPONSE = {
code: 1,
message: 'my company still uses IE6'
};
function ajaxHandler(resp) {
if (resp.code == 0) ajaxSuccess(resp);
if (resp.code == 1) ajaxFail(resp);
}
function ajaxSuccess(data) {
console.log(data);
}
function ajaxFail(data) {
alert('fml...' + data.message);
}
$(function() {
//
// setup with ajaxSuccess() and call ajax as usual
//
$(document).ajaxSuccess(function() {
ajaxHandler(MADE_UP_JSON_RESPONSE);
});
$.post('/echo/json/');
// ----------------------------------------------------
// or
// ----------------------------------------------------
//
// declare the handler right in your ajax call
//
$.post('/echo/json/', function() {
ajaxHandler(MADE_UP_JSON_RESPONSE);
});
});​
Working: http://jsfiddle.net/pF5cb/3/
Here is the most basic example:
$.ajaxSetup({
success: function(data){
//default code here
}
});
Feel free to look up the documentation on $.ajaxSetup()
this is your call to ajax method
function getData(newUrl, newData, callBack) {
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: newUrl,
data: newData,
dataType: "json",
ajaxSuccess: function () { alert('ajaxSuccess'); },
success: function (response) {
callBack(true, response);
if (callBack == null || callBack == undefined) {
callBack(false, null);
}
},
error: function () {
callBack(false, null);
}
});
}
and after that callback success or method success
$(document).ajaxStart(function () {
alert('ajax ajaxStart called');
});
$(document).ajaxSuccess(function () {
alert('ajax gvPerson ajaxSuccess called');
});

Categories

Resources