# How to work with jquery (in repeat.for)

**URL:** <https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431>\
**Category:** Help Requests\
**Created:** [July 16, 2018, 6:31am UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431 "2018-07-16T06:31:39Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![SNO](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sno/32/650_2.png) [@SNO](https://discourse.aurelia.io/u/SNO)\
**Post date:** [July 16, 2018, 6:31am UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/1 "2018-07-16T06:31:39Z")

</div>

I’m trying to use some global jquery-libraries e.g. bootstrap-datepicker and facing the problem, that especially in repeat.for blocks, the jquery gets not executed.  
I guess this is because of the dynamic rendering of html blocks.

But is there a clever way to bypass that?

An example:

```auto
<div repeat.for="item of items">
    <input type="text" name="date" class="datepicker" />
</div>

```

```auto
export class testView{
    attached(){
        $('input[name="date"]').datepicker();
    }
}

```

Sometimes, the datepicker gets attached, and sometimes (after reloading the page) it gets not attached.

---

<div class="post-metadata">

**Author:** ![Malexion](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/malexion/32/188_2.png) [@Malexion](https://discourse.aurelia.io/u/Malexion)\
**Post date:** [July 17, 2018, 9:09pm UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/2 "2018-07-17T21:09:38Z")

</div>

Wrap the input in a custom element, this wraps the attached / detached per instance of repeated item.

```javascript
import { bindable, bindingMode, inlineView, containerless } from 'aurelia-framework';
import $ from 'jquery';

@inlineView(`
   <template>
      <input ref="element" type="text" name.bind="name" value.bind="value" />
   </template>
`)
@containerless()
export class DatePicker {

    @bindable() name = '';
    @bindable({ defaultBindingMode: bindingMode.twoWay }) value = '';

    attached() {
        $(this.element).datepicker();
    }

    detached() {
        $(this.element).datepicker('destroy');
    }

}

```

**Edited because I forgot `<template>` in the inlineView**

---

<div class="post-metadata">

**Author:** ![Malexion](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/malexion/32/188_2.png) [@Malexion](https://discourse.aurelia.io/u/Malexion)\
**Post date:** [July 17, 2018, 9:23pm UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/3 "2018-07-17T21:23:18Z")

</div>

Then you can use it like

```auto
<div repeat.for="item of items">
    <date-picker name.bind="item.name" 
                 value.bind="item.value"></date-picker>
</div>

```

---

<div class="post-metadata">

**Author:** ![SNO](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sno/32/650_2.png) [@SNO](https://discourse.aurelia.io/u/SNO)\
**Post date:** [July 18, 2018, 6:16am UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/4 "2018-07-18T06:16:31Z")

</div>

Thank you for your support. This solution looks really good.

Currently I solved that issue using a custom-attribute:

```auto
import { DOM, customAttribute, inject } from 'aurelia-framework';
import 'bootstrap-datepicker';
import * as $ from 'jquery';

@customAttribute('datepicker')
@inject(DOM.Element)
export class DatepickerCustomAttribute {
  private value: Date;

  constructor(private element: Element) {
  }

  public attached() {
    var options = {
      format: 'yyyy.mm',
      todayHighlight: true,
      autoclose: true,
      language: "de"
    };

    $(this.element)
      .datepicker(options)
      .on('changeDate', evt => {
        this.value = evt.date;
      });
  }

  public detached() {
    $(this.element).datepicker('destroy');
  }
}

```

But looking to your solution I’m not sure which is the better way. Do you have any experiences?

---

<div class="post-metadata">

**Author:** ![Malexion](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/malexion/32/188_2.png) [@Malexion](https://discourse.aurelia.io/u/Malexion)\
**Post date:** [July 20, 2018, 4:57pm UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/5 "2018-07-20T16:57:49Z")

</div>

I’m a little more partial to custom elements for jquery custom wrappers because it just looks cleaner to me and the ease of access to bindables.

I’ve also had issues with `@bindable()` in attributes when using `@dynamicoptions` in the past, for me it didn’t trigger property changed or bindable changed if the value passed in was set inside the consuming component’s constructor, but the value was updated in the attribute.

That may or may not be fixed now but I don’t know.

As an example, it was something like this:

```auto
<template>
   <div some-custom-attribute="some.bind: myValue;"></div>
</template>

```

```javascript
export class SomeViewModel {
   constructor() {
      this.myValue = 200;
   }
}

```

---

<div class="post-metadata">

**Author:** ![SNO](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/sno/32/650_2.png) [@SNO](https://discourse.aurelia.io/u/SNO)\
**Post date:** [July 27, 2018, 9:45am UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/6 "2018-07-27T09:45:53Z")

</div>

Could you please give me an example how to implement that solution with allowing the addition of further attributes like “click.delegate” or “change.delegate”?

Currently you only have “name.bind=“name” value.bind=“value”” in your template-html.

---

<div class="post-metadata">

**Author:** ![Malexion](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/malexion/32/188_2.png) [@Malexion](https://discourse.aurelia.io/u/Malexion)\
**Post date:** [July 27, 2018, 7:02pm UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/7 "2018-07-27T19:02:50Z")

</div>

How to use the examples, keep in mind the called functions can be named whatever you want the `change.call` is the important part it could also be done with `change.bind` though you would get a single object param rather than your params spread out, with the element code below that.

**Consume**

```auto
<date-picker change.call="change(event, value)"
             keyup.call="keyup(event, value)"
             keydown.call="keydown(event, value)"
             value-change.call="valueChange(value)"
             select-change.call="selectChange(event, value)"></date-picker

```

```javascript
export class SomePage {

    change(event, value) { ... }

    keyup(event, value) { ... }

    keydown(event, value) { ... }

    valueChange(value) { ... }

    selectChange(event, value) { ... }

}

```

So here are 5 options of how you could pursue change checking, I would toss a console log in each and see if it gives you what you want and triggers when you would expect.

**Component**

```javascript
import { bindable, bindingMode, inlineView, containerless } from 'aurelia-framework';
import $ from 'jquery';

@inlineView(`
   <template>
      <input ref="element" 
             type="text" 
             name.bind="name" 
             value.bind="value"
             change.delegate="proxy('change', $event)"
             keyup.delegate="proxy('keyup', $event)"
             keydown.delegate="proxy('keydown', $event)" />
   </template>
`)
@containerless()
export class DatePicker {

    @bindable() change = () => {}; // aurelia's built in for <input> value change
    @bindable() keyup = () => {}; // on keyup so value has been changed
    @bindable() keydown = () => {}; // on keydown so value has not been changed yet
    @bindable() valueChange = () => {}; // triggers when this.value is modified before this.value is set with new value
    @bindable() selectChange = () => {}; // jquery.datepicker onSelect event is triggered
    @bindable() name = '';
    @bindable({ defaultBindingMode: bindingMode.twoWay }) value = '';

    constructor() {
        var vm = this;
        this.options = {
            onSelect: function(event) {
                if(vm.selectChange)
                    vm.selectChange({ event: event, value: this.value });
            }
        };
    }

    proxy(eventName, event) {
        if(this[eventName])
            this[eventName]({ event: event, value: this.value });
    }

    valueChange(value) {
        if(this.valueChange)
            this.valueChange({ value: value });
    }

    attached() {
        $(this.element).datepicker(this.options);
    }

    detached() {
        $(this.element).datepicker('destroy');
    }

}

```

---

<div class="post-metadata">

**Author:** ![jsobell](https://yyz1.discourse-cdn.com/flex027/user_avatar/discourse.aurelia.io/jsobell/32/87_2.png) [@jsobell](https://discourse.aurelia.io/u/jsobell)\
**Post date:** [July 29, 2018, 4:52am UTC](https://discourse.aurelia.io/t/how-to-work-with-jquery-in-repeat-for/1431/8 "2018-07-29T04:52:49Z")

</div>

@SNO, your code will only work if `items` has been populated before the `attached` is called, but if you’re loading them in a Promise they may not exist before `attach` is triggered, so JQuery won’t have any elements yet to bind to.  
@Malexion’s solution ensures the jquery attachment is made only when the element is added. You could use a custom attribute instead to avoid the new element, but the key thing is that the call to `.datepicker()` is on each inner loop element, meaning the DOM element must be in existence.
