I would like to know if the way I have assigned values to the 'Deval' and 'Reval' variables in the 'datevalidate' method is correct?
If you notice my code, I am assigning values by specifying the entire chain pointing to the method like so 'x9.validator.check_element_val()'. Can I make a less explicit call? Since I am trying to access a function outside the immediate lexical scope of these variables, is there some way I can use a closure to better approach this?
Kindly correct my understanding of closures if it is not apt for the current scenario.
var x9 = {} || x9;
x9.validator = {
mode : 1,
check_element_val : function(el){
var returnval = 0;
if (el.value == 0 || el.value == undefined || el.value == null || el.value == ''){
returnval = 0;
}else{
returnval = 1;
}
return returnval;
},
datevalidate : function(mode, dep_el, ret_el){
var returnobj = new Object();
if (mode == 1){
Deval = x9.validator.check_element_val(dep_el);
Reval = x9.validator.check_element_val(ret_el);
if (Deval == 0 || Reval == 0){
returnobj.returnval = false;
}else{
returnobj.returnval = true;
}
}
return JSON.stringify(returnobj);
}
};
Thanks in advance.
Perhaps you would benefit from the Module pattern (see this simple example). You could do something like this:
var x9 = {} || x9;
x9.validator = (function() {
var mode = 1;
var check_element_val = function(el){
var returnval = 0;
if (el.value == 0 || el.value == undefined || el.value == null || el.value == ''){
returnval = 0;
}else{
returnval = 1;
}
return returnval;
};
var datevalidate = function(mode, dep_el, ret_el){
var returnobj = new Object();
if (mode == 1){
Deval = check_element_val(dep_el);
Reval = check_element_val(ret_el);
if (Deval == 0 || Reval == 0){
returnobj.returnval = false;
}else{
returnobj.returnval = true;
}
}
return JSON.stringify(returnobj);
}
return {
mode : mode,
check_element_val : check_element_val,
datevalidate : datevalidate
};
})();
As a side note, I'm not sure what you were trying to do with the mode variable, but be aware that the datevalidate function will not be using it unless you supply it yourself as an argument, for instance:
var validation = x9.validator.datevalidate(x9.validator.mode,someValue1,someValue2);
If you want the function to only use the mode variable from within the validator, remove mode from the argument list. If you want to keep the ability to provide different modes, though, you can write an additional function. For example:
var datevalidate_default_mode = function(dep_el,ret_el) {
return datevalidate(mode, dep_el, ret_el);
};
I think it looks nicer than adding x9.validator.mode to the datevalidate function every time you want to use the default value. And that way you can even remove mode from the module output. Either way, if you're adding a new public function, don't forget to expose it in the module output as well!
Related
First of all I'm not a programmer. I need to use some really basic HTML, CSS and XML for my work. The program I am using allows running javascripts, too.
I usually have a lot of variables from my XML files. They go by something like this:
VAL001
VAL002
VAL003
VAL004
You get it.
These variables are often checkboxes. The values can be either 'Checked' or 'Unchecked'.
Instead of embedding these variables in the HTML code, I tend to convert it to something else so it gets nicer. Like this:
if ( VAL001 == 'Checked' ) CHK001 = '✓';
else CHK001 = '';
When this is done, I insert CHK001 (instead of VAL001) in the HTML so I get a nice check mark if the box was checked and nothing when it was not checked. When there are a lot of these boxes it's not too effective to do it one by one.
What I tried in JavaScript is:
var i;
for ( i = 1, i <= 9, i++ ) {
if ( VAL00$i == 'Checked' ) CHK00$i = '✓'
else CHK00$i = '';
}
var j;
for ( j = 10, j <= 99, j++ ) {
if ( VAL0$j == 'Checked' ) CHK0$j = '✓'
else CHK0$j = '';
}
I thought that this would replace the last digits with i and j and I would get what I need. Unfortunately this just brings up a ReferenceError saying that VAL00$i can't be found.
If I replace the $i and $j with [i] and [j] I get the same ReferenceError but this time i and j are not told to be wrong so I get that VAL00 can't be found. A simple solution would really speed up things for me. Thank you in advance!
You could put your variables in an array and use map to check and change the variables to be a tick or not.
var array = [
VAL001,
VAL002,
VAL003,
VAL004
];
var newArray = array.map(val=>{
if (val === 'Checked') return '✓';
else return '';
});
Alteratively, if you need to know the names of the variables after checking everything you could use an object.
var obj = {
VAL001: VAL001,
VAL002: VAL002,
VAL003: VAL003,
VAL004: VAL004
};
var newObj;
for (var i of Object.keys(obj){
if (obj[i] === 'Checked') newObj[i] = '✓';
else newObj[i] = '';
}
If you are having VAL001 variables as property in obj then you can perform like below.
Here i.toString().padStart(3, 0), for i = 1 it will return 001 similarly for i=10 it will return 010; You can access property of object with obj[propertyName]. So these values will be accessible with obj[VAL${index}].
var obj = {
VAL001: 'Checked',
VAL002: '',
VAL003: 'Checked',
VAL004: '',
VAL010: '',
VAL099: 'Checked',
};
var result = {};
for (var i = 1; i <= 99; i++) {
let index = i.toString().padStart(3, 0);
if (obj.hasOwnProperty(`VAL${index}`)) {
if (obj[`VAL${index}`] == 'Checked') result[`CHK${index}`] = '✓'
else result[`CHK${index}`] = '';
}
}
console.log(result);
If you are having variables in global scope then you can use windows["VAL001"].
var VAL001 = 'Checked',
VAL002 = '',
VAL003 = 'Checked',
VAL004 = '',
VAL010 = '',
VAL099 = 'Checked';
for (var i = 1; i <= 99; i++) {
let index = i.toString().padStart(3, 0);
if (window.hasOwnProperty(`VAL${index}`)) {
if (window[`VAL${index}`] == 'Checked') window[`CHK${index}`] = '✓'
else window[`CHK${index}`] = '';
console.log(`CHK${index} = ` + window[`CHK${index}`]);
}
}
We are lacking some information about your environment, but assuming your framework gives you a set of global variables, this should get you started:
for (var i=1, i<=99, i++) {
var i_padded = i.toString().padStart(3, 0);
if (window["VAL" + i_padded] == 'Checked') {
window["CHK" + i_padded] = '✓';
} else {
window["CHK" + i_padded] = "";
}
}
In order to access your global variables I am using the window object here. This is assuming you are running this JS in a browser or browser-like environment.
I am getting a value as a string from cookie which has multiple values stored in it.
I am separating these values with the use of the split() function, but I am getting an error continuously. Here is my code. It would be a great help if anyone can help me out with this.
var sourcez = jQuery.cookie("Source");
var mediumz = jQuery.cookie("Medium");
function utmze(eutmz) {
var utmz_val = jQuery.cookie("__utmzz");
for (var o = utmz_val, r = o.split("|"), a = 0; (a < r.length); a++) {
var t = r[a].split("=");
if (t[0] == eutmz) {
return t[1];
}
}
}
Make sure that string is not empty , null and undefined before you are performing the split action
function isValidString(input){
if(input != null && input != '' && input != undefined){
return true;
}
return false;
}
if(isValidString(input)){
input.split('=');
}
Make the following changes to avoid the error:
var sourcez = jQuery.cookie("Source");
var mediumz = jQuery.cookie("Medium");
function utmze(eutmz) {
var utmz_val = jQuery.cookie("__utmzz");
for (var o = utmz_val, r = o.split("|"), a = 0; (a < r.length); a++) {
if (typeof r[a] != "undefined") { // Checking if the variable is defined.
var t = r[a].split("=");
if (t[0] == eutmz) {
return t[1];
}
}
}
}
I'm trying the following code:
var var1 = "";
var var2 = "test";
var var3 = "";
vars = new Array('var1','var2','var3');
var count = 0;
for (var i = 0; i < vars.length; ++i) {
var name = vars[i];
if (field_is_empty(name)) {
count++;
}
}
console.log(count);
function field_is_empty(sValue) {
if (sValue == "" || sValue == null || sValue == "undefined")
{
return true;
}
return false;
}
The result here should have been count = 2 because two of the variables are empty but it's always 0. I guess it must something when using if (field_is_empty(name)) because it might not getting the name converted to the name of the actual var.
PROBLEM 2# Still related
I've updated the code as Karthik Ganesan mentioned and it works perfectly.
Now the code is:
var var1 = "";
var var2 = "test";
var var3 = "";
vars = new Array(var1,var2,var3);
var count = 0;
for (var i = 0; i < vars.length; ++i) {
var name = vars[i];
if (field_is_empty(name)) {
count++;
}
}
console.log(count);
function field_is_empty(sValue) {
if (sValue == "" || sValue == null || sValue == "undefined")
{
return true;
}
return false;
}
And the problem is that if add a new if statement something like this:
if (count == '3') {
console.log('AllAreEmpty');
} else {
for (var i = 0; i < vars.length; ++i) {
var name = vars[i];
if (field_is_empty(name)) {
//Set the empty variables as "1900-01-01"
variableService.setValue(name,"test");
}
}
}
It does nothing and I've tested using variableService.setValue('var1',"test") and it works.
PS: The variableService.setValue is a function controlled by the software I don't know exactly what it does I know if use it like mentioned on above line it works.
In your first attempt you used the variable names as strings when you created an array. You need to either use the values themselves:
vars = new Array(var1,var2,var3);
or if you insist to use them by their names, then you need to find them by names when you use them:
if (field_is_empty(window[name])) {
It does nothing
That's not really possible. It could throw an error, or enter the if or enter the else, but doing nothing is impossible. However, since you intended to use the variables by name in the first place (probably not without a reason) and then you intend to pass a name, but it is a value and it does not work as expected, I assume that your initial array initialization was correct and the if should be fixed like this:
var var1 = "";
var var2 = "test";
var var3 = "";
vars = new Array(var1,var2,var3);
var count = 0;
for (var i = 0; i < vars.length; ++i) {
var v = window[vars[i]]; //You need the value here
if (field_is_empty(v)) {
count++;
}
}
console.log(count);
if (count == '3') {
console.log('AllAreEmpty');
} else {
for (var i = 0; i < vars.length; ++i) {
var v = window[vars[i]];
if (field_is_empty(v)) {
//Set the empty variables as "1900-01-01"
variableService.setValue(vars[i],"test");
}
}
}
function field_is_empty(sValue) {
if (sValue == "" || sValue == null || sValue == "undefined")
{
return true;
}
return false;
}
You definitely incorrectly initialize array, you put strings "var1", "var2", "var3" instead of references to strings (variables).
Try this:
vars = new Array(var1,var2,var3);
Your array is wrong
it should be
vars = new Array(var1,var2,var3);
here is the jsfiddle
I have a javascript/jquery function that displays a notification. I want to make this function display a different mode if they aren't on x, y and z page.
This is how I tried to achieve this:
function display_alert(message, type, delay, mode)
{
type = (typeof type === "undefined") ? "danger" : type;
delay = (typeof delay === "undefined") ? 3000 : delay;
mode = (typeof mode === "undefined") ? 'normal' : mode;
var current_location = document.URL;
var home_locations = ['home', 'remote', 'zip'];
for (var i = 0; i < home_locations.length; i++)
{
if (current_location.toString().indexOf(home_locations[i]) == -1)
{
// alert(home_locations[i]); return;
mode = 'top';
break;
}
}
...
So if document.URL doesn't contain one of the array elements, then I want the mode variable to become top.
I think this is a simple problem, but I just can't see how to fix it.
You could use a regular expression built with your home_locations array :
var home_regex = new RegExp('('+home_locations.join('|')+')');
// home_regex = /(home|remote|zip)/;
if (!home_regex.test(document.URL)) mode = 'top';
You need to reverse the logic in your loop...
var current_location = document.URL;
var home_locations = ['home', 'remote', 'zip'];
var found = false;
for (var i = 0; i < home_locations.length; i++)
{
if (current_location.toString().indexOf(home_locations[i]) >= 0)
{
found = true;
break;
}
}
if (!found) {
mode = 'top';
}
I'm dealing with a ball-of-mudd project that uses frames & iframes to create a "customizable" interface (like people did in 2002).
The application runs from within a hta and kind of emulates a real WPF style app. I need to capture keys so I can selectively change/refresh some of the subframes.
What I'm trying to do is, if there was a sub-sub frame called desktop and that had some frames in it how would I capture an event, safely, across all frames; and refresh a frames subframes?
Any help appreciated; I accept no responsibility for nausia caused by repeating the last paragraph too many times. :)
Answering to get the formatting
arrFrames[i].document.onkeypress = function(){
var evtobj = window.event ? event : e;
evtobj.cancelBubble = true;
if (evtobj.stopPropagation){ evtobj.stopPropagation();}
top.console.log(evtobj.type+' - '+(evtobj.which?evtobj.which:evtobj.keyCode));
};
I don't know anything about HTA, but the question is marked as javascript / jquery / iframe, so i'll guess it isn't a problem...
You can use an object in window.top to manage your events in a centralized place.
In your main window, you use something like:
var getTopObject = function() {
return window.top.topObject;
}
var TopClass = function () {
this.processClick = function (frame) {
//do something...
alert('click in ' + frame.document.location.toString());
var msj = frame.document.getElementById("msj");
msj.innerHTML = "change!";
};
}
window.top.topObject = new TopClass();
And then, on every iframe, you put:
window.onclick = function () { getTopObject().processClick(window); };
That way you get notified of the click event.
Also note that inside the 'processClick' function in the example you can access the iframe document.
Of course, you can do this a lot more complex, but that's the basic idea. You will have to deal with different events in your case.
Hope this helps, and sorry for my english!
Working; digs through the frames in a loop using a function calling itself; I limited it to 8 rather as I know thats the deepest it will get. You can always change that yourself.
var XXX_util_keyboard = function()
{
//"private" variables:
var objTopWindow = top.window.frames,
arrFrames = [],
MaxDepth = 8;
//"private" methods:
var AddToArray = function(obj){
if(typeof obj.document != "undefined") {
arrFrames.push(obj);
return true;
}
return false;
};
var DeleteFromArray = function(obj){
if(typeof obj != "undefined") {
arrFrames.splice(arrFrames.indexOf(obj), 1);
return true;
}
return false;
};
var FrameLoop = function(objFrames){
if(MaxDepth > 0){
if(objFrames !== null)
{
for(var k = 0; k < objFrames.frames.length; k++)
{
var tmp = objFrames.frames[k];
AddToArray( tmp );
FrameLoop( tmp );
}
this.MaxDepth--;
}
}
};
var AttachEvent = function(key, fn) {
for(var i = 0; i < arrFrames.length; i++){
arrFrames[i].document.onkeypress = function(e) {
var evt = e || window.event,
charCode;
if(evt === null){ evt = this.parentWindow.event; /*IE doesnt capture scope correctly*/ }
charCode = evt.keyCode || evt.which;
alert(charCode);
evt.cancelBubble = true;
if (evt.stopPropagation){ evt.stopPropagation();}
};
}
};
return {
init: function()
{
AddToArray(this.getTopWindow()[0]);
FrameLoop(this.getTopWindow()[0]);
},
getFrames: function()
{
if(arrFrames.length < 1){ FrameLoop(objTopWindow[0]); }
return arrFrames;
},
getTopWindow: function()
{
return objTopWindow === undefined ? window.frames : objTopWindow.window.frames;
},
attachEvent: function()
{
if(arrFrames.length < 1){ FrameLoop(objTopWindow[0]); }
AttachEvent();
}
};
}();