scope of javascript variable in the class - javascript

inside click_save() method of Controller, this is not pointing to the controller instance, but instead it points to button instance
How to get access to this. so it points to controller and I can do this.userModelDialog().method call
```
// --- Controller manages/dispatches tasks of view and model
function Controller() {
var controller = this;
api = new API();
var table = $('#table');
this.userModelDialog = new UserModalDialog();
$('button[data-type="edituser"]').on("click", function(e) {
controller.click_button(this);
});
// Register the button handlers
$.each(["save", "close", "copy", "delete", "reset"], function(index, id) {
msg.clear();
$("#" + id).click(controller["click_" + id]);
});
}
$.extend(Controller.prototype, {
click_user: function(id) {
api.getUser(id)
.done(function(data) {
_.keys(data).forEach(function(property) {
$('#' + property).val(data[property]);
});
})
.fail(function(data) {
alert('fail');
});
$('#userDetails').modal('show');
},
click_button: function(button) {
var id = $(button).attr('data-id');
this.click_user(id);
},
click_save: function(button) {
this.userModelDialog.submit();
msg.show({
TYPE: 'success',
MESSAGE: 'saved successfull!'
});
$('#userDetails').modal('hide');
},
click_new: function() {
},
click_copy: function() {
},
click_delete: function() {
},
click_reset: function() {
},
click_row: function(row) {
var id = $(row).attr('data-uniqueid');
this.click_user(id);
},
updateFromServer: function(data, callback) {
msg.show(data);
callback(data);
}
});
```

// Register the button handlers
$.each(["save", "close", "copy", "delete", "reset"], function(index, id) {
msg.clear();
var methodName = 'click_' + id;
if (controller[methodName]) {
$("#" + id).click(controller[methodName].bind(controller));
} else {
console.log('There is not method in class with name: ' + methodName);
}
});

Related

Intermitient "Cannot reinitialise DataTable" error

I am making a project with a DataTable (https://datatables.net) and the issue I am having is pretty strange.
Sometimes when I load the page, everything works 100% and other times when I load the page I get this error from DataTables in a popup:
DataTables warning: table id=resdatatable - Cannot reinitialise DataTable. For more information about this error, please see http://datatables.net/tn/3
As I have said, there's no sure fire way to trigger this. If I hit refresh sometimes it will work, sometimes it will give me that error.
I am not trying to reinitialize the DataTable, so I am a bit confused on why this is happening. I checked the link in the description but I am not understanding how to remedy this.
Here is my code:
let statusList = getStatusList();
function getRes(callback) { // ADDED CALLBACK
let city = document.getElementById("cityselect").value;
$.ajax({
type: 'get',
url: 'getreservationstable.php?city='+city,
dataType: 'json',
cache: false,
success: callback // USED CALLBACK
});
}
function changeCity()
{
$('#resdatatable').DataTable().ajax.reload();
}
getRes(function (result) { // APPLIED CALLBACK
$('#resdatatable').DataTable({
data: result, // YOUR RESULT
columns: [
{ data: 'id', title: 'ID' },
{ data: 'bookingdatetime', title: 'Booking Date' },
{ data: 'name', title: 'Name' },
{ data: 'class', title: 'Class' },
{ data: 'pickupdatetime', title: 'Pick up' },
{ data: 'duration', title: 'Duration' },
{ data: 'dropdatetime', title: 'Drop off' },
{ data: 'age', title: 'Age' },
{ data: 'coverage', title: 'Coverage' },
{ data: 'quote', title: 'Quote' },
{
data: 'status',
title: 'Status',
render: function(data, type, row) {
let isKnown = statusList.filter(function(k) { return k.id === data; }).length > 0;
if (isKnown) {
return $('<select id ="resstatus' + row.id + '" onchange="changeResStatus(' + row.id + ')">', {
id: 'resstatus-' + row.id, // custom id
value: data
}).append(statusList.map(function(knownStatus) {
let $option = $('<option>', {
text: knownStatus.text,
value: knownStatus.id
});
if (row.status === knownStatus.id) {
$option.attr('selected', 'selected');
}
return $option;
})).on('change', function() {
changeresstatus(row.id); // Call change with row ID
}).prop('outerHTML');
} else {
return data;
}
}
}
]
});
});
/**
* jQuery plugin to convert text in a cell to a dropdown
*/
(function($) {
$.fn.createDropDown = function(items) {
let oldTxt = this.text();
let isKnown = items.filter(function(k) { return k.id === oldTxt; }).length > 0;
if (isKnown) {
this.empty().append($('<select>').append(items.map(function(item) {
let $option = $('<option>', {
text: item.text,
value: item.id
});
if (item.id === oldTxt) {
$option.attr('selected', 'selected');
}
return $option;
})));
}
return this;
};
})(jQuery);
// If you remove the renderer above and change this to true,
// you can call this, but it will run once...
if (false) {
$('#resdatatable > tbody tr').each(function(i, tr) {
$(tr).find('td').last().createDropDown(statusList);
});
}
function getStatusList() {
return [{
id: 'Confirmed',
text: 'Confirmed'
}, {
id: 'Unconfirmed',
text: 'Unconfirmed'
}, {
id: 'Open',
text: 'Open'
}, {
id: 'Closed',
text: 'Closed'
}, {
id: 'Canceled',
text: 'Canceled'
}];
}
function changeResStatus(str1) {
var id = str1;
var status = document.getElementById("resstatus" + id).value;
var mailres = "";
var r = confirm("Change Status for ID # " + id + " to " + status + "?");
if (r == true) {
if (document.getElementById("resstatus" + id).value == "Confirmed"){
var s = confirm("Send ID # " + id + " a confirmation email?");
if (s == true) {
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("result").setAttribute ("data-notify-msg", this.responseText);
document.getElementById("result").setAttribute ("data-notify-type", "info");
SEMICOLON.widget.notifications(document.getElementById("result"));
}
};
xmlhttp.open("GET","sendconfirmationemail.php?id="+id,true);
xmlhttp.send();
}
}
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("result").setAttribute ("data-notify-msg", this.responseText);
document.getElementById("result").setAttribute ("data-notify-type", "info");
SEMICOLON.widget.notifications(document.getElementById("result"));
}
};
xmlhttp.open("GET","changeresstatus.php?id="+id+"&status="+status,true);
xmlhttp.send();
}else{
document.getElementById("result").setAttribute ("data-notify-msg", "Change status action aborted");
document.getElementById("result").setAttribute ("data-notify-type", "error");
SEMICOLON.widget.notifications(document.getElementById("result"));
}
}
$(document).ready(function() {
var table = $('#resdatatable').DataTable();
$('#resdatatable tbody').on('click', 'tr', function () {
var data = table.row( this ).data().id;
$.ajax({
type: 'POST',
url: 'getreservationsdetails.php',
dataType: 'json',
data: { id:data, },
success: function(response) {
$('#resulttitle').html("Booking ID # " + response[0].id);
$('#resdetname').html(response[0].name);
$('#resdetbdate').html(response[0].bookingdatetime);
$('#resdetadd').html("<br>" + response[0].address + "<br>" + response[0].city + "<br>" + response[0].state + " " + response[0].post);
$('#resdetphone').html(response[0].phone);
$('#resdetemail').html(response[0].email);
$('#resdetdln').html(response[0].dlnum);
$('#resdetdle').html(response[0].dlexp);
$('#resdetdlc').html(response[0].dlcountry);
$('#resdetpickup').html(response[0].pickuploc + " " + response[0].pickupdatetime);
$('#resdetduration').html(response[0].duration);
$('#resdetdrop').html(response[0].droploc + " " + response[0].dropdatetime);
$('#resdetclass').html(response[0].class);
$('#resdetcoverage').html(response[0].coverage);
$('#resdetage').html(response[0].age);
$('#resdetnumofdrivers').html(response[0].numofdrivers);
$('#resdetroadside').html(response[0].roadsideass);
$('#resdetafterhoursdrop').html(response[0].afterhoursdrop);
$('#resdetpromo').html(response[0].promo);
$('#resdetquote').html(response[0].quote);
$('#resdetaddcomments').html(response[0].name);
$('#resdetip').html(response[0].ip);
$("#modalresult").modal();
}
});
} );
} );
Edit:
Upon further examination, this error seems to be caused by the line var table = $('#resdatatable').DataTable(); in $(document).ready(function() { - if I remove that line, everything works just fine. How do I make this work???
Your error come from the fact you try to access a Database object which has not been initialized yet by getRes().
Because on $(document).ready you were creating a first database with no options, when getRes got trigger you should update its content instead of creating a second Database() on top of the same element (which explain the "Cannot reinitialise DataTable")
Try to move the table var from your document ready to your on event:
$(document).ready(function() {
$('#resdatatable tbody').on('click', 'tr', function () {
var table = $('#resdatatable').DataTable();
var data = table.row( this ).data().id;
Or maybe init the $('#resdatatable tbody').on on getRes() as it might not have access to tbody yet:
getRes(function (result) { // APPLIED CALLBACK
$('#resdatatable').DataTable({
...
});
$('#resdatatable tbody').on('click', 'tr', function () {
...
How I fixed this problem:
I added a 1ms delay for the code to run:
setTimeout(function() {
$(document).ready(function() {
var table = $('#resdatatable').DataTable();
$('#resdatatable tbody').on('click', 'tr', function () {
var data = table.row( this ).data().id;
$.ajax({
type: 'POST',
url: 'getreservationsdetails.php',
dataType: 'json',
data: { id:data, },
success: function(response) {
$('#resulttitle').html("Booking ID # " + response[0].id);
$('#resdetname').html(response[0].name);
$('#resdetbdate').html(response[0].bookingdatetime);
$('#resdetadd').html("<br>" + response[0].address + "<br>" + response[0].city + "<br>" + response[0].state + " " + response[0].post);
$('#resdetphone').html(response[0].phone);
$('#resdetemail').html(response[0].email);
$('#resdetdln').html(response[0].dlnum);
$('#resdetdle').html(response[0].dlexp);
$('#resdetdlc').html(response[0].dlcountry);
$('#resdetpickup').html(response[0].pickuploc + " " + response[0].pickupdatetime);
$('#resdetduration').html(response[0].duration);
$('#resdetdrop').html(response[0].droploc + " " + response[0].dropdatetime);
$('#resdetclass').html(response[0].class);
$('#resdetcoverage').html(response[0].coverage);
$('#resdetage').html(response[0].age);
$('#resdetnumofdrivers').html(response[0].numofdrivers);
$('#resdetroadside').html(response[0].roadsideass);
$('#resdetafterhoursdrop').html(response[0].afterhoursdrop);
$('#resdetpromo').html(response[0].promo);
$('#resdetquote').html(response[0].quote);
$('#resdetaddcomments').html(response[0].name);
$('#resdetip').html(response[0].ip);
$("#modalresult").modal();
}
});

calling action method with javascript asp mvc

i am using Datatable jquery and i would like to call delete action on every row inside a button ...how can i redirect to action method delete of the controllers User with the right parameter?
var datatableVariable = $('#myTable').DataTable({
....
columns: [
...column definition...{
data: null,
render: function(data, type, row) {
return "<a href='#' class='btn btn-danger' onclick=DeleteData('" + row.id + "'); >Delete</a>";
}
},
],
});
function DeleteData(id) {
if (confirm("Are you sure you want to delete ...?")) {
Delete(id);
} else {
return false;
}
}
function Delete(id) {
var url = '#Url.Content("~/")' + "Users/Delete";
$.post(url, {
ID: id
}, function(data) {
if (data) {
oTable = $('#myTable').DataTable();
oTable.draw();
} else {
alert("Something Went Wrong!");
}
});
}
I assume you just want to call your action method in the controller.
Use Ajax
$.ajax({
type: "POST",
url: "/Users/Delete",
data: { ID: id},
success: {
},
});

How to execute string as a function using AngularJS?

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']();
}

on commenting one function code works, otherwise it fails

In my application when I am trying to copy one object its getting copied but if I am defining another function call, the code which was executing properly gives error, don't know why. Any help on this is highly appreciated, and thanks in advance
If I comment this function that._createCustomStore(data); everything works good, if I uncomment this it gives me error as Uncaught ReferenceError: _newParent is not defined on this line copiedParent = _newParent;
below is my code
_genericInnerCopy: function(_childObj) {
copiedParent = {};
that = this;
model = that.model;
var record = Ext.create(model, {
Name: _childObj.get('Name'),
//Parent: _newParent.get("_ref");,
});
record.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log("Done");
//that._copyChild();
} else {
console.log("error");
}
}
})
that._all_pis.push(record);
copiedParent = _newParent;
var store = Ext.create('Rally.data.custom.Store', {
data: that._all_pis,
listeners: {
load: function(store,data,success) {
that._updateAll(store, data, copiedParent);
},
scope: that
},
});
//console.log("record values", that._all_pis);
},
_updateAll: function(store,data, copiedParent) {
that = this;
Rally.data.BulkRecordUpdater.updateRecords({
records: data,
propertiesToUpdate: {
Parent: copiedParent.get("_ref")
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: that
});
that._createCustomStore(data);
},
_createCustomStore: function(data) {
me = this;
Ext.create('Rally.data.custom.Store', {
data: data,
//model: 'PortfolioItem/' + _newParent.get('PortfolioItemTypeName'),
autoSync:true,
listeners: {
load: function(store,data,success) {
console.log("store value", store);
console.log("data value", data);
console.log("success value", success);
},
scope: me
},
});
},
onqModelRetrieved: function() {
var that = this;
that._type = 'PortfolioItem/' + that._type,
Rally.data.ModelFactory.getModel({
type: that._type,
success: this.onModelRetrieved,
scope: this
});
},
onModelRetrieved: function(model) {
this.model = model;
this.createFeature();
},
createFeature: function() {
var record = Ext.create(this.model, {
Name: "(Copy of) " + this._newObj.get('Name'),
});
record.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
_newParent = result
Ext.Msg.alert('created ' + result.get('PortfolioItemTypeName') + ':', result.get('Name'));
}
else{
console.log("error");
}
}
});
}
});
Try define it and use it like this:
_newParent: null,
_genericInnerCopy: function(_childObj) {
copiedParent = {};
that = this;
model = that.model;
var record = Ext.create(model, {
Name: _childObj.get('Name')
//Parent: _newParent.get("_ref");,
});
record.save({
callback: function(result, operation) {
if(operation.wasSuccessful()) {
console.log("Done");
//that._copyChild();
} else {
console.log("error");
}
}
})
that._all_pis.push(record);
copiedParent = that._newParent;
var store = Ext.create('Rally.data.custom.Store', {
data: that._all_pis,
listeners: {
load: function(store,data,success) {
that._updateAll(store, data, copiedParent);
},
scope: that
}
});
//console.log("record values", that._all_pis);
},
_updateAll: function(store,data, copiedParent) {
that = this;
Rally.data.BulkRecordUpdater.updateRecords({
records: data,
propertiesToUpdate: {
Parent: copiedParent.get("_ref")
},
success: function(readOnlyRecords){
//all updates finished, except for given read only records
},
scope: that
});
that._createCustomStore(data);
},
_createCustomStore: function(data) {
me = this;
Ext.create('Rally.data.custom.Store', {
data: data,
//model: 'PortfolioItem/' + _newParent.get('PortfolioItemTypeName'),
autoSync:true,
listeners: {
load: function(store,data,success) {
console.log("store value", store);
console.log("data value", data);
console.log("success value", success);
},
scope: me
}
});
},
onqModelRetrieved: function() {
var that = this;
that._type = 'PortfolioItem/' + that._type,
Rally.data.ModelFactory.getModel({
type: that._type,
success: this.onModelRetrieved,
scope: this
});
},
onModelRetrieved: function(model) {
this.model = model;
this.createFeature();
},
createFeature: function () {
var that = this;
var record = Ext.create(this.model, {
Name: "(Copy of) " + this._newObj.get('Name')
});
record.save({
callback: function (result, operation) {
if (operation.wasSuccessful()) {
that._newParent = result
Ext.Msg.alert('created ' + result.get('PortfolioItemTypeName') + ':', result.get('Name'));
}
else {
console.log("error");
}
}
});
}

Javascript Outerhtml error in IE

I have a script for show and hide some html content.my code like this
$(".head-text").live('click', function (event) {
var header = $(this);
var listid = header.find('strong').attr("data-id");
var list = "#" + listid;
var ajaxManager = $.manageAjax.create('cacheQueue', {
queue: true,
cacheResponse: false
});
if ($(list).length == 0) {
$("#ajax-loading-01").show();
ajaxManager.add({
type: 'GET', url: '/ajaxhandler', data: { showlist: "1", listid: listid }
, success: function (data) {
header.parent().append($(data).find(list)[0].outerHTML);
header.parent()._removeClass('show').addClass('hide');
}
, complete: function () {
$("#ajax-loading-01").hide();
}
, error: function (err) {
}
});
return false;
}
});
It is nice working in chrome and mozilla, but the outerHTML is not working in IE - header.parent().append($(data).find(list)[0].outerHTML)). How can I resolve this problem?

Categories

Resources