subscribe one control as listener to events of another

Here is what i have:

I have a datatable ‘books’ that is filled with records, lets say book_id, author_id, author_name and title. When i select one book with id=1234 then another datatable ‘checkouts’ (which is initally empty) fetches data from the server and shows every checkout (date, person_id, name, etc) accessed that particular book.

What i did is bound an ‘onAfterSelect’ event to the ‘books’ grid and got the id of the book. then i use $$(‘checkouts’).load(‘checkouts.php?book_id=1234’)

is there another way of doing it?

i am asking this because at further interaction might create other components that would be dependent on $$(‘books’) selection.

I don’t want $$(‘books’) to know anything about other controls but rather have those controls subscribe/register themselves as listeners to $$(‘books’) “onAfterSelect” event

By default, bind links the component to the master by a single property. If you want to create a more complex binding, you can use something like next

$$("table2").bind( $$("table1"), "$data", function(data, source){
   if (data)
         this.load("some.php?school="+data.school_id+"&year="+data.year);
});

This is great, somehow i kept missing this part of documentation.

One remark though. In my case (other than example above) the master table1 does not have a meaningful id - it’s more of joined view of multiple entities. the query for Table2 needs values from more than one columns from table1. My solution was to use a function for dataFeed property and access selected item from table1 directly.

datafFeed: function(row_id, useless_object) {
    // where useless_object == {id: row_id}
    item = $$('table1').getSelectedItem();
    school_id = item.school_id;
    school_year = item.school_id;
    .... 
    this.load(....);
}

I wonder why is that second argument supplied? I would rather have the whole row (selected item), so that i can do something with the values other than id. And it would be really great if there was yet one more argument - the master object itself - table1. Because who says that a view can’t have multiple masters?

Lets say i have a list of all Hollywood studios in one list (master1) and a tree of genres (master2) and a grid of movies (common_slave).

Or should i look at it differently? I am still trying to grok “the webix way” of doing things.

Damn it! You guys have thought of everything!

It just shows how badly i read documentation. I actually have seen usage of a function as second argument to bind(). And i thought i understood it’s applications well enough. Apparently no!

On the other hand some documentations are better then others :wink:

Yep, while documentation contains all necessary info, it is not so easy to locate the necessary part. We are working to improve it.

Check
http://docs.webix.com/desktop__binding_details.html#usingbindingforserverside

You can use

$$("table2").dataFeed="checkouts.php";
$$("table2").bind( $$("table1") );

As result, each time when record is selected in table1, data in table2 will be reloaded

This isn’t working for me at all. I’ve done exactly as described but nothing happens. I have

news = { id:'news', view:"datatable", ... }
// layout code here...
$$("news").dataFeed = ... ;//url
$$("news").bind($$("companies"), function(a,b,c){ console.log('hello') });

Both datatables show but the “news” table is always blank and the console.log is never run, even if selection changes in “companies” table.

If I change the last line to

$$("news").bind($$("companies", "$data", ...

then the function gets called, but if I select anything in the “news” table then it ALSO calls the function, which reloads everything!

Please check http://webix.com/snippet/a66e334f

  • dataFeed set by define
  • name of key field used in the bind command

As result, each time when master record selected, related table will issue request to the server side as

http://webix.com/snippet/dummy.php?filter[id]=2

also, there is the onAfterSelect event, where you can issue any command on item selection in the master table.