Function to create a detail grid

If you're a new user of AppGini, feel free to ask general usage questions, or look for answers here.
Post Reply
DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Function to create a detail grid

Post by DevGiu » 2016-07-16 07:45

I'm testing mktabbed library by grimbelfritz , and I would like to have a detail grid, inside one of his tabs, after my field

There are some code to include on a page a tableview sending the parameters needed?

Better. There are some way to build a table view inside a detail view with a customized sql?
/Giuseppe
Professional Outsourcing Services

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-16 09:22

I think I'm near.

I see a POST to parent-children.php can do the job for basic things. Just need to know how to "overwrite" $pcConfig array to fit my needs, for advanced behaviours.
/Giuseppe
Professional Outsourcing Services

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 08:27

I think I'm advancing on this (slowly because I'm with various things at the same time, but advancing)

Code: Select all

		ob_start(); ?>

		<script>
			$j(function(){				
				post(
					"parent-children.php", 
					{ 
						ChildTable: "direccionentidad", 
						ChildLookupField: "entidad_id", 
						SelectedID: "<?php echo $selectedID; ?>", 
						Page: 1, 
						SortBy: "", 
						SortDirection: "", 
						Operation: "get-records" 
					}, 
					"di-info"
				);
				$j('#entidad-children').remove();

			});
		</script>

		<?php
		$data = ob_get_contents();
		ob_end_clean();

		$html .= $data;
Whth this code, I get the detail child, on the div I want (a tab generated with _mktabbed.
Problem,

Reload don't works.
Because reloads the original pane of the detail and is hardcoded in JS and then is looking for the pane I removed.

Can't tune SQL to return exactly what I want.
To add some kind of filter.

Example: I want 2 detail-views from table commercialdocuments. One filtered by "discriminatoryfield="INVOICE" and another filtered by "discriminatoryfield="ORDERS"
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 12:03

Reload

If it's failing because it can't find the element you removed... can you hide the element instead?

Code: Select all

$j('entidad-children').hide()
Tune SQL

I don't think you'll get there using parent-children.php since it doesn't support filtering. Or, at least I don't see that it does. You'd have to customize it to add WHERE filtering.

Can you not filter the response from the POST instead, before performing $html .= $data?

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 14:17

grimblefritz wrote:Reload

If it's failing because it can't find the element you removed... can you hide the element instead?

Code: Select all

$j('entidad-children').hide()
Hi grimblefrisz.

Don't works with hide() either. If I set a breakpoint, and/or execute this code in web console, then it works (with hide and with remove).
Tune SQL

I don't think you'll get there using parent-children.php since it doesn't support filtering. Or, at least I don't see that it does. You'd have to customize it to add WHERE filtering.

Can you not filter the response from the POST instead, before performing $html .= $data?
I don't try to filter master data, but detail data.
Let me explain.
This is an Entity form. An Entity could be a customer, or a provider or both.
At the other side, I have a CommercialDocument table, where invoices, orders and so on are stored with a discriminatory field, based on the type of document.
My form has 2 tabs (thanks to your library ;) ). One for sales (if it's customer), and other for purchases (if it's provider)
I want to show Sales done to this customer, if it's a customer.
I want to show what we bought to this provider (if it's provider).
What I'm looking to do? I want to create a "custom" detail view like parent-child, but I need not only 1, but 2 from the same related table (for this specific scenario), and each one filtered with

Code: Select all

DTYPE="Sale" and customer=$customerid 
and other with

Code: Select all

DTYPE="Purchase" and customer=$customerid 
I mean, I need to get the same detail view you get when setup parent/child, but instead one, I need 2, and tweaking a little the SQL to retrieve only what I want.

Another scenario. An Entity has addresses. I want to show a detail-view with addresses of this entity, but only addresses with active=1

Right now I'm studying parent-child.php code because probably I need an auxiliar file like this for my purposses, and I don't want to modify "core" files.

EDITED: I asked about similar in the course Questions section. But I think I explained better here.
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 14:25

Have you tried wrapping the code in setTimeout?

Code: Select all

      <script>
         $j(function(){
           setTimeout(function(){            
            post(
               "parent-children.php", 
               { 
                  ChildTable: "direccionentidad", 
                  ChildLookupField: "entidad_id", 
                  SelectedID: "<?php echo $selectedID; ?>", 
                  Page: 1, 
                  SortBy: "", 
                  SortDirection: "", 
                  Operation: "get-records" 
               }, 
               "di-info"
            );
          
            $j('#entidad-children').remove();
           }, 1000);
         });
      </script>
I recently had a problem where code that worked from the console, did not work from the script, and this resolved it.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 14:29

grimblefritz wrote:Have you tried wrapping the code in setTimeout?

Code: Select all

      <script>
         $j(function(){
           setTimeout(function(){            
            post(
               "parent-children.php", 
               { 
                  ChildTable: "direccionentidad", 
                  ChildLookupField: "entidad_id", 
                  SelectedID: "<?php echo $selectedID; ?>", 
                  Page: 1, 
                  SortBy: "", 
                  SortDirection: "", 
                  Operation: "get-records" 
               }, 
               "di-info"
            );
          
            $j('#entidad-children').remove();
           }, 1000);
         });
      </script>
I recently had a problem where code that worked from the console, did not work from the script, and this resolved it.
Prize for you ;) I thought about this, but I tought $j(function(){} is executed once DOM is builded.

About other point, some idea/suggestion?
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 14:44

Not sure I understand the other issue well enough to be much help. What I think your saying is:

Detail view 1 - records where id=customerid AND type=sale

Detail view 2 - records where id=customerid AND type=purchase

So I think the problem is in getting that AND condition into the query.

Do you have the display issues resolved, so you're getting two tabs with the same detail view? If so, then all we have to solve is getting that AND into the query, right?

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 14:47

I have solved the display issue of the detail with the delay. If I use standard way, it works (moving an existing child view to other position).

But I try to find the way to create customs-childs on demand. I think I'm near, but tweaking parent-child.php on a new file.
/Giuseppe
Professional Outsourcing Services

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 14:51

This places a detail_view inside one of your tabs for example:

Code: Select all

$j(function(){
				//"parent-children.php", 
				post(
					"komaestro-detalle.php", 
					{ 
						ChildTable: "direccionentidad", 
						ChildLookupField: "entidad_id", 
						SelectedID: "1", 
						Page: 1, 
						SortBy: "", 
						SortDirection: "", 
						Operation: "get-records" 
					}, 
					"di-info"
				);
				$j('#entidad-children').remove();

			});
But:
1- You can't tweak SQL.
2- I can't get more detail-views of the same table (probably because name conflicts in DOM)

I'm working on this right now.
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 15:03

I think this is where AppGini support for sql views would be useful. What you really want is two additional sql views of the CommercialDocuments table, one filtered for type=sales and the other for type=purchase. Each view gets a unique name, so it would resolve that collision.

If we had sql views, then it would be a simple matter. Or so I think.

Without that...

I suppose you could create two additional tables, one called sale_documents, the other purchase_documents. Basically, copies of the CommercialDocuments table structure.

Then you could easily have two detail views, one for sale_documents, the other for purchase_documents.

You would have to add a bit of code into a hook, so when a customer record is selected:

1. Empty sale_documents and purchase_documents
2. Copy records from CommercialDocuments to sale_documents where dtype=sale and id=id
3. Do the same, but for purchase_documents

A total hack, but it would work. I think.

It's basically creating a "view" on the fly. As far as AppGini knows, they are just two different tables, so you're creating a parent->multiple-child type of situation.

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 15:27

There's a down side, however.

Such views would have to be readonly.

Or, if you allow edits, then you have to also write hook code to reflect any edits back into CommercialDocuments.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 15:47

Warning, Brick after this line.
-------------------

Well, SQL Views, and "ModelViews" as is. Sometimes you want to show some table data in other form or somewhere, but you don't want to show all fields on a related form.
OpenXava solves this with Views Annotations:
You can write on a class:

Code: Select all

@View(name="Simple", // This view is used only when “Simple” is specified
    members="number, name" // Shows only number and name in the same line
)
And just number,name fields will be showed when you specify to use the view "Simple".

Your solution probably works, the problem is that goes against all database design principles.

As far as I see on the code. Right now, the core is on parent-child.php
Here there are a hardcoded array with tables and relationships or parent-child.

The code creates an array based on permissions and look for the table asked if there are permissions or not to show.
How? Using the JS function post (common.js.php).

Code: Select all

function post(url, params, update, disable, loading){
new Ajax.Request(
	url, {
		method: 'post',
		parameters: params,
		onCreate: function() {
			if($(disable) != undefined) $(disable).disabled=true;
			if($(loading) != undefined && update != loading) $(loading).update('<div style="direction: ltr;"><img src="loading.gif"> <?php echo $Translation['Loading ...']; ?></div>');
		},
		onSuccess: function(resp) {
			if($(update) != undefined) $(update).update(resp.responseText);
		},
		onComplete: function() {
			if($(disable) != undefined) $(disable).disabled=false;
			if($(loading) != undefined && loading != update) $(loading).update('');
		}
	}
);
}
How is used this function? As I epxlained in previous post:

Code: Select all

post(
   "parent-children.php",
   {
      ChildTable: "direccionentidad",
      ChildLookupField: "entidad_id",
      SelectedID: "<?php echo {$SelectedID}; ?>",
      Page: 1,
      SortBy: "",
      SortDirection: "",
      Operation: "get-records"
   },
   "di-info"
);
You specify the childtable, lookup field, actual ID of parent and an operation, and where you want to "print" ("di-info" div)
get-records operation is responsible to return the detail view as is (show-childrens return the complete Childs frame, and calls recursivelly to itself for get-records)
get-records builds SQL based on the hardcoded parent/childs array and prepare some data to pass to loadView (incCommon.php)

Code: Select all

/**
* Loads a given view from the templates folder, passing the given data to it
* @param $view the name of a php file (without extension) to be loaded from the 'templates' folder
* @param $the_data_to_pass_to_the_view (optional) associative array containing the data to pass to the view
* @return the output of the parsed view as a string
*/
function loadView($view, $the_data_to_pass_to_the_view=false){
	global $Translation;

	$view = dirname(__FILE__)."/templates/$view.php";
	if(!is_file($view)) return false;

	if(is_array($the_data_to_pass_to_the_view)){
		foreach($the_data_to_pass_to_the_view as $k => $v)
			$$k = $v;
	}
	unset($the_data_to_pass_to_the_view, $k, $v);

	ob_start();
	@include($view);
	$out=ob_get_contents();
	ob_end_clean();

	return $out;
}
loadView calls this template (normally, children-relatedtable.php) and with the data passed builds all.

Template, creates JS functions to retrieve data and manage behaviour of the generated detail-view, like get records, create new one and so on, calling to, again, to parent-children.php and with a composed name like ($table.$lookupfield)GetRecords({ Verb: '' }) where verb could be new, reload and so on...

Summarizing, this is all.

My idea is to create a "clone" of parent-child.php, that "ignores" the hardcode array, and works with data passed.
For example

Code: Select all

post(
   "aux-detail-view.php",
   {
   	  ViewName: "MyView",
      ChildTable: "direccionentidad",
      ChildLookupField: "entidad_id",
      SelectedID: "<?php echo {$SelectedID}; ?>",
      Page: 1,
      SortBy: "",
      SortDirection: "",
      Operation: "get-records"
      ParamsArray: "",
      Query: ""
   },
   "target-div"
);
Ideally, that could understand a new data array

Code: Select all

'data' => array(   
	'parent-table' => '',
	'parent-primary-key' => '',
	'child-primary-key' => '',
	'child-primary-key-index' => 0,
	'tab-label' => 'D',
	'table-icon' => '',
	'display-refresh' => true,
	'display-add-new' => true,
	'forced-where' => '',
	'display-fields' => array(5 => 'Nombre', 6 => 'Direcci&#243;n por defecto'),
	'display-field-names' => array(5 => 'nombreDireccion', 6 => 'direccion_defecto', ),
	'sortable-fields' => array(),
	'records-per-page' => 10,
	'default-sort-by' => false,
	'default-sort-direction' => 'asc',
	'open-detail-view-on-click' => true,
	'display-page-selector' => true,
	'show-page-progress' => true,
	'template' => '',
	'template-printable' => '',
	'query' => ""
)
Obviously, is needed a "generic" children-view.php template too, because templates are hardcoded on the table too, and calls parent-children.php too. And JScode takes into consideration the name of the table, and should be the ViewName. Then, is needed a new one, independent of the table, because will be passed as param, calling this new "aux-detail-view.php".

A lot of work.

I hope I explained.

Note: I though this was simpler to do, and can't understand how anybody need it before.
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 17:44

My suggestion is a hack, no doubt. Sometimes, however, a working hack is better than non-working theory :)

I don't know about others, but I have never had a need for what you're trying to do. Never with an AppGini app. And in other environments, I've had access to sortable, filterable detail views so having two separate view panels for the same table was not needed.

Curious to see how you get it sorted.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 17:56

grimblefritz wrote:My suggestion is a hack, no doubt. Sometimes, however, a working hack is better than non-working theory :)
Totally agree.
I don't know about others, but I have never had a need for what you're trying to do. Never with an AppGini app. And in other environments, I've had access to sortable, filterable detail views so having two separate view panels for the same table was not needed.
Curious to see how you get it sorted.
Well, problem is I'm under time pressure, and don't know if a) probably I will use some kind of hack, b) spend time in try to develop some library to do what I try to do or c) some in the middle like maybe going to build my own boostrap tables hardcoded to get data I need.
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 18:23

Is this what you're wanting to do, except with the detail tabs moved up into the parent tabs?

Image

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-25 18:49

Not sure, what it is what I'm seeing? Lol
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-25 22:38

That is from one of my apps.

Up top is a table of materials, with two tabs Material Data and Status.

On the bottom are purchases and sales of that item. One tab for Purchased Items, one for Sold Items.

I think that's similar to your Customer and CommercialDocuments order/sale scenario, is it not?

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-26 06:19

Similar.

Top should be a customer record, child's, should be sales and purchases, but both comes from the same child/related table
/Giuseppe
Professional Outsourcing Services

grimblefritz
AppGini Super Hero
AppGini Super Hero
Posts: 336
Joined: 2015-12-23 16:52

Re: Function to create a detail grid

Post by grimblefritz » 2016-07-26 12:25

Right. I think where you're running into problems is the ambiguity due to the multiple transaction/object identities, introduced by the DTYPE key field, in your CommercialDocuments table.

By that I mean, your records do not represent a single object. You're using a key field that alters the record identity, so a record can represent more than one type of transaction. That means your table does not represent a single object in your model, but multiple.

Have you considered altering your model, to have both sales and purchases tables? Those could have few fields, and primarily link to a record in your CommercialDocuments table, but the transaction identity is established clearly by the transaction record (sales or purchases.) This would eliminate the multi-value key field (DTYPE). And, it would allow you to use AppGini to easily produce a view like the one I showed above.

DevGiu
AppGini Super Hero
AppGini Super Hero
Posts: 151
Joined: 2016-05-27 09:08

Re: Function to create a detail grid

Post by DevGiu » 2016-07-26 12:33

Its in my TODO, evaluate the impac of divide commercial documents between different tables. Maybe I have to do it
/Giuseppe
Professional Outsourcing Services

Post Reply