0

I have a photogallery produced from a JSViews template with an upvote and downvote button. The OnClick triggers a database update to increment the underlying score. I also need to increment the Score field in the HTML rendered in the page so that it is consistent with the new values in the database.

The code below is my first attempt, but it doesn't work. How could I achieve this?

     <script type="text/x-jsrender" id="gallerycat1">
    {{for List}}
    <ul>
        <li data-type="media" data-url="{{:MainImage}}"></li>
        <li data-thumbnail-path="{{:Thumbnail}}"></li>
        <li data-thumbnail-text>
            <p  data-link="Score"  class="largeLabel"><span id="span-a-{{:ProfileId}}">{{:Score}}</span> {{:FirstName}} {{:LastName}}, {{:Company}}</p>

            <p class="smallLabel">Click to vote.</p>
        </li>
        <li data-info="">
            <div class="voting-buttons">
                <a href="#" data-link="Score" onclick="upVote('<%= userVoted%>',{{:[ImageId]}},1);">
                    <img width="30" src="/client/images_webdev/buttons/heart.png" alt="Upvote this" />
                </a>
                <a href="#"  data-link="Score"  onclick="downVote('<%= userVoted%>',{{:[ImageId]}},0);">
                    <img data-link="Score" width="30" src="/client/images_webdev/buttons/thumbs.png" alt="Downvote this" />
                </a>

            </div>
            <p class="mediaDescriptionHeader"><span data-link="Score" id="scorem">{^{:Score}}</span> {{:FirstName}} {{:LastName}}, {{:Company}}</p>
        </li>
    </ul>
    {{/for}}
</script>

Here's the onClick event for voting

function castVote(userVoted, imageId, vote) {
    jQuery.ajax({
        url: '/client/webservice/voting.asmx/InsertVote',
        type: "POST",
        data: "{'userVoted':'" + userVoted + "','imageId':" + imageId + ",'vote':" + vote + "}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
            if (response.d == 'True') {
                var counter = jQuery('#scorem').text();
                if (vote > 0) {
                    counter++;
                } else {
                    counter--;
                }
                jQuery('#scorem').text(counter);
                upVoteConfirm();
            } else {
                downVoteConfirm();
            }
        }
    });

1 Answers1

0

I assume you are using JsViews, not just JsRender. Are you calling the link method, or just the render method? The data-link expressions you have above won't work unless you are actually data-linking using JsViews link method.

If you are data-linking, then you need to call $.observable(listItem).setProperty("Score", listItem.Score+1); - and that will automatically update either data-link expressions like <span data-link="Score"></span> or data-linked tags like {^{:Score}}.

See for example http://www.jsviews.com/#jsvplaying, where there are two samples which have "Change" buttons to modify the name property.

BorisMoore
  • 8,444
  • 1
  • 16
  • 27
  • Thank for you comment Boris. I am using JSViews and using the link method: template.link( "#tmplTopRated", data1 ); However no joy with updating the value. I get Uncaught ReferenceError: listItem is not defined... – user2427285 Apr 03 '14 at 21:33
  • You are doing {{for List}} so you are iterating over some items and want the click code to increment the Score property of the 'current list item'. So you need to get that item. One way is to write: var listItem = $.view(this).data; Take a look at the samples in more detail, and the associated docs and descriptive text. You will see how similar scenarios are achieved there. (In the sample I pointed to see the line: var dataItem = $.view(this).data;...) – BorisMoore Apr 03 '14 at 23:17
  • In fact you need to understand the basics of how data-binding and views work in JsViews. A good plan is to go to the sample and play with modifying the sample using the 'Try It' tab - then choosing the 'Run It' button. Or copy the sample code from the 'Full Code' tab and use that as starting point for exploring your own scenario. – BorisMoore Apr 03 '14 at 23:22
  • Incidentally you are using data-link in several places in a way that conflicts with other markup. Data-linking an element will replace the element content by the value of the linked expression. So

    other content

    will replace the 'other content'. {^{:Score}} is redundantly using both a linked element (which will remove the content) and a linked tag as content. You can choose one or the other... Again, see the examples...
    – BorisMoore Apr 04 '14 at 17:46