Jump to content

The problem in ticking nodes and sub-nodes of UniTreeView


Ario.Paxaz

Recommended Posts

Hello,

I see you applied the solution from here:

 

Okay.

Add some delay:

function afterCreate(sender) 
{
    sender.on('checkchange', function(node, checked) {
        Ext.defer(function() {
            if (checked == true) {
                node.cascadeBy(function(node) {
                    node.set('checked', checked)
                });

                node.cascadeBy(function(node) {
                    if (node.parentNode) {
                        var allChecked = true;
                        node.parentNode.childNodes.forEach(function(childNode) {
                            if (childNode.get('checked') == true) {
                                allChecked = allChecked && true
                            } else {
                                allChecked = false
                            }
                        });
                        if (node.parentNode.childNodes.length > 0) node.parentNode.set('checked', allChecked);
                    }
                })
            } else {
                node.parentNode.cascadeBy(function(node) {
                    if (node.parentNode) {
                        node.parentNode.set('checked', checked)
                    }
                });

                node.cascadeBy(function(node) {
                    node.set('checked', checked)
                })
            }
        }, 100)
    })
}

 

Link to comment
Share on other sites

1 hour ago, Sherzod said:

tri-state tree

It is not important to be in three modes now.
I need when the all sub nodes to be checked the parent node is checked , and when  the parent node is also unchecked the sub nodes are unchecked.

Link to comment
Share on other sites

1 hour ago, Ario.Paxaz said:

It is not important to be in three modes now.

Ok.

Try this approach for now:

function afterCreate(sender) 
{
    updateChildNodes = function(node, checked) {
        node.eachChild(function(child) {
            child.set('checked', checked);
            this.updateChildNodes(child, checked);
        }, this);
    };

    updateParentNodes = function(node) {
        var parentNode = node.parentNode;
        if (parentNode) {
            var checkedChildNodes = parentNode.childNodes.filter(function(child) {
                return child.get('checked');
            });

            var uncheckedChildNodes = parentNode.childNodes.filter(function(child) {
                return !child.get('checked');
            });

            if (checkedChildNodes.length === parentNode.childNodes.length) {
                parentNode.set('checked', true);
            } else if (uncheckedChildNodes.length === parentNode.childNodes.length) {
                parentNode.set('checked', false);
            } else {
                //todo: for tri-state
            }

            this.updateParentNodes(parentNode);
        }
    };

    sender.on('checkchange', function(node, checked) {
        updateChildNodes(node, checked);
        updateParentNodes(node);
    });
}

 

Link to comment
Share on other sites

2 hours ago, Sherzod said:

I am also testing tri-state:

Thank you, the display problem has been solved to some extent.
Now another problem has arisen.
When I Browse the with the For to separate the ticked nodes, we don't notice that they are ticked.

Link to comment
Share on other sites

6 hours ago, Ario.Paxaz said:

It will not be displayed in the list until we tick with the mouse.

Hello,

Yes, because there is no synchronization with the server.
I will try to analyze.

Link to comment
Share on other sites

12 hours ago, Ario.Paxaz said:

It will not be displayed in the list until we tick with the mouse.

Try this approach for now:

1. 

function afterCreate(sender) 
{
    updateChildNodes = function(node, checked) {
        node.eachChild(function(child) {
            child.set('checked', checked);
            ajaxRequest(sender, '_nodeChecked', {nodeId: child.id, checked:(checked?1:0)});
            this.updateChildNodes(child, checked);
        }, this);
    };

    updateParentNodes = function(node) {
        var parentNode = node.parentNode;
        if (parentNode) {
            var checkedChildNodes = parentNode.childNodes.filter(function(child) {
                return child.get('checked');
            });

            var uncheckedChildNodes = parentNode.childNodes.filter(function(child) {
                return !child.get('checked');
            });

            if (checkedChildNodes.length === parentNode.childNodes.length) {
                parentNode.set('checked', true);
                ajaxRequest(sender, '_nodeChecked', {nodeId: parentNode.id, checked:1})
            } else if (uncheckedChildNodes.length === parentNode.childNodes.length) {
                parentNode.set('checked', false);
                ajaxRequest(sender, '_nodeChecked', {nodeId: parentNode.id, checked:0})
            } else {
                //todo: for tri-state
            }

            this.updateParentNodes(parentNode);
        }
    };

    sender.on('checkchange', function(node, checked) {
        updateChildNodes(node, checked);
        updateParentNodes(node);
    });
}

2. 

function FindNode(Tree: TUniTreeView; NodeId: Integer; AChecked: Boolean): TWebTreeNode;
var
  I : Integer;
begin
  for I := 0 to Tree.Items.Count - 1 do
  begin
    Result := TWebTreeNode(Tree.Items[I]);
    if Result.Id = NodeId then
    begin
      Result.Checked := AChecked;
      Exit;
    end;
  end;
  Result := nil;
end;

3. 

procedure TMainForm.TWAjaxEvent(Sender: TComponent; EventName: string;
  Params: TUniStrings);
var
  IdValue: Integer;
begin
  if EventName = '_nodeChecked' then
   if TryStrToInt(Params.Values['nodeId'], IdValue) then
     FindNode((Sender as TUniTreeView), IdValue, StrToBool(Params.Values['checked']))

end;

 

Link to comment
Share on other sites

20 hours ago, Ario.Paxaz said:

My problem was not solved.

 

Yes, because you are doing it wrong!

Incorrect:

procedure TMainForm.UniFormAjaxEvent(Sender: TComponent; EventName: string; Params: TUniStrings);
var
  IdValue: Integer;
begin
  if EventName = '_nodeChecked' then
    if TryStrToInt(Params.Values['nodeId'], IdValue) then
      FindNode((Sender as TUniTreeView), IdValue, StrToBool(Params.Values['checked']))
end;

Correct:

procedure TMainForm.TWAjaxEvent(Sender: TComponent; EventName: string;
  Params: TUniStrings);
var
  IdValue: Integer;
begin
  if EventName = '_nodeChecked' then
    if TryStrToInt(Params.Values['nodeId'], IdValue) then
      FindNode((Sender as TUniTreeView), IdValue, StrToBool(Params.Values['checked']))
end;

image.png.c9c31a148c5b75d20cb7db29953fe181.png

Link to comment
Share on other sites

14 hours ago, Ario.Paxaz said:

Unfortunately, my problem was not solved.

When I Browse the with the For to separate the ticked nodes, we don't notice that they are ticked.

Please pay more attention when checking the solution!

I already told you about this. You did not assign the event to TW...

image.thumb.png.a6375b1d9dc6a32506f4d8e44f731425.png

 

Told you, the solution works!

image.png.627eefa9d79c79ea518c4760fd928f75.png

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...