Jump to content

misc

uniGUI Subscriber
  • Posts

    97
  • Joined

  • Last visited

  • Days Won

    3

Posts posted by misc

  1. @ Zilav: Thank you for your suggestions. But creating a handful of controls at runtime is Delphi standard, and if I cannot do it without large time delays or through complicated quirks, then - for me - what's the point of doing it in Delphi at all? I have close to 90 mySQL tables, and there are many other controls I need to create at runtime. In fact, basically, everything is created at runtime.

     

    Your idea of using a stringgrid and manually populating it everytime a record changes is interesting (I've thought of it myself), but last resort for me - after all, I joined this forum because I like Delphi RAD and am not a fan of misusing controls for what they were not meant to. If there are good uniGUI data-aware controls, which connect perfectly to my TDataSource and TDataset, why complicate everything because there may be a pending speed problem with uniGUI, which may get solved soon. After all, I'm not the first person to notice this.

     

    Anyhow, to get back to my observation, I removed the edit panel, put it in a hidden form, then parented it again after having it filled, and thus saved 7/10 of the time. I still have no explanation why this works so much faster, so if anyone can explain the technical background I (and I'm sure some others) would be grateful.

  2. Well... If you don't see any other solution than create 100 controls at runtime or design edit forms for every possible joined sql statement, I think that you really need to think about the way you analyze/modelize your application...

    For example: do your 100 fields need, for each one, titles, controls and button created and shown at the start of you application? Couldn't it be possible to show only 1 control and 1 button on the specific field you're mousing over?  In that case, you just need to create 1 button and 1 control, and show it over the field that your mouse is over...

     

    Anyway, I don't think that the problem is about uniGUi performances, but about the way you want to make your application.

     

    No, I think the problem is that I did not manage to make it clear to you what i am doing. Here's a screnshot with only 3 x 2 dynamically created fields:

    filterPNG.png

     

    "Current Record" is the panel with the dynamically created fields. The tables at the left are also dynamically populated from a mySQL database.

     

    I don't want to offend you, but it might help to accept that there are project requirements you haven't though of, before repeatedly suggesting to change the design..:D That does not always help solve the problem.

     

    But thank you for the Sencha tip - I will look into it.

  3. "Good idea, or am I totally on the wrong theory?"

     

    That was exactly my suggestion (22th Nov 2013)...

    Anyway, I cannot figure why you need to create 100 controls in runtime.  That is not a good practice, far from OOP, MVC and other design patterns.  Doing that with uniGUI is as odd as doing that with standard VCL or FMx forms.

    Maybe you first need to think about the way you analyze/modelize/build your application, before trying to create so many controls...

     

    No, your suggestion was creating the controls at design time. I created them at runtime in a hidden form, which accelerated the whole thing by 300% as explained above. I am just wondering why.

     

    And concerning the design, it is well thought of: I have a grid, populated by an sql statement at runtime (and there can be infinite sql constructions on 90 existing tables of the database...), and beside the grid I dynamically show a vertical record editor. Every field has a title, an edit control and possibly a button. So if the query has 10 fields, that makes at least 20 controls created at runtime. Or would you rather I design an edit form for every possible joined sql statement containing any possible number of fields? ;-)

     

    @ Oliver: does this mean that everytime I create a control at runtime, the server "inserts" this into the client. That would mean, that for 100 creations the server has to insert 100 times in the client, whereas if I create all controls in a hidden form at runtime, then set the parent of my panel (containing the controls) to mainform, then this "big insertion" is done only once?

  4. Farshad, can you explain what happens every time I create a control at runtime in my current form, because I too have big speed problems when creating runtime edit controls for a database grid. Is there an ajax commnunication every time I create a new control, or why does it take so long?

     

    Would it help to create them in an invisible form, and then set the parent to my current form once all the controls are created?

     

    Is there any other trick?

     

    In fact, I just created about 100 controls in a hidden form before calling showmodal (3 secs), and I beat the creation of the SAME controls in the mainform by 300% (> 10 secs).

     

    So what exactly is slowing down the control creation in the mainform? It really seems that every control creation is initiating some kind of communication - is this true?

     

    That would imply that creating a large number of controls is better done in a hidden panel or form, and once done can be assigned to the parent form.

     

    Good idea, or am I totally on the wrong theory?

  5. Farshad, can you explain what happens every time I create a control at runtime in my current form, because I too have big speed problems when creating runtime edit controls for a database grid. Is there an ajax commnunication every time I create a new control, or why does it take so long?

     

    Would it help to create them in an invisible form, and then set the parent to my current form once all the controls are created?

     

    Is there any other trick?

  6. Got the above code to work. I set the Margins too high - they are counted as cm/in, not pixels. I mistook the error message for an uniGUI problem.

     

    It's possible to create VCL forms at runtime and put VCL components on it. At least in my case no crashes.

     

    So my solution is a free and lean way of converting HTML to PDF.

     

    @ Farshad, at this point I must say, you had a truely amazing idea with uniGUI.

  7. I got the THtmlViewer working by placing it on a VCL form and creating it (without showing). Maybe not an intended solution, but no crash so far

     

    However, I could not get THtml2Pdf working, because it needs a VCL canvas.

     

    The THtmlViewer/THtml2Pdf combination works superb in VCL applications, but I cannot get it to work under uniGUI.

     

    So the question that remains: Has anybody found a solution to convert HTML to PDF without the large fingerprint of FastReport and likewise report engines?

  8. Maybe i'm lacking understanding of uniGUI, but I tried to add a THtmlViewer to TuniHiddenPanel, and I always get the message "Cannot assign nil to a font." at runtime. Even when I create it at runtime.

    I want to use the THtmlViewer to load some Html and save it as PDF. The Fastreport engine does not create nice tables without having to buy the full product, and IMO it's a little heavy for my task.

     

    I want to do something like this:

    
      HtmlViewer1:= THtmlViewer.Create(Self);
      HtmlViewer1.Parent:= UniHiddenPanel1;  //must have a parent control
    
    
    
        ... load some html code into htm
        HtmlViewer1.LoadTextStrings(htm);  //"cannot assign nil to a font"
    
        with THtml2Pdf.Create do begin
          Viewer := HtmlViewer1;
          MarginLeft := 10;
          MarginRight := 10;
          ScaleToFit := true;
          Orientation := poLandscape;
          DefaultPaperSize := psA4;
          DrawPageNumber := true;
          DrawPageNumberText := fname + ' - Page %d/%d';
          Execute;
          SaveToFile(fname);
          Free;
        end;
    

    Does anybody have an alternative, or knows how to overcome this?

  9. Perfect. it works. How do you find these kind of solutions?!

     

    Also, can you explain to me why I have to typecast like this?

    TxPopupMenu = class(TuniPopupMenu)
    uniSession.AddJS(TxPopupMenu(pmMasterTables).GetMenuControl.JSName + '.items.clear();');
    

    Should I post this into bug reports, because obviously "pmMastertables.Items.Clear;" is not working?

  10. Did that. Now the number of menuitems is correct, but they are somewhat painted over the old ones and cannot be clicked either. So I'm actually worse off.

     

    My code:

        uniSession.AddJS(TxPopupMenu(pmMasterTables).GetMenuControl.JSName + '.items.clear();');
        pmMastertables.Items.Clear;
    
    

    Result:

     

    image04.jpg

     

    Farshad, can you please confirm this to be a bug?

    How do I dynamically populate a popup menu?

     

    I have no use for a popup menu which I cannot populate dynamically from code. I need to be able to add/delete menuitems in runtime.

  11. Providing source code with the product helps to:

     

    • understand the components, thus reducing support
    • find bugs, thus reducing support
    • encourage code enhancements from the community
    • complete projects faster, thus accelerating the success of the product

     

    IMO, these arguemtns are very important for a young product.

     

    I would therfore suggest code separation at a later version.

    • Upvote 2
  12. Hello Farshad, can you confirm if this is a bug?

    Even setting the menu items to invisible is ignored.

        popMenu.Items.Clear;  //dont work
        while popMenu.Items.Count > 0 do begin
          mn:= popMenu.Items[pmMastertables.Items.Count - 1];
          mn.visible:= false;  //don't work
          popMenu.Items.Remove(mn);  //don't work
          mn.free;
        end;
    
  13. Please allow to dynamically create grid editors at runtime and attach them to a dynamically populated uniGrid.

     

    See thread;:

    http://forums.unigui.com/index.php?/topic/3836-can-grid-editors-be-dynamically-assigned/

     

    This is needed, when I dynamically create an sql statement at runtime, and thus cannot predefine the grid columns in design time.

     

    Example:

            if Columns[ix].Field.DataType in [ftDate, ftDateTime] then begin
              uniDate:= TUniDateTimePicker.Create(Application);
              with uniDate do begin
                DateFormat:= 'dd/MM/yyyy';  TimeFormat:= 'HH:mm:ss';
                ParentColor:= False;
                Color:= clWhite;
              end;
              Columns[ix].Editor:= uniDate;  //don't work, or like this: ?
              UniSession.AddJS(Format(JSName + '.columnManager.columns[%d].setEditor(' + uniDate.JSName + ');', [ix]))
            end;
    
  14. Hi, it's me again, the guy who likes to create controls at runtime, giving you headaches... ;-)

     

    This time: TuniPopupMenu

    var mn: TUniMenuItem;
    
        popMenu.Items.Clear;  //dont work
        while popMenu.Items.Count > 0 do begin  //also don't work
          mn:= popMenu.Items[pmMastertables.Items.Count - 1];
          popMenu.Items.Remove(mn);
          mn.free;
        end;
    
        for ix:= 0 to List.Count - 1 do begin
          mn:= TUniMenuItem.Create(self);
          with mn do begin
            Caption:= List[ix];
            Hint:= 'This does something';
            OnClick:= DoSomethingClick;
          end;
          popMenu.Items.Add(mn);
        end;
    
    

    Works fine to add menuitems, but the removal code at the beginning does not work in web mode. So whenever I call this routine again to populate an EMPTY menu with NEW items, the old items remain.

     

    I've tried everything... Do I need to call some refresh somewhere?!

     

  15. Hi Advanced member, your code actually works:

    for i := 0 to UniDBGrid1.Columns.Count - 1 do begin    
    if UniDBGrid1.Columns[i].Field.DataType in [ftDateTime] then 
    begin
          UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[' + IntToStr(i) + '].setEditor(' +
                           ' new Ext.form.field.Date({' +
                           ' id: ''' + UniDBGrid1.JSName + 'columnsEditor' + IntToStr(i) + ''', ' +
                           ' xtype: ''datefield'',' +
                           ' format: ''d/m/Y'',' +
                           ' anchor: ''100%'',' +
                           ' maxValue: new Date()' +
                           ' })' +
                           ' );');
        end
    

    So Farshads "You can't assign or change an editor after Column is created" seems to be false. Farshad, can you comment on that?

     

    However, when I go into edit mode, the current cell value is not displayed anymore, and also the datetimepicker does not show the value. Is there any way to dynamically show the current record value in the picker?

  16. I now tried querying the visible/invisible property through the AjaxEvent, like this:

     

    function columnhide(ct, column, eOpts)
    {
      ajaxRequest(MainForm.uniGrid, "columnhide", ["column=" + column.getIndex(), "visible=" + column.isHidden()]);
    }

     

    The result is: "column=-1, visible=true" no matter which column I click.

    What am I doing wrong, or is this a bug?

  17. 1. You do not need to assign each time editor for columns!

     

    Yes I do, because I fill my Grid.Datasource.Dataset dynamically at runtime, meaning I just don't know at designtime how many instances of UniDateTimePicker I need, i.e. how many DateTime fields there are in my query.
     
    2. You can after opening the DataSet, attach the editor like this: 
    UniSession.AddJS(UniDBGrid1.JSName + '.columnManager.columns[8].setEditor(' + UniDateTimePicker1.JSName + ');');
    

    Then I need to create an unknown amount of UniDateTimePickers (see above) during design time. If I create 10, it will be enough most of the time, but it's not nice coding. But what if I have a table at runtime which has 11 datetime fields?

    3. But, I think you can not assign for multiple columns one editor.

    I know, that is why I am trying to create one for every date field I stumble upon during runtime.

     

    Clear now, what I am trying to do?

  18. @ Farshad

     

    The Ajax error message was already solved. This I conveyed above through:
     

    ok, apaprently the "if EventName = .." statement is mandatory. Didn't know this had an effect on client side as well.

     

    I reopened the thread above, because I had another problem / bug (I should have created a new thread, sorry):

     

     

    If I click on the uniDBGrid Header in the browser, and deselect a column, a "columnhide" event is correctly fired.

    However, in my server side AjaxEvent, the corresponding column is still marked as visible (Columns.Items[ix].Visible = true). Is this correct? Are the client sided property changes not propagated to the server grid columns?

     

     

    So, in other words: I want to catch a users column de/seletion on the server side. The only event I could find was (likewise for columnshow):

    function columnhide(ct, column, eOpts)
    {
      ajaxRequest(MainForm.uniDetail, "columnhide", []);
    }
    

    My problem is: the event IS fired, when a user hides a column. However, column.visible is still true on the server side!

     

    Does that make it clearer?

  19. The sender is conveyed correctly to my AjaxEvent (I used "Mainform.Grid" as sender), but it (the server) does not know yet that the column has been de/selected by the user.

     

    Does this info come at a later time? How/when is this info conveyed from the browser to the server? The other way around, if I de/select the column from code (column.visible:= ...), everything is displayed correctly.

×
×
  • Create New...