I'm struggling with this 3 days and can't get my mind around why the first viewModel is working but second isn't , it even doesn't allow me console.log() anything.
My view Models and ko bindings:
// KO View Models
var indexViewModel = {
item: ko.observableArray([]),
cat: ko.observableArray([]),
loadcontent: function () {
alert("inside index function");
$.ajax({
url: '/api/item/all',
dataType: 'json',
success: function (data) {
var getArray = [];
$.each(data, function (index, item) {
getArray[index] = item;
});
indexViewModel.item(getArray);
}
});
$.ajax({
url: '/api/category/all',
dataType: 'json',
success: function (data) {
var getArray = [];
$.each(data, function (index, item) {
getArray[index] = item;
});
indexViewModel.cat(getArray);
}
});
}
};
var dataReal = null;
var itemViewModel = {
item: ko.observableArray([]),
loadcontent: function (getID) {
alert(getID);
$.ajax({
url: '/api/item/details/' + getID,
dataType: 'json',
success: function (data) {
var getArray = [];
$.each(data, function (index, item) {
getArray[index] = item;
});
itemViewModel.item(getArray);
dataReal = data;
},
error: function (xhr, status) {
switch (status) {
case 404:
alert('File not found');
break;
case 500:
alert('Server error');
break;
case 0:
alert('Request aborted');
break;
default:
alert('Unknown error ' + status);
}
}
});
}
};
var mainViewModel = {
indexPage: indexViewModel,
itemPage: itemViewModel
};
ko.applyBindings(mainViewModel);
My working HTML:
<div id="index-content" data-bind="init: mainViewModel.indexPage.loadcontent(), with: mainViewModel.indexPage">
<div class="item-list" data-bind="foreach: item">
<div class="item-container clearfix">
<div class="item-content clearfix">
<div class="title" data-bind="text: Title">
</div>
<div class="left-side clearfix">
<div class="item-image" data-bind="style: { backgroundImage: 'url(content/u/'+Image+')' }">
</div>
<div class="item-descr">
<div class="body" data-bind="text: Body">
</div>
<div class="item-more-details">
Vairāk...
</div>
</div>
</div>
And the HTML witch even ignores my console.log() calls:
#{
ViewBag.Title = "Details";
Layout = "~/Views/Shared/_Layout.cshtml";
int id = ViewBag.id;
}
<div id="item-details-content">
<input type="hidden" id="item-id" value="#id" data-bind=""/>
<div class="item-list" data-bind="init: itemPage.loadcontent(#id), with: itemPage.item">
<div class="item-container clearfix" data-bind="init: console.log($root)">
<div class="item-content clearfix">
<div class="title" data-bind="text: Title">
</div>
<div class="left-side clearfix">
<div class="item-image" data-bind="style: { backgroundImage: 'url(content/u/'+Image+')' }">
</div>
<div class="item-descr">
<div class="body" data-bind="text: Body">
</div>
<div class="item-more-details">
Vairāk...
</div>
</div>
</div>
Questions
What am I doing wrong?
Where is syntax errors?
How can I get console.log() working there?
Maybe there is an alternative to my problem, maybe I'm misunderstanding the concept of KO.js?
Conclusions
I know there is data inside mainViewModel.itemPage.loadcontent($.ajax(data)) because alert() shows it, but it doesn't pass the value to item!
I'm a newbie, total newbie, and if I thought I'am somewhat a decent programmer now I think I am total dumb ass and I am starting to hate KO.js, but I need it very badly!
NOTE: You can see in debug section that index page works just fine.
DEBUG PLACE
Here is published web application
And here is single item page
THANK YOU
Thanks everyone for helping me, I was so frustrated that I even didn't see any more the obvious, thanks again! Cheers!
1) At first glance, I noticed your HTML bindings are referring to mainViewModel. For example:
data-bind="init: mainViewModel.itemPage.loadcontent(#id), with: mainViewModel.itemPage.item
should likely be
data-bind="init: itemPage.loadcontent(#id), with: itemPage.item
You are already bound to mainViewModel
2) For debugging, use this to see what you are bound to in the view.
<pre data-bind="text:ko.toJSON(yourViewModelGoesHere, null, 2)"></pre>
3) The data being returned is not an array, though you are treating it as such.
$.ajax({
url: '/api/item/details/' + getID,
dataType: 'json',
success: function (data) {
var getArray = [];
$.each(data, function (index, item) {
getArray[index] = item;
});
itemViewModel.item(getArray);
dataReal = data;
},
If you create a sample at http://jsfiddle.net we can help you more.
Within the data-bind elements, you are referring to your model relative the the object you specified in the applyBindings() function. In your case, you called applyBindings(mainViewModel), so in the bindings themselves, you refer to its properties, not to mainViewModel itself.
In your non-working HTML, <div class="item-container clearfix" data-bind="console.log($root)"> seems suspicious. What kind of binding is this? It doesn't specify any particular property to bind.
Use your browser's developer tools (Firebug in Firefox, Developer Tools in Chrome/IE...) to see the syntax errors. If there are problems with bindings, you will see them there.
Related
I have a method that return json ContentResult. I call on from JavaScript file like this:
$scope.GetUserRoles = function () {
$http({
method: "GET",
url: Current.VirtualUrl + "Store/Counting/GetUserRoles"
}).then(function mySucces(response) {
if (response.data.Status == 1) {
$scope.UserRoles = response.data.Data;
$scope.GetCountingList(0, false, "CountingId", "DESC");
}
else {
console.log(response);
$scope.ShowMessage(msgWarning, msgDataFromServerFail + response.data.Data);
}
}, function myError(response) {
});
}
When calling here GetUserRoles method doesn't fire and Response.Data get this error:
<link href="/MySite/Assets/css/pages/error.css" rel="stylesheet" />
<div class="page-500-full-page">
<div class="row">
<div class="col-md-12 page-500">
<div class=" number">
500
</div>
<div>
<h3>Oops! Something went wrong.</h3>
<p>
The view 'GetUserRoles' or its master was not found or no view engine supports the searched locations. The following locations were searched:
~/Areas/iStore/Views/Counting/GetUserRoles.aspx
~/Areas/iStore/Views/Counting/GetUserRoles.ascx
~/Areas/iStore/Views/Shared/GetUserRoles.aspx
~/Areas/iStore/Views/Shared/GetUserRoles.ascx
~/Views/Counting/GetUserRoles.aspx
~/Views/Counting/GetUserRoles.ascx
~/Views/Shared/GetUserRoles.aspx
~/Views/Shared/GetUserRoles.ascx
~/Areas/iStore/Views/Counting/GetUserRoles.cshtml
~/Areas/iStore/Views/Counting/GetUserRoles.vbhtml
~/Areas/iStore/Views/Shared/GetUserRoles.cshtml
~/Areas/iStore/Views/Shared/GetUserRoles.vbhtml
~/Views/Counting/GetUserRoles.cshtml
~/Views/Counting/GetUserRoles.vbhtml
~/Views/Shared/GetUserRoles.cshtml
~/Views/Shared/GetUserRoles.vbhtml </p>
</div>
</div>
</div>
</div>
Any help will be much appreciated.
Thanks in advance.
try replacing:
url: Current.VirtualUrl + "Store/Counting/GetUserRoles"
with this:
url:"/Store/Counting/GetUserRoles"
or make sure, you have:
url:"/ControllerName/MethodName"
in url
I found the problem. Base controller class override OnActionExecuting method. And an if condition prevent coming here.
Thanks for your all advices.
I am trying to add a on click function on the specific child of .article which will show certain wikipedia link base on the pageid received from the request. But all the .article are pointing to the same page.
HTML:
<section id="body-article">
<div id="body-container">
</div>
</section>
JavaScript(jQuery):
function SendRequest(searchEntry){
$.ajax({
url: `https://en.wikipedia.org/w/api.php?action=query&list=search&format=json&srsearch=${searchEntry}`,
type: 'GET',
dataType: 'jsonp',
headers: {'Api-User-Agent': 'WikiReader/0.1.0'}
}).done(function(data, status) {
console.log(data);
GenerateArticle(data);
}).fail(function(data, status) {
console.log("ERROR! " + status);
});
}
function GenerateArticle(data){
//shows all the article in a div
var totalArticleLength = data.query.search.length;
for(var i=0;i<totalArticleLength;i++){
var title= data.query.search[i].title;
var pageid=data.query.search[i].pageid;
var snippet=data.query.search[i].snippet;
//responsible for showing single data
CreateSingleArticle(title,pageid,snippet);
// PROBLEM IS WITH THE BELOW LINE
$(`.article:nth-child(${i+1})`).on("click",function(){
window.open(`https://en.wikipedia.org/?curid=${pageid}`, 'Wikipedia', 'window settings');
})
}
}
function CreateSingleArticle(title,pageid,snippet){
//creates a individual data
html =
`<div class="article">
<div class="side-bar"></div>
<div class="article-container">
<div class="article-header">
${title}
</div>
<div class="snippet">
${snippet}
</div>
</div>
</div>`
$("#body-container").append(html);
}
Answer is quite simple. You ran into javascript scope problem. Have a look at the immediate function call. Read more here. http://tobyho.com/2011/11/02/callbacks-in-loops/
for(var i=0;i<totalArticleLength;i++){
(function(index, pageId){
var title= data.query.search[index].title;
var pageid=data.query.search[index].pageid;
var snippet=data.query.search[index].snippet;
//responsible for showing single data
CreateSingleArticle(title,pageid,snippet);
// PROBLEM IS WITH THE BELOW LINE
$(`.article:nth-child(${index+1})`).on("click",function(){
window.open(`https://en.wikipedia.org/?curid=${pageId}`, 'Wikipedia', 'window settings');
})
})(i, data.query.search[i].pageid)
}
Trying to search in Wikipedia by user's input but it doesn't work for some reason. First I thought it could be due to cross domain problem. But .ajax should help with that.
Here is codepen: http://codepen.io/ekilja01/pen/pRerpb
Here is my HTML:
<script src="https://use.fontawesome.com/43f8201759.js">
</script>
<body>
<h2 class="headertext">WIKIPEDIA <br> VIEWER </h2>
<div class="row">
<div class="col-10-md">
<input class="searchRequest blink_me" id="cursor" type="text" placeholder="__"></input>
</div>
<div class="searchIcon col-2-md"> </div>
</div>
<div>
<p class=results></p>
</div>
</body>
Here is my jQuery:
$(document).ready(function() {
var icon = "<i class='fa fa-search fa-2x'></i>";
$('#cursor').on("keydown", function() {
$(this).removeClass("blink_me");
var searchIcon = $(".searchIcon");
searchIcon.empty();
if ($(".searchRequest").val().length > 0) {
searchIcon.append(icon);
}
searchIcon.on("click", function() {
console.log("clicked!");
var search = $(".searchRequest").val();
var url = "https://en.wikipedia.org/w/api.php?action=opensearch&format=json&search=" + search + "&format=json&callback=?";
$.ajax({
dataType: "jsonp",
url: url,
success: function(data) {
$(".results").html(data[0]);
console.log(data[0]);
}
});
});
});
});
What am doing wrong? Please help.
There's an error in the order of load for your js.
The data object contains the text of the results in the array with index 2, which i assume is what you want to show, change it to
$(".results").html(data[2]);
You can check a modified version of your original code here
http://codepen.io/anon/pen/mRmGXG
I am designing a social network that has timeline and there is like button. I use AJAX to apply the like button on the server side. the problem is that I want to change the number of like for each post immediately after they have liked successfully. Because my elements are generated by for-each, I want to change the number of like for the exact element, I really have a problem with it.I am using thymeleaf.
I am looking for an idea that how to do this.
here is my html code:
<div class="col-sm-4">
<div class="row" >
<div class="col-sm-12">
<img th:if="${tweet.isFavorited()}" src="../static/images/like.png" th:src="#{/images/like.png}" th:class="like-img" th:id="${tweet.getId()}" width="35" height="35"/>
<img th:if="${!tweet.isFavorited()}" src="../static/images/dislike.png" th:src="#{/images/dislike.png}" th:class="like-img" th:id="${tweet.getId()}" width="35" height="35"/>
</div>
</div>
<div class="row">
<div class="col-sm-12" >
<h6 th:if="${tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}" th:text="${tweet.getRetweetedStatus().getFavoriteCount()}"></h6>
<h6 th:if="${!tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}" th:text="${tweet.getFavoriteCount()}"></h6>
</div>
</div>
and it is my script code:
$(function () {
$(".like-img").click(function () {
event.preventDefault();
var $post = $(this);
var toSend = {
"tweetId": this.getAttribute("id")
}
$.ajax({
type : "POST",
contentType: "application/json; charset=utf-8",
url : "like",
data : JSON.stringify(toSend),
dataType : 'json'
}).done(function (data) {
if(data.status == "success") {
if ($($post).attr("src") == "/images/dislike.png") {
$($post).attr('src','/images/like.png');
}
else {
$($post).attr('src','/images/dislike.png');
}
return false;
}
});
});
})
Okay so to make this work you will need to assign unique ids to the like-count elements, something like so:
<h6 th:if="${tweet.isRetweet()}" th:class="like-count" th:id="${tweet.getId()}_like_count" th:text="${tweet.getRetweetedStatus().getFavoriteCount()}"></h6>
Then you can retrieve the current count, increment it, and set the text of the count element. Something like so:
var currentCount = parseInt($('#'+toSend.tweetId+'_like_count').innerHtml)
var newCount = currentCount++;
$('#'+toSend.tweetId+'_like_count').text(newCount);
how to get muttiple data attribute from element classes of response html.
I can extract only data.
this is response.html
<div class="book" data-name="frozen" data-author="micheal" data-price="30">
Frozen
</div>
<div class="book" data-name="unbroken" data-author="jimmy" data-price="25">
Unbroken
</div>
<div class="book" data-name="carry on" data-author="alex" data-price="32">
Carry On
</div>
Ajax code here
function getData($scope){
$.ajax({
url: "/response.html",
dataType: "html",
success: function(response) {
var $response = $(response);
// not working
// var $book-data = $response.find('div.book').data({'name','author','price'});
var $bookData = $response.find('div.book').data('name');
alert($bookData);
}
});
}
I wish to get book-data as json or array to display in angular.
try this:
var bookData=Array();
$.get("stackTest.html", function(response) {
$.each($(response).find(".book"),function(ind,ele){
bookData.push($(ele).data());
});
console.log(bookData);
});
then you get an array with the data-object of each ".book" node
mike
Pretty easy:
var allData = [];
$('.book').each(function(i){
allData.push( $(this).data() );
});
console.log( allData );
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="book" data-name="frozen" data-author="micheal" data-price="30">
Frozen
</div>
<div class="book" data-name="unbroken" data-author="jimmy" data-price="25">
Unbroken
</div>
<div class="book" data-name="carry on" data-author="alex" data-price="32">
Carry On
</div>