7

This is so infuriating. It seems like it should be so simple, but I can't find the magic incantation.

Here's the gist of what I need to do:

<div rv-each-thing="data.things">
  <input type=button value="Click" onclick="abc( {thing} )">
</div>

That should illustrate what I need to do. I've tried many different things, but nothing seems to work.

paulwal222
  • 1,488
  • 11
  • 18
  • `rv-on-click="abc( {thing} )"` http://rivetsjs.com/docs/reference/#on-[event] You need to read what 2 way binding is, and use the documentation of the binding library. – Pogrindis Sep 21 '15 at 11:46
  • Nope. I definitely tried that, and it doesn't work. Gives this error: Uncaught TypeError: this.call is not a function / t.public.handler @ rivets.bundled.min.js:6 / t.Binding.e.eventHandler @ rivets.bundled.min.js:6 / n.event.dispatch @ jquery-2.1.4.min.js:3 / n.event.add.r.handle @ jquery-2.1.4.min.js:3 – paulwal222 Sep 21 '15 at 13:11
  • The only working solution I found is using a function that is a member of {thing}, which seems ridiculous to me. So: `rv-on-click="thing.my_function"` – paulwal222 Sep 21 '15 at 13:14

3 Answers3

5

Below is the default configuration of event handler from rivets website:

 // Augment the event handler of the on-* binder
 handler: function(target, event, binding) {
    this.call(target, event, binding.view.models)
 }

So apart from the event object, you can also get a reference to the models related to the particular binding as second argument.

Using which you can access the particular object

For example

 <div rv-each-thing="data.things">
  <input type=button value="Click" rv-on-click="abc">
 </div>

function abc(event,rivetsBinding){
  rivetsBinding.thing //heres your thing :)
}
T J
  • 42,762
  • 13
  • 83
  • 138
  • 1
    @sairfan for this to work the event should be bound with rivets event binder. Answer had the copy pasted js binding from question. If rivets binding doesn't work please share an [mcve] – T J Sep 29 '17 at 10:04
1

Here is something how i gone through this. Just copy and paste working examples below

Solution 1

<body>
    <div rv-each-book="model.books">
        <button rv-on-click="model.selectedBook | args book">
            Read the book {book}
        </button>
    </div>
</body>

<script type="text/javascript">
    rivets.formatters["args"] = function (fn) {
        var args = Array.prototype.slice.call(arguments, 1);
        return function () {
            return fn.apply(null, args);

        };
    };

    rvBinder = rivets.bind(document.body, {
        model: {
            selectedBook: function (book) {
                alert("Selected book is " + book);
            },
            books: ["Asp.Net", "Javascript"]
        }
    });
</script>

Or an alternate approach is binding event

Solution 2

<body>
    <div rv-each-book="books">
        <a rv-cust-href="book">
            Read the book {book}
        </a>
    </div>
</body>

<script type="text/javascript">

    rivets.binders['cust-href'] = function (el, value) {
        //el.href = '/Books/Find/' + value;
        //OR
        el.onclick = function () { alert(value); };

    }

    rvBinder = rivets.bind(document.body, {
        books: ["Asp.Net", "Javascript"]
    });
</script>
sairfan
  • 970
  • 2
  • 12
  • 20
  • This is not the right way to do it, unless something broke in a version update of rivets, in that case you should report a bug rather than using poor work arounds – T J Sep 29 '17 at 10:01
  • 3
    should i stop my project until i get solution?? we have to comeout of situation, we will update when its updated in rivetsjs. this issue is already reported, solution something like above is discussed on rivetsjs related page, you did not even bother to verify what I'm trying to say. – sairfan Sep 29 '17 at 15:23
  • I did check the source of rivets before posting the comment, and the existing answer should still work with minor change to arguments. The answer is 6 years old, JS libraries update very fast. The answer contains the code for invoking event handler from rivet's source at the time of writing. It seems you did not do any investigation on why existing solution doesn't work... – T J Sep 29 '17 at 15:39
  • you did not described your answer well, I asked question on it, that its not working for me, but no reply, I further searched around and reached issue at [link](https://github.com/mikeric/rivets/issues/554) I found the solution, and i posted so that it can help others, I also provided the link where event is binded which is still better explained and working example. – sairfan Sep 29 '17 at 15:39
1

Sorry if I'm late, just started using Rivets and had come across the same problem.

Solution: Bind your function first

For example you have a function:

function customOnClickCallback(event, item) {
    console.log(event);
    console.log(item);
    console.log(item.thing); // Instead of {{ thing }}
}

First you bind your function to be called (I'll be binding it to the Body for now):

rivets.bind(document.getElementsByTagName("body")[0], {
    customOnClick: customOnClickCallback
});

Then you can use customOnClick as your rv-on-click

<input type=button value="Click" rv-on-click="customOnClick">

As for accessing your variable thing, it should be accessible as item.thing.