Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TActivedropdownList will empty TActiveDataGrid #692

Closed
jo49bimpf opened this issue Apr 25, 2019 · 28 comments
Closed

TActivedropdownList will empty TActiveDataGrid #692

jo49bimpf opened this issue Apr 25, 2019 · 28 comments

Comments

@jo49bimpf
Copy link

Hello,

if I use a TActiveDropdownList in the editmode of the TActiveDataGrid, the grid will be emptied after selection is changed in the dropdownlist:

Before:
grafik

At edititng:
grafik

After selection change:

grafik

And I'll see some uncaught exceptions:
grafik

I use version 3.3.3

@jo49bimpf
Copy link
Author

This is the object:

grafik

An this is the grid:

grafik

@jo49bimpf
Copy link
Author

Something about the uncatched exception.
I Think it comes from here:
grafik

grafik

and in ajax3.js (line 391 and 392) :

grafik

@ctrlaltca
Copy link
Member

I'm not sure i understand the problem. The second and third images ("At editing" and "After selection change") are the same. Do you mean that even if you change the selection on the TActiveDropDownList it resets itself to the old value?

One thing that i noticed:

Schermata 2019-04-25 alle 15 53 52

This should probably use a databind tag: SelectedValue = "<%# $this->Quellehd->Value %>"

@jo49bimpf
Copy link
Author

Please look at the rows above the dropdownlist.
In the screenshot "At editing" the row is filled" and in the row After selection chande" the rows are empty:
Before:
grafik

After:

grafik

@ctrlaltca
Copy link
Member

Can i see the <prop:ItemTemplate> (not the<prop:EditItemTemplate>) for those TTemplatColumn?

@jo49bimpf
Copy link
Author

Here it is:

				<!--- QUELLE --->						
		        <com:TTemplateColumn 
                    ID="Quelleht" 
                    SortExpression="Quelle" 
                    HeaderStyle.CssClass="pflichtfeld_fa_header sort-arrow" 
                    HeaderText="Quelle" 
                    ItemTemplate="<%# $this->Parent->Data->Quelle %>" 
                    >
                    <prop:Headertemplate>
                        <com:TLinkButton 
                            Text="Quelle" 
                            CommandName="Sort" 
                            CommandParameter="Quelle" 
                            CausesValidation="false"
                            ToolTip="Die Spalte Quelle enthält die Eventquelle" 
                        />
                        <br> 
                        <div>
                            <com:TActiveTextBox 
                                ID="SearchBoxQuelle" 
                                AutoPostBack="true" 
                                OnCallback="Page.loadSearchHeader" 
                                OnTextChanged="Page.loadSearchHeader" 
                                OnInit="Page.setSearchHeaderText"
                            />
                        </div>
                    </prop:Headertemplate>
                      <prop:EditItemTemplate>
        		      	<com:TActiveDropDownList
            				ID="Quelledl"
            				
            				DataTextField  = "Name"
            				DataValueField = "Name" 
                            SelectedValue  = "<%= $this->Quellehd->Value %>"
                            OnselectedIndexChanged = "page.onSourceChanged"
                           
                        />
                    	<com:THiddenField 
                            ID="Quellehd" 
                            value="<%# $this->Parent->Data->Quelle %>" 
                        /> 
						<com:TRequiredFieldValidator
						    ID="QuelleVal"
						    ControlToValidate="Quelledl"
						    ControlCssClass="required"
						    InitialValue="Bitte selektieren"
						    FocusOnError="true"
						    ValidationGroup="Group1" >
							<prop:ClientSide.OnValidationError>
						        //alert("Bitte füllen Sie die Spalte Quelle aus.");
						    </prop:ClientSide.OnValidationError>
						</com:TRequiredFieldValidator>
    				</prop:EditItemTemplate>
    			</com:TTemplateColumn>

@ctrlaltca
Copy link
Member

I see:

ItemTemplate="<%# $this->Parent->Data->Quelle %>" 

Try to remove it and add this instead:

<prop:ItemTemplate>
  <com:TLiteral Encode="true" Text="<%# $this->Parent->Data->Quelle %>"/>
<prop:ItemTemplate>

@jo49bimpf
Copy link
Author

I've tried it, but get this:
grafik

@jo49bimpf
Copy link
Author

Without encode, I'll get thgis:

grafik

@ctrlaltca
Copy link
Member

ctrlaltca commented Apr 26, 2019

place the ItemTemplate outside the TTemplateColumn definition:

<com:TTemplateColumn ...>
	<prop:ItemTemplate>
		<!-- content -->
	</prop:ItemTemplate>
	<prop:EditItemTemplate>
		<!-- content -->
	</prop:EditItemTemplate>
</com:TTemplateColumn>

@jo49bimpf
Copy link
Author

This will work. :-)
One question to the handlers oft th activedropdownlist:
I use this one:
OnselectedIndexChanged = "page.onSourceChanged"

it seems for me, that the oncallback will do the same again.
How can I prevent to raise the callback?
Or cann I use soem js direkt in this to events?

Thanks alot for your help!!

@ctrlaltca
Copy link
Member

OnSelectedIndexChanged is a generic method that works both for callbacks and postbacks, and exists both in TDropDownList and TActiveDropDownList.
OnCallback is specific to TActiveDropDownList, and it will trigger an ajax callback.
To prevent the callback you can set the AutoPostBack property to false.

@jo49bimpf
Copy link
Author

jo49bimpf commented Apr 26, 2019

because it was wrong.
In the php whioch is raised in OnselectedIndexChanged I'll change some innerHtml-code in the row.
This will bedone, but it will be redone automatically and I don't know why.
If I make some alters in the js, I see my changes and after the code was done, the old values are shown ...

@ctrlaltca
Copy link
Member

Both the TDropDownlist and TActiveDropDownlist controls receive the OnSelectedIndexChanged event if their selection is changed, but in order to receive that event the page needs to be POSTed, either by a page load or by an ajax call.
On normal controls like TDropDownlist the AutoPostBack property defaults to false, so they won't force a page load when the user chooses a value from the dropdownlist.
In order to trigger the event, you need to enable that property or have the user pressa button in order to force a page load.
On the other side, ajax enabled controls like TActiveDropDownlist have the AutoPostBack property defaults to true, so every time the user chooses a value they will force an ajax call the events will be executed.

@ctrlaltca
Copy link
Member

In the php whioch is raised in OnselectedIndexChanged I'll change some innerHtml-code in the row.
This will bedone, but it will be redone automatically and I don't know why.
If I make some alters in the js, I see my changes and after the code was done, the old values are shown

If in the same page load you change some innerHtml inside the datagrid and rebind the datagrid, it wll be updated twice:

  1. the first time by your innerHtml changes
  2. the second time Prado will replace the grid contents with the updated contents from the databind

That's why probably your changes are overwritten.
If you need to make a change on the datagrid, change the model's data before databinding

@jo49bimpf
Copy link
Author

Ok, thanks a lot for your help !!!! A+++

@jo49bimpf
Copy link
Author

Sorry for this question, but I can't get to the fields of den EditItem (or the row/cells of the EditItemIndex)
Perhaps, you can give me an hint.

Thanks alot.

@ctrlaltca
Copy link
Member

Can you please elaborate a bit?
Are you trying to get the value of the TActiveDropDownList inside the EditItem? Have a look at Sample 3, expecially the saveItem function

@jo49bimpf
Copy link
Author

No, I get the value of the changed Item in the dropdownlist.
Accordingly to this value, I've to change some other values in the row of the EditItemIndex.
I've made this with some js (like mentioned above, the innerHtml) called with a callback.
This worked fine in version 3.3.2. But in the new version, this would be overwritten.
So, I thought, I would set the new values not via jjs, but direct in the php .....
But I don't know, how to get the object/cells...

@jo49bimpf
Copy link
Author

This is the object, I want to change:

         <com:TTemplateColumn 
                    SortExpression="infoeventfilter" 
                    ID="InfoEventFilterht" 
                    HeaderText="Auftragssicht Info" 
		        	HeaderStyle.CssClass="" 
                   
                    >
                    
                    <prop:ItemTemplate>
                    	<center>
	                    <com:TactiveLabel  
                            ID="InfoEventFilterlb" 
                            style="font-weight: normal;" 
                            Text="<%# $this->Parent->Data->InfoEventFilter %>"
                            OnPreRender="Page.setEventFilterText" 
	                    />							                 
	                   	</center>
	                   	
	                   	<com:THiddenField ID="InfoEventFilterhd" value="<%# $this->Parent->Data->InfoEventFilter %>"/>
	                   	
                    </prop:ItemTemplate>
					<prop:EditItemTemplate>
						<com:TActiveHiddenField 
                            ID="InfoEventFiltertx" 
                            value="<%# $this->Parent->Data->InfoEventFilter %>"
                        />
                       
						<com:TActiveLabel 
                            ID="InfoEventFilterbt" 
                            Text="<%# $this->InfoEventFiltertx->Value %>"
                            BorderStyle ="solid"
                            borderColor="silver"
                            BorderWidth="1px"
                            Backcolor="lightyellow"
                            style="font-weight: normal;"
                            Attributes.onClick="javascript:openEventFilter('<%# $this->Parent->ItemIndex %>','<%# $this->Parent->Data->ID %>','Info')"
                            Attributes.onMouseover ="javascript:document.body.style.cursor = 'pointer';"
                            Attributes.onMouseout ="javascript:document.body.style.cursor = 'default';"
                            OnPreRender="Page.setEventFilterText"  
                            
                        />
                        
                    </prop:EditItemTemplate>

@ctrlaltca
Copy link
Member

I'm not sure i can understand and help you fixing the problem without debugging the app.
If your changes gets overwritten, that's probably due to the datagrid being databinded on the callback: this forces the datagrind to overwritten with new content, probably discarding your changes.
I would start adding a debugger call in the javascript code that you inject to update the page, and
opening your browser's debugging tools.
If you get the browser debugger to execute the breakpoint on your code, step-by-step debugging what's going on.
Also in the "network" tab I would look for the response of the ajax call where you try to update the datagrid using js.
The response should contain:

  • one or more prado actions that will be executed by javascript;
  • one or more piece of html code, included in random tags, that will replace part of code in the page;
  • the updated viewstate

Sorry for the late answer.

@jo49bimpf
Copy link
Author

jo49bimpf commented May 3, 2019

Ok, I will try this.
Do you have a hint for me, how I can get/set values in the edit-template

<prop:EditItemTemplate>
						<com:TActiveHiddenField 
                            ID="InfoEventFiltertx" 
                            value="<%# $this->Parent->Data->InfoEventFilter %>"
                        />
                       
						<com:TActiveLabel 
                            ID="InfoEventFilterbt" 
                            Text="<%# $this->InfoEventFiltertx->Value %>"
                            BorderStyle ="solid"
                            borderColor="silver"
                            BorderWidth="1px"
                            Backcolor="lightyellow"
                            style="font-weight: normal;"
                            Attributes.onClick="javascript:openEventFilter('<%# $this->Parent->ItemIndex %>','<%# $this->Parent->Data->ID %>','Info')"
                            Attributes.onMouseover ="javascript:document.body.style.cursor = 'pointer';"
                            Attributes.onMouseout ="javascript:document.body.style.cursor = 'default';"
                            OnPreRender="Page.setEventFilterText"  
                            
                        />

if the script fires the OnItemCreated="VersionCreated" event?
I don'tr get the any value/text back. If I get there my values or can set them there, I think I can forget my js-callback.

@ctrlaltca
Copy link
Member

You may want to use OnItemDataBound to set the values; it gets called after the item is created, when the data is databinded to the table:

<com:TActiveDataGrid
  ...
  OnItemDataBound="itemDataBound"
>
  <com:TTemplateColumn ID="MyColumn" ...>
    <prop:ItemTemplate>
      ...
    </prop:ItemTemplate>
    <prop:EditItemTemplate>
      <com:TTextBox ID="MyTextBox" />
    </prop:EditItemTemplate>
  </com:TTemplateColumn>
</com:TActiveDataGrid>
	public function itemDataBound($sender, $param)
	{
		$item = $param->Item;
		if ($item->ItemType === 'EditItem') {
			// this is equivalent of using the databind tag <%# %> in the page template
			$item->MyColumn->MyTextBox->Text = $item->Data->MyField;
		}
	}

@ctrlaltca
Copy link
Member

In order to retrieve the values after and edit, i see you are already using an OnUpdateCommand="updateVersion" event handler.
If you want to retrieve the value of a specific field during the edit, before it gets confirmed by pressing the "ok" button on the row, you need to somehow generate a serverside event. An ajax callback is the most common way, eg. by adding an OnCallback event handler to the control you want to react when its value gets changed.
You'll get the control a the $sender parameter of the callback

@jo49bimpf
Copy link
Author

jo49bimpf commented May 3, 2019

Hmm, I've done this. With 3.3.2 it has worked fine. With 3.3.3 my results get overwritten.
This is my solution:

If I change something in this TActiveDropDownlist:

<prop:EditItemTemplate>
	        		      	<com:TActiveDropDownList
	            				ID="Quelledl"
	            				AutoPostback = "true"
	            				DataTextField  = "Name"
	            				DataValueField = "Name" 
	                            SelectedValue  = "<%= $this->Quellehd->Value %>"
	                            OnselectedIndexChanged = "page.onSourceChanged"
	                           
	                        />
	                    	<com:THiddenField 
                                ID="Quellehd" 
                                value="<%# $this->Parent->Data->Quelle %>" 
                            /> 

The OnSelectedIndexChanged event starts this php:

    protected function onSourceChanged($sender,$param){
   	
    	$this->Session['sourcechanged'] = 1;
    	$sender->Parent->Quellehd->Value=$sender->Text;
 
   ... some other stuff ....

    	$this->Page->CallBackClient->callClientFunction ("updateEventFilter" , array ("onSourceChanged",$this->VersionGrid->EditItemIndex+2,"Info","$InfoEventFilter","$InfoEventFilterText"));
    	$this->Page->CallBackClient->callClientFunction ("updateEventFilter" , array ("onSourceChanged",$this->VersionGrid->EditItemIndex+2,"Info1","$Info1EventFilter","$Info1EventFilterText"));
    	$this->Page->CallBackClient->callClientFunction ("updateEventFilter" , array ("onSourceChanged",$this->VersionGrid->EditItemIndex+2,"Info2","$Info2EventFilter","$Info2EventFilterText"));
    	$this->Page->CallBackClient->callClientFunction ("updateEventFilter" , array ("onSourceChanged",$this->VersionGrid->EditItemIndex+2,"Warning","$WarningEventFilter","$WarningEventFilterText"));

    	$this->Page->CallBackClient->callClientFunction ("updateEventFilter" , array ("onSourceChanged",$this->VersionGrid->EditItemIndex+2,"RotEvent","$RotEventEventFilter","$RotEventEventFilterText"));

}

And this is the javascript for the callback:

function updateEventFilter(callerid,row_index,severity,eventfilter,eventfiltertext){
				
					
		if (row_index && callerid == "onSourceChanged"){
				
								
				    if(eventfilter === ""){eventfilter = 1;}
				    
					var fieldhd = '<%=$this->VersionGrid->getClientID()%>'+'_ctl'+row_index+'_'+severity+'EventFiltertx';
					var fieldbt = '<%=$this->VersionGrid->getClientID()%>'+'_ctl'+row_index+'_'+severity+'EventFilterbt';
					
				
					
					document.getElementById(fieldhd).value = eventfilter;
					document.getElementById(fieldbt).innerHTML = eventfiltertext;
					
		      
				
					}
				
					
				}
	--> If I put a alert at the end of the js, I'll see that the content was changed how expected.

--> but then the former values will be rewritten. Perhaps a databind with load-data will be performed. So I'll see the old, unchanged values again
--> I don't find any way to get my wanted values. And how I've said, in 3.3.2 it works.

@ctrlaltca
Copy link
Member

With 3.3.2 it has worked fine. With 3.3.3 my results get overwritten.

Comparing the changes between 3.3.2 and 3.3.3, i don't see anything that could be related to this:
3.3.2...3.3.3

Just to understand if the problem is really the values being overwritten after you change them, does it works if you add a setTimeout around the javascript code that updates the innerHTML?

@jo49bimpf
Copy link
Author

Yes it works with a setTimeout.

@ctrlaltca
Copy link
Member

Closing. If you still need help, feel free to reopen, but it will be hard to fix the problem without a proper testcase in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants