Please consider the following code. This code works as expected.
function paging(totalItems, currentPage, itemsPerPage) {
this.totalItems = (typeof totalItems !== 'undefined') ? totalItems : 0;
this.currentPage = (typeof currentPage !== 'undefined') ? currentPage : 1;
this.itemsPerPage = (typeof itemsPerPage !== 'undefined') ? itemsPerPage : 18;
}
function viewModel(foo, bar, paging) {
this.foo = (typeof foo !== 'undefined') ? foo : true;
this.bar = (typeof bar !== 'undefined') ? bar : false;
this.paging = (typeof paging !== 'undefined') ? paging : {};
}
function init() {
// Create a new viewmodel object and assign it to $scope (AngularJS)
$scope.viewModel = new viewModel();
// Set the paging parameter to a new paging object
$scope.viewModel.paging = new paging();
// Now we can use dot notation to assign the value in the sub-function
$scope.viewModel.paging.currentPage = 1;
}
init();
Now, what I'm trying to do, and can't quite figure out, is how to call "new viewModel()" and have the paging property automatically populate itself with a new paging(), without having to make the extra call in init(). So, for example, something like this...
function viewModel(foo, bar, paging) {
this.foo = (typeof foo !== 'undefined') ? foo : true;
this.bar = (typeof bar !== 'undefined') ? bar : false;
this.paging = (typeof paging !== 'undefined') ? paging : new paging();
}
Which throws an error about a constructor if I remember correctly.
I also tried this:
function viewModel(foo, bar, paging) {
this.foo = (typeof foo !== 'undefined') ? foo : true;
this.bar = (typeof bar !== 'undefined') ? bar : false;
function paging(totalItems, currentPage, itemsPerPage) {
this.totalItems = (typeof totalItems !== 'undefined') ? totalItems : 0;
this.currentPage = (typeof currentPage !== 'undefined') ? currentPage : 1;
this.itemsPerPage = (typeof itemsPerPage !== 'undefined') ? itemsPerPage : 18;
}
}
... and several other forms of the above, but nothing seems to properly init the paging property except the original example. Isn't there a better way to handle this?
Related
If you create a multidimensional-array:
var ThisArray = [];
ThisArray["a"] = [];
ThisArray["a"]["b"] = [];
ThisArray["a"]["b"]["c"] = "This is a string.";
How can you check if ThisArray["a"]["w"]["c"] for example is defined. Right now I'm doing this:
if (typeof ThisArray !== 'undefined') {
if (typeof ThisArray["a"] !== 'undefined') {
if (typeof ThisArray["a"]["w"] !== 'undefined') {
if (typeof ThisArray["a"]["w"]["c"] !== 'undefined') {
// ThisArray["a"]["w"]["c"] is defined!
}
}
}
}
How can I do this better and cleaner?
Use optional chaining:
if (typeof ThisArray?.["a"]?.["w"]?.["c"] !== 'undefined') {
// ThisArray["a"]["w"]["c"] is defined!
}
As noted in the comments, this is a relatively new language feature, and is not supported by older browsers. See Browser Compatibility.
You can use optional chaining.
the optional chaining operator enables simple way to access values through connected objects when it's possible that a reference or function may be undefined or null, hence, protecting you from getting null exception on null/undefined objects.
var ThisArray = [];
ThisArray["a"] = [];
ThisArray["a"]["b"] = [];
ThisArray["a"]["b"]["c"] = "This is a string.";
console.log(ThisArray.a.b.c?.d?.e);
This is a perfect place to use optional chaining!
You can do so like this:
if (typeof ThisArray.a?.b?.c !== 'undefined') {
console.log(`ThisArray["a"]["b"]["c"] is defined!`);
}
Here's a full demo:
var ThisArray = [];
ThisArray["a"] = [];
ThisArray["a"]["b"] = [];
ThisArray["a"]["b"]["c"] = "This is a string.";
if (typeof ThisArray.a?.b?.c !== 'undefined') {
console.log(`ThisArray["a"]["b"]["c"] is defined!`);
console.log(`ThisArray.a.w.c === "${ThisArray.a.b.c}"`)
} else {
console.log(`ThisArray["a"]["b"]["c"] is NOT defined!`);
}
go with try catch
var thirdDimensionValue = null;
try{
thirdDimensionValue = ThisArray["a"]["b"]["c"]
}
catch{
thirdDimensionValue = null
}
if(thirdDimensionValue){
console.log("value exist")
}
else{
console.log("No value exist in the property")
}
So I'm trying validate the two dropdowns that I have on button click. When the dropdowns first initiate, they are initiated with a value of undefined because nothing has been selected. This is what I want. But when I click the add button to validate the dropdowns before I add another row, the validation never occurs.
JS
ko.validation.init({
insertMessages: false,
errorMessageClass: "ErrorLine"
});
ko.validation.rules['bothUndefined'] = {
getValue: function (o) {
return (typeof o === 'function' ? o() : o);
},
validator: function (val, params) {
var self = this;
var anyOne = ko.utils.arrayForEach(params, function (param) {
if (typeof param === "function") {
return typeof param() === "undefined";
} else {
return (typeof param === "undefined");
}
});
return (typeof anyOne !== "undefined");
},
message: 'Please select one change.'
};
ko.validation.registerExtenders();
function BookPossessionTransferVM() {
var self = this;
.
.
.
self.PossessionChanges = ko.observableArray([]);
self.PossessionChangesErrors = ko.validation.group(self.PossessionChanges(), { deep: true, live: true });
self.PossessionChanges.push(new PossessionChangeVM(self.PossessionChanges().length +1))
.
.
.
self.addPossessionChange = function () {
if (self.PossessionChanges().length < 1) {
self.PossessionChanges.push(new PossessionChangesVM(self.PossessionChanges().length + 1,
self.AllFrom()));
} else {
self.PossessionChangesErrors.showAllMessages();
}
}
}
function PossessionChangeVM(possessionChangeId) {
var self = this;
self.possessionChangeId = ko.observable(possessionChangeId);
self.SelectedFrom = ko.validatedObservable();
self.SelectedTo = ko.validatedObservable();
self.IsValidRow = ko.pureComputed(function() {
return typeof self.SelectedFrom !== "undefined" && typeof self.SelectedTo !== "undefined";
}).extend({
bothUndefined: {
params: [self.SelectedFrom, self.SelectedTo]
}
});
self.ChangeType = ko.pureComputed(function() {
if (self.SelectedFrom() !== undefined && self.SelectedTo() !== undefined) {
return 'Update';
} else if (self.SelectedFrom() === undefined && self.SelectedTo() === undefined) {
return '';
} else if (self.SelectedFrom() === undefined) {
return 'Add';
} else if (self.SelectedTo() === undefined) {
return 'Remove';
} else { return ''; }
});
}
After I click the add button, I am expecting PossessionChangesErrors to have one issue since it should load with undefined options. But I am getting nothing. Thanks again for helping!
EDIT:
Now I have the validation working, but I am not able to clear the validation to create a new row once one of the drop downs have been selected. Here is the fiddle: https://jsfiddle.net/p6x1nqm5/18/
Turns out I just didn't have the correct logic for the validation. Here is the new fiddle with the changes. https://jsfiddle.net/zw80kh2n/2/
self.IsValidRow became
self.IsValidRow = ko.pureComputed(function() {
return (!(self.SelectedFrom() === undefined && self.SelectedTo() === undefined))
}).extend({ bothUndefined: {}
});
and the validation became
ko.validation.rules['bothUndefined'] = {
getValue: function (o) {
return (typeof o === 'function' ? o() : o);
},
validator: function (val) {
return val;
},
message: 'Please select one change.'
};
ko.validation.registerExtenders();
Hi I'm looking to add javascript functions to game maker, but the format of them is like this:
companyname.initialize({
soundMuteCallback: muteSound, // optional
soundUnmuteCallback: unmuteSound // optional
});
And in the file they look like this
this.initialize = function(params) {
companyname.getSharedEventCenter().postEvent(SharedEventKeys.API_INITIALIZE);
_isInitialized = true;
if (typeof params !== "undefined") {
var muteSoundCallback = ("soundMuteCallback" in params && typeof params["soundMuteCallback"] === "function") ? params["soundMuteCallback"] : undefined;
var unmuteSoundCallback = ("soundUnmuteCallback" in params && typeof params["soundUnmuteCallback"] === "function") ? params["soundUnmuteCallback"] : undefined;
_adsManager.setSoundCallbacks(function() {
typeof muteSoundCallback === "function" && muteSoundCallback();
[].forEach.call(document.getElementsByTagName("audio"), function(element){
element.muted = true;
});
}, function() {
typeof unmuteSoundCallback === "function" && unmuteSoundCallback();
[].forEach.call(document.getElementsByTagName("audio"), function(element){
element.muted = false;
});
});
}
_tryShowAd();
};
Does anyone have any idea how to do this in game maker? I don't know what information to put in the extension function properties.
Thanks,
Mitchell.
I would recommend creating a new function that Game Maker can understand and then use that to create your object and the constructor you are showing here.
company.initialize = function(params) {
companyname.getSharedEventCenter().postEvent(SharedEventKeys.API_INITIALIZE);
_isInitialized = true;
if (typeof params !== "undefined") {
var muteSoundCallback = ("soundMuteCallback" in params && typeof params["soundMuteCallback"] === "function") ? params["soundMuteCallback"] : undefined;
var unmuteSoundCallback = ("soundUnmuteCallback" in params && typeof params["soundUnmuteCallback"] === "function") ? params["soundUnmuteCallback"] : undefined;
_adsManager.setSoundCallbacks(function() {
typeof muteSoundCallback === "function" && muteSoundCallback();
[].forEach.call(document.getElementsByTagName("audio"), function(element){
element.muted = true;
});
}, function() {
typeof unmuteSoundCallback === "function" && unmuteSoundCallback();
[].forEach.call(document.getElementsByTagName("audio"), function(element){
element.muted = false;
});
});
}
_tryShowAd();
};
function createMuteCallback() {
muteCallback = function () {
// Code to handle the callback
}
return muteCallback;
}
function createUnmuteCallback() {
unmuteCallback = function () {
// Code to handle the callback
}
return unmuteCallback;
}
function createCompany (mute, unmute) {
if (mute == 1) {
soundMuteCallback.createMuteCallback();
}
if (unmute == 1) {
soundUnmuteCallback.createUnmuteCallback();
}
company.initialize(soundMuteCallback, soundUnmuteCallback);
}
So all of that goes in the same .js file. Create a new extension in Game Maker. Add the .js file to that extension. Add a function named createCompany with two optional parameters.
Then when you call createCompany(1, 1); in your Game Maker code, the .js file will run and will initialize the company object with the two callback functions.
Hope this helps.
I'm making a code that removes a videoplayer from the page and then places it back when needed (even if the element doesn't have an id).
I'm finding issues with IE7
Here is my code:
var weboElem, weboElemPar, weboElemIndex, weboStored;
function weboRemoveVideoplayer(vpId){
weboElem = document.getElementById(vpId);
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
var child = weboElem;
while( (child = child.previousSibling) != null )
weboElemIndex++;
weboElemPar.removeChild(weboElem);
return true;
}
function weboPlaceVideoplayerBack(){
if(weboElemPar.insertBefore !== undefined && weboElemPar.childNodes !== undefined)
{
weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
return true;
}
return false;
}
var result = document.evaluate(
'//*/param[contains(#value, "autoplay=1")]/..', // XPath expression
document, // context node
null, // namespace resolver
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
} else document.getElementById('info').innerHTML = "not found";
(Note that document.evaluate WORKS because I imported javascript-xpath library)
On IE7 if the XPath finds an IFRAME there are no problems and it works but if it finds an OBJECT does nothing and stops at weboElem = document.getElementById(vpId); as if it didn't find the id.
I tried modifying the code like this:
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
node.parentNode.removeChild(node);
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
if(node.nodeName.toLowerCase() == "object") weboStored = node;
else weboStored = null;
} else document.getElementById('info').innerHTML = "not found";
and it works, the videoplayer disappears at page load. I want to use the function though, so I edited everything like this (storing the node into a global var that later I get in the weboRemoveVideoplayer function):
var weboElem, weboElemPar, weboElemIndex, weboStored;
function weboRemoveVideoplayer(vpId){
if(!weboStored) weboElem = document.getElementById(vpId);
else weboElem = weboStored;
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
var child = weboElem;
while( (child = child.previousSibling) != null )
weboElemIndex++;
weboElemPar.removeChild(weboElem);
alert("5");
return true;
}
function weboPlaceVideoplayerBack(){
if(weboElemPar.insertBefore !== undefined && weboElemPar.childNodes !== undefined)
{
weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
return true;
}
return false;
}
// bind XPath methods to document and window objects
// NOTE: This will overwrite native XPath implementation if it exists
//XPathJS.bindDomLevel3XPath(); //solo per xpathJs
var result = document.evaluate(
'//*/param[contains(#value, "autoplay=1")]/..', // XPath expression
document, // context node
null, // namespace resolver
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE
);
if(result.snapshotLength > 0)
{
var node = result.snapshotItem(0);
node.id = "webo";
node.parentNode.removeChild(node);
document.getElementById('info').innerHTML = node.nodeName.toLowerCase()+" -> "+node.id;
if(node.nodeName.toLowerCase() == "object") weboStored = node;
else weboStored = null;
} else document.getElementById('info').innerHTML = "not found";
This way the code blocks itself when trying to retrieve the parent node.
Could someone suggest me what to do here?
PS: with chrome and firefox the code works perfectly in the first version I posted.
Fixed it!
I solved the issue by wrapping the OBJECT inside a div with an id of my choice which I can retrieve whenever I want. I do this in the resolveXpath function.
Here the code:
var weboElem, weboElemPar, ieObject = false;
var weboElemIndex = 0;
function weboRemoveVideoplayer(vpId){
var child;
if(!ieObject) weboElem = document.getElementById(vpId);
else weboElem = document.getElementById('my_usage');
if(!weboElem) return false;
weboElemPar = weboElem.parentNode;
weboElemIndex = 0;
child = weboElem;
while( (child = child.previousSibling) != null ) weboElemIndex++;
if(typeof weboElemPar.removeChild !== 'undefined') weboElemPar.removeChild(weboElem);
else return false;
return true;
}
function weboPlaceVideoplayerBack(){
if(typeof weboElemPar.insertBefore !== 'undefined' && typeof weboElemPar.childNodes !== 'undefined' && typeof weboElemPar.appendChild !== 'undefined'){
if(weboElemPar.childNodes.length > 0 && weboElemIndex < weboElemPar.childNodes.length) weboElemPar.insertBefore(weboElem, weboElemPar.childNodes[weboElemIndex]);
else weboElemPar.appendChild(weboElem);
return true;
}
return false;
}
function resolveXpath(path)
{
//XPathJS.bindDomLevel3XPath(); //solo per xpathJs
var result = document.evaluate(path,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);
if(result.snapshotLength > 0){
var child, node = result.snapshotItem(0);
if(node.nodeName.toLowerCase() == 'object'){
ieObject = true;
child = node;
while( (child = child.previousSibling) != null ) weboElemIndex++;
var div = document.createElement('div');
div.id = 'my_usage';
if(typeof node.parentNode.insertBefore !== 'undefined' && typeof node.parentNode.childNodes !== 'undefined' && typeof node.parentNode.appendChild !== 'undefined'){
if(node.parentNode.childNodes.length > 0 && weboElemIndex < node.parentNode.childNodes.length) node.parentNode.insertBefore(div,node.parentNode.childNodes[weboElemIndex]);
else node.parentNode.appendChild(div);
div.appendChild(node);
} else return false;
} else node.id = 'my_usage';
return true;
} else return false;
}
resolveXpath('//*/param[contains(#src, "autoplay=1")]/..');
Variable CIMtrek_Attachement_1 getting undefined it is not checking the if condition it moving to this line var selecteditems = CIMtrek_Attachement_1.split("\\");
var CIMtrek_Attachement_1= $("#CIMtrek_RegWhseCo_Attachement_1").val();
alert("CIMtrek_Attachement_1=666666==>> "+CIMtrek_Attachement_1);
if (CIMtrek_Attachement_1 !== null && CIMtrek_Attachement_1 !== "" && CIMtrek_Attachement_1 === undefined)
{
var selecteditems = CIMtrek_Attachement_1.split("\\");
var filename = selecteditems[(selecteditems.length-1)];
alert("selecteditems=666==>> "+selecteditems);
alert("filename=66666==>> "+filename);
nodeField = createNodeField(xmlDoc, new Array("FieldName"), "Record")
nodeField.attributes[0].value = NewFormFields[i]
nodeField.appendChild(xmlDoc.createTextNode(filename));
rootElement.appendChild(nodeField);
}
try typeof(CIMtrek_Attachement_1) === undefined :) and shouldn't it be !== instead of === ?