How can I update underlying JSViews data from onclick event - javascript

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();
}
}
});

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.

Related

Using JQuery to dynamically insert list items yields different results than hard coded list items...why?

I created some html that has a couple of different drop down boxes, the first one lets the user select which fields should be viewed in the report, the second one lets them select which months should be viewed on the report. I started out by hard coding the list items for both drop down boxes, and everything worked as expected. I assigned a dummy class to both drop downs called "dropdown-menu" so that they could both be referenced by the same javascript function. For some reason, the "Filter Columns" drop down box won't open in the code snippet I created...but that's not the problem I'm having (so please don't get side tracked on that).
$(document).ready(function() {
var options = [];
$('.dropdown-menu a').on('click', function(event) {
console.log(event);
var $target = $(event.currentTarget),
val = $target.attr('data-value'),
column = 'table .' + val,
$inp = $target.find('input'),
idx;
if ((idx = options.indexOf(val)) > -1) {
options.splice(idx, 1);
setTimeout(function() {
$inp.prop('checked', true)
}, 0);
$(column).toggle();
if ($target.find("secondRow")) {
var cs = $(".topRow").attr("colspan");
$(".topRow").attr("colspan", parseInt(cs) + 2);
}
} else {
options.push(val);
setTimeout(function() {
$inp.prop('checked', false)
}, 0);
$(column).toggle();
if ($target.find("secondRow")) {
var cs = $(".topRow").attr("colspan");
$(".topRow").attr("colspan", parseInt(cs) - 2);
}
}
$(event.target).blur();
return false;
});
})
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="col-md-1 button-group" style="padding-top: 12px; padding-bottom: 1px; margin-bottom: 1px;">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-cog"></span> Filter Columns <span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>
<a href="#" class="small" data-value="attRate">
<input type="checkbox" checked="checked" /> Attendance Rate</a>
</li>
<li>
<a href="#" class="small" data-value="enrDays">
<input type="checkbox" checked="checked" /> Ttl Enrollment Days</a>
</li>
<li>
<a href="#" class="small" data-value="msdDays">
<input type="checkbox" checked="checked" /> Ttl Missed Days</a>
</li>
<li>
<a href="#" class="small" data-value="lstRev">
<input type="checkbox" checked="checked" /> Lost Revenue</a>
</li>
<li>
<a href="#" class="small" data-value="lstHrs">
<input type="checkbox" checked="checked" /> Instrl Hrs Lost</a>
</li>
</ul>
</div>
<div class="col-md-1 button-group" style="padding-top: 12px; padding-bottom: 1px; margin-bottom: 1px;">
<button type="button" class="btn btn-default btn-sm dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-list"></span> Select Months <span class="caret"></span>
</button>
<ul id="ddStudentMonths" class="dropdown-menu"></ul>
</div>
In my code, when a "Filter Columns" value gets selected, the console.log event is triggered and shows me it is a mouse event. However, in the dynamically inserted "Select Months" drop down box, the console.log event never gets reached when a value is selected. In the above code snippet, this is what I see when I click "View Source", it does not show the dynamically insert list items. However, I can open the drop down box and see the items, and I can also see them when I'm debugging through the code. I'm guessing this is where the problem is occurring, and where I'm kind of stumped.
To populate the student months drop down box, I'm calling the following javascript function:
function getStudentMonths(pID) {
//pID is the page ID as stored in the table dmcPages
var param = { pageID: pID };
$.ajax({
type: "POST",
contentType: "application/json; charset=UTF-8",
url: "../WebServices/myDates.asmx/getStudentMonths",
data: JSON.stringify(param),
dataType: "json",
success: function (msg) {
var data = [];
data.push(msg.d);
for (var i = 0; i <= data.length; i++) {
$('#ddStudentMonths').append(data[i]);
}
}
})
};
The webmethod is constructing the list item strings, and I've verified that they look exactly like the hard-coded list items.
Any ideas on what I'm doing wrong? :(
Quickly try this:
Change this
$('.dropdown-menu a').on('click', function(event) {
to this:
$(document).on('click', '.dropdown-menu a', function(event) {
and report back to see if that did the trick?
The reason for the change is; Yes, .on() is supposed to work for dynamically created elements, but there's not great literature on the fact that your .on('click'... is on an element that did not exist in the DOM in the first place. That's why we use $(document) to listen for the click even, since the document is there always, every time. Then we specify what you're clicking on by adding the class inside the .on() function.

How to remove and display this elements when ajax success?

How to remove and display this elements when ajax success ?
i want to remove this elements when success
<a class="hyper" id="1234567890">
<div class="mine">
<img src="moo.png"/>
</div>
</a>
and display this elements when success
<a class="success" id="1234567890">
<div class="sura">
<img src="naa.png"/>
</div>
</a>
and this is my ajax post code
$('body').on('click','.hyper',function() {
var my_id = $(this).attr('id');
var postData = 'mydata='+my_id+'&time=now';
$.ajax({
type: "POST",
url: "my_post.php",
data: postData,
cache: false,
success: function()
{
}
});
})
When i use follow Zentoaku
$('#1234567890').removeClass('hyper').addClass('success').html('<div class="sura"><img src="naa.png"/></div>');
after success my element display
<a class="hyper" id="1234567890">
<div class="mine">
<img src="moo.png"/>
</div>
<a class="success" id="1234567890">
<div class="sura">
<img src="naa.png"/>
</div>
</a>
</a>
but after success i want to see this
<a class="success" id="1234567890">
<div class="sura">
<img src="naa.png"/>
</div>
</a>
how can i do ?
To Hide you can use following:
success: function()
{
$('.hyper').hide();
}
You can also use remove() method to completely remove the elements from DOM.
To show use this:
success: function()
{
$('.success').show();
}
You can use Id as well as your selector, if you use different ids for both the elements.
NOTE: This solution will be applicable when you have your html code already exists on your page which you have shown in your question.
jQuery has a toggle function, with which you can toggle the visibility of an item.
http://api.jquery.com/toggle/
Your code then could look like this:
$('body').on('click','.hyper',function() {
var my_id = $(this).attr('id');
var postData = 'mydata='+my_id+'&time=now';
$.ajax({
type: "POST",
url: "my_post.php",
data: postData,
cache: false,
success: function(my_id)
{
$('#'+my_id+'.hyper').toggle();
$('#'+my_id+'.success').toggle();
}
});
})
$('#1234567890').removeClass('hyper').addClass('success');
$('#1234567890 > div').removeClass('mine').addClass('sura');
$('#1234567890 > div > img').attr('src', 'naa.png')
OR
$('#1234567890').removeClass('hyper').addClass('success').html('<div class="sura"><img src="naa.png"/></div>');

Refering to a span of a li by clicking a button

I'm trying to create a todo application using php, ajax and mysql.
There should be a button that, once clicked, deletes the item from the screen and the database, but I don't know how to refer that I want to delete a certain item.
(each item has a unique id in the database, also a text and the ID from the list that contains it)
An example of my html would be something like that:
<ul id="list">
<li class="i­tem">
<div class="draggertab">
<img src="imatges/botofletxa.jpg" width="30" height="30">
</div>
<div class="deletetab">
<img src="imatges/botocreu.jpg" width="30" height="30">
</div> <span>Buy some cookies</span>
</li>
</ul>
And I the javascript code would look like that:
$('.deletetab').live('click', function () {
var result = confirm("Are you sure?");
if (result == true) {
$(this).parent().remove();
}
});
But I don't know how to send (using ajax) the information to another php file (which connects to the database), or which variable should I use.
Sorry if that's a silly question, I'm new at programming!
I don't know how you are rendering the list (ul), suppose it's a foreach loop or something of that kind. You can store each item's ID in a hidden field, so that you can access it's value from js:
<ul id="list">
<li class="i­tem">
<input type="hidden" class="hidden_id" value="render_id_here" />
<div class="draggertab">
<img src="imatges/botofletxa.jpg" width="30" height="30">
</div>
<div class="deletetab">
<img src="imatges/botocreu.jpg" width="30" height="30">
</div> <span>Buy some cookies</span>
</li>
</ul>
js:
$('#list').on('click', '.deletetab', function(){
var result = confirm("Are you sure?");
if (result==true) {
var parent = $(this).parent();
$.ajax({
type: 'POST',
data: { idToDelete: parent.find('.hidden_id').val() }, //Find hidden ID field within parent div and read it's value
url: 'delete.php'
}).done(function() { //success callback
parent.remove();
}).fail(function(qXHR, textStatus) { //error callback
alert('Server responded with error status ' + textSatus);
});
}
});
On the server side you need to search the "idToDelete" parameter in posted data.
First, you can put your item's id on data-id attribute of each item.
<li class="item" data-id="{{ item_id"}}>
// the rest of the html
</li>
Then the javascript
$('.deletetab').click(function() {
var $this, $item;
$this = $(this);
$item = $this.closest('.item');
if (confirm('Are you sure')) {
$.post('url_to_delete.php', {id: $item.attr('data-id')}, function(data) {
$item.remove();
});
}
});

How to call a ASP function from onclick in the HTML?

I have 3 link in my HTML. When I click one of these a variable in the session must change.
How can I do that?
<div id="eng">
<a href="#" onClick="setLanguage('en')";>
<img id="eng_img" src="bandiera01.png" />
</a>
</div>
<div id="rus">
<a href="#" onclick="setLanguage('ru');">
<img id="rus_img" src="bandiera02.png" />
</a>
</div>
<div id="ted">
<a href="#" onclick="setLanguage('de');">
<img id="ted_img" src="bandiera03.png" />
</a>
</div>
setLanguage(txt) is a JavaScript function but I want to use it in ASP to save it in session.
You need send the information to server, you can post by a normal link or send by ajax. I think with in this case, is better you send by normal link, for example:
<div id="eng">
<a href="ChangeLanguage.asp?language=en">
<img id="eng_img" src="bandiera01.png" /></a>
</a>
</div>
<div id="rus">
<a href="ChangeLanguage.asp?language=ru">
<img id="rus_img" src="bandiera02.png" />
</a>
</div>
<div id="ted">
<a href="ChangeLanguage.asp?language=de">
<img id="ted_img" src="bandiera03.png" />
</a>
</div>
In the page of destination, you get the "language" information of the link.
You can address this issue in a couple of way:
Turn your links into submit buttons, put them inside a form, submit the page server side to manage the language change business logic. This is a classic asp approach. You have to rebuild the page server side.
Let the setLanguage() fire an ajax call to an asp page that retrieves the localized resources. On success, the resources are mapped into the corresponding elements of the DOM: maybe set this logic into a different function:
HTML
<div class="lang">
en
</div>
<div class="lang">
ru
</div>
<div class="lang">
de
</div>
SCRIPT
(function($){
window.setLanguage = function(langCode){
$.ajax({
type: "GET",
url: "myLanguageHandler.asp",
data: { "languageCode": languageCode },
async: true,
error: function (req, status, message) {
//manage the error
},
success: function (data) {
mapPage(data);
}
});
/*
* for demo purpose only
* console.log('Set language: ' + langCode);
*/
};
$('.lang a').bind('click', function(e){
window.setLanguage($(e.target).attr('data-lang'));
return false;
});
})(jQuery)

Create link with JQuery

I got this Jquery code
<head>
<script type="text/javascript">
$(document).ready(function() {
$("#pav li a").click(function() {
$(".srvctext").empty().append("<div id='loading'><img src='loading2.gif' alt='Loading' /></div>");
$("#pav li a").css('color','#656565');
$(this).css('color','#3ca5d4');
$.ajax({
url: this.href,
success: function(html) {
$(".srvctext").empty().append(html);
}
});
return false;
});
});
</script>
</head>
and this HTML
<div class="srvclinksholder">
<h4> Our Services </h4>
<ul id="pav">
<li>Technical Infrastructure Service</li>
<li>Email Exchange Service (Messaging)</li>
<li>Firewall Services</li>
<li>Security and Antivirus Service</li>
....
I want to be able create a link from another page to one of these pages, I think I have to use # somehow just unsure. So if I have <a href="service/pages/page_4.html"> service being the page name that will not obviously work. Maybe something like this <a href="service.html#pages/page_4.html">
What changes do I have to make to achieve this?
DEMO: http://jsfiddle.net/LxreN/3/
Basically you are going to be changing the html of the other div.
$(".srvctext").html("<div id='loading'><img src='loading2.gif' alt='Loading' /></div>");
with the following the in success, there isn't a need to empty everytime since that is causing 2 DOM accesses everytime, which IE doesn't handle well.
success: function(html) {
$(".srvctext").html(html);
}

Categories