0

I have two javscript files f1.js and f2.js in the same directory/folder which are part of a web application. f1 is responsible for displaying jqxdatagrid with multiple rows and columns.

My goal :

I am basically trying to figure out a way to call function f2 when a user clicks on a row of the jqxdatagrid. All the logic related to grabbing row data is defined in f1.js inside this line $("#dataDocumentPanel").on('rowclick',function(event){

My Attempt:

I was looking at this post Call variables from one javascript file to another So I declared var SUBTYPE

which will initialize mySubtype.

In order to access the above value, I did the following in f2.js

var forf1 = new Object;

alert(forf1.mySubtype);

So, before doing anything, I want to check via alert whether I am getting the value of mySubtype in f2.js or not.

Please correct me if I am wrong but the reason because alert in f2.js isn't working is because I feel like I would need to call the f2 file when a user clicks on a particular row of jqxdatagrid. I mean something needs to happen on this line $("#dataDocumentPanel").on('rowclick',function(event){ ?

Here are my two javascript files :

f1.js

function f1() {

    var self = this;


    this.urlKey = "showIDNumber";

    this.getData = function (IDNumber_) {

        //Some code related to ajax reques
        .done(function (data_, textStatus_, jqXHR_) {

             self.processdataDocuments(data_.data_document_list);
          })
        .fail(function (jqXHR_, textStatus_, errorThrown_) {
           // some code here
        });
    };


    // Initialize the page
    this.initialize = function () {

        self.getData(IDNumber);
    };



    this.processdataDocuments = function (collection_) {
        var source =
        {
           localdata: collection_,
           datatype: "array"
         };
     var dataAdapter = new $.jqx.dataAdapter(source, {
                loadComplete: function (data) { },
                loadError: function (xhr, status, error) { }
            });
     $("#dataDocumentPanel").jqxGrid(
            // some code here to populate jqxgrid
             });
      // For getting the contents of a row, I am using jqxgrid approach as mentioned in their doc here :
      //    http://www.jqwidgets.com/getting-the-clicked-grid-row/           

      $("#dataDocumentPanel").on('rowclick',function(event){

           var row = event.args.rowindex;

           var datarow = $("#dataDocumentPanel").jqxGrid('getrowdata', row);
           var jsonStringify = JSON.stringify(datarow,null,10);
           alert(jsonStringify); // This alert displays the JSON data in a formatted manner 
           var obj = jQuery.parseJSON(response);
           //alert("display Subtype "+obj.nc_subtype)  // Works fine

           var SUBTYPE = {

             mySubtype : obj.nc_subtype
          };


         });

    };
};

f2.js

function f2() {


     var self = this;

     var forf1 = new Object;

    alert(forf1.mySubtype); // Trying to display obj.nc_subtype value from f1

     this.getData = function (IDNumber_) {

        // some code will be here      

        var ajaxRequest = jQuery.ajax({
            // some code will be here
        })
        .done(function (data_, textStatus_, jqXHR_) {
            // some code will be here
         })
        .fail(function (jqXHR_, textStatus_, errorThrown_) {
           // some code will be here
        });
    };

}
Community
  • 1
  • 1
Tan
  • 1,433
  • 5
  • 27
  • 47

1 Answers1

1

From Properties of Javascript function objects

You could make f1 into a class (as F1, since classes are uppercased) with

var F1 = (function() {
    var cls = function() { }

    var self = cls.prototype;

    self.foo = "Foo";
    self.bar = funciton() { ... },
    ...

    return cls;
})();

From there, provided that you're referencing both f1 and f2 in your HTML page, you can create an F1 object with

var f1 = new F1();

and then access its properties simply by doing

f1.property

and assigning them with

f1.property = ...

To set mySubType of f1, instead of

var SUBTYPE = {
    mySubtype : obj.nc_subtype
};

do

self.mySubtype = ...

which will assign f1.mySubtype.

Here is an example snippet with f1 and f2 turned into classes (F1 and F2), with F2 objects creating an F1 object and accessing its mySubtype. In the demo I set F1.mySubtype to the string Foo, and created an f2, so when the snippet is run it should print "Foo"; however, in the real program those two things should probably be removed:

//f1.js ---

var F1 = (function() {
    var cls = function() { }

    var self = cls.prototype;
  
    self.urlKey = "showIDNumber";

    self.getData = function (IDNumber_) {

        //Some code related to ajax reques
        this.done(function (data_, textStatus_, jqXHR_) {

             self.processdataDocuments(data_.data_document_list);
        });
        this.fail(function (jqXHR_, textStatus_, errorThrown_) {
           // some code here
        });
    };

    // Initialize the page
    self.initialize = function () {

        self.getData(IDNumber);
    };

    self.processdataDocuments = function (collection_) {
        var source =
        {
           localdata: collection_,
           datatype: "array"
         };
     var dataAdapter = new $.jqx.dataAdapter(source, {
                loadComplete: function (data) { },
                loadError: function (xhr, status, error) { }
            });
      $("#dataDocumentPanel").jqxGrid({
            // some code here to populate jqxgrid
      });
      // For getting the contents of a row, I am using jqxgrid approach as mentioned in their doc here :
      //    http://www.jqwidgets.com/getting-the-clicked-grid-row/           

      $("#dataDocumentPanel").on('rowclick',function(event){

           var row = event.args.rowindex;

           var datarow = $("#dataDocumentPanel").jqxGrid('getrowdata', row);
           var jsonStringify = JSON.stringify(datarow,null,10);
           alert(jsonStringify); // This alert displays the JSON data in a formatted manner 
           var obj = jQuery.parseJSON(response);
           //alert("display Subtype "+obj.nc_subtype)  // Works fine
        
           self.mySubtype = obj.nc_subtype;
         });

    };
  
    //I added this line for the demo to show 'f2' accessing this property from 'f1'. You should remove it if copying this code into your application
    self.mySubtype = "Foo";

    return cls;
})();

var f1 = new F1();

//f2.js ---

var F2 = (function() {
     var cls = function() { }

     var self = cls.prototype;

     alert(f1.mySubtype);

     self.getData = function (IDNumber_) {

        // some code will be here      

        var ajaxRequest = jQuery.ajax({
            // some code will be here
        })
        .done(function (data_, textStatus_, jqXHR_) {
            // some code will be here
         })
        .fail(function (jqXHR_, textStatus_, errorThrown_) {
           // some code will be here
        });
    };

    return cls;
})();

var f2 = new F2();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Community
  • 1
  • 1
Doc
  • 281
  • 3
  • 5
  • Thanks. Yes, I have both the files included in the HTML. For some reason, specifying `self.mySubtype = obj.nc_subtype;` in `f1` is prohibiting page from loading. However, with `var SUBTYPE = { mySubtype : obj.nc_subtype };` page loads perfectly fine. I hope you didn't mean to define `f2();` in the very last line? – Tan Aug 02 '16 at 18:07
  • Also, changing `function f1()` to `f1 = { ...` is breaking the page loading. Do you think it's possible to keep both the functions as it is ( By as it is I mean, we don't change `function f1()` to `f1 = { ...` and keep it as `function f1()` only) and achieve the goal? Thanks – Tan Aug 02 '16 at 18:18
  • You can see what's breaking the page from loading by looking at the browser console; right-click in the webpage and you should see an option "Inspect Element". Click on that, and a mini-editor should pop up in the browser, usually below the page. There should be a "Console" option on that mini-editor; click on it. Then, wherever there's a red line, an error occurred. It should show the name of the file that's causing the error on the right of the line, and if its your file, click on that name and it should take you into the source, showing the line the error occurred on – Doc Aug 02 '16 at 18:25
  • I think the `self.mySubtype = obj.nc_subtype` case isn't working because `obj` is nil, or doesn't have the property `nc_subtype`. Check `response` – Doc Aug 02 '16 at 18:29
  • This line works fine and I get the result in my original code `//alert("display Subtype "+obj.nc_subtype) // Works fine` – Tan Aug 02 '16 at 18:31
  • For the second case, I think you can keep `f1` as a function if you do `var f1 = function() { ... `, and then replace `this.property` with `f1.property` (this also means assigning `self` to `f1`). Also I just put `f2();` in the last line for the demo, like with `mySubtype: "Foo"`; you don't need it in your program – Doc Aug 02 '16 at 18:33
  • Hmm, for second case, in `f2.js`, I was trying to do like this `var f1 = new f1();` and then specify in alert `alert(f1.mySubtype)`. Could you please update your solution to match this ( I mean keeping f1 as a function). Thanks – Tan Aug 02 '16 at 18:38
  • Ok I edited the answer to show you how to make a class, so you can do something like `var f1 = new f1();` (in this case it's actually `var f1 = new F1();`, since classes typically have uppercase names – Doc Aug 02 '16 at 19:13
  • Thanks very much. Sorry to bother you but do you think we can keep the original functions in f1.js `f1() { }` and `f2() { }` in f2.js . I mean if we don't turn them into classes and just try to achieve the functionality by keeping both the functions in respective javascript file? – Tan Aug 02 '16 at 19:34
  • If you don't want them to be classes, than just make them lowercase again (so `var f1 = (function() {...` instead of `var F1 = ...`), remove `cls = ...` and replace `self` with `self = cls.prototype;`, and return `self` instead of `cls`. Then you can't do `var f1 = new F1();`; you would have to remove all those occurrences. – Doc Aug 02 '16 at 19:47
  • Alternatively, you could just do `var f1 = new F1();` in your `f1.js` and `var f2 = new F2();` in your `f2.js`. Then, you still have the classes `F1` and `F2`, but you can use their global instances `f1` and `f2`, without declaring them anywhere else – Doc Aug 02 '16 at 19:49
  • I mean if I want to keep the functions as defined in the original code. So for example in `f1.js` it will start with `function f1() { ... }` and in `f2.js` , it will start like `function f2{ .. } `. So basically I would not prefer to start my `f1.js` with `var f1 = (function() ....` and `f2.js` with `var f2 = ( function () ..`. Thanks – Tan Aug 02 '16 at 19:58
  • Try using your original code, but replacing `this` with `f1` and `f2` (and replacing `var SUBTYPE = { mySubtype : obj.nc_subtype };` with `self.mySubtype = obj.nc_subtype`). If this doesn't work and fails on the line of the first property you assign to `f1`, then take all of the property assignments out of the function and don't use `self`, so you have something like `function f1() { } f1.urlKey = "showIdNumber";`. If both of these things don't work than I think you have to assign `f1` to a variable. – Doc Aug 02 '16 at 20:10
  • I believe replacing `this` with `f1` everywhere in `f1.js` is same as keeping `this` ? Same for replacing `this` with `f2` everywhere in `f2.js` ? I replaced `var SUBTYPE = { mySubtype : obj.nc_subtype }; `with `self.mySubtype = obj.nc_subtype` in `f1.js` and in `f2.js`, I tried to do like this `var x = new f1() ; alert (x.mySubType);` . I hope I am doing correctly in `f2.js` ? It hasn't worked till now. ( Also I haven't replaced `this` with `f1` and `f2` till now; thought of asking first before proceeding) – Tan Aug 02 '16 at 21:20
  • Look at http://stackoverflow.com/questions/4195970/what-does-this-mean; it goes over the possible values of `this`. `this` inside of a function declared by `function x() { ... }` doesn't refer to the function unless you call the function like this: `x.call(x, args ...)` or `x.apply(x, args)`. So you could do something like `function _f1() { /* code in original function f1() with this */ }` with `function f1() { _f1.apply(_f1, arguments) }`. But that's kind of hackish, and at least to me just replacing `this` with the function name seems better – Doc Aug 02 '16 at 22:54
  • Thanks. I am checking by replacing `this` with function name everywhere. In the interim, one thing I am wondering, how would `f1.js` know that `f2.js` is the next javascript file to transfer its variable to. I know both the files have been included in the html but still there are other JS files as well. I was wondering if something needs to be done within `f1.js` which will make sure that the variable gets passed to the `alert` of `f2.js`. Thanks – Tan Aug 02 '16 at 23:16
  • Update: I tried assigning `f` to the variable approach and it seems like the control is not getting transferred to `f2`. It's the same result that I saw with my original code. And replacing `this` with `f1` approach didn't work either. :( – Tan Aug 03 '16 at 01:46
  • You can look at or copy the code in the snippet in my answer, which at least works on my browser. See if there are any differences. Also, make sure the code doing `f1.mySubtype = ...` is actually being called and that `f1.mySubtype` is actually being assigned; if `f2` is called before the assignment happens, than `f1.mySubtype` will be undefined and it will look like before. – Doc Aug 03 '16 at 02:15
  • Thanks. Copying my code in the snippet works but same code in application doesn't. By the way `var f1 = new F1();` and `var f2 = new F2();` are required at the end of `f1.js` and `f2.js` respectively, right? I saw that in your previous snipped edit you moved `var f1 = new F1();` from `f2.js` to the end of `f1.js`. – Tan Aug 03 '16 at 14:19
  • It looks like when I moved your declaration of `self.mySubtype = "Foo";` inside the `.on( ` function, you will see `undefined` for the ` `alert(f1.mySubtype);`. Is it like `f2` is not able to access the property from `f1` in this case? – Tan Aug 03 '16 at 14:50
  • Yes you need `var f1` and `var f2`, and they need to be assigned after `F1` and `F2` in their respective files. `alert(f1.mySubtype)` is probably undefined because the `alert` is called before the function in `.on`, which actually defines `mySubtype`. Move the alert to where you actually need to use `mySubtype` (like in the `self.getData` function), or put it in the `cls` declaration in `f2` (`var cls = function() { alert(f1.mySubtype); }`), and you can call `f2()` in the `.on` function to make sure `f1.mySubtype` is defined from `f2` – Doc Aug 03 '16 at 17:13
  • Thanks for the clarification. I guess I am not seeing my `f2.js` when I checked the Network section of developer tools which is quite strange as I can see `f1.js` over there. Here is the `loader.js` that is basically included in the HTML and its responsible for loading all JS files. https://jsfiddle.net/pxtxLm90/ Probably this could be the reason `alert` in `f2.js` is not getting called? – Tan Aug 03 '16 at 20:06
  • Usually you have to have `f2.js` included in your html with ``, I don't know how you're loading the scripts here but at least check that that `script` tag is in the HTML from the "Elements" section. Also in the JSFiddle since you're putting everything in a function, you're `this` doesn't refer to the function so when you do `this.property` is assigns `property` to another object (maybe the window) – Doc Aug 03 '16 at 20:17