5

I am working on angular 4 project, I had a requirement to drag item, So I was using ng2-dragula plugin to do it for me. Now I need to extract data-id attribute from each row after drop to specific position.

 dragulaService.drop.subscribe(
      (args) =>{
        const [bagName, elSource, bagTarget, bagSource, elTarget] = args;
        console.log('after', $(bagSource)); // element after the inserted element
});

In $bagSource variable I will get each rows in new order. Say it be

<tr attributes  data-id="23"><tr>
<tr attributes  data-id="2"><tr>
<tr attributes  data-id="32"><tr>

How could I extract data-id from each tr fields. I need to get each id in their new order in an array. My required result should be [23,2,32];

jquery $(element).attr("data-id") equivalent in angular 4.

3
  • See if this helps -- stackoverflow.com/questions/24673418/… Commented Nov 30, 2017 at 5:54
  • What is the signature of the method called when drop occurs? means what's the type of object you receive in your in method as argument? Commented Nov 30, 2017 at 6:15
  • Can you explain how tr are related to drag zone? Commented Nov 30, 2017 at 6:32

2 Answers 2

5

Something similiar to jquery $(element).attr("data-id") can be achieved with @ViewChild and some old-fashioned javascript. It would look like:

Use this only when drag zone and table is not related (if it is use @user3263307 answer it's more Angular-friendly). However the best option would be make use of [attr.data-id]="someVariable", but since I don't know your app structure can't help you with implementing this method.

.*html File

<table #tableRef>
    <tr attributes  [attr.data-id]="23"><tr>
    <tr attributes  [attr.data-id]="2"><tr>
    <tr attributes  [attr.data-id]="32"><tr>
</table>

Simply #tableRef is something like template variable which angular will bind with @ViewChild in component file.

*.component.ts

@ViewChild() tableRef: ElementRef;

    public getIds() {
        if (!this.tableRef|| !this.tableRef.nativeElement)
            return;
        //assuming that table would have only one `tbody` tag.
        let tableBody = this.tableRef.tBodies[0];
        if (!tableBody)
           return;

        // we need to use Array.from, because `.children` returns HTMLCollection<Element>
        // type which is not handy to iterate through it.

        let childs: Array<HTMLTableSectionElement> = Array.from(tableBody.nativeElement.children);
        let arrIds = [];
        for(let child of childs) {
            if (!(child.nodeName && child.nodeName.toLowerCase() == "tr"))
                continue;

            arrIds.push(child.dataset.id);
        }
    }

Please note that it's a bit brutal method for angular since it's best not to interfere into HTML DOM structure. However as long we are only getting data from elements everything should be fine.

Please note that too about using @ViewChild.

Use this API as the last resort when direct access to DOM is needed. Use templating and data-binding provided by Angular instead. Alternatively you can take a look at Renderer2 which provides API that can safely be used even when direct access to native elements is not supported. Relying on direct DOM access creates tight coupling between your application and rendering layers which will make it impossible to separate the two and deploy your application into a web worker.

From Angular docs link

Sign up to request clarification or add additional context in comments.

Comments

0

In angular attributes should be defined like this:-

<tr attributes  [attr.data-id]="23"><tr>

And attribute can be accessed using dataset property of Eventtarget object:-

 dragulaService.drop.subscribe(
  (args) =>{
    const [bagName, elSource, bagTarget, bagSource, elTarget] = args;
    console.log('id is:', elTarget.dataset.id);
 });

3 Comments

is it possible to get the id's of the entire array if it is in *ngFor
Yes possible using a utility function that keep on storing Ids(eiher in array or as a comma seperated string) every time when it is invoked. Invoke this function with each *ngFor element.
Could you please let me know how could we achieve this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.