jQuery nth-child only selecting first element - javascript

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

Related

How might I avoid opening a new window in due to watch results?

Please, look into my code. I would like to avoid opening a new window in due to watching results. I would like to avoid showing results instead of current content in the same window.
I have thought about using AJAX to show results in Dialog window (JQueryUI)
https://jqueryui.com/dialog/
but I have no idea how? Thank You in advance :)
HTML: result_browser.html
<form class="form" method="post" id="resultbrowserform">
<!--Something-->
<button type="submit" class="btn btn-default"> Apply </button>
</form>
<div id="dialog" title="Details">
<p></p>
</div>
JS:
$(function () { function serializeForm(form){...}
...
$('#resultbrowserform').submit(function () {
$.ajax({
type: 'POST',
url: '/result_browser/data/',
data: serializeForm($('#resultbrowserform')),
success: function (data, status, jqXHR) {
$('#resultbrowsertablecontainer').remove();
data = data.data;
if (!data.length) {
window.alert('No data for selected time period');
return;
}
div = $('<div id="resultbrowsertablecontainer">');
table = $('<table class="table table-striped">');
header = $('<thead>');
header.append($('<tr>')
.append( $('<th>').html('Die Id'))
.append( $('<th>').html('Application'))
.append( $('<th>').html('Result'))
table.append(header);
body = $('<tbody>');
for (i = 0; i < data.length; i++) {
row = $('<tr>');
row.append( $('<td>').html(data[i].die_id));
row.append( $('<td>').html(data[i].application));
row.append( $('<td>').html(data[i].result));
<!--I would like to avoid opening a new window-->
link = $('<a>').attr('target', '_blank').attr('href', '/result_details/' + data[i].result_id + '/').html('Details');
row.append($('<td>').append(link));
body.append(row);
}
table.append(body);
div.append(table);
$('#resultbrowsercontainer').append(div);
}
});
return false;
});
});
Simply remove the target attribute and then it will open inside itself:
<!--I would like to avoid opening a new window-->
link = $('<a>').attr('href', '/result_details/' + data[i].result_id + '/').html('Details');

Wikipedia API sandbox, search by user's input

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

get multi data atrributes from element classes of response html

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>

JQuery Clear <ul> Two Menus Away

I have three menus: College, Department and Program. When a College is clicked, the list of Departments belonging to that College is shown. When a Department is clicked, the list of Programs belonging to that Department is shown.
My problem is that when I click a new College, the Departments re-populate in the second list but I can't get the Programs in the third column to clear out. I've tried a bunch of different things with .nextAll() and .siblings() and whatnot, but nothing has worked yet.
Here's the HTML:
<div class="row">
<div class="col-xs-4">
<h4>Colleges</h4>
<ul class="colleges-menu">
<?php CommonFunctions::getCollege('list'); ?>
</ul>
</div>
<div class="col-xs-4">
<h4>Departments</h4>
<ul id="departments" class="colleges-menu">
</ul>
</div>
<div class="col-xs-4">
<h4>Programs</h4>
<ul id="programs" class="colleges-menu">
</ul>
</div>
And the JQuery:
function ajaxLists(){
var entity = '.' + $(this).attr('class');
var nextEntity;
var value;
var data;
switch(entity){
case '.college':
nextEntity = '#departments';
value = $(this).val();
data = {list_college: value};
break;
case '.departments':
nextEntity = '#programs';
value = $(this).val();
data = {list_departments: value};
break;
default:
break;
}
//this should ONLY run if we are selecting a college or department
if(entity == '.college' || entity == '.departments'){
$("body").css("cursor", "progress");
$.ajax({
url: "sort_college.php",
type: "post",
data: data,
success: function(info){
$(nextEntity).html('');
$(nextEntity).append(info);
console.log(info);
},
error: function(){
alert("there's an error with AJAX");
}
}).done(function(){
$("body").css("cursor", "default");
}); //end ajax
}
}
As you mentioned that your code should fit further elements added in the future, you need to make sure you don't rely on hardcoded IDs, classes, etc.
This should solve your problem, or at least give you a good ground to go from there:
$(function () {
$('.col-xs-4 .colleges-menu').on('click', 'li', function () {
// Go up in this element parents until you reach the div.
// Then you go to its next sibling and grab the ul.
var nextEntity = $(this).parents('.col-xs-4').next().find('ul');
// Self explanatory.
var value = $(this).val();
// Variable to store the data.
var data = {};
// If there's a nextEntity element, it means you didn't reach the last
// set of options.
if (nextEntity) {
// Creating a property for data that is based in a variable.
data["list_" + nextEntity.attr("id")] = value;
$("body").css("cursor", "progress");
$.ajax({
url: "sort_college.php",
type: "post",
data: data,
success: function (info) {
nextEntity.html('');
nextEntity.append(info);
console.log(info);
},
error: function () {
alert("there's an error with AJAX");
}
}).done(function () {
$("body").css("cursor", "default");
});
}
});
});

Why isn't my viewModel working

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.

Categories